diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6704566 --- /dev/null +++ b/.gitignore @@ -0,0 +1,104 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..8ed25e2 --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +@trycrypto:registry=https://pkgs.dev.azure.com/trycrypto/_packaging/trycrypto/npm/registry/ + +always-auth=true \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..40a460b --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +

+Dappstarter Giveaway +

+ +# My Dapp + +This project is for the blockchain application My Dapp. It contains code for the Smart Contract, web-based dapp and NodeJS server. + +# Pre-requisites + +In order to develop and build "My Dapp," the following pre-requisites must be installed: + +* [Visual Studio Code](https://code.visualstudio.com/download) (or any IDE for editing Javascript) +* [NodeJS](https://nodejs.org/en/download/) + +# Installation + +Using a terminal (or command prompt), change to the folder containing the project files and type: `npm run bootstrap` This will fetch all required dependencies. The process will take 1-3 minutes and while it is in progress you can move on to the next step. + +Note: You may see some npm warnings about "web3-bzz" after dependencies are installed. These can be ignored as the associated code is never invoked. +# Build, Deploy and Test + +Using a terminal (or command prompt), change to the folder containing the project files and type: `npm run dev` This will run all the dev scripts in each project package.json. + +To view your dapp, open your browser to http://localhost:5000 + +If you encounter any problems at this step, visit [https://support.trycrypto.com](https://support.trycrypto.com) for help. + + +## Smart Contract + +`lerna run deploy --scope=@trycrypto/dappstarter-dapplib --stream` to compile contracts/*.sol files, deploy them to the blockchain. + +## Dapp + +Run the dapp in a separate terminal. You *must* have run `npm run deploy` for the dapp to see most recent smart contract changes. + +`lerna run dev --scope=@trycrypto/dappstarter-client --stream` runs the dapp on http://localhost:5001 using webpack dev server + +## Server + +Run the server in a separate terminal. You *must* have run `npm run deploy` for the dapp to see most recent smart contract changes. + +`lerna run dev --scope=@trycrypto/dappstarter-server --stream` runs NodeJS server app on port 5002 with NestJS + +## Testing + +`test-config.js` contains settings used by test scripts + +Run tests using `lerna run test [test file] --scope=@trycrypto/dappstarter-dapplib --stream` +## Production Builds + +DappStarter currently does not provide blockchain migration scripts to be used in production. However, here are the scripts for generating production builds: + +`lerna run build:prod` generates dapp bundle for production. + diff --git a/lerna.json b/lerna.json new file mode 100644 index 0000000..6cf7d3f --- /dev/null +++ b/lerna.json @@ -0,0 +1,7 @@ +{ + "packages": [ + "packages/*" + ], + "npmClient": "npm", + "version": "0.0.0" +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..444a2da --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "@trycrypto/dappstarter-hypergen", + "version": "1.0.0", + "scripts": { + "bootstrap": "npx lerna bootstrap", + "start": "npx lerna run dev --no-sort --stream --parallel", + "dev": "npm start" + }, + "devDependencies": { + "chalk": "^4.0.0", + "detect-port": "^1.3.0", + "lerna": "^3.21.0" + + } +} \ No newline at end of file diff --git a/packages/client/.babelrc b/packages/client/.babelrc new file mode 100644 index 0000000..e05d60a --- /dev/null +++ b/packages/client/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + "@babel/env" + ,"@babel/react" + ], + "plugins": [ + ["@babel/plugin-proposal-decorators", { "legacy": true }], + "@babel/plugin-proposal-class-properties", + "@babel/plugin-transform-runtime" + ] +} + diff --git a/packages/client/.gitignore b/packages/client/.gitignore new file mode 100644 index 0000000..716fc80 --- /dev/null +++ b/packages/client/.gitignore @@ -0,0 +1,63 @@ +# Logs +logs +*.log +npm-debug.log* +src/config.json +prod/ +dist/ + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release +build/contracts +build + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +~$*.pptx diff --git a/packages/client/LICENSE b/packages/client/LICENSE new file mode 100644 index 0000000..aeb3362 --- /dev/null +++ b/packages/client/LICENSE @@ -0,0 +1,74 @@ +MIT License + +Copyright (c) 2019 Decent Function, Inc. d/b/a TryCrypto + +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. + + +OTHER LICENSES: + +LICENSE FOR SafeMath + +The MIT License (MIT) + +Copyright (c) 2016 Smart Contract Solutions, Inc. + +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. + + +LICENSE for MDBootstrap + +Copyright (c) 2019 MDBootstrap.com + +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/packages/client/README.md b/packages/client/README.md new file mode 100644 index 0000000..065a5ee --- /dev/null +++ b/packages/client/README.md @@ -0,0 +1,69 @@ +# My Dapp + +This project is for the blockchain application My Dapp. It contains code for the Smart Contract, web-based dapp and NodeJS server. + +# Pre-requisites + +In order to develop and build "My Dapp," the following pre-requisites must be installed: + +* [Visual Studio Code](https://code.visualstudio.com/download) (or any IDE for editing Javascript) +* [NodeJS v10.x](https://nodejs.org/en/download/) +* [Solidity v0.5.11](https://www.npmjs.com/package/solc) +* [Truffle v5.0.7](https://truffleframework.com/truffle) +* [Ganache v2.0.0](https://truffleframework.com/ganache) - blockchain simulator for Ethereum + +# Installation + +Using a terminal (or command prompt), change to the folder containing the project files and type: `lerna bootstrap` This will fetch all required dependencies. The process will take 1-3 minutes and while it is in progress you can move on to the next step. + +Note: You may see some npm warnings about "web3-bzz" after dependencies are installed. These can be ignored as the associated code is never invoked. + +## Ganache Settings (for Ethereum only; skip for other blockchains) + +Launch the Ganache GUI, then create a new workspace with any name of your choice. Once the workspace is active, click the gear icon and complete these configuration steps: + +- Workspace Tab: Truffle Projects: Select "Add Project" and select "truffle-config.js" from the same folder as this README.md file + +- Accounts & Keys Tab: Mnemonic (field with 12 or more words): Copy/paste the words below. + + ### grid arena fog sugar noodle ribbon remain evil install seek fresh smile + + These keywords are used to auto-generate accounts with private keys for development. If the keywords in "truffle-config.js" (which are the same as above) and Ganache don't match, you will not be able to deploy your Smart Contracts to Ganache. + +- Server Tab: Check that "Port Number" is "7545" and "Network ID = 5777" +# Build, Deploy and Test + +Using a terminal (or command prompt), change to the folder containing the project files and type: `npm run dev` This will run all the dev scripts in each project package.json. + +To view your dapp, open your browser to http://localhost:5000 + +If you encounter any problems at this step, visit [https://support.trycrypto.com](https://support.trycrypto.com) for help. + + +## Smart Contract + +`lerna run deploy --scope=@trycrypto/dappstarter-dapplib --stream` to compile contracts/*.sol files, deploy them to the blockchain. + +## Dapp + +Run the dapp in a separate terminal. You *must* have run `npm run deploy` for the dapp to see most recent smart contract changes. + +`lerna run dev --scope=@trycrypto/dappstarter-client --stream` runs the dapp on http://localhost:5001 using webpack dev server + +## Server + +Run the server in a separate terminal. You *must* have run `npm run deploy` for the dapp to see most recent smart contract changes. + +`lerna run dev --scope=@trycrypto/dappstarter-server --stream` runs NodeJS server app on port 5002 with NestJS + +## Testing + +`test-config.js` contains settings used by test scripts + +Run tests using `lerna run test [test file] --scope=@trycrypto/dappstarter-dapplib --stream` +## Production Builds + +DappStarter currently does not provide blockchain migration scripts to be used in production. However, here are the scripts for generating production builds: + +`lerna run build:prod` generates dapp bundle for production. + diff --git a/packages/client/jsconfig.json b/packages/client/jsconfig.json new file mode 100644 index 0000000..95f773e --- /dev/null +++ b/packages/client/jsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "target": "es6", + "experimentalDecorators": true + } +} \ No newline at end of file diff --git a/packages/client/package.json b/packages/client/package.json new file mode 100644 index 0000000..852c332 --- /dev/null +++ b/packages/client/package.json @@ -0,0 +1,80 @@ +{ + "name": "@trycrypto/dappstarter-client", + "version": "0.1.0", + "description": "Dapp scaffolding created with DappStarter", + "directories": { + "test": "test" + }, + "license": "MIT", + "scripts": { + "start": "npm run deploy && npm run dapp", + "dev": "wait-on ../dapplib/src/dapp-config.json && npm run client", + "client": "npm run dapp", + "dapp": "webpack-dev-server --mode development --config webpack.config.dapp.js", + "dapp:prod": "webpack --mode production --config webpack.config.dapp.js" + }, + "authors": [ + "Nik Kalyani https://www.trycrypto.com" + ], + "devDependencies": { + "@babel/core": "^7.7.7", + "@babel/plugin-proposal-decorators": "^7.8.3", + "@babel/plugin-proposal-class-properties": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.8.3", + "@babel/polyfill": "^7.7.0", + "@babel/preset-env": "^7.7.7", + "@babel/preset-react": "^7.8.3", + "@babel/register": "^7.8.3", + "autoprefixer": "^9.7.4", + "babel-loader": "^8.0.6", + "bn-chai": "1.0.1", + "css-loader": "^3.4.2", + "express": "4.16.4", + "favicons-webpack-plugin": "^2.1.0", + "file-loader": "3.0.1", + "ganache-cli": "^6.9.1", + "glob": "^7.1.6", + "html-loader": "0.5.5", + "html-webpack-plugin": "^3.2.0", + "npm-run-all": "^4.1.5", + "postcss-cli": "^7.1.0", + "postcss-loader": "^3.0.0", + "rimraf": "^3.0.2", + "start-server-webpack-plugin": "2.2.5", + "style-loader": "^1.1.3", + "tailwindcss": "^1.2.0", + "wait-on": "^4.0.2", + "webpack": "^4.6.0", + "webpack-cli": "^3.3.0", + "webpack-dev-server": "^3.1.14", + "react": "^16.13.0", + "react-dom": "^16.13.0", + "react-redux": "^7.2.0", + "react-router-dom": "^5.1.2", + "redux": "^4.0.5" + }, + "dependencies": { + "@trycrypto/dappstarter-dapplib": "^0.1.0", + "@grubersjoe/slide-menu": "1.2.3", + "@truffle/hdwallet-provider": "1.0.32", + "@uppy/core": "^1.7.1", + "@uppy/dashboard": "^1.5.2", + "bn.js": "5.0.0", + "bs58": "4.0.1", + "clipboard": "2.0.4", + "cross-spawn": "^7.0.1", + "ipfs-http-client": "41.0.0", + "lit-element": "^2.3.1", + "lit-html": "^1.2.1", + "mdbreact": "^4.25.3", + "mini-css-extract-plugin": "^0.9.0", + "quote": "^0.4.0", + "raw-loader": "^4.0.0", + "react": "^16.13.0", + "react-dom": "^16.13.0", + "react-redux": "^7.2.0", + "react-router-dom": "^5.1.2", + "redux": "^4.0.5", + "web3": "1.2.6" + } +} \ No newline at end of file diff --git a/packages/client/postcss.config.js b/packages/client/postcss.config.js new file mode 100644 index 0000000..3693803 --- /dev/null +++ b/packages/client/postcss.config.js @@ -0,0 +1,7 @@ +const tailwindcss = require('tailwindcss'); +module.exports = { + plugins: [ + tailwindcss('./tailwind.config.js'), + require('autoprefixer'), + ], +}; \ No newline at end of file diff --git a/packages/client/src/dapp/App.jsx b/packages/client/src/dapp/App.jsx new file mode 100644 index 0000000..86193f9 --- /dev/null +++ b/packages/client/src/dapp/App.jsx @@ -0,0 +1,18 @@ +import React, { Component } from 'react'; +import './pages/components/top-navigation'; +import './pages/components/page-loader'; +import '../dapp/pages/dapp-page'; + +class App extends Component { + + render() { + return ( +
+ + +
+ ); + } +} + +export default App; diff --git a/packages/client/src/dapp/actions/index.js b/packages/client/src/dapp/actions/index.js new file mode 100644 index 0000000..ad5bf85 --- /dev/null +++ b/packages/client/src/dapp/actions/index.js @@ -0,0 +1,6 @@ +export const SAMPLE_ACTION = 'SAMPLE_ACTION'; + +export const sampleAction = (title) => ({ + type: SAMPLE_ACTION, + title +}); diff --git a/packages/client/src/dapp/assets/img/canvas.jpg b/packages/client/src/dapp/assets/img/canvas.jpg new file mode 100644 index 0000000..b210807 Binary files /dev/null and b/packages/client/src/dapp/assets/img/canvas.jpg differ diff --git a/packages/client/src/dapp/assets/img/dappstarter.png b/packages/client/src/dapp/assets/img/dappstarter.png new file mode 100644 index 0000000..ae561be Binary files /dev/null and b/packages/client/src/dapp/assets/img/dappstarter.png differ diff --git a/packages/client/src/dapp/components/Sample.jsx b/packages/client/src/dapp/components/Sample.jsx new file mode 100644 index 0000000..f092d7c --- /dev/null +++ b/packages/client/src/dapp/components/Sample.jsx @@ -0,0 +1,26 @@ +import React, { Component } from 'react'; +import { MDBBtn } from 'mdbreact'; +import { connect } from "react-redux"; +import { bindActionCreators } from 'redux'; +import { sampleAction } from '../actions'; + +class Sample extends Component { + + render(){ + return ( + { this.props.sampleAction(); }}>Sample Action + ) + } +} + +const mapStateToProps = state => { + return { ...state.sample } +}; + +const mapDispatchToProps = dispatch => { + return bindActionCreators({ + sampleAction + }, dispatch) +} + +export default connect(mapStateToProps, mapDispatchToProps)(Sample); diff --git a/packages/client/src/dapp/index.css b/packages/client/src/dapp/index.css new file mode 100644 index 0000000..550af62 --- /dev/null +++ b/packages/client/src/dapp/index.css @@ -0,0 +1,241 @@ +@import url('https://fonts.googleapis.com/css?family=Roboto&display=swap'); +@import url('https://fonts.googleapis.com/css?family=Share+Tech+Mono&display=swap'); + +@import "tailwindcss/base"; +@import "tailwindcss/components"; +@import "tailwindcss/utilities"; + +body{ + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: left; + background-color: #EDEDEE; +} + +a { + color: inherit; +} + +.list-group-flush{ + color: #495057; +} + +.active{ + background-color: #e9ecef !; +} + +main { + background-color: #EDEDEE; +} + +.navbar-brand{ + margin-left: 15px; + color: #2196f3 !important; +} + +.sidebar-fixed { + left: 0; + top: 0; + height: 100vh; + width: 270px; + z-index: 1050; + padding: 1.5rem; + padding-top: 0; + cursor: default; + background-color: #fff; +} + +.sidebar-fixed-collapsed { + display: none; +} + +.sidebar-handle{ + left: 270px; + top: 0; + height: 100vh; + width: 5px; + cursor: pointer; + background-color: #eee; + box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); + z-index: 1050; +} + +.sidebar-handle-gripper { + position: absolute; + top: 50%; + width: 100%; + height: 50px; + background-color: #aaa; +} + +.sidebar-handle-collapsed { + left: 0 !important; + margin-left: 0 !important; +} + +.flexible-navbar { + transition: padding-left 0.5s; + padding-left: 300px; + background: #fff; +} + +.sidebar-fixed .logo-wrapper img{ + width: 100%; + padding: 2.5rem; +} + +.list-group-item { + display: block !important; + transition: background-color 0.3s; +} + +.list-group-item:hover { + color: #49505B; + text-decoration: none; + background-color: #f8f9fa +} + +.list-group-item:hover { + color: #49505B; + text-decoration: none; + background-color: #f8f9fa +} + + +.list-group .active { + box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); + border-radius: 5px; +} + +.form-inline{ + flex-flow: unset +} + +.breadcrumb{ + margin: 0; +} + +.active .list-group-item { + z-index: 5; + color: #fff; + border-color: #007bff; + box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); + border-radius: 5px !important; + background-color: #007bff !important; +} + +.page-footer{ + margin-left: 270px; +} + +.card-body { + padding: 0; +} + +.card-body-padded { + padding: 1.25rem +} + +.test { + background-color: purple; +} + +.card-body-padded:last-child { + margin-bottom: 0; +} + +@media (max-width: 1000px) { + + .flexible-content { + padding-left: 0; + } + .flexible-navbar { + padding-left: 10px; + } + + #content{ + margin-left: 0px; + } + + .page-footer{ + margin-left: 0px; + } + + .fixed-bottom { + display: none; + } + +} + +@media (max-width: 576px) { + + #breadcrumb{ + flex-direction: column; + } +} + +.number { + font-family: 'Share Tech Mono', monospace; +} + +.circle-icon { + background-color: #ffffff; + display: inline-flex; + justify-content: center; + align-items: center; + width: 30px; + height: 30px; + border-radius: 50px; +} + +.overflow-scroll { + max-height: 150px; + overflow: scroll; +} + +.slide-menu { + position: fixed; + width: 400px; + max-width: 85%; + height: 100vh; + top: 0; + right: 0px; + display: none; + box-sizing: border-box; + transform: translateX(100%); + z-index: 9999; +} + +.slide-menu, +.slide-menu .slide-menu__slider { + transition: transform 0.3s ease-in-out; + will-change: transform; +} + +.slide-menu .slide-menu__slider { + width: 100%; + transform: translateX(0); +} + +.slide-menu__control { + display: block; + width: 20px; + height: 40px; + line-height: 40px; + position: absolute; + top: 0; + left: -20px; + z-index: 1001; + color: #ffffff; + text-align: center; + font-size: 20px; + cursor: pointer; +} + +.slide-menu a { + cursor: pointer; +} \ No newline at end of file diff --git a/packages/client/src/dapp/index.html b/packages/client/src/dapp/index.html new file mode 100644 index 0000000..e278838 --- /dev/null +++ b/packages/client/src/dapp/index.html @@ -0,0 +1,15 @@ + + + + + + + My Dapp + + + +
+ + diff --git a/packages/client/src/dapp/index.jsx b/packages/client/src/dapp/index.jsx new file mode 100644 index 0000000..817be47 --- /dev/null +++ b/packages/client/src/dapp/index.jsx @@ -0,0 +1,16 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import { Provider } from 'react-redux' +import { createStore, compose, combineReducers } from 'redux' +import '@fortawesome/fontawesome-free/css/all.min.css'; +import './index.css'; +import App from './App.jsx'; +import * as reducers from './reducers'; +import registerServiceWorker from './registerServiceWorker'; +import { BrowserRouter as Router } from 'react-router-dom'; + +const app = combineReducers(reducers); +const store = compose(window.devToolsExtension ? window.devToolsExtension() : f => f)(createStore)(app); + +ReactDOM.render(, document.getElementById('root')); +registerServiceWorker(); diff --git a/packages/client/src/dapp/pages/[block-pages].js b/packages/client/src/dapp/pages/[block-pages].js new file mode 100644 index 0000000..96559f9 --- /dev/null +++ b/packages/client/src/dapp/pages/[block-pages].js @@ -0,0 +1 @@ +///+page-post-content diff --git a/packages/client/src/dapp/pages/components/page-body.js b/packages/client/src/dapp/pages/components/page-body.js new file mode 100644 index 0000000..94505fa --- /dev/null +++ b/packages/client/src/dapp/pages/components/page-body.js @@ -0,0 +1,78 @@ +import { LitElement, html, customElement, property } from "lit-element"; + +@customElement("page-body") +export default class PageBody extends LitElement { + @property() + category; + @property() + title; + @property() + description; + + constructor(args) { + super(args); + const children = [...this.children]; + setTimeout(() => { + for (let index = 0; index < children.length; index++) { + const element = children[index]; + this.querySelector(".slot").append(element); + } + }, 0); + } + + createRenderRoot() { + return this; + } + + render() { + return html` +
+
+ + + + + + + + + + + + + + +
+
${this.category}
+ +

+ ${this.title} +

+
+
+ ${this.description} +
+
+
+
+ `; + } +} diff --git a/packages/client/src/dapp/pages/components/page-loader.js b/packages/client/src/dapp/pages/components/page-loader.js new file mode 100644 index 0000000..34b99bd --- /dev/null +++ b/packages/client/src/dapp/pages/components/page-loader.js @@ -0,0 +1,46 @@ +import DOM from "../../../lib/components/shared/dom"; +import { LitElement, html, customElement, property } from "lit-element"; + +@customElement("page-loader") +export default class PageLoader extends LitElement { + @property() + name; + @property() + route; + + createRenderRoot() { + return this; + } + + pageContent = null; + + render() { + return html` +
+
${this.pageContent}
+
+ `; + } + + async load(pageItem) { + this.classList.add("relative", "grid", "xl:grid-cols-4", "lg:grid-cols-1"); + this.setAttribute("style", "top: 70px"); + + try { + await import(`../../pages/${pageItem.name}-page.js`); + let pageName = pageItem.name.replace("_", "-") + "-page"; + + this.pageContent = DOM.create(pageName, { + title: pageItem.title, + description: pageItem.description, + category: pageItem.category + }); + } catch (e) { + console.log(e); + this.pageContent = DOM.div( + `Error loading content page for "${pageItem.title}"` + ); + } + this.requestUpdate(); + } +} diff --git a/packages/client/src/dapp/pages/components/page-panel.js b/packages/client/src/dapp/pages/components/page-panel.js new file mode 100644 index 0000000..df2e633 --- /dev/null +++ b/packages/client/src/dapp/pages/components/page-panel.js @@ -0,0 +1,91 @@ +import "@grubersjoe/slide-menu/dist/slide-menu.js"; +import { LitElement, html, customElement, property } from "lit-element"; +@customElement("page-panel") +export default class PagePanel extends LitElement { + @property() + title; + @property() + category; + @property() + description; + + createRenderRoot() { + return this; + } + + constructor(args) { + super(args); + + setTimeout(() => { + let panelElement = this.querySelector(".result-panel"); + this.resultPanel = new SlideMenu(panelElement, { + showBackLink: false, + position: "right" + }); + + panelElement.addEventListener("sm.open-after", function() { + this.querySelector(".slide-menu__control").innerHTML = "x"; + }); + + panelElement.addEventListener("sm.close-after", function() { + this.querySelector(".slide-menu__control").innerHTML = "+"; + }); + }, 0); + } + + toggle() { + this.resultPanel.toggle(); + } + + open() { + this.resultPanel.open(); + } + + close() { + this.resultPanel.close(); + } + + prepend(content) { + let self = this; + self + .querySelector(".result-list") + .prepend(self._addAutoFadeToContent(content)); + } + + append(content) { + let self = this; + self + .querySelector(".result-list") + .append(self._addAutoFadeToContent(content)); + } + + _addAutoFadeToContent(content) { + let fadingContent = document.createElement("div"); + fadingContent.appendChild(content); + window.setTimeout(() => { + fadingContent.style = "opacity: 0.5"; + }, 5000); + + return fadingContent; + } + + render() { + let content = html` +
+
+ + +
+

Result Viewer

+
+
+ `; + return content; + } +} diff --git a/packages/client/src/dapp/pages/components/top-navigation.js b/packages/client/src/dapp/pages/components/top-navigation.js new file mode 100644 index 0000000..8f3f851 --- /dev/null +++ b/packages/client/src/dapp/pages/components/top-navigation.js @@ -0,0 +1,102 @@ +import { LitElement, html, customElement, property } from "lit-element"; +@customElement('top-navigation') +export default class TopNavigation extends LitElement { + @property() + collapse; + + createRenderRoot() { + return this; + } + + constructor(args) { + super(args); + setTimeout(() => { + this.setPageLoader(); + }, 0); + } + + getPages() { + let staticPages = [ + { + name: "dapp", + title: "My Dapp", + route: "/" + } + ]; + return staticPages.concat([]); + } + + navigate = name => { + let contentPages = this.getPages(); + let pageItem = contentPages.find(item => item.name === name); + if (!pageItem) { + return; + } + + window.history.pushState(null, pageItem.title, pageItem.route); + this.setPageLoader(pageItem); + }; + + handleClick = e => { + e.preventDefault(); + this.navigate(e.target.dataset.link); + this.requestUpdate(); + }; + + setPageLoader(pageItem) { + let pages = this.getPages(); + if (pageItem == null) { + let pageName = location.href.split("/").pop(); + if (pageName !== "") { + pageItem = pages.find(x => x.name == pageName); + } else { + pageItem = pages[0]; + } + } + + let pageLoader = document.getElementById("page-loader"); + pageLoader.load(pageItem); + } + + render() { + this.classList.add('z-10', 'fixed'); + let content = html` + + `; + return content; + } +} + + + diff --git a/packages/client/src/dapp/pages/dapp-page.js b/packages/client/src/dapp/pages/dapp-page.js new file mode 100644 index 0000000..393a423 --- /dev/null +++ b/packages/client/src/dapp/pages/dapp-page.js @@ -0,0 +1,146 @@ +import DappLib from "@trycrypto/dappstarter-dapplib"; +import DOM from "../../lib/components/shared/dom"; +import "../../lib/components/shared/action-card.js"; +import "../../lib/components/widgets/number-widget.js"; +import ActionButton from "../../lib/components/shared/action-button"; +import canvas from "../assets/img/canvas.jpg"; +import { LitElement, html, customElement, property } from "lit-element"; +@customElement("dapp-page") +export default class DappPage extends LitElement { + @property() + get; + @property() + post; + @property() + title; + @property() + category; + @property() + description; + + createRenderRoot() { + return this; + } + constructor(args) { + super(args); + this.counter = 0; + this.fetchAndDisplayCounter(); + } + + handleClick = e => { + DOM.el("top-navigation").handleClick(e); + }; + + buttonClick = async e => { + let info = e.detail; + if (info.type === DappLib.DAPP_RESULT_ERROR) { + DOM.elid("result").innerHTML = + '' + info.result + ""; + } else { + setTimeout(() => this.fetchAndDisplayCounter(), 500); + } + } + + render() { + let content = html` +
+
+
+ + + + + + + + + + + + + + +
+

🎉 Dappiness!

+

+ Your Dapp is ready, and the world is waiting for you to create + something amazing. Visit + TryCrypto.com + for more insights on dapp development. The examples below + demonstrate how to use the Dapp Library, ActionCard and ActionButton + components to interact with the Dapp smart contract. +

+
+ +
+
+ + +
+ +
+

+ Counter value from contract: + ${this.counter} +

+ + +
+ +
+
+
+ `; + return content; + + // Handle increment counter click + } + + async fetchAndDisplayCounter() { + let result = await DappLib["getStateCounter"].call(); + this.counter = result.callData; + await this.requestUpdate(); + // DOM.elid("counter").innerHTML = result.callData; + } +} diff --git a/packages/client/src/dapp/reducers/index.js b/packages/client/src/dapp/reducers/index.js new file mode 100644 index 0000000..3f81fba --- /dev/null +++ b/packages/client/src/dapp/reducers/index.js @@ -0,0 +1,12 @@ +import * as Action from '../actions'; + +export const samplePanel = (state={}, action) => { + switch (action.type){ + case Action.SAMPLE_ACTION: + return { ...state }; + + default: + return state + } +} + diff --git a/packages/client/src/dapp/registerServiceWorker.js b/packages/client/src/dapp/registerServiceWorker.js new file mode 100644 index 0000000..a3e6c0c --- /dev/null +++ b/packages/client/src/dapp/registerServiceWorker.js @@ -0,0 +1,117 @@ +// In production, we register a service worker to serve assets from local cache. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on the "N+1" visit to a page, since previously +// cached resources are updated in the background. + +// To learn more about the benefits of this model, read https://goo.gl/KwvDNy. +// This link also includes instructions on opting out of this behavior. + +const isLocalhost = Boolean( + window.location.hostname === 'localhost' || + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.1/8 is considered localhost for IPv4. + window.location.hostname.match( + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ + ) +); + +export default function register() { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL(process.env.PUBLIC_URL, window.location); + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 + return; + } + + window.addEventListener('load', () => { + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + + if (isLocalhost) { + // This is running on localhost. Lets check if a service worker still exists or not. + checkValidServiceWorker(swUrl); + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + console.log( + 'This web app is being served cache-first by a service ' + + 'worker. To learn more, visit https://goo.gl/SC7cgQ' + ); + }); + } else { + // Is not local host. Just register service worker + registerValidSW(swUrl); + } + }); + } +} + +function registerValidSW(swUrl) { + navigator.serviceWorker + .register(swUrl) + .then(registration => { + registration.onupdatefound = () => { + const installingWorker = registration.installing; + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the old content will have been purged and + // the fresh content will have been added to the cache. + // It's the perfect time to display a "New content is + // available; please refresh." message in your web app. + console.log('New content is available; please refresh.'); + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.'); + } + } + }; + }; + }) + .catch(error => { + console.error('Error during service worker registration:', error); + }); +} + +function checkValidServiceWorker(swUrl) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl) + .then(response => { + // Ensure service worker exists, and that we really are getting a JS file. + if ( + response.status === 404 || + response.headers.get('content-type').indexOf('javascript') === -1 + ) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then(registration => { + registration.unregister().then(() => { + window.location.reload(); + }); + }); + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl); + } + }) + .catch(() => { + console.log( + 'No internet connection found. App is running in offline mode.' + ); + }); +} + +export function unregister() { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready.then(registration => { + registration.unregister(); + }); + } +} diff --git a/packages/client/src/lib/components/shared/action-button.js b/packages/client/src/lib/components/shared/action-button.js new file mode 100644 index 0000000..7bbf8b1 --- /dev/null +++ b/packages/client/src/lib/components/shared/action-button.js @@ -0,0 +1,120 @@ +import DappLib from "@trycrypto/dappstarter-dapplib"; +import { LitElement, html, customElement, property } from "lit-element"; +@customElement("action-button") +export default class ActionButton extends LitElement { + @property() + get; + @property() + post; + @property() + action; + @property() + method; + @property() + fields; + @property() + message; + @property() + return; + @property() + source; + @property() + text; + @property() + "event-click"; + + @property({ type: Function }) + 'click'; + + createRenderRoot() { + return this; + } + + constructor(args) { + super(args); + this.clicked = false; + } + + render() { + this.clicked = false; + this.classList.remove("disabled"); + return html` + + `; + // if (DappLib[this.action] && this.source) { + + // } else { + // console.error("😕 Action or Source not found"); + // } + } + + async clickHandler() { + if (this.clicked === true) { + return; + } + this.clicked = true; + + // render( + // html` + // + // `, + // this + // ); + this.classList.add("disabled"); + // Capture values of all fields of interest + let source = document.querySelector(this.source); + let values = {}; + let fields = this.fields.split(" "); + fields.map(field => { + if (field) { + let fieldElement = source.querySelector(`[data-field=${field}]`); + if (fieldElement) { + if (fieldElement.type === "checkbox") { + values[field] = fieldElement.checked; + } else if (fieldElement.type === "uploader") { + values[field] = fieldElement.files; + } else { + values[field] = fieldElement.value || ""; + } + } + } + }); + + try { + //console.log('Last call, values: ', this.action, values); + let retVal = await DappLib[this.action].call(null, values); + let resultNode = DappLib.getFormattedResultNode(retVal, this.return); + this.fireClickEvent(retVal, resultNode); + } catch (e) { + if (e.message.indexOf("run Out of Gas") > -1) { + e.message = + "Can't access the blockchain. Check that access to it isn't blocked. During development this error usually means your test blockchain is not running or has test accounts that don't match the accounts in your development configuration."; + } + let retVal = { + type: DappLib.DAPP_RESULT_ERROR, + label: "Error Message", + result: e + }; + let resultNode = DappLib.getFormattedResultNode(retVal); + this.fireClickEvent(retVal, resultNode); + } finally { + this.render(); + } + } + + fireClickEvent(data, node) { + this['click']({ + detail: { + info: data, + node: node + } + }); + } +} diff --git a/packages/client/src/lib/components/shared/action-card.js b/packages/client/src/lib/components/shared/action-card.js new file mode 100644 index 0000000..e469add --- /dev/null +++ b/packages/client/src/lib/components/shared/action-card.js @@ -0,0 +1,112 @@ +import DappLib from "@trycrypto/dappstarter-dapplib"; +import SvgIcons from "../widgets/svg-icons"; +import "../widgets/wait-widget"; +import { unsafeHTML } from "lit-html/directives/unsafe-html"; +import { LitElement, html, customElement, property } from "lit-element"; +@customElement("action-card") +export default class ActionCard extends LitElement { + @property({ type: String }) + action = null; + @property({ type: String }) + method = null; + @property({ type: String }) + fields = null; + @property({ type: String }) + message = null; + @property({ type: String }) + return = null; + @property({ type: String }) + target = null; + @property({ type: String }) + description = null; + + createRenderRoot() { + return this; + } + + constructor(args) { + super(args); + const children = [...this.children]; + setTimeout(() => { + for (let index = 0; index < children.length; index++) { + const element = children[index]; + this.querySelector(".slot").append(element); + } + }, 0); + + this.clicked = false; + if (!this.id) { + this.id = + "x" + + Math.random() + .toString(36) + .substr(2, 9); + } + } + + handleClick = e => { + if (this.action) { + let resultPanel = document.getElementById("resultPanel"); + if (e.detail.info.type === DappLib.DAPP_RESULT_ERROR) { + resultPanel.prepend(e.detail.node); + resultPanel.open(); + } else { + if (this.method === "get" || this.method === 'post') { + let existing = this.querySelectorAll( + `#card-body-${this.action} .note` + ); + existing.forEach(el => el.setAttribute("style", "opacity:0.5;")); + this.querySelector(`#card-body-${this.action}`).append(e.detail.node); + } else { + if (this.target) { + let targetPanel = document.getElementById(this.target); + targetPanel.prepend(e.detail.node); + } else { + resultPanel.prepend(e.detail.node); + resultPanel.open(); + } + } + } + } + }; + + render() { + return html` +
+
+
${this.title}
+ ${this.method === "post" + ? unsafeHTML(SvgIcons.readWrite) + : unsafeHTML(SvgIcons.readOnly)} +
+
-1 ? "p-3" : ""}" + id="card-body-${this.action}" + >
+
+
+ +
+ +
+
+
+
+ `; + } +} diff --git a/packages/client/src/lib/components/shared/dom.js b/packages/client/src/lib/components/shared/dom.js new file mode 100644 index 0000000..8714f93 --- /dev/null +++ b/packages/client/src/lib/components/shared/dom.js @@ -0,0 +1,100 @@ +export default class DOM { + + static stringToHTML(str) { + if (!str) { + return {}; + } + var parser = new DOMParser(); + var doc = parser.parseFromString(str, 'text/html'); + return doc.body; + }; + + static a = (...args) => DOM.create(`a`, ...args); + static div = (...args) => DOM.create(`div`, ...args); + static ul = (...args) => DOM.create(`ul`, ...args); + static li = (...args) => DOM.create(`li`, ...args); + static h1 = (...args) => DOM.create(`h1`, ...args); + static h2 = (...args) => DOM.create(`h2`, ...args); + static h3 = (...args) => DOM.create(`h3`, ...args); + static h4 = (...args) => DOM.create(`h4`, ...args); + static h5 = (...args) => DOM.create(`h5`, ...args); + static h6 = (...args) => DOM.create(`h6`, ...args); + static header = (...args) => DOM.create(`header`, ...args); + static section = (...args) => DOM.create(`section`, ...args); + static p = (...args) => DOM.create(`p`, ...args); + static span = (...args) => DOM.create(`span`, ...args); + static img = (...args) => DOM.create(`img`, ...args); + static td = (...args) => DOM.create(`td`, ...args); + + static elid(id) { + return document.getElementById(id); + } + + static el(name) { + return document.querySelector(name); + } + + static appendText(el, text) { + const textNode = document.createTextNode(text); + el.appendChild(textNode); + } + + static appendArray(el, children) { + children.forEach((child) => { + if (Array.isArray(child)) { + DOM.appendArray(el, child); + } else if (child instanceof window.Element) { + el.appendChild(child); + } else if (typeof child === `string`) { + DOM.appendText(el, child); + } + }); + } + + static setStyles(el, styles) { + if (!styles) { + el.removeAttribute(`styles`); + return; + } + + Object.keys(styles).forEach((styleName) => { + if (styleName in el.style) { + el.style[styleName] = styles[styleName]; // eslint-disable-line no-param-reassign + } else { + console.warn(`${styleName} is not a valid style for a <${el.tagName.toLowerCase()}>`); + } + }); + } + + static create(type, textOrPropsOrChild, ...otherChildren) { + const el = document.createElement(type); + + if (textOrPropsOrChild) { + + if (Array.isArray(textOrPropsOrChild)) { + DOM.appendArray(el, textOrPropsOrChild); + } else if (textOrPropsOrChild instanceof window.Element) { + el.appendChild(textOrPropsOrChild); + } else if (typeof textOrPropsOrChild === `string`) { + DOM.appendText(el, textOrPropsOrChild); + } else if (typeof textOrPropsOrChild === `object`) { + Object.keys(textOrPropsOrChild).forEach((propName) => { + if (propName in el) { + const value = textOrPropsOrChild[propName]; + + if (value) { + el[propName] = value; + } + } else { + console.warn(`${propName} is not a valid property of a <${type}>`); + } + }); + } + + } + + if (otherChildren) DOM.appendArray(el, otherChildren); + + return el; + } +} \ No newline at end of file diff --git a/packages/client/src/lib/components/widgets/account-widget.js b/packages/client/src/lib/components/widgets/account-widget.js new file mode 100644 index 0000000..9935992 --- /dev/null +++ b/packages/client/src/lib/components/widgets/account-widget.js @@ -0,0 +1,38 @@ +import { LitElement, html, customElement, property } from "lit-element"; + +@customElement("account-widget") +export default class AccountWidget extends LitElement { + @property() + field; + @property() + label; + @property() + placeholder; + + createRenderRoot() { + return this; + } + + constructor(args) { + super(args); + } + + render() { + this.classList.add("mb-3", "w-full", "block"); + let content = html` +
+ + +
+ `; + + return content; + } +} diff --git a/packages/client/src/lib/components/widgets/number-widget.js b/packages/client/src/lib/components/widgets/number-widget.js new file mode 100644 index 0000000..fcd79ff --- /dev/null +++ b/packages/client/src/lib/components/widgets/number-widget.js @@ -0,0 +1,42 @@ +import { LitElement, html, customElement, property } from "lit-element"; +@customElement('number-widget') +export default class NumberWidget extends LitElement { + @property() + field; + @property() + label; + @property() + placeholder; + + createRenderRoot() { + return this; + } + + constructor(args) { + super(args); + } + + render() { + let content = html` +
+ + +
+ `; + return content; + } + + value() { + return this.querySelector(`[data-field=${this.field}]`).value; + } +} + + diff --git a/packages/client/src/lib/components/widgets/svg-icons.js b/packages/client/src/lib/components/widgets/svg-icons.js new file mode 100644 index 0000000..d427355 --- /dev/null +++ b/packages/client/src/lib/components/widgets/svg-icons.js @@ -0,0 +1,54 @@ +export default class SvgIcons { + + static get readOnly() { + return ` + + + + + + + + + + +` + } + + static get readWrite() { + return ` + + + + + + + + + +` + } + + static get clippy() { + return ` + + + + +` + } +} + \ No newline at end of file diff --git a/packages/client/src/lib/components/widgets/switch-widget.js b/packages/client/src/lib/components/widgets/switch-widget.js new file mode 100644 index 0000000..6259e01 --- /dev/null +++ b/packages/client/src/lib/components/widgets/switch-widget.js @@ -0,0 +1,45 @@ +import { LitElement, html, customElement, property } from "lit-element"; + +@customElement("switch-widget") +export default class SwitchWidget extends LitElement { + @property({ type: String }) + field = ""; + + @property({ type: String }) + label = ""; + + createRenderRoot() { + return this; + } + + constructor(args) { + super(args); + console.log('Switch'); + + } + + render() { + this.style.display = "block"; + if (this.nextSibling) { + this.classList.add("mb-3"); + } + return html` +
+
+ + +
+
+ `; + } + value() { + return this.querySelector(`[data-field=${this.field}]`).checked; + } +} diff --git a/packages/client/src/lib/components/widgets/text-widget.js b/packages/client/src/lib/components/widgets/text-widget.js new file mode 100644 index 0000000..022dd76 --- /dev/null +++ b/packages/client/src/lib/components/widgets/text-widget.js @@ -0,0 +1,36 @@ +import { LitElement, html, customElement, property } from "lit-element"; +@customElement("text-widget") +export default class TextWidget extends LitElement { + @property({ type: String }) + field = null; + @property({ type: String }) + label = null; + @property({ type: String }) + placeholder = null; + createRenderRoot() { + return this; + } + constructor(args) { + super(args); + } + + render() { + this.classList.add("mb-3"); + let content = html` +
+ + +
+ `; + + return content; + } +} diff --git a/packages/client/src/lib/components/widgets/upload-widget.js b/packages/client/src/lib/components/widgets/upload-widget.js new file mode 100644 index 0000000..e8e2838 --- /dev/null +++ b/packages/client/src/lib/components/widgets/upload-widget.js @@ -0,0 +1,95 @@ +import Uppy from "@uppy/core"; +import UppyDashboard from "@uppy/dashboard"; +import { LitElement, html, customElement, property } from "lit-element"; +@customElement("upload-widget") +export default class UploadWidget extends LitElement { + createRenderRoot() { + return this; + } + @property() + field; + @property() + label; + @property() + placeholder; + @property() + multiple; + @property() + maxsize; + @property() + filesChanged; + + createRenderRoot() { + return this; + } + + constructor(args) { + super(args); + this.type = "uploader"; + this.uppy = null; + this.files = []; + + if (!this.maxsize) { + this.maxsize = "2000000"; + } + + setTimeout(() => { + const uploadElement = this.getElementsByClassName("upload")[0]; + if (uploadElement != null) { + this.uppy = Uppy({ + debug: false, + autoProceed: false, + restrictions: { + maxFileSize: Number(this.maxsize), + maxNumberOfFiles: this.multiple === "true" ? 10 : 1, + minNumberOfFiles: 1, + allowedFileTypes: null + } + }) + .use(UppyDashboard, { + id: `Dashboard-${this.uniqueId}`, + autoProceed: false, + hideUploadButton: true, + hideRetryButton: true, + hidePauseResumeButton: true, + hideCancelButton: true, + showSelectedFiles: true, + proudlyDisplayPoweredByUppy: false, + disableStatusBar: false, + note: `${this.placeholder}
File size limited to ${String( + (this.maxsize / 1000000).toFixed(0) + )}MB`, + inline: true, + height: 200, + width: (this.parentElement?.clientWidth || 0) + 300, + target: uploadElement + }) + .on("file-added", file => { + this._fireFilesChangedEvent(); + }) + .on("file-removed", file => { + this._fireFilesChangedEvent(); + }); + } + }, 0); + } + + render() { + this.classList.add("mb-3"); + + let content = html` +
+ `; + return content; + } + + _fireFilesChangedEvent() { + this.files = this.uppy.getFiles().map(f => f.data); + let filesChangedEvent = new CustomEvent(UploadWidget.EVENT_FILES_CHANGED, { + detail: { + files: this.files + } + }); + this.dispatchEvent(filesChangedEvent); + } +} diff --git a/packages/client/src/lib/components/widgets/wait-widget.js b/packages/client/src/lib/components/widgets/wait-widget.js new file mode 100644 index 0000000..5f42100 --- /dev/null +++ b/packages/client/src/lib/components/widgets/wait-widget.js @@ -0,0 +1,136 @@ +import { unsafeHTML } from "lit-html/directives/unsafe-html"; +import { LitElement, html, customElement, property } from "lit-element"; + +@customElement('wait-widget') +export default class WaitWidget extends LitElement { + @property({ type: String }) + waiting = ""; + @property({ type: String }) + "waiting-title" = ""; + @property({ type: String }) + size = ""; + + createRenderRoot() { + return this; + } + + render() { + let size = this.size || "100"; + let waitingTitle = this[WaitWidget.ATTRIBUTE_WAITING_TITLE] || "Waiting..."; + let spinner = html` + + + + + + + + + + + + + + + + + + + + + + + + + + + `; + if (this.waiting === "true") { + return html` +
+ ${spinner} +
${waitingTitle}
+
+ `; + } else { + return html` +
${unsafeHTML(this.title)}
+ `; + } + } +} + diff --git a/packages/client/tailwind.config.js b/packages/client/tailwind.config.js new file mode 100644 index 0000000..1a1c818 --- /dev/null +++ b/packages/client/tailwind.config.js @@ -0,0 +1,694 @@ +module.exports = { + prefix: '', + important: false, + separator: ':', + theme: { + screens: { + sm: '640px', + md: '768px', + lg: '1024px', + xl: '1280px', + }, + colors: { + transparent: 'transparent', + + black: '#000', + white: '#fff', + + gray: { + 100: '#f7fafc', + 200: '#edf2f7', + 300: '#e2e8f0', + 400: '#cbd5e0', + 500: '#a0aec0', + 600: '#718096', + 700: '#4a5568', + 800: '#2d3748', + 900: '#1a202c', + }, + red: { + 100: '#fff5f5', + 200: '#fed7d7', + 300: '#feb2b2', + 400: '#fc8181', + 500: '#f56565', + 600: '#e53e3e', + 700: '#c53030', + 800: '#9b2c2c', + 900: '#742a2a', + }, + orange: { + 100: '#fffaf0', + 200: '#feebc8', + 300: '#fbd38d', + 400: '#f6ad55', + 500: '#ed8936', + 600: '#dd6b20', + 700: '#c05621', + 800: '#9c4221', + 900: '#7b341e', + }, + yellow: { + 100: '#fffff0', + 200: '#fefcbf', + 300: '#faf089', + 400: '#f6e05e', + 500: '#ecc94b', + 600: '#d69e2e', + 700: '#b7791f', + 800: '#975a16', + 900: '#744210', + }, + green: { + 100: '#f0fff4', + 200: '#c6f6d5', + 300: '#9ae6b4', + 400: '#68d391', + 500: '#48bb78', + 600: '#38a169', + 700: '#2f855a', + 800: '#276749', + 900: '#22543d', + }, + teal: { + 100: '#e6fffa', + 200: '#b2f5ea', + 300: '#81e6d9', + 400: '#4fd1c5', + 500: '#38b2ac', + 600: '#319795', + 700: '#2c7a7b', + 800: '#285e61', + 900: '#234e52', + }, + blue: { + 100: '#ebf8ff', + 200: '#bee3f8', + 300: '#90cdf4', + 400: '#63b3ed', + 500: '#4299e1', + 600: '#3182ce', + 700: '#2b6cb0', + 800: '#2c5282', + 900: '#2a4365', + }, + indigo: { + 100: '#ebf4ff', + 200: '#c3dafe', + 300: '#a3bffa', + 400: '#7f9cf5', + 500: '#667eea', + 600: '#5a67d8', + 700: '#4c51bf', + 800: '#434190', + 900: '#3c366b', + }, + purple: { + 100: '#faf5ff', + 200: '#e9d8fd', + 300: '#d6bcfa', + 400: '#b794f4', + 500: '#9f7aea', + 600: '#805ad5', + 700: '#6b46c1', + 800: '#553c9a', + 900: '#44337a', + }, + pink: { + 100: '#fff5f7', + 200: '#fed7e2', + 300: '#fbb6ce', + 400: '#f687b3', + 500: '#ed64a6', + 600: '#d53f8c', + 700: '#b83280', + 800: '#97266d', + 900: '#702459', + }, + }, + spacing: { + px: '1px', + '0': '0', + '1': '0.25rem', + '2': '0.5rem', + '3': '0.75rem', + '4': '1rem', + '5': '1.25rem', + '6': '1.5rem', + '8': '2rem', + '10': '2.5rem', + '12': '3rem', + '16': '4rem', + '20': '5rem', + '24': '6rem', + '32': '8rem', + '40': '10rem', + '48': '12rem', + '56': '14rem', + '64': '16rem', + }, + backgroundColor: theme => theme('colors'), + backgroundPosition: { + bottom: 'bottom', + center: 'center', + left: 'left', + 'left-bottom': 'left bottom', + 'left-top': 'left top', + right: 'right', + 'right-bottom': 'right bottom', + 'right-top': 'right top', + top: 'top', + }, + backgroundSize: { + auto: 'auto', + cover: 'cover', + contain: 'contain', + }, + borderColor: theme => ({ + ...theme('colors'), + default: theme('colors.gray.300', 'currentColor'), + }), + borderRadius: { + none: '0', + sm: '0.125rem', + default: '0.25rem', + md: '0.375rem', + lg: '0.5rem', + full: '9999px', + }, + borderWidth: { + default: '1px', + '0': '0', + '2': '2px', + '4': '4px', + '8': '8px', + }, + boxShadow: { + xs: '0 0 0 1px rgba(0, 0, 0, 0.05)', + sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)', + default: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', + md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', + lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', + xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', + '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)', + outline: '0 0 0 3px rgba(66, 153, 225, 0.5)', + none: 'none', + }, + container: {}, + cursor: { + auto: 'auto', + default: 'default', + pointer: 'pointer', + wait: 'wait', + text: 'text', + move: 'move', + 'not-allowed': 'not-allowed', + }, + fill: { + current: 'currentColor', + }, + flex: { + '1': '1 1 0%', + auto: '1 1 auto', + initial: '0 1 auto', + none: 'none', + }, + flexGrow: { + '0': '0', + default: '1', + }, + flexShrink: { + '0': '0', + default: '1', + }, + fontFamily: { + sans: [ + 'system-ui', + '-apple-system', + 'BlinkMacSystemFont', + '"Segoe UI"', + 'Roboto', + '"Helvetica Neue"', + 'Arial', + '"Noto Sans"', + 'sans-serif', + '"Apple Color Emoji"', + '"Segoe UI Emoji"', + '"Segoe UI Symbol"', + '"Noto Color Emoji"', + ], + serif: ['Georgia', 'Cambria', '"Times New Roman"', 'Times', 'serif'], + mono: ['Menlo', 'Monaco', 'Consolas', '"Liberation Mono"', '"Courier New"', 'monospace'], + }, + fontSize: { + xs: '0.75rem', + sm: '0.875rem', + base: '1rem', + lg: '1.125rem', + xl: '1.25rem', + '2xl': '1.5rem', + '3xl': '1.875rem', + '4xl': '2.25rem', + '5xl': '3rem', + '6xl': '4rem', + }, + fontWeight: { + hairline: '100', + thin: '200', + light: '300', + normal: '400', + medium: '500', + semibold: '600', + bold: '700', + extrabold: '800', + black: '900', + }, + height: theme => ({ + auto: 'auto', + ...theme('spacing'), + full: '100%', + screen: '100vh', + }), + inset: { + '0': '0', + auto: 'auto', + }, + letterSpacing: { + tighter: '-0.05em', + tight: '-0.025em', + normal: '0', + wide: '0.025em', + wider: '0.05em', + widest: '0.1em', + }, + lineHeight: { + none: '1', + tight: '1.25', + snug: '1.375', + normal: '1.5', + relaxed: '1.625', + loose: '2', + '3': '.75rem', + '4': '1rem', + '5': '1.25rem', + '6': '1.5rem', + '7': '1.75rem', + '8': '2rem', + '9': '2.25rem', + '10': '2.5rem', + }, + listStyleType: { + none: 'none', + disc: 'disc', + decimal: 'decimal', + }, + margin: (theme, { negative }) => ({ + auto: 'auto', + ...theme('spacing'), + ...negative(theme('spacing')), + }), + maxHeight: { + full: '100%', + screen: '100vh', + }, + maxWidth: (theme, { breakpoints }) => ({ + none: 'none', + xs: '20rem', + sm: '24rem', + md: '28rem', + lg: '32rem', + xl: '36rem', + '2xl': '42rem', + '3xl': '48rem', + '4xl': '56rem', + '5xl': '64rem', + '6xl': '72rem', + full: '100%', + ...breakpoints(theme('screens')), + }), + minHeight: { + '0': '0', + full: '100%', + screen: '100vh', + }, + minWidth: { + '0': '0', + full: '100%', + }, + objectPosition: { + bottom: 'bottom', + center: 'center', + left: 'left', + 'left-bottom': 'left bottom', + 'left-top': 'left top', + right: 'right', + 'right-bottom': 'right bottom', + 'right-top': 'right top', + top: 'top', + }, + opacity: { + '0': '0', + '25': '0.25', + '50': '0.5', + '75': '0.75', + '100': '1', + }, + order: { + first: '-9999', + last: '9999', + none: '0', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + '8': '8', + '9': '9', + '10': '10', + '11': '11', + '12': '12', + }, + padding: theme => theme('spacing'), + placeholderColor: theme => theme('colors'), + stroke: { + current: 'currentColor', + }, + strokeWidth: { + '0': '0', + '1': '1', + '2': '2', + }, + textColor: theme => theme('colors'), + width: theme => ({ + auto: 'auto', + ...theme('spacing'), + '1/2': '50%', + '1/3': '33.333333%', + '2/3': '66.666667%', + '1/4': '25%', + '2/4': '50%', + '3/4': '75%', + '1/5': '20%', + '2/5': '40%', + '3/5': '60%', + '4/5': '80%', + '1/6': '16.666667%', + '2/6': '33.333333%', + '3/6': '50%', + '4/6': '66.666667%', + '5/6': '83.333333%', + '1/12': '8.333333%', + '2/12': '16.666667%', + '3/12': '25%', + '4/12': '33.333333%', + '5/12': '41.666667%', + '6/12': '50%', + '7/12': '58.333333%', + '8/12': '66.666667%', + '9/12': '75%', + '10/12': '83.333333%', + '11/12': '91.666667%', + full: '100%', + screen: '100vw', + }), + zIndex: { + auto: 'auto', + '0': '0', + '10': '10', + '20': '20', + '30': '30', + '40': '40', + '50': '50', + }, + gap: theme => theme('spacing'), + gridTemplateColumns: { + none: 'none', + '1': 'repeat(1, minmax(0, 1fr))', + '2': 'repeat(2, minmax(0, 1fr))', + '3': 'repeat(3, minmax(0, 1fr))', + '4': 'repeat(4, minmax(0, 1fr))', + '5': 'repeat(5, minmax(0, 1fr))', + '6': 'repeat(6, minmax(0, 1fr))', + '7': 'repeat(7, minmax(0, 1fr))', + '8': 'repeat(8, minmax(0, 1fr))', + '9': 'repeat(9, minmax(0, 1fr))', + '10': 'repeat(10, minmax(0, 1fr))', + '11': 'repeat(11, minmax(0, 1fr))', + '12': 'repeat(12, minmax(0, 1fr))', + }, + gridColumn: { + auto: 'auto', + 'span-1': 'span 1 / span 1', + 'span-2': 'span 2 / span 2', + 'span-3': 'span 3 / span 3', + 'span-4': 'span 4 / span 4', + 'span-5': 'span 5 / span 5', + 'span-6': 'span 6 / span 6', + 'span-7': 'span 7 / span 7', + 'span-8': 'span 8 / span 8', + 'span-9': 'span 9 / span 9', + 'span-10': 'span 10 / span 10', + 'span-11': 'span 11 / span 11', + 'span-12': 'span 12 / span 12', + }, + gridColumnStart: { + auto: 'auto', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + '8': '8', + '9': '9', + '10': '10', + '11': '11', + '12': '12', + '13': '13', + }, + gridColumnEnd: { + auto: 'auto', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + '8': '8', + '9': '9', + '10': '10', + '11': '11', + '12': '12', + '13': '13', + }, + gridTemplateRows: { + none: 'none', + '1': 'repeat(1, minmax(0, 1fr))', + '2': 'repeat(2, minmax(0, 1fr))', + '3': 'repeat(3, minmax(0, 1fr))', + '4': 'repeat(4, minmax(0, 1fr))', + '5': 'repeat(5, minmax(0, 1fr))', + '6': 'repeat(6, minmax(0, 1fr))', + }, + gridRow: { + auto: 'auto', + 'span-1': 'span 1 / span 1', + 'span-2': 'span 2 / span 2', + 'span-3': 'span 3 / span 3', + 'span-4': 'span 4 / span 4', + 'span-5': 'span 5 / span 5', + 'span-6': 'span 6 / span 6', + }, + gridRowStart: { + auto: 'auto', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + }, + gridRowEnd: { + auto: 'auto', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + }, + transformOrigin: { + center: 'center', + top: 'top', + 'top-right': 'top right', + right: 'right', + 'bottom-right': 'bottom right', + bottom: 'bottom', + 'bottom-left': 'bottom left', + left: 'left', + 'top-left': 'top left', + }, + scale: { + '0': '0', + '50': '.5', + '75': '.75', + '90': '.9', + '95': '.95', + '100': '1', + '105': '1.05', + '110': '1.1', + '125': '1.25', + '150': '1.5', + }, + rotate: { + '-180': '-180deg', + '-90': '-90deg', + '-45': '-45deg', + '0': '0', + '45': '45deg', + '90': '90deg', + '180': '180deg', + }, + translate: (theme, { negative }) => ({ + ...theme('spacing'), + ...negative(theme('spacing')), + '-full': '-100%', + '-1/2': '-50%', + '1/2': '50%', + full: '100%', + }), + skew: { + '-12': '-12deg', + '-6': '-6deg', + '-3': '-3deg', + '0': '0', + '3': '3deg', + '6': '6deg', + '12': '12deg', + }, + transitionProperty: { + none: 'none', + all: 'all', + default: 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform', + colors: 'background-color, border-color, color, fill, stroke', + opacity: 'opacity', + shadow: 'box-shadow', + transform: 'transform', + }, + transitionTimingFunction: { + linear: 'linear', + in: 'cubic-bezier(0.4, 0, 1, 1)', + out: 'cubic-bezier(0, 0, 0.2, 1)', + 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)', + }, + transitionDuration: { + '75': '75ms', + '100': '100ms', + '150': '150ms', + '200': '200ms', + '300': '300ms', + '500': '500ms', + '700': '700ms', + '1000': '1000ms', + }, + }, + variants: { + accessibility: ['responsive', 'focus'], + alignContent: ['responsive'], + alignItems: ['responsive'], + alignSelf: ['responsive'], + appearance: ['responsive'], + backgroundAttachment: ['responsive'], + backgroundColor: ['responsive', 'hover', 'focus'], + backgroundPosition: ['responsive'], + backgroundRepeat: ['responsive'], + backgroundSize: ['responsive'], + borderCollapse: ['responsive'], + borderColor: ['responsive', 'hover', 'focus'], + borderRadius: ['responsive'], + borderStyle: ['responsive'], + borderWidth: ['responsive'], + boxShadow: ['responsive', 'hover', 'focus'], + boxSizing: ['responsive'], + cursor: ['responsive'], + display: ['responsive'], + fill: ['responsive'], + flex: ['responsive'], + flexDirection: ['responsive'], + flexGrow: ['responsive'], + flexShrink: ['responsive'], + flexWrap: ['responsive'], + float: ['responsive'], + clear: ['responsive'], + fontFamily: ['responsive'], + fontSize: ['responsive'], + fontSmoothing: ['responsive'], + fontStyle: ['responsive'], + fontWeight: ['responsive', 'hover', 'focus'], + height: ['responsive'], + inset: ['responsive'], + justifyContent: ['responsive'], + letterSpacing: ['responsive'], + lineHeight: ['responsive'], + listStylePosition: ['responsive'], + listStyleType: ['responsive'], + margin: ['responsive'], + maxHeight: ['responsive'], + maxWidth: ['responsive'], + minHeight: ['responsive'], + minWidth: ['responsive'], + objectFit: ['responsive'], + objectPosition: ['responsive'], + opacity: ['responsive', 'hover', 'focus'], + order: ['responsive'], + outline: ['responsive', 'focus'], + overflow: ['responsive'], + padding: ['responsive'], + placeholderColor: ['responsive', 'focus'], + pointerEvents: ['responsive'], + position: ['responsive'], + resize: ['responsive'], + stroke: ['responsive'], + strokeWidth: ['responsive'], + tableLayout: ['responsive'], + textAlign: ['responsive'], + textColor: ['responsive', 'hover', 'focus'], + textDecoration: ['responsive', 'hover', 'focus'], + textTransform: ['responsive'], + userSelect: ['responsive'], + verticalAlign: ['responsive'], + visibility: ['responsive'], + whitespace: ['responsive'], + width: ['responsive'], + wordBreak: ['responsive'], + zIndex: ['responsive'], + gap: ['responsive'], + gridAutoFlow: ['responsive'], + gridTemplateColumns: ['responsive'], + gridColumn: ['responsive'], + gridColumnStart: ['responsive'], + gridColumnEnd: ['responsive'], + gridTemplateRows: ['responsive'], + gridRow: ['responsive'], + gridRowStart: ['responsive'], + gridRowEnd: ['responsive'], + transform: ['responsive'], + transformOrigin: ['responsive'], + scale: ['responsive', 'hover', 'focus'], + rotate: ['responsive', 'hover', 'focus'], + translate: ['responsive', 'hover', 'focus'], + skew: ['responsive', 'hover', 'focus'], + transitionProperty: ['responsive'], + transitionTimingFunction: ['responsive'], + transitionDuration: ['responsive'], + }, + corePlugins: {}, + plugins: [], +} diff --git a/packages/client/webpack.config.dapp.js b/packages/client/webpack.config.dapp.js new file mode 100644 index 0000000..dc8ca60 --- /dev/null +++ b/packages/client/webpack.config.dapp.js @@ -0,0 +1,83 @@ +const path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const FaviconsWebpackPlugin = require("favicons-webpack-plugin"); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); + + +module.exports = (env, argv) => { + return { + entry: ["@babel/polyfill", path.join(__dirname, "src/dapp")], + output: { + path: path.join( + __dirname, + argv.mode === "development" ? "dist/dapp" : "prod/dapp" + ), + filename: "bundle.js", + publicPath: "/" + }, + module: { + rules: [ + { + test: /\.(js|jsx)$/, + use: "babel-loader", + exclude: /node_modules/ + }, + { + test: /\.css$/, + use: ['style-loader', "css-loader", "postcss-loader"] + }, + + { + test: /\.(png|svg|jpg|gif)$/, + use: [ + { + loader: "file-loader", + options: { + name: "assets/img/[name].[ext]?[hash]" + } + } + ] + }, + { + test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/, + use: [ + { + loader: "file-loader", + options: { + name: "assets/fonts/[name].[ext]" + } + } + ] + }, + { + test: /\.html$/, + use: "html-loader", + exclude: /node_modules/ + } + ] + }, + plugins: [ + new HtmlWebpackPlugin({ + template: path.join(__dirname, "src/dapp/index.html") + }), + new FaviconsWebpackPlugin("src/dapp/assets/img/dappstarter.png"), + // new MiniCssExtractPlugin() + ], + resolve: { + extensions: [".js", ".jsx"] + }, + devtool: "cheap-source-map", + devServer: { + contentBase: path.join(__dirname, "dapp"), + port: 5001, + host: "0.0.0.0", + disableHostCheck: true, + stats: "minimal", + historyApiFallback: true, + open: false, + headers: { + "Access-Control-Allow-Origin": "*" + } + } + }; +}; diff --git a/packages/connector-plugin/dapp-connector.html b/packages/connector-plugin/dapp-connector.html new file mode 100644 index 0000000..7157be1 --- /dev/null +++ b/packages/connector-plugin/dapp-connector.html @@ -0,0 +1,137 @@ + + + + + + \ No newline at end of file diff --git a/packages/connector-plugin/dapp-connector.js b/packages/connector-plugin/dapp-connector.js new file mode 100644 index 0000000..756c37b --- /dev/null +++ b/packages/connector-plugin/dapp-connector.js @@ -0,0 +1,75 @@ +const Web3 = require("web3"); +const { readFileSync } = require("fs"); +const { join } = require("path"); +const { promisify } = require("util"); +const dappConfig = require("@trycrypto/dappstarter-dapplib/src/dapp-config.json"); +const truffleConfig = require("@trycrypto/dappstarter-dapplib/truffle-config"); +const dappStateAbi = require('@trycrypto/dappstarter-dapplib/build/contracts/DappState.json').abi; +module.exports = function(RED) { + function DappConnectorNode(config) { + let node = this; + RED.nodes.createNode(this, config); + setupWeb3(node, config); + + // if (this.interval_id == null && config.eventName != "") { + // this.interval_id = setInterval(() => { + // this.emit("input", { + // payload: new Date().getTime() + // }); + // }, 3000); + // } + + // this.on("input", msg => { + // RED.util.evaluateNodeProperty( + // this.payload, + // this.payloadType, + // this, + // msg, + // (err, res) => { + // if (err) { + // this.error(err, msg); + // } else { + // this.send(msg); + // } + // } + // ); + // }); + } + + async function setupWeb3(node, config) { + let connection = new Web3( + new Web3.providers.WebsocketProvider(dappConfig.wsUri) + ); + + if (config.abi) { + let dappContract = new connection.eth.Contract( + config.abi, + config.contractAddress + ); + + dappContract.events[config.eventName]({ + fromBlock: (await connection.eth.getBlockNumber()) + 1 + }).on("data", event => { + node.send({ + payload: event + }); + }); + } + } + RED.nodes.registerType("dapp-connector", DappConnectorNode, { + settings: { + dappConnectorAbi: { + value: dappStateAbi, + exportable: true + }, + dappConnectorContract: { + value: dappConfig.dappStateContractAddress, + exportable: true + } + } + }); + + DappConnectorNode.prototype.close = function() { + // clearInterval(this.interval_id); + }; +}; diff --git a/packages/connector-plugin/dapp-transaction.html b/packages/connector-plugin/dapp-transaction.html new file mode 100644 index 0000000..fb59826 --- /dev/null +++ b/packages/connector-plugin/dapp-transaction.html @@ -0,0 +1,163 @@ + + + \ No newline at end of file diff --git a/packages/connector-plugin/dapp-transaction.js b/packages/connector-plugin/dapp-transaction.js new file mode 100644 index 0000000..2236e61 --- /dev/null +++ b/packages/connector-plugin/dapp-transaction.js @@ -0,0 +1,63 @@ +const Web3 = require("web3"); +const { readFileSync } = require("fs"); +const { join } = require("path"); +const { promisify } = require("util"); +const dappConfig = require("@trycrypto/dappstarter-dapplib/src/dapp-config.json"); +const truffleConfig = require("@trycrypto/dappstarter-dapplib/truffle-config"); +const dappStateAbi = require("@trycrypto/dappstarter-dapplib/build/contracts/DappState.json") + .abi; +module.exports = function(RED) { + _contract = null; + + function DappTransactionNode(config) { + let node = this; + RED.nodes.createNode(this, config); + (async function() { + const connection = await setupWeb3(node, config); + node.on("input", async data => { + let result = await _contract.methods[config.contractFunction](1).send({ + from: connection.eth.accounts.privateKeyToAccount( + truffleConfig.testAccounts[0] + ).address + }); + node.send({ + payload: result.transactionHash + }); + console.log(result); + }); + })(); + } + + async function setupWeb3(node, config) { + let connection = new Web3( + new Web3.providers.WebsocketProvider(dappConfig.wsUri) + ); + + if (config.abi) { + let dappContract = new connection.eth.Contract( + config.abi, + config.contractAddress + ); + _contract = dappContract; + } + + return connection; + } + + RED.nodes.registerType("dapp-transaction", DappTransactionNode, { + settings: { + dappTransactionAbi: { + value: dappStateAbi, + exportable: true + }, + dappTransactionContract: { + value: dappConfig.dappStateContractAddress, + exportable: true + }, + dappTransactionPrivateKey: { + value: truffleConfig.testAccounts[0], + exportable: true + } + } + }); +}; diff --git a/packages/connector-plugin/icons/ethjs.png b/packages/connector-plugin/icons/ethjs.png new file mode 100644 index 0000000..a362fb0 Binary files /dev/null and b/packages/connector-plugin/icons/ethjs.png differ diff --git a/packages/connector-plugin/package.json b/packages/connector-plugin/package.json new file mode 100644 index 0000000..767b6c2 --- /dev/null +++ b/packages/connector-plugin/package.json @@ -0,0 +1,16 @@ +{ + "version": "1.0.0", + "name": "@trycrypto/dappstarter-connector-plugin", + "node-red": { + "nodes": { + "dapp-connector": "dapp-connector.js", + "dapp-transaction": "dapp-transaction.js" + } + }, + "dependencies": { + "@trycrypto/dappstarter-dapplib": "^0.1.0", + "node-red": "^1.0.3", + "rxjs": "^6.5.4", + "web3": "^1.2.6" + } +} diff --git a/packages/connector-plugin/yarn.lock b/packages/connector-plugin/yarn.lock new file mode 100644 index 0000000..184568a --- /dev/null +++ b/packages/connector-plugin/yarn.lock @@ -0,0 +1,3902 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/runtime@^7.3.1": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" + integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== + dependencies: + regenerator-runtime "^0.13.4" + +"@node-red/editor-api@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@node-red/editor-api/-/editor-api-1.0.4.tgz#768c2dba7122148261474edfaeaba081ba2805f0" + integrity sha512-Bs37Jz/eLNy2qqQXbAX6ix/zvfvZEyZgvWE19PPCoF0BkVn290fkIK48ccdkALjKwmJRErpGEyzERcTWQks4BA== + dependencies: + "@node-red/editor-client" "1.0.4" + "@node-red/util" "1.0.4" + bcryptjs "2.4.3" + body-parser "1.19.0" + clone "2.1.2" + cors "2.8.5" + express "4.17.1" + express-session "1.17.0" + memorystore "1.6.2" + mime "2.4.4" + mustache "4.0.0" + oauth2orize "1.11.0" + passport "0.4.1" + passport-http-bearer "1.0.1" + passport-oauth2-client-password "0.1.2" + when "3.7.8" + ws "6.2.1" + optionalDependencies: + bcrypt "3.0.6" + +"@node-red/editor-client@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@node-red/editor-client/-/editor-client-1.0.4.tgz#b7658291647a65a5608f72efdf3236c4b2208e44" + integrity sha512-BGjsNvvfEYPJIeoP8/8IwLbZeFqYUeEIWBcJ8PTCKPSb5H6Ettwpl6sgLNgSDbHbWHGg3avm7Y94qBnLFICKJg== + +"@node-red/nodes@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@node-red/nodes/-/nodes-1.0.4.tgz#ef505bce4e594639051ab8373f8399dbf6ca8a5c" + integrity sha512-l64ZDLDBCgjdJrRVderJ83Sq24F8/rMhhv1Hmo7w4QCDX0Ki7sHWWQVa0BuS5u4n+jewiOLGs93RWWAzHccWRQ== + dependencies: + ajv "6.12.0" + body-parser "1.19.0" + cheerio "0.22.0" + content-type "1.0.4" + cookie "0.4.0" + cookie-parser "1.4.4" + cors "2.8.5" + cron "1.8.2" + denque "1.4.1" + fs-extra "8.1.0" + fs.notify "0.0.4" + hash-sum "2.0.0" + https-proxy-agent "5.0.0" + iconv-lite "0.5.1" + is-utf8 "0.2.1" + js-yaml "3.13.1" + media-typer "1.1.0" + mqtt "2.18.8" + multer "1.4.2" + mustache "4.0.0" + on-headers "1.0.2" + raw-body "2.4.1" + request "2.88.0" + ws "6.2.1" + xml2js "0.4.23" + +"@node-red/registry@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@node-red/registry/-/registry-1.0.4.tgz#781e782797525ec1c9626d321d52a905b57fbe8d" + integrity sha512-vPKxglgpm1ZDxQd7385iYmZZ6VRZ+1v69fllGZDkhOZi5CVL/GwZ/G93fWyuO8g51fWHOu2qjGgaf7IfJ0iHhA== + dependencies: + "@node-red/util" "1.0.4" + semver "6.3.0" + uglify-js "3.8.0" + when "3.7.8" + +"@node-red/runtime@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@node-red/runtime/-/runtime-1.0.4.tgz#182ea0f23edf4c7f8e63bc9e7ed847906e3c4c32" + integrity sha512-cbi5hd+LPERQpo0BuHYf67YPY+Z3hu+tDmRkEFfvDEgTz6qgiXg6FteMcWNx9a1dpt+30HuNhVPFAE8oa+L/Ug== + dependencies: + "@node-red/registry" "1.0.4" + "@node-red/util" "1.0.4" + clone "2.1.2" + express "4.17.1" + fs-extra "8.1.0" + json-stringify-safe "5.0.1" + when "3.7.8" + +"@node-red/util@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@node-red/util/-/util-1.0.4.tgz#747b2cfddb1b0417bd3ee4d5a33acb318e403c72" + integrity sha512-/+aj0C71TtoD2NwOU/J69Lw7skNk0mJp7LgpRfiMPoLuPASNuZdGbMZ2NjO7cvMfTtVvOG1APHnqT9dDyR3umg== + dependencies: + clone "2.1.2" + i18next "15.1.2" + json-stringify-safe "5.0.1" + jsonata "1.8.1" + when "3.7.8" + +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + +"@types/bn.js@^4.11.3", "@types/bn.js@^4.11.4": + version "4.11.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" + integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== + dependencies: + "@types/node" "*" + +"@types/node@*", "@types/node@^12.6.1": + version "12.12.31" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.31.tgz#d6b4f9645fee17f11319b508fb1001797425da51" + integrity sha512-T+wnJno8uh27G9c+1T+a1/WYCHzLeDqtsGJkoEdSp2X8RTh3oOCZQcUnjAx90CS8cmmADX51O0FI/tu9s0yssg== + +"@types/node@^10.12.18", "@types/node@^10.3.2": + version "10.17.17" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.17.tgz#7a183163a9e6ff720d86502db23ba4aade5999b8" + integrity sha512-gpNnRnZP3VWzzj5k3qrpRC6Rk3H/uclhAVo1aIvwzK5p5cOrs9yEyQ8H/HBsBY0u5rrWxXEiVPQ0dEB6pkjE8Q== + +"@web3-js/scrypt-shim@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@web3-js/scrypt-shim/-/scrypt-shim-0.1.0.tgz#0bf7529ab6788311d3e07586f7d89107c3bea2cc" + integrity sha512-ZtZeWCc/s0nMcdx/+rZwY1EcuRdemOK9ag21ty9UsHkFxsNb/AaoucUz0iPuyGe0Ku+PFuRmWZG7Z7462p9xPw== + dependencies: + scryptsy "^2.1.0" + semver "^6.3.0" + +"@web3-js/websocket@^1.0.29": + version "1.0.30" + resolved "https://registry.yarnpkg.com/@web3-js/websocket/-/websocket-1.0.30.tgz#9ea15b7b582cf3bf3e8bc1f4d3d54c0731a87f87" + integrity sha512-fDwrD47MiDrzcJdSeTLF75aCcxVVt8B1N74rA+vh2XCAvFy4tEWJjtnUtj2QG7/zlQ6g9cQ88bZFBxwd9/FmtA== + dependencies: + debug "^2.2.0" + es5-ext "^0.10.50" + nan "^2.14.0" + typedarray-to-buffer "^3.1.5" + yaeti "^0.0.6" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +aes-js@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" + integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= + +agent-base@6: + version "6.0.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.0.tgz#5d0101f19bbfaed39980b22ae866de153b93f09a" + integrity sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw== + dependencies: + debug "4" + +ajv@6.12.0, ajv@^6.5.5: + version "6.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" + integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +any-promise@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= + +append-field@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" + integrity sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY= + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async@~0.1.22: + version "0.1.22" + resolved "https://registry.yarnpkg.com/async/-/async-0.1.22.tgz#0fc1aaa088a0e3ef0ebe2d8831bab0dcf8845061" + integrity sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE= + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" + integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +basic-auth@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" + integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== + dependencies: + safe-buffer "5.1.2" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +bcrypt@3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-3.0.6.tgz#f607846df62d27e60d5e795612c4f67d70206eb2" + integrity sha512-taA5bCTfXe7FUjKroKky9EXpdhkVvhE5owfxfLYodbrAR1Ul3juLmIQmIQBK4L9a5BuUcE6cqmwT+Da20lF9tg== + dependencies: + nan "2.13.2" + node-pre-gyp "0.12.0" + +bcryptjs@2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" + integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms= + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bip66@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" + integrity sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI= + dependencies: + safe-buffer "^5.0.1" + +bl@^1.0.0, bl@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" + integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + +bluebird@^3.5.0: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@4.11.6: + version "4.11.6" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" + integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= + +bn.js@4.11.8, bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +body-parser@1.19.0, body-parser@^1.16.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + 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.17" + +boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-to-arraybuffer@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" + integrity sha1-YGSkD6dutDxyOrqe+PbhIW0QURo= + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^5.0.5, buffer@^5.2.1: + version "5.5.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.5.0.tgz#9c3caa3d623c33dd1c7ef584b89b88bf9c9bc1ce" + integrity sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +busboy@^0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" + integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM= + dependencies: + dicer "0.2.5" + readable-stream "1.1.x" + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + +callback-stream@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/callback-stream/-/callback-stream-1.1.0.tgz#4701a51266f06e06eaa71fc17233822d875f4908" + integrity sha1-RwGlEmbwbgbqpx/BcjOCLYdfSQg= + dependencies: + inherits "^2.0.1" + readable-stream "> 1.0.0 < 3.0.0" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +cheerio@0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" + integrity sha1-qbqoYKP5tZWmuBsahocxIe06Jp4= + dependencies: + css-select "~1.2.0" + dom-serializer "~0.1.0" + entities "~1.1.1" + htmlparser2 "^3.9.1" + lodash.assignin "^4.0.9" + lodash.bind "^4.1.4" + lodash.defaults "^4.0.1" + lodash.filter "^4.4.0" + lodash.flatten "^4.2.0" + lodash.foreach "^4.3.0" + lodash.map "^4.4.0" + lodash.merge "^4.4.0" + lodash.pick "^4.2.1" + lodash.reduce "^4.4.0" + lodash.reject "^4.4.0" + lodash.some "^4.4.0" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +clone@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@~2.20.3: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@~2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ= + dependencies: + graceful-readlink ">= 1.0.0" + +commist@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/commist/-/commist-1.1.0.tgz#17811ec6978f6c15ee4de80c45c9beb77cee35d5" + integrity sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg== + dependencies: + leven "^2.1.0" + minimist "^1.1.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.2, concat-stream@^1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@1.0.4, content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-parser@1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.4.tgz#e6363de4ea98c3def9697b93421c09f30cf5d188" + integrity sha512-lo13tqF3JEtFO7FyA49CqbhaFkskRJ0u/UAiINgrIXeRCY41c88/zxtrECl8AKH3B0hj9q10+h3Kt8I7KlW4tw== + dependencies: + cookie "0.3.1" + cookie-signature "1.0.6" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +cookiejar@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" + integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cors@2.8.5, cors@^2.8.1: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cron@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/cron/-/cron-1.8.2.tgz#4ac5e3c55ba8c163d84f3407bde94632da8370ce" + integrity sha512-Gk2c4y6xKEO8FSAUTklqtfSr7oTq0CiPQeLBG5Fl0qoXpZyMcj1SG59YL+hqq04bu6/IuEA7lMkYDAplQNKkyg== + dependencies: + moment-timezone "^0.5.x" + +crypto-browserify@3.12.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-select@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-what@2.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +debug@2.6.9, debug@2.x.x, debug@^2.2.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@4: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +debug@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decompress-response@^3.2.0, decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" + integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== + dependencies: + file-type "^5.2.0" + is-stream "^1.1.0" + tar-stream "^1.5.2" + +decompress-tarbz2@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" + integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== + dependencies: + decompress-tar "^4.1.0" + file-type "^6.1.0" + is-stream "^1.1.0" + seek-bzip "^1.0.5" + unbzip2-stream "^1.0.9" + +decompress-targz@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" + integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== + dependencies: + decompress-tar "^4.1.1" + file-type "^5.2.0" + is-stream "^1.1.0" + +decompress-unzip@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" + integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k= + dependencies: + file-type "^3.8.0" + get-stream "^2.2.0" + pify "^2.3.0" + yauzl "^2.4.2" + +decompress@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.0.tgz#7aedd85427e5a92dacfe55674a7c505e96d01f9d" + integrity sha1-eu3YVCflqS2s/lVnSnxQXpbQH50= + dependencies: + decompress-tar "^4.0.0" + decompress-tarbz2 "^4.0.0" + decompress-targz "^4.0.0" + decompress-unzip "^4.0.1" + graceful-fs "^4.1.10" + make-dir "^1.0.0" + pify "^2.3.0" + strip-dirs "^2.0.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +denque@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/denque/-/denque-1.4.1.tgz#6744ff7641c148c3f8a69c307e51235c1f4a37cf" + integrity sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +depd@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +dicer@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" + integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8= + dependencies: + readable-stream "1.1.x" + streamsearch "0.1.2" + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-serializer@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" + integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== + dependencies: + domelementtype "^1.3.0" + entities "^1.1.1" + +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= + +domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +drbg.js@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b" + integrity sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs= + dependencies: + browserify-aes "^1.0.6" + create-hash "^1.1.2" + create-hmac "^1.1.4" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplexify@^3.5.1, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +elliptic@6.3.3: + version "6.3.3" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.3.tgz#5482d9646d54bcb89fd7d994fc9e2e9568876e3f" + integrity sha1-VILZZG1UvLif19mU/J4ulWiHbj8= + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + inherits "^2.0.1" + +elliptic@^6.0.0, elliptic@^6.4.0, elliptic@^6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" + integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +entities@^1.1.1, entities@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" + integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== + +es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@~0.10.14: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@~2.0.1, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-map@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-symbol@^3.1.1, es6-symbol@~3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eth-ens-namehash@2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf" + integrity sha1-IprEbsqG1S4MmR58sq74P/D2i88= + dependencies: + idna-uts46-hx "^2.3.1" + js-sha3 "^0.5.7" + +eth-lib@0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.7.tgz#2f93f17b1e23aec3759cd4a3fe20c1286a3fc1ca" + integrity sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco= + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + xhr-request-promise "^0.1.2" + +eth-lib@^0.1.26: + version "0.1.29" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.29.tgz#0c11f5060d42da9f931eab6199084734f4dbd1d9" + integrity sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + nano-json-stream-parser "^0.1.2" + servify "^0.1.12" + ws "^3.0.0" + xhr-request-promise "^0.1.2" + +eth-lib@^0.2.8: + version "0.2.8" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" + integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + xhr-request-promise "^0.1.2" + +ethereum-bloom-filters@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.6.tgz#9cdebb3ec20de96ec4a434c6bad6ea5a513037aa" + integrity sha512-dE9CGNzgOOsdh7msZirvv8qjHtnHpvBlKe2647kM8v+yeF71IRso55jpojemvHV+jMjr48irPWxMRaHuOWzAFA== + dependencies: + js-sha3 "^0.8.0" + +ethereumjs-common@^1.3.2, ethereumjs-common@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.0.tgz#d3e82fc7c47c0cef95047f431a99485abc9bb1cd" + integrity sha512-SZOjgK1356hIY7MRj3/ma5qtfr/4B5BL+G4rP/XSMYr2z1H5el4RX5GReYCKmQmYI/nSBmRnwrZ17IfHuG0viQ== + +ethereumjs-tx@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz#5dfe7688bf177b45c9a23f86cf9104d47ea35fed" + integrity sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw== + dependencies: + ethereumjs-common "^1.5.0" + ethereumjs-util "^6.0.0" + +ethereumjs-util@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz#23ec79b2488a7d041242f01e25f24e5ad0357960" + integrity sha512-vb0XN9J2QGdZGIEKG2vXM+kUdEivUfU6Wmi5y0cg+LRhDYKnXIZ/Lz7XjFbHRR9VIKq2lVGLzGBkA++y2nOdOQ== + dependencies: + "@types/bn.js" "^4.11.3" + bn.js "^4.11.0" + create-hash "^1.1.2" + ethjs-util "0.1.6" + keccak "^2.0.0" + rlp "^2.2.3" + secp256k1 "^3.0.1" + +ethers@4.0.0-beta.3: + version "4.0.0-beta.3" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.0-beta.3.tgz#15bef14e57e94ecbeb7f9b39dd0a4bd435bc9066" + integrity sha512-YYPogooSknTwvHg3+Mv71gM/3Wcrx+ZpCzarBj3mqs9njjRkrOo2/eufzhHloOCo3JSoNI4TQJJ6yU5ABm3Uog== + dependencies: + "@types/node" "^10.3.2" + aes-js "3.0.0" + bn.js "^4.4.0" + elliptic "6.3.3" + hash.js "1.1.3" + js-sha3 "0.5.7" + scrypt-js "2.0.3" + setimmediate "1.0.4" + uuid "2.0.1" + xmlhttprequest "1.8.0" + +ethjs-unit@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" + integrity sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk= + dependencies: + bn.js "4.11.6" + number-to-bn "1.7.0" + +ethjs-util@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" + integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== + dependencies: + is-hex-prefixed "1.0.0" + strip-hex-prefix "1.0.0" + +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= + dependencies: + d "1" + es5-ext "~0.10.14" + +eventemitter3@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" + integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +express-session@1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.0.tgz#9b50dbb5e8a03c3537368138f072736150b7f9b3" + integrity sha512-t4oX2z7uoSqATbMfsxWMbNjAL0T5zpvcJCk3Z9wnPPN7ibddhnmDZXHfEcoBMG2ojKXZoCyPMc5FbtK+G7SoDg== + dependencies: + cookie "0.4.0" + 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.0" + uid-safe "~2.1.5" + +express@4.17.1, express@^4.14.0: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" + integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== + dependencies: + type "^2.0.0" + +extend@^3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= + dependencies: + pend "~1.2.0" + +file-type@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= + +file-type@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" + integrity sha1-LdvqfHP/42No365J3DOMBYwritY= + +file-type@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + 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" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^1.2.5: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + +fs.notify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/fs.notify/-/fs.notify-0.0.4.tgz#63284d45a34b52ce60088a6ddbec5b776d3c013d" + integrity sha1-YyhNRaNLUs5gCIpt2+xbd208AT0= + dependencies: + async "~0.1.22" + retry "~0.6.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +get-stream@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4= + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" + integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== + dependencies: + pump "^3.0.0" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-stream@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" + integrity sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ= + dependencies: + extend "^3.0.0" + glob "^7.1.1" + glob-parent "^3.1.0" + is-negated-glob "^1.0.0" + ordered-read-streams "^1.0.0" + pumpify "^1.3.5" + readable-stream "^2.1.5" + remove-trailing-separator "^1.0.1" + to-absolute-glob "^2.0.0" + unique-stream "^2.0.2" + +glob@^7.1.1, glob@^7.1.3: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global@~4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= + dependencies: + min-document "^2.19.0" + process "~0.5.1" + +got@9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +got@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" + integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== + dependencies: + decompress-response "^3.2.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-plain-obj "^1.1.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + p-cancelable "^0.3.0" + p-timeout "^1.1.1" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + url-parse-lax "^1.0.0" + url-to-options "^1.0.1" + +graceful-fs@^4.1.10, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" + integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.0, har-validator@~5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== + dependencies: + has-symbol-support-x "^1.4.1" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash-sum@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" + integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg== + +hash.js@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" + integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.0" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +help-me@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/help-me/-/help-me-1.1.0.tgz#8f2d508d0600b4a456da2f086556e7e5c056a3c6" + integrity sha1-jy1QjQYAtKRW2i8IZVbn5cBWo8Y= + dependencies: + callback-stream "^1.0.2" + glob-stream "^6.1.0" + through2 "^2.0.1" + xtend "^4.0.0" + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +htmlparser2@^3.9.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@1.7.3, http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-https@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" + integrity sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs= + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-proxy-agent@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +i18next@15.1.2: + version "15.1.2" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-15.1.2.tgz#635b7bc688cf36620cab8fa1c3af97817a47f95a" + integrity sha512-98ELn/dqep00DQ/v1E1gpM21HNN6nqU3mS85mYKd9P7lXrhfUcuysPaa3HviKSFb3WPdjf7avuAST3P0dhNp/A== + dependencies: + "@babel/runtime" "^7.3.1" + +iconv-lite@0.4.24, iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.5.1.tgz#b2425d3c7b18f7219f2ca663d103bddb91718d64" + integrity sha512-ONHr16SQvKZNSqjQT9gy5z24Jw+uqfO02/ngBSBoqChZ+W8qXX7GPRa1RoUnzGADw8K63R1BXUMzarCVQBpY8Q== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +idna-uts46-hx@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz#a1dc5c4df37eee522bf66d969cc980e00e8711f9" + integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA== + dependencies: + punycode "2.1.0" + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +ignore-walk@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" + integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== + dependencies: + minimatch "^3.0.4" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + +is-extglob@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-function@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" + integrity sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU= + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-hex-prefixed@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" + integrity sha1-fY035q135dEnFIkTxXPggtd39VQ= + +is-natural-number@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" + integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg= + +is-negated-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" + integrity sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI= + +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= + +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== + dependencies: + is-unc-path "^1.0.0" + +is-retry-allowed@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + +is-stream@^1.0.0, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-typedarray@^1.0.0, is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== + dependencies: + unc-path-regex "^0.1.2" + +is-utf8@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-windows@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + +js-sha3@0.5.7, js-sha3@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" + integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= + +js-sha3@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + +js-yaml@3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stringify-safe@5.0.1, json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +jsonata@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/jsonata/-/jsonata-1.8.1.tgz#75f942971a1fe1019c86690e1ddc2af7e21dbec9" + integrity sha512-Lw1ApNtYH9i/lWBuRSm1I/xfhPyTvlVslVIaGLW/bxFimxQYzQx2y3+DNRmbx5mmCmRb+bCLdIJasEFyb+aUlQ== + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +keccak@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-2.1.0.tgz#734ea53f2edcfd0f42cdb8d5f4c358fef052752b" + integrity sha512-m1wbJRTo+gWbctZWay9i26v5fFnYkOn7D5PCxJ3fZUGUEb49dE1Pm4BREUYCt/aoO6di7jeoGmhvqN9Nzylm3Q== + dependencies: + bindings "^1.5.0" + inherits "^2.0.4" + nan "^2.14.0" + safe-buffer "^5.2.0" + +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + +leven@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= + +lodash.assignin@^4.0.9: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" + integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI= + +lodash.bind@^4.1.4: + version "4.2.1" + resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" + integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU= + +lodash.defaults@^4.0.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= + +lodash.filter@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" + integrity sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4= + +lodash.flatten@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= + +lodash.foreach@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" + integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM= + +lodash.map@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" + integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= + +lodash.merge@^4.4.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.pick@^4.2.1: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" + integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= + +lodash.reduce@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" + integrity sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs= + +lodash.reject@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" + integrity sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU= + +lodash.some@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" + integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= + +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lru-cache@^4.0.3: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +media-typer@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.0.tgz#6ab74b8f2d3320f2064b2a87a38e7931ff3a5561" + integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== + +memorystore@1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/memorystore/-/memorystore-1.6.2.tgz#66e7190d7d54885372c1aec3e256b92e3bf1d163" + integrity sha512-HQM+cZB/kY1+jj57It22FsptJ3nuZRYxnwh3rWZEvDZO1zuzhIrX9uyFcjP9AhFQvM5WS6vZKtn3veohDH4S7w== + dependencies: + debug "3.1.0" + lru-cache "^4.0.3" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.43.0: + version "1.43.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" + integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== + +mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.26" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" + integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== + dependencies: + mime-db "1.43.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" + integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== + +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.1.0, minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + +mkdirp-promise@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" + integrity sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE= + dependencies: + mkdirp "*" + +mkdirp@*: + version "1.0.3" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.3.tgz#4cf2e30ad45959dddea53ad97d518b6c8205e1ea" + integrity sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g== + +mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.4.tgz#fd01504a6797ec5c9be81ff43d204961ed64a512" + integrity sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw== + dependencies: + minimist "^1.2.5" + +mock-fs@^4.1.0: + version "4.11.0" + resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.11.0.tgz#0828107e4b843a6ba855ecebfe3c6e073b69db92" + integrity sha512-Yp4o3/ZA15wsXqJTT+R+9w2AYIkD1i80Lds47wDbuUhOvQvm+O2EfjFZSz0pMgZZSPHRhGxgcd2+GL4+jZMtdw== + +moment-timezone@^0.5.x: + version "0.5.28" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.28.tgz#f093d789d091ed7b055d82aa81a82467f72e4338" + integrity sha512-TDJkZvAyKIVWg5EtVqRzU97w0Rb0YVbfpqyjgu6GwXCAohVRqwZjf4fOzDE6p1Ch98Sro/8hQQi65WDXW5STPw== + dependencies: + moment ">= 2.9.0" + +"moment@>= 2.9.0": + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== + +mqtt-packet@^5.6.0: + version "5.6.1" + resolved "https://registry.yarnpkg.com/mqtt-packet/-/mqtt-packet-5.6.1.tgz#8ecafce091f5af460664268a22b22091c8915f7b" + integrity sha512-eaF9rO2uFrIYEHomJxziuKTDkbWW5psLBaIGCazQSKqYsTaB3n4SpvJ1PexKaDBiPnMLPIFWBIiTYT3IfEJfww== + dependencies: + bl "^1.2.1" + inherits "^2.0.3" + process-nextick-args "^2.0.0" + safe-buffer "^5.1.0" + +mqtt@2.18.8: + version "2.18.8" + resolved "https://registry.yarnpkg.com/mqtt/-/mqtt-2.18.8.tgz#9d213ccab92151accfb21ee8c0860dc6866ab259" + integrity sha512-3h6oHlPY/yWwtC2J3geraYRtVVoRM6wdI+uchF4nvSSafXPZnaKqF8xnX+S22SU/FcgEAgockVIlOaAX3fkMpA== + dependencies: + commist "^1.0.0" + concat-stream "^1.6.2" + end-of-stream "^1.4.1" + es6-map "^0.1.5" + help-me "^1.0.1" + inherits "^2.0.3" + minimist "^1.2.0" + mqtt-packet "^5.6.0" + pump "^3.0.0" + readable-stream "^2.3.6" + reinterval "^1.1.0" + split2 "^2.1.1" + websocket-stream "^5.1.2" + xtend "^4.0.1" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +multer@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.2.tgz#2f1f4d12dbaeeba74cb37e623f234bf4d3d2057a" + integrity sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg== + dependencies: + append-field "^1.0.0" + busboy "^0.2.11" + concat-stream "^1.5.2" + mkdirp "^0.5.1" + object-assign "^4.1.1" + on-finished "^2.3.0" + type-is "^1.6.4" + xtend "^4.0.0" + +mustache@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.0.0.tgz#7f02465dbb5b435859d154831c032acdfbbefb31" + integrity sha512-FJgjyX/IVkbXBXYUwH+OYwQKqWpFPLaLVESd70yHjSDunwzV2hZOoTBvPf4KLoxesUzzyfTH6F784Uqd7Wm5yA== + +nan@2.13.2: + version "2.13.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" + integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== + +nan@^2.14.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + +nano-json-stream-parser@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" + integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18= + +needle@^2.2.1: + version "2.3.3" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.3.3.tgz#a041ad1d04a871b0ebb666f40baaf1fb47867117" + integrity sha512-EkY0GeSq87rWp1hoq/sH/wnTWgFVhYlnIkbJ0YJFfRgEFlz2RraCjBpFQ+vrEgEdp0ThfyHADmkChEhcb7PKyw== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +node-pre-gyp@0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" + integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +node-red-node-rbe@^0.2.6: + version "0.2.8" + resolved "https://registry.yarnpkg.com/node-red-node-rbe/-/node-red-node-rbe-0.2.8.tgz#b421a7e5a00e4b8f4d3a7101b43911444c40973b" + integrity sha512-v2pZOn/raE87JLB86l5fH2JkU7uthqzV3lLI9WcL+fA+vDlg5iN2p/eQfhUy1DhgEmqmGrLu03h5efv+Sly5Vg== + +node-red-node-tail@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/node-red-node-tail/-/node-red-node-tail-0.1.1.tgz#eb14c39119d05fb0304a0a2e485911432c745ba3" + integrity sha512-j1g/VtSCI2tBrBnCD+u8iSo9tH0nvn70k1O1SxkHk3+qx7tHUyOKQc7wNc4rUs9J1PkGngUC3qEDd5cL7Z/klg== + dependencies: + tail "^2.0.3" + +node-red@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/node-red/-/node-red-1.0.4.tgz#214e98f5ebb4d88b3e3a8df19a587bcc94230320" + integrity sha512-7cRGr69ibl7vnEMWEO2qHhO4L6ft2XsySoE+mMSW7h2tODNTNECelCQtTA+kYfX1wlFS3axu52Y2Br0AV5D+ww== + dependencies: + "@node-red/editor-api" "1.0.4" + "@node-red/nodes" "1.0.4" + "@node-red/runtime" "1.0.4" + "@node-red/util" "1.0.4" + basic-auth "2.0.1" + bcryptjs "2.4.3" + express "4.17.1" + fs-extra "8.1.0" + node-red-node-rbe "^0.2.6" + node-red-node-tail "^0.1.0" + nopt "4.0.1" + semver "6.3.0" + optionalDependencies: + bcrypt "3.0.6" + +nopt@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + dependencies: + abbrev "1" + osenv "^0.1.4" + +nopt@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" + integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-url@^4.1.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" + integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== + +npm-bundled@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" + integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== + dependencies: + npm-normalize-package-bin "^1.0.1" + +npm-normalize-package-bin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== + +npm-packlist@^1.1.6: + version "1.4.8" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" + integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + npm-normalize-package-bin "^1.0.1" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +nth-check@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +number-to-bn@1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" + integrity sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA= + dependencies: + bn.js "4.11.6" + strip-hex-prefix "1.0.0" + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +oauth2orize@1.11.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/oauth2orize/-/oauth2orize-1.11.0.tgz#793cef251d45ebdeac32ae40a8b6814faab1d483" + integrity sha1-eTzvJR1F696sMq5AqLaBT6qx1IM= + dependencies: + debug "2.x.x" + uid2 "0.0.x" + utils-merge "1.x.x" + +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +oboe@2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.4.tgz#20c88cdb0c15371bb04119257d4fdd34b0aa49f6" + integrity sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY= + dependencies: + http-https "^1.0.0" + +on-finished@^2.3.0, on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@1.0.2, on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +ordered-read-streams@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" + integrity sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4= + dependencies: + readable-stream "^2.0.1" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-tmpdir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-cancelable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" + integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== + +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-timeout@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" + integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y= + dependencies: + p-finally "^1.0.0" + +parse-asn1@^5.0.0: + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-headers@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.3.tgz#5e8e7512383d140ba02f0c7aa9f49b4399c92515" + integrity sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA== + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +passport-http-bearer@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/passport-http-bearer/-/passport-http-bearer-1.0.1.tgz#147469ea3669e2a84c6167ef99dbb77e1f0098a8" + integrity sha1-FHRp6jZp4qhMYWfvmdu3fh8AmKg= + dependencies: + passport-strategy "1.x.x" + +passport-oauth2-client-password@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/passport-oauth2-client-password/-/passport-oauth2-client-password-0.1.2.tgz#4f378b678b92d16dbbd233a6c706520093e561ba" + integrity sha1-TzeLZ4uS0W270jOmxwZSAJPlYbo= + dependencies: + passport-strategy "1.x.x" + +passport-strategy@1.x.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" + integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= + +passport@0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.1.tgz#941446a21cb92fc688d97a0861c38ce9f738f270" + integrity sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg== + dependencies: + passport-strategy "1.x.x" + pause "0.0.1" + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +pause@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= + +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.1" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +psl@^1.1.24, psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.5: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + integrity sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0= + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +random-bytes@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" + integrity sha1-T2ih3Arli9P7lYSMMDJNt11kNgs= + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +raw-body@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" + integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== + dependencies: + bytes "3.1.0" + http-errors "1.7.3" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +readable-stream@1.1.x: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +"readable-stream@> 1.0.0 < 3.0.0", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.1.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +regenerator-runtime@^0.13.4: + version "0.13.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" + integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== + +reinterval@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/reinterval/-/reinterval-1.1.0.tgz#3361ecfa3ca6c18283380dd0bb9546f390f5ece7" + integrity sha1-M2Hs+jymwYKDOA3Qu5VG85D17Oc= + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +request@2.88.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +request@^2.79.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + +retry@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.6.1.tgz#fdc90eed943fde11b893554b8cc63d0e899ba918" + integrity sha1-/ckO7ZQ/3hG4k1VLjMY9DombqRg= + +rimraf@^2.6.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +rlp@^2.2.3: + version "2.2.4" + resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.4.tgz#d6b0e1659e9285fc509a5d169a9bd06f704951c1" + integrity sha512-fdq2yYCWpAQBhwkZv+Z8o/Z4sPmYm1CUq6P7n6lVTOdb949CnqA0sndXal5C1NleSVSZm6q5F3iEbauyVln/iw== + dependencies: + bn.js "^4.11.1" + +rxjs@^6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" + integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sax@>=0.6.0, sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +scrypt-js@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.3.tgz#bb0040be03043da9a012a2cea9fc9f852cfc87d4" + integrity sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q= + +scryptsy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-2.1.0.tgz#8d1e8d0c025b58fdd25b6fa9a0dc905ee8faa790" + integrity sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w== + +secp256k1@^3.0.1: + version "3.8.0" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.8.0.tgz#28f59f4b01dbee9575f56a47034b7d2e3b3b352d" + integrity sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw== + dependencies: + bindings "^1.5.0" + bip66 "^1.1.5" + bn.js "^4.11.8" + create-hash "^1.2.0" + drbg.js "^1.0.1" + elliptic "^6.5.2" + nan "^2.14.0" + safe-buffer "^5.1.2" + +seek-bzip@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc" + integrity sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w= + dependencies: + commander "~2.8.1" + +semver@6.3.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^5.3.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + 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.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +servify@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" + integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== + dependencies: + body-parser "^1.16.0" + cors "^2.8.1" + express "^4.14.0" + request "^2.79.0" + xhr "^2.3.3" + +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +setimmediate@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" + integrity sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48= + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +signal-exit@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +simple-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" + integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= + +simple-get@^2.7.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" + integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw== + dependencies: + decompress-response "^3.3.0" + once "^1.3.1" + simple-concat "^1.0.0" + +source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +split2@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" + integrity sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw== + dependencies: + through2 "^2.0.2" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +streamsearch@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-dirs@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" + integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== + dependencies: + is-natural-number "^4.0.1" + +strip-hex-prefix@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" + integrity sha1-DF8VX+8RUTczd96du1iNoFUA428= + dependencies: + is-hex-prefixed "1.0.0" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +swarm-js@0.1.39: + version "0.1.39" + resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.39.tgz#79becb07f291d4b2a178c50fee7aa6e10342c0e8" + integrity sha512-QLMqL2rzF6n5s50BptyD6Oi0R1aWlJC5Y17SRIVXRj6OR1DRIPM7nepvrxxkjA1zNzFz6mUOMjfeqeDaWB7OOg== + dependencies: + bluebird "^3.5.0" + buffer "^5.0.5" + decompress "^4.0.0" + eth-lib "^0.1.26" + fs-extra "^4.0.2" + got "^7.1.0" + mime-types "^2.1.16" + mkdirp-promise "^5.0.1" + mock-fs "^4.1.0" + setimmediate "^1.0.5" + tar "^4.0.2" + xhr-request-promise "^0.1.2" + +tail@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/tail/-/tail-2.0.3.tgz#37567adc4624a70b35f1d146c3376fa3d6ef7c04" + integrity sha512-s9NOGkLqqiDEtBttQZI7acLS8ycYK5sTlDwNjGnpXG9c8AWj0cfAtwEIzo/hVRMMiC5EYz+bXaJWC1u1u0GPpQ== + +tar-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + +tar@^4, tar@^4.0.2: + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.8.6" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" + +through2-filter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254" + integrity sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA== + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2@^2.0.1, through2@^2.0.2, through2@~2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +timed-out@^4.0.0, timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + +to-absolute-glob@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" + integrity sha1-GGX0PZ50sIItufFFt4z/fQ98hJs= + dependencies: + is-absolute "^1.0.0" + is-negated-glob "^1.0.0" + +to-buffer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== + +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tslib@^1.9.0: + version "1.11.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" + integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-is@^1.6.4, type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" + integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +uglify-js@3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.8.0.tgz#f3541ae97b2f048d7e7e3aa4f39fd8a1f5d7a805" + integrity sha512-ugNSTT8ierCsDHso2jkBHXYrU8Y5/fY2ZUprfrJUiD7YpuFvV4jODLFmb3h4btQjqr5Nh4TX4XtgDfCU1WdioQ== + dependencies: + commander "~2.20.3" + source-map "~0.6.1" + +uid-safe@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a" + integrity sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA== + dependencies: + random-bytes "~1.0.0" + +uid2@0.0.x: + version "0.0.3" + resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" + integrity sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I= + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + +unbzip2-stream@^1.0.9: + version "1.3.3" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz#d156d205e670d8d8c393e1c02ebd506422873f6a" + integrity sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + +unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= + +underscore@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" + integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg== + +unique-stream@^2.0.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" + integrity sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== + dependencies: + json-stable-stringify-without-jsonify "^1.0.1" + through2-filter "^3.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +url-set-query@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" + integrity sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk= + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= + +utf8@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" + integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +utils-merge@1.0.1, utils-merge@1.x.x: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" + integrity sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w= + +uuid@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +web3-bzz@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.6.tgz#0b88c0b96029eaf01b10cb47c4d5f79db4668883" + integrity sha512-9NiHLlxdI1XeFtbPJAmi2jnnIHVF+GNy517wvOS72P7ZfuJTPwZaSNXfT01vWgPPE9R96/uAHDWHOg+T4WaDQQ== + dependencies: + "@types/node" "^10.12.18" + got "9.6.0" + swarm-js "0.1.39" + underscore "1.9.1" + +web3-core-helpers@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.6.tgz#7aacd25bf8015adcdfc0f3243d0dcfdff0373f7d" + integrity sha512-gYKWmC2HmO7RcDzpo4L1K8EIoy5L8iubNDuTC6q69UxczwqKF/Io0kbK/1Z10Av++NlzOSiuyGp2gc4t4UOsDw== + dependencies: + underscore "1.9.1" + web3-eth-iban "1.2.6" + web3-utils "1.2.6" + +web3-core-method@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.6.tgz#f5a3e4d304abaf382923c8ab88ec8eeef45c1b3b" + integrity sha512-r2dzyPEonqkBg7Mugq5dknhV5PGaZTHBZlS/C+aMxNyQs3T3eaAsCTqlQDitwNUh/sUcYPEGF0Vo7ahYK4k91g== + dependencies: + underscore "1.9.1" + web3-core-helpers "1.2.6" + web3-core-promievent "1.2.6" + web3-core-subscriptions "1.2.6" + web3-utils "1.2.6" + +web3-core-promievent@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.6.tgz#b1550a3a4163e48b8b704c1fe4b0084fc2dad8f5" + integrity sha512-km72kJef/qtQNiSjDJJVHIZvoVOm6ytW3FCYnOcCs7RIkviAb5JYlPiye0o4pJOLzCXYID7DK7Q9bhY8qWb1lw== + dependencies: + any-promise "1.3.0" + eventemitter3 "3.1.2" + +web3-core-requestmanager@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.6.tgz#5808c0edc0d6e2991a87b65508b3a1ab065b68ec" + integrity sha512-QU2cbsj9Dm0r6om40oSwk8Oqbp3wTa08tXuMpSmeOTkGZ3EMHJ1/4LiJ8shwg1AvPMrKVU0Nri6+uBNCdReZ+g== + dependencies: + underscore "1.9.1" + web3-core-helpers "1.2.6" + web3-providers-http "1.2.6" + web3-providers-ipc "1.2.6" + web3-providers-ws "1.2.6" + +web3-core-subscriptions@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.6.tgz#9d44189e2321f8f1abc31f6c09103b5283461b57" + integrity sha512-M0PzRrP2Ct13x3wPulFtc5kENH4UtnPxO9YxkfQlX2WRKENWjt4Rfq+BCVGYEk3rTutDfWrjfzjmqMRvXqEY5Q== + dependencies: + eventemitter3 "3.1.2" + underscore "1.9.1" + web3-core-helpers "1.2.6" + +web3-core@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.6.tgz#bb42a1d7ae49a7258460f0d95ddb00906f59ef92" + integrity sha512-y/QNBFtr5cIR8vxebnotbjWJpOnO8LDYEAzZjeRRUJh2ijmhjoYk7dSNx9ExgC0UCfNFRoNCa9dGRu/GAxwRlw== + dependencies: + "@types/bn.js" "^4.11.4" + "@types/node" "^12.6.1" + web3-core-helpers "1.2.6" + web3-core-method "1.2.6" + web3-core-requestmanager "1.2.6" + web3-utils "1.2.6" + +web3-eth-abi@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.6.tgz#b495383cc5c0d8e2857b26e7fe25606685983b25" + integrity sha512-w9GAyyikn8nSifSDZxAvU9fxtQSX+W2xQWMmrtTXmBGCaE4/ywKOSPAO78gq8AoU4Wq5yqVGKZLLbfpt7/sHlA== + dependencies: + ethers "4.0.0-beta.3" + underscore "1.9.1" + web3-utils "1.2.6" + +web3-eth-accounts@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.6.tgz#a1ba4bf75fa8102a3ec6cddd0eccd72462262720" + integrity sha512-cDVtonHRgzqi/ZHOOf8kfCQWFEipcfQNAMzXIaKZwc0UUD9mgSI5oJrN45a89Ze+E6Lz9m77cDG5Ax9zscSkcw== + dependencies: + "@web3-js/scrypt-shim" "^0.1.0" + any-promise "1.3.0" + crypto-browserify "3.12.0" + eth-lib "^0.2.8" + ethereumjs-common "^1.3.2" + ethereumjs-tx "^2.1.1" + underscore "1.9.1" + uuid "3.3.2" + web3-core "1.2.6" + web3-core-helpers "1.2.6" + web3-core-method "1.2.6" + web3-utils "1.2.6" + +web3-eth-contract@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.6.tgz#39111543960035ed94c597a239cf5aa1da796741" + integrity sha512-ak4xbHIhWgsbdPCkSN+HnQc1SH4c856y7Ly+S57J/DQVzhFZemK5HvWdpwadJrQTcHET3ZeId1vq3kmW7UYodw== + dependencies: + "@types/bn.js" "^4.11.4" + underscore "1.9.1" + web3-core "1.2.6" + web3-core-helpers "1.2.6" + web3-core-method "1.2.6" + web3-core-promievent "1.2.6" + web3-core-subscriptions "1.2.6" + web3-eth-abi "1.2.6" + web3-utils "1.2.6" + +web3-eth-ens@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.6.tgz#bf86a624c4c72bc59913c2345180d3ea947e110d" + integrity sha512-8UEqt6fqR/dji/jBGPFAyBs16OJjwi0t2dPWXPyGXmty/fH+osnXwWXE4HRUyj4xuafiM5P1YkXMsPhKEadjiw== + dependencies: + eth-ens-namehash "2.0.8" + underscore "1.9.1" + web3-core "1.2.6" + web3-core-helpers "1.2.6" + web3-core-promievent "1.2.6" + web3-eth-abi "1.2.6" + web3-eth-contract "1.2.6" + web3-utils "1.2.6" + +web3-eth-iban@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.6.tgz#0b22191fd1aa6e27f7ef0820df75820bfb4ed46b" + integrity sha512-TPMc3BW9Iso7H+9w+ytbqHK9wgOmtocyCD3PaAe5Eie50KQ/j7ThA60dGJnxItVo6yyRv5pZAYxPVob9x/fJlg== + dependencies: + bn.js "4.11.8" + web3-utils "1.2.6" + +web3-eth-personal@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.6.tgz#47a0a0657ec04dd77f95451a6869d4751d324b6b" + integrity sha512-T2NUkh1plY8d7wePXSoHnaiKOd8dLNFaQfgBl9JHU6S7IJrG9jnYD9bVxLEgRUfHs9gKf9tQpDf7AcPFdq/A8g== + dependencies: + "@types/node" "^12.6.1" + web3-core "1.2.6" + web3-core-helpers "1.2.6" + web3-core-method "1.2.6" + web3-net "1.2.6" + web3-utils "1.2.6" + +web3-eth@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.6.tgz#15a8c65fdde0727872848cae506758d302d8d046" + integrity sha512-ROWlDPzh4QX6tlGGGlAK6X4kA2n0/cNj/4kb0nNVWkRouGmYO0R8k6s47YxYHvGiXt0s0++FUUv5vAbWovtUQw== + dependencies: + underscore "1.9.1" + web3-core "1.2.6" + web3-core-helpers "1.2.6" + web3-core-method "1.2.6" + web3-core-subscriptions "1.2.6" + web3-eth-abi "1.2.6" + web3-eth-accounts "1.2.6" + web3-eth-contract "1.2.6" + web3-eth-ens "1.2.6" + web3-eth-iban "1.2.6" + web3-eth-personal "1.2.6" + web3-net "1.2.6" + web3-utils "1.2.6" + +web3-net@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.6.tgz#035ca0fbe55282fda848ca17ebb4c8966147e5ea" + integrity sha512-hsNHAPddrhgjWLmbESW0KxJi2GnthPcow0Sqpnf4oB6+/+ZnQHU9OsIyHb83bnC1OmunrK2vf9Ye2mLPdFIu3A== + dependencies: + web3-core "1.2.6" + web3-core-method "1.2.6" + web3-utils "1.2.6" + +web3-providers-http@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.6.tgz#3c7b1252751fb37e53b873fce9dbb6340f5e31d9" + integrity sha512-2+SaFCspb5f82QKuHB3nEPQOF9iSWxRf7c18fHtmnLNVkfG9SwLN1zh67bYn3tZGUdOI3gj8aX4Uhfpwx9Ezpw== + dependencies: + web3-core-helpers "1.2.6" + xhr2-cookies "1.1.0" + +web3-providers-ipc@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.6.tgz#adabab5ac66b3ff8a26c7dc97af3f1a6a7609701" + integrity sha512-b0Es+/GTZyk5FG3SgUDW+2/mBwJAXWt5LuppODptiOas8bB2khLjG6+Gm1K4uwOb+1NJGPt5mZZ8Wi7vibtQ+A== + dependencies: + oboe "2.1.4" + underscore "1.9.1" + web3-core-helpers "1.2.6" + +web3-providers-ws@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.6.tgz#3cecc49f7c99f07a75076d3c54247050bc4f7e11" + integrity sha512-20waSYX+gb5M5yKhug5FIwxBBvkKzlJH7sK6XEgdOx6BZ9YYamLmvg9wcRVtnSZO8hV/3cWenO/tRtTrHVvIgQ== + dependencies: + "@web3-js/websocket" "^1.0.29" + underscore "1.9.1" + web3-core-helpers "1.2.6" + +web3-shh@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.6.tgz#2492616da4cac32d4c7534b890f43bac63190c14" + integrity sha512-rouWyOOM6YMbLQd65grpj8BBezQfgNeRRX+cGyW4xsn6Xgu+B73Zvr6OtA/ftJwwa9bqHGpnLrrLMeWyy4YLUw== + dependencies: + web3-core "1.2.6" + web3-core-method "1.2.6" + web3-core-subscriptions "1.2.6" + web3-net "1.2.6" + +web3-utils@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.6.tgz#b9a25432da00976457fcc1094c4af8ac6d486db9" + integrity sha512-8/HnqG/l7dGmKMgEL9JeKPTtjScxOePTzopv5aaKFExPfaBrYRkgoMqhoowCiAl/s16QaTn4DoIF1QC4YsT7Mg== + dependencies: + bn.js "4.11.8" + eth-lib "0.2.7" + ethereum-bloom-filters "^1.0.6" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randombytes "^2.1.0" + underscore "1.9.1" + utf8 "3.0.0" + +web3@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.6.tgz#c497dcb14cdd8d6d9fb6b445b3b68ff83f8ccf68" + integrity sha512-tpu9fLIComgxGrFsD8LUtA4s4aCZk7px8UfcdEy6kS2uDi/ZfR07KJqpXZMij7Jvlq+cQrTAhsPSiBVvoMaivA== + dependencies: + "@types/node" "^12.6.1" + web3-bzz "1.2.6" + web3-core "1.2.6" + web3-eth "1.2.6" + web3-eth-personal "1.2.6" + web3-net "1.2.6" + web3-shh "1.2.6" + web3-utils "1.2.6" + +websocket-stream@^5.1.2: + version "5.5.2" + resolved "https://registry.yarnpkg.com/websocket-stream/-/websocket-stream-5.5.2.tgz#49d87083d96839f0648f5513bbddd581f496b8a2" + integrity sha512-8z49MKIHbGk3C4HtuHWDtYX8mYej1wWabjthC/RupM9ngeukU4IWoM46dgth1UOS/T4/IqgEdCDJuMe2039OQQ== + dependencies: + duplexify "^3.5.1" + inherits "^2.0.1" + readable-stream "^2.3.3" + safe-buffer "^5.1.2" + ws "^3.2.0" + xtend "^4.0.0" + +when@3.7.8: + version "3.7.8" + resolved "https://registry.yarnpkg.com/when/-/when-3.7.8.tgz#c7130b6a7ea04693e842cdc9e7a1f2aa39a39f82" + integrity sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I= + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + +ws@^3.0.0, ws@^3.2.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +xhr-request-promise@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz#343c44d1ee7726b8648069682d0f840c83b4261d" + integrity sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0= + dependencies: + xhr-request "^1.0.1" + +xhr-request@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" + integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== + dependencies: + buffer-to-arraybuffer "^0.0.5" + object-assign "^4.1.1" + query-string "^5.0.1" + simple-get "^2.7.0" + timed-out "^4.0.1" + url-set-query "^1.0.0" + xhr "^2.0.4" + +xhr2-cookies@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" + integrity sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg= + dependencies: + cookiejar "^2.1.1" + +xhr@^2.0.4, xhr@^2.3.3: + version "2.5.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd" + integrity sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ== + dependencies: + global "~4.3.0" + is-function "^1.0.1" + parse-headers "^2.0.0" + xtend "^4.0.0" + +xml2js@0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" + integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + +xmlhttprequest@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" + integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= + +xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yallist@^3.0.0, yallist@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yauzl@^2.4.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" diff --git a/packages/connector/.gitattributes b/packages/connector/.gitattributes new file mode 100644 index 0000000..c19f935 --- /dev/null +++ b/packages/connector/.gitattributes @@ -0,0 +1 @@ +/packages/node_modules/** linguist-generated=false diff --git a/packages/connector/.gitignore b/packages/connector/.gitignore new file mode 100644 index 0000000..c3fa962 --- /dev/null +++ b/packages/connector/.gitignore @@ -0,0 +1,24 @@ +.DS_store +.config.json +.dist +.jshintignore +.npm +.project +.sessions.json +.settings +.tern-project +*.backup +*_cred* +coverage +credentials.json +flows*.json +nodes/node-red-nodes/ +node_modules +public +locales/zz-ZZ +nodes/core/locales/zz-ZZ +!packages/node_modules +packages/node_modules/@node-red/editor-client/public +!test/**/node_modules +docs +!packages/node_modules/**/docs diff --git a/packages/connector/.jshintrc b/packages/connector/.jshintrc new file mode 100644 index 0000000..719eecb --- /dev/null +++ b/packages/connector/.jshintrc @@ -0,0 +1,19 @@ +{ + "asi": true, // allow missing semicolons + "curly": true, // require braces + "eqnull": true, // ignore ==null + //"eqeqeq": true, // enforce === + "freeze": true, // don't allow override + "indent": 4, // default indent of 4 + "forin": true, // require property filtering in "for in" loops + "immed": true, // require immediate functions to be wrapped in ( ) + "nonbsp": true, // warn on unexpected whitespace breaking chars + //"strict": true, // commented out for now as it causes 100s of warnings, but want to get there eventually + //"unused": true, // Check for unused functions and variables + "loopfunc": true, // allow functions to be defined in loops + //"expr": true, // allow ternery operator syntax... + "shadow": true, // allow variable shadowing (re-use of names...) + "sub": true, // don't warn that foo['bar'] should be written as foo.bar + "proto": true, // allow setting of __proto__ in node < v0.12, + "esversion": 6 // allow es6 +} diff --git a/packages/connector/.nodemonignore b/packages/connector/.nodemonignore new file mode 100644 index 0000000..612a1e1 --- /dev/null +++ b/packages/connector/.nodemonignore @@ -0,0 +1,4 @@ +/Gruntfile.js +/.git/* +*.backup +/public/* diff --git a/packages/connector/.travis.yml b/packages/connector/.travis.yml new file mode 100644 index 0000000..a101eec --- /dev/null +++ b/packages/connector/.travis.yml @@ -0,0 +1,11 @@ +sudo: false +language: node_js +matrix: + include: + - node_js: "12" + - node_js: "10" + script: + - ./node_modules/.bin/grunt && istanbul report text && ( cat coverage/lcov.info | $(npm get prefix)/bin/coveralls || true ) && rm -rf coverage + before_script: + - npm install -g istanbul coveralls + - node_js: "8" diff --git a/packages/connector/API.md b/packages/connector/API.md new file mode 100644 index 0000000..f349ea8 --- /dev/null +++ b/packages/connector/API.md @@ -0,0 +1,15 @@ +Node-RED Modules +--- + +Node-RED provides a set of node modules that implement different parts of the +application. + +Module | Description +-------|------- +[node-red](node-red.html) | the main module that pulls together all of the internal modules and provides the executable version of Node-RED +[@node-red/editor-api](@node-red_editor-api.html) | an Express application that serves the Node-RED editor and provides the Admin HTTP API +[@node-red/runtime](@node-red_runtime.html) | the core runtime of Node-RED +[@node-red/util](@node-red_util.html) | common utilities for the Node-RED runtime and editor modules +@node-red/registry | the internal node registry +@node-red/nodes | the default set of core nodes +@node-red/editor-client | the client-side resources of the Node-RED editor application diff --git a/packages/connector/CHANGELOG.md b/packages/connector/CHANGELOG.md new file mode 100644 index 0000000..7ea3845 --- /dev/null +++ b/packages/connector/CHANGELOG.md @@ -0,0 +1,1990 @@ +#### 1.0.4: Maintenance Release + +Runtime + + - Update all dependencies to latest fix versions + - Update JSONata to 1.8.1 + - #2473 Handle httpAdminRoot missing ending slash with login strategy Fixes + - #2470 Update https-proxy-agent + - #2461 Allow credentials to be provided as part of /flows api + - #2444 Move receive metric position to better reflect async changes Fixes + - #2406 Improve file store error when cache disabled and sync api used Closes + - #2399 cloneMessage should handle undefined without throwing err Fixes + - #2418 Fix the library api routes to prevent too broad matching of regex URLs + - #2417 Remove undefined loadFlowLibrary call + +Editor + + - #2465 Add better regex highlighting in jsonata edit mode Fixes + - Add regex awareness to jsonata formatter + - #2472 Avoid adding extra newlines when formating jsonata Fixes + - #2475 Add UI test case for error handling + - Avoid adding extra divs to edit form to avoid size miscalculation + - Upgrade to latest marked and dompurify libs + - Ensure catalog load errors are logged to the console + - #2460 Track context sidebar element paths to track formatting changes Fixes + - Battling Chrome Autocomplete, part 31: Wrap search input with form + - #2445 Trick chrome into autofilling dummy username/password inputs Fixes + - #2457 Fix garbled characters in library + - #2409 Filter palette using raw label not html formatted label Fixes + - #2400 Wrap long context values when displaying in sidebar Fixes + - Fix duplicating array item in visual json editor + - #2338 Modify history sidebar button positioning to handle long labels Fixes + - #2438 Add some auto-complete snippets to the nrjavascript mode Close + - #2430 Ignore disabled nodes when checking for invalid configs on deploy Closes + - #2442 #2458 #2453 Update zh-CN translations + - #2235 Add initial zh-TW translation + - Re-enable jshint on editor and fixup issues + - #2431 Remove unnecessary namespaces for i18n + - #2440 Support BrowserStack in UI testing + - #2358 Add path property to debug messages Fixes + - Fix false change detection when no config node selected + - Fix IME bug in text editor + - Make node highlighting a bit more obvious for busy flows + - #2392 Add icons and support i18n in typedInput of JSON editor + +Nodes + - #2462 MQTT: Ensure IPv6 broker names are wrapped in brackets Fixes + - Join node - check existance before clearing timeout + - Trigger: Complete 2nd msg when set to send latest + - TCP: clarify text regarding blank parameters. + - #2449 HTTP Request: Add HEAD as Method + - Make min-height for change, switch, batch and mqtt consistent + + +#### 1.0.3: Maintenance Release + +Runtime + - Increase timeouts in Subflow tests to minimise false positives + - Update grunt-sass and add node-sass for node12 support + - Fix timings of Delay node tests + - #2340 Update JSONata to 1.7.0 + - Bump https-proxy-agent version + - #2332 Fix error handling of nodes with multiple input handlers + - Add script to generate npm publish script + - #2371 Ensure folder is present before write (e.g. flows file not in user folder) + - #2371 Handle windows UNC '\\' paths + - #2366 Handle logging of non-JSON encodable objects + +Editor + - #2328 Fix language handling in subflow node + - Use default language if lng param not set in i18n req + - #2326 Fix palette editor search visualization + - #2375 Subflow status not showing i18n version of contained core nodes status + - Fix inverse of 'replace' editor event + - #2376 Fallback to base language files if present + - #2373 Support UI testing on the latest Google Chrome + - #2364 Add tooltip to expand button in markdown editor + - #2363 Support ctrl key to select tabs for Windows + - #2356 Make JSONata help initially shown in expression editor + - #2355 Prohibit line break in type menu of typedInput + +Nodes + - Delay: Fix delay to not pass through .reset and .flush props consistently + - #2352 File: Using the ‘a msg per line’ the last line does not get msg.topic passed + - #2339 HTTP Request: Check auth type on opening + - HTTP Request: add units info + - #2372 MQTT/WS: Improved proxy support for MQTT and WebSocket nodes + - #2370 MQTT: Add clarification that MQTT Out requires payload to send msg + + +#### 1.0.2: Maintenance Release + +Runtime + - Allow node.status() to be passed number/bool types + - Allow node emitted events to have multiple arguments + - #2323 Fixed docstrings to have them match the function signature (name of parameters). + - #2318 NLS: Unify translations of "boolean" + +Editor + - Ensure node status is refreshed whenever node is edited + - #2316 Ensure z property included in full message debug payload #2315 + - #2321 Fixed editor.json (JA nls) + - #2313 Fix element to collapse items in visual JSON editor + - #2314 Insert divider in menu by calling RED.menu.addItem('id', null); + +Nodes + - Change: Fixup use of node.done + - #2322 Template: Fix invalid JSON data in template node docs + - #2320 File: Fixed a typo in 10-file.html (JA nls) + - #2312 Template: Remove unnecessary comma in help text + - #2319 Inject: Interval of inject node should be 596 hours or less. + +#### 1.0.1: Maintenance Release + +Runtime + - #2301 Add env vars to enable safe mode and projects + - `NODE_RED_ENABLE_SAFE_MODE` + - `NODE_RED_ENABLE_PROJECTS` + +Editor + - #2308 Fix grid setting + - #2306 i18n support in tooltips + - Fix error when setting typedInput to boolean true/false + - #2299 Fix SVG icons in IE11 + - #2303 Fix issue where subflow color did not update when not on a flow + +Nodes + - #2297 TLS: Allow TLS config node to provide just CA cert + - #2307 Inject: Fix width on inject node property + - #2305 Switch: Let switch node between rule work both ways round + - Range: Add example to range node info and make use of target consistent + - Join: node must clone group message before sending + + +#### 1.0.0: Milestone Release + +Editor + - Add click-on-tooltip to close + - Fix node draggable handling + - Ensure complete node scope property is remapped on import + - Update i18n for project feature + - Fix menu hiding function for flow editor + - Normalise default subflow color references + - Hide header text of very small screens to deploy is visible + - Fix tab access on touch screens + - Update radialMenu to use standard theme colours + - Fix undefined reference loading on mobile + - Allow word breaking of node name with long word + - Enable wrap mode in Markdown editor + - Maximize the size of markdown editor + +Nodes + - remove legacy error option from file in mode + - Change MQTT node default 3.1 compatibility mode to false + - Show clear debug shortcut in tooltip + - Fix file-in port labels for all 4 options + - Add extra comment re Mustache escapes to Template info + - Fix typo in complete node + - Allow Function node output input to go to 0 + +#### 1.0.0-beta.4: Beta Release + +Runtime + - Clone the first message passed to node.send in Function node + +Editor + - Move flow-status button to footer for consistency + - Fix node hover effect to prevent jumping position + - Filter quick-add properly when splicing a wire + - #2274 Mark workspace dirty when deleting link node link Fixes + - Add red-ui-button class to strategy login button + - #2276 Fix padding of subflow locale select Closes + - Update info text of complete node & add JP text + - Add class red-ui-button to cancel button + - Add css class to login submit button (#2275) + - Realign subflow output port labels + - Move context sidebar auto-refresh option to individual sections + - Update Japanese message catalogue + - Fix subflow UI for select + - remove padding before label text for SUBFLOW UI row + - Allow SUBFLOW UI label row without variable name + +Nodes + - Remove old rc option from exec node for 1.0 + - Add python and SQL to template language options + - Fix Switch node display of jsonata_exp type + - Remove sentiment from core nodes + +#### 1.0.0-beta.3: Beta Release + +Runtime + - [FEATURE] Add Node Done API - make message passing async + - Ensure the subflow stop promise is waiting for before restarting + - Limit the regex for the /nodes/ api end points + - #2255 Add error event handler to ssh-keygen child_process Fixes + - #2252 Fix default value handling on context array access Fixes + - Remove all ui test dependencies from package.json + - Add req back to audit log events and extend to Projects api + - #2228 Ensure 2nd arg to node.error is an object Fixes + - #2271 Use a more atomic process for writing context files Fixes + + +Editor + - [FEATURE] Change core node categories + - [FEATURE] Subflow Instance property UI (#2236) + - [FEATURE] Add visual JSON editor + - [FEATURE] Add Action List dialog + - [FEATURE] Add new shortcut to clear debug message list - ctrl-alt-l + - [FEATURE] Add show-library dialog actions + - [FEATURE] Add shift-cursor handling for moving quick-add dialog + - [FEATURE] Add enable/disable-flow actions + - [FEATURE] Add actions to change deploy type + - [FEATURE] Allow config nodes to be disabled, tidy css and add actions + - [FEATURE] Add default shortcut (ctrl-d) for deploy + - [FEATURE] Initial implementation of redo (un-undo) - ctrl-y + - [FEATURE] add support for specifying subflow template color + - [FEATURE] Use ctrl-click on wire to splice node in place + - [FEATURE] Allow search results to show more than 25 results + - #2268 [FEATURE] Allow a node to change if it has an input port Closes + - #2172 Revealing node position needs to account for zoom level Fixes + - #2174 Fix typedInput option selection Fixes + - #2173 Fix palette node id handling so search works Fixes + - Add popover tooltips to debug sidebar,function and template + - Add popovers to context sidebar mini buttons + - Ensure node status icon is shown when value set + - Revert treeList children function signature change + - Restore tray component css for compatibility. Mark as deprecated + - fix function name & string compare function + - #2171 Handle empty list of example flows Fixes + - Ensure library list has an item selected when opened + - Ensure tooltip popover doesn't replace normal popover + - Fix clipboard export download button + - Ensure input box has focus on repeated quick add + - Fix width calculation of typedInput + - Remove some hardcoded css colors + - #2194 Fix display of node help when clicking in palette Fixes + - #2195 Ensure node help is loaded in the right language Fixes + - Do not allow tab focus on clipboard hidden element + - Fix undefined error on typedInput due to valueLabel used before being added + - Fix undo of flow disable state change + - Fix select-all action in main view + - Fix delete-all action on config node sidebar + - Update UI tests for new editor css + - Add insertItemAt doc to editableList + - Ensure focus returns to the right element after dialogs shown + - Set autocomplete to disabled in form input elements + - Update all node icons to SVG + - Handle png/svg fallback for def.icon values. Remove old pngs + - Ignore empty examples directories (don't add to import menu) + - #2222 better handle example file at any depth - + - Properly escape node types in palette + - Ensure session expiry timeout doesn't exceed limit + - Use node/tab map to make filterNodes more efficient + - Rearrange contents of subflow template settings tab + - Handle undefined node.\_def in edit stack title. + - fix converting selection to subflow + - Fix inserting new subflow node to existing wire between nodes + - #2246 Support displaying falsey node status values Fixes + - Remove tab menu from node property UI for subflow and config nodes + - #2260 Mark workspace dirty when shift-click-drag detaches wires Fixes + - Fix subflow category change on palette + + +Nodes + - Remove pi gpi, twitter, email and feedparser nodes from core + - #2182 Fix error handling in Websocket broadcast function Fixes + - Handle websocket item being parseable but not an object better + - stop join tripping up if last message of buffer is blank. + - Add support for env var propety in switch node + - Improve handling of file upload in request node + - Add "has key" rule to switch node + tests + - Optimise generation of switch node edit dialog + - #2261 Add keep-alive option to HTTP Request - + +#### 1.0.0-beta.2: Beta Release + +Runtime + - Fix length calculation when loading library file + +#### 1.0.0-beta.1: Beta Release + +Runtime + - Update runtime apis to support multiple libraries + - Add Node 12 to travis (allow_failures) + - #2152 Bump all dependencies Fixes + +Editor + - [BREAKING] complete overhaul of editor DOM/CSS structure + - [BREAKING] Get rid of Bootstrap + - Simplify index.mst to a single div to insert the editor + - Append node configs to div rather than body + - Only redraw node status when it has changed + - Minimise work done to calculate node label widths + - Allow script tags with src to reference esm modules + - Upgrade to jq 3.4.1 / jq-ui 1.12.1 + - Allow editor language to be chosen in editor settings + - #2128 Only NLS status text that starts with a letter Fixes + - #2140 Fix display of link node list within subflow Fixes + - #2097 Blur the active element when closing edit dialog via action Fixes + - #2160 Trigger change evnt on typedInput when type changes and options present Fixes + - Move library import/export to single dialog + - Move type-library dialogs to new style dialog + - Fix node drag and drop animation + - let status be simple text if wanted + - Add workspace statusBar + - Complete refresh of German translations + - #2163 Fix memory leak in Debug sidebar + - Introduce toggleButton and move flow-disabled to use it + - Allow RED.settings.get/set to use full property desc + - Add auto-refresh toggle to context sidebar + - Add build-custom-theme script + - Add RED.view.selectNodes api for node selection whilst editing + - Add node-select to typedInput + +Nodes + - http request node: warn user if msg.requestTimeout == 0 + - hide delay node reset label on deploy + - Fix CSV regex to treat strings starting e as text + - Add "don't parse numbers" option to csv node + - Add expand editor button to Template node + - Update catch/status nodes to use selectNodes api and treeList + +#### 0.20.8: Maintenance Release + + - Sanitize tab name in edit dialog + - #2272 Pass httpServer to runtime even when httpAdmin disabled Fixes + +#### 0.20.7: Maintenance Release + + - #2183 Update jsonata to 1.6.5 which should fix + - Ensure the subflow stop promise is waiting for before restarting + - Properly escape node types in palette + +#### 0.20.6: Maintenance Release + + - #2172 Revealing node position needs to account for zoom level Fixes + - stop join tripping up if last message of buffer is blank. + - Improve handling of file upload in request node + - #2202 Handle subflow internal node wired to a non-existant node Fixes + - Do not save subflow env vars with blank names + - Don't allow a link node virtual wire to connect to normal port + - #2215 Clear HTTP Request node authType when auth disabled Fixes + - #2216 Fix parsing of content-type header Fixes + - Fix join node reset issue with merging objects + - #2211 Copy data-i18n attribute on TypedInput Fixes + +#### 0.20.5: Maintenance Release + + - Revert error handling in palette manager + +#### 0.20.4: Maintenance Release + +- Switch media-typer to content-type module Fixes #2122 #2123 +- Use userObj.username and not .name for ssh key lookup Closes #2109 +- Ensure mqtt message handlers are tidied up properly on partial deploy +- Update package dependencies +- Fix encoding menu in file node #2125 +- Update ACE to 1.4.3-src-min-noconflict Fixes #2106 +- Fix creating missing package.json when existing project imported Fixes #2115 +- Allow subflow instance to override env var with falsey values Fixes #2113 +- Prevent wire from normal node to link virtual port Fixes #2114 +- Add explanation to the help text on the new feature to build query string from msg.payload #2116 +- Bump bcrypt to latest +- Add Korean locales files for nodes #2100 +- Add error message if catalog is invalid json +- Reduce udp out timeout to be less than default inject at start #2127 + +#### 0.20.3: Maintenance Release + +- Do not dynamically add/remove upgrade listener in ws nodes +- Avoid env var reference loops and support $parent. prefix Fixes #2099 +- Ensure config.\_flow is non-enumerable so is ignored by JSON.stringify +- Block loading ACE from cdn + +#### 0.20.2: Maintenance Release + + - Filter out duplicate nodes when importing a flow + - Handle node configs with multiple external scripts properly + +#### 0.20.1: Maintenance Release + + - #2095 Ensure all subflow instances are stopped when flow stopping Fixes + - #2091 modify name of korean locale forders + - Ensure node names are sanitized before being presented + - #2087 Subflow status node must pass status to parent flow Fixes + - #2090 fix problem on displaying option label on Firefox + +#### 0.20.0: Milestone Release + +Runtime + - Pass complete status to Status node and filter to editor + - #2067 Ensure flows wait for all nodes to close before restarting Fixes + - Fix git clone with password protected key + - Allow a project to be located below the root of repo + - Detect the cloning of an empty git repo properly + - Fix use of custom auth strategy plugins + - #2057 Remove remnants of when library in git/index Fixes + - Clear subflow status on close + - Add exportGlobalContextKeys to prevent exposing functionGlobalContext keys + - Add --no-audit and --no-update-notifier flags to npm commands to reduce workload + - Add envVarExcludes setting to block named env vars + - #2082 Update settings.js docs on userDir to match reality Fixes + - Add Korean Language + + +Editor + - Automatic placing of node icon according to input/output counts + - Transfer placeholder and type to generated TypedInput field + - Hitting enter in Comment node name field clicks markdown button + - Shift status text left if no shape specified + - Better align node status text to status dot + - Handle treeList labels as text not html + - Change subflow edit dialog titles + - Resize subflow edit dialog properly + - Add flow list button to tab bar + - Handle node name as unsanitized text in debug sidebar + +Nodes + + - HTTP Request: Add Digest and Bearer Auth modes to http request node (#2061) + - HTTP Request: Add multipart/form-data support to http request node (#2076) + - TCP: include session/event info in status events + - WebSocket: include session/event info in status events + - Add i18n support for port label of inject/exec/httprequest/file nodes + - Join node: handle merged objects with repeated properties and honour parts + - JSON node: handle single booleans and numbers + - File node: add encoding support to file in/out node (#2066) + +#### 0.20.0-beta.5: Beta Release + +Runtime + + - Bump dependencies + - Allow `$parent` access of flow context + - Make Node.\_flow a writeable property + - Do not propagate Flow.getNode to parent when called from outside flow + - Add support of subflow env var + +Editor + + - Properly sanitize node names in deploy warning dialogs + - Fix XSS issues in library ui code + - Add env type to subflow env var types + - Display parent subflow properties in edit dialog + - Fix direction value of subflow output + - #597 Add Status Node to Subflow to allow subflow-specific status Closes + - #2039 Better handling of multiple flow merges Fixes + +Nodes + + - Various translation updates + - #1747 Catch: Add 'catch uncaught only' mode. Closes + - Link: scroll to current flow in node list + - HTTPRequest: add option to urlencode cookies + - #1981 HTTPRequest: option to use msg.payload as query params on GET. + - Debug: Add local time display option to numerics in debug window + - MQTT: Add parsed JSON output option + +#### 0.20.0-beta.4: Beta Release + +Runtime + + - Bump JSONata to 1.6.4 + - Add Flow.getSetting for resolving env-var properties + - Refactor Subflow logic into own class + - Restore RED.auth to node-red module api + - Tidy up when usage in Flow and Node + +Editor + + - German translation + - Change default dropdown appearance and sidebar tab menu handling + - #2021 Handle multiple-select box when nothing selected Fixes + - #2028 Handle i18n properly when key is a valid sub-identifier Fixes + - #2032 Avoid duplicate links when missing node type installed Fixes + - Add View Tools + - Don't collapse version control header when clicking refresh + - Add fast entry via keyboard for string of nodes + - Check for undeployed change before showing open project dialog + - Add placeholder node when in quick-add mode + - Move nodes to top-left corner when converting to subflow + +Nodes + + - Debug: Allow debug edit expression to be sent to status + - WebSocket: Fix missing translated help + + +#### 0.20.0-beta.3: Beta Release + +Editor + + - Update palette manager view properly when module updated + - Add TreeList common widget + - #2008 Fix visual jump when opening Comment editor on Safari Part of + - #2008 Fix vertical align of markdown editor in Safari Fixes + - #2009 Avoid marking node as changed if label state is default Fixes + - Highlight port on node hover while joining + - Support drag-wiring of link nodes + - Allow TypeSearch to include a filter option + - Improve diff colouring + - Allow sections to toggle in 2-element stack + - #1980 Add support for ${} env var syntax when skipping validation Closes + - i18 support for markdown editor tooltip + - Add RED.editor.registerTypeEditor for custom type editors + - Tidy up markdown toolbar handling across all editors + - Added validation while export into library + - Reuse notification boxes rather than stack multiple of the same type + - Make ssh key dialog accessible when opened from new proj dialog + +Runtime + + - #2023 Bump JSONata to 1.6.4 Fixes + - Add audit logging to admin api + - #2010 Fix failure of RED.require + - #1998 Allow oauth strategy callback method to be customised Closes + - #2001 Ensure fs context cache is flushed on close Fixes + - Fix library Buffer( to Buffer.alloc( for node 10 + - Catch file-not-found on startup when non-existant flow file specified + - Actively expire login sesssions and notify user + - #1976 Add quotation marks for basic auth challenge + +Nodes + + - Change: remove promises to improve performance + - Debug: add ability to apply JSONata expression to message + - Join: remove promises to improve performance + - JSON: delete msg.schema before sending msg to avoid conflicts + - Link: update UI to use common TreeList widget + - Switch: remove promises to improve performance + +#### 0.20.0-beta.2: Beta Release + + - Split Node-RED internals into multiple sub-modules + +Editor + + - Allow the editor to use a custom admin api url root + - #1989 Improve performance of Flow Diff dialog - @TothiViseo + - Add 'open project' option to Projects Welcome dialog + - Add 'type already registered' check in palette editor + - Handle missing tab.disabled property + - Handle missing wires prop and string x/y props on import + - Add RED.notifications.hide flag - for UI testing + - Improve alignment of node label edit inputs + - Show arrow-in node when invalid font-awesome icon name was specified for default icon + - Add ability to delete context values from sidebar + - Allow copy-to-clipboard copy whole tabs + - Make disabled flows more obvious in editor + - Allow import/export from file in editor + - Allow config nodes to be selected in sidebar and deleted + - Show port label of subflow with input port + - Support ctrl-click selection of flow tabs + - Allow left-hand node button to act as toggle + - Support dbl-click in tab bar to add new flow in position + - Fix duplicate subflow detection on import + - #1862 Add import notification with info on what has been imported Closes + - Show error details when trying to import invalid json + - Show default icon when non-existent font-awesome icon was specified + - Add configurable option for showing node label + - #1903 Avoid http redirects as Safari doesn't reuse Auth header Fixes + - Tidy up ace tooltip styling + - Add event log to editor + - Add tooltips to multiple editor elements + - Allow palette to be hidden + - Add node module into to sidebar and palette popover + - Mark all newly imported nodes as changed + - Allow a node label to be hidden + - Add markdown formatting toolbar + - Add markdown toolbar to various editors + - Fix i18n handling for ja-JP locale on Safari/MacOS + - Add node body tooltip + - Decrease opacity of flow-navigator + - Update tooltip style + - Update ACE to 1.4.1-src-min-noconflict + - Cache node locales by language + - Show icon element with either icon image or fa-icon + - Added font-awesome icons to user defined icon + - Update info side bar with node description section + - One-click search of config node users + - Redesign node edit dialog to tabbed style + - Add 'restart flows' option to deploy menu + - Add node description property UI + + +Runtime + + - Allow a project to be loaded from cmdline + - #1978 Handle lookup of undefined property in Global context Fixes + - Refuse to enable Manage Palette if npm too old + - Remove restriction on upgrading non-local modules + - #1709 Remove deprecated Buffer constructor usage Fixes + - Update httpServerOptions doc in settings.js + - Exclude non-testable .js files from the unit tests + - Add --safe mode flag to allow starting without flows running + - #1789 Add setting-defined accessToken for automated access to the adminAPI - + +Nodes + + - #1990 Move all core node EN help to their own locale files - + - CSV: better regex for number detection + - Debug: hide button if not configured to send to sidebar + - Delay: report queue activity when in by-topic mode + - Delay: add msg.flush mode + - Exec: Preserve existing properties on msg object + - File: remove CR/LF from incoming filename + - #1911 Function: create custom ace javascript mode to handle ES6 Fixes + - Function: add env.get + - #1913 HTTP Request: Add http-proxy config + - HTTP Request: add msg.redirectList to output + - #1959 HTTP Request: add msg.requestTimeout option for per-message setting - @natcl + - #1912 - @DurandA MQTT: add auto-detect and base64 output to mqtt node Fixes + - MQTT: only unsubscribe node that is being removed + - Sentiment: move to node-red-node-sentiment + - Switch: add missing edit dialog icon + - Tail: move to node-red-node-tail + - TCPGet: clear status if user changes target per message + - Template: tidy up edit dialog + - UDP: more resilient binding to correct port for udp, give input side priority + - Split/Join: add msg.reset to info panel + - Split/Join: reset join without sending part array + - Watch: add msg.filename so can feed direct to file in node + - WebSocket: preserve \_session on msg but don't send as part of wholemsg + +#### 0.19.6: Maintenance Release + + - #2051 Fix encoding of file node from binary to utf8 - + +#### 0.19.5: Maintenance Release + + - Recognize pip installs of RPi.GPIO (#1934) + - #1941 from node-red-hitachi/master-batch Merge pull request + - #1931 from node-red-hitachi/master-typedinput Merge pull request + - Set min value of properties and spinners for batch + - Fix that unnecessary optionMenu remains + - #1894 from node-red-hitachi/fix-overlapping-file-node-execution Merge pull request + - #1924 from imZack/patch-1 Merge pull request + - Add missing comma + - #1921 Do not disable context sidebar during node edit Fixes + - #1920 Don't allow virtual links to be spliced Fixes + - Merge project package changes to avoid overwritten changes + - #1908 Handle manually added project deps that are unused Fixes + - update close & input handling of File node + - make close handler argument only one + - #1907 from amilajack/patch-2 Merge pull request + - Change repo badge to point to master branch + - invoke callbacks if async handler is specified + - #1891 from camlow325/resolve-example-path-for-windows-support Merge pull request + - #1900 from kazuhitoyokoi/master-addtestcases4settings.js Merge pull request + - wait closing while pending messages exist + - Add test cases for red/api/editor/settings.js + - #1893 Ensure all palette categories are opened properly Closes + - Resolve path when sending example file for Windows support + - fix multiple input message processing of file node + +#### 0.19.4: Maintenance Release + + - #1888 Fix race condition in non-cache lfs context Fixes + - LocalFileSystem Context: Remove extra flush code + - Prevent race condition in caching mode of lfs context (#1889) + - Allow context store name to be provided in the key + - Switch node: only use promises when absolutely necessary + - Fix dbl-click handling on webkit-based browsers + - Ensure context.flow/global cannot be deleted or enumerated + - #1883 Handle context.get with multiple levels of unknown key Fixes + - Fix global.get("foo.bar") for functionGlobalContext set values + - Fix node color bug (#1877) + - #1857 from cclauss/patch-1 Merge pull request + - Define raw_input() in Python 3 & fix time.sleep() + +#### 0.19.3: Maintenance Release + + - Split node - fix complete to send msg for k/v object + - Remove unused Join node merged object key typed input + - Set the JavaScript editor to full-screen + - Filter global modules installed locally + - Add svg to permitted icon extension list + - Debug node - indicate status all the time if selected to do so + - pi nodes - increase test coverage slightly + - TCP-request node - only write payload + - JSON schema: perform validation when obj -> obj or str -> str + - JSON schema: add draft-06 support (via $schema keyword) + - #1651. Mqtt proxy configuration for websocket connection, + - Allows MQTT Shared Subscriptions for MQTT-In core node + - Fix use of HTML tag or CSS class specification as icon of typedInput + +#### 0.19.2: Maintenance Release + + - Ensure node default colour is used if palette.theme has no match + - #1863 (#1864) fix lost messages / properties in TCPRequest Node; closes + - Fix typo in template.html + - Improve error reporting from context plugin loading + - Prevent no-op edit of node marking as changed due to icon + - Change node must handle empty rule set + +#### 0.19.1: Maintenance Release + + - Pull in latest twitter node + - Handle windows paths for context storage + - Handle persisting objects with circular refs in context + - Ensure js editor can expand to fill available space + - Add example localfilesystem contextStorage to settings + - Fix template node handling of nested context tags + +#### 0.19: Milestone Release + +Editor + + - Add editorTheme.palette.theme to allow overriding colours + - #1446 Index all node properties when searching Fixes + - #1779 Handle NaN and Infinity properly in debug sidebar Fixes #1778 + - Prevent horizontal scroll when palette name cannot wrap + - Ignore middle-click on node/ports to enable panning + - Better wire layout when looping back + - fix appearence of retry button of remote branch management dialog + - Handle releasing ctrl when using quick-add node dialog + - Add $env function to JSONata expressions + - Widen support for env var to use ${} or $() syntax + - Add env-var support to TypedInput + - Show unknown node properties in info tab + - Add node icon picker widget + - Only edit nodes on dbl click on primary button with no modifiers + - Allow subflows to be put in any palette category + - Add flow navigator widget + - #1753 Cache flow library result to improve response time Fixes + - Add middle-button-drag to pan the workspace + - allow multi-line category name in editor + - Redesign sidebar tabs + - Do not disable the export-clipboard menu option with empty selection + +Nodes + + - #1769 Change: Ensure runtime errors in Change node can be caught Fixes + - File: Add output to File Out node + - Function: add expandable JavaScript editor pane + - Function: allow id and name reference in function node code (#1731) + - HTTP Request: Move to request module + - #1278 HTTP: Ensure apiMaxLength applies to HTTP Nodes Fixes + - Join: accumulate top level properties + - Join: allow environment variable as reduce init value + - JSON: add JSON schema validation via msg.schema + - Pi: Let nrgpio code work with python 3 + - Pi: let Pi nodes be visible/editable on all platforms + - Switch: add isEmpty rule + - #1414 TCP: queue messages while connecting; closes + - #1805 TLS: Add servername option to TLS config node for SNI Fixes + - UDP: Don't accidentally re-use udp port when set to not do so + +Persistent Context + + - Add Context data sidebar + - Add persistable context option + - Add default memory store + - Add file-based context store + - Add async mode to evaluateJSONataExpression + - Update RED.util.evaluateNodeProperty to support context stores + +Runtime + + - Support flow.disabled and .info in /flow API + - #1781 Node errors should be Strings not Errors Fixes + - #1770 Add detection of connection timeout in git communication Fixes + - Handle loading empty nodesDir + - Add 'private' property to userDir generated package.json + - Add RED.require to allow nodes to access other modules + - Ensure add/remove modules are run sequentially + +#### 0.18.7: Maintenance Release + +Editor Fixes + + - #1737 Do not trim wires if node declares outputs in defaults but misses value Fixes + +Node Fixes + + - Relax twitter node version ready for major version bump + - Pass Date into the Function node sandbox to fix instanceof tests + - let TCP in node report remote ip and port when in single packet mode + - typo fix in node help (#1735) + +Other Fixes + - #1738 Tidy up default grunt task and fixup test break due to reorder Fixes + - Bump jsonata version + +#### 0.18.6: Maintenance Release + +Editor Fixes + + - #1724 Handle a node having wires in the editor on ports it no longer has Fixes + - Add missing ACE snippet files + - #1726 Fix wireClippedNodes is not defined Fixes + - Split node html to isolate bad nodes when loading + - Avoid unnecessary use of .html() where .text() will do + + - Add editorTheme.projects.enabled to default settings.js" + +#### 0.18.5: Maintenance Release + +Projects + + - Add clone project to welcome screen + - Handle cloning a project without package.json + - Keep remote branch state in sync between editor and runtime + +New Features + + - Add type checks to switch node options (#1714) + - add output property select to HTML parse node (#1701) + - Add Prevent Following Redirect to HTTP Request node (#615) (#1684) + - Add debug and trace functions to function node (#1654) + - Enable user defined icon for subflow + - Add MQTT disconnect message and rework broker node UI (#1719) + - Japanese message catalogue updates (#1723) + - Show node load errors in the Palette Manager view + +Editor Fixes + + - #1698 Highlight subflow node when log msg comes from inside Fixes + - #1678 Ensure node wires array is not longer than outputs value Fixes + - #1681 Allow importing an unknown config node to be undone Fixes + - #1696 Ensure keyboard shortcuts get saved in runtime settings Fixes + - Don't mark a subflow changed when actually modified nothing (#1665) + +Node Fixes + + - bind to correct port when doing udp broadcast/multicast (#1686) + - Provide full error stack in Function node log message (#1700) + - #1690 Fix http request doc type Fixes + - Make debug slightly larger to pass WCAG AA rating + - #1673 Make core nodes labels more consistent, to close + - #1671 Allow template node to be updated more than once Fixes + - Fix the problem that output labels of switch node sometimes disappear (#1664) + - Chinese translations for core nodes (#1607) + +Runtime Fixes + + - #1689 (#1694) Handle and display for invalid flow credentials when project is disabled + - node-red-pi: fix behavior with old bash version (#1713) + - Fix ENOENT error on first start when no user dir (#1711) + - #1721 Handle null error object in Flow.handleError Fixes + - update settings comments to describe how to setup for ipv6 (#1675) + - #1359 Remove credential props after diffing flow to prevent future false positives Fixes + - #1645 Log error if settings unavailable when saving user settings Fixes + - Keep backup of .config.json + - Add warning if using \_credentialSecret from .config.json + - Filter req.user in /settings to prevent potentially leaking info + +#### 0.18.4: Maintenance Release + +Projects + + - Ensure sshkey file path is properly escaped on Windows + - Normalize ssh key paths for Windows file names + - Ensure userDir is an absolute path when used with sshkeygen + - Detect if there are no existing flows to migrate into a project + - Use relative urls when retriving flow history + - Add credentialSecret to clone pane + - Delay clearing inflight when changing credentials key + - Mark deploy inflight when reverting a file change + - Handle missing_flow_file error on clone properly + - Remote project from cached list on delete so it can be reused + - Fix tests for existing file flag in settings + +Editor Fixes + + - Fix merging a remote diff + - Fixed the problems when using a node without defaults + - Disable user defined icon for subflow + - #1635 getDefaultNodeIcon should handle subflow instance nodes Fixes + - Add Japanese info text for core nodes + - Fix message lookup for core nodes in case of i18 locales directory exists + - Prevent the last tab from being deleted + +Node Fixes + + - Ensure trigger gets reset when 2nd output is null + + +#### 0.18.3: Maintenance Release + +Projects + + - Fix permissions on git/ssh scripts + - Add support for GIT_SSH on older levels of git + - Handle host key verification as auth error + - Ensure commit list has a refs object even if empty + - Make git error detection case-insensitive + - Fix up merge conflict handling + - Use flow-diff when looking at flow file changes + +Node Fixes + + - Ensure debug tools show for 'complete msg object' + - Fix msg.parts handling in concat mode of Batch node + +Editor Fixes + + - Fix offset calculation when dragging node from palette + - Allow a library entry to use non-default node-input- prefixes + - #1628 Change remote-diff shortcut and add it to keymap Fixes + +#### 0.18.2: Maintenance Release + +Projects + + - Filter out %D from git log command for older git versions + - Ensure projects are created as logged in user + - Better error handling/reporting in project creation + - Add Project Settings menu option + - Refresh vc sidebar on remote add/remove + - Fix auth prompt for ssh repos + - Prevent http git urls from including username/pword + - Fix fetch auth handling on non-default remote + - Avoid exception if git not installed + - Check version of git client on startup + - Fix pull/push when no tracked branch + - Add git_pull_unrelated_history handling + - Handle delete of last remote in project settings + +Node Fixes + + - Fix and Add some Chinese translations + - Update sort/batch docs + - Don't assume node has defaults when exporting icon property + - Ensure send is last thing trigger does + - Ensure trigger doesn't set two simultaneous timeouts + - Add missing property select var to HTML node + - Add a default keepalive to tcp client mode + - Move node.send in exec and httprequest nodes + + +#### 0.18.1: Maintenance Release + +Projects + + - Handle more repo clone error cases + - Relax validation of git urls + - Revalidate project name on return to project-details view + - #1597 Avoid unnecessary project refresh on branch-switch Fixes + - Add support for file:// git urls + - Handle project first-run without existing flow file + - Handle delete of last remote in project settings + - Add git_pull_unrelated_history handling + - Fix pull/push when no tracked branch + - Remember to disable projects in editor when git not found + +Node Fixes + + - Trigger node migration - ensure bytopic not blank + - #1598 Add HEAD to list of methods with no body in http req node + - #1598 Do not include payload in GET requests Fixes + - #1601 Update sort/batch docs Fixes + - Don't assume node has defaults when exporting icon property + + +#### 0.18: Milestone Release + +Runtime + + - Beta: Projects - must be enabled in settings file + - Allow port zero for Express (#1363) + - Better error reporting when module provides duplicate type + - Update jsonata to 1.5.0 + - add express-session memorystore without leaks (#1435) + - #1461 Allow adminAuth.user to be a Function Fixes + - Ensure RED.server is set even if admin api disabled + - #1481 Ensure strategy login button uses relative URL Fixes + - ignore `_msgid` when merging full objects + - #1488 Move node install to spawn to allow for big stdout Fixes + - SIGINT handler should wait for stop to complete before exit + +Editor + + - allow a node's icon to be set dynamically (#1490) + - Batch messages sent over comms to increase throughput + - Migrate deploy confirmations to notifications + - #1346 `oneditdelete` should be available to all node types Closes + - Sort typeSearch results based on position of match + - Update ACE to test and add python highlighter (#1373) + - #1517 Clear mouse state when typeSearch cancelled Fixes + - Handle scoped modules via palette editor + - #1549 TypedInput: handle user defined value/labels options Fixes + +Nodes + + - add msg. select to range and yaml nodes + - add property choice to xml, sentiment nodes + - mqtt: Add 'name' to mqtt-broker node, and label it by this if it is set. (#1364) + - Add option to JSON node to ensure particular encoding + - add parts support for HTML node (#1495) + - Add passphrase to TLS node + - Add rc property to exec node outputs 1 and 2 (#1401) + - Add skip first n lines capability to csv node (#1535) + - Add support for rejectUnauthorized msg property + - Add TLS options to WebSocket client + - Added parsed YAML support for template node (#1443) + - #1360 Allow delay node in rate-limit mode to be reset Fixes + - Allow setTimeout in Function node to be promisified in node 8 + - Debug to status option (#1499) + - enable template config via msg.template for stored or generated templates (#1503) + - HTTP REQUEST: Adding PROPPATCH and PROPFIND http methods (#1531) + - Initial support of merge & reduce mode for JOIN node (#1546) + - Initial support of new BATCH node (#1548) + - Initial support of sequence rules for SWITCH node (#1545) + - initial support of SORT node (#1500) + - Inject node - let once delay be editable (#1541) + - Introduce `nodeMessageBufferMaxLength` setting for msg sequence nodes + - Let CSV correct parts if we remove header row. + - let default apply if msg.delay not set in override mode. (#1397) + - let trigger node be reset by boolean message (#1554) + - Let trigger node support per topic mode (#1398) + - let HTML node return empty array for no matching input (#1582) + - MQTT node - if Server/URL config contains '//' use it as a complete url; enabled ws:// and wss:// + - clone messages before delayed send (#1474) + - Decrement connected client count rather than show disconnected + - #1566 Don't end mqtt client on first error Fixes + - #1489 File out - create dirs synchronously to ensure they exist Fixes + - Fix debug message format for Buffer (#1444) + - Fix global.keys() bug in function node (#1417) + - Handle escape characters in template node which uses Mustache format and JSON output mode (#1377) + - #1527) (#1539) Move all node.send to end of timer functions in trigger node (issue + - #1521 Publish null/undefined to mqtt as blank not toString Fixes + - remove inject node at specific time spinner + - restrict inject interval to less that 2^31 millisecs + - tag UDP ports in use properly so they get closed correctly (#1508) + +#### 0.17.5: Maintenance Release + + - Add express-session missing dependency for oauth + - Fix improper type tests is core test cases + - #1351 File node: recreate write stream when file deleted Fixes + - Add flow stopping trace messages + - Fix userDir test case when .config.json exists (#1350) + - #1344 Do not try to send msg after http request error handled Fixes + - Fix boundary problem in range node (#1338) + - Modify messages in node properties to refer messages.json (#1339) + - Fix settings.js replacing webSocketVerifyClient by webSocketNodeVerifyClient (#1343) + + +#### 0.17.4: Maintenance Release + + - Add request node test case for POSTing 0 + - Allow false and 0 in payload for httprequest (#1334) + - Add file extension into flow name of library automatically (#1331) + - #1335 Fix accessing global context from jsonata expressions Fixes + - #1332 Disable editor whilst a deploy is inflight Fixes + - Replace Unknown nodes with their real versions when node loaded + - Retry auto-install of modules that fail + - Fix column name in link nodes to refer language file (#1330) + - #1329 Use namespaces with link node title attributes i18n name Fixes + - #1328 Tidy up GPIO pin table presentation Fixes + - Join: count of 0 should not send on every msg + - Handle importing only one end of a link node pair + - #1323 Make sending to Debug synchronous again Fixes + - Make send-error behaviour optional in file node + - Restore File In node behaviour of sending msg on error + - Expose context.keys within Function node + - JSON parser default should be not formatting output + + +#### 0.17.3: Maintenance Release + + - Fix flow library in menu to support period characters as flow name (#1320) + - editorTheme not setting custom css/scripts properly + - Fix missing icons for some nodes (#1321) + - Add reformat button to JSONata test data editor + - Update delay node status without spawning unnecessary intervals + - #1311 Avoid stringify ServerResponse and Socket in Debug node Fixes + - Fix creating userDir other than system drive on Windows (#1317) + - #1316 Trigger node not handling a duration of 0 as block mode Fixes + - #1314 Unable to config GPIO Pin 13 Fixes + +#### 0.17.2: Maintenance Release + + - Fix GPIO node labels + +#### 0.17.1: Maintenance Release + + - Fix PI gpio to use BCM + - #1311 Prevent event thread contention when sending to Debug node Closes + - Fix Bug: Can not display node icon when npm package has scope (#1305) (#1309) + - Clear moved flag when nodes are deployed + +#### 0.17: Milestone Release + +Runtime + + - #1273 Return flow rev on reload api when api v2 enabled Closes + - Provide single endpoint to load all node message catalogs + - Add .trace and .debug to Node prototype + - Rename oauth auth scheme to strategy as it works for openid + - Allow oauth schemes provide a custom verify function + - Add support for oauth adminAuth configs + - Cache auth details to save needlessly recalculating hashes + - Add context.keys function to list top-level keys + - #1239 Strip BOM character from JSON files if present Fixes + - Version check no meta (#1243) + - #1230 Ensure all nodes have access to global context Fixes + - #851 Don't process subscription for unauthenticated comms link Fixes + - #1198 Clone credentials when passing to node Fixes + - Resolve dir argument of getLocalNodeFiles function (#1216) + - Add wait for writing a library entry into a file. (#1186) + - Use correct Buffer.from method rather than constructor + - update core nodes to use newer Buffer syntax + - #1167 Treat missing msg properties as undefined rather than throw error Fixes + - Allows flows to be enabled/disabled in the runtime + - add off option to logging settings comment + - Log error stack traces if verbose flag is set + - Extract line number if available from node load errors + - Add node 8 to travis (with allow failure) + - Shuffle promises for creating default package.json + - Create a package.json file in userDir if one doesn't exist + - autoInstallModules option must honour version/pending_version + - Refuse to update a non-local node module + - Finalise nodeSettings and update tlsConfigDisableLocalFiles + - Allow a node to declare what settings should be made available to the editor. (#1185) + - Add node whitelist function (#1184) + - Allow a node to declare settings that should be exported + - Add test coverage for deleting a flow + - Update tests for oauth -> strategy rename + - Fix the test cases which sometimes fails due to timing. (#1228) + - Extend timeout for the test case of installing non-existant path. (#1191) + - Fix loader test to expect line numbers in load errors + - Update ui_spec for icon module path + - let node installer try to save with ~ version prefix to allow minor updates + - Log error when non-msg-object is returned from a Function + - Timeout a node that fails to close - default 15s timeout + - Pass a 'removed' parameter to node close handler + - Remove event passing for icons/examples from the api layer + - Update general dependencies + +Nodes + + - Do not log node errors if handled by a Catch node + - Fix wrong number of double quotes in CSV parsing + - let csv node handle ip addresses without trying to parse + - Update debug node to register the settings it uses + - #1202 Handle IncomingMessage/ServerResponse object types in debug Fixes + - #1203 Toggling debug node enabled/disabled state should set state dirty Fixes + - redo delay node status messages to be interval based + - Update delay node ui + - Add new msg.delay option to delay node + - stop delay node spamming web socket (when in fast rate limit mode) + - Delay/Range node help tidy up + - Bug fix in exec node. White spaces in arguments now works (#1285) + - Make exec node explicitly call SIGTERM for default + - Fix exec node error tests on Windows (#1234) + - update messages for updated exec node + - Make exec node spawn and exec outputs more consistent + - Exec node for windows environment (#1200) + - remove requirement for cmd in exec node config + new style info + - retry exec node tests + - let exec node take msg.kill SIG... param and pid param + - Third output from Exec node must be consistent for success/failure conditions + - exec node returns 0 on the third output if command ended without error. (#1160) + - exec node can be killed on demand + - add "split/stream" ability to file in node + - add port label to file node and update info + - Allow nodes to have translations not in core (#1183) + - fix tcp node new Buffer alloc size 0 + - change pin selection table for pi gpis nodes + - stop using sudo for Pi gpio access + - adding frequency configuration to pwm output (#1206) + - Fix Pi GPIO debounce + - let Hypriot on Pi detect gpio correctly + - More core node info help tidy up + - Tidy up more core node help text + - Tidy up parser node edit dialogs and help text + - yet more core node info updates + - more core node info updates to newer style + - Update some core nodes info + - First pass of new node-info style + - MQTT new style info + - Fix empty extra node help content issue + - #1218 Handle HTTP In url that is missing its leading / Fixes + - Add file upload support to HTTP In node + - HTTP Request node: add info on how to do form encoding + - #1015 Prevent unmodified msg.headers from breaking HTTP Request flows Closed + - Add cookie handling to HTTP Request node + - Add guard against the http-request buffer fix being reverted + - Multipart streaming + - Add http-request node unit tests + - http request node add transport validity check and warn. + - #1172 Update follow_redirects to fix http_proxy handling Fixes + - Allow statusCode/headers to be set directly within HTTP Response node + - let inject "between time" also fire at start - Plus new info + - remove repeat symbol from inject if repeat is 0 + - Add port labels to inject node (to show types) + - Add buffer joiner mode to Join node + - Let join node auto re-assemble buffers + - let join also accumulate strings (and not fail) + - Add Pretty print option to JSON node and + - Fix selection of link nodes + - Add link label value as portLabels + - Add sentence about clearing retained topic on mqtt + - make sure MQTT client closes if redeploy during reconnect + - make sure MQTT client closes if redeploy during reconnect + - slight filed size adjust for mqtt broker port field - allow 5 digits + - Add help info for split node + - split node - in object mode allow msg.complete on its own + - let split of objects use key to set another property (e.g. topic) + - adding streaming modes into split node + - let split node reassemble based on a final packet. (as well as the first) + - Add buffer support to split node + - updated split/join node (split still needs work before release) + - Added a name icon and a description label on edit subflow window. + - Don't display port labels for subflow pseudo-port nodes + - Added a name icon and a description label on edit subflow window. + - tcp request - remove confusing timeout wording from info + - Final TCP node nits - let 0 do it's thing as per every other timeout + - fix tcp port not waiting as per info/previous behaviour + - TCP In: Fix error in timout callback (#1249) + - Make tcp send msg more consistent + - Update 31-tcpin.js (#1235) + - really close tcp node connection right away (if told to) + - clone message before send in stay connected mode + - Better template node help example + - Add option to parse Template result as JSON before sending + - nail trigger test for windows AND linux + - give up on SIGQUIT for widows test + - better tests for windows nodes + - comment out 2nd exec node kill tests + - fixes for grunt files tests on Windows + - Add events to test helper + - Change default value of tlsConfigDisableLocalFiles to false + - Add the node setting tlsConfigDisableLocalFiles for tls node. (#1190) + - UI to upload certificates and keys for TLS node + - Update trigger help + - let trigger node set repeated outputs + - Move udp sock error listener to only be instantiated once. + - Let watch node recurse into subdirectories + - Misconfigured WebSocket nodes should not register msg handlers + - #1127 Add websocketVerifyClient option to enable custom websocket auth Fixes + +Editor + + - Bump ACE editor to v1.2.7 + - Add RED.utils.getNodeLabel utility function + - Include module name in requests for node icons + - Change debug message menu icon + - Handle empty array/objects in debug view + - Add per-node filter option to Debug pane + - Ensure debug node marked changed when button pressed + - Fix pop-out debug window for all the recent updates + - Add debug message menu + - Don't include msg. in debug message copied paths + - Format Buffer numbers as hex by default + - Remember formatting choices for dbg msg elements + - Allow debug msg elements to be pinned + - Only show debug tools under the debug tab + - Fix test for valid js identifiers in debug path construction + - Remove unused modified flag on debug messages + - Add copy path/value buttons to debug messages + - dont match only part of the node type (#1242) + - #1213 Add editorTheme.logout.redirect to allow redirect on logout Closes + - #1288 Handle logging out and already logged-out editor Fixes + - Fix bug: Export Subflows (#1282) + - destroy editor to ensure fully removed on close (function, template, comment) + - #1258 Don't try to nls status text starting with '.' Fixes + - Add note of removed flows in diffConfig (#1253) + - Add description to flow same as subflow + - Allow tabs to be enabled/disabled in the editor + - Make H3 sections in node help collapsible + - Add JSON Expression editor + - Expression editor - clear legacy flag for blank expressions + - Ensure node labels are reordered properly to match outputs + - Add 'none' placeholder for empty port label form + - Don't mark a node changed when going from none to blank labels + - Leave a node to nls its own port labels + - Allow a node to override default labels + - Add placeholder text on label inputs and clear buttons + - Add port labels to Subflow nodes + - Keep port label form in sync with output reordering + - Basic node label editor + - Port label editor starting point + - Allow port labels be i18n identifiers + - Add inputLabels and outputLabels to node defn + Update Change node + - Resize port labels based on content + - Initial port label behaviour + - Allow a node to decide for itself if its button should be enabled or not + - Provide feedback when enable/disable node fails + - Add node module update api and expose in palette editor + - Reset palette-manager tabs when settings dialog reopened + - Move palette editor to settings panel + - Move palette editor to userSettings dialog + - Move view and keyboard into user settings dialog + - Add basic user settings panel + - Node status should be on by default + - Make theme able to load custom javascript (#1211) + - Allow tips to be hidden and cycled through + - Add info tips back to the sidebar + - Add buffer mode to typedInput + - Add typedInput binary mode icon + - Ensure all ace editors are destroyed in the expression editors + - Refresh sidebar info when tab is changed + - better spacing for library widget + - Fix gridSize for node width calculation to avoid odd resizing + - Redraw grid properly if gridSize changes + - Scroll sidebar info tab to top when changing content + - Ensure info tab sections are collapsible when set from palette + - Only show tab info if there is an active tab + - Only check for reordered outputs if outputMap defiend + - Avoid circular references when stingifying node objects + - Fix padding of config node edit dialog + - Add force-deploy option when conflict detected + - Hide tip box on startup if disabled + - Track node moves separately to node config changes + - Ensure ace editor instances are freed if edit cancelled + - Clip overly long notification messages + - Use queryCommandSupported not queryCommandEnabled to check for copy support + - Add tip to tab description editor + - Make tab info edit box resizable + - Shrink config node appearance in info table + - Display config nodes in Info sidebar table + - Ensure flow info box updates after editing flow + - Hide Node info section when displaying changelog + - Restructure info tab + - Provide notification when new flows deployed in the background + - Stop some ui elements from clearing url anchor when clicked + - clipboard export text stay highlighted even when button deselected + - ensure export clipboard keeps text selected and formatted + - Defer resizing tray components until they have finished building + - Use pre-calculated values for connection path + - Use textContent to avoid manual escaping + - Add RED.stack as a common ui component + - Numeric validator that accepts blank should accept undefined + - Add visual cue as to whether the workspace is focused + - Allow RED.validators.number to allow blank values as valid + - Support dropping json files into the editor + - NLS Expression/JSON editor and fix their height calculation + - #1275 Update JSONata to 1.2.4 Closes + - Remember test expression data on a per-node basis + - NLS jsonata test messages + - Add JSONata expr tester and improved feedback + - Add $context/$flow/$global functions to jsonata + - Update jsonata + +Other + + - add allow es6 to .jshintrc + - travis - don't allow node 8 fails, (and re-add 7) + - ask istanbul for more reports as default + - Add istanbul to Gruntfile.js (#1189) + + +#### 0.16.2: Maintenance Release + + - #1126 Ensure custom mustache context parent set in Template node fixes + - Display debug node name in debug panel if its known + - Ensure auth-tokens are removed when no user is specified in settings + - Ensure all a tags have blank target in info sidebar + - Ensure links do not span tabs in the editor + - Avoid creating multiple reconnect timers in websocket node + - #1120 Fix inner reference in install fail message catalog entry Fixes + - Display buffer data properly for truncated buffers under Object property + +#### 0.16.1: Maintenance Release + + - Add colour swatches to debug when hex colour matched + - Nodes with hasUsers set to false should not appear unused + - Change hard error to verbose warning if using old node.js level + - #1117 Don't filter debug properties starting with _ Fixes + - #1116 Node logged errors not displayed properly in debug pane Fixes + - #1114 Do not look for existing nodes when checking for wires on paste Fixes + - -v option not enabling verbose mode properly + - Add node.js version check on startup + +#### 0.16.0: Milestone Release + +Runtime + + - Drop support for node 0.10 and 0.12 + +Nodes + + - #1103 Add option to colourise debug console output Closes + - Add property validation to nodes using typedInput + - #1104 Add common validator for typedInput fields Closes + - #1094 Update debug node console logging indicator icon Closes + - Let exec node (spawn) handle commands with spaces in path + - Add symbol to debug node to indicate debugging also to console.log + - Change file node to use node 4 syntax (drops support for 0.8) + - add info for httprequest responseUrl property + - Add res.responseUrl to httprequest node response + - Add support for flow and global context in Template node (#1048) + - Added YAML parser node (#1034) + - node-red-node-serialport removed as a default node + +Editor + + - #1109 Add install/remove dialog to increase friction Closes + - #1009 Report node catalogue load errors Closes + - #1043 Properly report module remove errors in palette editor Fixes + - Update rather than hide install button after success install + - Tweak search box styling + - Display info tips slightly longer + - Allow tips to be enabled/disabled via menu option + - Info-tips update + - Make typedInput keyboard navigable + - update Font Awesome to 4.7.0 + - Add expression editor for jsonata + - Overhaul keyboard handling and introduce editor actions + - Add Japanese translation file(editor.json) (#1084) + - Add quick-add node mode with cmd/ctrl-click + - Add cmd/ctrl-click to quick add wires + - Use json-stringify-safe to detect circular references in debug msgs + - debug - format if time if correct length/range + - Make Debug object explorable + - Initial debug pop-out window + - Add proper three-way diff view + - Focus tray body when edit dialog opened + - Hit enter to edit first node in selection + - Add node delete button to edit dialog + - #832 Add notification when runtime stopped due to missing types Part of + +Fixes + + - #1111 Do not tie debug src loading to needsPermission Fixes + - #1095 Initialise nodeApp regardless of httpAdmin setting Closes #1096 + - Speed up reveal of search dialogs + - #1069 Ensure flows exist before delegating status/error events Fixes + - Update package dependencies + - Update MQTT to latest 2.2.1 + - Node status not being refreshed properly in the editor + - #1081 Try to prevent auto-fill of password fields in node edit tray Fixes + - Fix whitespace in localfilesystem + - fix bug where savesettings did not honor local settings variables (#1073) + - #922 Tidy up unused/duplicate editor messages Closes + - Property expressions must not be blank + - Tidy up merge commit of validatePropertyExpression + - add port if wires array > number of ports declared. + - #1101 Allow quoted property expressions Fixes + - Index all node properties for node search + - Remove node 0.10 from travis config + - update welcome message to use logger so it can be turned off/on if required (#1083) + - Fix dynamically loading multiple node-sets from palette editor + - #1031 Allow a node to reorder its outputs and maintain links Fixes + +#### 0.15.3: Maintenance Release + + - Tcpgetfix: Another small check (#1070) + - TCPGet: Ensure done() is called only once (#1068) + - #1063 Allow $ and _ at start of property identifiers Fixes + - TCPGet: Separated the node.connected property for each instance (#1062) + - Corrected 'overide' typo in XML node help (#1061) + - TCPGet: Last property check (hopefully) (#1059) + - Add additional safety checks to avoid acting on non-existent objects (#1057) + - add --title for process name to command line options + - add indicator for fire once on inject node + - reimplement $(env var) replace to share common code. + - Fix error message for missing node html file, and add test. + - Let credentials also use $(...) substitutions from ENV + - Rename insecureRedirect to requireHttps + - Add setting to cause insecure redirect (#1054) + - Palette editor fixes (#1033) + - Close comms on stopServer in test helper (#1020) + - Tcpgetfix (#1050) + - TCPget: Store incoming messages alongside the client object to keep reference + - Merge remote-tracking branch 'upstream/master' into tcpgetfix + - TCPget can now handle concurrent sessions (#1042) + - Better scope handling + - Add security checks + - small change to udp httpadmin + - Fix comparison to "" in tcpin + - Change scope of clients object + - Works when connection is left open + - First release of multi connection tcpget + - Fix node.error() not printing when passed false (#1037) + - fix test for CSV array input + - different test for Pi (rather than use serial port name) + - Fix missing 0 handling for css node with array input + + +#### 0.15.2: Maintenance Release + + - #1024 Revert bidi changes to nodes and hide menu option until fixed Fixes + - Let xml node set options both ways + - Bump serialport to use version 4 + - gpio node handle multiple bits of data returned in one go + - #1023 HTTP In should pass application/octet-stream as buffer not string Fixes + - Handle missing httpNodeRoot setting properly + - Config sidebar not handling node definition error properly + - Add minimum show time to deploy spinner to avoid flicker + - Add work-in-progress update button to palette-editor + - Add log.removeHandler function + - Add Crtl/Shift/p shortcut for manage palette + - Add spinner to deploy button + - #1016 Status messages from nodes in subflows not delegated properly Fixes + - fix spelling in join node info + - Speed up tab scrolling + - #1013 Update delay burst test to be more tolerant of timing Fixes + +#### 0.15.1: Maintenance Release + + - Update default palette catalogue to use https + - Disable palette editor if npm not found - and fix for Windows + - #1010 Searching package catalogue should be case-insensitive Fixes + - #1011 contenteditable fields not handled in config nodes Fixes + - Change html link refs from `_new` to `_blank` to be standards compliant + +#### 0.15.0: Milestone Release + +Runtime + + - #1001 Increase default apiMaxLength to 5mb and add to default settings Closes + - Add v2 /flows api and deploy-overwrite protection + - Encrypt credentials by default + - Ensure errors thrown by RED.events handlers don't percolate up + +Editor + + - Mark nodes as changed when they are moved + - Added parent containment option for draggable. (#1006) + - #999 Ignore bidi event handling on non-existent and non-Input elements Closes + - Remove list of flows from menu + - Allow nodes to be imported with their credentials + - Add workspace search option + - Add scrollOnAdd option to editableList + - Add swift markup to editor for open whisk node + - Scrollable tabs 👍 + - Allow linking to individual flow via url hash + - Avoid duplicating existing subflows on import + - Add import-to-new-tab option + - Add new options to export-nodes dialog + - Stop nodes being added beyond the outer bounds of the workspace + - #972 Default config nodes to global scope unless in a subflow Closes + - Bidi support for Text Direction and Structured Text (#961) + - Fix jQuery selector, selecting more than one help pane/popover and displaying incorrectly. (#970) + - Fixes removeItem not passing row data to callback. (#965) + - Move common components and add searchBox + - Add initial palette sidebar + +Nodes + + - Inject node label - show topic for timestamp mode if short + - Let change node set type if total match + - Clean up status on close for several core nodes. + - Change node: re-parse JSON set value each time to avoid pass-by-ref + - Better handle HTTP Request header capitalisation + - #985 Enable ES6 parsing in Function editor by default Fixes + - Update debug sidebar to use RED.view.reveal to show debug nodes + - Add full path tip to file node, And tidy up Pi node tips + - Remove WebSocket node maxlistener warning + - Update mqtt-broker node to use fully name-space qualified status messages + - Let UDP node better share same port instance if required + - Add number of units to the delay node (rate) (#994) + - Allow http middleware to skip rawBodyParser + - Let change node move property to sub-property. + - Add info to exec warning about buffered output if using python + - TCP node: pass on latest input msg properties + - Make sure MQTT broker is really set + - Fix escape character catch in TCPGet + support 0x?? sequences + - Fix split character in TCP Request node + - Add CSS highlighting to the template node (#950) + - Only update switch previous value after all rules are run + +Other + + - #660 Add npm build/test scripts Closes #946 + - Move travis to node 6 and 7 - drop 5 and 0.12 + + +#### 0.14.6: Maintenance Release + +Fixes + + - #927 Tell ace about Function node globals. Closes + - #935 Tidy up mqtt nodes - linting and done handling. Closes + - Fix invalid html in TCP and HTML node edit templates + - Add proper help text to link nodes + - Handle importing old mqtt-broker configs that lack properties + - Update ace to 1.2.4 + - Allow config nodes to provide a sort function for their select list + - Add log warning if node module required version cannot be satisfied + - #937 Handle empty credentials file. Closes + - Add RPi.GPIO lib test for ArchLinux + +#### 0.14.5: Maintenance Release + +Fixes + + - Cannot clear cookies with http nodes + - let HTML parse node allow msg.select set select + - Validate nodes on import after any references have been remapped + - #933 Debug node handles objects without constructor property Fixes + - #940 Ensure 'false' property values are displayed in info panel Fixes + - Fix node enable/disable over restart - load configs after settings init + +#### 0.14.4: Maintenance Release + +Nodes + + - Update trigger node ui to use typedInputs + - Better handling of quotes in CSV node + - #929 Clarify the MQTT node sends msg.payload - closes + - #914 Inject node should reuse the message it is triggered with Closes + - Stop trigger node re-using old message + - Allow node.status text to be 'falsey' values + +Fixes + + - #932 Handle DOMException when embedded in an iframe of different origin Fixes + - Fix double firing of menu actions + - #928 Fix select box handling in Safari - fixes + - #858 Clear context in node test helper Fixes + - #880 Allow node properties to be same as existing object functions Fixes + - Handle comms link closing whilst completing the initial connect + - #917 Protect against node type names that clash with Object property names Fixes + - Clone default node properties to avoid reference leakage + - Strip tab node definition when exporting + - Check for null config properties in editor before over-writing them + - Add hasUsers flag to config nodes + +Editor + + - Add sql mode to ace editor + - Keyboard shortcuts dialog update (#923) + - #921 Ensure importing link nodes to a subflow doesn't add outbound links Fixes + - Add updateConfigNodeUsers function to editor + - Scroll to bottom when item added to editableList + - #920 Form input widths behave more consistently when resizing Fixes #919 + +#### 0.14.3: Maintenance Release + +Fixes + + - #908 Create default setting.js in user-specified directory. Fixes + - MQTT In subscription qos not defaulting properly + - Let exec node handle 0 as well as "0" + +#### 0.14.2: Maintenance Release + +Fixes + + - #913 Cannot add new twitter credentials. Fixes + - Support array references in Debug property field + +#### 0.14.1: Maintenance Release + +Fixes + + - Handle undefined property that led to missing wires in the editor + - #911 Remove duplicate 'Delete' entry in keyboard shortcut window. Closes + - #910 Add 'exec' to node-red-pi launch script. Closes + +#### 0.14.0: Milestone Release + +Editor + + - Replace edit dialog with edit tray + - Enable shift-drag detach of just the selected link + - Allow workspace tabs to be re-ordered + - Scope keyboard shortcuts to dom elements + - Ensure parent nodes marked as changed due to child config node changes + - Validate all edit dialog inputs when one changes + - Add editableList widget and update Switch/Change nodes to use it + - Add option to filter Debug sidebar by flow and highlight subflow-emitting nodes + - Back off comms reconnect attempts after prolonged failures + - Prompt for login if comms reconnect fails authentication + - Change style of nodes in subflow template view + - Add CHANGELOG.md and make it accessible from menu + +Runtime + + - Always log node warnings on start without requiring -v + - #885 Add support for loading scoped node modules. Closes + - Add process.env.PORT to settings.js + - #870 Clear node context on deploy. Closes + - Enable finer grained permissions in adminAuth + +Nodes + + - Enable config nodes to reference other config nodes + - Add Split/Join nodes + - Add Link nodes + - #904 Add support to HTTP In node for PATCH requests. Closes + - Add cookie handling to HTTP In and HTTP Response nodes + - #887 Add repeat indicator to inject node label. Closes + - Add javascript highlighter to template node + - Add optional timeout to exec node + - Add TLS node and update MQTT/HTTP nodes to use it + - Let trigger node also send last payload to arrive + - Add timestamp as a default typedInput and update Inject and change nodes to match, + - Add QoS option to MQTT In node + - Add status to exec spawn mode + - Add Move capability to Change node + - Update Serial node to support custom baud rates + - Add support for array-syntax in typedInput msg properties + - Add RED.util to Function node sandbox + - #879 Capture error stack on node.error. Closes + + +Fixes + + - Add error handling to all node definition api calls + - Handle null return from Function node in array of messages + - #895 Defer loading of token sessions until they are accessed. Fixes + - set pi gpio pin status correctly if set on start + - #635 Prevent parent window scrolling when view is focused. Fixes + - Handle missing tab nodes in a loaded flow config + - Ensure typedInput dropdown doesn't fall off the page + - #880 Protect against node types with reserved names such as toString. Fixes + - Do not rely on the HTML file to identify where nodes are registered from + - Preserve node properties on import + - Fix regression in delay node. topic based queue was emptying all the time instead of spreading out messages. + - Throw an error if a Function node adds an input event listener + - Fix hang on partial deploy with disconnected mqtt node + - TypedInput: preload type icons to ensure width calc correct + - Ensure tcp node creates a buffer of size 1 at least + - Return editorTheme default if value is undefined + - Fix RED.util.compareObjects for Function created objects and Buffers + - Ensure default settings copied to command-line specified userDir + + +#### 0.13.4: Maintenance Release + + - Add timed release mode to delay node + - #811 Enable link splicing for when import_dragging nodes. Closes + - Fix uncaught exception on deploy whilst node sending messages + - Deprecate old mqtt client and connection pool modules + - #835 Change node: add bool/num types to change mode Closes + - #825 Validate fields that are `$(env-vars)` Closes + - Handle missing config nodes when validating node properties + - Pi node - don't try to send data if closing + - Load node message catalog when added dynamically + - Split palette labels on spaces and hyphens when laying out + - #816 Warn if editor routes are accessed but runtime not started Closes + - #819 Better handling of zero-length flow files Closes + - Allow runtime calls to RED._ to specify other namespace + - Better right alignment of numerics in delay and trigger nodes + - Allow node modules to include example flows + - Create node_modules in userDir + - #815 Ensure errors in node def functions don't break view rendering Fixes + - Updated Inject node info with instructions for flow and global options + + + +#### 0.13.3: Maintenance Release + + - Fix crash on repeated inject of invalid json payload + - Add binary mode to tail node + - Revert Cheerio to somewhat smaller version + - Add os/platform info to default debug + + + +#### 0.13.2: Maintenance Release + + - Don't force reconnect mqtt client if message arrives (fixes the MQTT connect/disconnect endless cycle) + - Add -p/--port option to override listening port + - Invert config node filter toggle button colours so state is more obvious + - Add timeout to httprequest node + - Tidy up of all node info content - make style consistent + - Make jquery spinner element css consistent with other inputs + - tcp node add reply (to all) capability + - Allow the template node to be treated as plain text + - #792 Validate MQTT In topics Fixes + - #793 httpNodeAuth should not block http options requests Fixes + - Disable perMessageDeflate on WS servers - fixes 'zlib binding closed' error + - Clear trigger status icon on re-deploy + - Don't default inject payload to blank string + - Trigger node, add configurable reset + - #790 - fixes use of httpNodeMiddleware Allow function properties in settings Fixes + - Fix order of config dialog calls to save/creds/validate + - Add debounce to Pi GPIO node + + + +#### 0.13.1: Maintenance Release + + - Revert wrapping of http request object + + + +#### 0.13.0: Milestone Release + + - Add 'previous value' option to Switch node + - Allow existing nodes to splice into links on drag + - #783 CORS not properly configured on multiple http routes Fixes + - Restore shift-drag to snap/unsnap to grid + - Moving nodes with keyboard should flag workspace dirty + - Notifications flagged as fixed should not be click-closable + - Rework config sidebar and deploy warning + - Wrap http request object to match http response object + - Add 'view' menu and reorganise a few things + - Allow shift-click to detach existing wires + - Splice nodes dragged from palette into links + - try to trim imported/dragged flows to [ ] + - Move version number as title of NR logo + - Moving nodes mark workspace as dirty + - Ok/Cancel edit dialogs with Ctrl-Enter/Escape + - Handle OSX Meta key when selecting nodes + - Add grid-alignment options + - Add oneditresize function definition + - Rename propertySelect to typedInput and add boolean opt + - Add propertySelect to switch node + - Add propertySelect support to Change node + - Add context/flow/global support to Function node + - Add node context/flow/global + - Add propertySelect jquery widget + - Add add/update/delete flow apis + - Allow core nodes dir to be provided to runtime via settings + - Tidy up API passed to node modules + - Move locale files under api/runtime components + - Add flow reload admin api + + + +#### 0.12.5: Maintenance Release + + - Add attribute capability to HTML parser node + - Add Pi Keyboard code node + - Fix for MQTT client connection cycling on partial deploy + - Fix for tcp node properly closing connections + - Update sentiment node dependencies + - Fix for file node handling of UTF8 extended characters + + + +#### 0.12.4: Maintenance Release + + - Add readOnly setting to prevent file writes in localfilesystem storage + - Support bcrypt for httpNodeAuth + - Pi no longer needs root workaround to access gpio + - Fix: Input File node will not retain the file name + + + +#### 0.12.3: Maintenance Release + + - Fixes for TCP Get node reconnect handling + - Clear delay node status on re-deploy + - Update Font-Awesome to v4.5 + - Fix trigger to block properly until reset + - Update example auth properties in settings.js + - Ensure httpNodeAuth doesn't get applied to admin routes + - TCP Get node not passing on existing msg properties + + + +#### 0.12.2: Maintenance Release + + - Enable touch-menu for links so they can be deleted + - Allow nodes to be installed by path name + - Fix basic authentication on httpNode/Admin/Static + - Handle errors thrown in Function node setTimeout/Interval + - Fix mqtt node lifecycle with partial deployments + - Update tcp node status on reconnect after timeout + - Debug node not handling null messages + - Kill processes run with exec node when flows redeployed + - Inject time spinner incrementing value incorrectly + + + +#### 0.12.1: Maintenance Release + + - Enable touch-menu for links so they can be deleted + - Allow nodes to be installed by path name + - Fix basic authentication on httpNode/Admin/Static + + + +#### 0.12.0: Milestone Release + + - Change/Switch rules now resize with dialog width + - Support for node 4.x + - Move to Express 4.x + - Copy default settings file to user dir on start up + - Config nodes can be scoped to a particular subflow/tab + - Comms link tolerates <5 second breaks in connection before notifying user + - MQTT node overhaul - add will/tls/birth message support + - Status node - to report status events from other nodes + - Error node can be targeted to specific other nodes + - JSON node can encode Array types + - Switch node regular expression rule can now be set to be case-insensitive + - HTTP In node can accept non-UTF8 payloads - will return a Buffer when appropriate + - Exec node configuration consistent regardless of the spawn option + - Function node can now display status icon/text + - CSV node can now handle arrays + - setInterval/clearInterval add to Function node + - Function node automatically clears all timers (setInterval/setTimeout) when the node is stopped + + + +#### 0.11.2: Maintenance Release + + - Allow XML parser options be set on the message + - Add 'mobile' category to the palette (no core nodes included) + - Allow a message catalog provide a partial translation + - Fix HTTP Node nls message id + - Remove delay spinner upper limit + - Update debug node output to include length of payload + + + + +#### 0.11.1: Maintenance Release + + - Fix exclusive config node check when type not registered (prevented HTTP In node from being editable unless the swagger node was also installed) + + + +#### 0.11.0: Milestone Release + + - Add Node 0.12 support + - Internationalization support + - Editor UI refresh + - Add RBE node + - File node optionally creates path to file + - Function node can access `clearTimeout` + - Fix: Unable to login with 'read' permission + + + +#### 0.10.10: Maintenance Release + + - Fix permissions issue with packaged nrgpio script + - Add better help message if deprecated node missing + + + +#### 0.10.9: Maintenance Release + +Fix packaging of bin scripts + + + +#### 0.10.8: Maintenance Release + + - Nodes moved out of core + - still included as a dependency: twitter, serial, email, feedparser + - no longer included: mongo, arduino, irc, redis + - node icon defn can be a function + - http_proxy support + - httpNodeMiddleware setting + - Trigger node ui refresh + - editorTheme setting + - Warn on deploy of unused config nodes + - catch node prevents error loops + + + +#### 0.10.6: Maintenance Release + +Changes: + - Performance improvements in editor + - Palette appearance update + - Warn on navigation with undeployed changes + - Disable undeployed node action buttons + - Disable subflow node action buttons + - Add Catch node + - Add logging functions to Function node + - Add send function to Function node + - Update Change node to support multiple rules + + + +#### 0.10.4: Maintenance Release + +Changes: + + - http request node passes on request url as msg.url + - handle config nodes appearing out of order in flow file - don't assume they are always at the start + - move subflow palette category to the top, to make it more obvious + - fix labelling of Raspberry Pi pins + - allow email node to mark mail as read + - fix saving library content + - add node-red and node-red-pi start scripts + - use $HOME/.node-red for user data unless specified otherwise (or existing data is found in install dir) + + + +#### 0.10.3: Maintenance Release + +Fixes: + + - httpAdminAuth was too aggressively deprecated (ie removed); restoring with a console warning when used + - adds reporting of node.js version on start-up + - mongo node skip/limit options can be strings or numbers + - CSV parser passes through provided message object + + + +#### 0.10.2: Maintenance Release + +Fixes: + - subflow info sidebar more useful + - adds missing font-awesome file + - inject node day selection defaulted to invalid selection + - loading a flow with no tabs failed to add nodes to default tab diff --git a/packages/connector/CODE_OF_CONDUCT.md b/packages/connector/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..b3c6806 --- /dev/null +++ b/packages/connector/CODE_OF_CONDUCT.md @@ -0,0 +1,74 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or +advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at team@nodered.org. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/packages/connector/CONTRIBUTING.md b/packages/connector/CONTRIBUTING.md new file mode 100644 index 0000000..f0f4096 --- /dev/null +++ b/packages/connector/CONTRIBUTING.md @@ -0,0 +1,57 @@ +# Contributing to Node-RED + +We welcome contributions, but request you follow these guidelines. + + - [Raising issues](#raising-issues) + - [Feature requests](#feature-requests) + - [Pull-Requests](#pull-requests) + - [Contributor License Agreement](#contributor-license-agreement) + +This project adheres to the [Contributor Covenant 1.4](http://contributor-covenant.org/version/1/4/). +By participating, you are expected to uphold this code. Please report unacceptable +behavior to the project's core team at team@nodered.org. + +## Raising issues + +Please raise any bug reports on the relevant project's issue tracker. Be sure to +search the list to see if your issue has already been raised. + +A good bug report is one that make it easy for us to understand what you were +trying to do and what went wrong. + +Provide as much context as possible so we can try to recreate the issue. +If possible, include the relevant part of your flow. To do this, select the +relevant nodes, press Ctrl-E and copy the flow data from the Export dialog. + +At a minimum, please include: + + - Version of Node-RED - either release number if you downloaded a zip, or the first few lines of `git log` if you are cloning the repository directly. + - Version of Node.js - what does `node -v` say? + +## Feature requests + +For feature requests, please raise them on the [forum](https://discourse.nodered.org). + +## Pull-Requests + +If you want to raise a pull-request with a new feature, or a refactoring +of existing code, it may well get rejected if you haven't discussed it on +the [forum](https://discourse.nodered.org) first. + +All contributors need to sign the JS Foundation's Contributor License Agreement. +It is an online process and quick to do. You can read the details of the agreement +here: https://cla.js.foundation/node-red/node-red. + +If you raise a pull-request without having signed the CLA, you will be prompted +to do so automatically. + + +### Coding standards + +Please ensure you follow the coding standards used through-out the existing +code base. Some basic rules include: + + - all files must have the Apache license in the header. + - indent with 4-spaces, no tabs. No arguments. + - opening brace on same line as `if`/`for`/`function` and so on, closing brace + on its own line. diff --git a/packages/connector/Gruntfile.js b/packages/connector/Gruntfile.js new file mode 100644 index 0000000..7f7e80f --- /dev/null +++ b/packages/connector/Gruntfile.js @@ -0,0 +1,642 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var path = require("path"); +var fs = require("fs-extra"); +var sass = require("node-sass"); + +module.exports = function(grunt) { + + var nodemonArgs = ["-v"]; + var flowFile = grunt.option('flowFile'); + if (flowFile) { + nodemonArgs.push(flowFile); + } + + var browserstack = grunt.option('browserstack'); + if (browserstack) { + process.env.BROWSERSTACK = true; + } + var nonHeadless = grunt.option('non-headless'); + if (nonHeadless) { + process.env.NODE_RED_NON_HEADLESS = true; + } + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + paths: { + dist: ".dist" + }, + simplemocha: { + options: { + globals: ['expect'], + timeout: 3000, + ignoreLeaks: false, + ui: 'bdd', + reporter: 'spec' + }, + all: { src: ['test/**/*_spec.js'] }, + core: { src: ["test/_spec.js","test/unit/**/*_spec.js"]}, + nodes: { src: ["test/nodes/**/*_spec.js"]} + }, + webdriver: { + all: { + configFile: 'test/editor/wdio.conf.js' + } + }, + mocha_istanbul: { + options: { + globals: ['expect'], + timeout: 3000, + ignoreLeaks: false, + ui: 'bdd', + reportFormats: ['lcov','html'], + print: 'both', + istanbulOptions: ['--no-default-excludes', '-i','**/packages/node_modules/**'] + }, + all: { src: ["test/unit/_spec.js","test/unit/**/*_spec.js","test/nodes/**/*_spec.js"] }, + core: { src: ["test/unit/_spec.js","test/unit/**/*_spec.js"]}, + nodes: { src: ["test/nodes/**/*_spec.js"]} + }, + jshint: { + options: { + jshintrc:true + // http://www.jshint.com/docs/options/ + //"asi": true, // allow missing semicolons + //"curly": true, // require braces + //"eqnull": true, // ignore ==null + //"forin": true, // require property filtering in "for in" loops + //"immed": true, // require immediate functions to be wrapped in ( ) + //"nonbsp": true, // warn on unexpected whitespace breaking chars + ////"strict": true, // commented out for now as it causes 100s of warnings, but want to get there eventually + //"loopfunc": true, // allow functions to be defined in loops + //"sub": true // don't warn that foo['bar'] should be written as foo.bar + }, + // all: [ + // 'Gruntfile.js', + // 'red.js', + // 'packages/**/*.js' + // ], + // core: { + // files: { + // src: [ + // 'Gruntfile.js', + // 'red.js', + // 'packages/**/*.js', + // ] + // } + // }, + nodes: { + files: { + src: [ 'nodes/core/*/*.js' ] + } + }, + editor: { + files: { + src: [ 'packages/node_modules/@node-red/editor-client/src/js/**/*.js' ] + } + }, + tests: { + files: { + src: ['test/**/*.js'] + }, + options: { + "expr": true + } + } + }, + concat: { + options: { + separator: ";", + }, + build: { + src: [ + // Ensure editor source files are concatenated in + // the right order + "packages/node_modules/@node-red/editor-client/src/js/jquery-addons.js", + "packages/node_modules/@node-red/editor-client/src/js/red.js", + "packages/node_modules/@node-red/editor-client/src/js/events.js", + "packages/node_modules/@node-red/editor-client/src/js/i18n.js", + "packages/node_modules/@node-red/editor-client/src/js/settings.js", + "packages/node_modules/@node-red/editor-client/src/js/user.js", + "packages/node_modules/@node-red/editor-client/src/js/comms.js", + "packages/node_modules/@node-red/editor-client/src/js/text/bidi.js", + "packages/node_modules/@node-red/editor-client/src/js/text/format.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/state.js", + "packages/node_modules/@node-red/editor-client/src/js/nodes.js", + "packages/node_modules/@node-red/editor-client/src/js/font-awesome.js", + "packages/node_modules/@node-red/editor-client/src/js/history.js", + "packages/node_modules/@node-red/editor-client/src/js/validators.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/utils.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/common/checkboxSet.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/common/menu.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/common/panels.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/common/popover.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/common/searchBox.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/common/tabs.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/common/stack.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/actions.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/diff.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/keyboard.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/statusBar.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/view.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/view-navigator.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/sidebar.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/palette.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/editor.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/editors/*.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/event-log.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/tray.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/library.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/notifications.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/search.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/actionList.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/typeSearch.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/userSettings.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectUserSettings.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/projects/tab-versionControl.js", + "packages/node_modules/@node-red/editor-client/src/js/ui/touch/radialMenu.js" + ], + dest: "packages/node_modules/@node-red/editor-client/public/red/red.js" + }, + vendor: { + files: { + "packages/node_modules/@node-red/editor-client/public/vendor/vendor.js": [ + "packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-3.4.1.min.js", + "packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-migrate-3.0.1.min.js", + "packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-ui.min.js", + "packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery.ui.touch-punch.min.js", + "node_modules/marked/marked.min.js", + "node_modules/dompurify/dist/purify.min.js", + "packages/node_modules/@node-red/editor-client/src/vendor/d3/d3.v3.min.js", + "packages/node_modules/@node-red/editor-client/src/vendor/i18next/i18next.min.js", + "node_modules/jsonata/jsonata-es5.min.js", + "packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js", + "packages/node_modules/@node-red/editor-client/src/vendor/ace/ace.js", + "packages/node_modules/@node-red/editor-client/src/vendor/ace/ext-language_tools.js", + ], + // "packages/node_modules/@node-red/editor-client/public/vendor/vendor.css": [ + // // TODO: resolve relative resource paths in + // // bootstrap/FA/jquery + // ], + "packages/node_modules/@node-red/editor-client/public/vendor/ace/worker-jsonata.js": [ + "node_modules/jsonata/jsonata-es5.min.js", + "packages/node_modules/@node-red/editor-client/src/vendor/jsonata/worker-jsonata.js" + ] + } + } + }, + uglify: { + build: { + files: { + 'packages/node_modules/@node-red/editor-client/public/red/red.min.js': 'packages/node_modules/@node-red/editor-client/public/red/red.js', + 'packages/node_modules/@node-red/editor-client/public/red/main.min.js': 'packages/node_modules/@node-red/editor-client/public/red/main.js', + 'packages/node_modules/@node-red/editor-client/public/vendor/ace/mode-jsonata.js': 'packages/node_modules/@node-red/editor-client/src/vendor/jsonata/mode-jsonata.js', + 'packages/node_modules/@node-red/editor-client/public/vendor/ace/snippets/jsonata.js': 'packages/node_modules/@node-red/editor-client/src/vendor/jsonata/snippets-jsonata.js' + } + } + }, + sass: { + build: { + options: { + implementation: sass, + outputStyle: 'compressed' + }, + files: [{ + dest: 'packages/node_modules/@node-red/editor-client/public/red/style.min.css', + src: 'packages/node_modules/@node-red/editor-client/src/sass/style.scss' + }] + } + }, + jsonlint: { + messages: { + src: [ + 'packages/node_modules/@node-red/nodes/locales/**/*.json', + 'packages/node_modules/@node-red/editor-client/locales/**/*.json', + 'packages/node_modules/@node-red/runtime/locales/**/*.json' + ] + }, + keymaps: { + src: [ + 'packages/node_modules/@node-red/editor-client/src/js/keymap.json' + ] + } + }, + attachCopyright: { + js: { + src: [ + 'packages/node_modules/@node-red/editor-client/public/red/red.min.js', + 'packages/node_modules/@node-red/editor-client/public/red/main.min.js' + ] + }, + css: { + src: [ + 'packages/node_modules/@node-red/editor-client/public/red/style.min.css' + ] + } + }, + clean: { + build: { + src: [ + "packages/node_modules/@node-red/editor-client/public/red", + "packages/node_modules/@node-red/editor-client/public/index.html", + "packages/node_modules/@node-red/editor-client/public/favicon.ico", + "packages/node_modules/@node-red/editor-client/public/icons", + "packages/node_modules/@node-red/editor-client/public/vendor" + ] + }, + release: { + src: [ + '<%= paths.dist %>' + ] + } + }, + watch: { + js: { + files: [ + 'packages/node_modules/@node-red/editor-client/src/js/**/*.js' + ], + tasks: ['copy:build','concat',/*'uglify',*/ 'attachCopyright:js'] + }, + sass: { + files: [ + 'packages/node_modules/@node-red/editor-client/src/sass/**/*.scss' + ], + tasks: ['sass','attachCopyright:css'] + }, + json: { + files: [ + 'packages/node_modules/@node-red/nodes/locales/**/*.json', + 'packages/node_modules/@node-red/editor-client/locales/**/*.json', + 'packages/node_modules/@node-red/runtime/locales/**/*.json' + ], + tasks: ['jsonlint:messages'] + }, + keymaps: { + files: [ + 'packages/node_modules/@node-red/editor-client/src/js/keymap.json' + ], + tasks: ['jsonlint:keymaps','copy:build'] + }, + misc: { + files: [ + 'CHANGELOG.md' + ], + tasks: ['copy:build'] + } + }, + + nodemon: { + /* uses .nodemonignore */ + dev: { + script: 'packages/node_modules/node-red/red.js', + options: { + args: nodemonArgs, + ext: 'js,html,json', + watch: [ + 'packages/node_modules', + '!packages/node_modules/@node-red/editor-client' + ] + } + } + }, + + concurrent: { + dev: { + tasks: ['nodemon', 'watch'], + options: { + logConcurrentOutput: true + } + } + }, + + copy: { + build: { + files:[ + { + src: 'packages/node_modules/@node-red/editor-client/src/js/main.js', + dest: 'packages/node_modules/@node-red/editor-client/public/red/main.js' + }, + { + src: 'packages/node_modules/@node-red/editor-client/src/js/keymap.json', + dest: 'packages/node_modules/@node-red/editor-client/public/red/keymap.json' + }, + { + cwd: 'packages/node_modules/@node-red/editor-client/src/images', + src: '**', + expand: true, + dest: 'packages/node_modules/@node-red/editor-client/public/red/images/' + }, + { + cwd: 'packages/node_modules/@node-red/editor-client/src/vendor', + src: [ + 'ace/**', + 'jquery/css/base/**', + 'font-awesome/**' + ], + expand: true, + dest: 'packages/node_modules/@node-red/editor-client/public/vendor/' + }, + { + cwd: 'packages/node_modules/@node-red/editor-client/src/icons', + src: '**', + expand: true, + dest: 'packages/node_modules/@node-red/editor-client/public/icons/' + }, + { + expand: true, + src: ['packages/node_modules/@node-red/editor-client/src/index.html','packages/node_modules/@node-red/editor-client/src/favicon.ico'], + dest: 'packages/node_modules/@node-red/editor-client/public/', + flatten: true + }, + { + src: 'CHANGELOG.md', + dest: 'packages/node_modules/@node-red/editor-client/public/red/about' + }, + { + src: 'CHANGELOG.md', + dest: 'packages/node_modules/node-red/' + }, + { + cwd: 'packages/node_modules/@node-red/editor-client/src/ace/bin/', + src: '**', + expand: true, + dest: 'packages/node_modules/@node-red/editor-client/public/vendor/ace/' + } + ] + } + }, + chmod: { + options: { + mode: '755' + }, + release: { + src: [ + "packages/node_modules/@node-red/nodes/core/hardware/nrgpio", + "packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/node-red-*sh" + ] + } + }, + 'npm-command': { + options: { + cmd: "pack", + cwd: "<%= paths.dist %>/modules" + }, + 'node-red': { options: { args: [__dirname+'/packages/node_modules/node-red'] } }, + '@node-red/editor-api': { options: { args: [__dirname+'/packages/node_modules/@node-red/editor-api'] } }, + '@node-red/editor-client': { options: { args: [__dirname+'/packages/node_modules/@node-red/editor-client'] } }, + '@node-red/nodes': { options: { args: [__dirname+'/packages/node_modules/@node-red/nodes'] } }, + '@node-red/registry': { options: { args: [__dirname+'/packages/node_modules/@node-red/registry'] } }, + '@node-red/runtime': { options: { args: [__dirname+'/packages/node_modules/@node-red/runtime'] } }, + '@node-red/util': { options: { args: [__dirname+'/packages/node_modules/@node-red/util'] } } + + + }, + mkdir: { + release: { + options: { + create: ['<%= paths.dist %>/modules'] + }, + }, + }, + compress: { + release: { + options: { + archive: '<%= paths.dist %>/node-red-<%= pkg.version %>.zip' + }, + expand: true, + cwd: 'packages/node_modules/', + src: [ + '**', + '!@node-red/editor-client/src/**' + ] + } + }, + jsdoc : { + modules: { + src: [ + 'API.md', + 'packages/node_modules/node-red/lib/red.js', + 'packages/node_modules/@node-red/runtime/lib/index.js', + 'packages/node_modules/@node-red/runtime/lib/api/*.js', + 'packages/node_modules/@node-red/runtime/lib/events.js', + 'packages/node_modules/@node-red/util/**/*.js', + 'packages/node_modules/@node-red/editor-api/lib/index.js', + 'packages/node_modules/@node-red/editor-api/lib/auth/index.js' + ], + options: { + destination: 'docs', + configure: './jsdoc.json' + } + }, + _editor: { + src: [ + 'packages/node_modules/@node-red/editor-client/src/js' + ], + options: { + destination: 'packages/node_modules/@node-red/editor-client/docs', + configure: './jsdoc.json' + } + } + + }, + jsdoc2md: { + runtimeAPI: { + options: { + separators: true + }, + src: [ + 'packages/node_modules/@node-red/runtime/lib/index.js', + 'packages/node_modules/@node-red/runtime/lib/api/*.js', + 'packages/node_modules/@node-red/runtime/lib/events.js' + ], + dest: 'packages/node_modules/@node-red/runtime/docs/api.md' + }, + nodeREDUtil: { + options: { + separators: true + }, + src: 'packages/node_modules/@node-red/util/**/*.js', + dest: 'packages/node_modules/@node-red/util/docs/api.md' + } + } + }); + + grunt.loadNpmTasks('grunt-simple-mocha'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-clean'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-concurrent'); + grunt.loadNpmTasks('grunt-sass'); + grunt.loadNpmTasks('grunt-nodemon'); + grunt.loadNpmTasks('grunt-contrib-compress'); + grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadNpmTasks('grunt-chmod'); + grunt.loadNpmTasks('grunt-jsonlint'); + grunt.loadNpmTasks('grunt-mocha-istanbul'); + if (fs.existsSync(path.join("node_modules", "grunt-webdriver"))) { + grunt.loadNpmTasks('grunt-webdriver'); + } + grunt.loadNpmTasks('grunt-jsdoc'); + grunt.loadNpmTasks('grunt-jsdoc-to-markdown'); + grunt.loadNpmTasks('grunt-npm-command'); + grunt.loadNpmTasks('grunt-mkdir'); + + grunt.registerMultiTask('attachCopyright', function() { + var files = this.data.src; + var copyright = "/**\n"+ + " * Copyright JS Foundation and other contributors, http://js.foundation\n"+ + " *\n"+ + " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"+ + " * you may not use this file except in compliance with the License.\n"+ + " * You may obtain a copy of the License at\n"+ + " *\n"+ + " * http://www.apache.org/licenses/LICENSE-2.0\n"+ + " *\n"+ + " * Unless required by applicable law or agreed to in writing, software\n"+ + " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"+ + " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"+ + " * See the License for the specific language governing permissions and\n"+ + " * limitations under the License.\n"+ + " **/\n"; + + if (files) { + for (var i=0; i 0) { + failures.forEach(f => grunt.log.error(f)); + grunt.fail.fatal("Failed to verify package dependencies"); + } + done(); + }); + }); + + grunt.registerTask('verifyUiTestDependencies', function() { + if (!fs.existsSync(path.join("node_modules", "grunt-webdriver"))) { + grunt.fail.fatal('You need to install the UI test dependencies first.\nUse the script in "scripts/install-ui-test-dependencies.sh"'); + return false; + } + }); + grunt.registerTask('generatePublishScript', + 'Generates a script to publish build output to npm', + function () { + const done = this.async(); + const generatePublishScript = require("./scripts/generate-publish-script.js"); + generatePublishScript().then(function(output) { + grunt.log.writeln(output); + + const filePath = path.join(grunt.config.get('paths.dist'),"modules","publish.sh"); + grunt.file.write(filePath,output); + + done(); + }); + }); + grunt.registerTask('setDevEnv', + 'Sets NODE_ENV=development so non-minified assets are used', + function () { + process.env.NODE_ENV = 'development'; + }); + + grunt.registerTask('default', + 'Builds editor content then runs code style checks and unit tests on all components', + ['build','verifyPackageDependencies','jshint:editor','mocha_istanbul:all']); + + grunt.registerTask('test-core', + 'Runs code style check and unit tests on core runtime code', + ['build','mocha_istanbul:core']); + + grunt.registerTask('test-editor', + 'Runs code style check on editor code', + ['jshint:editor']); + + if (!fs.existsSync(path.join("node_modules", "grunt-webdriver"))) { + grunt.registerTask('test-ui', + 'Builds editor content then runs unit tests on editor ui', + ['verifyUiTestDependencies']); + } else { + grunt.registerTask('test-ui', + 'Builds editor content then runs unit tests on editor ui', + ['verifyUiTestDependencies','build','jshint:editor','webdriver:all']); + } + + grunt.registerTask('test-nodes', + 'Runs unit tests on core nodes', + ['build','mocha_istanbul:nodes']); + + grunt.registerTask('build', + 'Builds editor content', + ['clean:build','jsonlint','concat:build','concat:vendor','copy:build','uglify:build','sass:build','attachCopyright']); + + grunt.registerTask('dev', + 'Developer mode: run node-red, watch for source changes and build/restart', + ['build','setDevEnv','concurrent:dev']); + + grunt.registerTask('release', + 'Create distribution zip file', + ['build','verifyPackageDependencies','clean:release','mkdir:release','chmod:release','compress:release','pack-modules','generatePublishScript']); + + grunt.registerTask('pack-modules', + 'Create module pack files for release', + ['mkdir:release','npm-command']); + + + grunt.registerTask('coverage', + 'Run Istanbul code test coverage task', + ['build','mocha_istanbul:all']); + + grunt.registerTask('docs', + 'Generates API documentation', + ['jsdoc']); +}; diff --git a/packages/connector/LICENSE b/packages/connector/LICENSE new file mode 100644 index 0000000..fc619bd --- /dev/null +++ b/packages/connector/LICENSE @@ -0,0 +1,178 @@ +Copyright JS Foundation and other contributors, http://js.foundation + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/packages/connector/README.md b/packages/connector/README.md new file mode 100644 index 0000000..3baa693 --- /dev/null +++ b/packages/connector/README.md @@ -0,0 +1,70 @@ +# Node-RED + +http://nodered.org + +[![Build Status](https://travis-ci.org/node-red/node-red.svg?branch=master)](https://travis-ci.org/node-red/node-red) +[![Coverage Status](https://coveralls.io/repos/node-red/node-red/badge.svg?branch=master)](https://coveralls.io/r/node-red/node-red?branch=master) + +Low-code programming for event-driven applications. + +![Node-RED: Low-code programming for event-driven applications](http://nodered.org/images/node-red-screenshot.png) + +## Quick Start + +Check out http://nodered.org/docs/getting-started/ for full instructions on getting +started. + +1. `sudo npm install -g --unsafe-perm node-red` +2. `node-red` +3. Open + +## Getting Help + +More documentation can be found [here](http://nodered.org/docs). + +For further help, or general discussion, please use the [Node-RED Forum](https://discourse.nodered.org) or [slack team](https://nodered.org/slack). + +## Developers + +If you want to run the latest code from git, here's how to get started: + +1. Clone the code: + + git clone https://github.com/node-red/node-red.git + cd node-red + +2. Install the node-red dependencies + + npm install + +3. Build the code + + npm run build + +4. Run + + npm start + +## Contributing + +Before raising a pull-request, please read our +[contributing guide](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md). + +This project adheres to the [Contributor Covenant 1.4](http://contributor-covenant.org/version/1/4/). + By participating, you are expected to uphold this code. Please report unacceptable + behavior to any of the project's core team at team@nodered.org. + +## Authors + +Node-RED is a project of the [OpenJS Foundation](https://openjsf.org). + +It was created by [IBM Emerging Technology](https://www.ibm.com/blogs/emerging-technology/). + +* Nick O'Leary [@knolleary](http://twitter.com/knolleary) +* Dave Conway-Jones [@ceejay](http://twitter.com/ceejay) + + + +## Copyright and license + +Copyright JS Foundation and other contributors, https://openjsf.org under [the Apache 2.0 license](LICENSE). diff --git a/packages/connector/SECURITY.md b/packages/connector/SECURITY.md new file mode 100644 index 0000000..a52064d --- /dev/null +++ b/packages/connector/SECURITY.md @@ -0,0 +1,13 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| 1.0.0 | :white_check_mark: | +| 0.20.x | :white_check_mark: | + + +## Reporting a Vulnerability + +Please report any potential security issues to `team@nodered.org`. This will notify the core project team who will respond accordingly. diff --git a/packages/connector/custom.css b/packages/connector/custom.css new file mode 100644 index 0000000..4119c2c --- /dev/null +++ b/packages/connector/custom.css @@ -0,0 +1,8 @@ +#red-ui-header { + background-color: #E2E8F0; +} + +#red-ui-header .button { + border-left: 0; + border-right: 0; +} \ No newline at end of file diff --git a/packages/connector/jsdoc.json b/packages/connector/jsdoc.json new file mode 100644 index 0000000..d7f8810 --- /dev/null +++ b/packages/connector/jsdoc.json @@ -0,0 +1,25 @@ +{ + "opts": { + "template": "./node_modules/jsdoc-nr-template", + "destination": "./docs", + "recurse": true + }, + "tags": { + "allowUnknownTags": false, + "dictionaries": ["jsdoc"] + }, + "source": { + "_include": [ + "./packages/node_modules/@node-red/runtime/lib/api" + ] + }, + "templates": { + "systemName": "Node-RED Runtime API", + "footer": "", + "copyright": "Released under the Apache License v2.0", + "default": { + "outputSourceFiles": false + } + }, + "plugins": ["plugins/markdown"] +} diff --git a/packages/connector/package.json b/packages/connector/package.json new file mode 100644 index 0000000..e4f3c9c --- /dev/null +++ b/packages/connector/package.json @@ -0,0 +1,123 @@ +{ + "name": "@trycrypto/dappstarter-connector", + "version": "1.0.4", + "description": "Low-code programming for event-driven applications", + "homepage": "http://nodered.org", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/node-red/node-red.git" + }, + "private": "true", + "scripts": { + "start": "nodemon -V --delay 2.5 -- packages/node_modules/node-red/red.js --settings settings.js", + "dev": "wait-on ../dapplib/src/dapp-config.json && npm run build && npm run start", + "test": "grunt", + "build": "grunt build", + "docs": "grunt docs" + }, + "contributors": [ + { + "name": "Nick O'Leary" + }, + { + "name": "Dave Conway-Jones" + } + ], + "dependencies": { + "@trycrypto/dappstarter-connector-plugin": "^1.0.0", + "@trycrypto/dappstarter-dapplib": "^0.1.0", + "ajv": "6.12.0", + "basic-auth": "2.0.1", + "bcryptjs": "2.4.3", + "body-parser": "1.19.0", + "cheerio": "0.22.0", + "clone": "2.1.2", + "content-type": "1.0.4", + "cookie": "0.4.0", + "cookie-parser": "1.4.4", + "cors": "2.8.5", + "cron": "1.8.2", + "cross-env": "^7.0.2", + "denque": "1.4.1", + "express": "4.17.1", + "express-session": "1.17.0", + "fs-extra": "8.1.0", + "fs.notify": "0.0.4", + "hash-sum": "2.0.0", + "https-proxy-agent": "5.0.0", + "i18next": "15.1.2", + "iconv-lite": "0.5.1", + "is-utf8": "0.2.1", + "js-yaml": "3.13.1", + "json-stringify-safe": "5.0.1", + "jsonata": "1.8.1", + "media-typer": "1.1.0", + "memorystore": "1.6.2", + "mime": "2.4.4", + "mqtt": "2.18.8", + "multer": "1.4.2", + "mustache": "4.0.0", + "node-red-node-rbe": "^0.2.6", + "node-red-node-sentiment": "^0.1.6", + "node-red-node-tail": "^0.1.0", + "nopt": "4.0.1", + "oauth2orize": "1.11.0", + "on-headers": "1.0.2", + "passport": "0.4.1", + "passport-http-bearer": "1.0.1", + "passport-oauth2-client-password": "0.1.2", + "raw-body": "2.4.1", + "request": "2.88.0", + "semver": "6.3.0", + "uglify-js": "3.8.0", + "when": "3.7.8", + "ws": "6.2.1", + "xml2js": "0.4.23" + }, + "optionalDependencies": { + "bcrypt": "3.0.6" + }, + "devDependencies": { + "dompurify": "2.0.8", + "grunt": "~1.0.4", + "grunt-chmod": "~1.1.1", + "grunt-cli": "~1.3.2", + "grunt-concurrent": "~2.3.1", + "grunt-contrib-clean": "~2.0.0", + "grunt-contrib-compress": "~1.5.0", + "grunt-contrib-concat": "~1.0.1", + "grunt-contrib-copy": "~1.0.0", + "grunt-contrib-jshint": "~2.1.0", + "grunt-contrib-uglify": "~4.0.1", + "grunt-contrib-watch": "~1.1.0", + "grunt-jsdoc": "^2.2.1", + "grunt-jsdoc-to-markdown": "^4.0.0", + "grunt-jsonlint": "~2.0.0", + "grunt-mkdir": "~1.0.0", + "grunt-mocha-istanbul": "5.0.2", + "grunt-nodemon": "~0.4.2", + "grunt-npm-command": "~0.1.2", + "grunt-sass": "~3.1.0", + "grunt-simple-mocha": "~0.4.1", + "http-proxy": "1.18.0", + "istanbul": "0.4.5", + "jsdoc-nr-template": "github:node-red/jsdoc-nr-template", + "marked": "0.8.0", + "minami": "1.2.3", + "mocha": "^5.2.0", + "mosca": "^2.8.3", + "node-red-node-test-helper": "^0.2.3", + "node-sass": "^4.13.1", + "nodemon": "^2.0.4", + "should": "^8.4.0", + "sinon": "1.17.7", + "stoppable": "^1.1.0", + "supertest": "3.4.2", + "supervisor": "^0.12.0", + "wait-on": "^4.0.2" + }, + "engines": { + "node": ">=8" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/.npmignore b/packages/connector/packages/node_modules/@node-red/editor-api/.npmignore new file mode 100644 index 0000000..99c96b4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/.npmignore @@ -0,0 +1,2 @@ +src +docs diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/LICENSE b/packages/connector/packages/node_modules/@node-red/editor-api/LICENSE new file mode 100644 index 0000000..fc619bd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/LICENSE @@ -0,0 +1,178 @@ +Copyright JS Foundation and other contributors, http://js.foundation + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/README.md b/packages/connector/packages/node_modules/@node-red/editor-api/README.md new file mode 100644 index 0000000..47c4bac --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/README.md @@ -0,0 +1,12 @@ +@node-red/editor-api +==================== + +Node-RED editor api module. + +This provides an Express application that can be used to serve the Node-RED +editor. + + +### Source + +The main Node-RED modules are maintained as a monorepo on [GitHub](https://github.com/node-red/node-red). diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/lib/admin/context.js b/packages/connector/packages/node_modules/@node-red/editor-api/lib/admin/context.js new file mode 100644 index 0000000..54bfd9f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/lib/admin/context.js @@ -0,0 +1,58 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var apiUtils = require("../util"); + +var runtimeAPI; + + +module.exports = { + init: function(_runtimeAPI) { + runtimeAPI = _runtimeAPI; + }, + + get: function(req,res) { + var opts = { + user: req.user, + scope: req.params.scope, + id: req.params.id, + key: req.params[0], + store: req.query['store'], + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.context.getValue(opts).then(function(result) { + res.json(result); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }, + + delete: function(req,res) { + var opts = { + user: req.user, + scope: req.params.scope, + id: req.params.id, + key: req.params[0], + store: req.query['store'], + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.context.delete(opts).then(function(result) { + res.status(204).end(); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/lib/admin/flow.js b/packages/connector/packages/node_modules/@node-red/editor-api/lib/admin/flow.js new file mode 100644 index 0000000..98ae997 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/lib/admin/flow.js @@ -0,0 +1,73 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var runtimeAPI; +var apiUtils = require("../util"); + +module.exports = { + init: function(_runtimeAPI) { + runtimeAPI = _runtimeAPI; + }, + get: function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.flows.getFlow(opts).then(function(result) { + return res.json(result); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }, + post: function(req,res) { + var opts = { + user: req.user, + flow: req.body, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.flows.addFlow(opts).then(function(id) { + return res.json({id:id}); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }, + put: function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + flow: req.body, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.flows.updateFlow(opts).then(function(id) { + return res.json({id:id}); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }, + delete: function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.flows.deleteFlow(opts).then(function() { + res.status(204).end(); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/lib/admin/flows.js b/packages/connector/packages/node_modules/@node-red/editor-api/lib/admin/flows.js new file mode 100644 index 0000000..11b30e4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/lib/admin/flows.js @@ -0,0 +1,72 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var runtimeAPI; +var apiUtils = require("../util"); + +module.exports = { + init: function(_runtimeAPI) { + runtimeAPI = _runtimeAPI; + }, + get: function(req,res) { + var version = req.get("Node-RED-API-Version")||"v1"; + if (!/^v[12]$/.test(version)) { + return res.status(400).json({code:"invalid_api_version", message:"Invalid API Version requested"}); + } + var opts = { + user: req.user, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.flows.getFlows(opts).then(function(result) { + if (version === "v1") { + res.json(result.flows); + } else if (version === "v2") { + res.json(result); + } + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }, + post: function(req,res) { + var version = req.get("Node-RED-API-Version")||"v1"; + if (!/^v[12]$/.test(version)) { + return res.status(400).json({code:"invalid_api_version", message:"Invalid API Version requested"}); + } + var opts = { + user: req.user, + deploymentType: req.get("Node-RED-Deployment-Type")||"full", + req: apiUtils.getRequestLogObject(req) + } + + if (opts.deploymentType !== 'reload') { + if (version === "v1") { + opts.flows = {flows: req.body} + } else { + opts.flows = req.body; + } + } + + runtimeAPI.flows.setFlows(opts).then(function(result) { + if (version === "v1") { + res.status(204).end(); + } else { + res.json(result); + } + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/lib/admin/index.js b/packages/connector/packages/node_modules/@node-red/editor-api/lib/admin/index.js new file mode 100644 index 0000000..50d7b16 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/lib/admin/index.js @@ -0,0 +1,72 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var express = require("express"); + +var nodes = require("./nodes"); +var flows = require("./flows"); +var flow = require("./flow"); +var context = require("./context"); +var auth = require("../auth"); + +var apiUtil = require("../util"); + +module.exports = { + init: function(runtimeAPI) { + flows.init(runtimeAPI); + flow.init(runtimeAPI); + nodes.init(runtimeAPI); + context.init(runtimeAPI); + + var needsPermission = auth.needsPermission; + + var adminApp = express(); + + // Flows + adminApp.get("/flows",needsPermission("flows.read"),flows.get,apiUtil.errorHandler); + adminApp.post("/flows",needsPermission("flows.write"),flows.post,apiUtil.errorHandler); + + // Flow + adminApp.get("/flow/:id",needsPermission("flows.read"),flow.get,apiUtil.errorHandler); + adminApp.post("/flow",needsPermission("flows.write"),flow.post,apiUtil.errorHandler); + adminApp.delete("/flow/:id",needsPermission("flows.write"),flow.delete,apiUtil.errorHandler); + adminApp.put("/flow/:id",needsPermission("flows.write"),flow.put,apiUtil.errorHandler); + + // Nodes + adminApp.get("/nodes",needsPermission("nodes.read"),nodes.getAll,apiUtil.errorHandler); + adminApp.post("/nodes",needsPermission("nodes.write"),nodes.post,apiUtil.errorHandler); + adminApp.get(/^\/nodes\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalogs,apiUtil.errorHandler); + adminApp.get(/^\/nodes\/((@[^\/]+\/)?[^\/]+\/[^\/]+)\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalog,apiUtil.errorHandler); + adminApp.get(/^\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.read"),nodes.getModule,apiUtil.errorHandler); + adminApp.put(/^\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.putModule,apiUtil.errorHandler); + adminApp.delete(/^\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.delete,apiUtil.errorHandler); + adminApp.get(/^\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,needsPermission("nodes.read"),nodes.getSet,apiUtil.errorHandler); + adminApp.put(/^\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,needsPermission("nodes.write"),nodes.putSet,apiUtil.errorHandler); + + // Context + adminApp.get("/context/:scope(global)",needsPermission("context.read"),context.get,apiUtil.errorHandler); + adminApp.get("/context/:scope(global)/*",needsPermission("context.read"),context.get,apiUtil.errorHandler); + adminApp.get("/context/:scope(node|flow)/:id",needsPermission("context.read"),context.get,apiUtil.errorHandler); + adminApp.get("/context/:scope(node|flow)/:id/*",needsPermission("context.read"),context.get,apiUtil.errorHandler); + + // adminApp.delete("/context/:scope(global)",needsPermission("context.write"),context.delete,apiUtil.errorHandler); + adminApp.delete("/context/:scope(global)/*",needsPermission("context.write"),context.delete,apiUtil.errorHandler); + // adminApp.delete("/context/:scope(node|flow)/:id",needsPermission("context.write"),context.delete,apiUtil.errorHandler); + adminApp.delete("/context/:scope(node|flow)/:id/*",needsPermission("context.write"),context.delete,apiUtil.errorHandler); + + return adminApp; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/lib/admin/nodes.js b/packages/connector/packages/node_modules/@node-red/editor-api/lib/admin/nodes.js new file mode 100644 index 0000000..2787a5c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/lib/admin/nodes.js @@ -0,0 +1,183 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var apiUtils = require("../util"); + +var runtimeAPI; + +module.exports = { + init: function(_runtimeAPI) { + runtimeAPI = _runtimeAPI; + }, + getAll: function(req,res) { + var opts = { + user: req.user, + req: apiUtils.getRequestLogObject(req) + } + if (req.get("accept") == "application/json") { + runtimeAPI.nodes.getNodeList(opts).then(function(list) { + res.json(list); + }) + } else { + opts.lang = apiUtils.determineLangFromHeaders(req.acceptsLanguages()); + runtimeAPI.nodes.getNodeConfigs(opts).then(function(configs) { + res.send(configs); + }) + } + }, + + post: function(req,res) { + var opts = { + user: req.user, + module: req.body.module, + version: req.body.version, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.nodes.addModule(opts).then(function(info) { + res.json(info); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }, + + delete: function(req,res) { + var opts = { + user: req.user, + module: req.params[0], + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.nodes.removeModule(opts).then(function() { + res.status(204).end(); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }, + + getSet: function(req,res) { + var opts = { + user: req.user, + id: req.params[0] + "/" + req.params[2], + req: apiUtils.getRequestLogObject(req) + } + if (req.get("accept") === "application/json") { + runtimeAPI.nodes.getNodeInfo(opts).then(function(result) { + res.send(result); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + } else { + opts.lang = apiUtils.determineLangFromHeaders(req.acceptsLanguages()); + runtimeAPI.nodes.getNodeConfig(opts).then(function(result) { + return res.send(result); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + } + }, + + getModule: function(req,res) { + var opts = { + user: req.user, + module: req.params[0], + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.nodes.getModuleInfo(opts).then(function(result) { + res.send(result); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }, + + putSet: function(req,res) { + var body = req.body; + if (!body.hasOwnProperty("enabled")) { + // log.audit({event: "nodes.module.set",error:"invalid_request"},req); + res.status(400).json({code:"invalid_request", message:"Invalid request"}); + return; + } + var opts = { + user: req.user, + id: req.params[0] + "/" + req.params[2], + enabled: body.enabled, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.nodes.setNodeSetState(opts).then(function(result) { + res.send(result); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }, + + putModule: function(req,res) { + var body = req.body; + if (!body.hasOwnProperty("enabled")) { + // log.audit({event: "nodes.module.set",error:"invalid_request"},req); + res.status(400).json({code:"invalid_request", message:"Invalid request"}); + return; + } + var opts = { + user: req.user, + module: req.params[0], + enabled: body.enabled, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.nodes.setModuleState(opts).then(function(result) { + res.send(result); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + + }, + + getModuleCatalog: function(req,res) { + var opts = { + user: req.user, + module: req.params[0], + lang: req.query.lng, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.nodes.getModuleCatalog(opts).then(function(result) { + res.json(result); + }).catch(function(err) { + console.log(err.stack); + apiUtils.rejectHandler(req,res,err); + }) + }, + + getModuleCatalogs: function(req,res) { + var opts = { + user: req.user, + lang: req.query.lng, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.nodes.getModuleCatalogs(opts).then(function(result) { + res.json(result); + }).catch(function(err) { + console.log(err.stack); + apiUtils.rejectHandler(req,res,err); + }) + }, + + getIcons: function(req,res) { + var opts = { + user: req.user, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.nodes.getIconList(opts).then(function(list) { + res.json(list); + }); + } +}; diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/lib/auth/clients.js b/packages/connector/packages/node_modules/@node-red/editor-api/lib/auth/clients.js new file mode 100644 index 0000000..63e59cc --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/lib/auth/clients.js @@ -0,0 +1,31 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var clients = [ + {id:"node-red-editor",secret:"not_available"}, + {id:"node-red-admin",secret:"not_available"} +]; + +module.exports = { + get: function(id) { + for (var i=0;i 0) { + urlPrefix += "/"; + } + response = { + "type":"strategy", + "prompts":[{type:"button",label:mergedAdminAuth.strategy.label, url: urlPrefix + "auth/strategy"}] + } + if (mergedAdminAuth.strategy.icon) { + response.prompts[0].icon = mergedAdminAuth.strategy.icon; + } + if (mergedAdminAuth.strategy.image) { + response.prompts[0].image = theme.serveFile('/login/',mergedAdminAuth.strategy.image); + } + } + if (theme.context().login && theme.context().login.image) { + response.image = theme.context().login.image; + } + } + res.json(response); +} + +function revoke(req,res) { + var token = req.body.token; + // TODO: audit log + Tokens.revoke(token).then(function() { + log.audit({event: "auth.login.revoke"},req); + if (settings.editorTheme && settings.editorTheme.logout && settings.editorTheme.logout.redirect) { + res.json({redirect:settings.editorTheme.logout.redirect}); + } else { + res.status(200).end(); + } + }); +} + +function completeVerify(profile,done) { + Users.authenticate(profile).then(function(user) { + if (user) { + Tokens.create(user.username,"node-red-editor",user.permissions).then(function(tokens) { + log.audit({event: "auth.login",username:user.username,scope:user.permissions}); + user.tokens = tokens; + done(null,user); + }); + } else { + log.audit({event: "auth.login.fail.oauth",username:typeof profile === "string"?profile:profile.username}); + done(null,false); + } + }); +} + + +function genericStrategy(adminApp,strategy) { + var crypto = require("crypto") + var session = require('express-session') + var MemoryStore = require('memorystore')(session) + + adminApp.use(session({ + // As the session is only used across the life-span of an auth + // hand-shake, we can use a instance specific random string + secret: crypto.randomBytes(20).toString('hex'), + resave: false, + saveUninitialized: false, + store: new MemoryStore({ + checkPeriod: 86400000 // prune expired entries every 24h + }) + })); + //TODO: all passport references ought to be in ./auth + adminApp.use(passport.initialize()); + adminApp.use(passport.session()); + + var options = strategy.options; + + passport.use(new strategy.strategy(options, + function() { + var originalDone = arguments[arguments.length-1]; + if (options.verify) { + var args = Array.from(arguments); + args[args.length-1] = function(err,profile) { + if (err) { + return originalDone(err); + } else { + return completeVerify(profile,originalDone); + } + }; + options.verify.apply(null,args); + } else { + var profile = arguments[arguments.length - 2]; + return completeVerify(profile,originalDone); + } + + } + )); + + adminApp.get('/auth/strategy', + passport.authenticate(strategy.name, {session:false, failureRedirect: settings.httpAdminRoot }), + completeGenerateStrategyAuth + ); + + var callbackMethodFunc = adminApp.get; + if (/^post$/i.test(options.callbackMethod)) { + callbackMethodFunc = adminApp.post; + } + callbackMethodFunc.call(adminApp,'/auth/strategy/callback', + passport.authenticate(strategy.name, {session:false, failureRedirect: settings.httpAdminRoot }), + completeGenerateStrategyAuth + ); + +} +function completeGenerateStrategyAuth(req,res) { + var tokens = req.user.tokens; + delete req.user.tokens; + // Successful authentication, redirect home. + res.redirect(settings.httpAdminRoot + '?access_token='+tokens.accessToken); +} + +module.exports = { + init: init, + needsPermission: needsPermission, + ensureClientSecret: ensureClientSecret, + authenticateClient: authenticateClient, + getToken: getToken, + errorHandler: function(err,req,res,next) { + //TODO: audit log statment + //console.log(err.stack); + //log.log({level:"audit",type:"auth",msg:err.toString()}); + return server.errorHandler()(err,req,res,next); + }, + login: login, + revoke: revoke, + genericStrategy: genericStrategy +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/lib/auth/permissions.js b/packages/connector/packages/node_modules/@node-red/editor-api/lib/auth/permissions.js new file mode 100644 index 0000000..ba5005b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/lib/auth/permissions.js @@ -0,0 +1,65 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require('util'); + +var readRE = /^((.+)\.)?read$/ +var writeRE = /^((.+)\.)?write$/ + +function hasPermission(userScope,permission) { + if (permission === "") { + return true; + } + var i; + + if (util.isArray(permission)) { + // Multiple permissions requested - check each one + for (i=0;i now; + }); + loginAttempts.push({time:now, user:username}); + var attemptCount = 0; + loginAttempts.forEach(function(logEntry) { + /* istanbul ignore else */ + if (logEntry.user == username) { + attemptCount++; + } + }); + if (attemptCount > 5) { + log.audit({event: "auth.login.fail.too-many-attempts",username:username,client:client.id}); + done(new Error("Too many login attempts. Wait 10 minutes and try again"),false); + return; + } + + Users.authenticate(username,password).then(function(user) { + if (user) { + if (scope === "") { + scope = user.permissions; + } + if (permissions.hasPermission(user.permissions,scope)) { + loginAttempts = loginAttempts.filter(function(logEntry) { + return logEntry.user !== username; + }); + Tokens.create(username,client.id,scope).then(function(tokens) { + log.audit({event: "auth.login",username:username,client:client.id,scope:scope}); + done(null,tokens.accessToken,null,{expires_in:tokens.expires_in}); + }); + } else { + log.audit({event: "auth.login.fail.permissions",username:username,client:client.id,scope:scope}); + done(null,false); + } + } else { + log.audit({event: "auth.login.fail.credentials",username:username,client:client.id,scope:scope}); + done(null,false); + } + }); +} + +function AnonymousStrategy() { + passport.Strategy.call(this); + this.name = 'anon'; +} +util.inherits(AnonymousStrategy, passport.Strategy); +AnonymousStrategy.prototype.authenticate = function(req) { + var self = this; + Users.default().then(function(anon) { + if (anon) { + self.success(anon,{scope:anon.permissions}); + } else { + self.fail(401); + } + }); +} + +module.exports = { + bearerStrategy: bearerStrategy, + clientPasswordStrategy: clientPasswordStrategy, + passwordTokenExchange: passwordTokenExchange, + anonymousStrategy: new AnonymousStrategy() +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/lib/auth/tokens.js b/packages/connector/packages/node_modules/@node-red/editor-api/lib/auth/tokens.js new file mode 100644 index 0000000..6e867d7 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/lib/auth/tokens.js @@ -0,0 +1,152 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +function generateToken(length) { + var c = "ABCDEFGHIJKLMNOPQRSTUZWXYZabcdefghijklmnopqrstuvwxyz1234567890"; + var token = []; + for (var i=0;i { listener(session) }) + delete sessions[t]; + modified = true; + } else { + if (session.expires < nextExpiry) { + nextExpiry = session.expires; + } + } + } + } + if (nextExpiry < Number.MAX_SAFE_INTEGER) { + // Allow 5 seconds grace + expiryTimeout = setTimeout(expireSessions,Math.min(2147483647,(nextExpiry - Date.now()) + 5000)) + } + if (modified) { + return storage.saveSessions(sessions); + } else { + return Promise.resolve(); + } +} +function loadSessions() { + if (loadedSessions === null) { + loadedSessions = storage.getSessions().then(function(_sessions) { + sessions = _sessions||{}; + return expireSessions(); + }); + } + return loadedSessions; +} + +module.exports = { + init: function(adminAuthSettings, _storage) { + storage = _storage; + + sessionExpiryListeners = []; + + sessionExpiryTime = adminAuthSettings.sessionExpiryTime || 604800; // 1 week in seconds + // At this point, storage will not have been initialised, so defer loading + // the sessions until there's a request for them. + loadedSessions = null; + + apiAccessTokens = {}; + if ( Array.isArray(adminAuthSettings.tokens) ) { + apiAccessTokens = adminAuthSettings.tokens.reduce(function(prev, current) { + prev[current.token] = { + user: current.user, + scope: current.scope + }; + return prev; + }, {}); + } + return Promise.resolve(); + }, + get: function(token) { + return loadSessions().then(function() { + var info = apiAccessTokens[token] || null; + + if (info) { + return Promise.resolve(info); + } else { + if (sessions[token]) { + if (sessions[token].expires < Date.now()) { + return expireSessions().then(function() { return null }); + } + } + return Promise.resolve(sessions[token]); + } + }); + }, + create: function(user,client,scope) { + return loadSessions().then(function() { + var accessToken = generateToken(128); + + var accessTokenExpiresAt = Date.now() + (sessionExpiryTime*1000); + + var session = { + user:user, + client:client, + scope:scope, + accessToken: accessToken, + expires: accessTokenExpiresAt + }; + sessions[accessToken] = session; + + if (!expiryTimeout) { + expiryTimeout = setTimeout(expireSessions,Math.min(2147483647,(accessTokenExpiresAt - Date.now()) + 5000)) + } + + return storage.saveSessions(sessions).then(function() { + return { + accessToken: accessToken, + expires_in: sessionExpiryTime + } + }); + }); + }, + revoke: function(token) { + return loadSessions().then(function() { + delete sessions[token]; + return storage.saveSessions(sessions); + }); + }, + onSessionExpiry: function(callback) { + sessionExpiryListeners.push(callback); + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/lib/auth/users.js b/packages/connector/packages/node_modules/@node-red/editor-api/lib/auth/users.js new file mode 100644 index 0000000..24a7629 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/lib/auth/users.js @@ -0,0 +1,122 @@ +/** +* Copyright JS Foundation and other contributors, http://js.foundation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + +var util = require("util"); +var clone = require("clone"); +var bcrypt; +try { bcrypt = require('bcrypt'); } +catch(e) { bcrypt = require('bcryptjs'); } +var users = {}; +var defaultUser = null; + +function authenticate() { + var username = arguments[0]; + if (typeof username !== 'string') { + username = username.username; + } + const args = Array.from(arguments); + return api.get(username).then(function(user) { + if (user) { + if (args.length === 2) { + // Username/password authentication + var password = args[1]; + return new Promise(function(resolve,reject) { + bcrypt.compare(password, user.password, function(err, res) { + resolve(res?cleanUser(user):null); + }); + }); + } else { + // Try to extract common profile information + if (args[0].hasOwnProperty('photos') && args[0].photos.length > 0) { + user.image = args[0].photos[0].value; + } + return cleanUser(user); + } + } + return null; + }); +} +function get(username) { + return Promise.resolve(users[username]); +} +function getDefaultUser() { + return Promise.resolve(null); +} + +var api = { + get: get, + authenticate: authenticate, + default: getDefaultUser +} + +function init(config) { + users = {}; + defaultUser = null; + if (config.type == "credentials" || config.type == "strategy") { + if (config.users) { + if (typeof config.users === "function") { + api.get = config.users; + } else { + var us = config.users; + /* istanbul ignore else */ + if (!util.isArray(us)) { + us = [us]; + } + for (var i=0;i { + if (connection.token === session.accessToken) { + connection.ws.send(JSON.stringify({auth:"fail"})); + connection.ws.close(); + } + }) +} +function generateSession(length) { + var c = "ABCDEFGHIJKLMNOPQRSTUZWXYZabcdefghijklmnopqrstuvwxyz1234567890"; + var token = []; + for (var i=0;i webSocketKeepAliveTime) { + activeConnections.forEach(connection => connection.send("hb",lastSentTime)); + } + }, webSocketKeepAliveTime); + }); + } +} + +function stop() { + if (heartbeatTimer) { + clearInterval(heartbeatTimer); + heartbeatTimer = null; + } + if (wsServer) { + wsServer.close(); + wsServer = null; + } +} + +function addActiveConnection(connection) { + activeConnections.push(connection); + runtimeAPI.comms.addConnection({client: connection}); +} +function removeActiveConnection(connection) { + for (var i=0;i { + if (!started) { + log.error("Node-RED runtime not started"); + res.status(503).send("Not started"); + } else { + next() + } + }) +} + +module.exports = { + init: function(server, settings, _runtimeAPI) { + runtimeAPI = _runtimeAPI; + needsPermission = auth.needsPermission; + if (!settings.disableEditor) { + info.init(runtimeAPI); + comms.init(server,settings,runtimeAPI); + + var ui = require("./ui"); + + ui.init(runtimeAPI); + + var editorApp = express(); + if (settings.requireHttps === true) { + editorApp.enable('trust proxy'); + editorApp.use(function (req, res, next) { + if (req.secure) { + next(); + } else { + res.redirect('https://' + req.headers.host + req.originalUrl); + } + }); + } + if (settings.httpServerOptions) { + for (var eOption in settings.httpServerOptions) { + editorApp.set(eOption, settings.httpServerOptions[eOption]); + } + } + editorApp.get("/",ensureRuntimeStarted,ui.ensureSlash,ui.editor); + + editorApp.get("/icons",needsPermission("nodes.read"),nodes.getIcons,apiUtil.errorHandler); + editorApp.get("/icons/:module/:icon",ui.icon); + editorApp.get("/icons/:scope/:module/:icon",ui.icon); + + var theme = require("./theme"); + theme.init(settings); + editorApp.use("/theme",theme.app()); + editorApp.use("/",ui.editorResources); + + //Projects + var projects = require("./projects"); + projects.init(runtimeAPI); + editorApp.use("/projects",projects.app()); + + // Locales + var locales = require("./locales"); + locales.init(runtimeAPI); + editorApp.get(/^\/locales\/(.+)\/?$/,locales.get,apiUtil.errorHandler); + + // Library + var library = require("./library"); + library.init(runtimeAPI); + editorApp.get(/^\/library\/([^\/]+)\/([^\/]+)(?:$|\/(.*))/,needsPermission("library.read"),library.getEntry); + editorApp.post(/^\/library\/([^\/]+)\/([^\/]+)\/(.*)/,needsPermission("library.write"),library.saveEntry); + + + // Credentials + var credentials = require("./credentials"); + credentials.init(runtimeAPI); + editorApp.get('/credentials/:type/:id', needsPermission("credentials.read"),credentials.get,apiUtil.errorHandler); + + // Settings + editorApp.get("/settings",needsPermission("settings.read"),info.runtimeSettings,apiUtil.errorHandler); + // User Settings + editorApp.get("/settings/user",needsPermission("settings.read"),info.userSettings,apiUtil.errorHandler); + // User Settings + editorApp.post("/settings/user",needsPermission("settings.write"),info.updateUserSettings,apiUtil.errorHandler); + // SSH keys + editorApp.use("/settings/user/keys",needsPermission("settings.write"),info.sshkeys()); + + return editorApp; + } + }, + start: function() { + var catalogPath = path.resolve(path.join(path.dirname(require.resolve("@node-red/editor-client")),"locales")); + return i18n.registerMessageCatalogs([ + {namespace: "editor", dir: catalogPath, file:"editor.json"}, + {namespace: "jsonata", dir: catalogPath, file:"jsonata.json"}, + {namespace: "infotips", dir: catalogPath, file:"infotips.json"} + ]).then(function(){ + comms.start(); + }); + }, + stop: comms.stop +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/library.js b/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/library.js new file mode 100644 index 0000000..47a41bb --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/library.js @@ -0,0 +1,73 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var apiUtils = require("../util"); +var fs = require('fs'); +var fspath = require('path'); +var when = require('when'); + +var runtimeAPI; + +module.exports = { + init: function(_runtimeAPI) { + runtimeAPI = _runtimeAPI; + }, + getEntry: function(req,res) { + var opts = { + user: req.user, + library: req.params[0], + type: req.params[1], + path: req.params[2]||"" + } + runtimeAPI.library.getEntry(opts).then(function(result) { + if (typeof result === "string") { + if (opts.type === 'flows') { + res.writeHead(200, {'Content-Type': 'application/json'}); + } else { + res.writeHead(200, {'Content-Type': 'text/plain'}); + } + res.write(result); + res.end(); + } else { + res.json(result); + } + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }); + }, + saveEntry: function(req,res) { + var opts = { + user: req.user, + library: req.params[0], + type: req.params[1], + path: req.params[2]||"" + } + // TODO: horrible inconsistencies between flows and all other types + if (opts.type === "flows") { + opts.meta = {}; + opts.body = JSON.stringify(req.body); + } else { + opts.meta = req.body; + opts.body = opts.meta.text; + delete opts.meta.text; + } + runtimeAPI.library.saveEntry(opts).then(function(result) { + res.status(204).end(); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }); + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/locales.js b/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/locales.js new file mode 100644 index 0000000..a7f300c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/locales.js @@ -0,0 +1,53 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +var fs = require('fs'); +var path = require('path'); +// var apiUtil = require('../util'); + +var i18n = require("@node-red/util").i18n; // TODO: separate module + +var runtimeAPI; + +function loadResource(lang, namespace) { + var catalog = i18n.i.getResourceBundle(lang, namespace); + if (!catalog) { + var parts = lang.split("-"); + if (parts.length == 2) { + var new_lang = parts[0]; + return i18n.i.getResourceBundle(new_lang, namespace); + } + } + return catalog; +} + +module.exports = { + init: function(_runtimeAPI) { + runtimeAPI = _runtimeAPI; + }, + get: function(req,res) { + var namespace = req.params[0]; + var lngs = req.query.lng; + namespace = namespace.replace(/\.json$/,""); + var lang = req.query.lng || i18n.defaultLang; //apiUtil.determineLangFromHeaders(req.acceptsLanguages() || []); + var prevLang = i18n.i.language; + // Trigger a load from disk of the language if it is not the default + i18n.i.changeLanguage(lang, function(){ + var catalog = loadResource(lang, namespace); + res.json(catalog||{}); + }); + i18n.i.changeLanguage(prevLang); + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/projects.js b/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/projects.js new file mode 100644 index 0000000..0849c8f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/projects.js @@ -0,0 +1,541 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var express = require("express"); +var apiUtils = require("../util"); + +var runtimeAPI; +var needsPermission = require("../auth").needsPermission; + +function listProjects(req,res) { + var opts = { + user: req.user, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.listProjects(opts).then(function(result) { + res.json(result); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }); +} +function getProject(req,res) { + var opts = { + user: req.user, + id: req.params.id, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.getProject(opts).then(function(data) { + if (data) { + res.json(data); + } else { + res.status(404).end(); + } + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) +} +function getProjectStatus(req,res) { + var opts = { + user: req.user, + id: req.params.id, + remote: req.query.remote, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.getStatus(opts).then(function(data){ + if (data) { + res.json(data); + } else { + res.status(404).end(); + } + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) +} +function getProjectRemotes(req,res) { + var opts = { + user: req.user, + id: req.params.id, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.getRemotes(opts).then(function(data) { + res.json(data); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) +} +module.exports = { + init: function(_runtimeAPI) { + runtimeAPI = _runtimeAPI; + }, + app: function() { + var app = express(); + + app.use(function(req,res,next) { + runtimeAPI.projects.available().then(function(available) { + if (!available) { + res.status(404).end(); + } else { + next(); + } + }) + }); + + // Projects + + // List all projects + app.get("/", needsPermission("projects.read"),listProjects); + + // Create project + app.post("/", needsPermission("projects.write"), function(req,res) { + var opts = { + user: req.user, + project: req.body, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.createProject(opts).then(function(result) { + res.json(result); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }); + }); + + // Update a project + app.put("/:id", needsPermission("projects.write"), function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + project: req.body, + req: apiUtils.getRequestLogObject(req) + } + + if (req.body.active) { + runtimeAPI.projects.setActiveProject(opts).then(function() { + listProjects(req,res); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + } else if (req.body.initialise) { + runtimeAPI.projects.initialiseProject(opts).then(function() { + getProject(req,res); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + } else if (req.body.hasOwnProperty('credentialSecret') || + req.body.hasOwnProperty('description') || + req.body.hasOwnProperty('dependencies')|| + req.body.hasOwnProperty('summary') || + req.body.hasOwnProperty('files') || + req.body.hasOwnProperty('git')) { + runtimeAPI.projects.updateProject(opts).then(function() { + getProject(req,res); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + } else { + res.status(400).json({error:"unexpected_error", message:"invalid_request"}); + } + }); + + // Get project metadata + app.get("/:id", needsPermission("projects.read"), getProject); + + // Delete project + app.delete("/:id", needsPermission("projects.write"), function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.deleteProject(opts).then(function() { + res.status(204).end(); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + + // Get project status - files, commit counts, branch info + app.get("/:id/status", needsPermission("projects.read"), getProjectStatus); + + + // Project file listing + app.get("/:id/files", needsPermission("projects.read"), function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.getFiles(opts).then(function(data) { + res.json(data); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + + }); + + + // Get file content in a given tree (index/stage) + app.get("/:id/files/:treeish/*", needsPermission("projects.read"), function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + path: req.params[0], + tree: req.params.treeish, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.getFile(opts).then(function(data) { + res.json({content:data}); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Revert a file + app.delete("/:id/files/_/*", needsPermission("projects.write"), function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + path: req.params[0], + req: apiUtils.getRequestLogObject(req) + } + + runtimeAPI.projects.revertFile(opts).then(function() { + res.status(204).end(); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Stage a file + app.post("/:id/stage/*", needsPermission("projects.write"), function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + path: req.params[0], + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.stageFile(opts).then(function() { + getProjectStatus(req,res); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Stage multiple files + app.post("/:id/stage", needsPermission("projects.write"), function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + path: req.body.files, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.stageFile(opts).then(function() { + getProjectStatus(req,res); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Commit changes + app.post("/:id/commit", needsPermission("projects.write"), function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + message: req.body.message, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.commit(opts).then(function() { + getProjectStatus(req,res); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Unstage a file + app.delete("/:id/stage/*", needsPermission("projects.write"), function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + path: req.params[0], + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.unstageFile(opts).then(function() { + getProjectStatus(req,res); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Unstage multiple files + app.delete("/:id/stage", needsPermission("projects.write"), function(req, res) { + var opts = { + user: req.user, + id: req.params.id, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.unstageFile(opts).then(function() { + getProjectStatus(req,res); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Get a file diff + app.get("/:id/diff/:type/*", needsPermission("projects.read"), function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + path: req.params[0], + type: req.params.type, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.getFileDiff(opts).then(function(data) { + res.json({ + diff: data + }) + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Get a list of commits + app.get("/:id/commits", needsPermission("projects.read"), function(req, res) { + var opts = { + user: req.user, + id: req.params.id, + limit: req.query.limit || 20, + before: req.query.before, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.getCommits(opts).then(function(data) { + res.json(data); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Get an individual commit details + app.get("/:id/commits/:sha", needsPermission("projects.read"), function(req, res) { + var opts = { + user: req.user, + id: req.params.id, + sha: req.params.sha, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.getCommit(opts).then(function(data) { + res.json({commit:data}); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Push local commits to remote + app.post("/:id/push/?*", needsPermission("projects.write"), function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + remote: req.params[0], + track: req.query.u, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.push(opts).then(function(data) { + res.status(204).end(); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Pull remote commits + app.post("/:id/pull/?*", needsPermission("projects.write"), function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + remote: req.params[0], + track: req.query.setUpstream, + allowUnrelatedHistories: req.query.allowUnrelatedHistories, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.pull(opts).then(function(data) { + res.status(204).end(); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Abort an ongoing merge + app.delete("/:id/merge", needsPermission("projects.write"), function(req, res) { + var opts = { + user: req.user, + id: req.params.id, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.abortMerge(opts).then(function() { + res.status(204).end(); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Resolve a merge + app.post("/:id/resolve/*", needsPermission("projects.write"), function(req, res) { + var opts = { + user: req.user, + id: req.params.id, + path: req.params[0], + resolution: req.body.resolutions, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.resolveMerge(opts).then(function() { + res.status(204).end(); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Get a list of local branches + app.get("/:id/branches", needsPermission("projects.read"), function(req, res) { + var opts = { + user: req.user, + id: req.params.id, + remote: false, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.getBranches(opts).then(function(data) { + res.json(data); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Delete a local branch - ?force=true + app.delete("/:id/branches/:branchName", needsPermission("projects.write"), function(req, res) { + var opts = { + user: req.user, + id: req.params.id, + branch: req.params.branchName, + force: !!req.query.force, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.deleteBranch(opts).then(function(data) { + res.status(204).end(); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Get a list of remote branches + app.get("/:id/branches/remote", needsPermission("projects.read"), function(req, res) { + var opts = { + user: req.user, + id: req.params.id, + remote: true, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.getBranches(opts).then(function(data) { + res.json(data); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Get branch status - commit counts/ahead/behind + app.get("/:id/branches/remote/*/status", needsPermission("projects.read"), function(req, res) { + var opts = { + user: req.user, + id: req.params.id, + branch: req.params[0], + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.getBranchStatus(opts).then(function(data) { + res.json(data); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Set the active local branch + app.post("/:id/branches", needsPermission("projects.write"), function(req, res) { + var opts = { + user: req.user, + id: req.params.id, + branch: req.body.name, + create: req.body.create, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.setBranch(opts).then(function(data) { + res.json(data); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Get a list of remotes + app.get("/:id/remotes", needsPermission("projects.read"), getProjectRemotes); + + // Add a remote + app.post("/:id/remotes", needsPermission("projects.write"), function(req,res) { + var opts = { + user: req.user, + id: req.params.id, + remote: req.body, + req: apiUtils.getRequestLogObject(req) + } + if (/^https?:\/\/[^/]+@/i.test(req.body.url)) { + res.status(400).json({error:"unexpected_error", message:"Git http url must not include username/password"}); + return; + } + runtimeAPI.projects.addRemote(opts).then(function(data) { + getProjectRemotes(req,res); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Delete a remote + app.delete("/:id/remotes/:remoteName", needsPermission("projects.write"), function(req, res) { + var opts = { + user: req.user, + id: req.params.id, + remote: req.params.remoteName, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.removeRemote(opts).then(function(data) { + getProjectRemotes(req,res); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + // Update a remote + app.put("/:id/remotes/:remoteName", needsPermission("projects.write"), function(req,res) { + var remote = req.body || {}; + remote.name = req.params.remoteName; + var opts = { + user: req.user, + id: req.params.id, + remote: remote, + req: apiUtils.getRequestLogObject(req) + } + runtimeAPI.projects.updateRemote(opts).then(function() { + res.status(204).end(); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }) + }); + + return app; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/settings.js b/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/settings.js new file mode 100644 index 0000000..9d9867f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/settings.js @@ -0,0 +1,91 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +var apiUtils = require("../util"); +var runtimeAPI; +var sshkeys = require("./sshkeys"); +var theme = require("./theme"); +var clone = require("clone"); + +var i18n = require("@node-red/util").i18n + +function extend(target, source) { + var keys = Object.keys(source); + var i = keys.length; + while(i--) { + var value = source[keys[i]] + var type = typeof value; + if (type === 'string' || type === 'number' || type === 'boolean' || Array.isArray(value)) { + target[keys[i]] = value; + } else if (value === null) { + if (target.hasOwnProperty(keys[i])) { + delete target[keys[i]]; + } + } else { + // Object + if (target.hasOwnProperty(keys[i])) { + target[keys[i]] = extend(target[keys[i]],value); + } else { + target[keys[i]] = value; + } + } + } + return target; +} + +module.exports = { + init: function(_runtimeAPI) { + runtimeAPI = _runtimeAPI; + sshkeys.init(runtimeAPI); + }, + runtimeSettings: function(req,res) { + var opts = { + user: req.user + } + runtimeAPI.settings.getRuntimeSettings(opts).then(function(result) { + result.editorTheme = result.editorTheme||{}; + var themeSettings = theme.settings(); + if (themeSettings) { + // result.editorTheme may already exist with the palette + // disabled. Need to merge that into the receive settings + result.editorTheme = extend(clone(themeSettings),result.editorTheme); + } + result.editorTheme.languages = i18n.availableLanguages("editor"); + res.json(result); + }); + }, + userSettings: function(req, res) { + var opts = { + user: req.user + } + runtimeAPI.settings.getUserSettings(opts).then(function(result) { + res.json(result); + }); + }, + updateUserSettings: function(req,res) { + var opts = { + user: req.user, + settings: req.body + } + runtimeAPI.settings.updateUserSettings(opts).then(function(result) { + res.status(204).end(); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }); + }, + sshkeys: function() { + return sshkeys.app() + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/sshkeys.js b/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/sshkeys.js new file mode 100644 index 0000000..3e7b0de --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/sshkeys.js @@ -0,0 +1,101 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var apiUtils = require("../util"); +var express = require("express"); +var runtimeAPI; + +function getUsername(userObj) { + var username = '__default'; + if ( userObj && userObj.name ) { + username = userObj.name; + } + return username; +} + +module.exports = { + init: function(_runtimeAPI) { + runtimeAPI = _runtimeAPI; + }, + app: function() { + var app = express(); + + // List all SSH keys + app.get("/", function(req,res) { + var opts = { + user: req.user + } + runtimeAPI.settings.getUserKeys(opts).then(function(list) { + res.json({ + keys: list + }); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }); + }); + + // Get SSH key detail + app.get("/:id", function(req,res) { + var opts = { + user: req.user, + id: req.params.id + } + runtimeAPI.settings.getUserKey(opts).then(function(data) { + res.json({ + publickey: data + }); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }); + }); + + // Generate a SSH key + app.post("/", function(req,res) { + var opts = { + user: req.user, + id: req.params.id + } + // TODO: validate params + opts.name = req.body.name; + opts.password = req.body.password; + opts.comment = req.body.comment; + opts.size = req.body.size; + + runtimeAPI.settings.generateUserKey(opts).then(function(name) { + res.json({ + name: name + }); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }); + }); + + // Delete a SSH key + app.delete("/:id", function(req,res) { + var opts = { + user: req.user, + id: req.params.id + } + runtimeAPI.settings.removeUserKey(opts).then(function(name) { + res.status(204).end(); + }).catch(function(err) { + apiUtils.rejectHandler(req,res,err); + }); + }); + + return app; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/theme.js b/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/theme.js new file mode 100644 index 0000000..17dbbaf --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/lib/editor/theme.js @@ -0,0 +1,200 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var express = require("express"); +var util = require("util"); +var path = require("path"); +var fs = require("fs"); +var clone = require("clone"); + +var defaultContext = { + page: { + title: "Node-RED", + favicon: "favicon.ico", + tabicon: "red/images/node-red-icon-black.svg" + }, + header: { + title: "Node-RED", + image: "red/images/node-red.svg" + }, + asset: { + red: (process.env.NODE_ENV == "development")? "red/red.js":"red/red.min.js", + main: (process.env.NODE_ENV == "development")? "red/main.js":"red/main.min.js", + + } +}; + +var theme = null; +var themeContext = clone(defaultContext); +var themeSettings = null; + +var themeApp; + +function serveFile(app,baseUrl,file) { + try { + var stats = fs.statSync(file); + var url = baseUrl+path.basename(file); + //console.log(url,"->",file); + app.get(url,function(req, res) { + res.sendFile(file); + }); + return "theme"+url; + } catch(err) { + //TODO: log filenotfound + return null; + } +} + +function serveFilesFromTheme(themeValue, themeApp, directory) { + var result = []; + if (themeValue) { + var array = themeValue; + if (!util.isArray(array)) { + array = [array]; + } + + for (var i=0;i= 1) { + lang = acceptedLanguages[0]; + } + return lang; + }, + rejectHandler: function(req,res,err) { + //TODO: why this when errorHandler also?! + log.audit({event: "api.error",error:err.code||"unexpected_error",message:err.message||err.toString()},req); + res.status(err.status||400).json({ + code: err.code||"unexpected_error", + message: err.message||err.toString() + }); + }, + getRequestLogObject: function(req) { + return { + user: req.user, + path: req.path, + ip: (req.headers && req.headers['x-forwarded-for']) || (req.connection && req.connection.remoteAddress) || undefined + } + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-api/package.json b/packages/connector/packages/node_modules/@node-red/editor-api/package.json new file mode 100644 index 0000000..9866a81 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-api/package.json @@ -0,0 +1,40 @@ +{ + "name": "@node-red/editor-api", + "version": "1.0.4", + "license": "Apache-2.0", + "main": "./lib/index.js", + "repository": { + "type": "git", + "url": "https://github.com/node-red/node-red.git" + }, + "contributors": [ + { + "name": "Nick O'Leary" + }, + { + "name": "Dave Conway-Jones" + } + ], + "dependencies": { + "@node-red/util": "1.0.4", + "@node-red/editor-client": "1.0.4", + "bcryptjs": "2.4.3", + "body-parser": "1.19.0", + "clone": "2.1.2", + "cors": "2.8.5", + "express-session": "1.17.0", + "express": "4.17.1", + "memorystore": "1.6.2", + "mime": "2.4.4", + "mustache": "4.0.0", + "oauth2orize": "1.11.0", + "passport-http-bearer": "1.0.1", + "passport-oauth2-client-password": "0.1.2", + "passport": "0.4.1", + "when": "3.7.8", + "ws": "6.2.1" + }, + "optionalDependencies": { + "bcrypt": "3.0.6" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/.npmignore b/packages/connector/packages/node_modules/@node-red/editor-client/.npmignore new file mode 100644 index 0000000..99c96b4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/.npmignore @@ -0,0 +1,2 @@ +src +docs diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/LICENSE b/packages/connector/packages/node_modules/@node-red/editor-client/LICENSE new file mode 100644 index 0000000..fc619bd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/LICENSE @@ -0,0 +1,178 @@ +Copyright JS Foundation and other contributors, http://js.foundation + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/README.md b/packages/connector/packages/node_modules/@node-red/editor-client/README.md new file mode 100644 index 0000000..18781bf --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/README.md @@ -0,0 +1,10 @@ +@node-red/editor-client +==================== + +Node-RED editor resources module. + +This provides all of the client-side resources of the Node-RED editor application. + +### Source + +The main Node-RED modules are maintained as a monorepo on [GitHub](https://github.com/node-red/node-red). diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/index.js b/packages/connector/packages/node_modules/@node-red/editor-client/index.js new file mode 100644 index 0000000..14800aa --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/index.js @@ -0,0 +1,17 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = false diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/de/editor.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/de/editor.json new file mode 100644 index 0000000..c7394c3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/de/editor.json @@ -0,0 +1,821 @@ +{ + "common" : { + "label" : { + "name" : "Name", + "ok" : "OK", + "done" : "Fertig", + "cancel" : "Abbrechen", + "delete" : "Löschen", + "close" : "Schließen", + "load" : "Laden", + "save" : "Speichern", + "import" : "Import", + "export" : "Exportieren", + "back" : "Zurück", + "next" : "Weiter", + "clone" : "Projekt duplizieren", + "cont" : "Weiter" + } + }, + "workspace" : { + "defaultName" : "Flow __number__", + "editFlow" : "Flow bearbeiten: __name__", + "confirmDelete" : "Löschen bestätigen", + "delete" : "Sind Sie wirklich sicher, dass Sie '__label__' löschen wollen?", + "dropFlowHere" : "Hier können Sie den Flow fallen lassen.", + "status" : "Status", + "enabled" : "Aktiviert", + "disabled" : "Inaktiviert", + "info" : "Beschreibung" + }, + "menu" : { + "label" : { + "view" : { + "view" : "Ansicht", + "grid" : "Gitter", + "showGrid" : "Raster anzeigen", + "snapGrid" : "Einrasten am Raster", + "gridSize" : "Rastergröße", + "textDir" : "Textrichtung", + "defaultDir" : "Standard", + "ltr" : "Links-nach-rechts", + "rtl" : "Von rechts nach links", + "auto" : "Kontextuell" + }, + "sidebar" : { + "show" : "Seitenleiste anzeigen" + }, + "settings" : "Einstellungen", + "userSettings" : "Benutzereinstellungen", + "nodes" : "Nodes", + "displayStatus" : "Nodestatus anzeigen", + "displayConfig" : "Konfigurations-Node", + "import" : "Import", + "export" : "Exportieren", + "search" : "Flows durchsuchen", + "searchInput" : "durchsuchen Sie Ihre Flows", + "subflows" : "Subflow", + "createSubflow" : "Subflow erstellen", + "selectionToSubflow" : "Auswahl für Subflow", + "flows" : "Flows", + "add" : "Hinzufügen", + "rename" : "Umbenennen", + "delete" : "Löschen", + "keyboardShortcuts" : "Tastaturkurzbefehle", + "login" : "Anmelden", + "logout" : "Abmelden", + "editPalette" : "Palette verwalten", + "other" : "Sonstige", + "showTips" : "Tipps anzeigen", + "help" : "Node-RED-Website", + "projects" : "Projekte", + "projects-new" : "Neu", + "projects-open" : "Öffnen", + "projects-settings" : "Projekteinstellungen" + } + }, + "user" : { + "loggedInAs" : "Angemeldet als __name__", + "username" : "Benutzername", + "password" : "Kennwort", + "login" : "Anmelden", + "loginFailed" : "Anmeldung fehlgeschlagen", + "notAuthorized" : "Keine Berechtigung", + "errors" : { + "settings" : "Sie müssen angemeldet sein, um auf die Einstellungen zuzugreifen.", + "deploy" : "Sie müssen angemeldet sein, um Änderungen anwenden zu können.", + "notAuthorized" : "Sie müssen angemeldet sein, um diese Aktion ausführen zu können." + } + }, + "notification" : { + "warning" : " Warnung : __message__", + "warnings" : { + "undeployedChanges" : "Node hat nicht implementierte Änderungen", + "nodeActionDisabled" : "In Subflow inaktivierte Nodeaktionen", + "missing-types" : "

Die Flows wurden aufgrund fehlender Nodetypen gestoppt.

", + "restartRequired" : "Node-RED muss erneut gestartet werden, damit aufgerüstete Module aktiviert werden können", + "credentials_load_failed" : "

Die Flows wurden gestoppt, da die Berechtigungsnachweise nicht entschlüsselt werden konnten.

Die Datei mit dem Datenflowberechtigungsnachweis ist verschlüsselt, aber der Verschlüsselungsschlüssel des Projekts fehlt oder ist ungültig.

", + "credentials_load_failed_reset" : "

Die Berechtigungsnachweise konnten nicht entschlüsselt werden

Die Datei mit dem Flow-Berechtigungsnachweis ist verschlüsselt, aber der Chiffrierschlüssel des Projekts fehlt oder ist ungültig.

Die Datei des Flow-Berechtigungsnachweises wird bei der nächsten Implementierung zurückgesetzt. Alle vorhandenen Datenflowberechtigungsnachweise werden gelöscht.

", + "missing_flow_file" : "

Die Projektflowdatei wurde nicht gefunden.

Das Projekt ist nicht mit einer Flow-Datei konfiguriert.

", + "missing_package_file" : "

Die Projektpaketdatei wurde nicht gefunden.

In dem Projekt fehlt eine Datei 'package.json'.

", + "project_empty" : "

Das Projekt ist leer.

Möchten Sie eine Standardgruppe von Projektdateien erstellen?
Andernfalls müssen Sie Dateien außerhalb des Editors manuell zum Projekt hinzufügen.

", + "project_not_found" : "

Das Projekt '__project__' wurde nicht gefunden.

", + "git_merge_conflict" : "

Das automatische Zusammenführen von Änderungen ist fehlgeschlagen.

Beheben Sie die nicht zusammengeführten Konflikte und schreiben Sie die Ergebnisse fest.

" + }, + "error" : " Fehler : __message__", + "errors" : { + "lostConnection" : "Verbindung zum Server verloren, Verbindung wird erneut hergestellt ...", + "lostConnectionReconnect" : "Verbindung zum Server verloren, Verbindung in __time__s wird wieder hergestellt.", + "lostConnectionTry" : "Jetzt testen", + "cannotAddSubflowToItself" : "Subflow kann nicht zu sich selbst hinzugefügt werden", + "cannotAddCircularReference" : "Subflow kann nicht hinzugefügt werden-zirkuläre Referenz wurde erkannt", + "unsupportedVersion" : "

Verwenden einer nicht unterstützten Version von Node.js

Sie sollten ein Upgrade auf das neueste LTS-Release von Node.js durchführen.

", + "failedToAppendNode" : "

Fehler beim Laden von '__module__'

__error__

" + }, + "project" : { + "change-branch" : "Wechseln Sie in die lokale Verzweigung '__project__'.", + "merge-abort" : "Git-Zusammenführung abgebrochen", + "loaded" : "Projekt '__project__' geladen", + "updated" : "Projekt '__project__' aktualisiert", + "pull" : "Projekt '__project__' erneut geladen", + "revert" : "Projekt '__project__' erneut geladen", + "merge-complete" : "Git-Zusammenführung abgeschlossen" + }, + "label" : { + "manage-project-dep" : "Projektabhängigkeiten verwalten", + "setup-cred" : "Berechtigungsnachweise einrichten", + "setup-project" : "Projektdateien konfigurieren", + "create-default-package" : "Standardpaketdatei erstellen", + "no-thanks" : "Nein danke", + "create-default-project" : "Standardprojektdateien erstellen", + "show-merge-conflicts" : "Zusammenführungskonflikte anzeigen" + } + }, + "clipboard" : { + "clipboard" : "Zwischenablage", + "nodes" : "Nodes", + "pasteNodes" : "Nodes hier einfügen", + "importNodes" : "Nodes importieren", + "exportNodes" : "Nodes in Zwischenablage exportieren", + "importUnrecognised" : "Importierter Typ nicht erkannt:", + "importUnrecognised_plural" : "Importierte Typen nicht erkannt:", + "nodesExported" : "Nodes, die in die Zwischenablage exportiert wurden", + "nodeCopied" : "__count__ Node kopiert", + "nodeCopied_plural" : "__count__ Nodes kopiert", + "invalidFlow" : "Ungültiger Nachrichtenflow: __message__", + "export" : { + "selected" : "Ausgewählte Nodes", + "current" : "Aktueller Flow", + "all" : "alle Flows", + "compact" : "kompakt", + "formatted" : "formatiert", + "copy" : "In Zwischenablage exportieren" + }, + "import" : { + "import" : "Importieren in", + "newFlow" : "neuer Flow" + }, + "copyMessagePath" : "Pfad kopiert", + "copyMessageValue" : "Wert kopiert", + "copyMessageValue_truncated" : "Abgeschnittene Wert kopiert" + }, + "deploy" : { + "deploy" : "deploy", + "full" : "Voll", + "fullDesc" : "Implementiert alles im Arbeitsbereich", + "modifiedFlows" : "Geänderte Flows", + "modifiedFlowsDesc" : "Implementiert nur Flows, die geänderte Nodes enthalten.", + "modifiedNodes" : "Geänderte Nodes", + "modifiedNodesDesc" : "Implementiert nur Nodes, die sich geändert haben.", + "successfulDeploy" : "Erfolgreich implementiert", + "deployFailed" : "Deploy fehlgeschlagen: __message__", + "unusedConfigNodes" : "Sie haben einige nicht verwendete Konfigurations-Nodes.", + "unusedConfigNodesLink" : "Klicken Sie hier, um sie zu sehen", + "errors" : { + "noResponse" : "Keine Antwort vom Server" + }, + "confirm" : { + "button" : { + "ignore" : "Ignorieren", + "confirm" : "Deploy bestätigen", + "review" : "Änderungen prüfen", + "cancel" : "Abbrechen", + "merge" : "Zusammenführen", + "overwrite" : "Ignorieren & deployen" + }, + "undeployedChanges" : "Sie haben nicht implementierte Änderungen.\n\nWenn Sie diese Seite verlassen, gehen diese Änderungen verloren.", + "improperlyConfigured" : "Der Arbeitsbereich enthält einige Nodes, die nicht ordnungsgemäß konfiguriert sind:", + "unknown" : "Der Arbeitsbereich enthält einige unbekannte Node-Typen:", + "confirm" : "Sind Sie sicher, dass Sie deployen möchten?", + "doNotWarn" : "warnen Sie nicht noch einmal.", + "conflict" : "Auf dem Server wird eine aktuellere Gruppe von Datenflüssen ausgeführt.", + "backgroundUpdate" : "Die Datenflüsse auf dem Server wurden aktualisiert.", + "conflictChecking" : "Überprüfen Sie, ob die Änderungen automatisch gemischt werden können.", + "conflictAutoMerge" : "Die Änderungen enthalten keine Konflikte und können automatisch gemischt werden.", + "conflictManualMerge" : "Zu den Änderungen gehören Konflikte, die aufgelöst werden müssen, bevor sie implementiert werden können.", + "plusNMore" : "+ __count__ mehr" + } + }, + "diff" : { + "unresolvedCount" : "__count__ unaufgelöster Konflikt", + "unresolvedCount_plural" : "__count__ unaufgelöste Konflikte", + "globalNodes" : "Globale Nodes", + "flowProperties" : "Flow-Eigenschaften", + "type" : { + "added" : "hinzugefügt", + "changed" : "geändert", + "unchanged" : "unverändert", + "deleted" : "gelöscht", + "flowDeleted" : "Flow gelöscht", + "flowAdded" : "Flow hinzugefügt", + "movedTo" : "verschoben zu __id__", + "movedFrom" : "verschoben von __id__" + }, + "nodeCount" : "__count__, Node", + "nodeCount_plural" : "__count__-Nodes", + "local" : "Lokale Änderungen", + "remote" : "Ferne Änderungen", + "reviewChanges" : "Änderungen prüfen", + "noBinaryFileShowed" : "Der Inhalt der Binärdatei kann nicht angezeigt", + "viewCommitDiff" : "Änderungen festschreiben", + "compareChanges" : "Änderungen vergleichen", + "saveConflict" : "Konfliktlösung speichern", + "conflictHeader" : " __resolved__ von __unresolved__ -Konflikten behoben", + "commonVersionError" : "Allgemeine Version enthält keine gültige JSON-Datei:", + "oldVersionError" : "Alte Version enthält keine gültige JSON-Datei:", + "newVersionError" : "Neue Version enthält keine gültige JSON-Datei:" + }, + "subflow" : { + "editSubflow" : "Flowschablone bearbeiten: __name__", + "edit" : "Flowsschablone bearbeiten", + "subflowInstances" : "Es ist __count__ Instanz dieser Subflow-Vorlage vorhanden.", + "subflowInstances_plural" : "Es gibt __count__ Instanzen dieser Subflow-Vorlage.", + "editSubflowProperties" : "Eigenschaften bearbeiten", + "input" : "Eingaben:", + "output" : "Ausgaben:", + "deleteSubflow" : "Subflow löschen", + "info" : "Beschreibung", + "category" : "Kategorie", + "errors" : { + "noNodesSelected" : " Subflow kann nicht erstellt werden : Es wurden keine Nodes ausgewählt.", + "multipleInputsToSelection" : " Subflow kann nicht erstellt werden : Mehrere Eingaben zur Auswahl" + } + }, + "editor" : { + "configEdit" : "Bearbeiten", + "configAdd" : "Hinzufügen", + "configUpdate" : "Aktualisieren", + "configDelete" : "Löschen", + "nodesUse" : "__count__node verwendet diese Konfiguration", + "nodesUse_plural" : "__count__ -Nodes verwenden diese Konfiguration", + "addNewConfig" : "Neuen __type__config-Node hinzufügen", + "editNode" : "__type__ Node bearbeiten", + "editConfig" : "__type__config-Node bearbeiten", + "addNewType" : "Neuen __type__ hinzufügen ...", + "nodeProperties" : "Node-Eigenschaften", + "portLabels" : "Node-Einstellungen", + "labelInputs" : "Eingänge", + "labelOutputs" : "Ausgänge", + "settingIcon" : "Symbol", + "noDefaultLabel" : "keine", + "defaultLabel" : "Standardbeschriftung verwenden", + "searchIcons" : "Suchsymbole", + "useDefault" : "Standardwert verwenden", + "errors" : { + "scopeChange" : "Wenn Sie den Geltungsbereich ändern, wird er für Nodes in anderen Nachrichtenflüssen, die ihn verwenden, nicht verfügbar sein." + } + }, + "keyboard" : { + "title" : "Tastaturkurzbefehle", + "keyboard" : "Tastatur", + "filterActions" : "Filteraktionen", + "shortcut" : "Direktaufruf", + "scope" : "Bereich", + "unassigned" : "Nicht zugeordnet", + "global" : "global", + "workspace" : "Arbeitsbereich", + "selectAll" : "Alle Nodes auswählen", + "selectAllConnected" : "Alle verbundenen Nodes auswählen", + "addRemoveNode" : "Node aus Auswahl hinzufügen/entfernen", + "editSelected" : "Ausgewählten Node bearbeiten", + "deleteSelected" : "Ausgewählte Node oder ausgewählten Link löschen", + "importNode" : "Node importieren", + "exportNode" : "Node exportieren", + "nudgeNode" : "Ausgewählte Nodes verschieben (1px)", + "moveNode" : "Ausgewählte Nodes verschieben (20px)", + "toggleSidebar" : "Seitenleiste ein-/ausschalten", + "copyNode" : "Ausgewählte Nodes kopieren", + "cutNode" : "Ausgewählte Nodes ausschneiden", + "pasteNode" : "Node einfügen", + "undoChange" : "Letzte Änderung rückgängig machen", + "searchBox" : "Suchfeld öffnen", + "managePalette" : "Palette verwalten" + }, + "library" : { + "library" : "Bibliothek", + "openLibrary" : "Bibliothek öffnen ...", + "saveToLibrary" : "In Bibliothek speichern ...", + "typeLibrary" : "__type__, Bibliothek", + "unnamedType" : "Unbenannt __type__", + "dialogSaveOverwrite" : "Ein __libraryType__ mit dem Namen __libraryName__ ist bereits vorhanden. Überschreiben?", + "invalidFilename" : "Ungültiger Dateiname", + "savedNodes" : "Gespeicherte Nodes", + "savedType" : "Gespeichert __type__", + "saveFailed" : "Speichern fehlgeschlagen: __message__", + "types": { + "examples" : "Beispiele" + } + }, + "palette" : { + "noInfo" : "Keine Informationen verfügbar", + "filter" : "Filter Nodes", + "search" : "Suchmodule", + "addCategory" : "Neu hinzufügen ...", + "label" : { + "subflows" : "Subflows", + "input" : "Eingabe", + "output" : "Ausgabe", + "function" : "Funktion", + "social" : "Soziale", + "storage" : "Speicher", + "analysis" : "Analyse", + "advanced" : "fortgeschritten" + }, + "event" : { + "nodeAdded" : "Node zur Palette hinzugefügt:", + "nodeAdded_plural" : "Die Nodes wurde der Palette hinzugefügt.", + "nodeRemoved" : "Node aus Palette entfernt:", + "nodeRemoved_plural" : "Nodes aus Palette entfernt:", + "nodeEnabled" : "Node aktiviert:", + "nodeEnabled_plural" : "Nodes aktiviert:", + "nodeDisabled" : "Node inaktiviert:", + "nodeDisabled_plural" : "Nodes inaktiviert:", + "nodeUpgraded" : "Node-Modul __module__ aktualisiert auf Version __version__" + }, + "editor" : { + "title" : "Palette verwalten", + "palette" : "Palette", + "times" : { + "seconds" : "Vor Sekunden", + "minutes" : "Minuten vor", + "minutesV" : "__count__ Minuten", + "hoursV" : "__count__ Stunde ago", + "hoursV_plural" : "__count__hours ago", + "daysV" : "__count__ Tag ago", + "daysV_plural" : "__count__ Tage", + "weeksV" : "__count__ Woche vor", + "weeksV_plural" : "__count__wochen ago", + "monthsV" : "__count__ Monat vor", + "monthsV_plural" : "__count__ Monaten", + "yearsV" : "__count__ Jahr", + "yearsV_plural" : "__count__ Jahren", + "yearMonthsV" : "____ Jahr, __count__ Monat", + "yearMonthsV_plural" : "____ Jahr, __count__ Monaten", + "yearsMonthsV" : "____ Jahre, __count__ Monat vor", + "yearsMonthsV_plural" : "____ Jahre, __count__ Monaten" + }, + "nodeCount" : "__label__, Node", + "nodeCount_plural" : "__label__ Nodes", + "moduleCount" : "__count__ Modul verfügbar", + "moduleCount_plural" : "__count__-Module verfügbar", + "inuse" : "im Gebrauch", + "enableall" : "alle aktivieren", + "disableall" : "Alle inaktivieren", + "enable" : "aktivieren", + "disable" : "inaktivieren", + "remove" : "entfernen", + "update" : "Update auf __version__", + "updated" : "aktualisiert", + "install" : "installieren", + "installed" : "installiert", + "loading" : "Kataloge werden geladen ...", + "tab-nodes" : "Nodes", + "tab-install" : "installieren", + "sort" : "Sortierung:", + "sortAZ" : "a-z", + "sortRecent" : "kürzlich", + "more" : "+ __count__ mehr", + "errors" : { + "catalogLoadFailed" : "

Fehler beim Laden des Node-Katalogs.

Weitere Informationen finden Sie in der Browserkonsole.

", + "installFailed" : "

Installation fehlgeschlagen: __module__

__message__

Überprüfen Sie das Protokoll auf weitere Informationen.

", + "removeFailed" : "

Entfernen fehlgeschlagen: __module__

__message__

Überprüfen Sie das Protokoll auf weitere Informationen.

", + "updateFailed" : "

Aktualisierung fehlgeschlagen: __module__

__message__

Überprüfen Sie das Protokoll auf weitere Informationen.

", + "enableFailed" : "

Fehlgeschlagene Aktivierung: __module__

__message__

Überprüfen Sie das Protokoll auf weitere Informationen.

", + "disableFailed" : "

Inaktivieren fehlgeschlagen: __module__

__message__

Überprüfen Sie das Protokoll auf weitere Informationen.

" + }, + "confirm" : { + "install" : { + "body" : "

Installieren von '__module__'

Vor der Installation von lesen Sie bitte die Dokumentation des Nodes. Einige Nodes haben Abhängigkeiten, die nicht automatisch aufgelöst werden können und einen Neustart von 'Node-RED' erfordern.

", + "title" : "Nodes installieren" + }, + "remove" : { + "body" : "

Entfernen von '__module__'

-Der Node deinstalliert ihn aus Node-RED. Der Node kann weiterhin Ressourcen verwenden, bis Node-RED erneut gestartet wird.

", + "title" : "Nodes entfernen" + }, + "update" : { + "body" : "

Aktualisieren von '__module__'

Für die Aktualisierung des Nodes ist ein Neustart von 'Node-RED' erforderlich, damit die Aktualisierung abgeschlossen werden kann. Dies muss manuell geschehen.

", + "title" : "Nodes aktualisieren" + }, + "cannotUpdate" : { + "body" : "Es ist eine Aktualisierung für diesen Node verfügbar, aber sie ist nicht an einer Position installiert, die vom Palettenmanager aktualisiert werden kann.

Weitere Informationen zum Aktualisieren dieses Nodes finden Sie in der Dokumentation." + }, + "button" : { + "review" : "Node-Informationen öffnen", + "install" : "installieren", + "remove" : "Entfernen", + "update" : "Aktualisieren" + } + } + } + }, + "sidebar" : { + "info" : { + "name" : "Node-Informationen", + "tabName" : "Name", + "label" : "info", + "node" : "Node", + "type" : "Typ", + "id" : "ID", + "status" : "Status", + "enabled" : "Aktiviert", + "disabled" : "Inaktiviert", + "subflow" : "Subflow", + "instances" : "Exemplare", + "properties" : "Eigenschaften", + "info" : "Informationen", + "blank" : "leer", + "null" : "null", + "showMore" : "Weitere anzeigen", + "showLess" : "Weniger anzeigen", + "flow" : "Flow", + "selection" : "Auswahl", + "nodes" : "__count__ Nodes", + "flowDesc" : "Beschreibung des Flows", + "subflowDesc" : "Beschreibung des Subflows", + "nodeHelp" : "Node-Hilfe", + "none" : "Keine", + "arrayItems" : "__count__ items", + "showTips" : "Sie können die Tipps in der Anzeige \"Einstellungen\" öffnen." + }, + "config" : { + "name" : "Konfigurations-Node", + "label" : "Konfiguration", + "global" : "Bei allen Flows", + "none" : "keine", + "subflows" : "Subflows", + "flows" : "Flows", + "filterAll" : "alle", + "filterUnused" : "Nicht verwendet", + "filtered" : "__count__ verdeckt" + }, + "context" : { + "name" : "Kontextdaten", + "label" : "Kontext", + "none" : "keine ausgewählt", + "refresh" : "Aktualisierung zum Laden", + "empty" : "leer", + "node" : "Node", + "flow" : "Flow", + "global" : "Global" + }, + "palette" : { + "name" : "Palettenverwaltung", + "label" : "Palette" + }, + "project" : { + "label" : "Projekt", + "name" : "Projekt", + "description" : "Beschreibung", + "dependencies" : "Abhängigkeiten", + "settings" : "Einstellungen", + "noSummaryAvailable" : "Keine Zusammenfassung verfügbar", + "editDescription" : "Projektbeschreibung bearbeiten", + "editDependencies" : "Projektabhängigkeiten bearbeiten", + "editReadme" : "README.md bearbeiten", + "projectSettings" : { + "edit" : "bearbeiten", + "none" : "Keine", + "install" : "installieren", + "removeFromProject" : "Aus Projekt entfernen", + "addToProject" : "zu Projekt hinzufügen", + "files" : "Dateien", + "flow" : "Flow", + "credentials" : "Berechtigungsnachweis", + "invalidEncryptionKey" : "Ungültiger Chiffrierschlüssel", + "encryptionEnabled" : "Verschlüsselung aktiviert", + "encryptionDisabled" : "Verschlüsselung inaktiviert", + "setTheEncryptionKey" : "Legen Sie den Verschlüsselungsschlüssel fest:", + "resetTheEncryptionKey" : "Setzt den Verschlüsselungsschlüssel zurück:", + "changeTheEncryptionKey" : "Ändern Sie den Verschlüsselungsschlüssel:", + "currentKey" : "Aktueller Schlüssel", + "newKey" : "Neuer Schlüssel", + "credentialsAlert" : "Dadurch werden alle vorhandenen Berechtigungsnachweise gelöscht.", + "versionControl" : "Versionssteuerung", + "branches" : "Verzweigungen", + "noBranches" : "Keine Verzweigungen", + "deleteConfirm" : "Sind Sie sicher, dass Sie die lokale Verzweigung '__name__' löschen wollen? Dies kann nicht rückgängig gemacht werden.", + "unmergedConfirm" : "Die lokale Verzweigung '__name__' enthält nicht zusammengeführte Änderungen, die verloren gehen. Sind Sie sicher, dass Sie ihn löschen möchten?", + "deleteUnmergedBranch" : "Nicht zusammengeführte Verzweigung löschen", + "gitRemotes" : "Git Remotes", + "addRemote" : "ferne hinzufügen", + "addRemote2" : "Ferne hinzufügen", + "remoteName" : "Ferner Name", + "nameRule" : "Darf nur A-Z 0-9 _ enthalten.", + "url" : "URL", + "urlRule" : "https://, ssh:// oder file://", + "urlRule2" : "Geben Sie den Benutzernamen/das Kennwort nicht in die URL ein.", + "noRemotes" : "Keine Remotes", + "deleteRemoteConfrim" : "Sind Sie sicher, dass Sie den fernen '__name__' löschen möchten?", + "deleteRemote" : "Ferne löschen" + }, + "userSettings" : { + "committerDetail" : "Committer-Details", + "committerTip" : "Leer Wert für Systemstandardwert belassen", + "userName" : "Benutzername", + "email" : "E-Mail", + "sshKeys" : "SSH-Schlüssel", + "sshKeysTip" : "Ermöglicht es Ihnen, sichere Verbindungen zu fernen Git-Repositorys zu erstellen.", + "add" : "Schlüssel hinzufügen", + "addSshKey" : "SSH-Schlüssel hinzufügen", + "addSshKeyTip" : "Ein neues öffentungs-/privates Schlüsselpaar generieren", + "name" : "Name", + "nameRule" : "Darf nur A-Z 0-9 _ enthalten.", + "passphrase" : "Kennphrase", + "passphraseShort" : "Kennphrase zu kurz", + "optional" : "Optional", + "cancel" : "Abbrechen", + "generate" : "Schlüssel generieren", + "noSshKeys" : "Keine SSH-Schlüssel", + "copyPublicKey" : "Öffentlichen Schlüssel in Zwischenablage kopieren", + "delete" : "Löschtaste", + "gitConfig" : "Git-Konfiguration", + "deleteConfirm" : "Sind Sie sicher, dass der SSH-Schlüssel __name__ gelöscht werden soll? Dies kann nicht rückgängig gemacht werden." + }, + "versionControl" : { + "unstagedChanges" : "Nicht zwischengespeicherte Änderungen", + "stagedChanges" : "Gespeichte Änderungen", + "resolveConflicts" : "Konflikte auflösen", + "head" : "HEAD", + "staged" : "Zwischengelagert", + "unstaged" : "Nicht zwischengespeichert", + "local" : "Lokal", + "remote" : "Fern", + "revert" : "Sind Sie sicher, dass die Änderungen auf '__file__' zurückgesetzt werden sollen? Dies kann nicht rückgängig gemacht werden.", + "revertChanges" : "Änderungen zurücksetzen", + "localChanges" : "Lokale Änderungen", + "none" : "Keine", + "conflictResolve" : "Alle Konflikte wurden aufgelöst. Festschreiben der Änderungen, um den Mischvorgang abzuschließen.", + "localFiles" : "Lokale Dateien", + "all" : "alle", + "unmergedChanges" : "Nicht zusammengeführte Änderungen", + "abortMerge" : "Zusammenführen abbrechen", + "commit" : "Festschreiben", + "changeToCommit" : "Änderungen beim Festschreiben", + "commitPlaceholder" : "Geben Sie Ihre Festschreibungsnachricht", + "cancelCapital" : "Abbrechen", + "commitCapital" : "Festschreiben", + "commitHistory" : "Protokoll festschreiben", + "branch" : "Verzweigung:", + "moreCommits" : " weitere Commit (s)", + "changeLocalBranch" : "Lokale Verzweigung ändern", + "createBranchPlaceholder" : "Verzweigung suchen oder erstellen", + "upstream" : "Upstream", + "localOverwrite" : "Sie haben lokale Änderungen, die überschrieben werden, indem Sie die Verzweigung ändern. Sie müssen diese Änderungen zuerst festschreiben oder rückgängig machen.", + "manageRemoteBranch" : "Ferne Verzweigung verwalten", + "unableToAccess" : "Zugriff auf fernes Repository nicht möglich", + "retry" : "Retry", + "setUpstreamBranch" : "Als vorgeschaltete Verzweigung festlegen", + "createRemoteBranchPlaceholder" : "Ferne Verzweigung suchen oder erstellen", + "trackedUpstreamBranch" : "Die erstellte Verzweigung wird als überwachte Upstream-Verzweigung festgelegt.", + "selectUpstreamBranch" : "Die Verzweigung wird erstellt. Wählen Sie diese Option aus, um sie als überwachte Upstream-Verzweigung festzulegen", + "pushFailed" : "Push ist fehlgeschlagen, da die ferne Commit-COMMs-COMMs (COMM Zuerst ziehen und mischen, dann erneut drücken.", + "push" : "Push", + "pull" : "Pull", + "unablePull" : "

Ferne Änderungen können nicht gezogen werden. Die nicht zwischengespeicherten lokalen Änderungen werden überschrieben.

Die Änderungen festschreiben und die Anforderung wiederholen.

", + "showUnstagedChanges" : "Nicht zwischengespeicherte Änderungen anzeigen", + "connectionFailed" : "Verbindung zum fernen Repository konnte nicht hergestellt werden: ", + "pullUnrelatedHistory" : "

Das ferne Protokoll der Festschreibungen hat einen nicht zugehörigen Verlauf.

Sind Sie sicher, dass Sie die Änderungen in Ihr lokales Repository ziehen möchten?

", + "pullChanges" : "Änderungen extrahieren", + "history" : "Verlauf", + "daysAgo" : "__count__ Tag ago", + "daysAgo_plural" : "__count__ Tage", + "hoursAgo" : "__count__ Stunde ago", + "hoursAgo_plural" : "__count__hours ago", + "minsAgo" : "__count__ min ago", + "minsAgo_plural" : "__count__ mins ago", + "secondsAgo" : "Sekunden zurück", + "notTracking" : "Ihre lokale Verzweigung verfolgt derzeit keine ferne Verzweigung.", + "statusUnmergedChanged" : "In Ihrem Repository sind nicht zusammengeführte Änderungen vorhanden. Sie müssen die Konflikte beheben und das Ergebnis festschreiben.", + "repositoryUpToDate" : "Ihr Repository ist auf dem neuesten Stand.", + "commitsAhead" : "Ihr Repository ist __count__commit vor der fernen. Sie können diese Festschreibung jetzt übertragen.", + "commitsAhead_plural" : "Ihr Repository ist __count__ ist vor der fernen Commits festgeschrieben. Sie können diese Commits jetzt verschieben.", + "commitsBehind" : "Ihr Projektarchiv ist __count__ hinter der Fernbedienung. Sie können diese Festschreibung jetzt extrahieren.", + "commitsBehind_plural" : "Ihr Repository ist __count__ ist hinter der Fernbedienung festgeschrieben. Sie können diese Commits jetzt extrahieren.", + "commitsAheadAndBehind1" : "Ihr Projektarchiv ist __count__commit hinter und ", + "commitsAheadAndBehind1_plural" : "Ihr Repository ist __count__ schreibt sich zurück und ", + "commitsAheadAndBehind2" : "__count__ wird vor der fernen festgeschrieben. ", + "commitsAheadAndBehind2_plural" : "__count__ schreibt vor der fernen Funktion fest. ", + "commitsAheadAndBehind3" : "Sie müssen die ferne Festschreibung nach unten ziehen, bevor Sie sie drücken.", + "commitsAheadAndBehind3_plural" : "Sie müssen die fernen Festschreibungen vor dem Pusdrücken zurückziehen." + } + } + }, + "typedInput" : { + "type" : { + "str" : "String", + "num" : "Number", + "re" : "Regulärer Ausdruck", + "bool" : "boolean", + "json" : "JSON", + "bin" : "Buffer", + "date" : "timestamp", + "jsonata" : "Ausdruck", + "env" : "env, Variable" + } + }, + "editableList" : { + "add" : "hinzufügen" + }, + "search" : { + "empty" : "Keine Übereinstimmungen gefunden", + "addNode" : "Node hinzufügen ..." + }, + "expressionEditor" : { + "functions" : "Funktionen", + "functionReference" : "Funktionsreferenz", + "insert" : "Einfügen", + "title" : "JSONata-Ausdruckseditor", + "test" : "Test", + "data" : "Beispielnachricht", + "result" : "Ergebnis", + "format" : "Formatiere Ausdruck", + "compatMode" : "Kompatibilitätsmodus aktiviert", + "compatModeDesc" : "

JSONata-Kompatibilitätsmodus

Der aktuelle Ausdruck scheint immer noch auf msg zu verweisen, so dass er im Kompatibilitätsmodus ausgewertet wird. Aktualisieren Sie den Ausdruck so, dass msg nicht verwendet wird, da dieser Modus in der Zukunft entfernt wird.

Wenn die JSONata-Unterstützung zuerst zu Node-RED hinzugefügt wurde, ist der Ausdruck erforderlich, um auf das Objekt msg zu verweisen. Beispiel: msg.payload würde für den Zugriff auf die Nutzdaten verwendet.

Das ist nicht mehr erforderlich, da der Ausdruck direkt anhand der Nachricht ausgewertet wird. Um auf die Nutzdaten zugreifen zu können, muss der Ausdruck nur Nutzdaten sein.

", + "noMatch" : "Kein übereinstimmende Ergebnisse", + "errors" : { + "invalid-expr" : "Ungültiger JSONata-Ausdruck:\n __message__", + "invalid-msg" : "Ungültiges Beispiel für JSON-Nachricht:\n __message__", + "context-unsupported" : "Kontextfunktionen können nicht getestet werden\n $flowContext oder $globalContext", + "eval" : "Fehler beim Auswerten des Ausdrucks\n __message__" + } + }, + "jsEditor" : { + "title" : "JavaScript-Editor" + }, + "jsonEditor" : { + "title" : "JSON-Editor", + "format" : "Formatiere JSON" + }, + "markdownEditor" : { + "title" : "Markdown-Editor" + }, + "bufferEditor" : { + "title" : "Buffereditor", + "modeString" : "Als UTF-8-Zeichenfolge bearbeiten", + "modeArray" : "Als JSON-Array bearbeiten", + "modeDesc" : "

Buffereditor

Der Buffertyp wird als JSON-Array mit Bytewerten gespeichert. Der Editor versucht, den eingegebenen Wert als JSON-Array zu parsen. Wenn es sich nicht um ein gültiges JSON handelt, wird es als UTF-8-Zeichenfolge behandelt und in ein Array der einzelnen Zeichencodepunkte konvertiert.

Beispiel: Der Wert Hello World wird in das JSON-Array konvertiert:

 [ 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100] 

" + }, + "projects" : { + "config-git" : "Git-Client konfigurieren", + "welcome" : { + "hello" : "Hallo! Wir haben 'Projekte' in 'Node-RED' eingeführt.", + "desc0" : "Dies ist eine neue Methode für die Verwaltung Ihrer Datenflowsdateien und die Versionssteuerung Ihrer Abläufe.", + "desc1" : "Um zu beginnen, können Sie Ihr erstes Projekt erstellen oder ein vorhandenes Projekt aus einem Git-Repository klonen.", + "desc2" : "Wenn Sie sich nicht sicher sind, können Sie das jetzt überspringen. Sie können immer noch Ihr erstes Projekt aus dem 'Projects' -Menü erstellen.", + "create" : "Projekt erstellen", + "clone" : "Repository klonen", + "not-right-now" : "Jetzt nicht mehr" + }, + "git-config" : { + "setup" : "Konfigurieren Sie Ihren Versionssteuerungsclient.", + "desc0" : "Node-RED verwendet das Open-Source-Tool Git für die Versionssteuerung. Es protokolliert Änderungen in Ihren Projektdateien und ermöglicht es Ihnen, sie in ferne Repositorys zu übertragen.", + "desc1" : "Wenn Sie eine Reihe von Änderungen festschreiben, werden die Änderungen mit einem Benutzernamen und einer E-Mail-Adresse von GIT-Datensätzen vorgenommen. Der Benutzername kann alles sein, was Sie wollen-es muss nicht Ihr richtiger Name sein.", + "desc2" : "Ihr Git-Client ist bereits mit den unten stehenden Details konfiguriert.", + "desc3" : "Sie können diese Einstellungen später unter der Registerkarte \"Git config\" des Einstellungsdialogs ändern.", + "username" : "Benutzername", + "email" : "E-Mail" + }, + "project-details" : { + "create" : "Erstellen Sie Ihr Projekt.", + "desc0" : "Ein Projekt wird als Git-Repository verwaltet. Es ist wesentlich einfacher, Ihre Abläufe mit anderen zu teilen und an ihnen zu arbeiten.", + "desc1" : "Sie können mehrere Projekte erstellen und schnell zwischen den Projekten im Editor wechseln.", + "desc2" : "Zu Beginn benötigt Ihr Projekt einen Namen und eine optionale Beschreibung.", + "already-exists" : "Das Projekt ist bereits vorhanden", + "must-contain" : "Darf nur A-Z 0-9 _ enthalten.", + "project-name" : "Projektname", + "desc" : "Beschreibung", + "opt" : "Optional" + }, + "clone-project" : { + "clone" : "Projekt klonen", + "desc0" : "Wenn Sie bereits über ein Git-Repository verfügen, das ein Projekt enthält, können Sie es klonen, um es zu starten.", + "already-exists" : "Das Projekt ist bereits vorhanden", + "must-contain" : "Darf nur A-Z 0-9 _ enthalten.", + "project-name" : "Projektname", + "no-info-in-url" : "Geben Sie den Benutzernamen/das Kennwort nicht in die URL ein.", + "git-url" : "Git-Repository-URL", + "protocols" : "https://, ssh:// oder file://", + "auth-failed" : "Authentifizierung fehlgeschlagen", + "username" : "Benutzername", + "passwd" : "Kennwort", + "ssh-key" : "SSH-Schlüssel", + "passphrase" : "Kennphrase", + "ssh-key-desc" : "Bevor Sie ein Repository über ssh klonen können, müssen Sie einen SSH-Schlüssel hinzufügen, um auf diesen zu zugreifen.", + "ssh-key-add" : "Einen ssh-Schlüssel hinzufügen", + "credential-key" : "Verschlüsselungsschlüssel für Berechtigungsnachweise", + "cant-get-ssh-key" : "Fehler! Der ausgewählte SSH-Schlüsselpfad kann nicht abgerufen werden.", + "already-exists2" : "bereits vorhanden", + "git-error" : "Git-Fehler", + "connection-failed" : "Verbindung fehlgeschlagen", + "not-git-repo" : "Kein Git-Repository", + "repo-not-found" : "Repository nicht gefunden" + }, + "default-files" : { + "create" : "Erstellen Sie Ihre Projektdateien.", + "desc0" : "Ein Projekt enthält Ihre Flow-Dateien, eine README-Datei und eine package.json-Datei.", + "desc1" : "Es kann alle anderen Dateien enthalten, die im Git-Repository verwaltet werden sollen.", + "desc2" : "Ihre vorhandenen Flow- und Berechtigungsnachweisdateien werden in das Projekt kopiert.", + "flow-file" : "Flow-Datei", + "credentials-file" : "Berechtigungsnachweisdatei" + }, + "encryption-config" : { + "setup" : "Setup der Verschlüsselung Ihrer Berechtigungsnachweisdatei", + "desc0" : "Die Datei mit den Datenflowsberechtigungsnachweisen kann verschlüsselt werden, um ihren Inhalt sicher zu halten.", + "desc1" : "Wenn Sie diese Berechtigungsnachweise in einem öffentlichen Git-Repository speichern möchten, müssen Sie sie verschlüsseln, indem Sie einen geheimen Schlüsselausdruck bereitstellen.", + "desc2" : "Die Datei mit den Datenflowberechtigungsnachweisen ist derzeit nicht verschlüsselt.", + "desc3" : "Das heißt, ihr Inhalt, wie z. B. Kennwörter und Zugriffstokens, kann von jedem mit Zugriff auf die Datei gelesen werden.", + "desc4" : "Wenn Sie diese Berechtigungsnachweise in einem öffentlichen Git-Repository speichern möchten, müssen Sie sie verschlüsseln, indem Sie einen geheimen Schlüsselausdruck bereitstellen.", + "desc5" : "Ihre Datei mit den Datenflowberechtigungsnachweisen wird derzeit mit der Eigenschaft credentialSecret aus Ihrer Einstellungsdatei als Schlüssel verschlüsselt.", + "desc6" : "Die Datei mit den Datenflowberechtigungsnachweisen wird derzeit mit einem vom System generierten Schlüssel verschlüsselt. Sie sollten einen neuen geheimen Schlüssel für dieses Projekt angeben.", + "desc7" : "Der Schlüssel wird separat von den Projektdateien gespeichert. Sie müssen den Schlüssel angeben, damit dieses Projekt in einer anderen Instanz von Node-RED verwendet werden kann.", + "credentials" : "Berechtigungsnachweis", + "enable" : "Verschlüsselung aktivieren", + "disable" : "Verschlüsselung inaktivieren", + "disabled" : "inaktiviert", + "copy" : "Vorhandenen Schlüssel kopieren", + "use-custom" : "Angepasster Schlüssel verwenden", + "desc8" : "Die Datei mit den Berechtigungsnachweisen wird nicht verschlüsselt, und ihr Inhalt kann leicht gelesen werden.", + "create-project-files" : "Projektdateien erstellen", + "create-project" : "Projekt erstellen", + "already-exists" : "bereits vorhanden", + "git-error" : "Git-Fehler", + "git-auth-error" : "git-auth-Fehler" + }, + "create-success" : { + "success" : "Sie haben Ihr erstes Projekt erfolgreich erstellt!", + "desc0" : "Sie können jetzt weiterhin Node-RED verwenden, wie Sie es immer haben.", + "desc1" : "Auf der Registerkarte \"info\" in der Seitenleiste wird angezeigt, was Ihr aktuelles aktives Projekt ist. Die Schaltfläche neben dem Namen kann für den Zugriff auf die Sicht 'Projekteinstellungen' verwendet werden.", + "desc2" : "Die Registerkarte 'Verlauf' in der Seitenleiste kann verwendet werden, um Dateien anzuzeigen, die sich in Ihrem Projekt geändert haben, und sie festzuschreiben. Es zeigt Ihnen eine vollständige Historie Ihrer Commits an und ermöglicht es Ihnen, Ihre Änderungen in ein fernes Repository zu übertragen." + }, + "create" : { + "projects" : "Projekte", + "already-exists" : "Das Projekt ist bereits vorhanden", + "must-contain" : "Darf nur A-Z 0-9 _ enthalten.", + "no-info-in-url" : "Geben Sie den Benutzernamen/das Kennwort nicht in die URL ein.", + "open" : "Projekt öffnen", + "create" : "Projekt erstellen", + "clone" : "Repository klonen", + "project-name" : "Projektname", + "desc" : "Beschreibung", + "opt" : "Optional", + "flow-file" : "Flow-Datei", + "credentials" : "Berechtigungsnachweis", + "enable-encryption" : "Verschlüsselung aktivieren", + "disable-encryption" : "Verschlüsselung inaktivieren", + "encryption-key" : "Chiffrierschlüssel", + "desc0" : "Eine Phrase, mit der Sie Ihre Berechtigungsnachweise schützen", + "desc1" : "Die Datei mit den Berechtigungsnachweisen wird nicht verschlüsselt, und ihr Inhalt kann leicht gelesen werden.", + "git-url" : "Git-Repository-URL", + "protocols" : "https://, ssh:// oder file://", + "auth-failed" : "Authentifizierung fehlgeschlagen", + "username" : "Benutzername", + "password" : "Kennwort", + "ssh-key" : "SSH-Schlüssel", + "passphrase" : "Kennphrase", + "desc2" : "Bevor Sie ein Repository über ssh klonen können, müssen Sie einen SSH-Schlüssel hinzufügen, um auf diesen zu zugreifen.", + "add-ssh-key" : "Einen ssh-Schlüssel hinzufügen", + "credentials-encryption-key" : "Verschlüsselungsschlüssel für Berechtigungsnachweise", + "already-exists-2" : "bereits vorhanden", + "git-error" : "Git-Fehler", + "con-failed" : "Verbindung fehlgeschlagen", + "not-git" : "Kein Git-Repository", + "no-resource" : "Repository nicht gefunden", + "cant-get-ssh-key-path" : "Fehler! Der ausgewählte SSH-Schlüsselpfad kann nicht abgerufen werden.", + "unexpected_error" : "unerwarteter_Fehler" + }, + "delete" : { + "confirm" : "Sind Sie sicher, dass Sie dieses Projekt löschen möchten?" + }, + "create-project-list" : { + "search" : "Projekte durchsuchen", + "current" : "aktuell" + }, + "require-clean" : { + "confirm" : "

Sie haben nicht implementierte Änderungen verloren, die verloren gehen.

Möchten Sie fortfahren?

" + }, + "send-req" : { + "auth-req" : "Authentifizierung für Repository erforderlich", + "username" : "Benutzername", + "password" : "Kennwort", + "passphrase" : "Kennphrase", + "retry" : "Retry", + "update-failed" : "Fehler beim Aktualisieren der Auth.", + "unhandled" : "Nicht behandelte Fehlerantwort" + }, + "create-branch-list" : { + "invalid" : "Ungültige Verzweigung", + "create" : "Verzweigung erstellen", + "current" : "aktuell" + }, + "create-default-file-set" : { + "no-active" : "Standarddatei kann ohne aktives Projekt nicht erstellt werden", + "no-empty" : "Für ein nicht leeres Projekt kann keine Standarddatei erstellt werden.", + "git-error" : "Git-Fehler" + }, + "errors" : { + "no-username-email" : "Ihr Git-Client ist nicht mit einem Benutzernamen/einer E-Mail konfiguriert.", + "unexpected" : "Es ist ein unerwarteter Fehler aufgetreten", + "code" : "code" + } + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/de/infotips.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/de/infotips.json new file mode 100644 index 0000000..4cec02f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/de/infotips.json @@ -0,0 +1,23 @@ +{ + "info" : { + "tip0" : "Sie können die ausgewählten Nodes oder Verbindungen mit {{ core:delete-selection }} entfernen.", + "tip1" : "Suche nach Nodes mit {{ core:search }}", + "tip2" : "{{ core:toggle-sidebar }} schaltet die Ansicht dieser Seitenleiste ein.", + "tip3" : "Sie können Ihre Palette von Nodes mit {{ core:manage-palette }} verwalten.", + "tip4" : "Ihre Flow-Konfigurations-Nodes werden in der Seitenleiste angezeigt. Es kann über das Menü oder mit {{ core:show-config-tab }} aufgerufen werden.", + "tip5" : "Aktiviert oder inaktiviert diese Tipps von der Option in den Einstellungen", + "tip6" : "Verschieben Sie die ausgewählten Nodes mit Hilfe der [left] [up] [down] und [right] Tasten. Halten Sie [Shift] gedrückt, um das Fenster weiter zu schieben", + "tip7" : "Wenn Sie einen Node auf eine Verbindung ziehen, wird er in die Verbindung eingefügt.", + "tip8" : "Die ausgewählten Nodes exportieren oder die aktuelle Registerkarte mit {{ core:show-export-dialog }}", + "tip9" : "Importieren Sie einen Flow, indem Sie sein JSON in den Editor ziehen oder mit {{ core:show-import-dialog }}.", + "tip10" : "[Umschalt] [Klicken] und ziehen Sie auf einen Node-Anschluss, um alle angeschlossenen Verbindungen oder nur die ausgewählte zu verschieben.", + "tip11" : "Die Registerkarte \"Info\" mit {{ core:show-info-tab }} oder der Registerkarte \"Debug\" mit {{ core:show-debug-tab }} anzeigen", + "tip12" : "[ctrl] [Klicken] in den Arbeitsbereich, um den Schnellhinzufügedialog zu öffnen.", + "tip13" : "Halten Sie [ctrl] gedrückt, wenn Sie auf einem Node-Anschluss klicken, um eine Schnellverbindung zu aktivieren.", + "tip14" : "Halten Sie [Umschalt] gedrückt, wenn Sie auf einen Node klicken, um auch alle verbundenen Nodes auszuwählen.", + "tip15" : "Halten Sie [ctrl] gedrückt, wenn Sie auf einen Node klicken, um ihn aus der aktuellen Auswahl hinzuzufügen oder zu entfernen.", + "tip16" : "Indexzungen wechseln mit {{ core:show-previous-tab }} und {{ core:show-next-tab }}", + "tip17" : "Sie können die Änderungen im Editierrahmen des Nodes mit {{ core:confirm-edit-tray }} bestätigen oder sie mit {{ core:cancel-edit-tray }} abbrechen.", + "tip18" : "Durch Drücken von {{ core:edit-selected-node }} wird der erste Node in der aktuellen Auswahl bearbeitet." + } +} \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/de/jsonata.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/de/jsonata.json new file mode 100644 index 0000000..7859ca8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/de/jsonata.json @@ -0,0 +1,222 @@ +{ + "$string" : { + "args" : "arg", + "desc" : "Transformiert den Parameter *arg* in eine Zeichenfolge mit den folgenden Transformationsregeln:\n\n -Zeichenfolgen bleiben unverändert\n -Funktionen werden in eine leere Zeichenfolge konvertiert\n -Numerische Unendlichkeit und NaN lösen einen Fehler aus, da sie nicht als JSON-Nummer dargestellt werden können.\n -Alle anderen Werte werden mit Hilfe der Funktion 'JSON.stringify' in eine JSON-Zeichenfolge konvertiert." + }, + "$length" : { + "args" : "str", + "desc" : "Gibt die Anzahl der Zeichen in der Zeichenfolge `str` zurück. Es wird ein Fehler ausgelöst, wenn `str` keine Zeichenfolge ist." + }, + "$substring" : { + "args" : "str, start [, länge]", + "desc" : "Gibt eine Zeichenfolge zurück, die die Zeichen im ersten Parameter `str` beginnend bei Position `start` (Null-Offset) enthält. Wenn \"length\" angegeben ist, enthält die Unterzeichenfolge maximal \"Länge\" Zeichen. Wenn `start` negativ ist, gibt es die Anzahl der Zeichen am Ende von `str` an." + }, + "$substringBefore" : { + "args" : "str, chars", + "desc" : "Gibt die Unterzeichenfolge vor dem ersten Auftreten der Zeichenfolge `chars` in `str` zurück. Falls `str` nicht `chars` enthält, gibt es `str` zurück." + }, + "$substringAfter" : { + "args" : "str, chars", + "desc" : "Gibt die Unterzeichenfolge nach dem ersten Auftreten der Zeichenfolge `chars` in `str` zurück. Falls `str` nicht `chars` enthält, gibt es `str` zurück." + }, + "$uppercase" : { + "args" : "str", + "desc" : "Gibt eine Zeichenfolge mit allen Zeichen von `str` zurück, die in Großbuchstaben konvertiert werden." + }, + "$lowercase" : { + "args" : "str", + "desc" : "Gibt eine Zeichenfolge mit allen Zeichen von `str` in Kleinbuchstaben zurück." + }, + "$trim" : { + "args" : "str", + "desc" : "Normalisiert und trimmt alle Leerzeichen in `str` durch Anwenden der folgenden Schritte:\n\n -Alle Tabulatorstopps, Wagenrückläufe und Zeilenvorschübe werden durch Leerzeichen ersetzt.\n-Zusammenhängende Folgen von Räumen werden auf einen einzigen Raum reduziert.\n-Trailing und führende Plätze werden entfernt.\n\n Wenn 'str' nicht angegeben ist (d. h. Diese Funktion wird ohne Argumente aufgerufen), dann wird der Kontextwert als Wert von `str` verwendet. Es wird ein Fehler ausgelöst, wenn `str` keine Zeichenfolge ist." + }, + "$contains" : { + "args" : "str, Muster", + "desc" : "Gibt `true` zurück, wenn `str` durch `Muster` abgeglichen wird, sonst gibt es `false` zurück. Wenn 'str' nicht angegeben ist (d. h. Diese Funktion wird mit einem Argument aufgerufen), dann wird der Kontextwert als Wert von `str` verwendet. Der Parameter 'Muster' kann entweder eine Zeichenfolge oder ein regulärer Ausdruck sein." + }, + "$split" : { + "args" : "str [, Trennzeichen] [, Grenzwert]", + "desc" : "Teilt den Parameter 'str' in einem Array mit Unterzeichenfolgen. Es ist ein Fehler, wenn `str` keine Zeichenfolge ist. Der optionale Parameter 'Trennzeichen' gibt die Zeichen in der `str` an, um die es entweder als Zeichenfolge oder als regulärer Ausdruck geteilt werden soll. Wenn 'Trennzeichen' nicht angegeben wird, wird die leere Zeichenfolge angenommen, und `str` wird in ein Array aus einzelnen Zeichen aufgeteilt. Es handelt sich um einen Fehler, wenn `Trennzeichen' keine Zeichenfolge ist. Der optionale Parameter 'Grenzwert' ist eine Zahl, die die maximale Anzahl von Unterzeichenfolgen angibt, die in das resultierende Array eingeschlossen werden sollen. Alle zusätzlichen Unterzeichenfolgen werden gelöscht. Wenn 'Grenzwert' nicht angegeben wird, wird ' str ` vollständig geteilt, wobei die Größe des resultierenden Arrays nicht begrenzt ist. Es handelt sich um einen Fehler, wenn `Grenzwert' keine nicht negative Zahl ist." + }, + "$join" : { + "args" : "array [, Trennzeichen]", + "desc" : "Verkettet ein Array von Komponentenzeichenfolgen in eine einzelne verkettete Zeichenfolge mit jeder Komponentenzeichenfolge, die durch den optionalen Parameter 'separator' getrennt ist. Es ist ein Fehler, wenn die Eingabe `Array` ein Element enthält, das keine Zeichenfolge ist. Wenn 'Trennzeichen' nicht angegeben wird, wird davon ausgegangen, dass es sich um eine leere Zeichenfolge handelt, d. h. Zwischen den Komponentenzeichenfolgen ist kein Trennzeichen vorhanden. Es handelt sich um einen Fehler, wenn `Trennzeichen' keine Zeichenfolge ist." + }, + "$match" : { + "args" : "str, Muster [, Grenzwert]", + "desc" : "Wendet die Zeichenfolge `str` an den regulären Ausdruck `Muster` an und gibt ein Array von Objekten zurück, wobei jedes Objekt Informationen zu jedem Vorkommen einer Übereinstimmung in `str` enthält." + }, + "$replace" : { + "args" : "str, Muster, Ersatz [, Grenzwert]", + "desc" : "Findet Vorkommen von `Muster` in `str` und ersetzt sie durch `Ersatz`.\n\nDer optionale Parameter 'Grenzwert' ist die maximale Anzahl an Ersetzungen." + }, + "$now" : { + "args" : "", + "desc" : "Generiert einen Zeitstempel im ISO-8601-kompatiblen Format und gibt sie als Zeichenfolge zurück." + }, + "$base64encode" : { + "args" : "Zeichenfolge", + "desc" : "Konvertiert eine ASCII-Zeichenfolge in eine Basis-64-Darstellung. Jedes Zeichen in der Zeichenfolge wird als Byte mit binären Daten behandelt. Dies setzt voraus, dass alle Zeichen in der Zeichenfolge im Bereich von 0x00 bis 0xFF liegen, der alle Zeichen in URI-codierten Zeichenfolgen enthält. Unicode-Zeichen außerhalb dieses Bereichs werden nicht unterstützt." + }, + "$base64decode" : { + "args" : "Zeichenfolge", + "desc" : "Konvertiert die Basis-64-codierten Byte in eine Zeichenfolge unter Verwendung einer UTF-8-Unicode-Codepage." + }, + "$number" : { + "args" : "arg", + "desc" : "Der Parameter 'arg' wird unter Verwendung der folgenden Regeln für das Casting in eine Zahl verwendet:\n\n -Zahlen bleiben unverändert\n -Zeichenfolgen, die eine Folge von Zeichen enthalten, die eine rechtliche JSON-Nummer darstellen, werden in diese Zahl konvertiert.\n -Alle anderen Werte bewirken, dass ein Fehler ausgelöst wird." + }, + "$abs" : { + "args" : "Anzahl", + "desc" : "Gibt den absoluten Wert des Parameters 'Zahl' zurück." + }, + "$floor" : { + "args" : "Anzahl", + "desc" : "Gibt den Wert von 'Zahl' auf die nächste ganze Zahl zurück, die kleiner oder gleich 'Zahl' ist." + }, + "$ceil" : { + "args" : "Anzahl", + "desc" : "Gibt den Wert von 'Zahl' auf die nächste ganze Zahl zurück, die größer oder gleich 'Zahl' ist." + }, + "$round" : { + "args" : "Zahl [, Genauigkeit]", + "desc" : "Gibt den Wert des Parameters `Zahl` zurück, der auf die Anzahl der Dezimalstellen gerundet wird, die durch den optionalen Parameter 'Genauigkeit' angegeben wird." + }, + "$power" : { + "args" : "Basis, Exponent", + "desc" : "Gibt den Wert von `Basis` potenziert mit `Exponent` zurück." + }, + "$sqrt" : { + "args" : "Zahl", + "desc" : "Gibt die Quadratwurzel des Werts des Parameters 'Zahl' zurück." + }, + "$random" : { + "args" : "", + "desc" : "Gibt eine Pseudozufallszahl größer-gleich null und kleiner als eins zurück." + }, + "$millis" : { + "args" : "", + "desc" : "Gibt die Anzahl der Millisekunden seit der Unix-Epoche (1. Januar 1970 (UTC)) als Zahl zurück. Alle Invocationen von `$millis ()` innerhalb einer Auswertung eines Ausdrucks geben alle denselben Wert zurück." + }, + "$sum" : { + "args" : "Array", + "desc" : "Gibt die arithmetische Summe eines `Array` von Zahlen zurück. Es ist ein Fehler, wenn die Eingabe `Array` ein Element enthält, das keine Zahl ist." + }, + "$max" : { + "args" : "Array", + "desc" : "Gibt die maximale Anzahl in einem `Array` von Zahlen zurück. Es ist ein Fehler, wenn die Eingabe `Array` ein Element enthält, das keine Zahl ist." + }, + "$min" : { + "args" : "Array", + "desc" : "Gibt die minimale Zahl in einem `Array` von Zahlen zurück. Es ist ein Fehler, wenn die Eingabe `Array` ein Element enthält, das keine Zahl ist." + }, + "$average" : { + "args" : "Array", + "desc" : "Gibt den Mittelwert eines `Array` von Zahlen zurück. Es ist ein Fehler, wenn die Eingabe `Array` ein Element enthält, das keine Zahl ist." + }, + "$boolean" : { + "args" : "arg", + "desc" : "Castet das Argument mit den folgenden Regeln in einen Booleschen Wert:\n\n -` Boolean ': nicht geändert\n -` string `: leer: `false`\n -` string `: nicht leer: `true`\n -` Zahl `: ` 0 `: ` falsch `\n -` Zahl `: Nicht-Null: `true`\n -` null `: `false`\n -` array `: leer: `false`\n -` array `: enthält ein Mitglied, das auf `true` setzt: `true`\n -` array `: alle Member werden in `false` umgesetzt: `false`\n -` object `: empty: `false`\n -` object `: non-empty: `true`\n -` Funktion `: ` falsch `" + }, + "$not" : { + "args" : "arg", + "desc" : "Gibt den Booleschen Wert NOT für das Argument zurück. `arg` wird zuerst in einen Booleschen Wert umgesetzt." + }, + "$exists" : { + "args" : "arg", + "desc" : "Gibt den Booleschen Wert 'true' zurück, wenn der Ausdruck `arg` als Wert ausgewertet wird, oder 'false', wenn der Ausdruck nicht mit einem anderen Ausdruck übereinstimmt (z. B. ein Pfad zu einer nicht vorhandenen Feldreferenz)." + }, + "$count" : { + "args" : "Array", + "desc" : "Gibt die Anzahl der Elemente in dem Array zurück." + }, + "$append" : { + "args" : "Array, Array", + "desc" : "Hängen Sie zwei Arrays an." + }, + "$sort" : { + "args" : "array [, Funktion]", + "desc" : "Gibt ein Array zurück, das alle Werte im Parameter 'array' enthält, aber in der Reihenfolge sortiert wird.\n\nWenn ein Vergleichsoperator 'function' angegeben wird, muss es sich um eine Funktion handeln, die zwei Parameter benötigt:\n\n` Funktion (links, rechts) `\n\nDiese Funktion wird durch den Sortieralgorithmus aufgerufen, um zwei Werte links und rechts zu vergleichen. Wenn der Wert von links nach dem Wert von rechts in der gewünschten Sortierreihenfolge platziert werden soll, muss die Funktion den Booleschen Wert 'true' zurückgeben, um einen Auslagerungsspeicher anzuzeigen. Andernfalls muss 'false' zurückgegeben werden." + }, + "$reverse" : { + "args" : "Array", + "desc" : "Gibt ein Array zurück, das alle Werte aus dem Parameter 'array' enthält, aber in umgekehrter Reihenfolge." + }, + "$shuffle" : { + "args" : "Array", + "desc" : "Gibt ein Array zurück, das alle Werte aus dem Parameter ` array ` enthält, aber in zufälliger Reihenfolge geschattiert ist." + }, + "$zip" : { + "args" : "Array, ...", + "desc" : "Gibt ein konvolviertes (gezipptes) Array zurück, das gruppierte Arrays von Werten aus den Argumenten ` array1 ` ... ` arrayN ' aus Index 0, 1, 2 ... enthält." + }, + "$keys" : { + "args" : "Objekt", + "desc" : "Gibt ein Array zurück, das die Schlüssel in dem Objekt enthält. Wenn es sich bei dem Argument um ein Array von Objekten handelt, enthält das zurückgegebene Array eine deduplizierte Liste aller Schlüssel in allen Objekten." + }, + "$lookup" : { + "args" : "Objekt, Schlüssel", + "desc" : "Gibt den Wert zurück, der dem Schlüssel im Objekt zugeordnet ist. Wenn es sich bei dem ersten Argument um ein Array von Objekten handelt, werden alle Objekte im Array durchsucht, und die Werte, die mit allen Vorkommen des Schlüssels verknüpft sind, werden zurückgegeben." + }, + "$spread" : { + "args" : "Objekt", + "desc" : "Teilt ein Objekt, das Schlüssel/Wert-Paare enthält, in ein Array von Objekten, von denen jedes ein einzelnes Schlüssel/Wert-Paar aus dem Eingabeobjekt hat. Wenn es sich bei dem Parameter um ein Array von Objekten handelt, enthält die resultierende Feldgruppe ein Objekt für jedes Schlüssel/Wert-Paar in jedem Objekt in der angegebenen Feldgruppe." + }, + "$merge" : { + "args" : "array <object>", + "desc" : "Mischt ein Array von ` Objekten ` in ein einzelnes ` Objekt `, das alle Schlüssel/Wert-Paare aus jedem der Objekte in dem Eingabe-Array enthält. Wenn eines der Eingabeobjekte denselben Schlüssel enthält, enthält das zurückgegebene Objekt den Wert des letzten Objekts in der Feldgruppe. Es handelt sich um einen Fehler, wenn das Eingabe-Array ein Element enthält, das kein Objekt ist." + }, + "$sift" : { + "args" : "Objekt, Funktion", + "desc" : "Gibt ein Objekt zurück, das nur die Schlüssel/Wert-Paare aus dem Parameter 'object' enthält, die die Prädikat ` funktion ' erfüllen, die als zweiter Parameter übergeben wird.\n\nDie Funktion ` function `, die als zweiter Parameter angegeben wird, muss die folgende Signatur aufweisen:\n\n` function (value [, key [, object]]) `" + }, + "$each" : { + "args" : "Objekt, Funktion", + "desc" : "Gibt ein Array zurück, das die Werte enthält, die von der Funktion ` function ` zurückgegeben werden, wenn sie auf jedes Schlüssel/Wert-Paar im ` object ` angewendet werden." + }, + "$map" : { + "args" : "Array, Funktion", + "desc" : "Gibt ein Array zurück, das die Ergebnisse der Anwendung des Parameters ` function ` auf jeden Wert im Parameter 'array' enthält.\n\nDie Funktion ` function `, die als zweiter Parameter angegeben wird, muss die folgende Signatur aufweisen:\n\n` function (value [, index [, array]]) `" + }, + "$filter" : { + "args" : "Array, Funktion", + "desc" : "Gibt ein Array zurück, das nur die Werte im Parameter 'array' enthält, die das Prädikat ` funktion ` erfüllen.\n\nDie Funktion ` function `, die als zweiter Parameter angegeben wird, muss die folgende Signatur aufweisen:\n\n` function (value [, index [, array]]) `" + }, + "$reduce" : { + "args" : "array, function [, init]", + "desc" : "Gibt einen aggregierten Wert zurück, der aus der Anwendung des Parameters ` function 'nacheinander auf jeden Wert in' array ` in Kombination mit dem Ergebnis der vorherigen Anwendung der Funktion angewendet wurde.\n\nDie Funktion muss zwei Argumente akzeptieren und verhält sich wie ein Infix-Operator zwischen jedem Wert innerhalb des ` Array `.\n\nDer optionale Parameter 'init' wird als Anfangswert in der Aggregation verwendet." + }, + "$flowContext" : { + "args" : "Zeichenfolge [, Zeichenfolge]", + "desc" : "Ruft eine Flusskontexteigenschaft ab.\n\nDies ist eine definierte Funktion vom Typ \"Node-RED\"." + }, + "$globalContext" : { + "args" : "Zeichenfolge [, Zeichenfolge]", + "desc" : "Ruft eine globale Kontexteigenschaft ab.\n\nDies ist eine definierte Funktion vom Typ \"Node-RED\"." + }, + "$pad" : { + "args" : "string, width [, char]", + "desc" : "Gibt eine Kopie der ` Zeichenfolge ` mit zusätzlichen Aufenthalten zurück, falls erforderlich, so dass die Gesamtzahl der Zeichen mindestens der absolute Wert des Parameters 'width' ist.\n\nWenn ` width ` eine positive Zahl ist, wird die Zeichenfolge nach rechts aufgefüllt. Wenn sie negativ ist, wird sie nach links geplisften.\n\nDas optionale Argument 'char' gibt die Padding-Zeichen an, die verwendet werden sollen. Wenn keine Angabe gemacht wird, wird standardmäßig der Wert für das Leerzeichen angenommen." + }, + "$fromMillis" : { + "args" : "Anzahl", + "desc" : "Konvertieren Sie eine Zahl, die Millisekunden seit der Unix-Epoche (1. Januar 1970 (UTC)) enthält in eine Zeitangabe im ISO 8601-Format." + }, + "$formatNumber" : { + "args" : "Zahl, Bild [, Optionen]", + "desc" : "Transformiere die `Zahl` an eine Zeichenfolge und formatiert sie in eine dezimale Darstellung, wie in der 'Bild' -Zeichenfolge angegeben.\n\n Das Verhalten dieser Funktion ist mit der XPath/XQuery-Funktion fn:formatnummer konsistent, wie sie in der XPath F&O 3.1-Spezifikation definiert ist. Der Parameter für die Bildzeichenfolge definiert, wie die Zahl formatiert ist und hat die gleiche Syntax wie fn:format-number.\n\nDas optionale dritte Argument ` Optionen ` wird verwendet, um die standardmäßigen länderspezifischen Formatierungszeichen, wie z. B. das Dezimaltrennzeichen, zu überschreiben. Wenn dieses Argument angegeben wird, muss es sich um ein Objekt handeln, das Name/Wert-Paare enthält, die im Abschnitt mit dem Dezimalformat der XPath F&O 3.1-Spezifikation angegeben sind." + }, + "$formatBase" : { + "args" : "Zahl [, Radix]", + "desc" : "Transformiere die `Zahl` in eine Zeichenfolge und formatiert sie in eine ganze Zahl, die in der durch das `radix` -Argument angegebenen Zahlenbasis dargestellt wird. Wenn 'radix' nicht angegeben wird, wird standardmäßig die Basis 10 verwendet. 'radix` kann zwischen 2 und 36 liegen, andernfalls wird ein Fehler ausgelöst." + }, + "$toMillis" : { + "args" : "timestamp", + "desc" : "Konvertieren Sie eine Zeitangabe im ISO 8601-Format in die Anzahl der Millisekunden seit der Unix-Epoche (1. Januar 1970 (UTC)) als Zahl. Es wird ein Fehler ausgelöst, wenn die Zeichenfolge nicht das richtige Format hat." + }, + "$env" : { + "args" : "arg", + "desc" : "Gibt den Wert einer Umgebungsvariablen zurück.\n\nDies ist eine definierte Funktion vom Typ \"Node-RED\"." + } +} \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json new file mode 100644 index 0000000..ed4d4f9 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json @@ -0,0 +1,1015 @@ +{ + "common": { + "label": { + "name": "Name", + "ok": "Ok", + "done":"Done", + "cancel": "Cancel", + "delete": "Delete", + "close": "Close", + "load": "Load", + "save": "Save", + "import": "Import", + "export": "Export", + "back": "Back", + "next": "Next", + "clone": "Clone project", + "cont": "Continue" + }, + "type": { + "string": "string", + "number": "number", + "boolean": "boolean", + "array": "array", + "buffer": "buffer", + "object": "object", + "jsonString": "JSON string", + "undefined": "undefined", + "null": "null" + } + }, + "workspace": { + "defaultName": "Flow __number__", + "editFlow": "Edit flow: __name__", + "confirmDelete": "Confirm delete", + "delete": "Are you sure you want to delete '__label__'?", + "dropFlowHere": "Drop the flow here", + "addFlow": "Add Flow", + "listFlows": "List Flows", + "status": "Status", + "enabled": "Enabled", + "disabled":"Disabled", + "info": "Description", + "selectNodes": "Click nodes to select" + }, + "menu": { + "label": { + "view": { + "view": "View", + "grid": "Grid", + "showGrid": "Show grid", + "snapGrid": "Snap to grid", + "gridSize": "Grid size", + "textDir": "Text Direction", + "defaultDir": "Default", + "ltr": "Left-to-right", + "rtl": "Right-to-left", + "auto": "Contextual", + "language": "Language", + "browserDefault": "Browser default" + }, + "sidebar": { + "show": "Show sidebar" + }, + "palette": { + "show": "Show palette" + }, + "settings": "Settings", + "userSettings": "User Settings", + "nodes": "Nodes", + "displayStatus": "Show node status", + "displayConfig": "Configuration nodes", + "import": "Import", + "export": "Export", + "search": "Search flows", + "searchInput": "search your flows", + "subflows": "Subflows", + "createSubflow": "Create Subflow", + "selectionToSubflow": "Selection to Subflow", + "flows": "Flows", + "add": "Add", + "rename": "Rename", + "delete": "Delete", + "keyboardShortcuts": "Keyboard shortcuts", + "login": "Login", + "logout": "Logout", + "editPalette":"Manage palette", + "other": "Other", + "showTips": "Show tips", + "help": "Node-RED website", + "projects": "Projects", + "projects-new": "New", + "projects-open": "Open", + "projects-settings": "Project Settings", + "showNodeLabelDefault": "Show label of newly added nodes" + } + }, + "actions": { + "toggle-navigator": "Toggle navigator", + "zoom-out": "Zoom out", + "zoom-reset": "Reset zoom", + "zoom-in": "Zoom in" + }, + "user": { + "loggedInAs": "Logged in as __name__", + "username": "Username", + "password": "Password", + "login": "Login", + "loginFailed": "Login failed", + "notAuthorized": "Not authorized", + "errors": { + "settings": "You must be logged in to access settings", + "deploy": "You must be logged in to deploy changes", + "notAuthorized": "You must be logged in to perform this action" + } + }, + "notification": { + "warning": "Warning: __message__", + "warnings": { + "undeployedChanges": "node has undeployed changes", + "nodeActionDisabled": "node actions disabled", + "nodeActionDisabledSubflow": "node actions disabled within subflow", + "missing-types": "

Flows stopped due to missing node types.

", + "safe-mode":"

Flows stopped in safe mode.

You can modify your flows and deploy the changes to restart.

", + "restartRequired": "Node-RED must be restarted to enable upgraded modules", + "credentials_load_failed": "

Flows stopped as the credentials could not be decrypted.

The flow credential file is encrypted, but the project's encryption key is missing or invalid.

", + "credentials_load_failed_reset":"

Credentials could not be decrypted

The flow credential file is encrypted, but the project's encryption key is missing or invalid.

The flow credential file will be reset on the next deployment. Any existing flow credentials will be cleared.

", + "missing_flow_file": "

Project flow file not found.

The project is not configured with a flow file.

", + "missing_package_file": "

Project package file not found.

The project is missing a package.json file.

", + "project_empty": "

The project is empty.

Do you want to create a default set of project files?
Otherwise, you will have to manually add files to the project outside of the editor.

", + "project_not_found": "

Project '__project__' not found.

", + "git_merge_conflict": "

Automatic merging of changes failed.

Fix the unmerged conflicts then commit the results.

" + }, + "error": "Error: __message__", + "errors": { + "lostConnection": "Lost connection to server, reconnecting...", + "lostConnectionReconnect": "Lost connection to server, reconnecting in __time__s.", + "lostConnectionTry": "Try now", + "cannotAddSubflowToItself": "Cannot add subflow to itself", + "cannotAddCircularReference": "Cannot add subflow - circular reference detected", + "unsupportedVersion": "

Using an unsupported version of Node.js

You should upgrade to the latest Node.js LTS release

", + "failedToAppendNode": "

Failed to load '__module__'

__error__

" + }, + "project": { + "change-branch": "Change to local branch '__project__'", + "merge-abort": "Git merge aborted", + "loaded": "Project '__project__' loaded", + "updated": "Project '__project__' updated", + "pull": "Project '__project__' reloaded", + "revert": "Project '__project__' reverted", + "merge-complete": "Git merge completed", + "setupCredentials": "Setup credentials", + "setupProjectFiles": "Setup project files", + "no": "No thanks", + "createDefault": "Create default project files", + "mergeConflict": "Show merge conflicts" + }, + "label": { + "manage-project-dep": "Manage project dependencies", + "setup-cred": "Setup credentials", + "setup-project": "Setup project files", + "create-default-package": "Create default package file", + "no-thanks": "No thanks", + "create-default-project": "Create default project files", + "show-merge-conflicts": "Show merge conflicts" + } + }, + "clipboard": { + "clipboard": "Clipboard", + "nodes": "Nodes", + "node": "__count__ node", + "node_plural": "__count__ nodes", + "configNode": "__count__ configuration node", + "configNode_plural": "__count__ configuration nodes", + "flow": "__count__ flow", + "flow_plural": "__count__ flows", + "subflow": "__count__ subflow", + "subflow_plural": "__count__ subflows", + "pasteNodes": "Paste flow json or", + "selectFile": "select a file to import", + "importNodes": "Import nodes", + "exportNodes": "Export nodes", + "download": "Download", + "importUnrecognised": "Imported unrecognised type:", + "importUnrecognised_plural": "Imported unrecognised types:", + "nodesExported": "Nodes exported to clipboard", + "nodesImported": "Imported:", + "nodeCopied": "__count__ node copied", + "nodeCopied_plural": "__count__ nodes copied", + "invalidFlow": "Invalid flow: __message__", + "export": { + "selected":"selected nodes", + "current":"current flow", + "all":"all flows", + "compact":"compact", + "formatted":"formatted", + "copy": "Copy to clipboard", + "export": "Export to library", + "exportAs": "Export as", + "overwrite": "Replace", + "exists": "

\"__file__\" already exists.

Do you want to replace it?

" + }, + "import": { + "import": "Import to", + "newFlow": "new flow", + "errors": { + "notArray": "Input not a JSON Array", + "itemNotObject": "Input not a valid flow - item __index__ not a node object", + "missingId": "Input not a valid flow - item __index__ missing 'id' property", + "missingType": "Input not a valid flow - item __index__ missing 'type' property" + } + }, + "copyMessagePath": "Path copied", + "copyMessageValue": "Value copied", + "copyMessageValue_truncated": "Truncated value copied" + }, + "deploy": { + "deploy": "Deploy", + "full": "Full", + "fullDesc": "Deploys everything in the workspace", + "modifiedFlows": "Modified Flows", + "modifiedFlowsDesc": "Only deploys flows that contain changed nodes", + "modifiedNodes": "Modified Nodes", + "modifiedNodesDesc": "Only deploys nodes that have changed", + "restartFlows": "Restart Flows", + "restartFlowsDesc": "Restarts the current deployed flows", + "successfulDeploy": "Successfully deployed", + "successfulRestart": "Successfully restarted flows", + "deployFailed": "Deploy failed: __message__", + "unusedConfigNodes":"You have some unused configuration nodes.", + "unusedConfigNodesLink":"Click here to see them", + "errors": { + "noResponse": "no response from server" + }, + "confirm": { + "button": { + "ignore": "Ignore", + "confirm": "Confirm deploy", + "review": "Review changes", + "cancel": "Cancel", + "merge": "Merge", + "overwrite": "Ignore & deploy" + }, + "undeployedChanges": "You have undeployed changes.\n\nLeaving this page will lose these changes.", + "improperlyConfigured": "The workspace contains some nodes that are not properly configured:", + "unknown": "The workspace contains some unknown node types:", + "confirm": "Are you sure you want to deploy?", + "doNotWarn": "do not warn about this again", + "conflict": "The server is running a more recent set of flows.", + "backgroundUpdate": "The flows on the server have been updated.", + "conflictChecking": "Checking to see if the changes can be merged automatically", + "conflictAutoMerge": "The changes include no conflicts and can be merged automatically.", + "conflictManualMerge": "The changes include conflicts that must be resolved before they can be deployed.", + "plusNMore": "+ __count__ more" + } + }, + "eventLog": { + "title": "Event log", + "view": "View log" + }, + "diff": { + "unresolvedCount": "__count__ unresolved conflict", + "unresolvedCount_plural": "__count__ unresolved conflicts", + "globalNodes": "Global nodes", + "flowProperties": "Flow Properties", + "type": { + "added": "added", + "changed": "changed", + "unchanged": "unchanged", + "deleted": "deleted", + "flowDeleted": "flow deleted", + "flowAdded": "flow added", + "movedTo": "moved to __id__", + "movedFrom": "moved from __id__" + }, + "nodeCount": "__count__ node", + "nodeCount_plural": "__count__ nodes", + "local":"Local changes", + "remote":"Remote changes", + "reviewChanges": "Review Changes", + "noBinaryFileShowed": "Cannot show binary file contents", + "viewCommitDiff": "View Commit Changes", + "compareChanges": "Compare Changes", + "saveConflict": "Save conflict resolution", + "conflictHeader": "__resolved__ of __unresolved__ conflicts resolved", + "commonVersionError": "Common Version doesn't contain valid JSON:", + "oldVersionError": "Old Version doesn't contain valid JSON:", + "newVersionError": "New Version doesn't contain valid JSON:" + }, + "subflow": { + "editSubflowInstance": "Edit subflow instance: __name__", + "editSubflow": "Edit subflow template: __name__", + "edit": "Edit subflow template", + "subflowInstances": "There is __count__ instance of this subflow template", + "subflowInstances_plural": "There are __count__ instances of this subflow template", + "editSubflowProperties": "edit properties", + "input": "inputs:", + "output": "outputs:", + "status": "status node", + "deleteSubflow": "delete subflow", + "info": "Description", + "category": "Category", + "env": { + "restore": "Restore to subflow default", + "remove": "Remove environment variable" + }, + "errors": { + "noNodesSelected": "Cannot create subflow: no nodes selected", + "multipleInputsToSelection": "Cannot create subflow: multiple inputs to selection" + } + }, + "editor": { + "configEdit": "Edit", + "configAdd": "Add", + "configUpdate": "Update", + "configDelete": "Delete", + "nodesUse": "__count__ node uses this config", + "nodesUse_plural": "__count__ nodes use this config", + "addNewConfig": "Add new __type__ config node", + "editNode": "Edit __type__ node", + "editConfig": "Edit __type__ config node", + "addNewType": "Add new __type__...", + "nodeProperties": "node properties", + "label": "Label", + "color": "Color", + "portLabels": "Port labels", + "labelInputs": "Inputs", + "labelOutputs": "Outputs", + "settingIcon": "Icon", + "default": "default", + "noDefaultLabel": "none", + "defaultLabel": "use default label", + "searchIcons": "Search icons", + "useDefault": "use default", + "description": "Description", + "show": "Show", + "hide": "Hide", + "locale": "Select UI Language", + "icon": "Icon", + "inputType": "Input type", + "inputs" : { + "input": "input", + "select": "select", + "checkbox": "checkbox", + "spinner": "spinner", + "none": "none", + "hidden": "hide property" + }, + "types": { + "str": "string", + "num": "number", + "bool": "bool", + "json": "JSON", + "bin": "buffer", + "env": "env variable" + }, + "menu": { + "input": "input", + "select": "select", + "checkbox": "checkbox", + "spinner": "spinner", + "hidden": "label only" + }, + "select": { + "label": "Label", + "value": "Value" + }, + "spinner": { + "min": "Minimum", + "max": "Maximum" + }, + "errors": { + "scopeChange": "Changing the scope will make it unavailable to nodes in other flows that use it", + "invalidProperties": "Invalid properties:" + } + }, + "keyboard": { + "title": "Keyboard Shortcuts", + "keyboard": "Keyboard", + "filterActions": "filter actions", + "shortcut": "shortcut", + "scope": "scope", + "unassigned": "Unassigned", + "global": "global", + "workspace": "workspace", + "selectAll": "Select all nodes", + "selectAllConnected": "Select all connected nodes", + "addRemoveNode": "Add/remove node from selection", + "editSelected": "Edit selected node", + "deleteSelected": "Delete selected nodes or link", + "importNode": "Import nodes", + "exportNode": "Export nodes", + "nudgeNode": "Move selected nodes (1px)", + "moveNode": "Move selected nodes (20px)", + "toggleSidebar": "Toggle sidebar", + "togglePalette": "Toggle palette", + "copyNode": "Copy selected nodes", + "cutNode": "Cut selected nodes", + "pasteNode": "Paste nodes", + "undoChange": "Undo the last change performed", + "searchBox": "Open search box", + "managePalette": "Manage palette", + "actionList":"Action list" + }, + "library": { + "library": "Library", + "openLibrary": "Open Library...", + "saveToLibrary": "Save to Library...", + "typeLibrary": "__type__ library", + "unnamedType": "Unnamed __type__", + "exportedToLibrary": "Nodes exported to library", + "dialogSaveOverwrite": "A __libraryType__ called __libraryName__ already exists. Overwrite?", + "invalidFilename": "Invalid filename", + "savedNodes": "Saved nodes", + "savedType": "Saved __type__", + "saveFailed": "Save failed: __message__", + "newFolder": "New folder", + "types": { + "local": "Local", + "examples": "Examples" + } + }, + "palette": { + "noInfo": "no information available", + "filter": "filter nodes", + "search": "search modules", + "addCategory": "Add new...", + "label": { + "subflows": "subflows", + "network": "network", + "common": "common", + "input": "input", + "output": "output", + "function": "function", + "sequence": "sequence", + "parser": "parser", + "social": "social", + "storage": "storage", + "analysis": "analysis", + "advanced": "advanced" + }, + "actions": { + "collapse-all": "Collapse all categories", + "expand-all": "Expand all categories" + }, + "event": { + "nodeAdded": "Node added to palette:", + "nodeAdded_plural": "Nodes added to palette:", + "nodeRemoved": "Node removed from palette:", + "nodeRemoved_plural": "Nodes removed from palette:", + "nodeEnabled": "Node enabled:", + "nodeEnabled_plural": "Nodes enabled:", + "nodeDisabled": "Node disabled:", + "nodeDisabled_plural": "Nodes disabled:", + "nodeUpgraded": "Node module __module__ upgraded to version __version__" + }, + "editor": { + "title": "Manage palette", + "palette": "Palette", + "times": { + "seconds": "seconds ago", + "minutes": "minutes ago", + "minutesV": "__count__ minutes ago", + "hoursV": "__count__ hour ago", + "hoursV_plural": "__count__ hours ago", + "daysV": "__count__ day ago", + "daysV_plural": "__count__ days ago", + "weeksV": "__count__ week ago", + "weeksV_plural": "__count__ weeks ago", + "monthsV": "__count__ month ago", + "monthsV_plural": "__count__ months ago", + "yearsV": "__count__ year ago", + "yearsV_plural": "__count__ years ago", + "yearMonthsV": "__y__ year, __count__ month ago", + "yearMonthsV_plural": "__y__ year, __count__ months ago", + "yearsMonthsV": "__y__ years, __count__ month ago", + "yearsMonthsV_plural": "__y__ years, __count__ months ago" + }, + "nodeCount": "__label__ node", + "nodeCount_plural": "__label__ nodes", + "moduleCount": "__count__ module available", + "moduleCount_plural": "__count__ modules available", + "inuse": "in use", + "enableall": "enable all", + "disableall": "disable all", + "enable": "enable", + "disable": "disable", + "remove": "remove", + "update": "update to __version__", + "updated": "updated", + "install": "install", + "installed": "installed", + "conflict": "conflict", + "conflictTip": "

This module cannot be installed as it includes a
node type that has already been installed

Conflicts with __module__

", + "loading": "Loading catalogues...", + "tab-nodes": "Nodes", + "tab-install": "Install", + "sort": "sort:", + "sortAZ": "a-z", + "sortRecent": "recent", + "more": "+ __count__ more", + "errors": { + "catalogLoadFailed": "

Failed to load node catalogue.

Check the browser console for more information

", + "installFailed": "

Failed to install: __module__

__message__

Check the log for more information

", + "removeFailed": "

Failed to remove: __module__

__message__

Check the log for more information

", + "updateFailed": "

Failed to update: __module__

__message__

Check the log for more information

", + "enableFailed": "

Failed to enable: __module__

__message__

Check the log for more information

", + "disableFailed": "

Failed to disable: __module__

__message__

Check the log for more information

" + }, + "confirm": { + "install": { + "body":"

Installing '__module__'

Before installing, please read the node's documentation. Some nodes have dependencies that cannot be automatically resolved and can require a restart of Node-RED.

", + "title": "Install nodes" + }, + "remove": { + "body":"

Removing '__module__'

Removing the node will uninstall it from Node-RED. The node may continue to use resources until Node-RED is restarted.

", + "title": "Remove nodes" + }, + "update": { + "body":"

Updating '__module__'

Updating the node will require a restart of Node-RED to complete the update. This must be done manually.

", + "title": "Update nodes" + }, + "cannotUpdate": { + "body":"An update for this node is available, but it is not installed in a location that the palette manager can update.

Please refer to the documentation for how to update this node." + }, + "button": { + "review": "Open node information", + "install": "Install", + "remove": "Remove", + "update": "Update" + } + } + } + }, + "sidebar": { + "info": { + "name": "Node information", + "tabName": "Name", + "label": "info", + "node": "Node", + "type": "Type", + "module": "Module", + "id": "ID", + "status": "Status", + "enabled": "Enabled", + "disabled": "Disabled", + "subflow": "Subflow", + "instances": "Instances", + "properties": "Properties", + "info": "Information", + "desc": "Description", + "blank": "blank", + "null": "null", + "showMore": "show more", + "showLess": "show less", + "flow": "Flow", + "selection":"Selection", + "nodes":"__count__ nodes", + "flowDesc": "Flow Description", + "subflowDesc": "Subflow Description", + "nodeHelp": "Node Help", + "none":"None", + "arrayItems": "__count__ items", + "showTips":"You can open the tips from the settings panel" + }, + "config": { + "name": "Configuration nodes", + "label": "config", + "global": "On all flows", + "none": "none", + "subflows": "subflows", + "flows": "flows", + "filterAll": "all", + "showAllConfigNodes": "Show all config nodes", + "filterUnused": "unused", + "showAllUnusedConfigNodes": "Show all unused config nodes", + "filtered": "__count__ hidden" + }, + "context": { + "name":"Context Data", + "label":"context", + "none": "none selected", + "refresh": "refresh to load", + "empty": "empty", + "node": "Node", + "flow": "Flow", + "global": "Global", + "deleteConfirm": "Are you sure you want to delete this item?", + "autoRefresh": "Refresh on selection change", + "refrsh": "Refresh", + "delete": "Delete" + }, + "palette": { + "name": "Palette management", + "label": "palette" + }, + "project": { + "label": "project", + "name": "Project", + "description": "Description", + "dependencies": "Dependencies", + "settings": "Settings", + "noSummaryAvailable": "No summary available", + "editDescription": "Edit project description", + "editDependencies": "Edit project dependencies", + "noDescriptionAvailable": "No description available", + "editReadme": "Edit README.md", + "showProjectSettings": "Show project settings", + "projectSettings": { + "title": "Project Settings", + "edit": "edit", + "none": "None", + "install": "install", + "removeFromProject": "remove from project", + "addToProject": "add to project", + "files": "Files", + "package": "Package", + "flow": "Flow", + "credentials": "Credentials", + "package":"Package", + "packageCreate":"File will be created when changes are saved", + "fileNotExist":"File does not exist", + "selectFile": "Select File", + "invalidEncryptionKey": "Invalid encryption key", + "encryptionEnabled": "Encryption enabled", + "encryptionDisabled": "Encryption disabled", + "setTheEncryptionKey": "Set the encryption key", + "resetTheEncryptionKey": "Reset the encryption key", + "changeTheEncryptionKey": "Change the encryption key", + "currentKey": "Current key", + "newKey": "New key", + "credentialsAlert": "This will delete all existing credentials", + "versionControl": "Version Control", + "branches": "Branches", + "noBranches": "No branches", + "deleteConfirm": "Are you sure you want to delete the local branch '__name__'? This cannot be undone.", + "unmergedConfirm": "The local branch '__name__' has unmerged changes that will be lost. Are you sure you want to delete it?", + "deleteUnmergedBranch": "Delete unmerged branch", + "gitRemotes": "Git remotes", + "addRemote": "add remote", + "addRemote2": "Add remote", + "remoteName": "Remote name", + "nameRule": "Must contain only A-Z 0-9 _ -", + "url": "URL", + "urlRule": "https://, ssh:// or file://", + "urlRule2": "Do not include the username/password in the URL", + "noRemotes": "No remotes", + "deleteRemoteConfrim": "Are you sure you want to delete the remote '__name__'?", + "deleteRemote": "Delete remote" + }, + "userSettings": { + "committerDetail": "Committer Details", + "committerTip": "Leave blank to use system default", + "userName": "Username", + "email": "Email", + "sshKeys": "SSH Keys", + "sshKeysTip": "Allows you to create secure connections to remote git repositories.", + "add": "add key", + "addSshKey": "Add SSH Key", + "addSshKeyTip": "Generate a new public/private key pair", + "name": "Name", + "nameRule": "Must contain only A-Z 0-9 _ -", + "passphrase": "Passphrase", + "passphraseShort": "Passphrase too short", + "optional": "Optional", + "cancel": "Cancel", + "generate": "Generate key", + "noSshKeys": "No SSH keys", + "copyPublicKey": "Copy public key to clipboard", + "delete": "Delete key", + "gitConfig": "Git config", + "deleteConfirm": "Are you sure you want to delete the SSH key __name__? This cannot be undone." + }, + "versionControl": { + "unstagedChanges": "Unstaged changes", + "stagedChanges": "Staged changes", + "unstageChange": "Unstage change", + "stageChange": "Stage change", + "unstageAllChange": "Unstage all changes", + "stageAllChange": "Stage all changes", + "commitChanges": "Commit changes", + "resolveConflicts": "Resolve conflicts", + "head": "HEAD", + "staged": "Staged", + "unstaged": "Unstaged", + "local": "Local", + "remote": "Remote", + "revert": "Are you sure you want to revert the changes to '__file__'? This cannot be undone.", + "revertChanges": "Revert changes", + "localChanges": "Local Changes", + "none": "None", + "conflictResolve": "All conflicts resolved. Commit the changes to complete the merge.", + "localFiles": "Local files", + "all": "all", + "unmergedChanges": "Unmerged changes", + "abortMerge": "abort merge", + "commit": "commit", + "changeToCommit": "Changes to commit", + "commitPlaceholder": "Enter your commit message", + "cancelCapital": "Cancel", + "commitCapital": "Commit", + "commitHistory": "Commit History", + "branch": "Branch:", + "moreCommits": " more commit(s)", + "changeLocalBranch": "Change local branch", + "createBranchPlaceholder": "Find or create a branch", + "upstream": "upstream", + "localOverwrite": "You have local changes that would be overwritten by changing the branch. You must either commit or undo those changes first.", + "manageRemoteBranch": "Manage remote branch", + "unableToAccess": "Unable to access remote repository", + "retry": "Retry", + "setUpstreamBranch": "Set as upstream branch", + "createRemoteBranchPlaceholder": "Find or create a remote branch", + "trackedUpstreamBranch": "The created branch will be set as the tracked upstream branch.", + "selectUpstreamBranch": "The branch will be created. Select below to set it as the tracked upstream branch.", + "pushFailed": "Push failed as the remote has more recent commits. Pull and merge first, then push again.", + "push": "push", + "pull": "pull", + "unablePull": "

Unable to pull remote changes; your unstaged local changes would be overwritten.

Commit your changes and try again.

", + "showUnstagedChanges": "Show unstaged changes", + "connectionFailed": "Could not connect to remote repository: ", + "pullUnrelatedHistory": "

The remote has an unrelated history of commits.

Are you sure you want to pull the changes into your local repository?

", + "pullChanges": "Pull changes", + "history": "history", + "projectHistory": "Project History", + "daysAgo": "__count__ day ago", + "daysAgo_plural": "__count__ days ago", + "hoursAgo": "__count__ hour ago", + "hoursAgo_plural": "__count__ hours ago", + "minsAgo": "__count__ min ago", + "minsAgo_plural": "__count__ mins ago", + "secondsAgo": "Seconds ago", + "notTracking": "Your local branch is not currently tracking a remote branch.", + "statusUnmergedChanged": "Your repository has unmerged changes. You need to fix the conflicts and commit the result.", + "repositoryUpToDate": "Your repository is up to date.", + "commitsAhead": "Your repository is __count__ commit ahead of the remote. You can push this commit now.", + "commitsAhead_plural": "Your repository is __count__ commits ahead of the remote. You can push these commits now.", + "commitsBehind": "Your repository is __count__ commit behind of the remote. You can pull this commit now.", + "commitsBehind_plural": "Your repository is __count__ commits behind of the remote. You can pull these commits now.", + "commitsAheadAndBehind1": "Your repository is __count__ commit behind and ", + "commitsAheadAndBehind1_plural": "Your repository is __count__ commits behind and ", + "commitsAheadAndBehind2": "__count__ commit ahead of the remote. ", + "commitsAheadAndBehind2_plural": "__count__ commits ahead of the remote. ", + "commitsAheadAndBehind3": "You must pull the remote commit down before pushing.", + "commitsAheadAndBehind3_plural": "You must pull the remote commits down before pushing.", + "refreshCommitHistory": "Refresh commit history", + "refreshChanges": "Refresh changes" + } + } + }, + "typedInput": { + "type": { + "str": "string", + "num": "number", + "re": "regular expression", + "bool": "boolean", + "json": "JSON", + "bin": "buffer", + "date": "timestamp", + "jsonata": "expression", + "env": "env variable" + } + }, + "editableList": { + "add": "add" + }, + "search": { + "empty": "No matches found", + "addNode": "add a node..." + }, + "expressionEditor": { + "functions": "Functions", + "functionReference": "Function reference", + "insert": "Insert", + "title": "JSONata Expression editor", + "test": "Test", + "data": "Example message", + "result": "Result", + "format": "format expression", + "compatMode": "Compatibility mode enabled", + "compatModeDesc": "

JSONata compatibility mode

The current expression appears to still reference msg so will be evaluated in compatibility mode. Please update the expression to not use msg as this mode will be removed in the future.

When JSONata support was first added to Node-RED, it required the expression to reference the msg object. For example msg.payload would be used to access the payload.

That is no longer necessary as the expression will be evaluated against the message directly. To access the payload, the expression should be just payload.

", + "noMatch": "No matching result", + "errors": { + "invalid-expr": "Invalid JSONata expression:\n __message__", + "invalid-msg": "Invalid example JSON message:\n __message__", + "context-unsupported": "Cannot test context functions\n $flowContext or $globalContext", + "eval": "Error evaluating expression:\n __message__" + } + }, + "jsEditor": { + "title": "JavaScript editor" + }, + "textEditor": { + "title": "Text editor" + }, + "jsonEditor": { + "title": "JSON editor", + "format": "format JSON", + "rawMode": "Edit JSON", + "uiMode": "Visual editor", + "insertAbove": "Insert above", + "insertBelow": "Insert below", + "addItem": "Add item", + "copyPath": "Copy path to item", + "expandItems": "Expand items", + "collapseItems": "Collapse items", + "duplicate": "Duplicate", + "error": { + "invalidJSON": "Invalid JSON: " + } + }, + "markdownEditor": { + "title": "Markdown editor", + "expand": "Expand", + "format": "Formatted with markdown", + "heading1": "Heading 1", + "heading2": "Heading 2", + "heading3": "Heading 3", + "bold": "Bold", + "italic": "Italic", + "code": "Code", + "ordered-list": "Ordered list", + "unordered-list": "Unordered list", + "quote": "Quote", + "link": "Link", + "horizontal-rule": "Horizontal rule", + "toggle-preview": "Toggle preview" + }, + "bufferEditor": { + "title": "Buffer editor", + "modeString": "Handle as UTF-8 String", + "modeArray": "Handle as JSON array", + "modeDesc":"

Buffer editor

The Buffer type is stored as a JSON array of byte values. The editor will attempt to parse the entered value as a JSON array. If it is not valid JSON, it will be treated as a UTF-8 String and converted to an array of the individual character code points.

For example, a value of Hello World will be converted to the JSON array:

[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

" + }, + "projects": { + "config-git": "Configure Git client", + "welcome": { + "hello": "Hello! We have introduced 'projects' to Node-RED.", + "desc0": "This is a new way for you to manage your flow files and includes version control of your flows.", + "desc1": "To get started you can create your first project or clone an existing project from a git repository.", + "desc2": "If you are not sure, you can skip this for now. You will still be able to create your first project from the 'Projects' menu at any time.", + "create": "Create Project", + "clone": "Clone Repository", + "openExistingProject": "Open existing project", + "not-right-now": "Not right now" + }, + "git-config": { + "setup": "Setup your version control client", + "desc0": "Node-RED uses the open source tool Git for version control. It tracks changes to your project files and lets you push them to remote repositories.", + "desc1": "When you commit a set of changes, Git records who made the changes with a username and email address. The Username can be anything you want - it does not need to be your real name.", + "desc2": "Your Git client is already configured with the details below.", + "desc3": "You can change these settings later under the 'Git config' tab of the settings dialog.", + "username": "Username", + "email": "Email" + }, + "project-details": { + "create": "Create your project", + "desc0": "A project is maintained as a Git repository. It makes it much easier to share your flows with others and to collaborate on them.", + "desc1": "You can create multiple projects and quickly switch between them from the editor.", + "desc2": "To begin, your project needs a name and an optional description.", + "already-exists": "Project already exists", + "must-contain": "Must contain only A-Z 0-9 _ -", + "project-name": "Project name", + "desc": "Description", + "opt": "Optional" + }, + "clone-project": { + "clone": "Clone a project", + "desc0": "If you already have a git repository containing a project, you can clone it to get started.", + "already-exists": "Project already exists", + "must-contain": "Must contain only A-Z 0-9 _ -", + "project-name": "Project name", + "no-info-in-url": "Do not include the username/password in the url", + "git-url": "Git repository URL", + "protocols": "https://, ssh:// or file://", + "auth-failed": "Authentication failed", + "username": "Username", + "passwd": "Password", + "ssh-key": "SSH Key", + "passphrase": "Passphrase", + "ssh-key-desc": "Before you can clone a repository over ssh you must add an SSH key to access it.", + "ssh-key-add": "Add an ssh key", + "credential-key": "Credentials encryption key", + "cant-get-ssh-key": "Error! Can't get selected SSH key path.", + "already-exists2": "already exists", + "git-error": "git error", + "connection-failed": "Connection failed", + "not-git-repo": "Not a git repository", + "repo-not-found": "Repository not found" + }, + "default-files": { + "create": "Create your project files", + "desc0": "A project contains your flow files, a README file and a package.json file.", + "desc1": "It can contain any other files you want to maintain in the Git repository.", + "desc2": "Your existing flow and credential files will be copied into the project.", + "flow-file": "Flow file", + "credentials-file": "Credentials file" + }, + "encryption-config": { + "setup": "Setup encryption of your credentials file", + "desc0": "Your flow credentials file can be encrypted to keep its contents secure.", + "desc1": "If you want to store these credentials in a public Git repository, you must encrypt them by providing a secret key phrase.", + "desc2": "Your flow credentials file is not currently encrypted.", + "desc3": "That means its contents, such as passwords and access tokens, can be read by anyone with access to the file.", + "desc4": "If you want to store these credentials in a public Git repository, you must encrypt them by providing a secret key phrase.", + "desc5": "Your flow credentials file is currently encrypted using the credentialSecret property from your settings file as the key.", + "desc6": "Your flow credentials file is currently encrypted using a system-generated key. You should provide a new secret key for this project.", + "desc7": "The key will be stored separately from your project files. You will need to provide the key to use this project in another instance of Node-RED.", + "credentials": "Credentials", + "enable": "Enable encryption", + "disable": "Disable encryption", + "disabled": "disabled", + "copy": "Copy over existing key", + "use-custom": "Use custom key", + "desc8": "The credentials file will not be encrypted and its contents easily read", + "create-project-files": "Create project files", + "create-project": "Create project", + "already-exists": "already exists", + "git-error": "git error", + "git-auth-error": "git auth error" + }, + "create-success": { + "success": "You have successfully created your first project!", + "desc0": "You can now continue to use Node-RED just as you always have.", + "desc1": "The 'info' tab in the sidebar shows you what your current active project is. The button next to the name can be used to access the project settings view.", + "desc2": "The 'history' tab in the sidebar can be used to view files that have changed in your project and to commit them. It shows you a complete history of your commits and allows you to push your changes to a remote repository." + }, + "create": { + "projects": "Projects", + "already-exists": "Project already exists", + "must-contain": "Must contain only A-Z 0-9 _ -", + "no-info-in-url": "Do not include the username/password in the url", + "open": "Open Project", + "create": "Create Project", + "clone": "Clone Repository", + "project-name": "Project name", + "desc": "Description", + "opt": "Optional", + "flow-file": "Flow file", + "credentials": "Credentials", + "enable-encryption": "Enable encryption", + "disable-encryption": "Disable encryption", + "encryption-key": "Encryption key", + "desc0": "A phrase to secure your credentials with", + "desc1": "The credentials file will not be encrypted and its contents easily read", + "git-url": "Git repository URL", + "protocols": "https://, ssh:// or file://", + "auth-failed": "Authentication failed", + "username": "Username", + "password": "Password", + "ssh-key": "SSH Key", + "passphrase": "Passphrase", + "desc2": "Before you can clone a repository over ssh you must add an SSH key to access it.", + "add-ssh-key": "Add an ssh key", + "credentials-encryption-key": "Credentials encryption key", + "already-exists-2": "already exists", + "git-error": "git error", + "con-failed": "Connection failed", + "not-git": "Not a git repository", + "no-resource": "Repository not found", + "cant-get-ssh-key-path": "Error! Can't get selected SSH key path.", + "unexpected_error": "unexpected_error" + }, + "delete": { + "confirm": "Are you sure you want to delete this project?" + }, + "create-project-list": { + "search": "search your projects", + "current": "current" + }, + "require-clean": { + "confirm": "

You have undeployed changes that will be lost.

Do you want to continue?

" + }, + "send-req": { + "auth-req": "Authentication required for repository", + "username": "Username", + "password": "Password", + "passphrase": "Passphrase", + "retry": "Retry", + "update-failed": "Failed to update auth", + "unhandled": "Unhandled error response", + "host-key-verify-failed": "

Host key verification failed.

The repository host key could not be verified. Please update your known_hosts file and try again." + }, + "create-branch-list": { + "invalid": "Invalid branch", + "create": "Create branch", + "current": "current" + }, + "create-default-file-set": { + "no-active": "Cannot create default file set without an active project", + "no-empty": "Cannot create default file set on a non-empty project", + "git-error": "git error" + }, + "errors" : { + "no-username-email": "Your Git client is not configured with a username/email.", + "unexpected": "An unexpected error occurred", + "code": "code" + } + }, + "editor-tab": { + "properties": "Properties", + "envProperties": "Environment Variables", + "description": "Description", + "appearance": "Appearance", + "preview": "UI Preview", + "defaultValue": "Default value" + }, + "languages" : { + "de": "German", + "en-US": "English", + "ja": "Japanese", + "ko": "Korean", + "zh-CN": "Chinese(Simplified)", + "zh-TW": "Chinese(Traditional)" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/en-US/infotips.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/en-US/infotips.json new file mode 100644 index 0000000..21a7e73 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/en-US/infotips.json @@ -0,0 +1,23 @@ +{ + "info": { + "tip0" : "You can remove the selected nodes or links with {{core:delete-selection}}", + "tip1" : "Search for nodes using {{core:search}}", + "tip2" : "{{core:toggle-sidebar}} will toggle the view of this sidebar", + "tip3" : "You can manage your palette of nodes with {{core:manage-palette}}", + "tip4" : "Your flow configuration nodes are listed in the sidebar panel. It can be accessed from the menu or with {{core:show-config-tab}}", + "tip5" : "Enable or disable these tips from the option in the settings", + "tip6" : "Move the selected nodes using the [left] [up] [down] and [right] keys. Hold [shift] to nudge them further", + "tip7" : "Dragging a node onto a wire will splice it into the link", + "tip8" : "Export the selected nodes, or the current tab with {{core:show-export-dialog}}", + "tip9" : "Import a flow by dragging its JSON into the editor, or with {{core:show-import-dialog}}", + "tip10" : "[shift] [click] and drag on a node port to move all of the attached wires or just the selected one", + "tip11" : "Show the Info tab with {{core:show-info-tab}} or the Debug tab with {{core:show-debug-tab}}", + "tip12" : "[ctrl] [click] in the workspace to open the quick-add dialog", + "tip13" : "Hold down [ctrl] when you [click] on a node port to enable quick-wiring", + "tip14" : "Hold down [shift] when you [click] on a node to also select all of its connected nodes", + "tip15" : "Hold down [ctrl] when you [click] on a node to add or remove it from the current selection", + "tip16" : "Switch flow tabs with {{core:show-previous-tab}} and {{core:show-next-tab}}", + "tip17" : "You can confirm your changes in the node edit tray with {{core:confirm-edit-tray}} or cancel them with {{core:cancel-edit-tray}}", + "tip18" : "Pressing {{core:edit-selected-node}} will edit the first node in the current selection" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/en-US/jsonata.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/en-US/jsonata.json new file mode 100644 index 0000000..d777d19 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/en-US/jsonata.json @@ -0,0 +1,270 @@ +{ + "$string": { + "args": "arg[, prettify]", + "desc": "Casts the `arg` parameter to a string using the following casting rules:\n\n - Strings are unchanged\n - Functions are converted to an empty string\n - Numeric infinity and NaN throw an error because they cannot be represented as a JSON number\n - All other values are converted to a JSON string using the `JSON.stringify` function. If `prettify` is true, then \"prettified\" JSON is produced. i.e One line per field and lines will be indented based on the field depth." + }, + "$length": { + "args": "str", + "desc": "Returns the number of characters in the string `str`. An error is thrown if `str` is not a string." + }, + "$substring": { + "args": "str, start[, length]", + "desc": "Returns a string containing the characters in the first parameter `str` starting at position `start` (zero-offset). If `length` is specified, then the substring will contain maximum `length` characters. If `start` is negative then it indicates the number of characters from the end of `str`." + }, + "$substringBefore": { + "args": "str, chars", + "desc": "Returns the substring before the first occurrence of the character sequence `chars` in `str`. If `str` does not contain `chars`, then it returns `str`." + }, + "$substringAfter": { + "args": "str, chars", + "desc": "Returns the substring after the first occurrence of the character sequence `chars` in `str`. If `str` does not contain `chars`, then it returns `str`." + }, + "$uppercase": { + "args": "str", + "desc": "Returns a string with all the characters of `str` converted to uppercase." + }, + "$lowercase": { + "args": "str", + "desc": "Returns a string with all the characters of `str` converted to lowercase." + }, + "$trim": { + "args": "str", + "desc": "Normalizes and trims all whitespace characters in `str` by applying the following steps:\n\n - All tabs, carriage returns, and line feeds are replaced with spaces.\n- Contiguous sequences of spaces are reduced to a single space.\n- Trailing and leading spaces are removed.\n\n If `str` is not specified (i.e. this function is invoked with no arguments), then the context value is used as the value of `str`. An error is thrown if `str` is not a string." + }, + "$contains": { + "args": "str, pattern", + "desc": "Returns `true` if `str` is matched by `pattern`, otherwise it returns `false`. If `str` is not specified (i.e. this function is invoked with one argument), then the context value is used as the value of `str`. The `pattern` parameter can either be a string or a regular expression." + }, + "$split": { + "args": "str[, separator][, limit]", + "desc": "Splits the `str` parameter into an array of substrings. It is an error if `str` is not a string. The optional `separator` parameter specifies the characters within the `str` about which it should be split as either a string or regular expression. If `separator` is not specified, then the empty string is assumed, and `str` will be split into an array of single characters. It is an error if `separator` is not a string. The optional `limit` parameter is a number that specifies the maximum number of substrings to include in the resultant array. Any additional substrings are discarded. If `limit` is not specified, then `str` is fully split with no limit to the size of the resultant array. It is an error if `limit` is not a non-negative number." + }, + "$join": { + "args": "array[, separator]", + "desc": "Joins an array of component strings into a single concatenated string with each component string separated by the optional `separator` parameter. It is an error if the input `array` contains an item which isn't a string. If `separator` is not specified, then it is assumed to be the empty string, i.e. no `separator` between the component strings. It is an error if `separator` is not a string." + }, + "$match": { + "args": "str, pattern [, limit]", + "desc": "Applies the `str` string to the `pattern` regular expression and returns an array of objects, with each object containing information about each occurrence of a match within `str`." + }, + "$replace": { + "args": "str, pattern, replacement [, limit]", + "desc": "Finds occurrences of `pattern` within `str` and replaces them with `replacement`.\n\nThe optional `limit` parameter is the maximum number of replacements." + }, + "$now": { + "args":"", + "desc":"Generates a timestamp in ISO 8601 compatible format and returns it as a string." + }, + "$base64encode": { + "args":"string", + "desc":"Converts an ASCII string to a base 64 representation. Each character in the string is treated as a byte of binary data. This requires that all characters in the string are in the 0x00 to 0xFF range, which includes all characters in URI encoded strings. Unicode characters outside of that range are not supported." + }, + "$base64decode": { + "args":"string", + "desc":"Converts base 64 encoded bytes to a string, using a UTF-8 Unicode codepage." + }, + "$number": { + "args": "arg", + "desc": "Casts the `arg` parameter to a number using the following casting rules:\n\n - Numbers are unchanged\n - Strings that contain a sequence of characters that represent a legal JSON number are converted to that number\n - All other values cause an error to be thrown." + }, + "$abs": { + "args":"number", + "desc":"Returns the absolute value of the `number` parameter." + }, + "$floor": { + "args":"number", + "desc":"Returns the value of `number` rounded down to the nearest integer that is smaller or equal to `number`." + }, + "$ceil": { + "args":"number", + "desc":"Returns the value of `number` rounded up to the nearest integer that is greater than or equal to `number`." + }, + "$round": { + "args":"number [, precision]", + "desc":"Returns the value of the `number` parameter rounded to the number of decimal places specified by the optional `precision` parameter." + }, + "$power": { + "args":"base, exponent", + "desc":"Returns the value of `base` raised to the power of `exponent`." + }, + "$sqrt": { + "args":"number", + "desc":"Returns the square root of the value of the `number` parameter." + }, + "$random": { + "args":"", + "desc":"Returns a pseudo random number greater than or equal to zero and less than one." + }, + "$millis": { + "args":"", + "desc":"Returns the number of milliseconds since the Unix Epoch (1 January, 1970 UTC) as a number. All invocations of `$millis()` within an evaluation of an expression will all return the same value." + }, + "$sum": { + "args": "array", + "desc": "Returns the arithmetic sum of an `array` of numbers. It is an error if the input `array` contains an item which isn't a number." + }, + "$max": { + "args": "array", + "desc": "Returns the maximum number in an `array` of numbers. It is an error if the input `array` contains an item which isn't a number." + }, + "$min": { + "args": "array", + "desc": "Returns the minimum number in an `array` of numbers. It is an error if the input `array` contains an item which isn't a number." + }, + "$average": { + "args": "array", + "desc": "Returns the mean value of an `array` of numbers. It is an error if the input `array` contains an item which isn't a number." + }, + "$boolean": { + "args": "arg", + "desc": "Casts the argument to a Boolean using the following rules:\n\n - `Boolean` : unchanged\n - `string`: empty : `false`\n - `string`: non-empty : `true`\n - `number`: `0` : `false`\n - `number`: non-zero : `true`\n - `null` : `false`\n - `array`: empty : `false`\n - `array`: contains a member that casts to `true` : `true`\n - `array`: all members cast to `false` : `false`\n - `object`: empty : `false`\n - `object`: non-empty : `true`\n - `function` : `false`" + }, + "$not": { + "args": "arg", + "desc": "Returns Boolean NOT on the argument. `arg` is first cast to a boolean" + }, + "$exists": { + "args": "arg", + "desc": "Returns Boolean `true` if the `arg` expression evaluates to a value, or `false` if the expression does not match anything (e.g. a path to a non-existent field reference)." + }, + "$count": { + "args": "array", + "desc": "Returns the number of items in the array" + }, + "$append": { + "args": "array, array", + "desc": "Appends two arrays" + }, + "$sort": { + "args":"array [, function]", + "desc":"Returns an array containing all the values in the `array` parameter, but sorted into order.\n\nIf a comparator `function` is supplied, then it must be a function that takes two parameters:\n\n`function(left, right)`\n\nThis function gets invoked by the sorting algorithm to compare two values left and right. If the value of left should be placed after the value of right in the desired sort order, then the function must return Boolean `true` to indicate a swap. Otherwise it must return `false`." + }, + "$reverse": { + "args":"array", + "desc":"Returns an array containing all the values from the `array` parameter, but in reverse order." + }, + "$shuffle": { + "args":"array", + "desc":"Returns an array containing all the values from the `array` parameter, but shuffled into random order." + }, + "$zip": { + "args":"array, ...", + "desc":"Returns a convolved (zipped) array containing grouped arrays of values from the `array1` … `arrayN` arguments from index 0, 1, 2...." + }, + "$keys": { + "args": "object", + "desc": "Returns an array containing the keys in the object. If the argument is an array of objects, then the array returned contains a de-duplicated list of all the keys in all of the objects." + }, + "$lookup": { + "args": "object, key", + "desc": "Returns the value associated with key in object. If the first argument is an array of objects, then all of the objects in the array are searched, and the values associated with all occurrences of key are returned." + }, + "$spread": { + "args": "object", + "desc": "Splits an object containing key/value pairs into an array of objects, each of which has a single key/value pair from the input object. If the parameter is an array of objects, then the resultant array contains an object for every key/value pair in every object in the supplied array." + }, + "$merge": { + "args": "array<object>", + "desc": "Merges an array of `objects` into a single `object` containing all the key/value pairs from each of the objects in the input array. If any of the input objects contain the same key, then the returned `object` will contain the value of the last one in the array. It is an error if the input array contains an item that is not an object." + }, + "$sift": { + "args":"object, function", + "desc":"Returns an object that contains only the key/value pairs from the `object` parameter that satisfy the predicate `function` passed in as the second parameter.\n\nThe `function` that is supplied as the second parameter must have the following signature:\n\n`function(value [, key [, object]])`" + }, + "$each": { + "args":"object, function", + "desc":"Returns an array containing the values return by the `function` when applied to each key/value pair in the `object`." + }, + "$map": { + "args":"array, function", + "desc":"Returns an array containing the results of applying the `function` parameter to each value in the `array` parameter.\n\nThe `function` that is supplied as the second parameter must have the following signature:\n\n`function(value [, index [, array]])`" + }, + "$filter": { + "args":"array, function", + "desc":"Returns an array containing only the values in the `array` parameter that satisfy the `function` predicate.\n\nThe `function` that is supplied as the second parameter must have the following signature:\n\n`function(value [, index [, array]])`" + }, + "$reduce": { + "args":"array, function [, init]", + "desc":"Returns an aggregated value derived from applying the `function` parameter successively to each value in `array` in combination with the result of the previous application of the function.\n\nThe function must accept two arguments, and behaves like an infix operator between each value within the `array`. The signature of `function` must be of the form: `myfunc($accumulator, $value[, $index[, $array]])`\n\nThe optional `init` parameter is used as the initial value in the aggregation." + }, + "$flowContext": { + "args": "string[, string]", + "desc": "Retrieves a flow context property.\n\nThis is a Node-RED defined function." + }, + "$globalContext": { + "args": "string[, string]", + "desc": "Retrieves a global context property.\n\nThis is a Node-RED defined function." + }, + "$pad": { + "args": "string, width [, char]", + "desc": "Returns a copy of the `string` with extra padding, if necessary, so that its total number of characters is at least the absolute value of the `width` parameter.\n\nIf `width` is a positive number, then the string is padded to the right; if negative, it is padded to the left.\n\nThe optional `char` argument specifies the padding character(s) to use. If not specified, it defaults to the space character." + }, + "$fromMillis": { + "args": "number", + "desc": "Convert a number representing milliseconds since the Unix Epoch (1 January, 1970 UTC) to a timestamp string in the ISO 8601 format." + }, + "$formatNumber": { + "args": "number, picture [, options]", + "desc": "Casts the `number` to a string and formats it to a decimal representation as specified by the `picture` string.\n\n The behaviour of this function is consistent with the XPath/XQuery function fn:format-number as defined in the XPath F&O 3.1 specification. The picture string parameter defines how the number is formatted and has the same syntax as fn:format-number.\n\nThe optional third argument `options` is used to override the default locale specific formatting characters such as the decimal separator. If supplied, this argument must be an object containing name/value pairs specified in the decimal format section of the XPath F&O 3.1 specification." + }, + "$formatBase": { + "args": "number [, radix]", + "desc": "Casts the `number` to a string and formats it to an integer represented in the number base specified by the `radix` argument. If `radix` is not specified, then it defaults to base 10. `radix` can be between 2 and 36, otherwise an error is thrown." + }, + "$toMillis": { + "args": "timestamp", + "desc": "Convert a `timestamp` string in the ISO 8601 format to the number of milliseconds since the Unix Epoch (1 January, 1970 UTC) as a number. An error is thrown if the string is not in the correct format." + }, + "$env": { + "args": "arg", + "desc": "Returns the value of an environment variable.\n\nThis is a Node-RED defined function." + }, + "$eval": { + "args": "expr [, context]", + "desc": "Parses and evaluates the string `expr` which contains literal JSON or a JSONata expression using the current context as the context for evaluation." + }, + "$formatInteger": { + "args": "number, picture", + "desc": "Casts the `number` to a string and formats it to an integer representation as specified by the `picture` string. The picture string parameter defines how the number is formatted and has the same syntax as `fn:format-integer` from the XPath F&O 3.1 specification." + }, + "$parseInteger": { + "args": "string, picture", + "desc": "Parses the contents of the `string` parameter to an integer (as a JSON number) using the format specified by the `picture` string. The `picture` string parameter has the same format as `$formatInteger`." + }, + "$error": { + "args": "[str]", + "desc": "Throws an error with a message. The optional `str` will replace the default message of `$error() function evaluated`" + }, + "$assert": { + "args": "arg, str", + "desc": "If `arg` is true the function returns undefined. If `arg` is false an exception is thrown with `str` as the message of the exception." + }, + "$single": { + "args": "array, function", + "desc": "Returns the one and only value in the `array` parameter that satisfies the `function` predicate (i.e. the `function` returns Boolean `true` when passed the value). Throws an exception if the number of matching values is not exactly one.\n\nThe function should be supplied in the following signature: `function(value [, index [, array]])` where value is each input of the array, index is the position of that value and the whole array is passed as the third argument" + }, + "$encodeUrl": { + "args": "str", + "desc": "Encodes a Uniform Resource Locator (URL) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character.\n\nExample: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`" + }, + "$encodeUrlComponent": { + "args": "str", + "desc": "Encodes a Uniform Resource Locator (URL) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character. \n\nExample: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`" + }, + "$decodeUrl": { + "args": "str", + "desc": "Decodes a Uniform Resource Locator (URL) component previously created by encodeUrlComponent. \n\nExample: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`" + }, + "$decodeUrlComponent": { + "args": "str", + "desc": "Decodes a Uniform Resource Locator (URL) previously created by encodeUrl. \n\nExample: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`" + }, + "$distinct": { + "args": "array", + "desc": "Returns an array with duplicate values removed from `array`" + }, + "$type": { + "args": "value", + "desc": "Returns the type of `value` as a string. If `value` is undefined, this will return `undefined`" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/ja/editor.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/ja/editor.json new file mode 100644 index 0000000..cf04ced --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/ja/editor.json @@ -0,0 +1,1013 @@ +{ + "common": { + "label": { + "name": "名前", + "ok": "OK", + "done": "完了", + "cancel": "中止", + "delete": "削除", + "close": "閉じる", + "load": "読み込み", + "save": "保存", + "import": "読み込み", + "export": "書き出し", + "back": "戻る", + "next": "進む", + "clone": "プロジェクトをクローン", + "cont": "続ける" + }, + "type": { + "string": "文字列", + "number": "数値", + "boolean": "真偽値", + "array": "配列", + "buffer": "バッファ", + "object": "オブジェクト", + "jsonString": "JSON文字列", + "undefined": "undefined", + "null": "null" + } + }, + "workspace": { + "defaultName": "フロー __number__", + "editFlow": "フローを編集: __name__", + "confirmDelete": "削除の確認", + "delete": "本当に '__label__' を削除しますか?", + "dropFlowHere": "ここにフローをドロップしてください", + "addFlow": "フローの追加", + "listFlows": "フロー一覧", + "status": "状態", + "enabled": "有効", + "disabled": "無効", + "info": "詳細", + "selectNodes": "ノードをクリックして選択" + }, + "menu": { + "label": { + "view": { + "view": "表示", + "grid": "グリッド", + "showGrid": "グリッドを表示", + "snapGrid": "ノードの配置を補助", + "gridSize": "グリッドの大きさ", + "textDir": "テキストの方向", + "defaultDir": "標準", + "ltr": "左から右", + "rtl": "右から左", + "auto": "文脈", + "language": "表示言語", + "browserDefault": "ブラウザのデフォルト" + }, + "sidebar": { + "show": "サイドバーを表示" + }, + "palette": { + "show": "パレットを表示" + }, + "settings": "設定", + "userSettings": "ユーザ設定", + "nodes": "ノード", + "displayStatus": "ノードの状態を表示", + "displayConfig": "ノードの設定", + "import": "読み込み", + "export": "書き出し", + "search": "ノードを検索", + "searchInput": "ノードを検索", + "subflows": "サブフロー", + "createSubflow": "サブフローを作成", + "selectionToSubflow": "選択部分をサブフロー化", + "flows": "フロー", + "add": "フローを新規追加", + "rename": "フロー名を変更", + "delete": "フローを削除", + "keyboardShortcuts": "ショートカットキーの説明", + "login": "ログイン", + "logout": "ログアウト", + "editPalette": "パレットの管理", + "other": "その他", + "showTips": "ヒントを表示", + "help": "Node-REDウェブサイト", + "projects": "プロジェクト", + "projects-new": "新規", + "projects-open": "開く", + "projects-settings": "設定", + "showNodeLabelDefault": "追加したノードのラベルを表示" + } + }, + "actions": { + "toggle-navigator": "ナビゲータの表示/非表示を切替", + "zoom-out": "縮小", + "zoom-reset": "拡大/縮小を初期化", + "zoom-in": "拡大" + }, + "user": { + "loggedInAs": "__name__ としてログインしました", + "username": "ユーザ名", + "password": "パスワード", + "login": "ログイン", + "loginFailed": "ログインに失敗しました", + "notAuthorized": "権限がありません", + "errors": { + "settings": "設定を参照するには、ログインする必要があります", + "deploy": "変更をデプロイするには、ログインする必要があります", + "notAuthorized": "本アクションを行うには、ログインする必要があります" + } + }, + "notification": { + "warning": "警告: __message__", + "warnings": { + "undeployedChanges": "ノードの変更をデプロイしていません", + "nodeActionDisabled": "ノードのアクションは無効になっています", + "nodeActionDisabledSubflow": "ノードのアクションは、サブフロー内で無効になっています", + "missing-types": "

不明なノードが存在するため、フローを停止しました。

", + "safe-mode": "

セーフモードでフローを停止しました

フローを変更し、再起動するために変更をデプロイできます

", + "restartRequired": "更新されたモジュールを有効化するため、Node-REDを再起動する必要があります", + "credentials_load_failed": "

認証情報を復号できないため、フローを停止しました

フローの認証情報ファイルは暗号化されています。しかし、プロジェクトの暗号鍵が存在しない、または不正です

", + "credentials_load_failed_reset": "

認証情報を復号できません

フローの認証情報ファイルは暗号化されています。しかし、プロジェクトの暗号鍵が存在しない、または不正です。

次回のデプロイでフローの認証情報ファイルがリセットされます。既存フローの認証情報は削除されます。

", + "missing_flow_file": "

プロジェクトのフローファイルが存在しません

本プロジェクトにフローファイルが登録されていません

", + "missing_package_file": "

プロジェクトのパッケージファイルが存在しません

本プロジェクトにはpackage.jsonファイルがありません

", + "project_empty": "

空のプロジェクトです

デフォルトのプロジェクトファイルを作成しますか?
作成しない場合、エディタの外でファイルをプロジェクトへ手動で追加する必要があります

", + "project_not_found": "

プロジェクト '__project__' が存在しません

", + "git_merge_conflict": "

変更の自動マージが失敗しました

マージされていない競合を解決し、コミットしてください

" + }, + "error": "エラー: __message__", + "errors": { + "lostConnection": "サーバとの接続が切断されました: 再接続しています", + "lostConnectionReconnect": "サーバとの接続が切断されました: __time__ 秒後に再接続します", + "lostConnectionTry": "すぐに接続", + "cannotAddSubflowToItself": "サブフロー自身を追加できません", + "cannotAddCircularReference": "循環参照を検出したため、サブフローを追加できません", + "unsupportedVersion": "

サポートされていないバージョンのNode.jsを使用しています。

最新のNode.js LTSに更新してください。

", + "failedToAppendNode": "

'__module__'がロードできませんでした。

__error__

" + }, + "project": { + "change-branch": "ローカルブランチ'__project__'に変更しました", + "merge-abort": "Gitマージを中止しました", + "loaded": "プロジェクト'__project__'をロードしました", + "updated": "プロジェクト'__project__'を更新しました", + "pull": "プロジェクト'__project__'を再ロードしました", + "revert": "プロジェクト'__project__'を取り消しました", + "merge-complete": "Gitマージが完了しました", + "setupCredentials": "認証情報を設定", + "setupProjectFiles": "プロジェクトファイルの設定", + "no": "結構です", + "createDefault": "デフォルトのプロジェクトファイルを作成", + "mergeConflict": "マージの衝突を表示" + }, + "label": { + "manage-project-dep": "プロジェクトの依存関係の管理", + "setup-cred": "認証情報の設定", + "setup-project": "プロジェクトファイルの設定", + "create-default-package": "デフォルトパッケージファイルの作成", + "no-thanks": "不要", + "create-default-project": "デフォルトプロジェクトファイルの作成", + "show-merge-conflicts": "マージ競合を表示" + } + }, + "clipboard": { + "clipboard": "クリップボード", + "nodes": "ノード", + "node": "__count__ 個のノード", + "node_plural": "__count__ 個のノード", + "configNode": "__count__ 個の設定ノード", + "configNode_plural": "__count__ 個の設定ノード", + "flow": "__count__ 個のフロー", + "flow_plural": "__count__ 個のフロー", + "subflow": "__count__ 個のサブフロー", + "subflow_plural": "__count__ 個のサブフロー", + "pasteNodes": "JSON形式のフローデータを貼り付けてください", + "selectFile": "読み込むファイルを選択してください", + "importNodes": "フローをクリップボートから読み込み", + "exportNodes": "フローをクリップボードへ書き出し", + "download": "ダウンロード", + "importUnrecognised": "認識できない型が読み込まれました:", + "importUnrecognised_plural": "認識できない型が読み込まれました:", + "nodesExported": "クリップボードへフローを書き出しました", + "nodesImported": "読み込みました:", + "nodeCopied": "__count__ 個のノードをコピーしました", + "nodeCopied_plural": "__count__ 個のノードをコピーしました", + "invalidFlow": "不正なフロー: __message__", + "export": { + "selected": "選択したフロー", + "current": "現在のタブ", + "all": "全てのタブ", + "compact": "インデントのないJSONフォーマット", + "formatted": "インデント付きのJSONフォーマット", + "copy": "書き出し", + "export": "ライブラリに書き出し", + "exportAs": "書き出し先", + "overwrite": "更新", + "exists": "

\"__file__\"は既に存在します。

更新しますか?

" + }, + "import": { + "import": "読み込み先", + "newFlow": "新規のタブ", + "errors": { + "notArray": "JSON形式の配列ではありません", + "itemNotObject": "不正なフロー - __index__ 番目の要素はノードオブジェクトではありません", + "missingId": "不正なフロー - __index__ 番目の要素に'id'プロパティがありません", + "missingType": "不正なフロー - __index__ 番目の要素に'type'プロパティがありません" + } + }, + "copyMessagePath": "パスをコピーしました", + "copyMessageValue": "値をコピーしました", + "copyMessageValue_truncated": "切り捨てられた値をコピーしました" + }, + "deploy": { + "deploy": "デプロイ", + "full": "全て", + "fullDesc": "ワークスペースを全てデプロイ", + "modifiedFlows": "変更したフロー", + "modifiedFlowsDesc": "変更したノードを含むフローのみデプロイ", + "modifiedNodes": "変更したノード", + "modifiedNodesDesc": "変更したノードのみデプロイ", + "restartFlows": "フローを再起動", + "restartFlowsDesc": "デプロイされた現在のフローを再起動", + "successfulDeploy": "デプロイが成功しました", + "successfulRestart": "フローの再起動が成功しました", + "deployFailed": "デプロイが失敗しました: __message__", + "unusedConfigNodes": "使われていない「ノードの設定」があります。", + "unusedConfigNodesLink": "設定を参照する", + "errors": { + "noResponse": "サーバの応答がありません" + }, + "confirm": { + "button": { + "ignore": "無視", + "confirm": "デプロイの確認", + "review": "差分を確認", + "cancel": "中止", + "merge": "変更をマージ", + "overwrite": "無視してデプロイ" + }, + "undeployedChanges": "デプロイしていない変更があります。このページを抜けると変更が削除されます。", + "improperlyConfigured": "以下のノードは、正しくプロパティが設定されていません:", + "unknown": "ワークスペースに未知の型のノードがあります。", + "confirm": "このままデプロイしても良いですか?", + "doNotWarn": "この警告を再度表示しない", + "conflict": "フローを編集している間に、他のブラウザがフローをデプロイしました。", + "backgroundUpdate": "サーバ上のフローが更新されました", + "conflictChecking": "変更を自動的にマージしてよいか確認してください。", + "conflictAutoMerge": "変更の衝突がないため、自動的にマージできます。", + "conflictManualMerge": "変更に衝突があるため、デプロイ前に解決する必要があります。", + "plusNMore": "さらに __count__ 個" + } + }, + "eventLog": { + "title": "イベントログ", + "view": "ログを確認" + }, + "diff": { + "unresolvedCount": "未解決の衝突 __count__", + "unresolvedCount_plural": "未解決の衝突 __count__", + "globalNodes": "グローバルノード", + "flowProperties": "フロープロパティ", + "type": { + "added": "追加", + "changed": "変更", + "unchanged": "変更なし", + "deleted": "削除", + "flowDeleted": "削除されたフロー", + "flowAdded": "追加されたフロー", + "movedTo": "__id__ へ移動", + "movedFrom": "__id__ から移動" + }, + "nodeCount": "__count__ 個のノード", + "nodeCount_plural": "__count__ 個のノード", + "local": "ローカルの変更", + "remote": "リモートの変更", + "reviewChanges": "変更を表示", + "noBinaryFileShowed": "バイナリファイルの中身は表示することができません", + "viewCommitDiff": "コミットの内容を表示", + "compareChanges": "変更を比較", + "saveConflict": "解決して保存", + "conflictHeader": "__unresolved__ 個中 __resolved__ 個のコンフリクトを解決", + "commonVersionError": "共通バージョンは正しいJSON形式ではありません:", + "oldVersionError": "古いバージョンは正しいJSON形式ではありません:", + "newVersionError": "新しいバージョンは正しいJSON形式ではありません:" + }, + "subflow": { + "editSubflowInstance": "サブフローインスタンスを編集: __name__", + "editSubflow": "サブフローのテンプレートを編集: __name__", + "edit": "サブフローのテンプレートを編集", + "subflowInstances": "このサブフローのテンプレートのインスタンスが __count__ 個存在します", + "subflowInstances_plural": "このサブフローのテンプレートのインスタンスが __count__ 個存在します", + "editSubflowProperties": "プロパティを編集", + "input": "入力:", + "output": "出力:", + "status": "ステータスノード", + "deleteSubflow": "サブフローを削除", + "info": "詳細", + "category": "カテゴリ", + "env": { + "restore": "デフォルト値に戻す", + "remove": "環境変数を削除" + }, + "errors": { + "noNodesSelected": "サブフローを作成できません: ノードが選択されていません", + "multipleInputsToSelection": "サブフローを作成できません: 複数の入力が選択されています" + } + }, + "editor": { + "configEdit": "編集", + "configAdd": "追加", + "configUpdate": "更新", + "configDelete": "削除", + "nodesUse": "__count__ 個のノードが、この設定を使用しています", + "nodesUse_plural": "__count__ 個のノードが、この設定を使用しています", + "addNewConfig": "新規に __type__ ノードの設定を追加", + "editNode": "__type__ ノードを編集", + "editConfig": "__type__ ノードの設定を編集", + "addNewType": "新規に __type__ を追加...", + "nodeProperties": "プロパティ", + "label": "ラベル", + "color": "色", + "portLabels": "ポートラベル", + "labelInputs": "入力", + "labelOutputs": "出力", + "settingIcon": "アイコン", + "default": "デフォルト", + "noDefaultLabel": "なし", + "defaultLabel": "既定のラベルを使用", + "searchIcons": "アイコンを検索", + "useDefault": "デフォルトを使用", + "description": "詳細", + "show": "表示", + "hide": "非表示", + "locale": "UI言語の選択", + "icon": "記号", + "inputType": "入力形式", + "inputs": { + "input": "入力", + "select": "メニュー", + "checkbox": "チェックボックス", + "spinner": "スピナー", + "none": "無し", + "hidden": "非表示" + }, + "types": { + "str": "文字列", + "num": "数値", + "bool": "真偽", + "json": "JSON", + "bin": "バッファ", + "env": "環境変数" + }, + "menu": { + "input": "入力", + "select": "選択", + "checkbox": "チェックボックス", + "spinner": "数値", + "hidden": "ラベルのみ" + }, + "select": { + "label": "ラベル", + "value": "値" + }, + "spinner": { + "min": "最小値", + "max": "最大値" + }, + "errors": { + "scopeChange": "スコープの変更は、他のフローで使われているノードを無効にします", + "invalidProperties": "プロパティが不正です:" + } + }, + "keyboard": { + "title": "キーボードショートカット", + "keyboard": "キーボード", + "filterActions": "動作を検索", + "shortcut": "ショートカット", + "scope": "範囲", + "unassigned": "未割当", + "global": "グローバル", + "workspace": "ワークスペース", + "selectAll": "全てのノードを選択", + "selectAllConnected": "接続された全てのノードを選択", + "addRemoveNode": "ノードの選択、選択解除", + "editSelected": "選択したノードを編集", + "deleteSelected": "選択したノードや接続を削除", + "importNode": "フローの読み込み", + "exportNode": "フローの書き出し", + "nudgeNode": "選択したノードを移動(移動量小)", + "moveNode": "選択したノードを移動(移動量大)", + "toggleSidebar": "サイドバーの表示/非表示", + "togglePalette": "パレットの表示/非表示", + "copyNode": "選択したノードをコピー", + "cutNode": "選択したノードを切り取り", + "pasteNode": "ノードを貼り付け", + "undoChange": "変更操作を戻す", + "searchBox": "ノードを検索", + "managePalette": "パレットの管理", + "actionList": "動作一覧" + }, + "library": { + "library": "ライブラリ", + "openLibrary": "ライブラリを開く", + "saveToLibrary": "ライブラリへ保存", + "typeLibrary": "__type__ ライブラリ", + "unnamedType": "名前なし __type__", + "exportedToLibrary": "ライブラリにノードを書き出しました", + "dialogSaveOverwrite": "__libraryName__ という __libraryType__ は既に存在しています 上書きしますか?", + "invalidFilename": "不正なファイル名", + "savedNodes": "フローを保存しました", + "savedType": "__type__ を保存しました", + "saveFailed": "保存に失敗しました: __message__", + "newFolder": "新規フォルダ", + "types": { + "local": "ローカル", + "examples": "サンプル" + } + }, + "palette": { + "noInfo": "情報がありません", + "filter": "ノードを検索", + "search": "ノードを検索", + "addCategory": "新規追加...", + "label": { + "subflows": "サブフロー", + "network": "ネットワーク", + "common": "共通", + "input": "入力", + "output": "出力", + "function": "機能", + "sequence": "シーケンス", + "parser": "パーサ", + "social": "ソーシャル", + "storage": "ストレージ", + "analysis": "分析", + "advanced": "その他" + }, + "actions": { + "collapse-all": "全カテゴリを折畳む", + "expand-all": "全カテゴリを展開" + }, + "event": { + "nodeAdded": "ノードをパレットへ追加しました:", + "nodeAdded_plural": "ノードをパレットへ追加しました:", + "nodeRemoved": "ノードをパレットから削除しました:", + "nodeRemoved_plural": "ノードをパレットから削除しました:", + "nodeEnabled": "ノードを有効化しました:", + "nodeEnabled_plural": "ノードを有効化しました:", + "nodeDisabled": "ノードを無効化しました:", + "nodeDisabled_plural": "ノードを無効化しました:", + "nodeUpgraded": "ノードモジュール __module__ をバージョン __version__ へ更新しました" + }, + "editor": { + "title": "パレットの管理", + "palette": "パレット", + "times": { + "seconds": "秒前", + "minutes": "分前", + "minutesV": "__count__ 分前", + "hoursV": "__count__ 時間前", + "hoursV_plural": "__count__ 時間前", + "daysV": "__count__ 日前", + "daysV_plural": "__count__ 日前", + "weeksV": "__count__ 週間前", + "weeksV_plural": "__count__ 週間前", + "monthsV": "__count__ ヵ月前", + "monthsV_plural": "__count__ ヵ月前", + "yearsV": "__count__ 年前", + "yearsV_plural": "__count__ 年前", + "yearMonthsV": "__y__ 年 __count__ ヵ月前", + "yearMonthsV_plural": "__y__ 年 __count__ ヵ月前", + "yearsMonthsV": "__y__ 年 __count__ ヵ月前", + "yearsMonthsV_plural": "__y__ 年 __count__ ヵ月前" + }, + "nodeCount": "__label__ 個のノード", + "nodeCount_plural": "__label__ 個のノード", + "moduleCount": "__count__ 個のモジュール", + "moduleCount_plural": "__count__ 個のモジュール", + "inuse": "使用中", + "enableall": "全て有効化", + "disableall": "全て無効化", + "enable": "有効化", + "disable": "無効化", + "remove": "削除", + "update": "__version__ へ更新", + "updated": "更新済", + "install": "ノードを追加", + "installed": "追加しました", + "conflict": "競合", + "conflictTip": "

インストール済みのノードの種別と競合しているため
ノードをインストールできません

競合: __module__

", + "loading": "カタログを読み込み中", + "tab-nodes": "現在のノード", + "tab-install": "ノードを追加", + "sort": "並べ替え:", + "sortAZ": "辞書順", + "sortRecent": "日付順", + "more": "+ さらに __count__ 個", + "errors": { + "catalogLoadFailed": "

ノードのカタログの読み込みに失敗しました。

詳細はブラウザのコンソールを確認してください。

", + "installFailed": "

追加処理が失敗しました: __module__

__message__

詳細はログを確認してください。

", + "removeFailed": "

削除処理が失敗しました: __module__

__message__

詳細はログを確認してください。

", + "updateFailed": "

更新処理が失敗しました: __module__

__message__

詳細はログを確認してください。

", + "enableFailed": "

有効化処理が失敗しました: __module__

__message__

詳細はログを確認してください。

", + "disableFailed": "

無効化処理が失敗しました: __module__

__message__

詳細はログを確認してください。

" + }, + "confirm": { + "install": { + "body": "

__module__ をインストールします。

ノードを追加する前に、ドキュメントを確認してください。ノードによっては、モジュールの依存関係を自動的に解決できない場合や、Node-REDの再起動が必要となる場合があります。

", + "title": "ノードを追加" + }, + "remove": { + "body": "

__module__ を削除します。

Node-REDからノードを削除します。ノードはNode-REDが再起動されるまで、リソースを使い続ける可能性があります。

", + "title": "ノードを削除" + }, + "update": { + "body": "

__module__ を更新します。

更新を完了するには手動でNode-REDを再起動する必要があります。

", + "title": "ノードの更新" + }, + "cannotUpdate": { + "body": "ノードの更新があります。「パレットの管理」の画面では更新されません。

ドキュメントを参照し、ノードの更新手順を確認してください。" + }, + "button": { + "review": "ノードの情報を参照", + "install": "追加", + "remove": "削除", + "update": "更新" + } + } + } + }, + "sidebar": { + "info": { + "name": "ノードの情報を表示", + "tabName": "名前", + "label": "情報", + "node": "ノード", + "type": "型", + "module": "モジュール", + "id": "ID", + "status": "状態", + "enabled": "有効", + "disabled": "無効", + "subflow": "サブフロー", + "instances": "インスタンス", + "properties": "プロパティ", + "info": "情報", + "desc": "詳細", + "blank": "ブランク", + "null": "ヌル", + "showMore": "さらに表示", + "showLess": "表示を省略", + "flow": "フロー", + "selection": "選択", + "nodes": "__count__ 個のノード", + "flowDesc": "フローの詳細", + "subflowDesc": "サブフローの詳細", + "nodeHelp": "ノードのヘルプ", + "none": "なし", + "arrayItems": "__count__ 要素", + "showTips": "設定からヒントを表示できます" + }, + "config": { + "name": "ノードの設定を表示", + "label": "ノードの設定", + "global": "全てのフロー上", + "none": "なし", + "subflows": "サブフロー", + "flows": "フロー", + "filterAll": "全て", + "showAllConfigNodes": "全設定ノードを表示", + "filterUnused": "未使用", + "showAllUnusedConfigNodes": "未使用の全設定ノードを表示", + "filtered": "__count__ 個が無効" + }, + "context": { + "name": "コンテキストデータ", + "label": "コンテキストデータ", + "none": "選択されていません", + "refresh": "読み込みのため更新してください", + "empty": "データが存在しません", + "node": "ノード", + "flow": "フロー", + "global": "グローバル", + "deleteConfirm": "データを削除しても良いですか?", + "autoRefresh": "選択対象が変化した場合更新", + "refrsh": "更新", + "delete": "削除" + }, + "palette": { + "name": "パレットの管理", + "label": "パレット" + }, + "project": { + "label": "プロジェクト", + "name": "プロジェクト", + "description": "詳細", + "dependencies": "依存関係", + "settings": "設定", + "noSummaryAvailable": "要約が存在しません", + "editDescription": "プロジェクトの詳細を編集", + "editDependencies": "プロジェクトの依存関係を編集", + "noDescriptionAvailable": "詳細が存在しません", + "editReadme": "README.mdを編集", + "showProjectSettings": "プロジェクト設定を表示", + "projectSettings": { + "title": "プロジェクト設定", + "edit": "編集", + "none": "なし", + "install": "インストール", + "removeFromProject": "プロジェクトから削除", + "addToProject": "プロジェクトへ追加", + "files": "ファイル", + "package": "パッケージ", + "flow": "フロー", + "credentials": "認証情報", + "packageCreate": "変更が保存された時にファイルが作成されます", + "fileNotExist": "ファイルが存在しません", + "selectFile": "ファイルを選択", + "invalidEncryptionKey": "不正な暗号化キー", + "encryptionEnabled": "暗号化が有効になっています", + "encryptionDisabled": "暗号化が無効になっています", + "setTheEncryptionKey": "暗号化キーを設定", + "resetTheEncryptionKey": "暗号化キーを初期化", + "changeTheEncryptionKey": "暗号化キーを変更", + "currentKey": "現在のキー", + "newKey": "新規のキー", + "credentialsAlert": "既存の認証情報は全て削除されます", + "versionControl": "バージョン管理", + "branches": "ブランチ", + "noBranches": "ブランチなし", + "deleteConfirm": "本当にローカルブランチ'__name__'を削除しますか?削除すると元に戻すことはできません。", + "unmergedConfirm": "ローカルブランチ'__name__'にはマージされていない変更があります。この変更は削除されます。本当に削除しますか?", + "deleteUnmergedBranch": "マージされていないブランチを削除", + "gitRemotes": "Gitリモート", + "addRemote": "リモートを追加", + "addRemote2": "リモートを追加", + "remoteName": "リモート名", + "nameRule": "A-Z 0-9 _ - のみを含む", + "url": "URL", + "urlRule": "https://、ssh:// または file://", + "urlRule2": "URLにユーザ名、パスワードを含んではいけません", + "noRemotes": "リモートなし", + "deleteRemoteConfrim": "本当にリモート'__name__'を削除しますか?", + "deleteRemote": "リモートを削除" + }, + "userSettings": { + "committerDetail": "コミッター詳細", + "committerTip": "システムのデフォルトを使用する場合、空白のままにしてください", + "userName": "ユーザ名", + "email": "メールアドレス", + "sshKeys": "SSH キー", + "sshKeysTip": "gitリポジトリへのセキュアな接続を作成できます。", + "add": "キーを追加", + "addSshKey": "SSHキーを追加", + "addSshKeyTip": "新しい公開鍵/秘密鍵ペアを生成します", + "name": "名前", + "nameRule": "A-Z 0-9 _ - のみを含む", + "passphrase": "パスフレーズ", + "passphraseShort": "パスフレーズが短すぎます", + "optional": "任意", + "cancel": "中止", + "generate": "キーを生成", + "noSshKeys": "SSHキーがありません", + "copyPublicKey": "公開鍵をクリップボードにコピー", + "delete": "キーを削除", + "gitConfig": "Git設定", + "deleteConfirm": "SSHキー __name__ を削除してもよいですか? 削除したSSHキーを元に戻すことはできません。" + }, + "versionControl": { + "unstagedChanges": "ステージングされていない変更", + "stagedChanges": "ステージングされた変更", + "unstageChange": "ステージングした変更の取り消し", + "stageChange": "変更をステージング", + "unstageAllChange": "ステージングした全ての変更の取り消し", + "stageAllChange": "全ての変更をステージング", + "commitChanges": "変更をコミット", + "resolveConflicts": "コンフリクトの解決", + "head": "最新", + "staged": "ステージング", + "unstaged": "未ステージング", + "local": "ローカル", + "remote": "リモート", + "revert": "'__file__'への変更を本当に戻しますか?この操作は元に戻せません。", + "revertChanges": "変更を戻す", + "localChanges": "ローカルの変更", + "none": "なし", + "conflictResolve": "全てのコンフリクトが解消されました。マージを完了するため、変更をコミットしてください。", + "localFiles": "ローカルファイル", + "all": "全て", + "unmergedChanges": "マージされていない変更", + "abortMerge": "マージ中止", + "commit": "コミット", + "changeToCommit": "コミット対象とする変更", + "commitPlaceholder": "コミットメッセージを入力してください。", + "cancelCapital": "キャンセル", + "commitCapital": "コミット", + "commitHistory": "コミット履歴", + "branch": "ブランチ:", + "moreCommits": "個のコミット", + "changeLocalBranch": "ローカルブランチの変更", + "createBranchPlaceholder": "ブランチの検索または作成", + "upstream": "アップストリーム", + "localOverwrite": "ブランチの変更によって上書きされたローカルの変更があります。これらの変更を先にコミットするか、あるいは元に戻さなければなりません。", + "manageRemoteBranch": "リモートブランチの管理", + "unableToAccess": "リモートのリポジトリにアクセスできません。", + "retry": "リトライ", + "setUpstreamBranch": "アップストリームとして設定する", + "createRemoteBranchPlaceholder": "リモートブランチの検索または作成", + "trackedUpstreamBranch": "作成されたブランチは、トラッキングされたアップストリームブランチとなります。", + "selectUpstreamBranch": "ブランチが作成されました。トラッキングするアップストリームブランチを選択してください。", + "pushFailed": "リモートに新しいコミットがあるため、プッシュに失敗しました。プルしてマージしてから、再度プッシュしてください。", + "push": "プッシュ", + "pull": "プル", + "unablePull": "

リモートの変更のプル失敗:ステージングされていないローカルの変更を上書きされてしまいます。

変更をコミットしてから再度実行してください。

", + "showUnstagedChanges": "ステージングされていない変更を表示", + "connectionFailed": "リモートリポジトリに接続できません: ", + "pullUnrelatedHistory": "

リモートに関連のないコミット履歴があります。

本当に変更をプルしてローカルリポジトリに反映しますか?

", + "pullChanges": "プル変更", + "history": "履歴", + "projectHistory": "プロジェクト履歴", + "daysAgo": "__count__ 日前", + "daysAgo_plural": "__count__ 日前", + "hoursAgo": "__count__ 時間前", + "hoursAgo_plural": "__count__ 時間前", + "minsAgo": "__count__ 分前", + "minsAgo_plural": "__count__ 分前", + "secondsAgo": "数秒前", + "notTracking": "ローカルブランチは現在リモートブランチをトラッキングしていません。", + "statusUnmergedChanged": "リポジトリ内にマージされていない変更があります。コンフリクトを解決してコミットしてください。", + "repositoryUpToDate": "リポジトリは最新です。", + "commitsAhead": "あなたのリポジトリはリモートより__count__コミット進んでいます。現在のコミットをプッシュできます。", + "commitsAhead_plural": "あなたのリポジトリはリモートより__count__コミット進んでいます。現在のコミットをプッシュできます。", + "commitsBehind": "あなたのリポジトリはリモートより__count__コミット遅れています。現在のコミットをプルできます。", + "commitsBehind_plural": "あなたのリポジトリはリモートより__count__コミット遅れています。現在のコミットをプルできます。", + "commitsAheadAndBehind1": "あなたのリポジトリはリモートより__count__コミット遅れており、かつ", + "commitsAheadAndBehind1_plural": "あなたのリポジトリはリモートより__count__コミット遅れており、かつ", + "commitsAheadAndBehind2": "__count__コミット進んでいます。 ", + "commitsAheadAndBehind2_plural": "__count__コミット進んでいます。 ", + "commitsAheadAndBehind3": "プッシュする前にリモートのコミットをプルしてください。", + "commitsAheadAndBehind3_plural": "プッシュする前にリモートのコミットをプルしてください。", + "refreshCommitHistory": "コミット履歴を更新", + "refreshChanges": "変更を更新" + } + } + }, + "typedInput": { + "type": { + "str": "文字列", + "num": "数値", + "re": "正規表現", + "bool": "真偽", + "json": "JSON", + "bin": "バッファ", + "date": "日時", + "jsonata": "JSONata式", + "env": "環境変数" + } + }, + "editableList": { + "add": "追加" + }, + "search": { + "empty": "一致したものが見つかりませんでした", + "addNode": "ノードを追加..." + }, + "expressionEditor": { + "functions": "関数", + "functionReference": "関数リファレンス", + "insert": "挿入", + "title": "JSONata式エディタ", + "test": "テスト", + "data": "メッセージ例", + "result": "結果", + "format": "整形", + "compatMode": "互換モードが有効になっています", + "compatModeDesc": "

JSONata互換モード

入力された式では msg を参照しているため、互換モードで評価します。このモードは将来廃止予定のため、式で msg を使わないよう修正してください。

JSONataをNode-REDで最初にサポートした際には、 msg オブジェクトの参照が必要でした。例えば msg.payload がペイロードを参照するために使われていました。

直接メッセージに対して式を評価するようになったため、この形式は使えなくなります。ペイロードを参照するには、単に payload にしてください。

", + "noMatch": "一致した結果なし", + "errors": { + "invalid-expr": "不正なJSONata式:\n __message__", + "invalid-msg": "不正なJSONメッセージ例:\n __message__", + "context-unsupported": "$flowContext や $globalContextの\nコンテキスト機能をテストできません", + "eval": "表現評価エラー:\n __message__" + } + }, + "jsEditor": { + "title": "JavaScriptエディタ" + }, + "textEditor": { + "title": "テキストエディタ" + }, + "jsonEditor": { + "title": "JSONエディタ", + "format": "JSONフォーマット", + "rawMode": "JSONを編集", + "uiMode": "ビジュアルエディタ", + "insertAbove": "上に挿入", + "insertBelow": "下に挿入", + "addItem": "要素を追加", + "copyPath": "要素のパスをコピー", + "expandItems": "要素を展開", + "collapseItems": "要素を折り畳む", + "duplicate": "複製", + "error": { + "invalidJSON": "不正なJSON: " + } + }, + "markdownEditor": { + "title": "マークダウンエディタ", + "expand": "拡大", + "format": "マークダウン形式で記述", + "heading1": "見出しレベル1", + "heading2": "見出しレベル2", + "heading3": "見出しレベル3", + "bold": "太字", + "italic": "斜体", + "code": "コード", + "ordered-list": "箇条書き(番号付き)", + "unordered-list": "箇条書き", + "quote": "引用", + "link": "リンク", + "horizontal-rule": "区切り線", + "toggle-preview": "プレビュー表示切替え" + }, + "bufferEditor": { + "title": "バッファエディタ", + "modeString": "UTF-8文字列として処理", + "modeArray": "JSON配列として処理", + "modeDesc": "

バッファエディタ

バッファ型は、バイト値から成るJSON配列として格納されます。このエディタは、入力値をJSON配列として構文解析します。もし不正なJSON配列の場合、UTF-8文字列として扱い、各文字コード番号から成る配列へ変換します。

例えば、 Hello World という値を、以下のJSON配列へ変換します。

[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

" + }, + "projects": { + "config-git": "Gitクライアントの設定", + "welcome": { + "hello": "こんにちは! Node-REDで「プロジェクト」機能が利用できるようになりました。", + "desc0": "フローファイルの管理方法が刷新され、バージョン管理も可能です。", + "desc1": "まず最初にプロジェクトを作成するか、既存のGitリポジトリからプロジェクトをクローンしてください。", + "desc2": "とりあえずこの処理をスキップしてもかまいません。「プロジェクト」メニューから、いつでもプロジェクトの作成を開始できます。", + "create": "プロジェクトの作成", + "clone": "プロジェクトのクローン", + "openExistingProject": "既存のプロジェクトを開く", + "not-right-now": "後にする" + }, + "git-config": { + "setup": "バージョン管理クライアントの設定", + "desc0": "Node-REDはオープンソースツールのGitを使ってバージョン管理を行います。Gitによりプロジェクトファイルに対する変化を記録し、外部リポジトリに保存することができます。", + "desc1": "変更をコミットする際、変更を行った人物の情報としてユーザ名とEmailアドレスをGitが記憶します。ユーザ名は本名でなくても構いません。好きな名前を使ってください。", + "desc2": "Gitクライアントの現在の設定は以下の通りです。", + "desc3": "設定ダイアログの「Git設定」タブから別途変更することもできます。", + "username": "ユーザ名", + "email": "Email" + }, + "project-details": { + "create": "プロジェクトの作成", + "desc0": "プロジェクトはGitリポジトリとして管理します。Gitリポジトリを使ってフローの共有やコラボレーションが簡単にできます。", + "desc1": "複数のプロジェクトを作成し、エディタから即座に変更できます。", + "desc2": "まず、プロジェクト名と説明(任意)を指定してください。", + "already-exists": "既に存在するプロジェクトです", + "must-contain": "A-Z 0-9 _ - のみ指定可能", + "project-name": "プロジェクト名", + "desc": "説明", + "opt": "任意" + }, + "clone-project": { + "clone": "プロジェクトをクローン", + "desc0": "プロジェクトを含んだGitリポジトリを作成済みの場合、クローンを作成することができます。", + "already-exists": "既に存在するプロジェクトです", + "must-contain": "A-Z 0-9 _ - のみ指定可能", + "project-name": "プロジェクト名", + "no-info-in-url": "URLにユーザ名/パスワードを含めないようにしてください", + "git-url": "GitリポジトリのURL", + "protocols": "https://, ssh:// もしくは file://", + "auth-failed": "認証に失敗しました", + "username": "ユーザ名", + "passwd": "パスワード", + "ssh-key": "SSHキー", + "passphrase": "パスフレーズ", + "ssh-key-desc": "SSHでリポジトリをクローンする前にSSHキーを追加してください。", + "ssh-key-add": "SSHキーの追加", + "credential-key": "認証情報の暗号化キー", + "cant-get-ssh-key": "エラー! 選択したSSHキーのパスを取得できません。", + "already-exists2": "既に存在します", + "git-error": "Gitエラー", + "connection-failed": "接続に失敗しました", + "not-git-repo": "Gitリポジトリではありません", + "repo-not-found": "リポジトリが見つかりません" + }, + "default-files": { + "create": "プロジェクト関連ファイルの作成", + "desc0": "プロジェクトはフローファイル、README、package.jsonを含みます。", + "desc1": "その他、Gitリポジトリで管理したいファイルを含めても構いません。", + "desc2": "既存のフローと認証情報ファイルをプロジェクトにコピーします。", + "flow-file": "フローファイル", + "credentials-file": "認証情報ファイル" + }, + "encryption-config": { + "setup": "認証情報ファイルの暗号化設定", + "desc0": "フロー認証情報ファイルを暗号化して内容の安全性を担保できます。", + "desc1": "認証情報を公開Gitリポジトリに保存する際には、秘密キーフレーズによって暗号化します。", + "desc2": "認証情報ファイルは暗号化されていません。", + "desc3": "パスワードやアクセストークンといった認証情報を他人が参照できます。", + "desc4": "認証情報を公開Gitリポジトリに保存する際には、秘密キーフレーズによって暗号化します。", + "desc5": "フロー認証情報ファイルはsettingsファイルのcredentialSecretプロパティで暗号化されています。", + "desc6": "フロー認証情報ファイルはシステムが生成したキーによって暗号化されています。このプロジェクト用に新しい秘密キーを指定してください。", + "desc7": "キーはプロジェクトファイルとは別に保存されます。他のNode-REDでこのプロジェクトを利用するには、このプロジェクトのキーが必要です。", + "credentials": "認証情報", + "enable": "暗号化を有効にする", + "disable": "暗号化を無効にする", + "disabled": "無効", + "copy": "既存のキーをコピー", + "use-custom": "カスタムキーを使用", + "desc8": "認証情報ファイルが暗号化されないため、簡単に読み出すことができます。", + "create-project-files": "プロジェクト関連ファイル作成", + "create-project": "プロジェクト作成", + "already-exists": "既に存在", + "git-error": "Gitエラー", + "git-auth-error": "Git認証エラー" + }, + "create-success": { + "success": "最初のプロジェクトの作成が成功しました!", + "desc0": "以降は、これまでと同様にNode-REDを利用できます。", + "desc1": "サイドバーの「情報」タブに現在選択されたプロジェクトを表示します。プロジェクト名の隣のボタンでプロジェクト設定画面を呼び出すことができます。", + "desc2": "サイドバーの「履歴」タブで変更が加えられたプロジェクト内のファイルを確認しコミットできます。このサイドバーでは、全てのコミット履歴を確認し、変更を外部リポジトリにプッシュすることが可能です。" + }, + "create": { + "projects": "プロジェクト", + "already-exists": "プロジェクトは既に存在します", + "must-contain": "A-Z 0-9 _ - のみ指定可能", + "no-info-in-url": "URLにユーザ名/パスワードを含めないようにしてください", + "open": "プロジェクトを開く", + "create": "プロジェクトを作成", + "clone": "プロジェクトをクローン", + "project-name": "プロジェクト名", + "desc": "説明", + "opt": "任意", + "flow-file": "フローファイル", + "credentials": "認証情報", + "enable-encryption": "暗号化を有効にする", + "disable-encryption": "暗号化を無効にする", + "encryption-key": "暗号化キー", + "desc0": "認証情報をセキュアにするためのフレーズ", + "desc1": "認証情報ファイルが暗号化されないため、簡単に読み出すことができます", + "git-url": "GitリポジトリのURL", + "protocols": "https://, ssh:// もしくは file://", + "auth-failed": "認証に失敗しました", + "username": "ユーザ名", + "password": "パスワード", + "ssh-key": "SSHキー", + "passphrase": "パスフレーズ", + "desc2": "SSHでリポジトリをクローンする前にSSHキーを追加してください。", + "add-ssh-key": "SSHキーの追加", + "credentials-encryption-key": "認証情報の暗号化キー", + "already-exists-2": "既に存在します", + "git-error": "Gitエラー", + "con-failed": "接続に失敗しました", + "not-git": "Gitリポジトリではありません", + "no-resource": "リポジトリが見つかりません", + "cant-get-ssh-key-path": "エラー! 選択したSSHキーのパスを取得できません。", + "unexpected_error": "予期しないエラー" + }, + "delete": { + "confirm": "プロジェクトを削除しても良いですか?" + }, + "create-project-list": { + "search": "プロジェクトを検索", + "current": "有効" + }, + "require-clean": { + "confirm": "

デプロイされていない変更は失われます。

続けますか?

" + }, + "send-req": { + "auth-req": "リポジトリに対する認証が必要です", + "username": "ユーザ名", + "password": "パスワード", + "passphrase": "パスフレーズ", + "retry": "リトライ", + "update-failed": "認証の更新に失敗しました", + "unhandled": "エラー応答が処理されませんでした" + }, + "create-branch-list": { + "invalid": "不正なブランチ", + "create": "ブランチの作成", + "current": "有効" + }, + "create-default-file-set": { + "no-active": "有効なプロジェクトが無い場合、デフォルトのファイル群を作成できません。", + "no-empty": "デフォルトのファイル群を空でないプロジェクトに作成することはできません。", + "git-error": "Gitエラー" + }, + "errors": { + "no-username-email": "Gitクライアントのユーザ名/emailが設定されていません。", + "unexpected": "予期しないエラーが発生しました", + "code": "コード" + } + }, + "editor-tab": { + "properties": "プロパティ", + "envProperties": "環境変数", + "description": "説明", + "appearance": "外観", + "preview": "UIプレビュー", + "defaultValue": "デフォルト値" + }, + "languages": { + "de": "ドイツ語", + "en-US": "英語", + "ja": "日本語", + "ko": "韓国語", + "zh-CN": "中国語(簡体)", + "zh-TW": "中国語(繁体)" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/ja/infotips.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/ja/infotips.json new file mode 100644 index 0000000..45ba845 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/ja/infotips.json @@ -0,0 +1,23 @@ +{ + "info": { + "tip0": "選択したノードや接続を {{core:delete-selection}} により、削除できます。", + "tip1": "{{core:search}} で、フロー内のノードを検索できます。", + "tip2": "{{core:toggle-sidebar}} で、サイドバーの表示/非表示の切り替えができます。", + "tip3": "{{core:manage-palette}} で「パレットの管理」が表示されます。", + "tip4": "フロー内の「ノードの設定」は、サイドバーに一覧表示できます。メニューから呼び出すか {{core:show-config-tab}} を入力してください。", + "tip5": "設定により、ヒントの表示/非表示を変更できます。", + "tip6": "[left] [up] [down] [right] で選択したノードを移動できます。[shift] を押すと移動量が大きくなります。", + "tip7": "ノードを接続の上へドラッグすると、接続内にノードを挿入できます。", + "tip8": "選択したノードやタブ内のフローをJSONデータとして書き出すには {{core:show-export-dialog}} を押してください。", + "tip9": "フローデータが入ったJSONファイルをエディタへドラッグ、または {{core:show-import-dialog}} により、フローを読み込むことができます。", + "tip10": "ノードの端子に複数の接続がある時、[shift] を押しながら [click] しドラッグすることで、複数の接続をまとめて他のノードの端子へ移動できます。", + "tip11": "{{core:show-info-tab}} で「情報」タブを表示します。 {{core:show-debug-tab}} で「デバッグ」タブを表示します。", + "tip12": "[ctrl] を押しながらワークスペースを [click] すると、ノードのダイアログが表示され、素早くノードを追加できます。", + "tip13": "[ctrl] を押しながらノードの端子や後続のノードを [click] すると、複数のノードを素早く接続できます。", + "tip14": "[shift] を押しながらノードを [click] すると、接続された全てのノードを選択できます。", + "tip15": "[ctrl] を押しながらノードを [click] すると、選択/非選択を切り替えできます。", + "tip16": "{{core:show-previous-tab}} や {{core:show-next-tab}} で、タブの切り替えができます。", + "tip17": "ノードのプロバティ設定画面にて {{core:confirm-edit-tray}} を押すと、変更を確定できます。また、 {{core:cancel-edit-tray}} を押すと、変更を取り消せます。", + "tip18": "ノードを選択し、 {{core:edit-selected-node}} を押すとプロパティ設定画面が表示されます。" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/ja/jsonata.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/ja/jsonata.json new file mode 100644 index 0000000..659cf66 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/ja/jsonata.json @@ -0,0 +1,270 @@ +{ + "$string": { + "args": "arg[, prettify]", + "desc": "以下の型変換ルールを用いて、引数 *arg* を文字列へ型変換します。:\n\n - 文字列は変換しません。\n - 関数は空の文字列に変換します。\n - JSONの数値として表現できないため、無限大やNaNはエラーになります。\n - 他の値は `JSON.stringify` 関数を用いて、JSONの文字列へ変換します。`prettify`が真の場合、JSONを整形出力します。フィールドを1行毎に出力。フィールドのネスト深さによってインデントを行います。" + }, + "$length": { + "args": "str", + "desc": "文字列 `str` の文字数を返します。 `str` が文字列でない場合、エラーを返します。" + }, + "$substring": { + "args": "str, start[, length]", + "desc": "位置 `start` (ゼロオフセット)から開始する引数 `str` の文字列を返します。 `length` を指定した場合、部分文字列は最大 `length` 文字を持ちます。 `start` が負の値の場合、その値は `str` の末尾からの文字数を指します。" + }, + "$substringBefore": { + "args": "str, chars", + "desc": "`str` 内で先頭に存在する文字列 `chars` より前の部分文字列を返します。 `str` が `chars` を持たない場合、 `str` を返します。" + }, + "$substringAfter": { + "args": "str, chars", + "desc": "`str` 内で先頭に存在する文字列 `chars` より後ろの部分文字列を返します。 `str` が `chars` を持たない場合、 `str` を返します。" + }, + "$uppercase": { + "args": "str", + "desc": "`str` の全ての文字を大文字にした文字列を返します。" + }, + "$lowercase": { + "args": "str", + "desc": "`str` の全ての文字を小文字にした文字列を返します。" + }, + "$trim": { + "args": "str", + "desc": "以下のステップを適用して `str` 内の全ての空白文字を取り除き、正規化します。\n\n - 全てのタブ、キャリッジリターン、ラインフィードを空白に置き換える。\n- 連続する空白を1つの空白に減らす。\n- 末尾と先頭の空白を削除する。\n\n `str` を指定しない場合(例: 本関数を引数なしで呼び出す)、コンテキスト値を `str` の値として使用します。 `str` が文字列でない場合、エラーになります。" + }, + "$contains": { + "args": "str, pattern", + "desc": "`str` が `pattern` とマッチした場合は `true` 、マッチしない場合は `false` を返します。 `str` を指定しない場合(例: 本関数を1つの引数で呼び出す)、コンテキスト値を `str` の値として使用します。引数 `pattern` は文字列や正規表現とすることができます。" + }, + "$split": { + "args": "str[, separator][, limit]", + "desc": "引数 `str` を分割し、部分文字列の配列にします。 `str` が文字列でない場合、エラーになります。省略可能な引数 `separator` には `str` を分割する文字を文字列または正規表現で指定します。 `separator` を指定しない場合、空の文字列と見なし、 `str` は1文字ずつから成る配列に分割します。 `separator` が文字列でない場合、エラーになります。省略可能な引数 `limit` には、結果の配列が持つ部分文字列の最大数を指定します。この数を超える部分文字列は破棄されます。 `limit` を指定しない場合、 `str` は結果の配列のサイズに上限なく完全に分割されます。 `limit` が負の値の場合、エラーになります。" + }, + "$join": { + "args": "array[, separator]", + "desc": "文字列の配列を、省略可能な引数 `separator` で区切った1つの文字列へ連結します。配列 `array` が文字列でない要素を含む場合、エラーになります。 `separator` を指定しない場合、空の文字列と見なします(例: 文字列間の `separator` なし)。 `separator` が文字列でない場合、エラーになります。" + }, + "$match": { + "args": "str, pattern [, limit]", + "desc": "文字列 `str` に対して正規表現 `pattern` を適用し、オブジェクトの配列を返します。配列要素のオブジェクトは `str` のうちマッチした部分の情報を保持します。" + }, + "$replace": { + "args": "str, pattern, replacement [, limit]", + "desc": "文字列 `str` からパターン `pattern` を検索し、置換文字列 `replacement` に置き換えます。\n\n任意の引数 `limit` には、置換回数の上限値を指定します。" + }, + "$now": { + "args": "", + "desc": "ISO 8601互換形式の時刻を生成し、文字列として返します。" + }, + "$base64encode": { + "args": "string", + "desc": "ASCII形式の文字列をBase 64形式へ変換します。文字列内の各文字は、バイナリデータのバイト値として扱われます。文字列内の文字は、URIエンコードした文字列も含め、0x00から0xFFの範囲である必要があります。範囲外のユニコードの文字はサポートされません。" + }, + "$base64decode": { + "args": "string", + "desc": "UTF-8のコードページを用いて、Base 64形式のバイト値を文字列に変換します。" + }, + "$number": { + "args": "arg", + "desc": "以下の型変換ルールを用いて、引数 `arg` を数値へ変換します。:\n\n - 数値は、変換しません。\n - 正しいJSONの数値を表す文字列は、数値に変換します。\n - 他の形式の値は、エラーになります。" + }, + "$abs": { + "args": "number", + "desc": "引数 `number` の絶対値を返します。" + }, + "$floor": { + "args": "number", + "desc": "`number` の値を `number` 以下の最も近い整数値へ切り捨てた値を返します。" + }, + "$ceil": { + "args": "number", + "desc": "`number` の値を `number` 以上の最も近い整数値へ切り上げた値を返します。" + }, + "$round": { + "args": "number [, precision]", + "desc": "引数 `number` の値を四捨五入した値を返します。任意の引数 `precision` には、四捨五入で用いる小数点以下の桁数を指定します。" + }, + "$power": { + "args": "base, exponent", + "desc": "基数 `base` を指数 `exponent` 分、累乗した値を返します。" + }, + "$sqrt": { + "args": "number", + "desc": "引数 `number` の平方根を返します。" + }, + "$random": { + "args": "", + "desc": "0以上、1未満の疑似乱数を返します。" + }, + "$millis": { + "args": "", + "desc": "Unixエポック(1 January, 1970 UTC)からの経過ミリ秒を数値として返します。評価対象式に含まれる `$millis()` の呼び出しは、全て同じ値を返します。" + }, + "$sum": { + "args": "array", + "desc": "数値の配列 `array` の合計値を返します。 `array` が数値でない要素を含む場合、エラーになります。" + }, + "$max": { + "args": "array", + "desc": "数値の配列 `array` 内の最大値を返します。 `array` が数値でない要素を含む場合、エラーになります。" + }, + "$min": { + "args": "array", + "desc": "数値の配列 `array` 内の最小値を返します。 `array` が数値でない要素を含む場合、エラーになります。" + }, + "$average": { + "args": "array", + "desc": "数値の配列 `array` の平均値を返します。 `array` が数値でない要素を含む場合、エラーになります。" + }, + "$boolean": { + "args": "arg", + "desc": "以下のルールを用いて、ブーリアン型へ型変換します。:\n\n - `Boolean` : 変換しない\n - `string`: 空 : `false`\n - `string`: 空でない : `true`\n - `number`: `0` : `false`\n - `number`: 0でない : `true`\n - `null` : `false`\n - `array`: 空 : `false`\n - `array`: `true` に型変換された要素を持つ: `true`\n - `array`: 全ての要素が `false` に型変換: `false`\n - `object`: 空 : `false`\n - `object`: 空でない : `true`\n - `function` : `false`" + }, + "$not": { + "args": "arg", + "desc": "引数の否定をブーリアン型で返します。 `arg` は最初にブーリアン型に型変換されます。" + }, + "$exists": { + "args": "arg", + "desc": "`arg` の式の評価値が存在する場合は `true` 、式の評価結果が未定義の場合(例: 存在しない参照フィールドへのパス)は `false` を返します。" + }, + "$count": { + "args": "array", + "desc": "配列の要素数を返します。" + }, + "$append": { + "args": "array, array", + "desc": "2つの配列を連結します。" + }, + "$sort": { + "args": "array [, function]", + "desc": "配列 `array` 内の値を並び変えた配列を返します。\n\n比較関数 `function` を用いる場合、比較関数は以下のとおり2つの引数を持つ必要があります。\n\n`function(left, right)`\n\n比較関数は、leftとrightの2つの値を比較するために、値を並び替える処理で呼び出されます。もし、求められる並び順にてleftの値をrightの値より後ろに置きたい場合は、比較関数は置き換えを表すブーリアン型の `true` を返す必要があります。一方、置き換えが不要の場合は `false` を返す必要があります。" + }, + "$reverse": { + "args": "array", + "desc": "配列 `array` の値を、逆順にした配列を返します。" + }, + "$shuffle": { + "args": "array", + "desc": "配列 `array` の値を、ランダムな順番にした配列を返します。" + }, + "$zip": { + "args": "array, ...", + "desc": "配列 `array1` … `arrayN` の位置 0, 1, 2.... の値を要素とする配列から成る配列を返します。" + }, + "$keys": { + "args": "object", + "desc": "オブジェクト内のキーを含む配列を返します。引数がオブジェクトの配列の場合、返す配列は全オブジェクトの全キーの重複の無いリストとなります。" + }, + "$lookup": { + "args": "object, key", + "desc": "オブジェクト内のキーが持つ値を返します。最初の引数がオブジェクトの配列の場合、配列内の全てのオブジェクトを検索し、存在する全てのキーが持つ値を返します。" + }, + "$spread": { + "args": "object", + "desc": "key/valueのペアを持つオブジェクトを、各要素が1つのkey/valueのペアを持つオブジェクトの配列に分割します。引数がオブジェクトの配列の場合、結果の配列は各オブジェクトから得た各key/valueのペアのオブジェクトを持ちます。" + }, + "$merge": { + "args": "array<object>", + "desc": "`object` の配列を1つの `object` へマージします。 マージ結果のオブジェクトは入力配列内の各オブジェクトのkey/valueペアを含みます。入力のオブジェクトが同じキーを持つ場合、戻り値の `object` には配列の最後のオブジェクトのkey/value値が格納されます。入力の配列がオブジェクトでない要素を含む場合、エラーとなります。" + }, + "$sift": { + "args": "object, function", + "desc": "引数 `object` が持つkey/valueのペアのうち、関数 `function` によってふるい分けたオブジェクトのみを返します。\n\n関数 `function` は、以下の引数を持つ必要があります。\n\n`function(value [, key [, object]])`" + }, + "$each": { + "args": "object, function", + "desc": "`object` の各key/valueのペアに対して、関数 `function` を適用し、その返却値から成る配列を返します。" + }, + "$map": { + "args": "array, function", + "desc": "配列 `array` 内の各値に対して、関数 `function` を適用した結果から成る配列を返します。\n\n関数 `function` は、以下の引数を持つ必要があります。\n\n`function(value [, index [, array]])`" + }, + "$filter": { + "args": "array, function", + "desc": "配列 `array` 内の値のうち、関数 `function` の条件を満たす値のみを持つ配列を返します。\n\n関数 `function` は、以下の引数を持つ必要があります。\n\n`function(value [, index [, array]])`" + }, + "$reduce": { + "args": "array, function [, init]", + "desc": "配列の各要素値に関数 `function` を連続的に適用して得られる集約値を返します。 `function` の適用の際には、直前の `function` の適用結果と要素値が引数として与えられます。\n\n関数 `function` は引数を2つ取り、配列の各要素の間に配置する中置演算子のように作用しなくてはなりません。関数`function`のシグネチャは`myfunc($accumulator, $value[, $index[, $array]])`という形式でなければなりません。\n\n任意の引数 `init` には、集約時の初期値を設定します。" + }, + "$flowContext": { + "args": "string", + "desc": "フローコンテキストのプロパティを取得します。" + }, + "$globalContext": { + "args": "string", + "desc": "グローバルコンテキストのプロパティを取得します。" + }, + "$pad": { + "args": "string, width [, char]", + "desc": "文字数が引数 `width` の絶対値以上となるよう、必要に応じて追加文字を付け足した `string` のコピーを返します。\n\n`width` が正の値の場合、文字列の右側に追加文字を付け足します。もし負の値の場合、文字列の左側に追加文字を付け足します。\n\n任意の引数 `char` には、本関数で用いる追加文字を指定します。もし追加文字を指定しない場合は、既定値として空白文字を使用します。" + }, + "$fromMillis": { + "args": "number", + "desc": "Unixエポック(1 January, 1970 UTC)からの経過ミリ秒を表す数値を、ISO 8601形式のタイムスタンプの文字列に変換します。" + }, + "$formatNumber": { + "args": "number, picture [, options]", + "desc": "`number` を文字列へ変換し、文字列 `picture` に指定した数値表現になるよう書式を変更します。\n\nこの関数の動作は、XPath F&O 3.1の仕様に定義されているXPath/XQuery関数のfn:format-numberの動作と同じです。引数の文字列 picture は、fn:format-numberと同じ構文で数値の書式を定義します。\n\n任意の第三引数 `options` は、小数点記号の様な既定のロケール固有の書式設定文字を上書きするために使用します。この引数を指定する場合、XPath F&O 3.1の仕様の数値形式の項に記述されているname/valueペアを含むオブジェクトでなければなりません。" + }, + "$formatBase": { + "args": "number [, radix]", + "desc": "`number` を引数 `radix` に指定した値を基数とした形式の文字列に変換します。 `radix` が指定されていない場合、基数10を既定値として設定します。 `radix` には2~36の値を設定でき、それ以外の値の場合はエラーになります。" + }, + "$toMillis": { + "args": "timestamp", + "desc": "ISO 8601形式の文字列 `timestamp` を、Unixエポック(1 January, 1970 UTC)からの経過ミリ秒を表す数値へ変換します。 文字列が正しい形式でない場合、エラーとなります。" + }, + "$env": { + "args": "arg", + "desc": "環境変数の値を返します。\n\n本関数はNode-REDの定義関数です。" + }, + "$eval": { + "args": "expr [, context]", + "desc": "JSONリテラルもしくはJSONata式を表す`expr`を評価します。評価の際には現在のコンテキストをコンテキストとして用います。" + }, + "$formatInteger": { + "args": "number, picture", + "desc": "`number`を`picture`指定に従って文字列に変換します。`picture`文字列は数値の変換方法をXPath F&O 3.1仕様の`fn:format-integer`に従って定義します。" + }, + "$parseInteger": { + "args": "string, picture", + "desc": "`picture`文字列の指定に従って、`string`パラメータを整数(JSON数値)に変換します。`picture`文字列は`$formatInteger`と同じ形式です。" + }, + "$error": { + "args": "[str]", + "desc": "メッセージを指定して例外を送出します。メッセージ`str`を省略した場合は`$error() function evaluated`をメッセージとします。" + }, + "$assert": { + "args": "arg, str", + "desc": "`arg`が真の場合、undefinedを返します。偽の場合、`str`をメッセージとする例外を送出します。" + }, + "$single": { + "args": "array, function", + "desc": "`array`の要素のうち、条件判定関数`function`を満たす(`function`に与えた場合に真偽値`true`を返す)要素が1つのみである場合、それを返します。マッチする要素が1つのみでない場合、例外を送出します。\n\n指定する関数は`function(value [, index [, array]])`というシグネチャでなければなりません。ここで、`value`は`array`の要素値、`index`は要素の添字、第三引数には配列全体を渡します。" + }, + "$encodeUrl": { + "args": "str", + "desc": "Uniform Resource Locator (URL)を構成する文字を1、2、3、もしくは、4文字エスケープシーケンスのUTF-8文字エンコーディングで置換します。\n\n例: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`" + }, + "$encodeUrlComponent": { + "args": "str", + "desc": "Uniform Resource Locator (URL)要素を構成する文字を1、2、3、もしくは、4文字エスケープシーケンスのUTF-8文字エンコーディングで置換します。\n\n例: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`" + }, + "$decodeUrl": { + "args": "str", + "desc": "encodeUrlComponentで置換したUniform Resource Locator (URL)をデコードします。\n\n例: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`" + }, + "$decodeUrlComponent": { + "args": "str", + "desc": "encodeUrlで置換したUniform Resource Locator (URL)要素をデコードします。 \n\n例: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`" + }, + "$distinct": { + "args": "array", + "desc": "配列`array`から重複要素を削除した配列を返します。" + }, + "$type": { + "args": "value", + "desc": "`value` の型を文字列として返します。もし `value` が未定義の場合、 `undefined` が返されます。" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/ko/editor.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/ko/editor.json new file mode 100644 index 0000000..099050d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/ko/editor.json @@ -0,0 +1,900 @@ +{ + "common": { + "label": { + "name": "이름", + "ok": "확인", + "done": "완료", + "cancel": "취소", + "delete": "삭제", + "close": "닫기", + "load": "열기", + "save": "저장", + "import": "가져오기", + "export": "내보내기", + "back": "뒤로", + "next": "앞으로", + "clone": "프로젝트 복제", + "cont": "계속하기" + } + }, + "workspace": { + "defaultName": "플로우 __number__", + "editFlow": "플로우 수정 : __name__", + "confirmDelete": "삭제 확인", + "delete": "정말로 '__label__' 을(를) 삭제하시겠습니까?", + "dropFlowHere": "플로우를 이곳에 가져오세요", + "addFlow": "플로우 추가", + "status": "상태", + "enabled": "사용가능", + "disabled": "사용불가능", + "info": "상세내역" + }, + "menu": { + "label": { + "view": { + "view": "창", + "grid": "눈금선", + "showGrid": "눈금선 보이기", + "snapGrid": "노드 배치 보조 켜기", + "gridSize": "눈금선 크기", + "textDir": "텍스트 방향", + "defaultDir": "기본", + "ltr": "왼쪽 -> 오른쪽", + "rtl": "오른쪽 -> 왼쪽", + "auto": "자동배분" + }, + "sidebar": { + "show": "우측사이드바 보이기" + }, + "palette": { + "show": "팔렛트 보이기" + }, + "settings": "설정", + "userSettings": "사용자 설정", + "nodes": "노드설정", + "displayStatus": "노드상태 보이기", + "displayConfig": "설정노드 보기", + "import": "가져오기", + "export": "내보내기", + "search": "플로우 겅색", + "searchInput": "플로우 검색", + "subflows": "보조 플로우", + "createSubflow": "보조 플로우 생성", + "selectionToSubflow": "보조 플로우 선택", + "flows": "플로우", + "add": "추가", + "rename": "이름변경", + "delete": "삭제", + "keyboardShortcuts": "단축키", + "login": "로그인", + "logout": "로그아웃", + "editPalette": "팔렛트 관리", + "other": "기타", + "showTips": "Tip 보기", + "help": "Node-RED 웹사이트", + "projects": "프로젝트", + "projects-new": "신규", + "projects-open": "열기", + "projects-settings": "프로젝트 설정", + "showNodeLabelDefault": "새로 추가된 노드의 라벨 보이기" + } + }, + "actions": { + "toggle-navigator": "네비게이터 표시/비표시", + "zoom-out": "축소하기", + "zoom-reset": "확대/축소 초기화", + "zoom-in": "확대하기" + }, + "user": { + "loggedInAs": "__name__ 에 로그인됨", + "username": "사용자명", + "password": "비밀번호", + "login": "로그인", + "loginFailed": "로그인 실패", + "notAuthorized": "권한이 없습니다", + "errors": { + "settings": "로그인 후 설정이 가능합니다", + "deploy": "로그인 후 배포가 가능합니다", + "notAuthorized": "이 기능은 로그인 후 사용가능합니다" + } + }, + "notification": { + "warning": "경고: __message__", + "warnings": { + "undeployedChanges": "변경사항 배포가 취소되었습니다", + "nodeActionDisabled": "노드 실행이 비활성화 되었습니다", + "nodeActionDisabledSubflow": "보조 플로우에서 노드 실행이 비활성화 되었습니다", + "missing-types": "

타입이 없는 노드로인해 플로우가 중지되었습니다

", + "safe-mode": "

[안전모드] 플로우가 정지되었습니다.

플로우의 수정과 배포가 가능합니다. 다시 배포버튼을 누르세요.

", + "restartRequired": "업그레이드한 모듈을 유효화하기 위해 Node-RED를 재시작 합니다 ", + "credentials_load_failed": "

인증정보 복호화에 실패하여 플로우가 멈췄습니다.

인증정보는 암호화 되어있습니다. 프로젝트의 암호화 키가 깨졌거나 정상적이지 않습니다.

", + "credentials_load_failed_reset": "

인증정보를 복호화할 수 없습니다

인증정보는 암호화 되어있습니다. 프로젝트의 암호화 키가 깨졌거나 정상적이지 않습니다.

다음 배포시 플로우의 인증정보는 초기화 될것입니다. 기존 모든 플로우의 인증정보가 지워집니다.

", + "missing_flow_file": "

프로젝트 플로우 파일을 찾을 수 없습니다

프로젝트의 플로우 파일이 설정되지 않았습니다

", + "missing_package_file": "

프로젝트 패키지 파일을 찾을 수 없습니다

프로젝트의 package.json 파일이 없습니다

", + "project_empty": "

프로젝트가 누락되어 있습니다.

기본 프로젝트 파일을 만드시겠습니까?
그렇지 않으면 수동으로 편집가 외부에 프로젝트 파일을 만드셔야 합니다.

", + "project_not_found": "

'__project__' 가 없습니다.

", + "git_merge_conflict": "

변경사항 자동병합에 실패했습니다.

병합되지 않은 충돌을 수정 후 재등록 하세요.

" + }, + "error": "에러: __message__", + "errors": { + "lostConnection": "서버와 연결이 끊어졌습니다. 재접속을 시도합니다 ...", + "lostConnectionReconnect": "서버와 연결이 끊어졌습니다. __time__ 초 안에 재접속을 시도합니다.", + "lostConnectionTry": "지금 재접속", + "cannotAddSubflowToItself": "서브플로우 자기자신을 추가할 수 없습니다", + "cannotAddCircularReference": "순환참조가 발견되었습니다. 서브플로우를 추가할 수 없습니다", + "unsupportedVersion": "

지원하지 않는 Node.js를 사용하고 있습니다

Node.js LTS 버전을 사용해 주세요

", + "failedToAppendNode": "

'__module__' 읽어오기 실패

__error__

" + }, + "project": { + "change-branch": "로컬지점으로 '__project__' 변경", + "merge-abort": "Git 병합을 중지했습니다.", + "loaded": "'__project__' 프로젝트를 열었습니다", + "updated": "'__project__'가 변경 되었습니다", + "pull": "'__project__'를 다시 가져왔습니다", + "revert": "'__project__'를 취소했습니다", + "merge-complete": "Git 병합이 완료되었습니다" + }, + "label": { + "manage-project-dep": "프로젝트 의존성 관리", + "setup-cred": "인증정보 설정", + "setup-project": "프로젝트 파일 설정", + "create-default-package": "기본 패키지 파일 생성", + "no-thanks": "괜찮습니다", + "create-default-project": "기본 프로젝트 파일 생성", + "show-merge-conflicts": "병합 충돌 보여주기" + } + }, + "clipboard": { + "clipboard": "클립보드", + "nodes": "노드", + "node": "__count__ 개의 노드", + "node_plural": "__count__ 개의 노드", + "configNode": "__count__ 개의 설정 노드", + "configNode_plural": "__count__ 개의 설정 노드", + "flow": "__count__ 개의 플로우", + "flow_plural": "__count__ 개의 플로우", + "subflow": "__count__ 개의 서브 플로우", + "subflow_plural": "__count__ 개의 서브 플로우", + "pasteNodes": "여기에 노드를 붙여넣기 하세요", + "selectFile": "불러올 파일을 선택하세요", + "importNodes": "노드 불러오기", + "exportNodes": "클립보드에 노드 내보내기", + "download": "다운로드", + "importUnrecognised": "알 수 없는 형식 :", + "importUnrecognised_plural": "알 수 없는 형식 :", + "nodesExported": "클립보드에 노드 내보내기", + "nodesImported": "불러오기 : ", + "nodeCopied": "__count__개의 노드가 복사 되었습니다", + "nodeCopied_plural": "__count__개의 노드가 복사 되었습니다", + "invalidFlow": "정상적지 않은 플로우 : __message__", + "export": { + "selected": "선택된 노드", + "current": "현재 플로우", + "all": "모든 플로우", + "compact": "압축형식", + "formatted": "서식유지", + "copy": "클립보드로 내보내기" + }, + "import": { + "import": "가져올 위치 : ", + "newFlow": "새로운 플로우", + "errors": { + "notArray": "입력이 JSON 배열이 아닙니다", + "itemNotObject": "입력이 올바른 플로우가 아닙니다 - __index__는 노드 오브젝트가 아닙니다", + "missingId": "입력이 올바른 플로우가 아닙니다 - __index__의 'id' 속성이 없습니다", + "missingType": "입력이 올바른 플로우가 아닙니다 - __index__의 'type' 속성이 없습니다" + } + }, + "copyMessagePath": "Path가 복사 되었습니다", + "copyMessageValue": "Value가 복사 되었습니다", + "copyMessageValue_truncated": "Truncated value가 복사 되었습니다" + }, + "deploy": { + "deploy": "배포하기", + "full": "전체", + "fullDesc": "작업공간 내 모든 플로우를 배포합니다", + "modifiedFlows": "변경된 플로우", + "modifiedFlowsDesc": "변경사항이 있는 플로우만 배포합니다", + "modifiedNodes": "변경된 노드", + "modifiedNodesDesc": "변경사항이 있는 노드만 배포합니다", + "restartFlows": "플로우 재시작", + "restartFlowsDesc": "현재 배포된 플로우를 재시작합니다", + "successfulDeploy": "배포가 성공했습니다", + "successfulRestart": "플로우 재시작을 성공했습니다", + "deployFailed": "배포 실패 : __message__", + "unusedConfigNodes": "사용되지 않는 설정노드가 있습니다", + "unusedConfigNodesLink": "여기를 클릭하면 볼 수 있습니다", + "errors": { + "noResponse": "서버의 응답이 없습니다" + }, + "confirm": { + "button": { + "ignore": "무시", + "confirm": "배포 확인", + "review": "변경사항 보기", + "cancel": "취소", + "merge": "병합", + "overwrite": "무시하고 배포하기" + }, + "undeployedChanges": "배포되지 않은 변경사항이 있습니다.\n\n이 페이지를 떠나면 변경사항이 사라집니다", + "improperlyConfigured": "작업공간에 올바르게 구성되지 않은 노드가 있습니다 :", + "unknown": "작업공간에 알려지지 않는 노드타입이 있습니다 :", + "confirm": "배포하시겠습니까?", + "doNotWarn": "이 경고를 무시", + "conflict": "서버가 최신 플로우를 사용중입니다", + "backgroundUpdate": "플로우가 변경되었습니다", + "conflictChecking": "변경사항이 자동으로 병합될 수 있는지 확인", + "conflictAutoMerge": "변경사항에 충돌이 없습니다. 자동병합이 가능합니다", + "conflictManualMerge": "변경사항에 충돌이 있습니다. 배포하기 전에 충돌을 해결하세요", + "plusNMore": "+ __count__ 개 더보기" + } + }, + "eventLog": { + "title": "이벤트 로그", + "view": "로그 보기" + }, + "diff": { + "unresolvedCount": "__count__개의 충돌이 해결되지 않음", + "unresolvedCount_plural": "__count__개의 충돌이 해결되지 않음", + "globalNodes": "Global 노드", + "flowProperties": "플로우 속성", + "type": { + "added": "추가됨", + "changed": "변경됨", + "unchanged": "변경없음", + "deleted": "삭제됨", + "flowDeleted": "플로우 삭제됨", + "flowAdded": "플로우 추가됨", + "movedTo": "__id__로 이동됨", + "movedFrom": "__id__로 부터 이동됨" + }, + "nodeCount": "__count__ 개의 노드", + "nodeCount_plural": "__count__ 개의 노드", + "local": "로컬 변경사항", + "remote": "원격 변경사항", + "reviewChanges": "변경사항 살펴보기", + "noBinaryFileShowed": "바이너리파일 내용을 볼수 없습니다", + "viewCommitDiff": "변경사항 보기", + "compareChanges": "변경사항 비교", + "saveConflict": "충돌 해결내용 저장", + "conflictHeader": "__unresolved__ 개 중 __resolved__ 충돌이 해결됨", + "commonVersionError": "Common Version의 JSON 형식이 올바르지 않습니다 :", + "oldVersionError": "Old Version의 JSON 형식이 올바르지 않습니다 :", + "newVersionError": "New Version의 JSON 형식이 올바르지 않습니다 :" + }, + "subflow": { + "editSubflow": "플로우 템플릿 수정 : __name__", + "edit": "플로우 템플릿 수정", + "subflowInstances": "서브 플로우 템플릿에 __count__개의 인스턴스가 있습니다", + "subflowInstances_plural": "서브 플로우 템플릿에 __count__개의 인스턴스가 있습니다", + "editSubflowProperties": "속성 수정", + "input": "입력:", + "output": "출력:", + "deleteSubflow": "서브 플로우 삭제", + "info": "상세내역", + "category": "카테고리", + "errors": { + "noNodesSelected": "서브 플로우를 생성할 수 없습니다 : 노드가 선택되지 않았습니다", + "multipleInputsToSelection": "서브 플로우를 생성할 수 없습니다 : 복수의 입력이 선택되었습니다" + } + }, + "editor": { + "configEdit": "수정", + "configAdd": "추가", + "configUpdate": "변경", + "configDelete": "삭제", + "nodesUse": "__count__개의 노드가 이 설정을 사용중입니다", + "nodesUse_plural": "__count__개의 노드가 이 설정을 사용중입니다", + "addNewConfig": "__type__의 설정노드 추가", + "editNode": "__type__의 노드 수정", + "editConfig": "__type__의 설정노드 수정", + "addNewType": "__type__의 노드타입 추가 ...", + "nodeProperties": "노드 속성", + "label": "명칭", + "portLabels": "포트 설정", + "labelInputs": "입력", + "labelOutputs": "출력", + "settingIcon": "아이콘", + "noDefaultLabel": "없음", + "defaultLabel": "기본 명칭", + "searchIcons": "아이콘 조회", + "useDefault": "기본설정 사용", + "description": "상세 내역", + "show": "보이기", + "hide": "숨기기", + "errors": { + "scopeChange": "범위를 변경하게 되면 다른 플로우의 노드가 사용이 불가능해 집니다." + } + }, + "keyboard": { + "title": "키보드 단축키", + "keyboard": "키보드", + "filterActions": "필터", + "shortcut": "단축키", + "scope": "범위", + "unassigned": "미할당", + "global": "글로벌", + "workspace": "작업공간", + "selectAll": "모든 노드 선택", + "selectAllConnected": "모든 연결된 노드 선택", + "addRemoveNode": "노드 추가/삭제", + "editSelected": "선택된 노드 수정", + "deleteSelected": "선택된 노드나 링크를 삭제", + "importNode": "노드 불러오기", + "exportNode": "노드 내보내기", + "nudgeNode": "선택된 노드 이동 (1px)", + "moveNode": "선택된 노드 이동 (20px)", + "toggleSidebar": "사이드바 표시/비표시", + "togglePalette": "팔렛트 표시/비표시", + "copyNode": "선택된 노드 복사", + "cutNode": "선택된 노드 잘라내기", + "pasteNode": "노드 붙여넣기", + "undoChange": "마지막 변경 되돌리기", + "searchBox": "검색창 열기", + "managePalette": "팔렛트 관리" + }, + "library": { + "library": "라이브러리", + "openLibrary": "라이브러리 열기...", + "saveToLibrary": "라이브러리로 저장...", + "typeLibrary": "__type__ 라이브러리", + "unnamedType": "이름없는 __type__", + "dialogSaveOverwrite": "__libraryType__이 __libraryName__으로 이미 등록되어있습니다. 덮어쓸까요?", + "invalidFilename": "파일명이 올바르지 않습니다", + "savedNodes": "저장된 노드", + "savedType": "저장된 __type__", + "saveFailed": "저장 실패 : __message__", + "types": { + "examples": "예시" + } + }, + "palette": { + "noInfo": "정보 없음", + "filter": "필터", + "search": "모듈 검색", + "addCategory": "추가 ...", + "label": { + "subflows": "서브 플로우", + "input": "입력", + "output": "출력", + "function": "기능", + "social": "소셜", + "storage": "저장", + "analysis": "분석", + "advanced": "그 외" + }, + "actions": { + "collapse-all": "모든 카테고리 접기", + "expand-all": "모든 카테고리 펼치기" + }, + "event": { + "nodeAdded": "팔렛트에 노드가 추가되었습니다:", + "nodeAdded_plural": "팔렛트에 노드가 추가되었습니다:", + "nodeRemoved": "팔렛트에서 노드가 삭제되었습니다:", + "nodeRemoved_plural": "팔렛트에서 노드가 삭제되었습니다:", + "nodeEnabled": "노드가 활성화 되었습니다:", + "nodeEnabled_plural": "노드가 활성화 되었습니다:", + "nodeDisabled": "노드가 비활성화 되었습니다:", + "nodeDisabled_plural": "노드가 비활성화 되었습니다:", + "nodeUpgraded": "__module__ 노드모듈이 __version__으로 업그레이드 되었습니다" + }, + "editor": { + "title": "팔렛트 관리", + "palette": "팔렛트", + "times": { + "seconds": "몇초 전", + "minutes": "몇분 전", + "minutesV": "__count__분 전", + "hoursV": "__count__시간 전", + "hoursV_plural": "__count__시간 전", + "daysV": "__count__일 전", + "daysV_plural": "__count__일 전", + "weeksV": "__count__주 전", + "weeksV_plural": "__count__주 전", + "monthsV": "__count__달 전", + "monthsV_plural": "__count__달 전", + "yearsV": "__count__년 전", + "yearsV_plural": "__count__년 전", + "yearMonthsV": "__y__년, __count__월 전", + "yearMonthsV_plural": "__y__년, __count__월 전", + "yearsMonthsV": "__y__년, __count__월 전", + "yearsMonthsV_plural": "__y__년, __count__월 전" + }, + "nodeCount": "__label__ 개의 노드", + "nodeCount_plural": "__label__ 개의 노드", + "moduleCount": "__count__ 개의 모듈 사용가능", + "moduleCount_plural": "__count__ 개의 모듈 사용가능", + "inuse": "사용중", + "enableall": "모두 활성화", + "disableall": "모두 비활성화", + "enable": "활성화", + "disable": "비활성화", + "remove": "삭제", + "update": "__version__으로 업데이트", + "updated": "업데이트 됨", + "install": "설치", + "installed": "설치됨", + "conflict": "충돌", + "conflictTip": "

노드타입이 이미 설치 되어 있습니다.
/p>

충돌모듈 : __module__

", + "loading": "카탈로그 여는중...", + "tab-nodes": "설치된 노드", + "tab-install": "설치가능한 노드", + "sort": "정렬:", + "sortAZ": "a-z", + "sortRecent": "최근", + "more": "+ __count__ 개 더 보기", + "errors": { + "catalogLoadFailed": "

노드 카탈로그를 설치하지 못했습니다.

브라우저 콘솔로그를 참고하세요.

", + "installFailed": "

설치 실패 : __module__

__message__

브라우저 콘솔로그를 참고하세요.

", + "removeFailed": "

삭제 실패 : __module__

__message__

브라우저 콘솔로그를 참고하세요.

", + "updateFailed": "

업데이트 실패 : __module__

__message__

브라우저 콘솔로그를 참고하세요.

", + "enableFailed": "

활성화 실패 : __module__

__message__

브라우저 콘솔로그를 참고하세요.

", + "disableFailed": "

비활성화 실패 : __module__

__message__

브라우저 콘솔로그를 참고하세요.

" + }, + "confirm": { + "install": { + "body": "

'__module__' 설치중

설치하기 전 노드 설명서를 읽으세요. 어떤 노드은 의존성이 자동으로 해결되지 않거나, Node-RED의 재시작이 필요할 수 있습니다.

", + "title": "노드 설치" + }, + "remove": { + "body": "

'__module__' 삭제중

Node-RED에서 노드를 제거합니다. Node-RED가 재시작되기까지 리소스가 계속 사용될 수도 있습니다.

", + "title": "노드 삭제" + }, + "update": { + "body": "

'__module__' 업데이트중

업데이트 반영을 위해 Node-RED를 수동으로 재시작해야 할 경우도 있습니다.

", + "title": "노드 변경" + }, + "cannotUpdate": { + "body": "이 노드에 대한 업데이트가 있지만, 팔레트 관리자가 변경할 수 있는 위치에 설치되지 않았습니다.

이 노드를 변경하는 방법은 설명서를 참조하세요" + }, + "button": { + "review": "노드정보 열기", + "install": "설치", + "remove": "삭제", + "update": "업데이트" + } + } + } + }, + "sidebar": { + "info": { + "name": "노드정보", + "tabName": "이름", + "label": "정보", + "node": "노드", + "type": "타입", + "module": "모듈", + "id": "ID", + "status": "상태", + "enabled": "활성화", + "disabled": "비활성화", + "subflow": "서브 플로우", + "instances": "인스턴스", + "properties": "속성", + "info": "정보", + "desc": "상세 내역", + "blank": "공백", + "null": "null", + "showMore": "더 보기", + "showLess": "간단히", + "flow": "플로우", + "selection": "선택", + "nodes": "__count__ 개의 노드", + "flowDesc": "플로우 상세내역", + "subflowDesc": "서브 플로우 상세내역", + "nodeHelp": "노드 도움말", + "none": "없음", + "arrayItems": "__count__ 개의 항목", + "showTips": "설정에서 도움말을 열 수 있습니다. " + }, + "config": { + "name": "노드 설정", + "label": "설정", + "global": "모든 플로우", + "none": "없음", + "subflows": "보조 플로우", + "flows": "플로우", + "filterAll": "전체", + "filterUnused": "미사용", + "filtered": "__count__ 개 숨김" + }, + "context": { + "name": "Context 데이터", + "label": "context", + "none": "선택 없음", + "refresh": "새로고침", + "empty": "공백", + "node": "노드", + "flow": "플로우", + "global": "Global", + "deleteConfirm": "정말로 이 아이템을 지우시겠습니까?" + }, + "palette": { + "name": "팔레트 관리", + "label": "팔레트" + }, + "project": { + "label": "프로젝트", + "name": "프로젝트", + "description": "상세내역", + "dependencies": "의존성", + "settings": "설정", + "noSummaryAvailable": "요약 없음", + "editDescription": "프로젝트 상세내역 수정", + "editDependencies": "프로젝트 의존성 수정", + "editReadme": "README.md 수정", + "showProjectSettings": "프로젝트 설정 보이기", + "projectSettings": { + "title": "프로젝트 설정", + "edit": "수정", + "none": "없음", + "install": "설치", + "removeFromProject": "프로젝트에서 삭제", + "addToProject": "프로젝트에 추가", + "files": "파일", + "flow": "플로우", + "credentials": "인증정보", + "invalidEncryptionKey": "잘못된 암호화 키", + "encryptionEnabled": "암호화 활성화", + "encryptionDisabled": "암호화 비활성화", + "setTheEncryptionKey": "암호화 키 설정 :", + "resetTheEncryptionKey": "암호화 키 초기화 :", + "changeTheEncryptionKey": "암호화 키 변경:", + "currentKey": "현재 키", + "newKey": "새로운 키", + "credentialsAlert": "모든 인증정보를 삭제합니다", + "versionControl": "버전 관리", + "branches": "브랜치", + "noBranches": "브랜치 없음", + "deleteConfirm": "다시 되돌릴 수 없습니다. '__name__'의 로컬 브랜치를 삭제 히시겠습니까?", + "unmergedConfirm": "'__name__'의 병합되지 않은 수정사항을 잃어버릴 수 있습니다. 그래도 삭제 하시겠습니까?", + "deleteUnmergedBranch": "미병합 브랜치 삭제", + "gitRemotes": "Git 원격", + "addRemote": "원격 추가", + "addRemote2": "원격 추가", + "remoteName": "원격 이름", + "nameRule": "A-Z 0-9 _ -의 문자만 사용이 가능합니다", + "url": "URL", + "urlRule": "https://, ssh:// or file://", + "urlRule2": "URL안에 사용자아이디/비밀번호를 사용하지 마세요", + "noRemotes": "원격 없음", + "deleteRemoteConfrim": "원격 '__name__'를 정말로 삭제하시겠습니까?", + "deleteRemote": "원격 삭제" + }, + "userSettings": { + "committerDetail": "Committer 상세내역", + "committerTip": "시스템 기본값을 사용하려면 비워두세요", + "userName": "사용자명", + "email": "이메일", + "sshKeys": "SSH키", + "sshKeysTip": "원격저장소에 대한 보안연결을 허용합니다", + "add": "키 추가", + "addSshKey": "SSH키 추가", + "addSshKeyTip": "public/private 키쌍을 추가합니다", + "name": "이름", + "nameRule": "A-Z 0-9 _ -의 문자만 사용이 가능합니다", + "passphrase": "암호", + "passphraseShort": "암호가 너무 짧습니다", + "optional": "선택항목", + "cancel": "취소", + "generate": "Key 생성", + "noSshKeys": "SSH키 없음", + "copyPublicKey": "클립보드로 public key 복사", + "delete": "키 삭제", + "gitConfig": "Git 설정", + "deleteConfirm": "다시 되돌릴 수 없습니다. __name__의 SSH키를 삭제하시겠습니까?" + }, + "versionControl": { + "unstagedChanges": "변경사항을 언스테이징", + "stagedChanges": "스테이징된 변경사항", + "unstageChange": "스테이징 되지않은 변경사항", + "stageChange": "변경사항을 스테이징", + "unstageAllChange": "모든 변경사항 언스테이징", + "stageAllChange": "모든 변경사항 스테이징", + "commitChanges": "변경사항 커밋", + "resolveConflicts": "충돌 해결", + "head": "HEAD", + "staged": "스테이징 됨", + "unstaged": "스테이징 안됨", + "local": "로컬", + "remote": "리모트", + "revert": "다시 복원할 수 없습니다. '__file__'을 되돌리시겠습니까?", + "revertChanges": "변경사항 되돌리기", + "localChanges": "로컬 변경사항", + "none": "없음", + "conflictResolve": "모든 충돌이 해결되었습니다. 변경사항을 적용하여 병합을 완료하세요", + "localFiles": "로컬 파일", + "all": "전체", + "unmergedChanges": "병합되지 않은 변경사항", + "abortMerge": "병합 중단", + "commit": "커밋", + "changeToCommit": "커밋 변경사항", + "commitPlaceholder": "커밋 메시지를 입력하세요", + "cancelCapital": "취소", + "commitCapital": "커밋", + "commitHistory": "커밋 이력", + "branch": "브랜치 :", + "moreCommits": "커밋 더보기", + "changeLocalBranch": "로컬 브랜치 변경", + "createBranchPlaceholder": "브렌치 찾기/생성", + "upstream": "업스트림", + "localOverwrite": "브랜치에 반영할 변경사항이 있습니다. 변경사항을 커밋하거나, 변경내역을 취소해야 합니다", + "manageRemoteBranch": "원격 브랜치 관리", + "unableToAccess": "원격저장소에 접근할 수 없습니다", + "retry": "재시도", + "setUpstreamBranch": "업스트림 브랜치로 설정", + "createRemoteBranchPlaceholder": "리모드 브랜치 찾기/생성", + "trackedUpstreamBranch": "생성된 브랜치는 트래킹된 업스트림 브랜치로 설정됩니다", + "selectUpstreamBranch": "브랜치가 생성될 것입니다. 트래킹된 업스트림 브랜치로 설정하세요", + "pushFailed": "리모트에 최신 커밋이 있기 때문에 push할 수 없습니다. 먼저 pull과 병합을 하신 후 push하세요", + "push": "push", + "pull": "pull", + "unablePull": "

원격저장소의 변경사항을 가져올 수 없습니다, 당신의 unstaged 로컬 변경사항을 덮어씁니다.

변경사항을 적용하고 다시 시도하세요

", + "showUnstagedChanges": "unstaged 변경사항 보여주기", + "connectionFailed": "원격저장소 연결 불가 : ", + "pullUnrelatedHistory": "

원격저장소에 연관없는 커밋 기록이 있습니다.

모든 변경사항을 로컬 저장소로 가져 오시겠습니까?

", + "pullChanges": "Pull 변경사항", + "history": "이력", + "projectHistory": "프로젝트 이력", + "daysAgo": "__count__일 전", + "daysAgo_plural": "__count__일 전", + "hoursAgo": "__count__시간 전", + "hoursAgo_plural": "__count__시간 전", + "minsAgo": "__count__분 전", + "minsAgo_plural": "__count__분 전", + "secondsAgo": "몇초 전", + "notTracking": "당신의 로컬 브랜치는 원격브랜치를 트래킹하고 있지 않습니다", + "statusUnmergedChanged": "당신의 저장소는 병합되지 않은 변경사항을 가지고 있습니다. 충돌을 수정하고 결과를 커밋하세요", + "repositoryUpToDate": "당신의 저장소는 최신상태 입니다", + "commitsAhead": "당신의 저장소가 원격지보다 __count__ 커밋을 앞서 있습니다. 이제 커밋 할 수 있습니다.", + "commitsAhead_plural": "당신의 저장소가 원격지보다 __count__ 커밋을 앞서 있습니다. 지금 커밋할 수 있습니다.", + "commitsBehind": "당신의 저장소가 원격지보다 __count__ 커밋이 늦습니다. 이제 pull 할 수 있습니다.", + "commitsBehind_plural": "당신의 저장소가 원격지보다 __count__ 커밋이 늦습니다. 이제 pull 할 수 있습니다.", + "commitsAheadAndBehind1": "당신의 저장소가 __count__ 커밋이 늦고, ", + "commitsAheadAndBehind1_plural": "당신의 저장소가 __count__ 커밋이 늦고 ", + "commitsAheadAndBehind2": "__count__ 커밋이 원격지보다 앞서 있습니다. ", + "commitsAheadAndBehind2_plural": "__count__ 커밋이 원격지보다 앞서 있습니다.", + "commitsAheadAndBehind3": "push하기전에 리모트 저장소에서 pull을 먼저 수행하세요.", + "commitsAheadAndBehind3_plural": "push하기전에 리모트 저장소에서 pull을 먼저 수행하세요.", + "refreshCommitHistory": "커밋 기록 새로고침", + "refreshChanges": "변경사항 새로고침" + } + } + }, + "typedInput": { + "type": { + "str": "string", + "num": "number", + "re": "regular expression", + "bool": "boolean", + "json": "JSON", + "bin": "buffer", + "date": "timestamp", + "jsonata": "expression", + "env": "env variable" + } + }, + "editableList": { + "add": "추가" + }, + "search": { + "empty": "결과 없음", + "addNode": "노드 추가 ..." + }, + "expressionEditor": { + "functions": "기능", + "functionReference": "기능 참조", + "insert": "삽입", + "title": "JSONata 형식 에디터", + "test": "테스트", + "data": "예제 메세지", + "result": "결과", + "format": "형식", + "compatMode": "호환모드 사용", + "compatModeDesc": "

JSONata호환 모드

입력된 형식은 msg 를 참조하고 있어, 호환모드로 평가합니다. 이 모드는 후에 폐지될 예정이니, msg 를 사용하지 않도록 해 주시길 바랍니다.

JSONata를 Node-RED에서 처음 지원했을 때에는 msg 오브젝트의 참조가 필요했습니다. 예를 들어 msg.payload 는 payload를 참고하기 위해 사용되었습니다.

직접 메시지에 대하여 식을 평가하도록 되었기에, 이 형식은 사용할 수 없게 됩니다. payload를 참조하려면 단순히 payload 로 지정해 주십시오.

", + "noMatch": "결과 없음", + "errors": { + "invalid-expr": "유효하지 않은 JSONata 형식 :\n __message__", + "invalid-msg": "유효하지 않은 예시 JSON 메세지 :\n __message__", + "context-unsupported": "컨텍스트 기능을 테스트 할 수 없습니다.\n $flowContext 또는 $globalContext", + "eval": "형식 오류 :\n __message__" + } + }, + "jsEditor": { + "title": "자바스크립트 에디터" + }, + "jsonEditor": { + "title": "JSON 에디터", + "format": "JSON 형식" + }, + "markdownEditor": { + "title": "Markdown 에디터", + "format": "Markdown 형식", + "heading1": "제목 레벨1", + "heading2": "제목 레벨2", + "heading3": "제목 레벨3", + "bold": "강조", + "italic": "이탤릭", + "code": "코드", + "ordered-list": "번호 목차", + "unordered-list": "목차", + "quote": "인용", + "link": "링크", + "horizontal-rule": "나눔줄", + "toggle-preview": "미리보기 전환" + }, + "bufferEditor": { + "title": "Buffer 에디터", + "modeString": "UTF-8 문자열로 처리", + "modeArray": "JSON 배열로 처리", + "modeDesc": "

Buffer 에디터

버퍼타입은 byet값의 JSON배열로 저장됩니다. 이 에디터는 입력된 값을 JSON 배열로 구문분석 합니다. 만약 유효한 JSON이 아닌경우 UTF-8 문자열로 처리되어 각 문자코드 번호의 배열로 변환됩니다.

예를들어 Hello World 라는 값은 다음의 JSON 배열로 변환됩니다.

[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

" + }, + "projects": { + "config-git": "Git client 설정", + "welcome": { + "hello": "안녕하세요. Node-RED에서 프로젝트 기능을 이용할 수 있게 되었습니다.", + "desc0": "플로우 파일을 관리하는 새로운 방법이며, 버전을 관리할 수 도 있습니다.", + "desc1": "무선 프로젝트를 작성하거나 기존의 Git저장소에서 프로젝트를 복제할 수 있습니다.", + "desc2": "이 기능을 건너뛰어도 상관없습니다. 언제든지 프로젝트 메뉴에서 첫번째 프로젝트를 만들 수 있습니다.", + "create": "프로젝트 생성", + "clone": "프로젝트 복제", + "not-right-now": "나중에" + }, + "git-config": { + "setup": "버전관리 클라이언트를 설정합니다", + "desc0": "Node-RED는 오픈소스 Git로 버전관리를 할 수 있습니다. 프로젝트 파일의 변경사항을 추적하고 원격저장소로 push할 수 있습니다.", + "desc1": "당신이 변경사항을 커밋하면 git은 누가 변경사항을 만들었는지 사용자명과 이메일 정보를 기록합니다. 사용자명은 꼭 당신의 실명일 필요는 없습니다.", + "desc2": "당신의 Git 클라이언트는 아래와 같이 이미 설정되었습니다.", + "desc3": "당신은 git config의 설정탭에서 설정을 변경할 수 있습니다.", + "username": "사용자명", + "email": "이메일" + }, + "project-details": { + "create": "프로젝트 생성", + "desc0": "프로젝트는 Git 저장소로 관리되어집니다. 다른 사람과 협업하거나 공유하기 쉬워집니다.", + "desc1": "당신은 여러 개의 프로젝트를 생성할 수 있고 에디터에서 프로젝트를 선택할 수 있습니다.", + "desc2": "시작하려면 프로젝트 이름과 프로젝트의 상세설명이 필요합니다.", + "already-exists": "프로젝트가 이미 존재합니다", + "must-contain": "A-Z 0-9 _ -의 문자만 사용이 가능합니다", + "project-name": "프로젝트명", + "desc": "상세설명", + "opt": "옵션" + }, + "clone-project": { + "clone": "프로젝트 복제", + "desc0": "프로젝트가 있는 저장소를 가지고 있다면, 즉시 복제하여 사용할 수 있습니다.", + "already-exists": "프로젝트가 이미 존재합니다", + "must-contain": "A-Z 0-9 _ -의 문자만 사용이 가능합니다", + "project-name": "프로젝트명", + "no-info-in-url": "URL안에 사용자아이디/비밀번호를 사용하지 마세요", + "git-url": "Git 저장소 URL", + "protocols": "https://, ssh:// 혹은 file://", + "auth-failed": "인증 실패", + "username": "사용자명", + "passwd": "패스워드", + "ssh-key": "SSH키", + "passphrase": "패스워드", + "ssh-key-desc": "저장소를 복제하기 전에 접속을 위해 SSH키를 먼저 추가하세요.", + "ssh-key-add": "ssh키 추가", + "credential-key": "인증 암호화 키", + "cant-get-ssh-key": "에러! 선택한 SSH키 경로를 가져올 수 없습니다", + "already-exists2": "이미 존재합니다", + "git-error": "git 에러", + "connection-failed": "접속 실패", + "not-git-repo": "Git저장소가 아닙니다", + "repo-not-found": "저장소가 없습니다" + }, + "default-files": { + "create": "프로젝트 파일 생성", + "desc0": "프로젝트는 당신의 플로우, README, package.json 파일을 포함합니다.", + "desc1": "Git 저장소에서 관리하고 싶은 다른 파일들을 포함할 수 있습니다.", + "desc2": "당신이 이미 가지고 있는 flow, 자격증명파일이 프로젝트로 복사될 것입니다.", + "flow-file": "플로우 파일", + "credentials-file": "자격증명 파일" + }, + "encryption-config": { + "setup": "자격인증 파일의 암호화 설정", + "desc0": "플로우의 자격인증 파일 암호화를 통해 내용을 안전하게 유지할 수 있습니다.", + "desc1": "자격증명을 공용 Git저장소에 저장하려면 비밀키 구문을 제공하여 암호화 해야 합니다", + "desc2": "당신의 플로우 자격인증 파일은 암호화 되어 있지 않습니다.", + "desc3": "즉, 암호 및 액세스 토큰과 같은 내용을 파일에 액세스 할 수있는 모든 사람이 열람할 수 있습니다.", + "desc4": "자격증명을 공용 Git저장소에 저장하려면 비밀키 구문을 제공하여 암호화 해야 합니다", + "desc5": "당신의 플로우 자격증명파일은 setting파일의 credentialSecret속성으로 암호화되어 있습니다.", + "desc6": "당신의 플로우 자격증명파일은 시스템이 생성된 키에 의해 암호화 되어있습니다. 이 프로젝트용 새로운 비밀키를 지정해 주세요.", + "desc7": "키는 프로젝트파일과는 별개로 보존됩니다. 다른 Node-RED에서 이 프로젝트를 이용하려면 이 프로젝트의 키가 필요합니다.", + "credentials": "자격인증", + "enable": "암호화 활성화", + "disable": "암호화 비활성화", + "disabled": "비활성화됨", + "copy": "기존 키를 복사", + "use-custom": "커스텀키 사용", + "desc8": "자격증명 파일이 암호화되어 있지 않아, 간단히 해당내용이 열람될 수 있습니다.", + "create-project-files": "프로젝트 생성", + "create-project": "프로젝트 생성", + "already-exists": "이미 존재합니다.", + "git-error": "git 에러", + "git-auth-error": "git 인증 에러" + }, + "create-success": { + "success": "당신의 첫번째 프로젝트 생성이 성공하였습니다.", + "desc0": "앞으로 이와 같이 Node-RED를 사용할 수 있습니다.", + "desc1": "사이드바의 '정보'탭은 현재 활성화된 프로젝트를 보여줍니다. 이름 옆에 있는 버틀을 사용하여 프로젝트 설정화면을 불러올 수 있습니다.", + "desc2": "사이드바의 '이력'탭은 프로젝트의 변경된 파일을 확인하고 커밋할 수 있습니다. 커밋의 전체 기록을 보여주고 변경사항을 원격 저장소에 push할 수 있습니다." + }, + "create": { + "projects": "프로젝트", + "already-exists": "프로젝트가 이미 존재합니다", + "must-contain": "A-Z 0-9 _ -의 문자만 사용이 가능합니다", + "no-info-in-url": "URL안에 사용자아이디/비밀번호를 사용하지 마세요", + "open": "프로젝트 열기", + "create": "프로젝트 생성", + "clone": "프로젝트 복제", + "project-name": "프로젝트명", + "desc": "상세내역", + "opt": "옵션", + "flow-file": "플로우 파일", + "credentials": "자격증명", + "enable-encryption": "암호화 활성화", + "disable-encryption": "암호화 비활성화", + "encryption-key": "암호화 키", + "desc0": "자격증명 정보를 안전하게 하는 문구", + "desc1": "자격증명 파일이 암호화되어 있지 않아, 간단히 해당내용이 열람될 수 있습니다.", + "git-url": "Git 저장소 URL", + "protocols": "https://, ssh:// 혹은 file://", + "auth-failed": "인증 실패", + "username": "사용자명", + "password": "패스워드", + "ssh-key": "SSH키", + "passphrase": "패스워드", + "desc2": "저장소를 복제하기 전에 접속을 위해 SSH키를 먼저 추가하세요.", + "add-ssh-key": "ssh키 추가", + "credentials-encryption-key": "자격인증 암호화 키", + "already-exists-2": "이미 존재합니다", + "git-error": "git 에러", + "con-failed": "접속 실패", + "not-git": "git 저장소가 아닙니다", + "no-resource": "저장소아 없습니다", + "cant-get-ssh-key-path": "에러! 선택한 SSH키 경로를 가져올 수 없습니다.", + "unexpected_error": "예기치 않은 에러" + }, + "delete": { + "confirm": "프로젝트를 정말 지우시겠습니까?" + }, + "create-project-list": { + "search": "프로젝트 검색", + "current": "현재" + }, + "require-clean": { + "confirm": "

변경사항을 배포하지 않아 내용이 손실될 수 있습니다.

계속 할까요?

" + }, + "send-req": { + "auth-req": "저장소에 대한 인증이 필요합니다.", + "username": "사용자명", + "password": "패스워드", + "passphrase": "패스워드", + "retry": "재시도", + "update-failed": "인증 변경 실패", + "unhandled": "오류 응답 미처리" + }, + "create-branch-list": { + "invalid": "올바르지 않은 브랜치", + "create": "브랜치 생성", + "current": "현재" + }, + "create-default-file-set": { + "no-active": "활성화된 프로젝트 없이 기본 파일을 만들 수 없습니다.", + "no-empty": "비어있지 않은 프로젝트에 기본 파일을 만들 수 없습니다.", + "git-error": "git 에러" + }, + "errors": { + "no-username-email": "당신의 Git 클라이언트에 사용자명/이메일이 설정되지 않았습니다.", + "unexpected": "예기치 않은 에러가 발생했습니다.", + "code": "코드" + } + }, + "editor-tab": { + "properties": "속성", + "description": "상세 내역", + "appearance": "모양" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/ko/infotips.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/ko/infotips.json new file mode 100644 index 0000000..c6b399c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/ko/infotips.json @@ -0,0 +1,23 @@ +{ + "info": { + "tip0": "{{core:delete-selection}}를 사용하여 선택된 노드나 링크를 삭제할 수 있습니다.", + "tip1": "{{core:search}}를 활용하여 노드를 검색할 수 있습니다.", + "tip2": "{{core:toggle-sidebar}}를 사용하여 사이드바를 표시/비표시 전환 할 수 있습니다.", + "tip3": "{{core:manage-palette}}를 사용하여 노드 팔레트를 관리 할 수 있습니다.", + "tip4": "플로우 안의 설정노드가 사이드바에 표시됩니다. 메뉴 혹은 {{core:show-config-tab}}를 사용하여 엑세스 할 수 있습니다.", + "tip5": "설정에서 이 팁을 활성화/비활성화 할 수 있습니다.", + "tip6": "[left] [up] [down] [right] 키를 사용하여 선택된 노드를 움직일 수 있습니다. [shift]키를 누른 채로 움직이면 이동폭이 늘어납니다.", + "tip7": "노드를 와이어 사이로 드래그 하여 연결할 수도 있습니다.", + "tip8": "{{core:show-export-dialog}}를 사용하여 선택한 노드 또는 현재탭을 내보낼 수 있습니다.", + "tip9": "JSON파일을 에디터로 드래그하거나 {{core:show-import-dialog}}를 사용하여 플로우 가져올 수 있습니다.", + "tip10": "[shift] [click] 하고서 드래그하여 선택한 와이어를 이동할 수 있습니다.", + "tip11": "{{core:show-info-tab}}를 사용하여 정보탭을 표시하거나 {{core:show-debug-tab}}를 사용하여 디버그탭을 표시할 수 있습니다.", + "tip12": "작업공간에서 [ctrl] [click]을 사용하여 빠른추가 대회상자를 열 수 있습니다.", + "tip13": "[ctrl]을 누른 상태로 노드의 포트를 클릭하여 빠르게 연결할 수 있습니다.", + "tip14": "[shift]를 누른 상태로 노드를 클릭하여 연결된 모든 노드를 선택할 수 있습니다.", + "tip15": "[ctrl]을 누른 상태로 노드를 클릭하여 현재 선택영역에 노드를 추가/제거 할 수 있습니다.", + "tip16": "{{core:show-previous-tab}}와 {{core:show-next-tab}}를 사용하여 탭을 전환할 수 있습니다.", + "tip17": "노드 편집 창에서 {{core : confirm-edit-tray}}로 변경 사항을 확인하거나 {{core : cancel-edit-tray}}로 취소 할 수 있습니다.", + "tip18": "{{core : edit-selected-node}}를 누르면 현재 선택 영역의 첫 번째 노드가 편집됩니다." + } +} \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/ko/jsonata.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/ko/jsonata.json new file mode 100644 index 0000000..8b28518 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/ko/jsonata.json @@ -0,0 +1,222 @@ +{ + "$string": { + "args": "arg", + "desc": "다음과 같은 규칙을 사용하여 인수 *arg*를 문자열로 변환합니다. \n\n - 문자열은 변경되지 않습니다. \n - 함수는 빈 문자열로 변환됩니다. \n - 무한대와 NaN은 JSON수치로 표현할 수 없기 때문에 오류처리 됩니다. \n - 다른 모든 값은 `JSON.stringify` 함수를 사용하여 JSON 문자열로 변환됩니다." + }, + "$length": { + "args": "str", + "desc": "문자열 `str`의 문자 수를 반환합니다. `str`가 문자열이 아닌 경우 에러를 반환합니다." + }, + "$substring": { + "args": "str, start[, length]", + "desc": "(zero-offset)의 `start`에서 시작하는 첫번째 인수 `str`의 문자열을 반환합니다. 만약 `length`가 지정된 경우, 부분 문자열은 최대 `length`의 크기를 갖습니다. 만약 `start` 인수가 음수이면 `str`의 끝에서부터의 문자수를 나타냅니다." + }, + "$substringBefore": { + "args": "str, chars", + "desc": "`str`에 `chars`문자가 처음으로 나오기 전까지의 부분문자열을 반환합니다. 만약 `chars`가 없으면 `str`을 반환합니다." + }, + "$substringAfter": { + "args": "str, chars", + "desc": "`str`에 `chars`문자가 처음으로 나온 이후의 부분문자열을 반환합니다. 만약 `chars`가 없으면 `str`을 반환합니다." + }, + "$uppercase": { + "args": "str", + "desc": "`str`의 문자를 대문자로 반환합니다." + }, + "$lowercase": { + "args": "str", + "desc": "`str`의 문자를 소문자로 반환합니다." + }, + "$trim": { + "args": "str", + "desc": "다음의 순서대로 `str`의 모든 공백을 자르고 정규화 합니다:\n\n - 모든 탭, 캐리지 리턴 및 줄 바꿈은 공백으로 대체됩니다. \n- 연속된 공백은 하나로 줄입니다.\n- 후행 및 선행 공백은 삭제됩니다.\n\n 만일 `str`이 지정되지 않으면 (예: 이 함수를 인수없이 호출), context값을 `str`의 값으로 사용합니다. `str`이 문자열이 아니면 에러가 발생합니다." + }, + "$contains": { + "args": "str, pattern", + "desc": "`str`이 `pattern`과 일치하면 `true`를, 일치하지 않으면 `false`를 반환합니다. 만약 `str`이 지정되지 않으면 (예: 이 함수를 인수없이 호출), context값을 `str`의 값으로 사용합니다. `pattern` 인수는 문자열이나 정규표현으로 할 수 있습니다." + }, + "$split": { + "args": "str[, separator][, limit]", + "desc": "`str`인수를 분할하여 부분문자열로 배열합니다. `str`이 문자열이 아니면 에러가 발생합니다. 생략가능한 인수 `separator`는 `str`을 분할하는 문자를 문자열 또는 정규표현으로 지정합니다. `separator`를 지정하지 않은 경우, 공백의 문자열로 간주하여 `str`은 단일 문자의 배열로 분리됩니다. `separator`가 문자열이 아니면 에러가 발생합니다. 생략가능한 인수 'limit`는 결과의 배열이 갖는 부분문자열의 최대수를 지정합니다. 이 수를 넘는 부분문자열은 파기됩니다. `limit`가 지정되지 않으면`str`은 결과 배열의 크기의 제한없이 완전히 분리됩니다. `limit`이 음수인 경우 에러가 발생합니다." + }, + "$join": { + "args": "array[, separator]", + "desc": "문자열의 배열을 생략가능한 인수 `separator`로 구분한 하나의 문자열로 연결합니다. 배열 `array`가 문자열이 아닌 요소를 포함하는 경우, 에러가 발생합니다. `separator`를 지정하지 않은 경우, 공백의 문자열로 간주합니다(예: 문자열간의 `separator`없음). `separator`가 문자열이 아닌 경우, 에러가 발생합니다." + }, + "$match": { + "args": "str, pattern [, limit]", + "desc": "`str`문자열에 `pattern`를 적용하여, 오브젝트 배열을 반환합니다. 배열요소의 오브젝트는 `str`중 일치하는 부분의 정보를 보유합니다." + }, + "$replace": { + "args": "str, pattern, replacement [, limit]", + "desc": "`str`문자열에서 `pattern` 패턴을 검색하여, `replacement`로 대체합니다.\n\n임의이ㅡ 인수 `limit`는 대체 횟수의 상한값을 지정합니다." + }, + "$now": { + "args": "", + "desc": "ISO 8601 호환 형식으로 타임 스탬프를 생성하고 이를 문자열로 반환합니다." + }, + "$base64encode": { + "args": "string", + "desc": "ASCII 문자열을 base 64 표현으로 변환합니다. 문자열의 각 문자는 이진 데이터의 바이트로 처리됩니다. 이렇게 하려면 문자열의 모든 문자가 URI로 인코딩 된 문자열을 포함하고, 0x00에서 0xFF 범위에 있어야합니다. 해당 범위를 벗어난 유니 코드 문자는 지원되지 않습니다" + }, + "$base64decode": { + "args": "string", + "desc": "UTF-8코드페이지를 이용하여, Base 64형식의 바이트값을 문자열로 변환합니다." + }, + "$number": { + "args": "arg", + "desc": "`arg`를 다음과 같은 규칙을 사요하여 숫자로 변환합니다. :\n\n - 숫자는 변경되지 않습니다.\n – 올바른 JSON의 숫자는 숫자 그대로 변환됩니다.\n – 그 외의 형식은 에러를 발생합니다." + }, + "$abs": { + "args": "number", + "desc": "`number`의 절대값을 반환합니다." + }, + "$floor": { + "args": "number", + "desc": "`number`를 `number`보다 같거나 작은 정수로 내림하여 반환합니다." + }, + "$ceil": { + "args": "number", + "desc": "`number`를 `number`와 같거나 큰 정수로 올림하여 반환합니다." + }, + "$round": { + "args": "number [, precision]", + "desc": "인수 `number`를 반올림한 값을 반환합니다. 임의의 인수 `precision`에는 반올립에서 사용할 소수점이하의 자릿수를 지정합니다." + }, + "$power": { + "args": "base, exponent", + "desc": "기수 `base`의 값을 지수 `exponent`만큼의 거듭 제곱으로 반환합니다." + }, + "$sqrt": { + "args": "number", + "desc": "인수 `number`의 제곱근을 반환합니다." + }, + "$random": { + "args": "", + "desc": "0이상 1미만의 의사난수를 반환합니다." + }, + "$millis": { + "args": "", + "desc": "Unix Epoch (1970 년 1 월 1 일 UTC)부터 경과된 밀리 초 수를 숫자로 반환합니다. 평가대상식에 포함되는 $millis()의 모든 호출은 모두 같은 값을 반환합니다." + }, + "$sum": { + "args": "array", + "desc": "숫자 배열 `array`의 합계를 반환합니다. `array`에 숫자가 아닌 요소가 있는 경우, 에러가 발생합니다." + }, + "$max": { + "args": "array", + "desc": "숫자 배열 `array`에서 최대값을 반환합니다. `array`에 숫자가 아닌 요소가 있는 경우, 에러가 발생합니다." + }, + "$min": { + "args": "array", + "desc": "숫자 배열 `array`에서 최소값을 반환합니다. `array`에 숫자가 아닌 요소가 있는 경우, 에러가 발생합니다." + }, + "$average": { + "args": "array", + "desc": "숫자 배열 `array`에서 평균값을 반환합니다. `array`에 숫자가 아닌 요소가 있는 경우, 에러가 발생합니다." + }, + "$boolean": { + "args": "arg", + "desc": "`arg` 값을 다음의 규칙에 의해 Boolean으로 변환합니다::\n\n - `Boolean` : 변환하지 않음\n - `string`: 비어있음 : `false`\n - `string`: 비어있지 않음 : `true`\n - `number`: `0` : `false`\n - `number`: 0이 아님 : `true`\n - `null` : `false`\n - `array`: 비어있음 : `false`\n - `array`: `true`로 변환된 요소를 가짐 : `true`\n - `array`: 모든 요소가 `false`로 변환 : `false`\n - `object`: 비어있음 : `false`\n - `object`: 비어있지 않음 : `true`\n - `function` : `false`" + }, + "$not": { + "args": "arg", + "desc": "인수의 부정을 Boolean으로 변환합니다. `arg`는 가장먼저boolean으로 변환됩니다." + }, + "$exists": { + "args": "arg", + "desc": "`arg` 식의 평가값이 존재하는 경우 `true`, 식의 평가결과가 미정의인 경우 (예: 존재하지 않는 참조필드로의 경로)는 `false`를 반환합니다." + }, + "$count": { + "args": "array", + "desc": "`array`의 요소 갯수를 반환합니다." + }, + "$append": { + "args": "array, array", + "desc": "두개의 `array`를 병합합니다." + }, + "$sort": { + "args": "array [, function]", + "desc": "배열 `array`의 모든 값을 순서대로 정렬하여 반환합니다. \n\n 비교함수 `function`을 이용하는 경우, 비교함수는 아래와 같은 두개의 인수를 가져야 합니다. \n\n `function(left,right)` \n\n 비교함수는 left와 right의 두개의 값을 비교하기에, 값을 정렬하는 처리에서 호출됩니다. 만약 요구되는 정렬에서 left값을 right값보다 뒤로 두고싶은 경우에는, 비교함수는 치환을 나타내는 Boolean형의 ``true`를, 그렇지 않은 경우에는 `false`를 반환해야 합니다." + }, + "$reverse": { + "args": "array", + "desc": "`array`에 포함된 모든 값의 순서를 역순으로 변환하여 반환합니다." + }, + "$shuffle": { + "args": "array", + "desc": "`array`에 포함된 모든 값의 순서를 랜덤으로 반환합니다." + }, + "$zip": { + "args": "array, ...", + "desc": "배열 `array1` ... arrayN`의 위치 0, 1, 2…. 의 값으로 구성된 convolved (zipped) 배열을 반환합니다." + }, + "$keys": { + "args": "object", + "desc": "`object` 키를 포함하는 배열을 반환합니다. 인수가 오브젝트의 배열이면 반환되는 배열은 모든 오브젝트에있는 모든 키의 중복되지 않은 목록이 됩니다." + }, + "$lookup": { + "args": "object, key", + "desc": "`object` 내의 `key`가 갖는 값을 반환합니다. 최초의 인수가 객체의 배열 인 경우, 배열 내의 모든 오브젝트를 검색하여, 존재하는 모든 키가 갖는 값을 반환합니다." + }, + "$spread": { + "args": "object", + "desc": "`object`의 키/값 쌍별로 각 요소가 하나인 오브젝트 배열로 분할합니다. 만일 오브젝트 배열인 경우, 배열의 결과는 각 오브젝트에서 얻은 키/값 쌍의 오브젝트를 갖습니다." + }, + "$merge": { + "args": "array<object>", + "desc": "`object`배열을 하나의 `object`로 병합합니다. 병합결과의 오브젝트는 입력배열내의 각 오브젝트의 키/값 쌍을 포함합니다. 입력 오브젝트가 같은 키를 가질경우, 반환 된 `object`에는 배열 마지막의 오브젝트의 키/값이 격납됩니다. 입력 배열이 오브젝트가 아닌 요소를 포함하는 경우, 에러가 발생합니다." + }, + "$sift": { + "args": "object, function", + "desc": "함수 `function`을 충족시키는 `object` 인수 키/값 쌍만 포함하는 오브젝트를 반환합니다. \n\n 함수 `function` 다음과 같은 인수를 가져야 합니다 : \n\n `function(value [, key [, object]])`" + }, + "$each": { + "args": "object, function", + "desc": "`object`의 각 키/값 쌍에, 함수`function`을 적용한 값의 배열을 반환합니다." + }, + "$map": { + "args": "array, function", + "desc": "`array`의 각 값에 `function`을 적용한 결과로 이루어진 배열을 반환합니다. \n\n 함수 `function`은 다음과 같은 인수를 가져야 합니다. \n\n `function(value[, index[, array]])`" + }, + "$filter": { + "args": "array, function", + "desc": "`array`의 값중, 함수 `function`의 조건을 만족하는 값으로 이루어진 배열을 반환합니다. \n\n 함수 `function`은 다음과 같은 형식을 가져야 합니다. \n\n `function(value[, index[, array]])`" + }, + "$reduce": { + "args": "array, function [, init]", + "desc": "배열의 각 요소값에 함수 `function`을 연속적으로 적용하여 얻어지는 집계값을 반환합니다. `function`의 적용에는 직전의 `function`의 적용결과와 요소값이 인수로 주어집니다. \n\n 함수 `function`은 인수를 두개 뽑아, 배열의 각 요소 사이에 배치하는 중치연산자처럼 작용해야 합니다. \n\n 임의의 인수 `init`에는 집약시의 초기값을 설정합니다." + }, + "$flowContext": { + "args": "string[, string]", + "desc": "플로우 컨텍스트 속성을 취득합니다." + }, + "$globalContext": { + "args": "string[, string]", + "desc": "플로우의 글로벌 컨텍스트 속성을 취득합니다." + }, + "$pad": { + "args": "string, width [, char]", + "desc": "문자수가 인수 `width`의 절대값이상이 되도록, 필요한 경우 여분의 패딩을 사용하여 `string`의 복사본을 반환합니다. \n\n `width`가 양수인 경우, 오른쪽으로 채워지고, 음수이면 왼쪽으로 채워집니다. \n\n 임의의 `char`인수에는 이 함수에서 사용할 패딩을 지정합니다. 지정하지 않는 경우에는, 기본값으로 공백을 사용합니다." + }, + "$fromMillis": { + "args": "number", + "desc": "Unix Epoch (1970 년 1 월 1 일 UTC) 이후의 밀리 초를 나타내는 숫자를 ISO 8601 형식의 타임 스탬프 문자열로 변환합니다." + }, + "$formatNumber": { + "args": "number, picture [, options]", + "desc": "`number`를 문자열로 변환하고 `picture` 문자열에 지정된 표현으로 서식을 변경합니다. \n\n 이 함수의 동작은 XPath F&O 3.1사양에 정의된 XPath/XQuery함수의 fn:format-number의 동작과 같습니다. 인수의 문자열 picture은 fn:format-number 과 같은 구문으로 수치의 서식을 정의합니다. \n\n 임의의 제3 인수 `option`은 소수점기호와 같은 기본 로케일 고유의 서식설정문자를 덮어쓰는데에 사용됩니다. 이 인수를 지정할 경우, XPath F&O 3.1사양의 수치형식에 기술되어있는 name/value 쌍을 포함하는 오브젝트여야 합니다." + }, + "$formatBase": { + "args": "number [, radix]", + "desc": "`number`를 인수 `radix`에 지정한 값을 기수로하는 문자열로 변환합니다. `radix`가 지정되지 않은 경우, 기수 10이 기본값으로 설정됩니다. `radix`에는 2~36의 값을 설정할 수 있고, 그 외의 값의 경우에는 에러가 발생합니다." + }, + "$toMillis": { + "args": "timestamp", + "desc": "ISO 8601 형식의 `timestamp`를 Unix Epoch (1970 년 1 월 1 일 UTC) 이후의 밀리 초 수로 변환합니다. 문자열이 올바른 형식이 아닌 경우 에러가 발생합니다." + }, + "$env": { + "args": "arg", + "desc": "환경변수를 값으로 반환합니다.\n\n 이 함수는 Node-RED 정의 함수입니다." + } +} \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-CN/editor.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-CN/editor.json new file mode 100644 index 0000000..95d3fa5 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-CN/editor.json @@ -0,0 +1,1014 @@ +{ + "common": { + "label": { + "name": "姓名", + "ok": "确认", + "done": "完成", + "cancel": "取消", + "delete": "删除", + "close": "关闭", + "load": "读取", + "save": "保存", + "import": "导入", + "export": "导出", + "back": "后退", + "next": "下一个", + "clone": "克隆项目", + "cont": "继续" + }, + "type": { + "string": "字符串", + "number": "数字", + "boolean": "布尔值", + "array": "数组", + "buffer": "buffer", + "object": "对象", + "jsonString": "JSON字符串", + "undefined": "未定义", + "null": "空" + } + }, + "workspace": { + "defaultName": "流程__number__", + "editFlow": "编辑流程: __name__", + "confirmDelete": "确认删除", + "delete": "你确定想删除 '__label__'?", + "dropFlowHere": "把流程放到这里", + "addFlow": "添加流程", + "listFlows": "流程一览", + "status": "状态", + "enabled": "有效", + "disabled": "无效", + "info": "详细描述", + "selectNodes": "点击节点来选择" + }, + "menu": { + "label": { + "view": { + "view": "显示", + "grid": "网格", + "showGrid": "显示网格", + "snapGrid": "对齐网格", + "gridSize": "网格尺寸", + "textDir": "文本方向", + "defaultDir": "默认方向", + "ltr": "从左到右", + "rtl": "从右到左", + "auto": "上下文", + "language": "语言", + "browserDefault": "浏览器默认" + }, + "sidebar": { + "show": "显示侧边栏" + }, + "palette": { + "show": "显示控制板" + }, + "settings": "设置", + "userSettings": "用户设置", + "nodes": "节点", + "displayStatus": "显示节点状态", + "displayConfig": "修改节点配置", + "import": "导入", + "export": "导出", + "search": "查找流程", + "searchInput": "查找流程", + "subflows": "子流程", + "createSubflow": "新建子流程", + "selectionToSubflow": "将选择部分更改为子流程", + "flows": "流程", + "add": "增加", + "rename": "重命名", + "delete": "删除", + "keyboardShortcuts": "键盘快捷方式", + "login": "登陆", + "logout": "退出", + "editPalette": "节点管理", + "other": "其他", + "showTips": "显示小提示", + "help": "Node-RED网页", + "projects": "项目", + "projects-new": "新建", + "projects-open": "打开", + "projects-settings": "项目设定", + "showNodeLabelDefault": "显示新添加的节点的标签" + } + }, + "actions": { + "toggle-navigator": "切换导航器", + "zoom-out": "缩小", + "zoom-reset": "重设缩放", + "zoom-in": "放大" + }, + "user": { + "loggedInAs": "作为__name__登陆", + "username": "账号", + "password": "密码", + "login": "登陆", + "loginFailed": "登陆失败", + "notAuthorized": "未授权", + "errors": { + "settings": "设置信息需要登陆后才能访问", + "deploy": "改动需要登陆后才能部署", + "notAuthorized": "此操作需要登陆后才能执行" + } + }, + "notification": { + "warning": "警告: __message__", + "warnings": { + "undeployedChanges": "节点中存在未部署的更改", + "nodeActionDisabled": "节点操作已禁用", + "nodeActionDisabledSubflow": "节点动作在子流程中被禁用", + "missing-types": "流程由于缺少节点类型而停止。请检查日志的详细信息", + "safe-mode": "

流程以安全模式停止。

您可以修改流程并部署更改以重新启动。

", + "restartRequired": "Node-RED必须重新启动,以启用升级的模块", + "credentials_load_failed": "

由于无法解密凭据,因此流程停止。

流程凭据文件已加密,但是项目的加密密钥丢失或无效。

", + "credentials_load_failed_reset": "

凭据无法解密

流凭据文件已加密,但是项目的加密密钥丢失或无效。

流凭据文件将在下一次部署时重置。任何现有的流凭证将被清除。

", + "missing_flow_file": "

找不到项目流程文件。

该项目未配置流程文件。

", + "missing_package_file": "

找不到项目包文件。

项目缺少package.json文件。

", + "project_empty": "

该项目为空。

是否要创建一组默认的项目文件?
否则,您将必须在编辑器外部手动将文件添加到项目中。

", + "project_not_found": "

未找到项目'__project__'。

", + "git_merge_conflict": "

自动合并更改失败。

修复未合并的冲突,然后提交结果。

" + }, + "error": "错误: __message__", + "errors": { + "lostConnection": "丢失与服务器的连接,重新连接...", + "lostConnectionReconnect": "丢失与服务器的连接,__time__秒后重新连接", + "lostConnectionTry": "现在尝试", + "cannotAddSubflowToItself": "无法向其自身添加子流程", + "cannotAddCircularReference": "无法添加子流程 - 循环引用", + "unsupportedVersion": "您正在使用不受支持的Node.js版本
请升级到最新版本的Node.js LTS", + "failedToAppendNode": "

'__module__'加载失败

__error__

" + }, + "project": { + "change-branch": "转到本地分支'__project__'", + "merge-abort": "Git合并中止", + "loaded": "项目'__project__'已加载", + "updated": "项目'__project__'已更新", + "pull": "项目'__project__'已重新加载", + "revert": "项目 '__project__'已还原", + "merge-complete": "Git合并完成", + "setupCredentials": "设定证书", + "setupProjectFiles": "设置项目文件", + "no": "不了,谢谢", + "createDefault": "创建默认项目文件", + "mergeConflict": "显示合并冲突" + }, + "label": { + "manage-project-dep": "管理项目依赖性", + "setup-cred": "设定证书", + "setup-project": "设置项目文件", + "create-default-package": "创建默认的包文件", + "no-thanks": "不了,谢谢", + "create-default-project": "创建默认项目文件", + "show-merge-conflicts": "显示合并冲突" + } + }, + "clipboard": { + "clipboard": "剪贴板", + "nodes": "节点", + "node": "__count__节点", + "node_plural": "__count__节点", + "configNode": "__count__配置节点", + "configNode_plural": "__count__配置节点", + "flow": "__count__流程", + "flow_plural": "__count__流程", + "subflow": "__count__子流程", + "subflow_plural": "__count__子流程", + "pasteNodes": "在这里粘贴节点", + "selectFile": "选择要导入的文件", + "importNodes": "导入节点", + "exportNodes": "导出节点至剪贴板", + "download": "下载", + "importUnrecognised": "导入了无法识别的类型:", + "importUnrecognised_plural": "导入了无法识别的类型:", + "nodesExported": "节点导出到了剪贴板", + "nodesImported": "导入:", + "nodeCopied": "已复制__count__个节点", + "nodeCopied_plural": "已复制__count__个节点", + "invalidFlow": "无效的流程: __message__", + "export": { + "selected": "已选择的节点", + "current": "现在的节点", + "all": "所有流程", + "compact": "紧凑", + "formatted": "已格式化", + "copy": "导出到剪贴板", + "export": "到处到库", + "exportAs": "导出为", + "overwrite": "替换", + "exists": "

\"__file__\"已存在

是否要替换它?

" + }, + "import": { + "import": "导入到", + "newFlow": "新流程", + "errors": { + "notArray": "输入的不是JSON数组", + "itemNotObject": "输入的流无效 - 项目__index__不是节点对象", + "missingId": "输入的流无效-项 __index__ 缺少'id'属性", + "missingType": "输入的流程无效-项__index__缺少'类型'属性" + } + }, + "copyMessagePath": "已复制路径", + "copyMessageValue": "已复制数值", + "copyMessageValue_truncated": "已复制舍弃的数值" + }, + "deploy": { + "deploy": "部署", + "full": "全面", + "fullDesc": "在工作区中部署所有内容", + "modifiedFlows": "已修改的流程", + "modifiedFlowsDesc": "只部署包含已更改节点的流", + "modifiedNodes": "已更改的节点", + "modifiedNodesDesc": "只部署已经更改的节点", + "restartFlows": "重启流程", + "restartFlowsDesc": "重新启动当前部署的流程", + "successfulDeploy": "部署成功", + "successfulRestart": "成功重启流程", + "deployFailed": "部署失败: __message__", + "unusedConfigNodes": "您有一些未使用的配置节点", + "unusedConfigNodesLink": "点击此处查看它们", + "errors": { + "noResponse": "服务器没有响应" + }, + "confirm": { + "button": { + "ignore": "忽略", + "confirm": "确认部署", + "review": "查看更改", + "cancel": "取消", + "merge": "合并", + "overwrite": "忽略 & 部署" + }, + "undeployedChanges": "您有未部署的更改。\n\n离开此页面将丢失这些更改。", + "improperlyConfigured": "工作区包含一些未正确配置的节点:", + "unknown": "工作区包含一些未知的节点类型:", + "confirm": "你确定要部署吗?", + "doNotWarn": "不要再对此发出警告", + "conflict": "服务器正在运行较新的一组流程。", + "backgroundUpdate": "服务器上的流程已更新。", + "conflictChecking": "检查是否可以自动合并更改", + "conflictAutoMerge": "此更改不包括冲突,可以自动合并", + "conflictManualMerge": "这些更改包括了在部署之前必须解决的冲突。", + "plusNMore": "+ __count__更多" + } + }, + "eventLog": { + "title": "事件记录日志", + "view": "查看日志" + }, + "diff": { + "unresolvedCount": "__count__个未解决的冲突", + "unresolvedCount_plural": "__count__个未解决的冲突", + "globalNodes": "全局节点", + "flowProperties": "流程属性", + "type": { + "added": "已添加", + "changed": "已更改", + "unchanged": "未更改", + "deleted": "已删除", + "flowDeleted": "已删除流程", + "flowAdded": "已添加流程", + "movedTo": "移动至__id__", + "movedFrom": "从__id__移动" + }, + "nodeCount": "__count__个节点", + "nodeCount_plural": "__count__个节点", + "local": "本地", + "remote": "远程", + "reviewChanges": "查看变更", + "noBinaryFileShowed": "无法显示二进制文件内容", + "viewCommitDiff": "查看提交更改", + "compareChanges": "比较变更", + "saveConflict": "保存冲突解决", + "conflictHeader": "已解决__unresolved__中的__resolved__个冲突", + "commonVersionError": "通用版本不包含有效的JSON:", + "oldVersionError": "旧版本不包含有效的JSON:", + "newVersionError": "新版本不包含有效的JSON:" + }, + "subflow": { + "editSubflowInstance": "编辑子流实例:__name__", + "editSubflow": "编辑流程模板: __name__", + "edit": "编辑流程模板", + "subflowInstances": "这个子流程模板有__count__个实例", + "subflowInstances_plural": "这个子流程模板有__count__个实例", + "editSubflowProperties": "编辑属性", + "input": "输入:", + "output": "输出:", + "status": "状态节点", + "deleteSubflow": "删除子流程", + "info": "详细描述", + "category": "类别", + "env": { + "restore": "恢复为默认子流", + "remove": "删除环境变量" + }, + "errors": { + "noNodesSelected": "无法创建子流程: 未选择节点", + "multipleInputsToSelection": "无法创建子流程: 多个输入到了选择" + } + }, + "editor": { + "configEdit": "编辑", + "configAdd": "添加", + "configUpdate": "更新", + "configDelete": "删除", + "nodesUse": "__count__个节点使用此配置", + "nodesUse_plural": "__count__个节点使用此配置", + "addNewConfig": "添加新的__type__配置", + "editNode": "编辑__type__节点", + "editConfig": "编辑__type__配置", + "addNewType": "添加新的__type__节点", + "nodeProperties": "节点属性", + "label": "标签", + "color": "颜色", + "portLabels": "端口标签", + "labelInputs": "输入", + "labelOutputs": "输出", + "settingIcon": "图标", + "default": "默认", + "noDefaultLabel": "无", + "defaultLabel": "使用默认标签", + "searchIcons": "搜索图标", + "useDefault": "使用默认", + "description": "描述", + "show": "显示", + "hide": "隐藏", + "locale": "选择界面语言", + "icon": "图标", + "inputType": "输入类型", + "inputs": { + "input": "输入", + "select": "选择", + "checkbox": "复选框", + "spinner": "微调器", + "none": "空", + "hidden": "隐藏属性" + }, + "types": { + "str": "字符串", + "num": "数字", + "bool": "布尔", + "json": "JSON", + "bin": "buffer", + "env": "环境变量" + }, + "menu": { + "input": "输入", + "select": "选择", + "checkbox": "复选框", + "spinner": "微调器", + "hidden": "仅标签" + }, + "select": { + "label": "标签", + "value": "值" + }, + "spinner": { + "min": "最小值", + "max": "最大值" + }, + "errors": { + "scopeChange": "更改范围将使其他流中的节点无法使用", + "invalidProperties": "无效的属性:" + } + }, + "keyboard": { + "title": "键盘快捷键", + "keyboard": "键盘", + "filterActions": "筛选动作", + "shortcut": "快捷键", + "scope": "范围", + "unassigned": "未分配", + "global": "全局", + "workspace": "工作组", + "selectAll": "选择所有节点", + "selectAllConnected": "选择所有连接的节点", + "addRemoveNode": "从选择中添加/删除节点", + "editSelected": "编辑选定节点", + "deleteSelected": "删除选定节点或链接", + "importNode": "导入节点", + "exportNode": "导出节点", + "nudgeNode": "移动所选节点(1px)", + "moveNode": "移动所选节点(20px)", + "toggleSidebar": "切换侧边栏", + "togglePalette": "切换控制板", + "copyNode": "复制所选节点", + "cutNode": "剪切所选节点", + "pasteNode": "粘贴节点", + "undoChange": "撤消上次执行的更改", + "searchBox": "打开搜索框", + "managePalette": "管理面板", + "actionList": "动作列表" + }, + "library": { + "library": "库", + "openLibrary": "打开库...", + "saveToLibrary": "保存到库...", + "typeLibrary": "__type__类型库", + "unnamedType": "无名__type__", + "exportedToLibrary": "节点导出到库", + "dialogSaveOverwrite": "一个叫做__libraryName__的__libraryType__已经存在,您需要覆盖么?", + "invalidFilename": "无效的文件名", + "savedNodes": "保存的节点", + "savedType": "已保存__type__", + "saveFailed": "保存失败: __message__", + "newFolder": "新文件夹", + "types": { + "local": "本地的", + "examples": "例子" + }, + "exportToLibrary": "将节点导出到库" + }, + "palette": { + "noInfo": "无可用信息", + "filter": "过滤节点", + "search": "搜索模块", + "addCategory": "添加新的...", + "label": { + "subflows": "子流程", + "network": "网络", + "common": "共通", + "input": "输入", + "output": "输出", + "function": "功能", + "sequence": "序列", + "parser": "解析", + "social": "社交", + "storage": "存储", + "analysis": "分析", + "advanced": "高级" + }, + "actions": { + "collapse-all": "收起所有类别", + "expand-all": "展开所有类别" + }, + "event": { + "nodeAdded": "添加到面板中的节点:", + "nodeAdded_plural": "添加到面板中的多个节点", + "nodeRemoved": "从面板中删除的节点:", + "nodeRemoved_plural": "从面板中删除的多个节点:", + "nodeEnabled": "启用节点:", + "nodeEnabled_plural": "启用多个节点:", + "nodeDisabled": "禁用节点:", + "nodeDisabled_plural": "禁用多个节点:", + "nodeUpgraded": "节点模块__module__升级到__version__版本" + }, + "editor": { + "title": "面板管理", + "palette": "控制板", + "times": { + "seconds": "秒前", + "minutes": "分前", + "minutesV": "__count__分前", + "hoursV": "__count__小时前", + "hoursV_plural": "__count__小时前", + "daysV": "__count__天前", + "daysV_plural": "__count__天前", + "weeksV": "__count__周前", + "weeksV_plural": "__count__周前", + "monthsV": "__count__月前", + "monthsV_plural": "__count__月前", + "yearsV": "__count__年前", + "yearsV_plural": "__count__年前", + "yearMonthsV": "__y__年, __count__月前", + "yearMonthsV_plural": "__y__年, __count__月前", + "yearsMonthsV": "__y__年, __count__月前", + "yearsMonthsV_plural": "__y__年, __count__月前" + }, + "nodeCount": "__label__个节点", + "nodeCount_plural": "__label__个节点", + "moduleCount": "__count__个可用模块", + "moduleCount_plural": "__count__个可用模块", + "inuse": "使用中", + "enableall": "全部启用", + "disableall": "全部禁用", + "enable": "启用", + "disable": "禁用", + "remove": "移除", + "update": "更新至__version__版本", + "updated": "已更新", + "install": "安装", + "installed": "已安装", + "conflict": "冲突", + "conflictTip": "

无法安装此模块,因为它包含已安装的
节点类型

__module__冲突

", + "loading": "加载目录...", + "tab-nodes": "节点", + "tab-install": "安装", + "sort": "排序:", + "sortAZ": "a-z顺序", + "sortRecent": "日期顺序", + "more": "增加__count__个", + "errors": { + "catalogLoadFailed": "无法加载节点目录。
查看浏览器控制台了解更多信息", + "installFailed": "无法安装: __module__
__message__
查看日志了解更多信息", + "removeFailed": "无法删除: __module__
__message__
查看日志了解更多信息", + "updateFailed": "无法更新: __module__
__message__
查看日志了解更多信息", + "enableFailed": "无法启用: __module__
__message__
查看日志了解更多信息", + "disableFailed": "无法禁用: __module__
__message__
查看日志了解更多信息" + }, + "confirm": { + "install": { + "body": "在安装之前,请阅读节点的文档,某些节点的依赖关系不能自动解决,可能需要重新启动Node-RED。", + "title": "安装节点" + }, + "remove": { + "body": "删除节点将从Node-RED卸载它。节点可能会继续使用资源,直到重新启动Node-RED。", + "title": "删除节点" + }, + "update": { + "body": "更新节点将需要重新启动Node-RED来完成更新,该过程必须由手动完成。", + "title": "更新节点" + }, + "cannotUpdate": { + "body": "此节点的更新可用,但不会安装在面板管理器可以更新的位置。

请参阅有关如何更新此节点的文档。" + }, + "button": { + "review": "打开节点信息", + "install": "安装", + "remove": "删除", + "update": "更新" + } + } + } + }, + "sidebar": { + "info": { + "name": "节点信息", + "tabName": "名称", + "label": "信息", + "node": "节点", + "type": "类型", + "module": "模组", + "id": "ID", + "status": "状态", + "enabled": "启用", + "disabled": "禁用", + "subflow": "子流程", + "instances": "实例", + "properties": "属性", + "info": "信息", + "desc": "描述", + "blank": "空白", + "null": "空", + "showMore": "展开", + "showLess": "收起", + "flow": "流程", + "selection": "选择", + "nodes": "__count__ 个节点", + "flowDesc": "流程描述", + "subflowDesc": "子流程描述", + "nodeHelp": "节点帮助", + "none": "无", + "arrayItems": "__count__个项目", + "showTips": "您可以从设置面板启用提示信息" + }, + "config": { + "name": "配置节点", + "label": "配置", + "global": "所有流程", + "none": "无", + "subflows": "子流程", + "flows": "流程", + "filterAll": "所有", + "showAllConfigNodes": "显示所有配置节点", + "filterUnused": "未使用", + "showAllUnusedConfigNodes": "显示所有未使用的配置节点", + "filtered": "__count__ 个隐藏" + }, + "context": { + "name": "上下文数据", + "label": "上下午", + "none": "未选择", + "refresh": "刷新以加载", + "empty": "空", + "node": "节点", + "flow": "流程", + "global": "全局", + "deleteConfirm": "你确定要删除这个项目吗?", + "autoRefresh": "刷新选择更改", + "refrsh": "刷新", + "delete": "删除" + }, + "palette": { + "name": "节点管理", + "label": "节点" + }, + "project": { + "label": "项目", + "name": "项目", + "description": "描述", + "dependencies": "依赖", + "settings": "设置", + "noSummaryAvailable": "无可用摘要", + "editDescription": "编辑项目描述", + "editDependencies": "编辑项目依赖", + "noDescriptionAvailable": "没有可用的描述", + "editReadme": "编辑README.md", + "showProjectSettings": "显示项目设置", + "projectSettings": { + "title": "项目设置", + "edit": "编辑", + "none": "空", + "install": "安装", + "removeFromProject": "从项目中删除", + "addToProject": "添加到项目", + "files": "文件", + "package": "包", + "flow": "流程", + "credentials": "证书", + "packageCreate": "保存更改后将创建文件", + "fileNotExist": "文件不存在", + "selectFile": "选择文件", + "invalidEncryptionKey": "无效的加密密钥", + "encryptionEnabled": "启用加密", + "encryptionDisabled": "加密已禁用", + "setTheEncryptionKey": "设置加密密钥", + "resetTheEncryptionKey": "重置加密密钥", + "changeTheEncryptionKey": "更改加密密钥", + "currentKey": "当前密钥", + "newKey": "新密钥", + "credentialsAlert": "这将删除所有现有凭证", + "versionControl": "版本控制", + "branches": "分支", + "noBranches": "没有分支", + "deleteConfirm": "您确定要删除本地分支'__name__'吗? 这不能被撤消。", + "unmergedConfirm": "本地分支'__name__'具有未合并的更改,这些更改将丢失。你确定要删除吗?", + "deleteUnmergedBranch": "删除未合并的分支", + "gitRemotes": "Git远程仓库", + "addRemote": "添加远程仓库", + "addRemote2": "添加远程仓库", + "remoteName": "远程仓库名", + "nameRule": "只能包含A-Z 0-9 _ -", + "url": "URL", + "urlRule": "https://, ssh:// or file://", + "urlRule2": "网址中不能包含用户名/密码", + "noRemotes": "没有远程仓库", + "deleteRemoteConfrim": "您确定要删除远程仓库'__name__'吗?", + "deleteRemote": "删除远程仓库" + }, + "userSettings": { + "committerDetail": "提交者详细信息", + "committerTip": "保留空白以使用系统默认值", + "userName": "用户名", + "email": "电子邮件", + "sshKeys": "SSH密钥", + "sshKeysTip": "允许您创建到远程git存储库的安全连接。", + "add": "添加密钥", + "addSshKey": "添加SSH密钥", + "addSshKeyTip": "生成新的公钥/私钥对", + "name": "名字", + "nameRule": "只能包含A-Z 0-9 _ -", + "passphrase": "密码短语", + "passphraseShort": "密码短语过短", + "optional": "可选的", + "cancel": "取消", + "generate": "生成密钥", + "noSshKeys": "没有SSH密钥", + "copyPublicKey": "将公钥复制到剪贴板", + "delete": "删除密钥", + "gitConfig": "Git配置", + "deleteConfirm": "您确定要删除SSH密钥__name__吗?这不能被撤消。" + }, + "versionControl": { + "unstagedChanges": "未暂存的变更", + "stagedChanges": "暂存的变更", + "unstageChange": "取消变更的暂存", + "stageChange": "暂存变更", + "unstageAllChange": "取消所有变更的暂存", + "stageAllChange": "暂存所有变更", + "commitChanges": "提交变更", + "resolveConflicts": "解决冲突", + "head": "HEAD", + "staged": "暂存的", + "unstaged": "未暂存的", + "local": "本地的", + "remote": "远程的", + "revert": "您确定要将更改恢复为'__file__'吗?这不能被撤消。", + "revertChanges": "还原变更", + "localChanges": "本地变更", + "none": "None", + "conflictResolve": "解决所有冲突。提交更改以完成合并。", + "localFiles": "本地文件", + "all": "所有的", + "unmergedChanges": "未合并的更改", + "abortMerge": "中止合并", + "commit": "提交", + "changeToCommit": "提交变更", + "commitPlaceholder": "输入您的提交信息", + "cancelCapital": "取消", + "commitCapital": "提交", + "commitHistory": "提交历史", + "branch": "分支:", + "moreCommits": "更多提交", + "changeLocalBranch": "变更本地分支", + "createBranchPlaceholder": "查找或创建分支", + "upstream": "上游", + "localOverwrite": "切换分支会覆盖您现有的本地更改。您必须先提交或撤消那些更改。", + "manageRemoteBranch": "管理远程分支", + "unableToAccess": "无法访问远程存储库", + "retry": "重试", + "setUpstreamBranch": "设置为上游分支", + "createRemoteBranchPlaceholder": "查找或创建远程分支", + "trackedUpstreamBranch": "创建的分支将被设置为跟踪的上游分支。", + "selectUpstreamBranch": "分支将被创建。 在下面选择以将其设置为被跟踪的上游分支。", + "pushFailed": "推送失败,因为远程具有更多的最新提交。请先拉取并合并,然后再尝试推送。", + "push": "推送", + "pull": "拉取", + "unablePull": "

无法提取远程更改;您未暂存的本地更改将被覆盖。

请先提交更改,然后重试。

", + "showUnstagedChanges": "显示未暂存的更改", + "connectionFailed": "无法连接到远程存储库:", + "pullUnrelatedHistory": "

远程有无关的提交历史

您确定要将这些更改拉入本地仓库吗?

", + "pullChanges": "拉取更改", + "history": "历史", + "projectHistory": "项目历史", + "daysAgo": "__count__天前", + "daysAgo_plural": "__count__天前", + "hoursAgo": "__count__小时前", + "hoursAgo_plural": "__count__小时前", + "minsAgo": "__count__分钟前", + "minsAgo_plural": "__count__分钟前", + "secondsAgo": "秒前", + "notTracking": "您的本地分支当前未跟踪一个远程分支。", + "statusUnmergedChanged": "您的仓库中有未合并的更改。您需要解决冲突并提交结果。", + "repositoryUpToDate": "您的仓库是最新的。", + "commitsAhead": "您的存储库领先远程仓库__count__次提交。您现在可以推送这些提交。", + "commitsAhead_plural": "您的存储库领先远程仓库__count__次提交。您现在可以推送这些提交。", + "commitsBehind": "您的存储库落后远程仓库__count__次提交。您现在可以拉取这些提交。", + "commitsBehind_plural": "您的存储库落后远程仓库__count__次提交。您现在可以拉取这些提交。", + "commitsAheadAndBehind1": "您的存储库落后远程仓库__count__次提交", + "commitsAheadAndBehind1_plural": "您的存储库落后远程仓库__count__次提交", + "commitsAheadAndBehind2": "领先远程仓库__count__次提交。", + "commitsAheadAndBehind2_plural": "领先远程仓库__count__次提交。", + "commitsAheadAndBehind3": "您必须先拉取远程提交,然后才能进行推送。", + "commitsAheadAndBehind3_plural": "您必须先拉取远程提交,然后才能进行推送。", + "refreshCommitHistory": "刷新提交历史", + "refreshChanges": "刷新更改" + } + } + }, + "typedInput": { + "type": { + "str": "文字列", + "num": "数字", + "re": "正则表达式", + "bool": "布尔值", + "json": "JSON", + "bin": "二进制流", + "date": "时间戳", + "jsonata": "表达式", + "env": "环境变量" + } + }, + "editableList": { + "add": "添加" + }, + "search": { + "empty": "找不到匹配", + "addNode": "添加一个节点..." + }, + "expressionEditor": { + "functions": "功能", + "functionReference": "功能reference", + "insert": "插入", + "title": "JSONata表达式编辑器", + "test": "测试", + "data": "示例消息", + "result": "结果", + "format": "格式表达方法", + "compatMode": "兼容模式启用", + "compatModeDesc": "

JSONata的兼容模式

目前的表达式仍然参考msg,所以将以兼容性模式进行评估。请更新表达式,使其不使用msg,因为此模式将在将来删除。

当JSONata支持首次添加到Node-RED时,它需要表达式引用msg对象。例如msg.payload将用于访问有效负载。

这样便不再需要表达式直接针对消息进行评估。要访问有效负载,表达式应该只是payload.

", + "noMatch": "无匹配结果", + "errors": { + "invalid-expr": "无效的JSONata表达式:\n __message__", + "invalid-msg": "无效的示例JSON消息:\n __message__", + "context-unsupported": "无法测试上下文函数\n $flowContext 或 $globalContext", + "eval": "评估表达式错误:\n __message__" + } + }, + "jsEditor": { + "title": "JavaScript编辑器" + }, + "textEditor": { + "title": "文本编辑器" + }, + "jsonEditor": { + "title": "JSON编辑器", + "format": "格式化JSON", + "rawMode": "编辑 JSON", + "uiMode": "Visual编辑器", + "insertAbove": "在上方插入", + "insertBelow": "在下方插入", + "addItem": "添加项目", + "copyPath": "复制路径到项目", + "expandItems": "展开项目", + "collapseItems": "收合项目", + "duplicate": "重复", + "error": { + "invalidJSON": "无效的JSON: " + } + }, + "markdownEditor": { + "title": "Markdown编辑器", + "expand": "展开", + "format": "格式化为markdown", + "heading1": "标题 1", + "heading2": "标题 2", + "heading3": "标题 3", + "bold": "粗体", + "italic": "斜体", + "code": "代码", + "ordered-list": "排序的列表", + "unordered-list": "非排序的列表", + "quote": "引用", + "link": "链接", + "horizontal-rule": "水平线", + "toggle-preview": "切换预览" + }, + "bufferEditor": { + "title": "缓冲区编辑器", + "modeString": "作为UTF-8字符串处理", + "modeArray": "作为JSON数组处理", + "modeDesc": "

缓冲区编辑器

缓冲区类型被存储为字节值的JSON数组。编辑器将尝试将输入的数值解析为JSON数组。如果它不是有效的JSON,它将被视为UTF-8字符串,并被转换为单个字符代码点的数组。

例如,Hello World的值会被转换为JSON数组:

[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

" + }, + "projects": { + "config-git": "配置Git客户端", + "welcome": { + "hello": "你好! 我们已经将“项目”引入了Node-RED。", + "desc0": "这是一种用于管理流程文件的新方法,并且包括对流程的版本控制。", + "desc1": "首先,您可以创建您的第一个项目或从git存储库克隆现有项目。", + "desc2": "如果不确定,可以暂时跳过此步骤。您仍然可以随时通过“项目”菜单创建第一个项目。", + "create": "建立专案", + "clone": "克隆仓库", + "openExistingProject": "打开现有项目", + "not-right-now": "不是现在" + }, + "git-config": { + "setup": "设置您的版本控制客户端", + "desc0": "Node-RED使用开源工具Git进行版本控制。它跟踪对项目文件的更改,并允许您将其推送到远程存储库。", + "desc1": "提交一组更改时,Git会使用用户名和电子邮件地址记录谁进行了更改。用户名可以是您想要的任何名称-不必是您的真实姓名。", + "desc2": "您的Git客户端已经配置了以下详细信息。", + "desc3": "您可以稍后在设置对话框的'Git config'标签下更改这些设置。", + "username": "用户名", + "email": "电子邮件" + }, + "project-details": { + "create": "创建你的项目", + "desc0": "项目被维护为Git仓库。与他人一起共享您的流程", + "desc1": "您可以创建多个项目,并通过编辑器在它们之间快速切换。", + "desc2": "首先,您的项目需要一个名称和一个可选的描述。", + "already-exists": "项目已存在", + "must-contain": "只能包含A-Z 0-9 _ -", + "project-name": "项目名", + "desc": "描述", + "opt": "可选的" + }, + "clone-project": { + "clone": "克隆一个项目", + "desc0": "如果您已经有一个包含项目的git仓库,则可以对其进行克隆以开始使用。", + "already-exists": "项目已存在", + "must-contain": "只能包含A-Z 0-9 _ -", + "project-name": "项目名", + "no-info-in-url": "网址中不要包含用户名/密码", + "git-url": "Git仓库的url", + "protocols": "https://, ssh:// or file://", + "auth-failed": "认证失败", + "username": "用户名", + "passwd": "秘密啊", + "ssh-key": "SSH密钥", + "passphrase": "密码短语", + "ssh-key-desc": "在通过ssh克隆仓库之前,必须添加SSH密钥才能访问它。", + "ssh-key-add": "添加一个ssh密钥", + "credential-key": "证书加密密钥", + "cant-get-ssh-key": "错误! 无法获取所选的SSH密钥路径。", + "already-exists2": "已存在", + "git-error": "git错误", + "connection-failed": "连接失败", + "not-git-repo": "不是一个git仓库", + "repo-not-found": "未发现仓库" + }, + "default-files": { + "create": "创建您的项目文件", + "desc0": "一个包含您的流程文件,Readme文件和package.json文件的项目。", + "desc1": "它可以包含您要在Git仓库中维护的任何其他文件。", + "desc2": "您现有的流程和凭证文件将被复制到项目中。", + "flow-file": "流程文件", + "credentials-file": "证书文件" + }, + "encryption-config": { + "setup": "设置证书文件的加密", + "desc0": "您的流程证书文件可以被加密以确保其内容安全。", + "desc1": "如果要将这些证书存储在公共Git存储库中,则必须通过提供密钥短语来对它们进行加密。", + "desc2": "您的流程证书文件当前未加密。", + "desc3": "这意味着任何有权访问该文件的人都可以读取其内容,例如密码和访问令牌。", + "desc4": "如果要将这些证书存储在公共Git仓库中,则必须通过提供密钥短语来对它们进行加密。", + "desc5": "当前,使用设置文件中的credentialSecret属性作为密钥来加密流程证书文件。", + "desc6": "您的流程证书文件当前使用系统生成的密钥加密。您应该为此项目提供一个新的密钥。", + "desc7": "密钥将与项目文件分开存储。您将需要提供在另一个Node-RED实例中使用该项目的密钥。", + "credentials": "证书", + "enable": "启用加密", + "disable": "禁用加密", + "disabled": "禁用的", + "copy": "复制现有密钥", + "use-custom": "使用自定义密钥", + "desc8": "证书文件不会被加密,其内容很容易阅读", + "create-project-files": "创建项目文件", + "create-project": "创建项目", + "already-exists": "已存在", + "git-error": "git错误", + "git-auth-error": "git认证错误" + }, + "create-success": { + "success": "您已经成功创建了第一个项目!", + "desc0": "现在,您可以像往常一样继续使用Node-RED。", + "desc1": "侧栏中的“信息”标签显示了您当前的活动项目。名称旁边的按钮可用于访问项目设置视图。", + "desc2": "侧栏中的“历史记录”标签可用于查看项目中已更改的文件并提交。它向您显示了提交的完整历史记录,并允许您将更改推送到远程存储库。" + }, + "create": { + "projects": "项目", + "already-exists": "项目已存在", + "must-contain": "只能包含A-Z 0-9 _ -", + "no-info-in-url": "网址中不要包含用户名/密码", + "open": "打开项目", + "create": "创建项目", + "clone": "克隆仓库", + "project-name": "项目名", + "desc": "描述", + "opt": "可选的", + "flow-file": "流程文件", + "credentials": "证书", + "enable-encryption": "启用加密", + "disable-encryption": "禁用加密", + "encryption-key": "加密密钥", + "desc0": "用来保护您的凭证的短语", + "desc1": "凭证文件不会被加密,其内容很容易阅读", + "git-url": "Git存储库URL", + "protocols": "https://, ssh:// or file://", + "auth-failed": "验证失败", + "username": "用户名", + "password": "密码", + "ssh-key": "SSH密钥", + "passphrase": "密码短语", + "desc2": "在通过ssh克隆存储库之前,必须添加SSH密钥才能访问它。", + "add-ssh-key": "添加一个ssh密钥", + "credentials-encryption-key": "证书加密密钥", + "already-exists-2": "已存在", + "git-error": "git错误", + "con-failed": "连接失败", + "not-git": "不是git仓库", + "no-resource": "找不到存储库", + "cant-get-ssh-key-path": "错误!无法获取所选的SSH密钥路径。", + "unexpected_error": "意外的错误" + }, + "delete": { + "confirm": "您确定要删除此项目吗?" + }, + "create-project-list": { + "search": "搜索您的项目", + "current": "当前的" + }, + "require-clean": { + "confirm": "

您有未部署的更改,这些更改将丢失。

您要继续吗?

" + }, + "send-req": { + "auth-req": "存储库需要认证", + "username": "用户名", + "password": "秘密", + "passphrase": "密码短语", + "retry": "重试", + "update-failed": "无法更新身份验证", + "unhandled": "未处理的错误响应" + }, + "create-branch-list": { + "invalid": "无效的分支", + "create": "创建分支", + "current": "当前的" + }, + "create-default-file-set": { + "no-active": "没有活动项目就无法创建默认文件集", + "no-empty": "无法在非空项目上创建默认文件集", + "git-error": "git错误" + }, + "errors": { + "no-username-email": "您的Git客户端未配置用户名/电子邮件。", + "unexpected": "发生了一个意料之外的问题", + "code": "代码" + } + }, + "editor-tab": { + "properties": "属性", + "envProperties": "环境变量", + "description": "描述", + "appearance": "外观", + "preview": "UI预览", + "defaultValue": "默认值" + }, + "languages": { + "de": "德语", + "en-US": "英文", + "ja": "日语", + "ko": "韩文", + "zh-CN": "简体中文", + "zh-TW": "繁体中文" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-CN/infotips.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-CN/infotips.json new file mode 100644 index 0000000..9fe92aa --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-CN/infotips.json @@ -0,0 +1,23 @@ +{ + "info": { + "tip0" : "您可以用 {{core:delete-selection}} 删除选择的节点或链接。", + "tip1" : "{{core:search}} 可以在流程内搜索节点。", + "tip2": "{{core:toggle-sidebar}} 可以显示或隐藏边栏。", + "tip3": "您可以在 {{core:manage-palette}} 中管理节点的控制面板。", + "tip4": "边栏中会列出流程中所有的配置节点。您可以通过菜单或者 {{core:show-config-tab}} 来访问这些节点。", + "tip5": "您可以在设定中选择显示或隐藏这些提示。", + "tip6": "您可以用[left] [up] [down] [right]键来移动被选中的节点。按住[shift]可以更快地移动节点。", + "tip7": "把节点拖到连接上可以向连接中插入节点。", + "tip8": "您可以用 {{core:show-export-dialog}} 来导出被选中的节点或标签页中的流程。", + "tip9": "您可以将流程的json文件拖入编辑框或 {{core:show-import-dialog}} 来导入流程。", + "tip10": "按住[shift]后单击并拖动节点可以将该节点的多个连接一并移动到其他节点的端口。", + "tip11": "{{core:show-info-tab}} 可以显示「信息」标签页。 {{core:show-debug-tab}} 可以显示「调试」标签页。", + "tip12": "按住[ctrl]的同时点击工作界面可以在节点的对话栏中快速添加节点。", + "tip13": "按住[ctrl]的同时点击节点的端口或后续节点可以快速连接多个节点。", + "tip14": "按住[shift]的同时点击节点会选中所有被连接的节点。", + "tip15": "按住[ctrl]的同时点击节点可以在选中或取消选中节点。", + "tip16": "{{core:show-previous-tab}} 和 {{core:show-next-tab}} 可以切换标签页。", + "tip17": "您可以在节点的属性配置画面中通过 {{core:confirm-edit-tray}} 来更改设置,或者用 {{core:cancel-edit-tray}} 来取消更改。", + "tip18": "您可以通过点击 {{core:edit-selected-node}} 来显示被选中节点的属性设置画面。" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-CN/jsonata.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-CN/jsonata.json new file mode 100644 index 0000000..f27ec1f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-CN/jsonata.json @@ -0,0 +1,270 @@ +{ + "$string": { + "args": "arg", + "desc": "通过以下的类型转换规则将参数*arg*转换成字符串:\n\n - 字符串不转换。\n -函数转换成空的字符串。\n - JSON的值无法用数字表示所以用无限大或者NaN(非数)表示。\n - 用’JSON.stringify’函数将其他值转换成JSON字符串。" + }, + "$length": { + "args": "str", + "desc": "输出字符串’str’的字数。如果’str’不是字符串,抛出错误。" + }, + "$substring": { + "args": "str, start[, length]", + "desc": "输出`start`位置后的的首次出现的包括`str`的子字符串。 如果`length`被指定,那么的字符串中将只包括前`length`个文字。如果`start`是负数则输出从`str`末尾开始的`length`个文字" + }, + "$substringBefore": { + "args": "str, chars", + "desc": "输出’str’中首次出现的’chars’之前的子字符串,如果’str’中不包括’chars’则输出’str’。" + }, + "$substringAfter": { + "args": "str, chars", + "desc": "输出’str’中首次出现的’chars’之后的子字符串,如果’str’中不包括’chars’则输出’str’。" + }, + "$uppercase": { + "args": "str", + "desc": "`将’str’中的所有字母变为大写后输出。" + }, + "$lowercase": { + "args": "str", + "desc": "将’str’中的所有字母变为小写后输出。" + }, + "$trim": { + "args": "str", + "desc": "将以下步骤应用于`str`来去除所有空白文字并实现标准化。\n\n – 将全部tab制表符、回车键、换行字符用空白代替。\n- 将连续的空白文字变成一个空白文字。\n- 消除开头和末尾的空白文字。\n\n如果`str`没有被指定(即在无输入参数的情况下调用本函数),将上下文的值作为`str`来使用。 如果`str` 不是字符串则抛出错误。" + }, + "$contains": { + "args": "str, pattern", + "desc": "字符串`str` 和 `pattern`匹配的话输出`true`,不匹配的情况下输出 `false`。 不指定`str`的情况下(比如用一个参数调用本函数时)、将上下文的值作为`str`来使用。参数 `pattern`可以为字符串或正则表达。" + }, + "$split": { + "args": "str[, separator][, limit]", + "desc": "将参数`str`分解成由子字符串组成的数组。 如果`str`不是字符串抛出错误。可以省略的参数 `separator`中指定字符串`str`的分隔符。分隔符可以是文字或正则表达式。在不指定`separator`的情况下、将分隔符看作空的字符串并把`str`拆分成由单个字母组成的数组。如果`separator`不是字符串则抛出错误。在可省略的参数`limit`中指定分割后的子字符串的最大个数。超出个数的子字符串将被舍弃。如果`limit`没有被指定,`str` 将不考虑子字符串的个数而将字符串完全分隔。如果`limit`是负数则抛出错误。" + }, + "$join": { + "args": "array[, separator]", + "desc": "用可以省略的参数 `separator`来把多个字符串连接。如果`array`不是字符串则抛出错误。 如果没有指定`separator`,则用空字符串来连接字符(即字符串之间没有`separator`)。 如果`separator`不是字符则抛出错误。" + }, + "$match": { + "args": "str, pattern [, limit]", + "desc": "对字符串`str`使用正则表达式`pattern`并输出与`str`相匹配的部分信息。" + }, + "$replace": { + "args": "str, pattern, replacement [, limit]", + "desc": "在字符串`str`中搜索`pattern`并用`replacement`来替换。\n\n可选参数`limit`用来指定替换次数的上限。" + }, + "$now": { + "args": "", + "desc": "生成ISO 8601互換格式的时刻,并作为字符串输出。" + }, + "$base64encode": { + "args": "string", + "desc": "将ASCII格式的字符串转换为Base 64格式。将字符串中的文字视作二进制形式的数据处理。包含URI编码在内的字符串文字必须在0x00到0xFF的范围内,否则不会被支持。" + }, + "$base64decode": { + "args": "string", + "desc": "用UTF-8代码页将Base 64形式二进制值转换为字符串。" + }, + "$number": { + "args": "arg", + "desc": "用下述的规则将参数 `arg`转换为数值。:\n\n – 数值不做转换。\n – 将字符串中合法的JSON数値表示转换成数値。\n – 其他形式的值则抛出错误。" + }, + "$abs": { + "args": "number", + "desc": "输出参数`number`的绝对值。" + }, + "$floor": { + "args": "number", + "desc": "输出比`number`的值小的最大整数。" + }, + "$ceil": { + "args": "number", + "desc": "输出比`number`的值大的最小整数。" + }, + "$round": { + "args": "number [, precision]", + "desc": "输出四舍五入后的参数`number`。可省略的参数 `precision`指定四舍五入后小数点下的位数。" + }, + "$power": { + "args": "base, exponent", + "desc": "输出底数`base`的`exponent`次幂。" + }, + "$sqrt": { + "args": "number", + "desc": "输出参数 `number`的平方根。" + }, + "$random": { + "args": "", + "desc": "输出比0大,比1小的伪随机数。" + }, + "$millis": { + "args": "", + "desc": "返回从UNIX时间 (1970年1月1日 UTC/GMT的午夜)开始到现在的毫秒数。在同一个表达式的测试中所有对`$millis()`的调用将会返回相同的值。" + }, + "$sum": { + "args": "array", + "desc": "输出数组`array`的总和。如果`array`不是数值则抛出错误。" + }, + "$max": { + "args": "array", + "desc": "输出数组`array`的最大值。如果`array`不是数值则抛出错误。" + }, + "$min": { + "args": "array", + "desc": "输出数组`array`的最小值。如果`array`不是数值则抛出错误。。" + }, + "$average": { + "args": "array", + "desc": "输出数组`array`的平均数。如果`array`不是数值则抛出错误。。" + }, + "$boolean": { + "args": "arg", + "desc": "用下述规则将数据转换成布尔值。:\n\n - 不转换布尔值`Boolean`。\n – 将空的字符串`string`转换为`false`\n – 将不为空的字符串`string`转换为`true`\n – 将为0的数字`number`转换成`false`\n –将不为0的数字`number`转换成`true`\n –将`null`转换成`false`\n –将空的数组`array`转换成`false`\n –如果数组`array`中含有可以转换成`true`的要素则转换成`true`\n –如果`array`中没有可转换成`true`的要素则转换成`false`\n – 空的对象`object`转换成`false`\n – 非空的对象`object`转换成`true`\n –将函数`function`转换成`false`" + }, + "$not": { + "args": "arg", + "desc": "输出做取反运算后的布尔值。首先将`arg`转换为布尔值。" + }, + "$exists": { + "args": "arg", + "desc": "如果算式`arg`的值存在则输出`true`。如果算式的值不存在(比如指向不存在区域的引用)则输出`false`。" + }, + "$count": { + "args": "array", + "desc": "输出数组中的元素数。" + }, + "$append": { + "args": "array, array", + "desc": "将两个数组连接。" + }, + "$sort": { + "args": "array [, function]", + "desc": "输出排序后的数组`array`。\n\n如果使用了比较函数`function`,则下述两个参数需要被指定。\n\n`function(left, right)`\n\n该比较函数是为了比较left和right两个值而被排序算法调用的。如果用户希望left的值被置于right的值之后,那么该函数必须输出布尔值`true`来表示位置交换。而在不需要位置交换时函数必须输出`false`。" + }, + "$reverse": { + "args": "array", + "desc": "输出倒序后的数组`array`。" + }, + "$shuffle": { + "args": "array", + "desc": "输出随机排序后的数组 `array`。" + }, + "$zip": { + "args": "array, ...", + "desc": "将数组中的值按索引顺序打包后输出。" + }, + "$keys": { + "args": "object", + "desc": "输出由对象内的键组成的数组。如果参数是对象的数组则输出由所有对象中的键去重后组成的队列。" + }, + "$lookup": { + "args": "object, key", + "desc": "输出对象中与参数`key`对应的值。如果第一个参数`object`是数组,那么数组中所有的对象都将被搜索并输出这些对象中与参数`key`对应的值。" + }, + "$spread": { + "args": "object", + "desc": "将对象中的键值对分隔成每个要素中只含有一个键值对的数组。如果参数`object`是数组,那么返回值的数组中包含所有对象中的键值对。" + }, + "$merge": { + "args": "array<object>", + "desc": "将输入数组`objects`中所有的键值对合并到一个`object`中并返回。如果输入数组的要素中含有重复的键,则返回的`object`中将只包含数组中最后出现要素的值。如果输入数组中包括对象以外的元素,则抛出错误。" + }, + "$sift": { + "args": "object, function", + "desc": "输出参数`object`中符合`function`的键值对。\n\n`function`必须含有下述参数。\n\n`function(value [, key [, object]])`" + }, + "$each": { + "args": "object, function", + "desc": "将函数`function`应用于`object`中的所有键值对并输出由所有返回值组成的数组。" + }, + "$map": { + "args": "array, function", + "desc": "将函数`function`应用于数组`array`中所有的值并输出由返回值组成的数组。\n\n`function`中必须含有下述参数。\n\n`function(value [, index [, array]])`" + }, + "$filter": { + "args": "array, function", + "desc": "输出数组`array`中符合函数`function`条件的值组成的数组。\n\n`function`必须包括下述参数。\n\n`function(value [, index [, array]])`" + }, + "$reduce": { + "args": "array, function [, init]", + "desc": "将`function`依次应用于数组中的各要素值。 其中,前一个要素值的计算结果将参与到下一次的函数运算中。。\n\n函数`function`接受两个参数并作为中缀表示法中的操作符。\n\n可省略的参数`init`将作为运算的初始值。" + }, + "$flowContext": { + "args": "string", + "desc": "获取流上下文(流等级的上下文,可以让所有节点共享)的属性。" + }, + "$globalContext": { + "args": "string", + "desc": "获取全局上下文的属性。" + }, + "$pad": { + "args": "string, width [, char]", + "desc": "根据需要,向字符串`string`的副本中填充文字使该字符串的字数达到`width`的绝对值并返回填充文字后的字符串。\n\n如果`width`的值为正,则向字符串`string`的右侧填充文字,如果`width`为负,则向字符串`string`的左侧填充文字。\n\n可选参数`char`用来指定填充的文字。如果未指定该参数,则填充空白文字。" + }, + "$fromMillis": { + "args": "number", + "desc": "将表示从UNIX时间 (1970年1月1日 UTC/GMT的午夜)开始到现在的毫秒数的数值转换成ISO 8601形式时间戳的字符串。" + }, + "$formatNumber": { + "args": "number, picture [, options]", + "desc": "将`number`转换成具有`picture`所指定的数值格式的字符串。\n\n此函数的功能与XPath F&O 3.1规格中定义的XPath/XQuery函数的fn:format-number功能相一致。参数`picture`用于指定数值的转换格式,其语法与fn:format-number中的定义一致。\n\n可选的第三参数`options`用来覆盖默认的局部环境格式,如小数点分隔符。如果指定该参数,那么该参数必须是包含name/value对的对象,并且name/value对必须符合XPath F&O 3.1规格中记述的数值格式。" + }, + "$formatBase": { + "args": "number [, radix]", + "desc": "将`number`变换为以参数`radix`的值为基数形式的字符串。如果不指定`radix`的值,则默认基数为10。指定的`radix`值必须在2~36之间,否则抛出错误。" + }, + "$toMillis": { + "args": "timestamp", + "desc": "将ISO 8601格式的字符串`timestamp`转换为从UNIX时间 (1970年1月1日 UTC/GMT的午夜)开始到现在的毫秒数。如果该字符串的格式不正确,则抛出错误。" + }, + "$env": { + "args": "arg", + "desc": "返回环境变量的值。\n\n这是Node-RED定义的函数。" + }, + "$eval": { + "args": "expr [, context]", + "desc": "使用当前上下文来作为评估依据,分析并评估字符串`expr`,其中包含文字JSON或JSONata表达式。" + }, + "$formatInteger": { + "args": "number, picture", + "desc": "将“数字”转换为字符串,并将其格式化为“图片”字符串指定的整数表示形式。图片字符串参数定义了数字的格式,并具有与XPath F&O 3.1 规范中的fn:format-integer相同的语法。" + }, + "$parseInteger": { + "args": "string, picture", + "desc": "使用“图片”字符串指定的格式将“字符串”参数的内容解析为整数(作为JSON数字)。图片字符串参数与$formatInteger格式相同。." + }, + "$error": { + "args": "[str]", + "desc": "引发错误并显示一条消息。 可选的`str`将替代$error()函数评估的默认消息。" + }, + "$assert": { + "args": "arg, str", + "desc": "如果`arg`为真,则该函数返回。 如果arg为假,则抛出带有str的异常作为异常消息。" + }, + "$single": { + "args": "array, function", + "desc": "返回满足参数function谓语的array参数中的唯一值 (比如:传递值时,函数返回布尔值“true”)。如果匹配值的数量不唯一时,则抛出异常。\n\n应在以下签名中提供函数:`function(value [,index [,array []]])`其中value是数组的每个输入,index是该值的位置,整个数组作为第三个参数传递。" + }, + "$encodeUrl": { + "args": "str", + "desc": "通过用表示字符的UTF-8编码的一个,两个,三个或四个转义序列替换某些字符的每个实例,对统一资源定位符(URL)组件进行编码。\n\n示例:`$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`" + }, + "$encodeUrlComponent": { + "args": "str", + "desc": "通过用表示字符的UTF-8编码的一个,两个,三个或四个转义序列替换某些字符的每个实例,对统一资源定位符(URL)进行编码。\n\n示例: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`" + }, + "$decodeUrl": { + "args": "str", + "desc": "解码以前由encodeUrlComponent创建的统一资源定位器(URL)组件。 \n\n示例: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`" + }, + "$decodeUrlComponent": { + "args": "str", + "desc": "解码先前由encodeUrl创建的统一资源定位符(URL)。 \n\n示例: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`" + }, + "$distinct": { + "args": "array", + "desc": "返回一个数组,其中重复的值已从`数组`中删除" + }, + "$type": { + "args": "value", + "desc": "以字符串形式返回`值`的类型。 如果该`值`未定义,则将返回`未定义`" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-TW/editor.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-TW/editor.json new file mode 100644 index 0000000..897599b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-TW/editor.json @@ -0,0 +1,1015 @@ +{ + "common": { + "label": { + "name": "名稱", + "ok": "確認", + "done": "完成", + "cancel": "取消", + "delete": "刪除", + "close": "關閉", + "load": "讀取", + "save": "保存", + "import": "匯入", + "export": "匯出", + "back": "返回", + "next": "下一步", + "clone": "複製專案", + "cont": "Continue" + }, + "type": { + "string": "字符串", + "number": "數值", + "boolean": "布林", + "array": "數組", + "buffer": "buffer", + "object": "對象", + "jsonString": "JSON字符串", + "undefined": "未定義", + "null": "空" + } + }, + "workspace": { + "defaultName": "流程__number__", + "editFlow": "編輯流程: __name__", + "confirmDelete": "確認刪除", + "delete": "確定想要刪除 '__label__'?", + "dropFlowHere": "把流程放到這裡", + "addFlow": "新增流程", + "listFlows": "流程列表", + "status": "狀態", + "enabled": "有效", + "disabled": "無效", + "info": "詳細描述", + "selectNodes": "點擊節點用於選擇" + }, + "menu": { + "label": { + "view": { + "view": "顯示", + "grid": "格線", + "showGrid": "顯示格線", + "snapGrid": "對齊格線", + "gridSize": "格線尺寸", + "textDir": "文本方向", + "defaultDir": "默認方向", + "ltr": "從左到右", + "rtl": "從右到左", + "auto": "上下文", + "language": "語言", + "browserDefault": "瀏覽器默認" + }, + "sidebar": { + "show": "顯示側邊欄" + }, + "palette": { + "show": "顯示控制板" + }, + "settings": "設置", + "userSettings": "使用者設置", + "nodes": "節點", + "displayStatus": "顯示節點狀態", + "displayConfig": "修改節點配置", + "import": "匯入", + "export": "匯出", + "search": "搜尋流程", + "searchInput": "搜尋流程", + "subflows": "子流程", + "createSubflow": "新建子流程", + "selectionToSubflow": "將選擇部分更改為子流程", + "flows": "流程", + "add": "增加", + "rename": "重新命名", + "delete": "刪除", + "keyboardShortcuts": "鍵盤快速鍵", + "login": "登入", + "logout": "退出", + "editPalette": "節點管理", + "other": "其他", + "showTips": "顯示小提示", + "help": "Node-RED website", + "projects": "專案", + "projects-new": "新專案", + "projects-open": "開啟專案", + "projects-settings": "專案設定", + "showNodeLabelDefault": "顯示新添加節點的標籤" + } + }, + "actions": { + "toggle-navigator": "切換導航器", + "zoom-out": "縮小", + "zoom-reset": "重置縮放", + "zoom-in": "放大" + }, + "user": { + "loggedInAs": "作為__name__登入", + "username": "帳號", + "password": "密碼", + "login": "登入", + "loginFailed": "登入失敗", + "notAuthorized": "未授權", + "errors": { + "settings": "設置資訊需要登入後才能訪問", + "deploy": "改動需要登入後才能部署", + "notAuthorized": "此操作需要登入後才能執行" + } + }, + "notification": { + "warning": "警告: __message__", + "warnings": { + "undeployedChanges": "節點中存在未部署的更改", + "nodeActionDisabled": "節點動作在子流程中被禁用", + "nodeActionDisabledSubflow": "子流程中禁用了節點操作", + "missing-types": "流程由於缺少節點類型而停止。請檢查日誌的詳細資訊", + "safe-mode": "

流程在安全模式下停止。

您可以修改流程並部署更改以重新啟動。

", + "restartRequired": "Node-RED必須重新啟動,以啟用升級的模組", + "credentials_load_failed": "

流程由於無法解密證書而停止。

流程證書文件已加密,但是項目的加密密鑰丟失或無效。

", + "credentials_load_failed_reset": "

證書無法解密

流程證書文件已加密,但是項目的加密密鑰丟失或無效。

流程證書文件將在下一次部署時重置。任何現有的流程證書將被清除。

", + "missing_flow_file": "

找不到項目流程文件。

該項目未配置流程文件。

", + "missing_package_file": "

找不到項目包文件。

項目缺少package.json文件。

", + "project_empty": "

該項目為空。

是否要創建一組默認的項目文件?
否則,您將不得不在編輯器外部手動將文件添加到項目中。

", + "project_not_found": "

找不到項目的'__project__'

", + "git_merge_conflict": "

自動合併更改失敗。

修復未合併的衝突,然後提交結果。

" + }, + "error": "Error: __message__", + "errors": { + "lostConnection": "丟失與伺服器的連接,重新連接...", + "lostConnectionReconnect": "丟失與伺服器的連接,__time__秒後重新連接", + "lostConnectionTry": "現在嘗試", + "cannotAddSubflowToItself": "無法向其自身添加子流程", + "cannotAddCircularReference": "無法添加子流程 - 迴圈引用", + "unsupportedVersion": "您正在使用不受支持的Node.js版本
請升級到最新版本的Node.js LTS", + "failedToAppendNode": "

加載'__module__'失敗

__error__

" + }, + "project": { + "change-branch": "轉到本地分支'__project__'", + "merge-abort": "Git合併中止", + "loaded": "已加載項目'__project__'", + "updated": "已更新項目'__project__'", + "pull": "已重新加載項目'__project__'", + "revert": "項目“__project__”已還原", + "merge-complete": "Git合併完成", + "setupCredentials": "設定證書", + "setupProjectFiles": "設置項目文件", + "no": "不了,謝謝", + "createDefault": "創建默認項目文件", + "mergeConflict": "顯示合併衝突" + }, + "label": { + "manage-project-dep": "管理項目依賴性", + "setup-cred": "設定憑證", + "setup-project": "設置項目文件", + "create-default-package": "創建默認的包文件", + "no-thanks": "不了,謝謝", + "create-default-project": "創建默認項目文件", + "show-merge-conflicts": "顯示合併衝突" + } + }, + "clipboard": { + "clipboard": "剪貼簿", + "nodes": "節點", + "node": "__count__ 節點", + "node_plural": "__count__ 多個節點", + "configNode": "__count__ 節點組態", + "configNode_plural": "__count__ 多節點組態", + "flow": "__count__ 流程", + "flow_plural": "__count__ 多流程", + "subflow": "__count__ 子流程", + "subflow_plural": "__count__ 多子流程", + "pasteNodes": "在這裡粘貼節點", + "selectFile": "匯入所選檔案", + "importNodes": "匯入節點", + "exportNodes": "匯出節點至剪貼簿", + "download": "下載", + "importUnrecognised": "匯入了無法識別的類型:", + "importUnrecognised_plural": "匯入了無法識別的類型:", + "nodesExported": "節點匯出到了剪貼簿", + "nodesImported": "已匯入:", + "nodeCopied": "已複製__count__個節點", + "nodeCopied_plural": "已複製__count__個節點", + "invalidFlow": "無效的流程: __message__", + "export": { + "selected": "已選擇的節點", + "current": "現在的節點", + "all": "所有流程", + "compact": "緊湊", + "formatted": "已格式化", + "copy": "匯出到剪貼簿", + "export": "匯出到庫", + "exportAs": "匯出為", + "overwrite": "取代", + "exists": "

\"__file__\" 已經存在.

是否要取代?

" + }, + "import": { + "import": "匯入到", + "newFlow": "新流程", + "errors": { + "notArray": "輸入的不是JSON數組", + "itemNotObject": "輸入的流程無效-項目__index__不是節點對象", + "missingId": "輸入的流程無效-項__index__缺少“ id”屬性", + "missingType": "輸入的流程無效-項__index__缺少“類型”屬性" + } + }, + "copyMessagePath": "已複製路徑", + "copyMessageValue": "已複製數值", + "copyMessageValue_truncated": "已複製捨棄的數值" + }, + "deploy": { + "deploy": "部署", + "full": "全面", + "fullDesc": "在工作區中部署所有內容", + "modifiedFlows": "已修改的流程", + "modifiedFlowsDesc": "只部署包含已更改節點的流程", + "modifiedNodes": "已更改的節點", + "modifiedNodesDesc": "只部署已經更改的節點", + "restartFlows": "重新啟動流程", + "restartFlowsDesc": "重新啟動當前部署的流程", + "successfulDeploy": "部署成功", + "successfulRestart": "成功重啟流程", + "deployFailed": "部署失敗: __message__", + "unusedConfigNodes": "您有一些未使用的配置節點", + "unusedConfigNodesLink": "點擊此處查看它們", + "errors": { + "noResponse": "伺服器沒有回應" + }, + "confirm": { + "button": { + "ignore": "忽略", + "confirm": "確認部署", + "review": "查看更改", + "cancel": "取消", + "merge": "合併", + "overwrite": "忽略 & 部署" + }, + "undeployedChanges": "您有未部署的更改。\n\n離開此頁面將丟失這些更改。", + "improperlyConfigured": "工作區包含一些未正確配置的節點:", + "unknown": "工作區包含一些未知的節點類型:", + "confirm": "確定要部署嗎?", + "doNotWarn": "不要再對此發出警告", + "conflict": "伺服器正在運行較新的一組流程。", + "backgroundUpdate": "伺服器上的流程已更新。", + "conflictChecking": "檢查是否可以自動合併更改", + "conflictAutoMerge": "此更改不包括衝突,可以自動合併", + "conflictManualMerge": "這些更改包括了在部署之前必須解決的衝突。", + "plusNMore": "+更多的__count__" + } + }, + "eventLog": { + "title": "事件日誌", + "view": "查看日誌" + }, + "diff": { + "unresolvedCount": "__count__個未解決的衝突", + "unresolvedCount_plural": "__count__個未解決的衝突", + "globalNodes": "全局節點", + "flowProperties": "流程屬性", + "type": { + "added": "已添加", + "changed": "已更改", + "unchanged": "未更改", + "deleted": "已刪除", + "flowDeleted": "已刪除流程", + "flowAdded": "已添加流程", + "movedTo": "移動至__id__", + "movedFrom": "從__id__移動" + }, + "nodeCount": "__count__個節點", + "nodeCount_plural": "__count__個節點", + "local": "本地", + "remote": "遠端", + "reviewChanges": "查看變更", + "noBinaryFileShowed": "無法顯示二進製文件內容", + "viewCommitDiff": "查看提交更改", + "compareChanges": "比較變更", + "saveConflict": "保存衝突解決", + "conflictHeader": "已解決__unresolved__中的__resolved__個衝突", + "commonVersionError": "通用版本不包含有效的JSON:", + "oldVersionError": "舊版本不包含有效的JSON:", + "newVersionError": "新版本不包含有效的JSON:" + }, + "subflow": { + "editSubflowInstance": "編輯子流程實例:__name__", + "editSubflow": "編輯流程範本: __name__", + "edit": "編輯流程範本", + "subflowInstances": "這個子流程範本有__count__個實例", + "subflowInstances_plural": "這個子流程範本有__count__個實例", + "editSubflowProperties": "編輯屬性", + "input": "輸入:", + "output": "輸出:", + "status": "狀態節點", + "deleteSubflow": "刪除子流程", + "info": "詳細描述", + "category": "類別", + "env": { + "restore": "恢復為默認子流程", + "remove": "類別刪除環境變量" + }, + "errors": { + "noNodesSelected": "無法創建子流程: 未選擇節點", + "multipleInputsToSelection": "無法創建子流程: 多個輸入到了選擇" + } + }, + "editor": { + "configEdit": "編輯", + "configAdd": "添加", + "configUpdate": "更新", + "configDelete": "刪除", + "nodesUse": "__count__個節點使用此配置", + "nodesUse_plural": "__count__個節點使用此配置", + "addNewConfig": "添加新的__type__配置", + "editNode": "編輯__type__節點", + "editConfig": "編輯__type__配置", + "addNewType": "添加新的__type__節點", + "nodeProperties": "節點屬性", + "label": "Label", + "color": "顏色", + "portLabels": "埠標籤", + "labelInputs": "輸入", + "labelOutputs": "輸出", + "settingIcon": "Icon", + "default": "默認", + "noDefaultLabel": "無", + "defaultLabel": "使用默認標籤", + "searchIcons": "搜尋圖標", + "useDefault": "使用默認", + "description": "描述", + "show": "顯示", + "hide": "隱藏", + "locale": "選擇界面語言", + "icon": "圖標", + "inputType": "輸入類型", + "inputs": { + "input": "輸入", + "select": "選擇", + "checkbox": "復選框", + "spinner": "微調器", + "none": "空", + "hidden": "隱藏屬性" + }, + "types": { + "str": "字符串", + "num": "數字", + "bool": "布爾", + "json": "JSON", + "bin": "buffer", + "env": "環境變量" + }, + "menu": { + "input": "輸入", + "select": "選擇", + "checkbox": "復選框", + "spinner": "微調器", + "hidden": "僅標簽" + }, + "select": { + "label": "標簽", + "value": "值" + }, + "spinner": { + "min": "最小值", + "max": "最大值" + }, + "errors": { + "scopeChange": "更改範圍將使其他流程中的節點無法使用", + "invalidProperties": "無效的屬性:" + } + }, + "keyboard": { + "title": "鍵盤快速鍵", + "keyboard": "鍵盤", + "filterActions": "篩選動作", + "shortcut": "快捷鍵", + "scope": "範圍", + "unassigned": "未分配", + "global": "全局", + "workspace": "工作區", + "selectAll": "選擇所有節點", + "selectAllConnected": "選擇所有連接的節點", + "addRemoveNode": "從選擇中添加/刪除節點", + "editSelected": "編輯選定節點", + "deleteSelected": "刪除選定節點或連結", + "importNode": "匯入節點", + "exportNode": "匯出節點", + "nudgeNode": "移動所選節點(1px)", + "moveNode": "移動所選節點(20px)", + "toggleSidebar": "切換側邊欄", + "togglePalette": "切換調色板", + "copyNode": "複製所選節點", + "cutNode": "剪切所選節點", + "pasteNode": "粘貼節點", + "undoChange": "撤銷上次執行的更改", + "searchBox": "打開搜尋框", + "managePalette": "管理面板", + "actionList": "動作列表" + }, + "library": { + "library": "庫", + "openLibrary": "打開庫...", + "saveToLibrary": "保存到庫...", + "typeLibrary": "__type__型別程式庫", + "unnamedType": "無名__type__", + "exportedToLibrary": "節點導出到庫", + "dialogSaveOverwrite": "一個叫做__libraryName__的__libraryType__已經存在,您需要覆蓋麼?", + "invalidFilename": "無效的檔案名", + "savedNodes": "保存的節點", + "savedType": "已保存__type__", + "saveFailed": "保存失敗: __message__", + "newFolder": "新文件夾", + "types": { + "local": "本地", + "examples": "例子" + }, + "exportToLibrary": "將節點匯出到庫" + }, + "palette": { + "noInfo": "無可用資訊", + "filter": "過濾節點", + "search": "搜尋模組", + "addCategory": "添加新的...", + "label": { + "subflows": "子流程", + "network": "網絡", + "common": "共通", + "input": "輸入", + "output": "輸出", + "function": "功能", + "sequence": "序列", + "parser": "解析", + "social": "社交", + "storage": "存儲", + "analysis": "分析", + "advanced": "高級" + }, + "actions": { + "collapse-all": "收起所有類別", + "expand-all": "展開所有類別" + }, + "event": { + "nodeAdded": "添加到面板中的節點:", + "nodeAdded_plural": "添加到面板中的多個節點", + "nodeRemoved": "從面板中刪除的節點:", + "nodeRemoved_plural": "從面板中刪除的多個節點:", + "nodeEnabled": "啟用節點:", + "nodeEnabled_plural": "啟用多個節點:", + "nodeDisabled": "禁用節點:", + "nodeDisabled_plural": "禁用多個節點:", + "nodeUpgraded": "節點模組__module__升級到__version__版本" + }, + "editor": { + "title": "面板管理", + "palette": "Palette", + "times": { + "seconds": "秒前", + "minutes": "分前", + "minutesV": "__count__分前", + "hoursV": "__count__小時前", + "hoursV_plural": "__count__小時前", + "daysV": "__count__天前", + "daysV_plural": "__count__天前", + "weeksV": "__count__周前", + "weeksV_plural": "__count__周前", + "monthsV": "__count__月前", + "monthsV_plural": "__count__月前", + "yearsV": "__count__年前", + "yearsV_plural": "__count__年前", + "yearMonthsV": "__y__年, __count__月前", + "yearMonthsV_plural": "__y__年, __count__月前", + "yearsMonthsV": "__y__年, __count__月前", + "yearsMonthsV_plural": "__y__年, __count__月前" + }, + "nodeCount": "__label__個節點", + "nodeCount_plural": "__label__個節點", + "moduleCount": "__count__個可用模組", + "moduleCount_plural": "__count__個可用模組", + "inuse": "使用中", + "enableall": "全部啟用", + "disableall": "全部禁用", + "enable": "啟用", + "disable": "禁用", + "remove": "移除", + "update": "更新至__version__版本", + "updated": "已更新", + "install": "安裝", + "installed": "已安裝", + "conflict": "conflict", + "conflictTip": "

無法安裝此模塊,因為它包含已安裝的
節點類型

__module__衝突

", + "loading": "載入目錄...", + "tab-nodes": "節點", + "tab-install": "安裝", + "sort": "排序:", + "sortAZ": "a-z順序", + "sortRecent": "日期順序", + "more": "增加__count__個", + "errors": { + "catalogLoadFailed": "無法載入節點目錄。
查看瀏覽器控制臺瞭解更多資訊", + "installFailed": "無法安裝: __module__
__message__
查看日誌瞭解更多資訊", + "removeFailed": "無法刪除: __module__
__message__
查看日誌瞭解更多資訊", + "updateFailed": "無法更新: __module__
__message__
查看日誌瞭解更多資訊", + "enableFailed": "無法啟用: __module__
__message__
查看日誌瞭解更多資訊", + "disableFailed": "無法禁用: __module__
__message__
查看日誌瞭解更多資訊" + }, + "confirm": { + "install": { + "body": "在安裝之前,請閱讀節點的文檔,某些節點的依賴關係不能自動解決,可能需要重新啟動Node-RED。", + "title": "安裝節點" + }, + "remove": { + "body": "刪除節點將從Node-RED卸載它。節點可能會繼續使用資源,直到重新啟動Node-RED。", + "title": "刪除節點" + }, + "update": { + "body": "更新節點將需要重新啟動Node-RED來完成更新,該過程必須由手動完成。", + "title": "更新節點" + }, + "cannotUpdate": { + "body": "此節點的更新可用,但不會安裝在面板管理器可以更新的位置。

請參閱有關如何更新此節點的文檔。" + }, + "button": { + "review": "打開節點資訊", + "install": "安裝", + "remove": "刪除", + "update": "更新" + } + } + } + }, + "sidebar": { + "info": { + "name": "節點信息", + "tabName": "名稱", + "label": "信息", + "node": "節點", + "type": "類型", + "module": "Module", + "id": "ID", + "status": "狀態", + "enabled": "啟用", + "disabled": "禁用", + "subflow": "子流程", + "instances": "實例", + "properties": "屬性", + "info": "信息", + "desc": "描述", + "blank": "空白", + "null": "空", + "showMore": "展開", + "showLess": "收起", + "flow": "流程", + "selection": "選擇", + "nodes": "__count__ 個節點", + "flowDesc": "流程描述", + "subflowDesc": "子流程描述", + "nodeHelp": "節點幫助", + "none": "無", + "arrayItems": "__count__個項目", + "showTips": "您可以從設置面板啟用提示資訊" + }, + "config": { + "name": "配置節點", + "label": "配置", + "global": "所有流程", + "none": "無", + "subflows": "子流程", + "flows": "流程", + "filterAll": "所有", + "showAllConfigNodes": "顯示所有配置節點", + "filterUnused": "未使用", + "showAllUnusedConfigNodes": "顯示所有未使用的配置節點", + "filtered": "__count__ 個隱藏" + }, + "context": { + "name": "上下文數據", + "label": "上下文", + "none": "未選擇", + "refresh": "刷新以加載", + "empty": "空", + "node": "節點", + "flow": "流程", + "global": "全局的", + "deleteConfirm": "你確定要刪除這個項目嗎?", + "autoRefresh": "自動刷新", + "refrsh": "刷新", + "delete": "刪除" + }, + "palette": { + "name": "節點管理", + "label": "節點" + }, + "project": { + "label": "項目", + "name": "名稱", + "description": "描述", + "dependencies": "依賴", + "settings": "設置", + "noSummaryAvailable": "無可用摘要", + "editDescription": "編輯專案描述", + "editDependencies": "編輯項目依賴", + "noDescriptionAvailable": "沒有可用的描述", + "editReadme": "Edit README.md", + "showProjectSettings": "顯示項目設置", + "projectSettings": { + "title": "項目設定", + "edit": "編輯", + "none": "None", + "install": "安裝", + "removeFromProject": "從項目中刪除", + "addToProject": "添加到項目", + "files": "文件", + "package": "包", + "flow": "流程", + "credentials": "證書", + "packageCreate": "保存更改後將創建文件", + "fileNotExist": "文件不存在", + "selectFile": "選擇文件", + "invalidEncryptionKey": "無效的加密密鑰", + "encryptionEnabled": "啟用加密", + "encryptionDisabled": "禁用加密", + "setTheEncryptionKey": "設置加密密鑰", + "resetTheEncryptionKey": "重置加密密鑰", + "changeTheEncryptionKey": "更改加密密鑰", + "currentKey": "當前密鑰", + "newKey": "新密鑰", + "credentialsAlert": "這將刪除所有現有證書", + "versionControl": "版本控制", + "branches": "分支", + "noBranches": "沒有分支", + "deleteConfirm": "您確定要刪除本地分支'__name__'嗎?這不能被撤消。", + "unmergedConfirm": "本地分支'__name__'具有未合併的更改,這些更改將丟失。你確定要刪除嗎?", + "deleteUnmergedBranch": "刪除未合併的分支", + "gitRemotes": "Git遠程倉庫", + "addRemote": "添加遠程倉庫", + "addRemote2": "添加遠程倉庫", + "remoteName": "遠程倉庫名", + "nameRule": "必須僅包含A-Z 0-9 _ -", + "url": "URL", + "urlRule": "https://, ssh:// or file://", + "urlRule2": "網址中不要包含用戶名/密碼", + "noRemotes": "沒有遠程倉庫", + "deleteRemoteConfrim": "確定要刪除遠程倉庫'__name__'嗎?", + "deleteRemote": "刪除遠程倉庫" + }, + "userSettings": { + "committerDetail": "提交者詳細信息", + "committerTip": "保留空白以使用系統默認值", + "userName": "用戶名", + "email": "電子郵件", + "sshKeys": "SSH密鑰", + "sshKeysTip": "允許您創建到遠程git存儲庫的安全連接。", + "add": "添加密鑰", + "addSshKey": "添加SSH密鑰", + "addSshKeyTip": "生成新的公鑰/私鑰對", + "name": "名字", + "nameRule": "必須僅包含A-Z 0-9 _ -", + "passphrase": "密碼短語", + "passphraseShort": "密碼短語太短", + "optional": "可選的", + "cancel": "取消", + "generate": "產生密鑰", + "noSshKeys": "沒有SSH密鑰", + "copyPublicKey": "將公鑰複製到剪貼板", + "delete": "刪除密鑰", + "gitConfig": "Git配置", + "deleteConfirm": "您確定要刪除SSH密鑰__name__嗎? 這不能被撤消。" + }, + "versionControl": { + "unstagedChanges": "未暫存的更改", + "stagedChanges": "已暫存的更改", + "unstageChange": "取消暫存更改", + "stageChange": "暫存更改", + "unstageAllChange": "取消暫存所有更改", + "stageAllChange": "暫存所有更改", + "commitChanges": "提交變更", + "resolveConflicts": "解決衝突", + "head": "HEAD", + "staged": "以暫存", + "unstaged": "未暫存", + "local": "本地的", + "remote": "遠程的", + "revert": "您確定要將更改恢復為'__file__'嗎? 這不能被撤消。", + "revertChanges": "還原變更", + "localChanges": "當地變化", + "none": "None", + "conflictResolve": "解決所有衝突。 提交更改以完成合併。", + "localFiles": "本地文件", + "all": "所有的", + "unmergedChanges": "未合併的更改", + "abortMerge": "合併中止", + "commit": "提交", + "changeToCommit": "提交變更", + "commitPlaceholder": "輸入您的提交信息", + "cancelCapital": "取消", + "commitCapital": "提交", + "commitHistory": "提交歷史", + "branch": "分支:", + "moreCommits": "更多提交", + "changeLocalBranch": "變更當地分支", + "createBranchPlaceholder": "查找或創建分支", + "upstream": "上遊的", + "localOverwrite": "您有可通過切換分支覆蓋的本地更改。您必須先提交或撤銷那些更改。", + "manageRemoteBranch": "管理遠程分支", + "unableToAccess": "無法訪問遠程存儲庫", + "retry": "重試", + "setUpstreamBranch": "設置為上遊分支", + "createRemoteBranchPlaceholder": "查找或創建遠程分支", + "trackedUpstreamBranch": "創建的分支將被設置為跟蹤的上遊分支。", + "selectUpstreamBranch": "分支將被創建。 在下面選擇以將其設置為被跟蹤的上遊分支。", + "pushFailed": "Push失敗,因為遠程具有更多的最新提交。請先進行pull與merge,然後再嘗試push。", + "push": "push", + "pull": "pull", + "unablePull": "

無法提取遠程更改;您未進行的暫存本地更改將被覆蓋。

提交更改,然後重試。

", + "showUnstagedChanges": "顯示未分階段的更改", + "connectionFailed": "無法連接到遠程存儲庫:", + "pullUnrelatedHistory": "

遠程服務器具有不相關的提交歷史記錄。

您確定要將更改保存到本地存儲庫中嗎?

", + "pullChanges": "Pull變更", + "history": "歷史", + "projectHistory": "項目歷史", + "daysAgo": "__count__天前", + "daysAgo_plural": "__count__天前", + "hoursAgo": "__count__小時前", + "hoursAgo_plural": "__count__小時前", + "minsAgo": "__count__分鐘前", + "minsAgo_plural": "__count__分鐘前", + "secondsAgo": "秒前", + "notTracking": "您的本地分支當前未跟蹤遠程分支。", + "statusUnmergedChanged": "您的存儲庫中有未合併的更改。您需要解決衝突並提交結果。", + "repositoryUpToDate": "您的存儲庫是最新的。", + "commitsAhead": "您的倉庫領先遠程倉庫__count__次提交。您現在可以push這些提交。", + "commitsAhead_plural": "您的倉庫領先遠程倉庫__count__次提交。您現在可以push這些提交。", + "commitsBehind": "您的倉庫落後遠程倉庫__count__次提交。您現在可以pull這些提交。", + "commitsBehind_plural": "您的倉庫落後遠程倉庫__count__次提交。您現在可以pull這些提交。", + "commitsAheadAndBehind1": "您的倉庫落後遠程倉庫__count__次提交", + "commitsAheadAndBehind1_plural": "您的倉庫落後遠程倉庫__count__次提交", + "commitsAheadAndBehind2": "領先遠程倉庫__count__次提交。", + "commitsAheadAndBehind2_plural": "領先遠程倉庫__count__次提交。", + "commitsAheadAndBehind3": "您必須先pull遠程提交,然後再進行push。", + "commitsAheadAndBehind3_plural": "您必須先pull遠程提交,然後再進行push。", + "refreshCommitHistory": "刷新提交歷史", + "refreshChanges": "刷新更改" + } + } + }, + "typedInput": { + "type": { + "str": "文字列", + "num": "數字", + "re": "規則運算式", + "bool": "布林", + "json": "JSON", + "bin": "二進位流", + "date": "時間戳記", + "jsonata": "expression", + "env": "env variable" + } + }, + "editableList": { + "add": "添加" + }, + "search": { + "empty": "找不到匹配", + "addNode": "添加一個節點..." + }, + "expressionEditor": { + "functions": "功能", + "functionReference": "Function reference", + "insert": "插入", + "title": "JSONata運算式編輯器", + "test": "Test", + "data": "示例消息", + "result": "結果", + "format": "格式表達方法", + "compatMode": "相容模式啟用", + "compatModeDesc": "

JSONata的相容模式

目前的運算式仍然參考msg,所以將以相容性模式進行評估。請更新運算式,使其不使用msg,因為此模式將在將來刪除。

當JSONata支持首次添加到Node-RED時,它需要運算式引用msg物件。例如msg.payload將用於訪問有效負載。

這樣便不再需要運算式直接針對消息進行評估。要訪問有效負載,運算式應該只是payload.

", + "noMatch": "無匹配結果", + "errors": { + "invalid-expr": "無效的JSONata運算式:\n __message__", + "invalid-msg": "無效的示例JSON消息:\n __message__", + "context-unsupported": "無法測試上下文函數\n $flowContext 或 $globalContext", + "eval": "評估運算式錯誤:\n __message__" + } + }, + "jsEditor": { + "title": "JavaScript 編輯器" + }, + "textEditor": { + "title": "Text 編輯器" + }, + "jsonEditor": { + "title": "JSON編輯器", + "format": "格式化JSON", + "rawMode": "編輯 JSON", + "uiMode": "Visual編輯器", + "insertAbove": "在上方插入", + "insertBelow": "在下方插入", + "addItem": "添加項目", + "copyPath": "復制路徑到項目", + "expandItems": "展開項目", + "collapseItems": "收合項目", + "duplicate": "重復", + "error": { + "invalidJSON": "無效的JSON: " + } + }, + "markdownEditor": { + "title": "Markdown 編輯器", + "expand": "展開", + "format": "F使用markdown格式化", + "heading1": "Heading 1", + "heading2": "Heading 2", + "heading3": "Heading 3", + "bold": "粗體", + "italic": "斜體", + "code": "程式碼", + "ordered-list": "編號清單", + "unordered-list": "符號清單", + "quote": "引用", + "link": "連結", + "horizontal-rule": "分隔線", + "toggle-preview": "預覽" + }, + "bufferEditor": { + "title": "緩衝區編輯器", + "modeString": "作為UTF-8字串處理", + "modeArray": "作為JSON陣列處理", + "modeDesc": "

緩衝區編輯器

緩衝區類型被存儲為位元組值的JSON陣列。編輯器將嘗試將輸入的數值解析為JSON陣列。如果它不是有效的JSON,它將被視為UTF-8字串,並被轉換為單個字元代碼點的陣列。

例如,Hello World的值會被轉換為JSON陣列:

[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

" + }, + "projects": { + "config-git": "配置Git客戶端", + "welcome": { + "hello": "你好! 我們已經將“項目”引入了Node-RED。", + "desc0": "這是一種用於管理流程文件的新方法,並且包括對流程的版本控制。", + "desc1": "首先,您可以創建您的第一個項目或從git存儲庫克隆現有項目。", + "desc2": "如果不確定,可以暫時跳過此步驟。 您仍然可以隨時通過“項目”菜單創建第一個項目。", + "create": "創建項目", + "clone": "克隆存儲庫", + "openExistingProject": "打開現有項目", + "not-right-now": "不是現在" + }, + "git-config": { + "setup": "設置您的版本控制客戶端", + "desc0": "Node-RED使用開源工具Git進行版本控制。 它跟蹤對項目文件的更改,並允許您將其推送到遠程存儲庫。", + "desc1": "提交一組更改時,Git會使用用戶名和電子郵件地址記錄誰進行了更改。 用戶名可以是您想要的任何名稱-不必是您的真實姓名。", + "desc2": "您的Git客戶端已經配置了以下詳細信息。", + "desc3": "您可以稍後在設置對話框的“ Git config”標籤下更改這些設置。", + "username": "用戶名", + "email": "電子郵件" + }, + "project-details": { + "create": "創建您的項目", + "desc0": "項目被維護為Git存儲庫。 與他人共享您的流程並進行協作更容易。", + "desc1": "您可以創建多個項目,並通過編輯器在它們之間快速切換。", + "desc2": "首先,您的項目需要一個名稱和一個可選的描述。", + "already-exists": "項目已存在", + "must-contain": "必須僅包含A-Z 0-9 _ -", + "project-name": "項目名", + "desc": "描述", + "opt": "可選的" + }, + "clone-project": { + "clone": "克隆項目", + "desc0": "如果您已經有一個包含項目的git存儲庫,則可以對其進行克隆以開始使用。", + "already-exists": "項目已經存在", + "must-contain": "必須僅包含A-Z 0-9 _ -", + "project-name": "項目名", + "no-info-in-url": "網址中不要包含用戶名/密碼", + "git-url": "Git存儲庫URL", + "protocols": "https://, ssh:// or file://", + "auth-failed": "驗證失敗", + "username": "用戶名", + "passwd": "密碼", + "ssh-key": "SSH密鑰", + "passphrase": "密碼短語", + "ssh-key-desc": "在通過ssh克隆存儲庫之前,必須添加SSH密鑰才能訪問它。", + "ssh-key-add": "添加一個ssh密鑰", + "credential-key": "證書加密密鑰", + "cant-get-ssh-key": "錯誤! 無法獲取所選的SSH密鑰路徑。", + "already-exists2": "已存在", + "git-error": "git錯誤", + "connection-failed": "連接失敗", + "not-git-repo": "不是一個git倉庫", + "repo-not-found": "未發現倉庫" + }, + "default-files": { + "create": "創建您的項目文件", + "desc0": "一個項目包含您的流程文件,自述文件和package.json文件。", + "desc1": "它可以包含您要在Git存儲庫中維護的任何其他文件。", + "desc2": "您現有的流程和證書文件將被複製到項目中。", + "flow-file": "流文件", + "credentials-file": "證書文件" + }, + "encryption-config": { + "setup": "設置證書文件的加密", + "desc0": "您的流程證書文件可以被加密以確保其內容安全。", + "desc1": "如果要將這些證書存儲在公共Git存儲庫中,則必須通過提供密鑰短語來對它們進行加密。", + "desc2": "您的流程證書文件當前未加密。", + "desc3": "這意味著任何有權訪問該文件的人都可以讀取其內容,例如密碼和訪問令牌。", + "desc4": "如果要將這些證書存儲在公共Git存儲庫中,則必須通過提供密鑰短語來對它們進行加密。", + "desc5": "當前,使用設置文件中的credentialSecret屬性作為密鑰來加密流憑據文件。", + "desc6": "您的流程證書文件當前使用系統生成的密鑰加密。 您應該為此項目提供一個新的密鑰。", + "desc7": "密鑰將與項目文件分開存儲。 您將需要提供在另一個Node-RED實例中使用該項目的密鑰。", + "credentials": "證書", + "enable": "啟用加密", + "disable": "禁用加密", + "disabled": "禁用的", + "copy": "複製現有密鑰", + "use-custom": "使用自定義密鑰", + "desc8": "憑證文件不會被加密,其內容很容易閱讀", + "create-project-files": "創建項目文件", + "create-project": "創建項目", + "already-exists": "已存在", + "git-error": "git錯誤", + "git-auth-error": "git認證錯誤" + }, + "create-success": { + "success": "您已經成功創建了第一個項目!", + "desc0": "現在,您可以像往常一樣繼續使用Node-RED。", + "desc1": "側欄中的“信息”標籤顯示了您當前的活動項目。名稱旁邊的按鈕可用於訪問項目設置視圖。", + "desc2": "側欄中的“歷史記錄”標籤可用於查看項目中已更改的文件並提交。 它向您顯示了提交的完整歷史記錄,並允許您將更改推送到遠程存儲庫。" + }, + "create": { + "projects": "項目", + "already-exists": "項目已存在", + "must-contain": "必須僅包含A-Z 0-9 _ -", + "no-info-in-url": "網址中不要包含用戶名/密碼", + "open": "打開項目", + "create": "創建項目", + "clone": "克隆倉庫", + "project-name": "項目名", + "desc": "描述", + "opt": "可選的", + "flow-file": "流程文件", + "credentials": "證書", + "enable-encryption": "啟用加密", + "disable-encryption": "禁用加密", + "encryption-key": "加密的密鑰", + "desc0": "用來保護您的憑證的短語", + "desc1": "憑證文件不會被加密,其內容很容易閱讀", + "git-url": "Git倉庫的URL", + "protocols": "https://, ssh:// or file://", + "auth-failed": "驗證失敗", + "username": "用戶名", + "password": "密碼", + "ssh-key": "SSH密鑰", + "passphrase": "密碼短語", + "desc2": "在通過ssh克隆存儲庫之前,必須添加SSH密鑰才能訪問它。", + "add-ssh-key": "添加一個ssh密鑰", + "credentials-encryption-key": "憑證加密密鑰", + "already-exists-2": "已存在", + "git-error": "git錯誤", + "con-failed": "連接失敗", + "not-git": "不是git倉庫", + "no-resource": "找不到存儲庫", + "cant-get-ssh-key-path": "錯誤! 無法獲取所選的SSH密鑰路徑。", + "unexpected_error": "意外的錯誤" + }, + "delete": { + "confirm": "您確定要刪除此項目嗎?" + }, + "create-project-list": { + "search": "搜尋您的項目", + "current": "當前的" + }, + "require-clean": { + "confirm": "

您有未部署的更改,這些更改將丟失。

您要繼續嗎?

" + }, + "send-req": { + "auth-req": "存儲庫需要認證", + "username": "用戶名", + "password": "密碼", + "passphrase": "密碼短語", + "retry": "重試", + "update-failed": "無法更新身份驗證", + "unhandled": "未處理的錯誤響應" + }, + "create-branch-list": { + "invalid": "無效的分支", + "create": "創建分支", + "current": "當前的" + }, + "create-default-file-set": { + "no-active": "沒有活動項目就無法創建默認文件集", + "no-empty": "無法在非空項目上創建默認文件集", + "git-error": "git error" + }, + "errors": { + "no-username-email": "您的Git客戶端未配置用戶名/電子郵件。", + "unexpected": "發生了一個意料之外的問題", + "code": "代碼" + } + }, + "editor-tab": { + "properties": "屬性", + "envProperties": "環境變量", + "description": "描述", + "appearance": "外觀", + "preview": "UI預覽", + "defaultValue": "默認值", + "env": "環境變量" + }, + "languages": { + "de": "德語", + "en-US": "英語", + "ja": "日語", + "ko": "韓語", + "zh-CN": "簡體中文", + "zh-TW": "繁體中文" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-TW/infotips.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-TW/infotips.json new file mode 100644 index 0000000..f783f2e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-TW/infotips.json @@ -0,0 +1,23 @@ +{ + "info": { + "tip0" : "您可以用 {{core:delete-selection}} 刪除選擇的節點或連結。", + "tip1" : "{{core:search}} 可以在流程內搜索節點。", + "tip2": "{{core:toggle-sidebar}} 可以顯示或隱藏邊側欄。", + "tip3": "您可以在 {{core:manage-palette}} 中管理節點的控制台。", + "tip4": "側邊欄中會列出流程中所有的配置節點。您可以通過功能表或者 {{core:show-config-tab}} 來訪問這些節點。", + "tip5": "您可以在設定中選擇顯示或隱藏這些提示。", + "tip6": "您可以用[left] [up] [down] [right]鍵來移動被選中的節點。按住[shift]可以更快地移動節點。", + "tip7": "把節點拖到連接上可以向連接中插入節點。", + "tip8": "您可以用 {{core:show-export-dialog}} 來匯出被選中的節點或標籤頁中的流程。", + "tip9": "您可以將流程的json文字檔拖入編輯方塊或 {{core:show-import-dialog}} 來導入流程。", + "tip10": "按住[shift]後按一下並拖動節點可以將該節點的多個連接一併移動到其他節點的埠。", + "tip11": "{{core:show-info-tab}} 可以顯示「資訊」標籤頁。 {{core:show-debug-tab}} 可以顯示「調試」標籤頁。", + "tip12": "按住[ctrl]的同時點擊工作介面可以在節點的對話欄中快速添加節點。", + "tip13": "按住[ctrl]的同時點擊節點的埠或後續節點可以快速連接多個節點。", + "tip14": "按住[shift]的同時點擊節點會選中所有被連接的節點。", + "tip15": "按住[ctrl]的同時點擊節點可以在選中或取消選中節點。", + "tip16": "{{core:show-previous-tab}} 和 {{core:show-next-tab}} 可以切換標籤頁。", + "tip17": "您可以在節點的屬性配置畫面中通過 {{core:confirm-edit-tray}} 來更改設置,或者用 {{core:cancel-edit-tray}} 來取消更改。", + "tip18": "您可以通過點擊 {{core:edit-selected-node}} 來顯示被選中節點的屬性設置畫面。" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-TW/jsonata.json b/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-TW/jsonata.json new file mode 100644 index 0000000..6d99ffc --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/locales/zh-TW/jsonata.json @@ -0,0 +1,270 @@ +{ + "$string": { + "args": "arg", + "desc": "通過以下的類型轉換規則將參數*arg*轉換成字串:\n\n - 字串不轉換。\n -函數轉換成空的字串。\n - JSON的值無法用數字表示所以用無限大或者NaN(非數)表示。\n - 用’JSON.stringify’函數將其他值轉換成JSON字串。" + }, + "$length": { + "args": "str", + "desc": "輸出字串’str’的字數。如果’str’不是字串,拋出錯誤。" + }, + "$substring": { + "args": "str, start[, length]", + "desc": "輸出`start`位置後的的首次出現的包括`str`的子字串。 如果`length`被指定,那麼的字串中將只包括前`length`個文字。如果`start`是負數則輸出從`str`末尾開始的`length`個文字" + }, + "$substringBefore": { + "args": "str, chars", + "desc": "輸出’str’中首次出現的’chars’之前的子字串,如果’str’中不包括’chars’則輸出’str’。" + }, + "$substringAfter": { + "args": "str, chars", + "desc": "輸出’str’中首次出現的’chars’之後的子字串,如果’str’中不包括’chars’則輸出’str’。" + }, + "$uppercase": { + "args": "str", + "desc": "`將’str’中的所有字母變為大寫後輸出。" + }, + "$lowercase": { + "args": "str", + "desc": "將’str’中的所有字母變為小寫後輸出。" + }, + "$trim": { + "args": "str", + "desc": "將以下步驟應用於`str`來去除所有空白文字並實現標準化。\n\n – 將全部tab定位字元、Enter鍵、換行字元用空白代替。\n- 將連續的空白文字變成一個空白文字。\n- 消除開頭和末尾的空白文字。\n\n如果`str`沒有被指定(即在無輸入參數的情況下調用本函數),將上下文的值作為`str`來使用。 如果`str` 不是字串則拋出錯誤。" + }, + "$contains": { + "args": "str, pattern", + "desc": "字串`str` 和 `pattern`匹配的話輸出`true`,不匹配的情況下輸出 `false`。 不指定`str`的情況下(比如用一個參數調用本函數時)、將上下文的值作為`str`來使用。參數 `pattern`可以為字串或正則表達。" + }, + "$split": { + "args": "str[, separator][, limit]", + "desc": "將參數`str`分解成由子字串組成的陣列。 如果`str`不是字串拋出錯誤。可以省略的參數 `separator`中指定字串`str`的分隔符號。分隔符號可以是文字或規則運算式。在不指定`separator`的情況下、將分隔符號看作空的字串並把`str`拆分成由單個字母組成的陣列。如果`separator`不是字串則拋出錯誤。在可省略的參數`limit`中指定分割後的子字串的最大個數。超出個數的子字串將被捨棄。如果`limit`沒有被指定,`str` 將不考慮子字串的個數而將字串完全分隔。如果`limit`是負數則拋出錯誤。" + }, + "$join": { + "args": "array[, separator]", + "desc": "用可以省略的參數 `separator`來把多個字元串連接。如果`array`不是字串則拋出錯誤。 如果沒有指定`separator`,則用空字串來連接字元(即字串之間沒有`separator`)。 如果`separator`不是字元則拋出錯誤。" + }, + "$match": { + "args": "str, pattern [, limit]", + "desc": "對字串`str`使用規則運算式`pattern`並輸出與`str`相匹配的部分資訊。" + }, + "$replace": { + "args": "str, pattern, replacement [, limit]", + "desc": "在字串`str`中搜索`pattern`並用`replacement`來替換。\n\n可選參數`limit`用來指定替換次數的上限。" + }, + "$now": { + "args": "", + "desc": "生成ISO 8601互換格式的時刻,並作為字串輸出。" + }, + "$base64encode": { + "args": "string", + "desc": "將ASCII格式的字串轉換為Base 64格式。將字串中的文字視作二進位形式的資料處理。包含URI編碼在內的字串文字必須在0x00到0xFF的範圍內,否則不會被支持。" + }, + "$base64decode": { + "args": "string", + "desc": "用UTF-8內碼表將Base 64形式二進位值轉換為字串。" + }, + "$number": { + "args": "arg", + "desc": "用下述的規則將參數 `arg`轉換為數值。:\n\n – 數值不做轉換。\n – 將字串中合法的JSON數値表示轉換成數値。\n – 其他形式的值則拋出錯誤。" + }, + "$abs": { + "args": "number", + "desc": "輸出參數`number`的絕對值。" + }, + "$floor": { + "args": "number", + "desc": "輸出比`number`的值小的最大整數。" + }, + "$ceil": { + "args": "number", + "desc": "輸出比`number`的值大的最小整數。" + }, + "$round": { + "args": "number [, precision]", + "desc": "輸出四捨五入後的參數`number`。可省略的參數 `precision`指定四捨五入後小數點下的位數。" + }, + "$power": { + "args": "base, exponent", + "desc": "輸出底數`base`的`exponent`次冪。" + }, + "$sqrt": { + "args": "number", + "desc": "輸出參數 `number`的平方根。" + }, + "$random": { + "args": "", + "desc": "輸出比0大,比1小的偽亂數。" + }, + "$millis": { + "args": "", + "desc": "返回從UNIX時間 (1970年1月1日 UTC/GMT的午夜)開始到現在的毫秒數。在同一個運算式的測試中所有對`$millis()`的調用將會返回相同的值。" + }, + "$sum": { + "args": "array", + "desc": "輸出陣列`array`的總和。如果`array`不是數值則拋出錯誤。" + }, + "$max": { + "args": "array", + "desc": "輸出陣列`array`的最大值。如果`array`不是數值則拋出錯誤。" + }, + "$min": { + "args": "array", + "desc": "輸出陣列`array`的最小值。如果`array`不是數值則拋出錯誤。。" + }, + "$average": { + "args": "array", + "desc": "輸出陣列`array`的平均數。如果`array`不是數值則拋出錯誤。。" + }, + "$boolean": { + "args": "arg", + "desc": "用下述規則將資料轉換成布林值。:\n\n - 不轉換布林值`Boolean`。\n – 將空的字串`string`轉換為`false`\n – 將不為空的字串`string`轉換為`true`\n – 將為0的數位`number`轉換成`false`\n –將不為0的數位`number`轉換成`true`\n –將`null`轉換成`false`\n –將空的陣列`array`轉換成`false`\n –如果陣列`array`中含有可以轉換成`true`的要素則轉換成`true`\n –如果`array`中沒有可轉換成`true`的要素則轉換成`false`\n – 空的物件`object`轉換成`false`\n – 非空的物件`object`轉換成`true`\n –將函數`function`轉換成`false`" + }, + "$not": { + "args": "arg", + "desc": "輸出做反轉運算後的布林值。首先將`arg`轉換為布林值。" + }, + "$exists": { + "args": "arg", + "desc": "如果算式`arg`的值存在則輸出`true`。如果算式的值不存在(比如指向不存在區域的引用)則輸出`false`。" + }, + "$count": { + "args": "array", + "desc": "輸出陣列中的元素數。" + }, + "$append": { + "args": "array, array", + "desc": "將兩個陣列連接。" + }, + "$sort": { + "args": "array [, function]", + "desc": "輸出排序後的陣列`array`。\n\n如果使用了比較函數`function`,則下述兩個參數需要被指定。\n\n`function(left, right)`\n\n該比較函數是為了比較left和right兩個值而被排序演算法調用的。如果使用者希望left的值被置於right的值之後,那麼該函數必須輸出布林值`true`來表示位置交換。而在不需要位置交換時函數必須輸出`false`。" + }, + "$reverse": { + "args": "array", + "desc": "輸出倒序後的陣列`array`。" + }, + "$shuffle": { + "args": "array", + "desc": "輸出隨機排序後的陣列 `array`。" + }, + "$zip": { + "args": "array, ...", + "desc": "將陣列中的值按索引順序打包後輸出。" + }, + "$keys": { + "args": "object", + "desc": "輸出由物件內的鍵組成的陣列。如果參數是物件的陣列則輸出由所有物件中的鍵去重後組成的佇列。" + }, + "$lookup": { + "args": "object, key", + "desc": "輸出對象中與參數`key`對應的值。如果第一個參數`object`是陣列,那麼陣列中所有的物件都將被搜索並輸出這些物件中與參數`key`對應的值。" + }, + "$spread": { + "args": "object", + "desc": "將物件中的鍵值對分隔成每個要素中只含有一個鍵值對的陣列。如果參數`object`是陣列,那麼返回值的陣列中包含所有物件中的鍵值對。" + }, + "$merge": { + "args": "array<object>", + "desc": "將輸入陣列`objects`中所有的鍵值對合併到一個`object`中並返回。如果輸入陣列的要素中含有重複的鍵,則返回的`object`中將只包含陣列中最後出現要素的值。如果輸入陣列中包括物件以外的元素,則拋出錯誤。" + }, + "$sift": { + "args": "object, function", + "desc": "輸出參數`object`中符合`function`的鍵值對。\n\n`function`必須含有下述參數。\n\n`function(value [, key [, object]])`" + }, + "$each": { + "args": "object, function", + "desc": "將函數`function`應用於`object`中的所有鍵值對並輸出由所有返回值組成的陣列。" + }, + "$map": { + "args": "array, function", + "desc": "將函數`function`應用於陣列`array`中所有的值並輸出由返回值組成的陣列。\n\n`function`中必須含有下述參數。\n\n`function(value [, index [, array]])`" + }, + "$filter": { + "args": "array, function", + "desc": "輸出陣列`array`中符合函數`function`條件的值組成的陣列。\n\n`function`必須包括下述參數。\n\n`function(value [, index [, array]])`" + }, + "$reduce": { + "args": "array, function [, init]", + "desc": "將`function`依次應用於陣列中的各要素值。 其中,前一個要素值的計算結果將參與到下一次的函數運算中。。\n\n函數`function`接受兩個參數並作為中綴標記法中的操作符。\n\n可省略的參數`init`將作為運算的初始值。" + }, + "$flowContext": { + "args": "string", + "desc": "獲取流上下文(流等級的上下文,可以讓所有節點共用)的屬性。" + }, + "$globalContext": { + "args": "string", + "desc": "獲取全域上下文的屬性。" + }, + "$pad": { + "args": "string, width [, char]", + "desc": "根據需要,向字串`string`的副本中填充文字使該字串的字數達到`width`的絕對值並返回填充文字後的字串。\n\n如果`width`的值為正,則向字串`string`的右側填充文字,如果`width`為負,則向字串`string`的左側填充文字。\n\n可選參數`char`用來指定填充的文字。如果未指定該參數,則填充空白文字。" + }, + "$fromMillis": { + "args": "number", + "desc": "將表示從UNIX時間 (1970年1月1日 UTC/GMT的午夜)開始到現在的毫秒數的數值轉換成ISO 8601形式時間戳記的字串。" + }, + "$formatNumber": { + "args": "number, picture [, options]", + "desc": "將`number`轉換成具有`picture`所指定的數值格式的字串。\n\n此函數的功能與XPath F&O 3.1規格中定義的XPath/XQuery函數的fn:format-number功能相一致。參數`picture`用於指定數值的轉換格式,其語法與fn:format-number中的定義一致。\n\n可選的第三參數`options`用來覆蓋預設的局部環境格式,如小數點分隔符號。如果指定該參數,那麼該參數必須是包含name/value對的物件,並且name/value對必須符合XPath F&O 3.1規格中記述的數值格式。" + }, + "$formatBase": { + "args": "number [, radix]", + "desc": "將`number`變換為以參數`radix`的值為基數形式的字串。如果不指定`radix`的值,則默認基數為10。指定的`radix`值必須在2~36之間,否則拋出錯誤。" + }, + "$toMillis": { + "args": "timestamp", + "desc": "將ISO 8601格式的字串`timestamp`轉換為從UNIX時間 (1970年1月1日 UTC/GMT的午夜)開始到現在的毫秒數。如果該字串的格式不正確,則拋出錯誤。" + }, + "$env": { + "args": "arg", + "desc": "返回環境變量的值。\n\n這是Node-RED定義的函數。" + }, + "$eval": { + "args": "expr [, context]", + "desc": "使用當前上下文來作為評估依據,分析並評估字符串`expr`,其中包含文字JSON或JSONata表達式。" + }, + "$formatInteger": { + "args": "number, picture", + "desc": "將“數字”轉換為字符串,並將其格式化為“圖片”字符串指定的整數表示形式。圖片字符串參數定義了數字的格式,並具有與XPath F&O 3.1 規範中的fn:format-integer相同的語法。" + }, + "$parseInteger": { + "args": "string, picture", + "desc": "使用“圖片”字符串指定的格式將“字符串”參數的內容解析為整數(作為JSON數字)。圖片字符串參數與$formatInteger格式相同。." + }, + "$error": { + "args": "[str]", + "desc": "引發錯誤並顯示一條消息。 可選的`str`將替代$error()函數評估的默認消息。" + }, + "$assert": { + "args": "arg, str", + "desc": "如果`arg`為真,則該函數返回。 如果arg為假,則拋出帶有str的異常作為異常消息。" + }, + "$single": { + "args": "array, function", + "desc": "返回滿足參數function謂語的array參數中的唯一值 (比如:傳遞值時,函數返回布林值“true”)。如果匹配值的數量不唯一時,則拋出異常。\n\n應在以下簽名中提供函數:`function(value [,index [,array []]])`其中value是數組的每個輸入,index是該值的位置,整個數組作為第三個參數傳遞。" + }, + "$encodeUrl": { + "args": "str", + "desc": "通過用表示字符的UTF-8編碼的一個,兩個,三個或四個轉義序列替換某些字符的每個實例,對統一資源定位符(URL)組件進行編碼。\n\n示例:`$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`" + }, + "$encodeUrlComponent": { + "args": "str", + "desc": "通過用表示字符的UTF-8編碼的一個,兩個,三個或四個轉義序列替換某些字符的每個實例,對統一資源定位符(URL)進行編碼。\n\n示例: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`" + }, + "$decodeUrl": { + "args": "str", + "desc": "解碼以前由encodeUrlComponent創建的統一資源定位器(URL)組件。 \n\n示例: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`" + }, + "$decodeUrlComponent": { + "args": "str", + "desc": "解碼先前由encodeUrl創建的統一資源定位符(URL)。 \n\n示例: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`" + }, + "$distinct": { + "args": "array", + "desc": "返回一個數組,其中重復的值已從`數組`中刪除" + }, + "$type": { + "args": "value", + "desc": "以字符串形式返回`值`的類型。 如果該`值`未定義,則將返回`未定義`" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/package.json b/packages/connector/packages/node_modules/@node-red/editor-client/package.json new file mode 100644 index 0000000..0b3e16e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/package.json @@ -0,0 +1,18 @@ +{ + "name": "@node-red/editor-client", + "version": "1.0.4", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/node-red/node-red.git" + }, + "contributors": [ + { + "name": "Nick O'Leary" + }, + { + "name": "Dave Conway-Jones" + } + ], + "main": "./lib/index.js" +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/ace/README.md b/packages/connector/packages/node_modules/@node-red/editor-client/src/ace/README.md new file mode 100644 index 0000000..bbcef57 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/ace/README.md @@ -0,0 +1,50 @@ +How to build the custom ACE modes for Node-RED +---------------------------------------------- + +Node-RED includes custom JSONata and JavaScript modes. + + +## JSONata + +The `ace/mode/jsonata` mode is maintained under `editor-client/src/vendor/jsonata`. +Those files are edited in place and copied into the build by Grunt. + +## JavaScript + +The `ace/mode/nrjavascript` mode is used exclusively by the Function node. It +inherits almost entirely from the normal JavaScript mode. The one key difference +is that it wraps the code with a Function before parsing. This is required to +avoid some false-flagged errors. + +The source of the mode is under `editor-client/src/ace/mode`. If those files are +modified in anyway, they *must* be manually built to generate the files under +`editor-client/src/ace/bin` and checked in. Those files are the ones the Grunt +built copies out in the Node-RED build. + +### Building the mode files + + +#### Setup build environment + + cd /tmp/ + git clone https://github.com/ajaxorg/ace.git + cd ace + npm install + +#### Copy mode src files into build environment + + cd /packages/node_modules/@node-red/editor-client/src/ace/bin/ + cp build/src-min-noconflict/snippets/nrjavascript.js \ + /packages/node_modules/@node-red/editor-client/src/ace/bin/snippets/ diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/ace/bin/mode-nrjavascript.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/ace/bin/mode-nrjavascript.js new file mode 100644 index 0000000..2f6d46c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/ace/bin/mode-nrjavascript.js @@ -0,0 +1,9 @@ +ace.define("ace/mode/doc_comment_highlight_rules",[],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},s.getTagRule(),{defaultToken:"comment.doc",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",[],function(e,t,n){"use strict";function a(){var e=o.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r=e.charAt(1)=="/"?2:1;if(r==1)t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++;else if(r==2&&t==this.nextState){n[1]--;if(!n[1]||n[1]<0)n.shift(),n.shift()}return[{type:"meta.tag.punctuation."+(r==1?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"",onMatch:function(e,t,n){return t==n[0]&&n.shift(),e.length==2&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,f("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function f(e){return[{token:"comment",regex:/\/\*/,next:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[i.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*",u=function(e){var t=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),n="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[i.getStartRule("doc-start"),f("no_regex"),{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+o+")(\\.)(prototype)(\\.)("+o+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+o+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:"+n+")\\b",next:"start"},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:t,regex:o},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(?:(\\s+)(\\w+))?(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:o},{regex:"",token:"empty",next:"no_regex"}],start:[i.getStartRule("doc-start"),f("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:o},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]};if(!e||!e.noES6)this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)n.unshift("start",t);else if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1||this.next.indexOf("jsx")!=-1)return"paren.quasi.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]}),(!e||e.jsx!=0)&&a.call(this);this.embedRules(i,"doc-",[i.getEndRule("no_regex")]),this.normalizeRules()};r.inherits(u,s),t.JavaScriptHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",[],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/cstyle",[],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",[],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/nrjavascript",[],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./javascript").Mode,s=e("../worker/worker_client").WorkerClient,o=function(){i.call(this)};r.inherits(o,i),function(){this.createWorker=function(e){var t=new s(["ace"],"ace/mode/nrjavascript_worker","NRJavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/nrjavascript"}.call(o.prototype),t.Mode=o}); + (function() { + ace.require(["ace/mode/nrjavascript"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/ace/bin/snippets/nrjavascript.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/ace/bin/snippets/nrjavascript.js new file mode 100644 index 0000000..c0f5c2e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/ace/bin/snippets/nrjavascript.js @@ -0,0 +1,8 @@ +ace.define("ace/snippets/nrjavascript",[],function(e,t,n){"use strict";t.snippetText='# Prototype\nsnippet proto\n ${1:class_name}.prototype.${2:method_name} = function(${3:first_argument}) {\n ${4:// body...}\n };\n# Function\nsnippet fun\n function ${1?:function_name}(${2:argument}) {\n ${3:// body...}\n }\n# Anonymous Function\nregex /((=)\\s*|(:)\\s*|(\\()|\\b)/f/(\\))?/\nsnippet f\n function${M1?: ${1:functionName}}($2) {\n ${0:$TM_SELECTED_TEXT}\n }${M2?;}${M3?,}${M4?)}\n# Immediate function\ntrigger \\(?f\\(\nendTrigger \\)?\nsnippet f(\n (function(${1}) {\n ${0:${TM_SELECTED_TEXT:/* code */}}\n }(${1}));\n# if\nsnippet if\n if (${1:true}) {\n ${0}\n }\n# if ... else\nsnippet ife\n if (${1:true}) {\n ${2}\n } else {\n ${0}\n }\n# tertiary conditional\nsnippet ter\n ${1:/* condition */} ? ${2:a} : ${3:b}\n# switch\nsnippet switch\n switch (${1:expression}) {\n case \'${3:case}\':\n ${4:// code}\n break;\n ${5}\n default:\n ${2:// code}\n }\n# case\nsnippet case\n case \'${1:case}\':\n ${2:// code}\n break;\n ${3}\n\n# while (...) {...}\nsnippet wh\n while (${1:/* condition */}) {\n ${0:/* code */}\n }\n# try\nsnippet try\n try {\n ${0:/* code */}\n } catch (e) {}\n# do...while\nsnippet do\n do {\n ${2:/* code */}\n } while (${1:/* condition */});\n# Object Method\nsnippet :f\nregex /([,{[])|^\\s*/:f/\n ${1:method_name}: function(${2:attribute}) {\n ${0}\n }${3:,}\n# setTimeout function\nsnippet setTimeout\nregex /\\b/st|timeout|setTimeo?u?t?/\n setTimeout(function() {${3:$TM_SELECTED_TEXT}}, ${1:10});\n# console.log (Firebug)\nsnippet cl\n console.log(${1});\n# return\nsnippet ret\n return ${1:result}\n# for (property in object ) { ... }\nsnippet fori\n for (var ${1:prop} in ${2:Things}) {\n ${0:$2[$1]}\n }\n# hasOwnProperty\nsnippet has\n hasOwnProperty(${1})\n# docstring\nsnippet /**\n /**\n * ${1:description}\n *\n */\nsnippet @par\nregex /^\\s*\\*\\s*/@(para?m?)?/\n @param {${1:type}} ${2:name} ${3:description}\nsnippet @ret\n @return {${1:type}} ${2:description}\n# JSON.parse\nsnippet jsonp\n JSON.parse(${1:jstr});\n# JSON.stringify\nsnippet jsons\n JSON.stringify(${1:object});\n# self-defining function\nsnippet sdf\n var ${1:function_name} = function(${2:argument}) {\n ${3:// initial code ...}\n\n $1 = function($2) {\n ${4:// main code}\n };\n }\n# \nsnippet for-\n for (var ${1:i} = ${2:Things}.length; ${1:i}--; ) {\n ${0:${2:Things}[${1:i}];}\n }\n# for (...) {...}\nsnippet for\n for (var ${1:i} = 0; $1 < ${2:Things}.length; $1++) {\n ${3:$2[$1]}$0\n }\n# for (...) {...} (Improved Native For-Loop)\nsnippet forr\n for (var ${1:i} = ${2:Things}.length - 1; $1 >= 0; $1--) {\n ${3:$2[$1]}$0\n }\n# Node-RED Specific Funcs\nsnippet nodes\n node.send(${1:msg})\nsnippet clone\n RED.util.cloneMessage(${1:msg})\nsnippet nodel\n node.log($1)\nsnippet nodew\n node.warn($1)\nsnippet nodee\n node.error($1)\nsnippet noded\n node.debug($1)\nsnippet done\n node.done($1)\nsnippet flowg\n flow.get($1)\nsnippet flows\n flow.set($1, $2)\nsnippet globalg\n global.get($1)\nsnippet globals\n global.set($1, $2)\n',t.scope="nrjavascript"}); + (function() { + ace.require(["ace/snippets/nrjavascript"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/ace/bin/worker-nrjavascript.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/ace/bin/worker-nrjavascript.js new file mode 100644 index 0000000..8e606c2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/ace/bin/worker-nrjavascript.js @@ -0,0 +1 @@ +"no use strict";!function(e){function t(e,t){var n=e,r="";while(n){var i=t[n];if(typeof i=="string")return i+r;if(i)return i.location.replace(/\/*$/,"/")+(r||i.main||i.name);if(i===!1)return"";var s=n.lastIndexOf("/");if(s===-1)break;r=n.substr(s)+r,n=n.slice(0,s)}return e}if(typeof e.window!="undefined"&&e.document)return;if(e.require&&e.define)return;e.console||(e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console),e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){postMessage({type:"error",data:{message:e,data:i.data,file:t,line:n,col:r,stack:i.stack}})},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(r,i){i||(i=r,r=null);if(!i.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");i=e.normalizeModule(r,i);var s=e.require.modules[i];if(s)return s.initialized||(s.initialized=!0,s.exports=s.factory().exports),s.exports;if(!e.require.tlns)return console.log("unable to load "+i);var o=t(i,e.require.tlns);return o.slice(-3)!=".js"&&(o+=".js"),e.require.id=i,e.require.modules[i]={},importScripts(o),e.require(r,i)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id);if(typeof r!="function"){e.require.modules[t]={exports:r,initialized:!0};return}n.length||(n=["require","exports","module"]);var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.slice(0,r.length).map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},require.tlns={},e.initBaseUrls=function(t){for(var n in t)require.tlns[n]=t[n]},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var n=e.main=null,r=e.sender=null;e.onmessage=function(t){var i=t.data;if(i.event&&r)r._signal(i.event,i.data);else if(i.command)if(n[i.command])n[i.command].apply(n,i.args);else{if(!e[i.command])throw new Error("Unknown command:"+i.command);e[i.command].apply(e,i.args)}else if(i.init){e.initBaseUrls(i.tlns),require("ace/lib/es5-shim"),r=e.sender=e.initSender();var s=require(i.module)[i.classname];n=e.main=new s(r)}}}(this),ace.define("ace/lib/oop",[],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/range",[],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?tthis.end.column?1:0:ethis.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.rowt)var r={row:t+1,column:0};else if(this.start.row=0&&t.row=0&&t.column<=e[t.row].length}function s(e,t){t.action!="insert"&&t.action!="remove"&&r(t,"delta.action must be 'insert' or 'remove'"),t.lines instanceof Array||r(t,"delta.lines must be an Array"),(!t.start||!t.end)&&r(t,"delta.start/end must be an present");var n=t.start;i(e,t.start)||r(t,"delta.start must be contained in document");var s=t.end;t.action=="remove"&&!i(e,s)&&r(t,"delta.end must contained in document for 'remove' actions");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,"delta.range must match delta lines")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||"";switch(t.action){case"insert":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case"remove":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),ace.define("ace/lib/event_emitter",[],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;othis.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",[],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./apply_delta").applyDelta,s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=e("./anchor").Anchor,a=function(e){this.$lines=[""],e.length===0?this.$lines=[""]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."),this.insertMergedLines(e,["",""])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:"insert",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e0,r=t=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action=="insert";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4?this.$splitAndapplyLargeDelta(e,2e4):(i(this.$lines,e,t),this._signal("change",e))},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length-t+1,i=e.start.row,s=e.start.column;for(var o=0,u=0;o0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),typeof console.trace=="function"&&console.trace())}return this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function r(){this.removeListener(e,r),n||(n=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var n=!1;return r.listener=t,this.on(e,r),this},r.prototype.removeListener=function(e,t){var n,r,s,u;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;n=this._events[e],s=n.length,r=-1;if(n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(o(n)){for(u=s;u-->0;)if(n[u]===t||n[u].listener&&n[u].listener===t){r=u;break}if(r<0)return this;n.length===1?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return arguments.length===0?this._events={}:this._events[e]&&delete this._events[e],this;if(arguments.length===0){for(t in this._events){if(t==="removeListener")continue;this.removeAllListeners(t)}return this.removeAllListeners("removeListener"),this._events={},this}n=this._events[e];if(i(n))this.removeListener(e,n);else while(n.length)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return!this._events||!this._events[e]?t=[]:i(this._events[e])?t=[this._events[e]]:t=this._events[e].slice(),t},r.listenerCount=function(e,t){var n;return!e._events||!e._events[t]?n=0:i(e._events[t])?n=1:n=e._events[t].length,n}},{}],"/node_modules/jshint/data/ascii-identifier-data.js":[function(e,t,n){var r=[];for(var i=0;i<128;i++)r[i]=i===36||i>=65&&i<=90||i===95||i>=97&&i<=122;var s=[];for(var i=0;i<128;i++)s[i]=r[i]||i>=48&&i<=57;t.exports={asciiIdentifierStartTable:r,asciiIdentifierPartTable:s}},{}],"/node_modules/jshint/lodash.js":[function(e,t,n){(function(e){(function(){function $(e,t,n){var r=e.length,i=n?r:-1;while(n?i--:++ir&&(r=i)}return r}function Dt(e,t){var n=-1,r=e.length;while(++ns?0:s+t),n=n===r||n>s?s:+n||0,n<0&&(n+=s),s=t>n?0:n-t>>>0,t>>>=0;var o=Array(s);while(++i>>1,o=e[s];(n?o<=t:o2&&n[i-2],o=i>2&&n[2],u=i>1&&n[i-1];typeof s=="function"?(s=on(s,u,5),i-=2):(s=typeof u=="function"?u:null,i-=s?1:0),o&&Tn(n[0],n[1],o)&&(s=i<3?null:s,i=1);while(++rf))return!1;while(c&&++a-1&&e%1==0&&e-1&&e%1==0&&e<=Nt}function kn(e){return e===e&&(e===0?1/e>0:!Jn(e))}function Ln(e){var t,n=Ct.support;if(!Y(e)||rt.call(e)!=d||!nt.call(e,"constructor")&&(t=e.constructor,typeof t=="function"&&!(t instanceof t)))return!1;var i;return Ut(e,function(e,t){i=t}),i===r||nt.call(e,i)}function An(e){var t=ir(e),n=t.length,r=n&&e.length,i=Ct.support,s=r&&Cn(r)&&(Xn(e)||i.nonEnumArgs&&Wn(e)),o=-1,u=[];while(++o>>0,r=Array(n);while(++t-1:gn(e,t,n)>-1):!1}function qn(e,t,n){var r=Xn(e)?Ot:qt;return t=mn(t,n,3),r(e,function(e,n,r){return!t(e,n,r)})}function Rn(e,t,n){var i=Xn(e)?Dt:tn;n&&Tn(e,t,n)&&(t=null);if(typeof t!="function"||n!==r)t=mn(t,n,3);return i(e,t)}function Un(e,t){if(typeof e!="function")throw new TypeError(s);return t=yt(t===r?e.length-1:+t||0,0),function(){var n=arguments,r=-1,i=yt(n.length-t,0),s=Array(i);while(++r0;while(++r>>1,Tt=dt?dt.BYTES_PER_ELEMENT:0,Nt=Math.pow(2,53)-1,kt=Ct.support={};(function(e){var t=function(){this.x=e},n={0:e,length:e},r=[];t.prototype={valueOf:e,y:e};for(var i in new t)r.push(i);kt.funcDecomp=/\bthis\b/.test(function(){return this}),kt.funcNames=typeof Function.name=="string";try{kt.nonEnumArgs=!ht.call(arguments,1)}catch(s){kt.nonEnumArgs=!0}})(1,0);var Ht=vt||function(e,t){return t==null?e:Bt(t,bn(t),Bt(t,rr(t),e))},It=fn(zt),Rt=ln();ot||(un=!st||!pt?fr(null):function(e){var t=e.byteLength,n=dt?ut(t/Tt):0,r=n*Tt,i=new st(t);if(n){var s=new dt(i,0,n);s.set(new dt(e,0,n))}return t!=r&&(s=new pt(i,r),s.set(new pt(e,r))),i});var yn=Yt("length"),bn=at?function(e){return at(On(e))}:fr([]),_n=cn(!0),jn=Un(Bn),Fn=hn(At,It),Xn=mt||function(e){return Y(e)&&Cn(e.length)&&rt.call(e)==u},$n=K(/x/)||pt&&!K(pt)?function(e){return rt.call(e)==c}:K,Gn=ft?function(e){if(!e||rt.call(e)!=d)return!1;var t=e.valueOf,n=Kn(t)&&(n=ft(t))&&ft(n);return n?e==n||ft(e)==n:Ln(e)}:Ln,tr=an(function(e,t,n){return n?Pt(e,t,n):Ht(e,t)}),rr=gt?function(e){if(e)var t=e.constructor,n=e.length;return typeof t=="function"&&t.prototype===e||typeof e!="function"&&Cn(n)?An(e):Jn(e)?gt(e):[]}:An,sr=an(Qt);Ct.assign=tr,Ct.callback=ar,Ct.constant=fr,Ct.forEach=Fn,Ct.keys=rr,Ct.keysIn=ir,Ct.merge=sr,Ct.property=cr,Ct.reject=qn,Ct.restParam=Un,Ct.slice=Hn,Ct.toPlainObject=er,Ct.unzip=Bn,Ct.values=or,Ct.zip=jn,Ct.each=Fn,Ct.extend=tr,Ct.iteratee=ar,Ct.clone=zn,Ct.escapeRegExp=ur,Ct.findLastIndex=_n,Ct.has=nr,Ct.identity=lr,Ct.includes=In,Ct.indexOf=Dn,Ct.isArguments=Wn,Ct.isArray=Xn,Ct.isEmpty=Vn,Ct.isFunction=$n,Ct.isNative=Kn,Ct.isNumber=Qn,Ct.isObject=Jn,Ct.isPlainObject=Gn,Ct.isString=Yn,Ct.isTypedArray=Zn,Ct.last=Pn,Ct.some=Rn,Ct.any=Rn,Ct.contains=In,Ct.include=In,Ct.VERSION=i,q&&R?X?(R.exports=Ct)._=Ct:q._=Ct:V._=Ct}).call(this)}).call(this,typeof global!="undefined"?global:typeof self!="undefined"?self:typeof window!="undefined"?window:{})},{}],"/node_modules/jshint/src/jshint.js":[function(e,t,n){var r=e("../lodash"),i=e("events"),s=e("./vars.js"),o=e("./messages.js"),u=e("./lex.js").Lexer,a=e("./reg.js"),f=e("./state.js").state,l=e("./style.js"),c=e("./options.js"),h=e("./scope-manager.js"),p=function(){"use strict";function k(e,t){return e=e.trim(),/^[+-]W\d{3}$/g.test(e)?!0:c.validNames.indexOf(e)===-1&&t.type!=="jslint"&&!r.has(c.removed,e)?(q("E001",t,e),!1):!0}function L(e){return Object.prototype.toString.call(e)==="[object String]"}function A(e,t){return e?!e.identifier||e.value!==t?!1:!0:!1}function O(e){if(!e.reserved)return!1;var t=e.meta;if(t&&t.isFutureReservedWord&&f.inES5()){if(!t.es5)return!1;if(t.strictOnly&&!f.option.strict&&!f.isStrict())return!1;if(e.isProperty)return!1}return!0}function M(e,t){return e.replace(/\{([^{}]*)\}/g,function(e,n){var r=t[n];return typeof r=="string"||typeof r=="number"?r:e})}function D(e,t){Object.keys(t).forEach(function(n){if(r.has(p.blacklist,n))return;e[n]=t[n]})}function P(){if(f.option.enforceall){for(var e in c.bool.enforcing)f.option[e]===undefined&&!c.noenforceall[e]&&(f.option[e]=!0);for(var t in c.bool.relaxing)f.option[t]===undefined&&(f.option[t]=!1)}}function H(){P(),!f.option.esversion&&!f.option.moz&&(f.option.es3?f.option.esversion=3:f.option.esnext?f.option.esversion=6:f.option.esversion=5),f.inES5()&&D(S,s.ecmaIdentifiers[5]),f.inES6()&&D(S,s.ecmaIdentifiers[6]),f.option.module&&(f.option.strict===!0&&(f.option.strict="global"),f.inES6()||F("W134",f.tokens.next,"module",6)),f.option.couch&&D(S,s.couch),f.option.qunit&&D(S,s.qunit),f.option.rhino&&D(S,s.rhino),f.option.shelljs&&(D(S,s.shelljs),D(S,s.node)),f.option.typed&&D(S,s.typed),f.option.phantom&&(D(S,s.phantom),f.option.strict===!0&&(f.option.strict="global")),f.option.prototypejs&&D(S,s.prototypejs),f.option.node&&(D(S,s.node),D(S,s.typed),f.option.strict===!0&&(f.option.strict="global")),f.option.devel&&D(S,s.devel),f.option.dojo&&D(S,s.dojo),f.option.browser&&(D(S,s.browser),D(S,s.typed)),f.option.browserify&&(D(S,s.browser),D(S,s.typed),D(S,s.browserify),f.option.strict===!0&&(f.option.strict="global")),f.option.nonstandard&&D(S,s.nonstandard),f.option.jasmine&&D(S,s.jasmine),f.option.jquery&&D(S,s.jquery),f.option.mootools&&D(S,s.mootools),f.option.worker&&D(S,s.worker),f.option.wsh&&D(S,s.wsh),f.option.globalstrict&&f.option.strict!==!1&&(f.option.strict="global"),f.option.yui&&D(S,s.yui),f.option.mocha&&D(S,s.mocha)}function B(e,t,n){var r=Math.floor(t/f.lines.length*100),i=o.errors[e].desc;throw{name:"JSHintError",line:t,character:n,message:i+" ("+r+"% scanned).",raw:i,code:e}}function j(){var e=f.ignoredLines;if(r.isEmpty(e))return;p.errors=r.reject(p.errors,function(t){return e[t.line]})}function F(e,t,n,r,i,s){var u,a,l,c;if(/^W\d{3}$/.test(e)){if(f.ignored[e])return;c=o.warnings[e]}else/E\d{3}/.test(e)?c=o.errors[e]:/I\d{3}/.test(e)&&(c=o.info[e]);return t=t||f.tokens.next||{},t.id==="(end)"&&(t=f.tokens.curr),a=t.line||0,u=t.from||0,l={id:"(error)",raw:c.desc,code:c.code,evidence:f.lines[a-1]||"",line:a,character:u,scope:p.scope,a:n,b:r,c:i,d:s},l.reason=M(c.desc,l),p.errors.push(l),j(),p.errors.length>=f.option.maxerr&&B("E043",a,u),l}function I(e,t,n,r,i,s,o){return F(e,{line:t,from:n},r,i,s,o)}function q(e,t,n,r,i,s){F(e,t,n,r,i,s)}function R(e,t,n,r,i,s,o){return q(e,{line:t,from:n},r,i,s,o)}function U(e,t){var n;return n={id:"(internal)",elem:e,value:t},p.internals.push(n),n}function z(){var e=f.tokens.next,t=e.body.match(/(-\s+)?[^\s,:]+(?:\s*:\s*(-\s+)?[^\s,]+)?/g)||[],i={};if(e.type==="globals"){t.forEach(function(n,r){n=n.split(":");var s=(n[0]||"").trim(),o=(n[1]||"").trim();if(s==="-"||!s.length){if(r>0&&r===t.length-1)return;q("E002",e);return}s.charAt(0)==="-"?(s=s.slice(1),o=!1,p.blacklist[s]=s,delete S[s]):i[s]=o==="true"}),D(S,i);for(var s in i)r.has(i,s)&&(n[s]=e)}e.type==="exported"&&t.forEach(function(n,r){if(!n.length){if(r>0&&r===t.length-1)return;q("E002",e);return}f.funct["(scope)"].addExported(n)}),e.type==="members"&&(E=E||{},t.forEach(function(e){var t=e.charAt(0),n=e.charAt(e.length-1);t===n&&(t==='"'||t==="'")&&(e=e.substr(1,e.length-2).replace('\\"','"')),E[e]=!1}));var o=["maxstatements","maxparams","maxdepth","maxcomplexity","maxerr","maxlen","indent"];if(e.type==="jshint"||e.type==="jslint")t.forEach(function(t){t=t.split(":");var n=(t[0]||"").trim(),i=(t[1]||"").trim();if(!k(n,e))return;if(o.indexOf(n)>=0){if(i!=="false"){i=+i;if(typeof i!="number"||!isFinite(i)||i<=0||Math.floor(i)!==i){q("E032",e,t[1].trim());return}f.option[n]=i}else f.option[n]=n==="indent"?4:!1;return}if(n==="validthis"){if(f.funct["(global)"])return void q("E009");if(i!=="true"&&i!=="false")return void q("E002",e);f.option.validthis=i==="true";return}if(n==="quotmark"){switch(i){case"true":case"false":f.option.quotmark=i==="true";break;case"double":case"single":f.option.quotmark=i;break;default:q("E002",e)}return}if(n==="shadow"){switch(i){case"true":f.option.shadow=!0;break;case"outer":f.option.shadow="outer";break;case"false":case"inner":f.option.shadow="inner";break;default:q("E002",e)}return}if(n==="unused"){switch(i){case"true":f.option.unused=!0;break;case"false":f.option.unused=!1;break;case"vars":case"strict":f.option.unused=i;break;default:q("E002",e)}return}if(n==="latedef"){switch(i){case"true":f.option.latedef=!0;break;case"false":f.option.latedef=!1;break;case"nofunc":f.option.latedef="nofunc";break;default:q("E002",e)}return}if(n==="ignore"){switch(i){case"line":f.ignoredLines[e.line]=!0,j();break;default:q("E002",e)}return}if(n==="strict"){switch(i){case"true":f.option.strict=!0;break;case"false":f.option.strict=!1;break;case"func":case"global":case"implied":f.option.strict=i;break;default:q("E002",e)}return}n==="module"&&(zt(f.funct)||q("E055",f.tokens.next,"module"));var s={es3:3,es5:5,esnext:6};if(r.has(s,n)){switch(i){case"true":f.option.moz=!1,f.option.esversion=s[n];break;case"false":f.option.moz||(f.option.esversion=5);break;default:q("E002",e)}return}if(n==="esversion"){switch(i){case"5":f.inES5(!0)&&F("I003");case"3":case"6":f.option.moz=!1,f.option.esversion=+i;break;case"2015":f.option.moz=!1,f.option.esversion=6;break;default:q("E002",e)}zt(f.funct)||q("E055",f.tokens.next,"esversion");return}var u=/^([+-])(W\d{3})$/g.exec(n);if(u){f.ignored[u[2]]=u[1]==="-";return}var a;if(i==="true"||i==="false"){e.type==="jslint"?(a=c.renamed[n]||n,f.option[a]=i==="true",c.inverted[a]!==undefined&&(f.option[a]=!f.option[a])):f.option[n]=i==="true",n==="newcap"&&(f.option["(explicitNewcap)"]=!0);return}q("E002",e)}),H()}function W(e){var t=e||0,n=y.length,r;if(t="a"&&t<="z"||t>="A"&&t<="Z")e.identifier=e.reserved=!0;return e}function ut(e,t){var n=nt(e,150);return ot(n),n.nud=typeof t=="function"?t:function(){this.arity="unary",this.right=Q(150);if(this.id==="++"||this.id==="--")f.option.plusplus?F("W016",this,this.id):this.right&&(!this.right.identifier||O(this.right))&&this.right.id!=="."&&this.right.id!=="["&&F("W017",this),this.right&&this.right.isMetaProperty?q("E031",this):this.right&&this.right.identifier&&f.funct["(scope)"].block.modify(this.right.value,this);return this},n}function at(e,t){var n=rt(e);return n.type=e,n.nud=t,n}function ft(e,t){var n=at(e,t);return n.identifier=!0,n.reserved=!0,n}function lt(e,t){var n=at(e,t&&t.nud||function(){return this});return t=t||{},t.isFutureReservedWord=!0,n.value=e,n.identifier=!0,n.reserved=!0,n.meta=t,n}function ct(e,t){return ft(e,function(){return typeof t=="function"&&t(this),this})}function ht(e,t,n,r){var i=nt(e,n);return ot(i),i.infix=!0,i.led=function(i){return r||Y(f.tokens.prev,f.tokens.curr),(e==="in"||e==="instanceof")&&i.id==="!"&&F("W018",i,"!"),typeof t=="function"?t(i,this):(this.left=i,this.right=Q(n),this)},i}function pt(e){var t=nt(e,42);return t.led=function(e){return Y(f.tokens.prev,f.tokens.curr),this.left=e,this.right=Xt({type:"arrow",loneArg:e}),this},t}function dt(e,t){var n=nt(e,100);return n.led=function(e){Y(f.tokens.prev,f.tokens.curr),this.left=e;var n=this.right=Q(100);return A(e,"NaN")||A(n,"NaN")?F("W019",this):t&&t.apply(this,[e,n]),(!e||!n)&&B("E041",f.tokens.curr.line),e.id==="!"&&F("W018",e,"!"),n.id==="!"&&F("W018",n,"!"),this},n}function vt(e){return e&&(e.type==="(number)"&&+e.value===0||e.type==="(string)"&&e.value===""||e.type==="null"&&!f.option.eqnull||e.type==="true"||e.type==="false"||e.type==="undefined")}function gt(e,t,n){var i;return n.option.notypeof?!1:!e||!t?!1:(i=n.inES6()?mt.es6:mt.es3,t.type==="(identifier)"&&t.value==="typeof"&&e.type==="(string)"?!r.contains(i,e.value):!1)}function yt(e,t){var n=!1;return e.type==="this"&&t.funct["(context)"]===null?n=!0:e.type==="(identifier)"&&(t.option.node&&e.value==="global"?n=!0:t.option.browser&&(e.value==="window"||e.value==="document")&&(n=!0)),n}function bt(e){function n(e){if(typeof e!="object")return;return e.right==="prototype"?e:n(e.left)}function r(e){while(!e.identifier&&typeof e.left=="object")e=e.left;if(e.identifier&&t.indexOf(e.value)>=0)return e.value}var t=["Array","ArrayBuffer","Boolean","Collator","DataView","Date","DateTimeFormat","Error","EvalError","Float32Array","Float64Array","Function","Infinity","Intl","Int16Array","Int32Array","Int8Array","Iterator","Number","NumberFormat","Object","RangeError","ReferenceError","RegExp","StopIteration","String","SyntaxError","TypeError","Uint16Array","Uint32Array","Uint8Array","Uint8ClampedArray","URIError"],i=n(e);if(i)return r(i)}function wt(e,t,n){var r=n&&n.allowDestructuring;t=t||e;if(f.option.freeze){var i=bt(e);i&&F("W121",e,i)}return e.identifier&&!e.isMetaProperty&&f.funct["(scope)"].block.reassign(e.value,e),e.id==="."?((!e.left||e.left.value==="arguments"&&!f.isStrict())&&F("E031",t),f.nameStack.set(f.tokens.prev),!0):e.id==="{"||e.id==="["?(r&&f.tokens.curr.left.destructAssign?f.tokens.curr.left.destructAssign.forEach(function(e){e.id&&f.funct["(scope)"].block.modify(e.id,e.token)}):e.id==="{"||!e.left?F("E031",t):e.left.value==="arguments"&&!f.isStrict()&&F("E031",t),e.id==="["&&f.nameStack.set(e.right),!0):e.isMetaProperty?(q("E031",t),!0):e.identifier&&!O(e)?(f.funct["(scope)"].labeltype(e.value)==="exception"&&F("W022",e),f.nameStack.set(e),!0):(e===f.syntax["function"]&&F("W023",f.tokens.curr),!1)}function Et(e,t,n){var r=ht(e,typeof t=="function"?t:function(e,t){t.left=e;if(e&&wt(e,t,{allowDestructuring:!0}))return t.right=Q(10),t;q("E031",t)},n);return r.exps=!0,r.assign=!0,r}function St(e,t,n){var r=nt(e,n);return ot(r),r.led=typeof t=="function"?t:function(e){return f.option.bitwise&&F("W016",this,this.id),this.left=e,this.right=Q(n),this},r}function xt(e){return Et(e,function(e,t){f.option.bitwise&&F("W016",t,t.id);if(e&&wt(e,t))return t.right=Q(10),t;q("E031",t)},20)}function Tt(e){var t=nt(e,150);return t.led=function(e){return f.option.plusplus?F("W016",this,this.id):(!e.identifier||O(e))&&e.id!=="."&&e.id!=="["&&F("W017",this),e.isMetaProperty?q("E031",this):e&&e.identifier&&f.funct["(scope)"].block.modify(e.value,e),this.left=e,this},t}function Nt(e,t,n){if(!f.tokens.next.identifier)return;n||V();var r=f.tokens.curr,i=f.tokens.curr.value;return O(r)?t&&f.inES5()?i:e&&i==="undefined"?i:(F("W024",f.tokens.curr,f.tokens.curr.id),i):i}function Ct(e,t){var n=Nt(e,t,!1);if(n)return n;if(f.tokens.next.value==="..."){f.inES6(!0)||F("W119",f.tokens.next,"spread/rest operator","6"),V();if(pn(f.tokens.next,"...")){F("E024",f.tokens.next,"...");while(pn(f.tokens.next,"..."))V()}if(!f.tokens.next.identifier){F("E024",f.tokens.curr,"...");return}return Ct(e,t)}q("E030",f.tokens.next,f.tokens.next.value),f.tokens.next.id!==";"&&V()}function kt(e){var t=0,n;if(f.tokens.next.id!==";"||e.inBracelessBlock)return;for(;;){do n=W(t),t+=1;while(n.id!=="(end)"&&n.id==="(comment)");if(n.reach)return;if(n.id!=="(endline)"){if(n.id==="function"){f.option.latedef===!0&&F("W026",n);break}F("W027",n,n.value,e.value);break}}}function Lt(){if(f.tokens.next.id!==";"){if(f.tokens.next.isUnclosed)return V();var e=G(f.tokens.next)===f.tokens.curr.line&&f.tokens.next.id!=="(end)",t=pn(f.tokens.next,"}");e&&!t?R("E058",f.tokens.curr.line,f.tokens.curr.character):f.option.asi||(t&&!f.option.lastsemic||!e)&&I("W033",f.tokens.curr.line,f.tokens.curr.character)}else V(";")}function At(){var e=g,t,n=f.tokens.next,r=!1;if(n.id===";"){V(";");return}var i=O(n);i&&n.meta&&n.meta.isFutureReservedWord&&W().id===":"&&(F("W024",n,n.id),i=!1),n.identifier&&!i&&W().id===":"&&(V(),V(":"),r=!0,f.funct["(scope)"].stack(),f.funct["(scope)"].block.addBreakLabel(n.value,{token:f.tokens.curr}),!f.tokens.next.labelled&&f.tokens.next.value!=="{"&&F("W028",f.tokens.next,n.value,f.tokens.next.value),f.tokens.next.label=n.value,n=f.tokens.next);if(n.id==="{"){var s=f.funct["(verb)"]==="case"&&f.tokens.curr.value===":";_t(!0,!0,!1,!1,s);return}return t=Q(0,!0),t&&(!t.identifier||t.value!=="function")&&(t.type!=="(punctuator)"||!t.left||!t.left.identifier||t.left.value!=="function")&&!f.isStrict()&&f.option.strict==="global"&&F("E007"),n.block||(!f.option.expr&&(!t||!t.exps)?F("W030",f.tokens.curr):f.option.nonew&&t&&t.left&&t.id==="("&&t.left.id==="new"&&F("W031",n),Lt()),g=e,r&&f.funct["(scope)"].unstack(),t}function Ot(){var e=[],t;while(!f.tokens.next.reach&&f.tokens.next.id!=="(end)")f.tokens.next.id===";"?(t=W(),(!t||t.id!=="("&&t.id!=="[")&&F("W032"),V(";")):e.push(At());return e}function Mt(){var e,t,n;while(f.tokens.next.id==="(string)"){t=W(0);if(t.id==="(endline)"){e=1;do n=W(e++);while(n.id==="(endline)");if(n.id===";")t=n;else{if(n.value==="["||n.value===".")break;(!f.option.asi||n.value==="(")&&F("W033",f.tokens.next)}}else{if(t.id==="."||t.id==="[")break;t.id!==";"&&F("W033",t)}V();var r=f.tokens.curr.value;(f.directive[r]||r==="use strict"&&f.option.strict==="implied")&&F("W034",f.tokens.curr,r),f.directive[r]=!0,t.id===";"&&V(";")}f.isStrict()&&(f.option["(explicitNewcap)"]||(f.option.newcap=!0),f.option.undef=!0)}function _t(e,t,n,i,s){var o,u=m,a=g,l,c,h,p;m=e,c=f.tokens.next;var d=f.funct["(metrics)"];d.nestedBlockDepth+=1,d.verifyMaxNestedBlockDepthPerFunction();if(f.tokens.next.id==="{"){V("{"),f.funct["(scope)"].stack(),h=f.tokens.curr.line;if(f.tokens.next.id!=="}"){g+=f.option.indent;while(!e&&f.tokens.next.from>g)g+=f.option.indent;if(n){l={};for(p in f.directive)r.has(f.directive,p)&&(l[p]=f.directive[p]);Mt(),f.option.strict&&f.funct["(context)"]["(global)"]&&!l["use strict"]&&!f.isStrict()&&F("E007")}o=Ot(),d.statementCount+=o.length,g-=f.option.indent}V("}",c),n&&(f.funct["(scope)"].validateParams(),l&&(f.directive=l)),f.funct["(scope)"].unstack(),g=a}else if(!e)if(n){f.funct["(scope)"].stack(),l={},t&&!i&&!f.inMoz()&&q("W118",f.tokens.curr,"function closure expressions");if(!t)for(p in f.directive)r.has(f.directive,p)&&(l[p]=f.directive[p]);Q(10),f.option.strict&&f.funct["(context)"]["(global)"]&&!l["use strict"]&&!f.isStrict()&&F("E007"),f.funct["(scope)"].unstack()}else q("E021",f.tokens.next,"{",f.tokens.next.value);else f.funct["(noblockscopedvar)"]=f.tokens.next.id!=="for",f.funct["(scope)"].stack(),(!t||f.option.curly)&&F("W116",f.tokens.next,"{",f.tokens.next.value),f.tokens.next.inBracelessBlock=!0,g+=f.option.indent,o=[At()],g-=f.option.indent,f.funct["(scope)"].unstack(),delete f.funct["(noblockscopedvar)"];switch(f.funct["(verb)"]){case"break":case"continue":case"return":case"throw":if(s)break;default:f.funct["(verb)"]=null}return m=u,e&&f.option.noempty&&(!o||o.length===0)&&F("W035",f.tokens.prev),d.nestedBlockDepth-=1,o}function Dt(e){E&&typeof E[e]!="boolean"&&F("W036",f.tokens.curr,e),typeof w[e]=="number"?w[e]+=1:w[e]=1}function Bt(){var e={};e.exps=!0,f.funct["(comparray)"].stack();var t=!1;return f.tokens.next.value!=="for"&&(t=!0,f.inMoz()||F("W116",f.tokens.next,"for",f.tokens.next.value),f.funct["(comparray)"].setState("use"),e.right=Q(10)),V("for"),f.tokens.next.value==="each"&&(V("each"),f.inMoz()||F("W118",f.tokens.curr,"for each")),V("("),f.funct["(comparray)"].setState("define"),e.left=Q(130),r.contains(["in","of"],f.tokens.next.value)?V():q("E045",f.tokens.curr),f.funct["(comparray)"].setState("generate"),Q(10),V(")"),f.tokens.next.value==="if"&&(V("if"),V("("),f.funct["(comparray)"].setState("filter"),e.filter=Q(10),V(")")),t||(f.funct["(comparray)"].setState("use"),e.right=Q(10)),V("]"),f.funct["(comparray)"].unstack(),e}function jt(){return f.funct["(statement)"]&&f.funct["(statement)"].type==="class"||f.funct["(context)"]&&f.funct["(context)"]["(verb)"]==="class"}function Ft(e){return e.identifier||e.id==="(string)"||e.id==="(number)"}function It(e){var t,n=!0;return typeof e=="object"?t=e:(n=e,t=Nt(!1,!0,n)),t?typeof t=="object"&&(t.id==="(string)"||t.id==="(identifier)"?t=t.value:t.id==="(number)"&&(t=t.value.toString())):f.tokens.next.id==="(string)"?(t=f.tokens.next.value,n||V()):f.tokens.next.id==="(number)"&&(t=f.tokens.next.value.toString(),n||V()),t==="hasOwnProperty"&&F("W001"),t}function qt(e){function h(e){f.funct["(scope)"].addParam.apply(f.funct["(scope)"],e)}var t,n=[],i,s=[],o,u=!1,a=!1,l=0,c=e&&e.loneArg;if(c&&c.identifier===!0)return f.funct["(scope)"].addParam(c.value,c),{arity:1,params:[c.value]};t=f.tokens.next,(!e||!e.parsedOpening)&&V("(");if(f.tokens.next.id===")"){V(")");return}for(;;){l++;var p=[];if(r.contains(["{","["],f.tokens.next.id)){s=Gt();for(o in s)o=s[o],o.id&&(n.push(o.id),p.push([o.id,o.token]))}else{pn(f.tokens.next,"...")&&(a=!0),i=Ct(!0);if(i)n.push(i),p.push([i,f.tokens.curr]);else while(!hn(f.tokens.next,[",",")"]))V()}u&&f.tokens.next.id!=="="&&q("W138",f.tokens.current),f.tokens.next.id==="="&&(f.inES6()||F("W119",f.tokens.next,"default parameters","6"),V("="),u=!0,Q(10)),p.forEach(h);if(f.tokens.next.id!==",")return V(")",t),{arity:l,params:n};a&&F("W131",f.tokens.next),tt()}}function Rt(e,t,n){var i={"(name)":e,"(breakage)":0,"(loopage)":0,"(tokens)":{},"(properties)":{},"(catch)":!1,"(global)":!1,"(line)":null,"(character)":null,"(metrics)":null,"(statement)":null,"(context)":null,"(scope)":null,"(comparray)":null,"(generator)":null,"(arrow)":null,"(params)":null};return t&&r.extend(i,{"(line)":t.line,"(character)":t.character,"(metrics)":Vt(t)}),r.extend(i,n),i["(context)"]&&(i["(scope)"]=i["(context)"]["(scope)"],i["(comparray)"]=i["(context)"]["(comparray)"]),i}function Ut(e){return"(scope)"in e}function zt(e){return e["(global)"]&&!e["(verb)"]}function Wt(e){function i(){if(f.tokens.curr.template&&f.tokens.curr.tail&&f.tokens.curr.context===t)return!0;var e=f.tokens.next.template&&f.tokens.next.tail&&f.tokens.next.context===t;return e&&V(),e||f.tokens.next.isUnclosed}var t=this.context,n=this.noSubst,r=this.depth;if(!n)while(!i())!f.tokens.next.template||f.tokens.next.depth>r?Q(0):V();return{id:"(template)",type:"(template)",tag:e}}function Xt(e){var t,n,r,i,s,o,u,a,l=f.option,c=f.ignored;e&&(r=e.name,i=e.statement,s=e.classExprBinding,o=e.type==="generator",u=e.type==="arrow",a=e.ignoreLoopFunc),f.option=Object.create(f.option),f.ignored=Object.create(f.ignored),f.funct=Rt(r||f.nameStack.infer(),f.tokens.next,{"(statement)":i,"(context)":f.funct,"(arrow)":u,"(generator)":o}),t=f.funct,n=f.tokens.curr,n.funct=f.funct,v.push(f.funct),f.funct["(scope)"].stack("functionouter");var h=r||s;h&&f.funct["(scope)"].block.add(h,s?"class":"function",f.tokens.curr,!1),f.funct["(scope)"].stack("functionparams");var p=qt(e);return p?(f.funct["(params)"]=p.params,f.funct["(metrics)"].arity=p.arity,f.funct["(metrics)"].verifyMaxParametersPerFunction()):f.funct["(metrics)"].arity=0,u&&(f.inES6(!0)||F("W119",f.tokens.curr,"arrow function syntax (=>)","6"),e.loneArg||V("=>")),_t(!1,!0,!0,u),!f.option.noyield&&o&&f.funct["(generator)"]!=="yielded"&&F("W124",f.tokens.curr),f.funct["(metrics)"].verifyMaxStatementsPerFunction(),f.funct["(metrics)"].verifyMaxComplexityPerFunction(),f.funct["(unusedOption)"]=f.option.unused,f.option=l,f.ignored=c,f.funct["(last)"]=f.tokens.curr.line,f.funct["(lastcharacter)"]=f.tokens.curr.character,f.funct["(scope)"].unstack(),f.funct["(scope)"].unstack(),f.funct=f.funct["(context)"],!a&&!f.option.loopfunc&&f.funct["(loopage)"]&&t["(isCapturing)"]&&F("W083",n),t}function Vt(e){return{statementCount:0,nestedBlockDepth:-1,ComplexityCount:1,arity:0,verifyMaxStatementsPerFunction:function(){f.option.maxstatements&&this.statementCount>f.option.maxstatements&&F("W071",e,this.statementCount)},verifyMaxParametersPerFunction:function(){r.isNumber(f.option.maxparams)&&this.arity>f.option.maxparams&&F("W072",e,this.arity)},verifyMaxNestedBlockDepthPerFunction:function(){f.option.maxdepth&&this.nestedBlockDepth>0&&this.nestedBlockDepth===f.option.maxdepth+1&&F("W073",null,this.nestedBlockDepth)},verifyMaxComplexityPerFunction:function(){var t=f.option.maxcomplexity,n=this.ComplexityCount;t&&n>t&&F("W074",e,n)}}}function $t(){f.funct["(metrics)"].ComplexityCount+=1}function Jt(e){var t,n;e&&(t=e.id,n=e.paren,t===","&&(e=e.exprs[e.exprs.length-1])&&(t=e.id,n=n||e.paren));switch(t){case"=":case"+=":case"-=":case"*=":case"%=":case"&=":case"|=":case"^=":case"/=":!n&&!f.option.boss&&F("W084")}}function Kt(e){if(f.inES5())for(var t in e)e[t]&&e[t].setterToken&&!e[t].getterToken&&F("W078",e[t].setterToken)}function Qt(e,t){if(pn(f.tokens.next,".")){var n=f.tokens.curr.id;V(".");var r=Ct();return f.tokens.curr.isMetaProperty=!0,e!==r?q("E057",f.tokens.prev,n,r):t(),f.tokens.curr}}function Gt(e){var t=e&&e.assignment;return f.inES6()||F("W104",f.tokens.curr,t?"destructuring assignment":"destructuring binding","6"),Yt(e)}function Yt(e){var t,n=[],r=e&&e.openingParsed,i=e&&e.assignment,s=i?{assignment:i}:null,o=r?f.tokens.curr:f.tokens.next,u=function(){var e;if(hn(f.tokens.next,["[","{"])){t=Yt(s);for(var r in t)r=t[r],n.push({id:r.id,token:r.token})}else if(pn(f.tokens.next,","))n.push({id:null,token:f.tokens.curr});else{if(!pn(f.tokens.next,"(")){var o=pn(f.tokens.next,"...");if(i){var a=o?W(0):f.tokens.next;a.identifier||F("E030",a,a.value);var l=Q(155);l&&(wt(l),l.identifier&&(e=l.value))}else e=Ct();return e&&n.push({id:e,token:f.tokens.curr}),o}V("("),u(),V(")")}return!1},a=function(){var e;pn(f.tokens.next,"[")?(V("["),Q(10),V("]"),V(":"),u()):f.tokens.next.id==="(string)"||f.tokens.next.id==="(number)"?(V(),V(":"),u()):(e=Ct(),pn(f.tokens.next,":")?(V(":"),u()):e&&(i&&wt(f.tokens.curr),n.push({id:e,token:f.tokens.curr})))};if(pn(o,"[")){r||V("["),pn(f.tokens.next,"]")&&F("W137",f.tokens.curr);var l=!1;while(!pn(f.tokens.next,"]"))u()&&!l&&pn(f.tokens.next,",")&&(F("W130",f.tokens.next),l=!0),pn(f.tokens.next,"=")&&(pn(f.tokens.prev,"...")?V("]"):V("="),f.tokens.next.id==="undefined"&&F("W080",f.tokens.prev,f.tokens.prev.value),Q(10)),pn(f.tokens.next,"]")||V(",");V("]")}else if(pn(o,"{")){r||V("{"),pn(f.tokens.next,"}")&&F("W137",f.tokens.curr);while(!pn(f.tokens.next,"}")){a(),pn(f.tokens.next,"=")&&(V("="),f.tokens.next.id==="undefined"&&F("W080",f.tokens.prev,f.tokens.prev.value),Q(10));if(!pn(f.tokens.next,"}")){V(",");if(pn(f.tokens.next,"}"))break}}V("}")}return n}function Zt(e,t){var n=t.first;if(!n)return;r.zip(e,Array.isArray(n)?n:[n]).forEach(function(e){var t=e[0],n=e[1];t&&n?t.first=n:t&&t.first&&!n&&F("W080",t.first,t.first.value)})}function en(e,t,n){var i=n&&n.prefix,s=n&&n.inexport,o=e==="let",u=e==="const",a,l,c,h;f.inES6()||F("W104",f.tokens.curr,e,"6"),o&&f.tokens.next.value==="("?(f.inMoz()||F("W118",f.tokens.next,"let block"),V("("),f.funct["(scope)"].stack(),h=!0):f.funct["(noblockscopedvar)"]&&q("E048",f.tokens.curr,u?"Const":"Let"),t.first=[];for(;;){var p=[];r.contains(["{","["],f.tokens.next.value)?(a=Gt(),l=!1):(a=[{id:Ct(),token:f.tokens.curr}],l=!0),!i&&u&&f.tokens.next.id!=="="&&F("E012",f.tokens.curr,f.tokens.curr.value);for(var d in a)a.hasOwnProperty(d)&&(d=a[d],f.funct["(scope)"].block.isGlobal()&&S[d.id]===!1&&F("W079",d.token,d.id),d.id&&!f.funct["(noblockscopedvar)"]&&(f.funct["(scope)"].addlabel(d.id,{type:e,token:d.token}),p.push(d.token),l&&s&&f.funct["(scope)"].setExported(d.token.value,d.token)));f.tokens.next.id==="="&&(V("="),!i&&f.tokens.next.id==="undefined"&&F("W080",f.tokens.prev,f.tokens.prev.value),!i&&W(0).id==="="&&f.tokens.next.identifier&&F("W120",f.tokens.next,f.tokens.next.value),c=Q(i?120:10),l?a[0].first=c:Zt(p,c)),t.first=t.first.concat(p);if(f.tokens.next.id!==",")break;tt()}return h&&(V(")"),_t(!0,!0),t.block=!0,f.funct["(scope)"].unstack()),t}function sn(e){return f.inES6()||F("W104",f.tokens.curr,"class","6"),e?(this.name=Ct(),f.funct["(scope)"].addlabel(this.name,{type:"class",token:f.tokens.curr})):f.tokens.next.identifier&&f.tokens.next.value!=="extends"?(this.name=Ct(),this.namedExpr=!0):this.name=f.nameStack.infer(),on(this),this}function on(e){var t=f.inClassBody;f.tokens.next.value==="extends"&&(V("extends"),e.heritage=Q(10)),f.inClassBody=!0,V("{"),e.body=un(e),V("}"),f.inClassBody=t}function un(e){var t,n,r,i,s=Object.create(null),o=Object.create(null),u;for(var a=0;f.tokens.next.id!=="}";++a){t=f.tokens.next,n=!1,r=!1,i=null;if(t.id===";"){F("W032"),V(";");continue}t.id==="*"&&(r=!0,V("*"),t=f.tokens.next);if(t.id==="[")t=cn(),u=!0;else{if(!Ft(t)){F("W052",f.tokens.next,f.tokens.next.value||f.tokens.next.type),V();continue}V(),u=!1;if(t.identifier&&t.value==="static"){pn(f.tokens.next,"*")&&(r=!0,V("*"));if(Ft(f.tokens.next)||f.tokens.next.id==="[")u=f.tokens.next.id==="[",n=!0,t=f.tokens.next,f.tokens.next.id==="["?t=cn():V()}t.identifier&&(t.value==="get"||t.value==="set")&&(Ft(f.tokens.next)||f.tokens.next.id==="[")&&(u=f.tokens.next.id==="[",i=t,t=f.tokens.next,f.tokens.next.id==="["?t=cn():V())}if(!pn(f.tokens.next,"(")){q("E054",f.tokens.next,f.tokens.next.value);while(f.tokens.next.id!=="}"&&!pn(f.tokens.next,"("))V();f.tokens.next.value!=="("&&Xt({statement:e})}u||(i?ln(i.value,n?o:s,t.value,t,!0,n):(t.value==="constructor"?f.nameStack.set(e):f.nameStack.set(t),fn(n?o:s,t.value,t,!0,n)));if(i&&t.value==="constructor"){var l=i.value==="get"?"class getter method":"class setter method";q("E049",t,l,"constructor")}else t.value==="prototype"&&q("E049",t,"class method","prototype");It(t),Xt({statement:e,type:r?"generator":null,classExprBinding:e.namedExpr?e.name:null})}Kt(s)}function fn(e,t,n,r,i){var s=["key","class method","static class method"];s=s[(r||!1)+(i||!1)],n.identifier&&(t=n.value),e[t]&&t!=="__proto__"?F("W075",f.tokens.next,s,t):e[t]=Object.create(null),e[t].basic=!0,e[t].basictkn=n}function ln(e,t,n,r,i,s){var o=e==="get"?"getterToken":"setterToken",u="";i?(s&&(u+="static "),u+=e+"ter method"):u="key",f.tokens.curr.accessorType=e,f.nameStack.set(r),t[n]?(t[n].basic||t[n][o])&&n!=="__proto__"&&F("W075",f.tokens.next,u,n):t[n]=Object.create(null),t[n][o]=r}function cn(){V("["),f.inES6()||F("W119",f.tokens.curr,"computed property names","6");var e=Q(10);return V("]"),e}function hn(e,t){return e.type==="(punctuator)"?r.contains(t,e.value):!1}function pn(e,t){return e.type==="(punctuator)"&&e.value===t}function dn(){var e=an();e.notJson?(!f.inES6()&&e.isDestAssign&&F("W104",f.tokens.curr,"destructuring assignment","6"),Ot()):(f.option.laxbreak=!0,f.jsonMode=!0,mn())}function mn(){function e(){var e={},t=f.tokens.next;V("{");if(f.tokens.next.id!=="}")for(;;){if(f.tokens.next.id==="(end)")q("E026",f.tokens.next,t.line);else{if(f.tokens.next.id==="}"){F("W094",f.tokens.curr);break}f.tokens.next.id===","?q("E028",f.tokens.next):f.tokens.next.id!=="(string)"&&F("W095",f.tokens.next,f.tokens.next.value)}e[f.tokens.next.value]===!0?F("W075",f.tokens.next,"key",f.tokens.next.value):f.tokens.next.value==="__proto__"&&!f.option.proto||f.tokens.next.value==="__iterator__"&&!f.option.iterator?F("W096",f.tokens.next,f.tokens.next.value):e[f.tokens.next.value]=!0,V(),V(":"),mn();if(f.tokens.next.id!==",")break;V(",")}V("}")}function t(){var e=f.tokens.next;V("[");if(f.tokens.next.id!=="]")for(;;){if(f.tokens.next.id==="(end)")q("E027",f.tokens.next,e.line);else{if(f.tokens.next.id==="]"){F("W094",f.tokens.curr);break}f.tokens.next.id===","&&q("E028",f.tokens.next)}mn();if(f.tokens.next.id!==",")break;V(",")}V("]")}switch(f.tokens.next.id){case"{":e();break;case"[":t();break;case"true":case"false":case"null":case"(number)":case"(string)":V();break;case"-":V("-"),V("(number)");break;default:q("E003",f.tokens.next)}}var e,t={"<":!0,"<=":!0,"==":!0,"===":!0,"!==":!0,"!=":!0,">":!0,">=":!0,"+":!0,"-":!0,"*":!0,"/":!0,"%":!0},n,d=["closure","exception","global","label","outer","unused","var"],v,m,g,y,b,w,E,S,x,T,N=[],C=new i.EventEmitter,mt={};mt.legacy=["xml","unknown"],mt.es3=["undefined","boolean","number","string","function","object"],mt.es3=mt.es3.concat(mt.legacy),mt.es6=mt.es3.concat("symbol"),at("(number)",function(){return this}),at("(string)",function(){return this}),f.syntax["(identifier)"]={type:"(identifier)",lbp:0,identifier:!0,nud:function(){var e=this.value;return f.tokens.next.id==="=>"?this:(f.funct["(comparray)"].check(e)||f.funct["(scope)"].block.use(e,f.tokens.curr),this)},led:function(){q("E033",f.tokens.next,f.tokens.next.value)}};var Pt={lbp:0,identifier:!1,template:!0};f.syntax["(template)"]=r.extend({type:"(template)",nud:Wt,led:Wt,noSubst:!1},Pt),f.syntax["(template middle)"]=r.extend({type:"(template middle)",middle:!0,noSubst:!1},Pt),f.syntax["(template tail)"]=r.extend({type:"(template tail)",tail:!0,noSubst:!1},Pt),f.syntax["(no subst template)"]=r.extend({type:"(template)",nud:Wt,led:Wt,noSubst:!0,tail:!0},Pt),at("(regexp)",function(){return this}),rt("(endline)"),rt("(begin)"),rt("(end)").reach=!0,rt("(error)").reach=!0,rt("}").reach=!0,rt(")"),rt("]"),rt('"').reach=!0,rt("'").reach=!0,rt(";"),rt(":").reach=!0,rt("#"),ft("else"),ft("case").reach=!0,ft("catch"),ft("default").reach=!0,ft("finally"),ct("arguments",function(e){f.isStrict()&&f.funct["(global)"]&&F("E008",e)}),ct("eval"),ct("false"),ct("Infinity"),ct("null"),ct("this",function(e){f.isStrict()&&!jt()&&!f.option.validthis&&(f.funct["(statement)"]&&f.funct["(name)"].charAt(0)>"Z"||f.funct["(global)"])&&F("W040",e)}),ct("true"),ct("undefined"),Et("=","assign",20),Et("+=","assignadd",20),Et("-=","assignsub",20),Et("*=","assignmult",20),Et("/=","assigndiv",20).nud=function(){q("E014")},Et("%=","assignmod",20),xt("&="),xt("|="),xt("^="),xt("<<="),xt(">>="),xt(">>>="),ht(",",function(e,t){var n;t.exprs=[e],f.option.nocomma&&F("W127");if(!tt({peek:!0}))return t;for(;;){if(!(n=Q(10)))break;t.exprs.push(n);if(f.tokens.next.value!==","||!tt())break}return t},10,!0),ht("?",function(e,t){return $t(),t.left=e,t.right=Q(10),V(":"),t["else"]=Q(10),t},30);var Ht=40;ht("||",function(e,t){return $t(),t.left=e,t.right=Q(Ht),t},Ht),ht("&&","and",50),St("|","bitor",70),St("^","bitxor",80),St("&","bitand",90),dt("==",function(e,t){var n=f.option.eqnull&&((e&&e.value)==="null"||(t&&t.value)==="null");switch(!0){case!n&&f.option.eqeqeq:this.from=this.character,F("W116",this,"===","==");break;case vt(e):F("W041",this,"===",e.value);break;case vt(t):F("W041",this,"===",t.value);break;case gt(t,e,f):F("W122",this,t.value);break;case gt(e,t,f):F("W122",this,e.value)}return this}),dt("===",function(e,t){return gt(t,e,f)?F("W122",this,t.value):gt(e,t,f)&&F("W122",this,e.value),this}),dt("!=",function(e,t){var n=f.option.eqnull&&((e&&e.value)==="null"||(t&&t.value)==="null");return!n&&f.option.eqeqeq?(this.from=this.character,F("W116",this,"!==","!=")):vt(e)?F("W041",this,"!==",e.value):vt(t)?F("W041",this,"!==",t.value):gt(t,e,f)?F("W122",this,t.value):gt(e,t,f)&&F("W122",this,e.value),this}),dt("!==",function(e,t){return gt(t,e,f)?F("W122",this,t.value):gt(e,t,f)&&F("W122",this,e.value),this}),dt("<"),dt(">"),dt("<="),dt(">="),St("<<","shiftleft",120),St(">>","shiftright",120),St(">>>","shiftrightunsigned",120),ht("in","in",120),ht("instanceof","instanceof",120),ht("+",function(e,t){var n;return t.left=e,t.right=n=Q(130),e&&n&&e.id==="(string)"&&n.id==="(string)"?(e.value+=n.value,e.character=n.character,!f.option.scripturl&&a.javascriptURL.test(e.value)&&F("W050",e),e):t},130),ut("+","num"),ut("+++",function(){return F("W007"),this.arity="unary",this.right=Q(150),this}),ht("+++",function(e){return F("W007"),this.left=e,this.right=Q(130),this},130),ht("-","sub",130),ut("-","neg"),ut("---",function(){return F("W006"),this.arity="unary",this.right=Q(150),this}),ht("---",function(e){return F("W006"),this.left=e,this.right=Q(130),this},130),ht("*","mult",140),ht("/","div",140),ht("%","mod",140),Tt("++"),ut("++","preinc"),f.syntax["++"].exps=!0,Tt("--"),ut("--","predec"),f.syntax["--"].exps=!0,ut("delete",function(){var e=Q(10);return e?(e.id!=="."&&e.id!=="["&&F("W051"),this.first=e,e.identifier&&!f.isStrict()&&(e.forgiveUndef=!0),this):this}).exps=!0,ut("~",function(){return f.option.bitwise&&F("W016",this,"~"),this.arity="unary",this.right=Q(150),this}),ut("...",function(){return f.inES6(!0)||F("W119",this,"spread/rest operator","6"),!f.tokens.next.identifier&&f.tokens.next.type!=="(string)"&&!hn(f.tokens.next,["[","("])&&q("E030",f.tokens.next,f.tokens.next.value),Q(150),this}),ut("!",function(){return this.arity="unary",this.right=Q(150),this.right||B("E041",this.line||0),t[this.right.id]===!0&&F("W018",this,"!"),this}),ut("typeof",function(){var e=Q(150);return this.first=this.right=e,e||B("E041",this.line||0,this.character||0),e.identifier&&(e.forgiveUndef=!0),this}),ut("new",function(){var e=Qt("target",function(){f.inES6(!0)||F("W119",f.tokens.prev,"new.target","6");var e,t=f.funct;while(t){e=!t["(global)"];if(!t["(arrow)"])break;t=t["(context)"]}e||F("W136",f.tokens.prev,"new.target")});if(e)return e;var t=Q(155),n;if(t&&t.id!=="function")if(t.identifier){t["new"]=!0;switch(t.value){case"Number":case"String":case"Boolean":case"Math":case"JSON":F("W053",f.tokens.prev,t.value);break;case"Symbol":f.inES6()&&F("W053",f.tokens.prev,t.value);break;case"Function":f.option.evil||F("W054");break;case"Date":case"RegExp":case"this":break;default:t.id!=="function"&&(n=t.value.substr(0,1),f.option.newcap&&(n<"A"||n>"Z")&&!f.funct["(scope)"].isPredefined(t.value)&&F("W055",f.tokens.curr))}}else t.id!=="."&&t.id!=="["&&t.id!=="("&&F("W056",f.tokens.curr);else f.option.supernew||F("W057",this);return f.tokens.next.id!=="("&&!f.option.supernew&&F("W058",f.tokens.curr,f.tokens.curr.value),this.first=this.right=t,this}),f.syntax["new"].exps=!0,ut("void").exps=!0,ht(".",function(e,t){var n=Ct(!1,!0);return typeof n=="string"&&Dt(n),t.left=e,t.right=n,n&&n==="hasOwnProperty"&&f.tokens.next.value==="="&&F("W001"),!e||e.value!=="arguments"||n!=="callee"&&n!=="caller"?!f.option.evil&&e&&e.value==="document"&&(n==="write"||n==="writeln")&&F("W060",e):f.option.noarg?F("W059",e,n):f.isStrict()&&q("E008"),!f.option.evil&&(n==="eval"||n==="execScript")&&yt(e,f)&&F("W061"),t},160,!0),ht("(",function(e,t){f.option.immed&&e&&!e.immed&&e.id==="function"&&F("W062");var n=0,r=[];e&&e.type==="(identifier)"&&e.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)&&"Array Number String Boolean Date Object Error Symbol".indexOf(e.value)===-1&&(e.value==="Math"?F("W063",e):f.option.newcap&&F("W064",e));if(f.tokens.next.id!==")")for(;;){r[r.length]=Q(10),n+=1;if(f.tokens.next.id!==",")break;tt()}return V(")"),typeof e=="object"&&(!f.inES5()&&e.value==="parseInt"&&n===1&&F("W065",f.tokens.curr),f.option.evil||(e.value==="eval"||e.value==="Function"||e.value==="execScript"?(F("W061",e),r[0]&&[0].id==="(string)"&&U(e,r[0].value)):!r[0]||r[0].id!=="(string)"||e.value!=="setTimeout"&&e.value!=="setInterval"?r[0]&&r[0].id==="(string)"&&e.value==="."&&e.left.value==="window"&&(e.right==="setTimeout"||e.right==="setInterval")&&(F("W066",e),U(e,r[0].value)):(F("W066",e),U(e,r[0].value))),!e.identifier&&e.id!=="."&&e.id!=="["&&e.id!=="=>"&&e.id!=="("&&e.id!=="&&"&&e.id!=="||"&&e.id!=="?"&&(!f.inES6()||!e["(name)"])&&F("W067",t)),t.left=e,t},155,!0).exps=!0,ut("(",function(){var e=f.tokens.next,t,n=-1,r,i,s,o,u=1,a=f.tokens.curr,l=f.tokens.prev,c=!f.option.singleGroups;do e.value==="("?u+=1:e.value===")"&&(u-=1),n+=1,t=e,e=W(n);while((u!==0||t.value!==")")&&e.value!==";"&&e.type!=="(end)");f.tokens.next.id==="function"&&(i=f.tokens.next.immed=!0);if(e.value==="=>")return Xt({type:"arrow",parsedOpening:!0});var h=[];if(f.tokens.next.id!==")")for(;;){h.push(Q(10));if(f.tokens.next.id!==",")break;f.option.nocomma&&F("W127"),tt()}V(")",this),f.option.immed&&h[0]&&h[0].id==="function"&&f.tokens.next.id!=="("&&f.tokens.next.id!=="."&&f.tokens.next.id!=="["&&F("W068",this);if(!h.length)return;return h.length>1?(r=Object.create(f.syntax[","]),r.exprs=h,s=h[0],o=h[h.length-1],c||(c=l.assign||l.delim)):(r=s=o=h[0],c||(c=a.beginsStmt&&(r.id==="{"||i||Ut(r))||i&&(!J()||f.tokens.prev.id!=="}")||Ut(r)&&!J()||r.id==="{"&&l.id==="=>"||r.type==="(number)"&&pn(e,".")&&/^\d+$/.test(r.value))),r&&(!c&&(s.left||s.right||r.exprs)&&(c=!K(l)&&s.lbp<=l.lbp||!J()&&o.lbp"),ht("[",function(e,t){var n=Q(10),r;return n&&n.type==="(string)"&&(!f.option.evil&&(n.value==="eval"||n.value==="execScript")&&yt(e,f)&&F("W061"),Dt(n.value),!f.option.sub&&a.identifier.test(n.value)&&(r=f.syntax[n.value],(!r||!O(r))&&F("W069",f.tokens.prev,n.value))),V("]",t),n&&n.value==="hasOwnProperty"&&f.tokens.next.value==="="&&F("W001"),t.left=e,t.right=n,t},160,!0),ut("[",function(){var e=an();if(e.isCompArray)return!f.option.esnext&&!f.inMoz()&&F("W118",f.tokens.curr,"array comprehension"),Bt();if(e.isDestAssign)return this.destructAssign=Gt({openingParsed:!0,assignment:!0}),this;var t=f.tokens.curr.line!==G(f.tokens.next);this.first=[],t&&(g+=f.option.indent,f.tokens.next.from===g+f.option.indent&&(g+=f.option.indent));while(f.tokens.next.id!=="(end)"){while(f.tokens.next.id===","){if(!f.option.elision){if(!!f.inES5()){F("W128");do V(",");while(f.tokens.next.id===",");continue}F("W070")}V(",")}if(f.tokens.next.id==="]")break;this.first.push(Q(10));if(f.tokens.next.id!==",")break;tt({allowTrailing:!0});if(f.tokens.next.id==="]"&&!f.inES5()){F("W070",f.tokens.curr);break}}return t&&(g-=f.option.indent),V("]",this),this}),function(e){e.nud=function(){var e,t,n,r,i,s=!1,o,u=Object.create(null);e=f.tokens.curr.line!==G(f.tokens.next),e&&(g+=f.option.indent,f.tokens.next.from===g+f.option.indent&&(g+=f.option.indent));var a=an();if(a.isDestAssign)return this.destructAssign=Gt({openingParsed:!0,assignment:!0}),this;for(;;){if(f.tokens.next.id==="}")break;o=f.tokens.next.value;if(!f.tokens.next.identifier||X().id!==","&&X().id!=="}")if(W().id===":"||o!=="get"&&o!=="set"){f.tokens.next.value==="*"&&f.tokens.next.type==="(punctuator)"?(f.inES6()||F("W104",f.tokens.next,"generator functions","6"),V("*"),s=!0):s=!1;if(f.tokens.next.id==="[")n=cn(),f.nameStack.set(n);else{f.nameStack.set(f.tokens.next),n=It(),fn(u,n,f.tokens.next);if(typeof n!="string")break}f.tokens.next.value==="("?(f.inES6()||F("W104",f.tokens.curr,"concise methods","6"),Xt({type:s?"generator":null})):(V(":"),Q(10))}else V(o),f.inES5()||q("E034"),n=It(),!n&&!f.inES6()&&q("E035"),n&&ln(o,u,n,f.tokens.curr),i=f.tokens.next,t=Xt(),r=t["(params)"],o==="get"&&n&&r?F("W076",i,r[0],n):o==="set"&&n&&(!r||r.length!==1)&&F("W077",i,n);else f.inES6()||F("W104",f.tokens.next,"object short notation","6"),n=It(!0),fn(u,n,f.tokens.next),Q(10);Dt(n);if(f.tokens.next.id!==",")break;tt({allowTrailing:!0,property:!0}),f.tokens.next.id===","?F("W070",f.tokens.curr):f.tokens.next.id==="}"&&!f.inES5()&&F("W070",f.tokens.curr)}return e&&(g-=f.option.indent),V("}",this),Kt(u),this},e.fud=function(){q("E036",f.tokens.curr)}}(rt("{"));var tn=it("const",function(e){return en("const",this,e)});tn.exps=!0;var nn=it("let",function(e){return en("let",this,e)});nn.exps=!0;var rn=it("var",function(e){var t=e&&e.prefix,n=e&&e.inexport,i,o,u,a=e&&e.implied,l=!e||!e.ignore;this.first=[];for(;;){var c=[];r.contains(["{","["],f.tokens.next.value)?(i=Gt(),o=!1):(i=[{id:Ct(),token:f.tokens.curr}],o=!0),(!t||!a)&&l&&f.option.varstmt&&F("W132",this),this.first=this.first.concat(c);for(var h in i)i.hasOwnProperty(h)&&(h=i[h],!a&&f.funct["(global)"]&&(S[h.id]===!1?F("W079",h.token,h.id):f.option.futurehostile===!1&&(!f.inES5()&&s.ecmaIdentifiers[5][h.id]===!1||!f.inES6()&&s.ecmaIdentifiers[6][h.id]===!1)&&F("W129",h.token,h.id)),h.id&&(a==="for"?(f.funct["(scope)"].has(h.id)||l&&F("W088",h.token,h.id),f.funct["(scope)"].block.use(h.id,h.token)):(f.funct["(scope)"].addlabel(h.id,{type:"var",token:h.token}),o&&n&&f.funct["(scope)"].setExported(h.id,h.token)),c.push(h.token)));f.tokens.next.id==="="&&(f.nameStack.set(f.tokens.curr),V("="),!t&&l&&!f.funct["(loopage)"]&&f.tokens.next.id==="undefined"&&F("W080",f.tokens.prev,f.tokens.prev.value),W(0).id==="="&&f.tokens.next.identifier&&(!t&&l&&!f.funct["(params)"]||f.funct["(params)"].indexOf(f.tokens.next.value)===-1)&&F("W120",f.tokens.next,f.tokens.next.value),u=Q(t?120:10),o?i[0].first=u:Zt(c,u));if(f.tokens.next.id!==",")break;tt()}return this});rn.exps=!0,st("class",function(){return sn.call(this,!0)}),st("function",function(e){var t=e&&e.inexport,n=!1;f.tokens.next.value==="*"&&(V("*"),f.inES6({strict:!0})?n=!0:F("W119",f.tokens.curr,"function*","6")),m&&F("W082",f.tokens.curr);var r=Nt();return f.funct["(scope)"].addlabel(r,{type:"function",token:f.tokens.curr}),r===undefined?F("W025"):t&&f.funct["(scope)"].setExported(r,f.tokens.prev),Xt({name:r,statement:this,type:n?"generator":null,ignoreLoopFunc:m}),f.tokens.next.id==="("&&f.tokens.next.line===f.tokens.curr.line&&q("E039"),this}),ut("function",function(){var e=!1;f.tokens.next.value==="*"&&(f.inES6()||F("W119",f.tokens.curr,"function*","6"),V("*"),e=!0);var t=Nt();return Xt({name:t,type:e?"generator":null}),this}),st("if",function(){var e=f.tokens.next;$t(),f.condition=!0,V("(");var t=Q(0);Jt(t);var n=null;f.option.forin&&f.forinifcheckneeded&&(f.forinifcheckneeded=!1,n=f.forinifchecks[f.forinifchecks.length-1],t.type==="(punctuator)"&&t.value==="!"?n.type="(negative)":n.type="(positive)"),V(")",e),f.condition=!1;var r=_t(!0,!0);return n&&n.type==="(negative)"&&r&&r[0]&&r[0].type==="(identifier)"&&r[0].value==="continue"&&(n.type="(negative-with-continue)"),f.tokens.next.id==="else"&&(V("else"),f.tokens.next.id==="if"||f.tokens.next.id==="switch"?At():_t(!0,!0)),this}),st("try",function(){function t(){V("catch"),V("("),f.funct["(scope)"].stack("catchparams");if(hn(f.tokens.next,["[","{"])){var e=Gt();r.each(e,function(e){e.id&&f.funct["(scope)"].addParam(e.id,e,"exception")})}else f.tokens.next.type!=="(identifier)"?F("E030",f.tokens.next,f.tokens.next.value):f.funct["(scope)"].addParam(Ct(),f.tokens.curr,"exception");f.tokens.next.value==="if"&&(f.inMoz()||F("W118",f.tokens.curr,"catch filter"),V("if"),Q(0)),V(")"),_t(!1),f.funct["(scope)"].unstack()}var e;_t(!0);while(f.tokens.next.id==="catch")$t(),e&&!f.inMoz()&&F("W118",f.tokens.next,"multiple catch blocks"),t(),e=!0;if(f.tokens.next.id==="finally"){V("finally"),_t(!0);return}return e||q("E021",f.tokens.next,"catch",f.tokens.next.value),this}),st("while",function(){var e=f.tokens.next;return f.funct["(breakage)"]+=1,f.funct["(loopage)"]+=1,$t(),V("("),Jt(Q(0)),V(")",e),_t(!0,!0),f.funct["(breakage)"]-=1,f.funct["(loopage)"]-=1,this}).labelled=!0,st("with",function(){var e=f.tokens.next;return f.isStrict()?q("E010",f.tokens.curr):f.option.withstmt||F("W085",f.tokens.curr),V("("),Q(0),V(")",e),_t(!0,!0),this}),st("switch",function(){var e=f.tokens.next,t=!1,n=!1;f.funct["(breakage)"]+=1,V("("),Jt(Q(0)),V(")",e),e=f.tokens.next,V("{"),f.tokens.next.from===g&&(n=!0),n||(g+=f.option.indent),this.cases=[];for(;;)switch(f.tokens.next.id){case"case":switch(f.funct["(verb)"]){case"yield":case"break":case"case":case"continue":case"return":case"switch":case"throw":break;default:f.tokens.curr.caseFallsThrough||F("W086",f.tokens.curr,"case")}V("case"),this.cases.push(Q(0)),$t(),t=!0,V(":"),f.funct["(verb)"]="case";break;case"default":switch(f.funct["(verb)"]){case"yield":case"break":case"continue":case"return":case"throw":break;default:this.cases.length&&(f.tokens.curr.caseFallsThrough||F("W086",f.tokens.curr,"default"))}V("default"),t=!0,V(":");break;case"}":n||(g-=f.option.indent),V("}",e),f.funct["(breakage)"]-=1,f.funct["(verb)"]=undefined;return;case"(end)":q("E023",f.tokens.next,"}");return;default:g+=f.option.indent;if(t)switch(f.tokens.curr.id){case",":q("E040");return;case":":t=!1,Ot();break;default:q("E025",f.tokens.curr);return}else{if(f.tokens.curr.id!==":"){q("E021",f.tokens.next,"case",f.tokens.next.value);return}V(":"),q("E024",f.tokens.curr,":"),Ot()}g-=f.option.indent}return this}).labelled=!0,it("debugger",function(){return f.option.debug||F("W087",this),this}).exps=!0,function(){var e=it("do",function(){f.funct["(breakage)"]+=1,f.funct["(loopage)"]+=1,$t(),this.first=_t(!0,!0),V("while");var e=f.tokens.next;return V("("),Jt(Q(0)),V(")",e),f.funct["(breakage)"]-=1,f.funct["(loopage)"]-=1,this});e.labelled=!0,e.exps=!0}(),st("for",function(){var e,t=f.tokens.next,n=!1,i=null;t.value==="each"&&(i=t,V("each"),f.inMoz()||F("W118",f.tokens.curr,"for each")),$t(),V("(");var s,o=0,u=["in","of"],a=0,l,c;hn(f.tokens.next,["{","["])&&++a;do{s=W(o),++o,hn(s,["{","["])?++a:hn(s,["}","]"])&&--a;if(a<0)break;a===0&&(!l&&pn(s,",")?l=s:!c&&pn(s,"=")&&(c=s))}while(a>0||!r.contains(u,s.value)&&s.value!==";"&&s.type!=="(end)");if(r.contains(u,s.value)){!f.inES6()&&s.value==="of"&&F("W104",s,"for of","6");var h=!c&&!l;c&&q("W133",l,s.value,"initializer is forbidden"),l&&q("W133",l,s.value,"more than one ForBinding"),f.tokens.next.id==="var"?(V("var"),f.tokens.curr.fud({prefix:!0})):f.tokens.next.id==="let"||f.tokens.next.id==="const"?(V(f.tokens.next.id),n=!0,f.funct["(scope)"].stack(),f.tokens.curr.fud({prefix:!0})):Object.create(rn).fud({prefix:!0,implied:"for",ignore:!h}),V(s.value),Q(20),V(")",t),s.value==="in"&&f.option.forin&&(f.forinifcheckneeded=!0,f.forinifchecks===undefined&&(f.forinifchecks=[]),f.forinifchecks.push({type:"(none)"})),f.funct["(breakage)"]+=1,f.funct["(loopage)"]+=1,e=_t(!0,!0);if(s.value==="in"&&f.option.forin){if(f.forinifchecks&&f.forinifchecks.length>0){var p=f.forinifchecks.pop();(e&&e.length>0&&(typeof e[0]!="object"||e[0].value!=="if")||p.type==="(positive)"&&e.length>1||p.type==="(negative)")&&F("W089",this)}f.forinifcheckneeded=!1}f.funct["(breakage)"]-=1,f.funct["(loopage)"]-=1}else{i&&q("E045",i);if(f.tokens.next.id!==";")if(f.tokens.next.id==="var")V("var"),f.tokens.curr.fud();else if(f.tokens.next.id==="let")V("let"),n=!0,f.funct["(scope)"].stack(),f.tokens.curr.fud();else for(;;){Q(0,"for");if(f.tokens.next.id!==",")break;l()}Z(f.tokens.curr),V(";"),f.funct["(loopage)"]+=1,f.tokens.next.id!==";"&&Jt(Q(0)),Z(f.tokens.curr),V(";"),f.tokens.next.id===";"&&q("E021",f.tokens.next,")",";");if(f.tokens.next.id!==")")for(;;){Q(0,"for");if(f.tokens.next.id!==",")break;l()}V(")",t),f.funct["(breakage)"]+=1,_t(!0,!0),f.funct["(breakage)"]-=1,f.funct["(loopage)"]-=1}return n&&f.funct["(scope)"].unstack(),this}).labelled=!0,it("break",function(){var e=f.tokens.next.value;return f.option.asi||Z(this),f.tokens.next.id!==";"&&!f.tokens.next.reach&&f.tokens.curr.line===G(f.tokens.next)?(f.funct["(scope)"].funct.hasBreakLabel(e)||F("W090",f.tokens.next,e),this.first=f.tokens.next,V()):f.funct["(breakage)"]===0&&F("W052",f.tokens.next,this.value),kt(this),this}).exps=!0,it("continue",function(){var e=f.tokens.next.value;return f.funct["(breakage)"]===0&&F("W052",f.tokens.next,this.value),f.funct["(loopage)"]||F("W052",f.tokens.next,this.value),f.option.asi||Z(this),f.tokens.next.id!==";"&&!f.tokens.next.reach&&f.tokens.curr.line===G(f.tokens.next)&&(f.funct["(scope)"].funct.hasBreakLabel(e)||F("W090",f.tokens.next,e),this.first=f.tokens.next,V()),kt(this),this}).exps=!0,it("return",function(){return this.line===G(f.tokens.next)?f.tokens.next.id!==";"&&!f.tokens.next.reach&&(this.first=Q(0),this.first&&this.first.type==="(punctuator)"&&this.first.value==="="&&!this.first.paren&&!f.option.boss&&I("W093",this.first.line,this.first.character)):f.tokens.next.type==="(punctuator)"&&["[","{","+","-"].indexOf(f.tokens.next.value)>-1&&Z(this),kt(this),this}).exps=!0,function(e){e.exps=!0,e.lbp=25}(ut("yield",function(){var e=f.tokens.prev;f.inES6(!0)&&!f.funct["(generator)"]?("(catch)"!==f.funct["(name)"]||!f.funct["(context)"]["(generator)"])&&q("E046",f.tokens.curr,"yield"):f.inES6()||F("W104",f.tokens.curr,"yield","6"),f.funct["(generator)"]="yielded";var t=!1;f.tokens.next.value==="*"&&(t=!0,V("*"));if(this.line===G(f.tokens.next)||!f.inMoz()){if(t||f.tokens.next.id!==";"&&!f.option.asi&&!f.tokens.next.reach&&f.tokens.next.nud)Y(f.tokens.curr,f.tokens.next),this.first=Q(10),this.first.type==="(punctuator)"&&this.first.value==="="&&!this.first.paren&&!f.option.boss&&I("W093",this.first.line,this.first.character);f.inMoz()&&f.tokens.next.id!==")"&&(e.lbp>30||!e.assign&&!J()||e.id==="yield")&&q("E050",this)}else f.option.asi||Z(this);return this})),it("throw",function(){return Z(this),this.first=Q(20),kt(this),this}).exps=!0,it("import",function(){f.inES6()||F("W119",f.tokens.curr,"import","6");if(f.tokens.next.type==="(string)")return V("(string)"),this;if(f.tokens.next.identifier){this.name=Ct(),f.funct["(scope)"].addlabel(this.name,{type:"const",token:f.tokens.curr});if(f.tokens.next.value!==",")return V("from"),V("(string)"),this;V(",")}if(f.tokens.next.id==="*")V("*"),V("as"),f.tokens.next.identifier&&(this.name=Ct(),f.funct["(scope)"].addlabel(this.name,{type:"const",token:f.tokens.curr}));else{V("{");for(;;){if(f.tokens.next.value==="}"){V("}");break}var e;f.tokens.next.type==="default"?(e="default",V("default")):e=Ct(),f.tokens.next.value==="as"&&(V("as"),e=Ct()),f.funct["(scope)"].addlabel(e,{type:"const",token:f.tokens.curr});if(f.tokens.next.value!==","){if(f.tokens.next.value==="}"){V("}");break}q("E024",f.tokens.next,f.tokens.next.value);break}V(",")}}return V("from"),V("(string)"),this}).exps=!0,it("export",function(){var e=!0,t,n;f.inES6()||(F("W119",f.tokens.curr,"export","6"),e=!1),f.funct["(scope)"].block.isGlobal()||(q("E053",f.tokens.curr),e=!1);if(f.tokens.next.value==="*")return V("*"),V("from"),V("(string)"),this;if(f.tokens.next.type==="default"){f.nameStack.set(f.tokens.next),V("default");var r=f.tokens.next.id;if(r==="function"||r==="class")this.block=!0;return t=W(),Q(10),n=t.value,this.block&&(f.funct["(scope)"].addlabel(n,{type:r,token:t}),f.funct["(scope)"].setExported(n,t)),this}if(f.tokens.next.value==="{"){V("{");var i=[];for(;;){f.tokens.next.identifier||q("E030",f.tokens.next,f.tokens.next.value),V(),i.push(f.tokens.curr),f.tokens.next.value==="as"&&(V("as"),f.tokens.next.identifier||q("E030",f.tokens.next,f.tokens.next.value),V());if(f.tokens.next.value!==","){if(f.tokens.next.value==="}"){V("}");break}q("E024",f.tokens.next,f.tokens.next.value);break}V(",")}return f.tokens.next.value==="from"?(V("from"),V("(string)")):e&&i.forEach(function(e){f.funct["(scope)"].setExported(e.value,e)}),this}if(f.tokens.next.id==="var")V("var"),f.tokens.curr.fud({inexport:!0});else if(f.tokens.next.id==="let")V("let"),f.tokens.curr.fud({inexport:!0});else if(f.tokens.next.id==="const")V("const"),f.tokens.curr.fud({inexport:!0});else if(f.tokens.next.id==="function")this.block=!0,V("function"),f.syntax["function"].fud({inexport:!0});else if(f.tokens.next.id==="class"){this.block=!0,V("class");var s=f.tokens.next;f.syntax["class"].fud(),f.funct["(scope)"].setExported(s.value,s)}else q("E024",f.tokens.next,f.tokens.next.value);return this}).exps=!0,lt("abstract"),lt("boolean"),lt("byte"),lt("char"),lt("class",{es5:!0,nud:sn}),lt("double"),lt("enum",{es5:!0}),lt("export",{es5:!0}),lt("extends",{es5:!0}),lt("final"),lt("float"),lt("goto"),lt("implements",{es5:!0,strictOnly:!0}),lt("import",{es5:!0}),lt("int"),lt("interface",{es5:!0,strictOnly:!0}),lt("long"),lt("native"),lt("package",{es5:!0,strictOnly:!0}),lt("private",{es5:!0,strictOnly:!0}),lt("protected",{es5:!0,strictOnly:!0}),lt("public",{es5:!0,strictOnly:!0}),lt("short"),lt("static",{es5:!0,strictOnly:!0}),lt("super",{es5:!0}),lt("synchronized"),lt("transient"),lt("volatile");var an=function(){var e,t,n,r=-1,i=0,s={};hn(f.tokens.curr,["[","{"])&&(i+=1);do{n=r===-1?f.tokens.curr:e,e=r===-1?f.tokens.next:W(r),t=W(r+1),r+=1,hn(e,["[","{"])?i+=1:hn(e,["]","}"])&&(i-=1);if(i===1&&e.identifier&&e.value==="for"&&!pn(n,".")){s.isCompArray=!0,s.notJson=!0;break}if(i===0&&hn(e,["}","]"])){if(t.value==="="){s.isDestAssign=!0,s.notJson=!0;break}if(t.value==="."){s.notJson=!0;break}}pn(e,";")&&(s.isBlock=!0,s.notJson=!0)}while(i>0&&e.id!=="(end)");return s},vn=function(){function i(e){var t=n.variables.filter(function(t){if(t.value===e)return t.undef=!1,e}).length;return t!==0}function s(e){var t=n.variables.filter(function(t){if(t.value===e&&!t.undef)return t.unused===!0&&(t.unused=!1),e}).length;return t===0}var e=function(){this.mode="use",this.variables=[]},t=[],n;return{stack:function(){n=new e,t.push(n)},unstack:function(){n.variables.filter(function(e){e.unused&&F("W098",e.token,e.raw_text||e.value),e.undef&&f.funct["(scope)"].block.use(e.value,e.token)}),t.splice(-1,1),n=t[t.length-1]},setState:function(e){r.contains(["use","define","generate","filter"],e)&&(n.mode=e)},check:function(e){if(!n)return;return n&&n.mode==="use"?(s(e)&&n.variables.push({funct:f.funct,token:f.tokens.curr,value:e,undef:!0,unused:!1}),!0):n&&n.mode==="define"?(i(e)||n.variables.push({funct:f.funct,token:f.tokens.curr,value:e,undef:!1,unused:!0}),!0):n&&n.mode==="generate"?(f.funct["(scope)"].block.use(e,f.tokens.curr),!0):n&&n.mode==="filter"?(s(e)&&f.funct["(scope)"].block.use(e,f.tokens.curr),!0):!1}}},gn=function(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")},yn=function(t,i,o){function U(e,t){if(!e)return;!Array.isArray(e)&&typeof e=="object"&&(e=Object.keys(e)),e.forEach(t)}var a,l,c,d,A,O,M={},P={};i=r.clone(i),f.reset(),i&&i.scope?p.scope=i.scope:(p.errors=[],p.undefs=[],p.internals=[],p.blacklist={},p.scope="(main)"),S=Object.create(null),D(S,s.ecmaIdentifiers[3]),D(S,s.reservedVars),D(S,o||{}),n=Object.create(null);var j=Object.create(null);if(i){U(i.predef||null,function(e){var t,n;e[0]==="-"?(t=e.slice(1),p.blacklist[t]=t,delete S[t]):(n=Object.getOwnPropertyDescriptor(i.predef,e),S[e]=n?n.value:!1)}),U(i.exported||null,function(e){j[e]=!0}),delete i.predef,delete i.exported,O=Object.keys(i);for(c=0;c0&&(e.implieds=u),T.length>0&&(e.urls=T),o=f.funct["(scope)"].getUsedOrDefinedGlobals(),o.length>0&&(e.globals=o);for(r=1;r0&&(e.unused=a);for(s in w)if(typeof w[s]=="number"){e.member=w;break}return e},yn.jshint=yn,yn}();typeof n=="object"&&n&&(n.JSHINT=p)},{"../lodash":"/node_modules/jshint/lodash.js","./lex.js":"/node_modules/jshint/src/lex.js","./messages.js":"/node_modules/jshint/src/messages.js","./options.js":"/node_modules/jshint/src/options.js","./reg.js":"/node_modules/jshint/src/reg.js","./scope-manager.js":"/node_modules/jshint/src/scope-manager.js","./state.js":"/node_modules/jshint/src/state.js","./style.js":"/node_modules/jshint/src/style.js","./vars.js":"/node_modules/jshint/src/vars.js",events:"/node_modules/browserify/node_modules/events/events.js"}],"/node_modules/jshint/src/lex.js":[function(e,t,n){"use strict";function h(){var e=[];return{push:function(t){e.push(t)},check:function(){for(var t=0;t0&&this.context[this.context.length-1].type===e},pushContext:function(e){this.context.push({type:e})},popContext:function(){return this.context.pop()},isContext:function(e){return this.context.length>0&&this.context[this.context.length-1]===e},currentContext:function(){return this.context.length>0&&this.context[this.context.length-1]},getLines:function(){return this._lines=o.lines,this._lines},setLines:function(e){this._lines=e,o.lines=this._lines},peek:function(e){return this.input.charAt(e||0)},skip:function(e){e=e||1,this.char+=e,this.input=this.input.slice(e)},on:function(e,t){e.split(" ").forEach(function(e){this.emitter.on(e,t)}.bind(this))},trigger:function(){this.emitter.emit.apply(this.emitter,Array.prototype.slice.call(arguments))},triggerAsync:function(e,t,n,r){n.push(function(){r()&&this.trigger(e,t)}.bind(this))},scanPunctuator:function(){var e=this.peek(),t,n,r;switch(e){case".":if(/^[0-9]$/.test(this.peek(1)))return null;if(this.peek(1)==="."&&this.peek(2)===".")return{type:l.Punctuator,value:"..."};case"(":case")":case";":case",":case"[":case"]":case":":case"~":case"?":return{type:l.Punctuator,value:e};case"{":return this.pushContext(c.Block),{type:l.Punctuator,value:e};case"}":return this.inContext(c.Block)&&this.popContext(),{type:l.Punctuator,value:e};case"#":return{type:l.Punctuator,value:e};case"":return null}return t=this.peek(1),n=this.peek(2),r=this.peek(3),e===">"&&t===">"&&n===">"&&r==="="?{type:l.Punctuator,value:">>>="}:e==="="&&t==="="&&n==="="?{type:l.Punctuator,value:"==="}:e==="!"&&t==="="&&n==="="?{type:l.Punctuator,value:"!=="}:e===">"&&t===">"&&n===">"?{type:l.Punctuator,value:">>>"}:e==="<"&&t==="<"&&n==="="?{type:l.Punctuator,value:"<<="}:e===">"&&t===">"&&n==="="?{type:l.Punctuator,value:">>="}:e==="="&&t===">"?{type:l.Punctuator,value:e+t}:e===t&&"+-<>&|".indexOf(e)>=0?{type:l.Punctuator,value:e+t}:"<>=!+-*%&|^".indexOf(e)>=0?t==="="?{type:l.Punctuator,value:e+t}:{type:l.Punctuator,value:e}:e==="/"?t==="="?{type:l.Punctuator,value:"/="}:{type:l.Punctuator,value:"/"}:null},scanComments:function(){function u(e,t,n){var r=["jshint","jslint","members","member","globals","global","exported"],i=!1,u=e+t,a="plain";return n=n||{},n.isMultiline&&(u+="*/"),t=t.replace(/\n/g," "),e==="/*"&&s.fallsThrough.test(t)&&(i=!0,a="falls through"),r.forEach(function(n){if(i)return;if(e==="//"&&n!=="jshint")return;t.charAt(n.length)===" "&&t.substr(0,n.length)===n&&(i=!0,e+=n,t=t.substr(n.length)),!i&&t.charAt(0)===" "&&t.charAt(n.length+1)===" "&&t.substr(1,n.length)===n&&(i=!0,e=e+" "+n,t=t.substr(n.length+1));if(!i)return;switch(n){case"member":a="members";break;case"global":a="globals";break;default:var r=t.split(":").map(function(e){return e.replace(/^\s+/,"").replace(/\s+$/,"")});if(r.length===2)switch(r[0]){case"ignore":switch(r[1]){case"start":o.ignoringLinterErrors=!0,i=!1;break;case"end":o.ignoringLinterErrors=!1,i=!1}}a=n}}),{type:l.Comment,commentType:a,value:u,body:t,isSpecial:i,isMultiline:n.isMultiline||!1,isMalformed:n.isMalformed||!1}}var e=this.peek(),t=this.peek(1),n=this.input.substr(2),r=this.line,i=this.char,o=this;if(e==="*"&&t==="/")return this.trigger("error",{code:"E018",line:r,character:i}),this.skip(2),null;if(e!=="/"||t!=="*"&&t!=="/")return null;if(t==="/")return this.skip(this.input.length),u("//",n);var a="";if(t==="*"){this.inComment=!0,this.skip(2);while(this.peek()!=="*"||this.peek(1)!=="/")if(this.peek()===""){a+="\n";if(!this.nextLine())return this.trigger("error",{code:"E017",line:r,character:i}),this.inComment=!1,u("/*",a,{isMultiline:!0,isMalformed:!0})}else a+=this.peek(),this.skip();return this.skip(2),this.inComment=!1,u("/*",a,{isMultiline:!0})}},scanKeyword:function(){var e=/^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input),t=["if","in","do","var","for","new","try","let","this","else","case","void","with","enum","while","break","catch","throw","const","yield","class","super","return","typeof","delete","switch","export","import","default","finally","extends","function","continue","debugger","instanceof"];return e&&t.indexOf(e[0])>=0?{type:l.Keyword,value:e[0]}:null},scanIdentifier:function(){function i(e){return e>256}function s(e){return e>256}function o(e){return/^[0-9a-fA-F]$/.test(e)}function p(e){return e.replace(/\\u([0-9a-fA-F]{4})/g,function(e,t){return String.fromCharCode(parseInt(t,16))})}var e="",t=0,n,r,u=function(){t+=1;if(this.peek(t)!=="u")return null;var e=this.peek(t+1),n=this.peek(t+2),r=this.peek(t+3),i=this.peek(t+4),u;return o(e)&&o(n)&&o(r)&&o(i)?(u=parseInt(e+n+r+i,16),f[u]||s(u)?(t+=5,"\\u"+e+n+r+i):null):null}.bind(this),c=function(){var e=this.peek(t),n=e.charCodeAt(0);return n===92?u():n<128?a[n]?(t+=1,e):null:i(n)?(t+=1,e):null}.bind(this),h=function(){var e=this.peek(t),n=e.charCodeAt(0);return n===92?u():n<128?f[n]?(t+=1,e):null:s(n)?(t+=1,e):null}.bind(this);r=c();if(r===null)return null;e=r;for(;;){r=h();if(r===null)break;e+=r}switch(e){case"true":case"false":n=l.BooleanLiteral;break;case"null":n=l.NullLiteral;break;default:n=l.Identifier}return{type:n,value:p(e),text:e,tokenLength:e.length}},scanNumericLiteral:function(){function f(e){return/^[0-9]$/.test(e)}function c(e){return/^[0-7]$/.test(e)}function h(e){return/^[01]$/.test(e)}function p(e){return/^[0-9a-fA-F]$/.test(e)}function d(e){return e==="$"||e==="_"||e==="\\"||e>="a"&&e<="z"||e>="A"&&e<="Z"}var e=0,t="",n=this.input.length,r=this.peek(e),i,s=f,u=10,a=!1;if(r!=="."&&!f(r))return null;if(r!=="."){t=this.peek(e),e+=1,r=this.peek(e);if(t==="0"){if(r==="x"||r==="X")s=p,u=16,e+=1,t+=r;if(r==="o"||r==="O")s=c,u=8,o.inES6(!0)||this.trigger("warning",{code:"W119",line:this.line,character:this.char,data:["Octal integer literal","6"]}),e+=1,t+=r;if(r==="b"||r==="B")s=h,u=2,o.inES6(!0)||this.trigger("warning",{code:"W119",line:this.line,character:this.char,data:["Binary integer literal","6"]}),e+=1,t+=r;c(r)&&(s=c,u=8,a=!0,i=!1,e+=1,t+=r),!c(r)&&f(r)&&(e+=1,t+=r)}while(e=0&&i<=7&&o.isStrict()});break;case"u":var s=this.input.substr(1,4),u=parseInt(s,16);isNaN(u)&&this.trigger("warning",{code:"W052",line:this.line,character:this.char,data:["u"+s]}),r=String.fromCharCode(u),n=5;break;case"v":this.triggerAsync("warning",{code:"W114",line:this.line,character:this.char,data:["\\v"]},e,function(){return o.jsonMode}),r="\x0b";break;case"x":var a=parseInt(this.input.substr(1,2),16);this.triggerAsync("warning",{code:"W114",line:this.line,character:this.char,data:["\\x-"]},e,function(){return o.jsonMode}),r=String.fromCharCode(a),n=3;break;case"\\":r="\\\\";break;case'"':r='\\"';break;case"/":break;case"":t=!0,r=""}return{"char":r,jump:n,allowNewLine:t}},scanTemplateLiteral:function(e){var t,n="",r,i=this.line,s=this.char,u=this.templateStarts.length;if(!o.inES6(!0))return null;if(this.peek()==="`")t=l.TemplateHead,this.templateStarts.push({line:this.line,"char":this.char}),u=this.templateStarts.length,this.skip(1),this.pushContext(c.Template);else{if(!this.inContext(c.Template)||this.peek()!=="}")return null;t=l.TemplateMiddle}while(this.peek()!=="`"){while((r=this.peek())===""){n+="\n";if(!this.nextLine()){var a=this.templateStarts.pop();return this.trigger("error",{code:"E052",line:a.line,character:a.char}),{type:t,value:n,startLine:i,startChar:s,isUnclosed:!0,depth:u,context:this.popContext()}}}if(r==="$"&&this.peek(1)==="{")return n+="${",this.skip(2),{type:t,value:n,startLine:i,startChar:s,isUnclosed:!1,depth:u,context:this.currentContext()};if(r==="\\"){var f=this.scanEscapeSequence(e);n+=f.char,this.skip(f.jump)}else r!=="`"&&(n+=r,this.skip(1))}return t=t===l.TemplateHead?l.NoSubstTemplate:l.TemplateTail,this.skip(1),this.templateStarts.pop(),{type:t,value:n,startLine:i,startChar:s,isUnclosed:!1,depth:u,context:this.popContext()}},scanStringLiteral:function(e){var t=this.peek();if(t!=='"'&&t!=="'")return null;this.triggerAsync("warning",{code:"W108",line:this.line,character:this.char},e,function(){return o.jsonMode&&t!=='"'});var n="",r=this.line,i=this.char,s=!1;this.skip();while(this.peek()!==t)if(this.peek()===""){s?(s=!1,this.triggerAsync("warning",{code:"W043",line:this.line,character:this.char},e,function(){return!o.option.multistr}),this.triggerAsync("warning",{code:"W042",line:this.line,character:this.char},e,function(){return o.jsonMode&&o.option.multistr})):this.trigger("warning",{code:"W112",line:this.line,character:this.char});if(!this.nextLine())return this.trigger("error",{code:"E029",line:r,character:i}),{type:l.StringLiteral,value:n,startLine:r,startChar:i,isUnclosed:!0,quote:t}}else{s=!1;var u=this.peek(),a=1;u<" "&&this.trigger("warning",{code:"W113",line:this.line,character:this.char,data:[""]});if(u==="\\"){var f=this.scanEscapeSequence(e);u=f.char,a=f.jump,s=f.allowNewLine}n+=u,this.skip(a)}return this.skip(),{type:l.StringLiteral,value:n,startLine:r,startChar:i,isUnclosed:!1,quote:t}},scanRegExp:function(){var e=0,t=this.input.length,n=this.peek(),r=n,i="",s=[],o=!1,u=!1,a,f=function(){n<" "&&(o=!0,this.trigger("warning",{code:"W048",line:this.line,character:this.char})),n==="<"&&(o=!0,this.trigger("warning",{code:"W049",line:this.line,character:this.char,data:[n]}))}.bind(this);if(!this.prereg||n!=="/")return null;e+=1,a=!1;while(e=this.getLines().length)return!1;this.input=this.getLines()[this.line],this.line+=1,this.char=1,this.from=1;var t=this.input.trim(),n=function(){return r.some(arguments,function(e){return t.indexOf(e)===0})},i=function(){return r.some(arguments,function(e){return t.indexOf(e,t.length-e.length)!==-1})};this.ignoringLinterErrors===!0&&!n("/*","//")&&(!this.inComment||!i("*/"))&&(this.input=""),e=this.scanNonBreakingSpaces(),e>=0&&this.trigger("warning",{code:"W125",line:this.line,character:e+1}),this.input=this.input.replace(/\t/g,o.tab),e=this.scanUnsafeChars(),e>=0&&this.trigger("warning",{code:"W100",line:this.line,character:e});if(!this.ignoringLinterErrors&&o.option.maxlen&&o.option.maxlen=0;--t){var n=a[t]["(labels)"];if(n[e])return n}}function x(e){for(var t=a.length-1;t>=0;t--){var n=a[t];if(n["(usages)"][e])return n["(usages)"][e];if(n===l)break}return!1}function T(t,n){if(e.option.shadow!=="outer")return;var r=l["(type)"]==="global",i=u["(type)"]==="functionparams",s=!r;for(var o=0;o1?a[a.length-2]:null,n=u===l,i=u["(type)"]==="functionparams",f=u["(type)"]==="functionouter",p,d,g=u["(usages)"],y=u["(labels)"],E=Object.keys(g);g.__proto__&&E.indexOf("__proto__")===-1&&E.push("__proto__");for(p=0;p=0;s--){var o=a[s];if(o["(labels)"][e]&&(!n||o["(labels)"][e]["(blockscoped)"]))return o["(labels)"][e]["(type)"];var u=r?a[s-1]:o;if(u&&u["(type)"]==="functionparams")return null}return null},hasBreakLabel:function(e){for(var t=a.length-1;t>=0;t--){var n=a[t];if(n["(breakLabels)"][e])return!0;if(n["(type)"]==="functionparams")return!1}return!1},has:function(e,t){return Boolean(this.labeltype(e,t))},add:function(e,t,n,r){u["(labels)"][e]={"(type)":t,"(token)":n,"(blockscoped)":!1,"(function)":l,"(unused)":r}}},block:{isGlobal:function(){return u["(type)"]==="global"},use:function(t,n){var r=l["(parent)"];r&&r["(labels)"][t]&&r["(labels)"][t]["(type)"]==="param"&&(C.funct.has(t,{excludeParams:!0,onlyBlockscoped:!0})||(r["(labels)"][t]["(unused)"]=!1)),n&&(e.ignored.W117||e.option.undef===!1)&&(n.ignoreUndef=!0),g(t),n&&(n["(function)"]=l,u["(usages)"][t]["(tokens)"].push(n))},reassign:function(e,t){this.modify(e,t),u["(usages)"][e]["(reassigned)"].push(t)},modify:function(e,t){g(e),u["(usages)"][e]["(modified)"].push(t)},add:function(e,t,n,r){u["(labels)"][e]={"(type)":t,"(token)":n,"(blockscoped)":!0,"(unused)":r}},addBreakLabel:function(t,n){var r=n.token;C.funct.hasBreakLabel(t)?v("E011",r,t):e.option.shadow==="outer"&&(C.funct.has(t)?v("W004",r,t):T(t,r)),u["(breakLabels)"][t]=r}}};return C};t.exports=o},{"../lodash":"/node_modules/jshint/lodash.js",events:"/node_modules/browserify/node_modules/events/events.js"}],"/node_modules/jshint/src/state.js":[function(e,t,n){"use strict";var r=e("./name-stack.js"),i={syntax:{},isStrict:function(){return this.directive["use strict"]||this.inClassBody||this.option.module||this.option.strict==="implied"},inMoz:function(){return this.option.moz},inES6:function(){return this.option.moz||this.option.esversion>=6},inES5:function(e){return e?(!this.option.esversion||this.option.esversion===5)&&!this.option.moz:!this.option.esversion||this.option.esversion>=5||this.option.moz},reset:function(){this.tokens={prev:null,next:null,curr:null},this.option={},this.funct=null,this.ignored={},this.directive={},this.jsonMode=!1,this.jsonWarnings=[],this.lines=[],this.tab="",this.cache={},this.ignoredLines={},this.forinifcheckneeded=!1,this.nameStack=new r,this.inClassBody=!1}};n.state=i},{"./name-stack.js":"/node_modules/jshint/src/name-stack.js"}],"/node_modules/jshint/src/style.js":[function(e,t,n){"use strict";n.register=function(e){e.on("Identifier",function(n){if(e.getOption("proto"))return;n.name==="__proto__"&&e.warn("W103",{line:n.line,"char":n.char,data:[n.name,"6"]})}),e.on("Identifier",function(n){if(e.getOption("iterator"))return;n.name==="__iterator__"&&e.warn("W103",{line:n.line,"char":n.char,data:[n.name]})}),e.on("Identifier",function(n){if(!e.getOption("camelcase"))return;n.name.replace(/^_+|_+$/g,"").indexOf("_")>-1&&!n.name.match(/^[A-Z0-9_]*$/)&&e.warn("W106",{line:n.line,"char":n.from,data:[n.name]})}),e.on("String",function(n){var r=e.getOption("quotmark"),i;if(!r)return;r==="single"&&n.quote!=="'"&&(i="W109"),r==="double"&&n.quote!=='"'&&(i="W108"),r===!0&&(e.getCache("quotmark")||e.setCache("quotmark",n.quote),e.getCache("quotmark")!==n.quote&&(i="W110")),i&&e.warn(i,{line:n.line,"char":n.char})}),e.on("Number",function(n){n.value.charAt(0)==="."&&e.warn("W008",{line:n.line,"char":n.char,data:[n.value]}),n.value.substr(n.value.length-1)==="."&&e.warn("W047",{line:n.line,"char":n.char,data:[n.value]}),/^00+/.test(n.value)&&e.warn("W046",{line:n.line,"char":n.char,data:[n.value]})}),e.on("String",function(n){var r=/^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i;if(e.getOption("scripturl"))return;r.test(n.value)&&e.warn("W107",{line:n.line,"char":n.char})})}},{}],"/node_modules/jshint/src/vars.js":[function(e,t,n){"use strict";n.reservedVars={arguments:!1,NaN:!1},n.ecmaIdentifiers={3:{Array:!1,Boolean:!1,Date:!1,decodeURI:!1,decodeURIComponent:!1,encodeURI:!1,encodeURIComponent:!1,Error:!1,eval:!1,EvalError:!1,Function:!1,hasOwnProperty:!1,isFinite:!1,isNaN:!1,Math:!1,Number:!1,Object:!1,parseInt:!1,parseFloat:!1,RangeError:!1,ReferenceError:!1,RegExp:!1,String:!1,SyntaxError:!1,TypeError:!1,URIError:!1},5:{JSON:!1},6:{Map:!1,Promise:!1,Proxy:!1,Reflect:!1,Set:!1,Symbol:!1,WeakMap:!1,WeakSet:!1}},n.browser={Audio:!1,Blob:!1,addEventListener:!1,applicationCache:!1,atob:!1,blur:!1,btoa:!1,cancelAnimationFrame:!1,CanvasGradient:!1,CanvasPattern:!1,CanvasRenderingContext2D:!1,CSS:!1,clearInterval:!1,clearTimeout:!1,close:!1,closed:!1,Comment:!1,CustomEvent:!1,DOMParser:!1,defaultStatus:!1,Document:!1,document:!1,DocumentFragment:!1,Element:!1,ElementTimeControl:!1,Event:!1,event:!1,fetch:!1,FileReader:!1,FormData:!1,focus:!1,frames:!1,getComputedStyle:!1,HTMLElement:!1,HTMLAnchorElement:!1,HTMLBaseElement:!1,HTMLBlockquoteElement:!1,HTMLBodyElement:!1,HTMLBRElement:!1,HTMLButtonElement:!1,HTMLCanvasElement:!1,HTMLCollection:!1,HTMLDirectoryElement:!1,HTMLDivElement:!1,HTMLDListElement:!1,HTMLFieldSetElement:!1,HTMLFontElement:!1,HTMLFormElement:!1,HTMLFrameElement:!1,HTMLFrameSetElement:!1,HTMLHeadElement:!1,HTMLHeadingElement:!1,HTMLHRElement:!1,HTMLHtmlElement:!1,HTMLIFrameElement:!1,HTMLImageElement:!1,HTMLInputElement:!1,HTMLIsIndexElement:!1,HTMLLabelElement:!1,HTMLLayerElement:!1,HTMLLegendElement:!1,HTMLLIElement:!1,HTMLLinkElement:!1,HTMLMapElement:!1,HTMLMenuElement:!1,HTMLMetaElement:!1,HTMLModElement:!1,HTMLObjectElement:!1,HTMLOListElement:!1,HTMLOptGroupElement:!1,HTMLOptionElement:!1,HTMLParagraphElement:!1,HTMLParamElement:!1,HTMLPreElement:!1,HTMLQuoteElement:!1,HTMLScriptElement:!1,HTMLSelectElement:!1,HTMLStyleElement:!1,HTMLTableCaptionElement:!1,HTMLTableCellElement:!1,HTMLTableColElement:!1,HTMLTableElement:!1,HTMLTableRowElement:!1,HTMLTableSectionElement:!1,HTMLTemplateElement:!1,HTMLTextAreaElement:!1,HTMLTitleElement:!1,HTMLUListElement:!1,HTMLVideoElement:!1,history:!1,Image:!1,Intl:!1,length:!1,localStorage:!1,location:!1,matchMedia:!1,MessageChannel:!1,MessageEvent:!1,MessagePort:!1,MouseEvent:!1,moveBy:!1,moveTo:!1,MutationObserver:!1,name:!1,Node:!1,NodeFilter:!1,NodeList:!1,Notification:!1,navigator:!1,onbeforeunload:!0,onblur:!0,onerror:!0,onfocus:!0,onload:!0,onresize:!0,onunload:!0,open:!1,openDatabase:!1,opener:!1,Option:!1,parent:!1,performance:!1,print:!1,Range:!1,requestAnimationFrame:!1,removeEventListener:!1,resizeBy:!1,resizeTo:!1,screen:!1,scroll:!1,scrollBy:!1,scrollTo:!1,sessionStorage:!1,setInterval:!1,setTimeout:!1,SharedWorker:!1,status:!1,SVGAElement:!1,SVGAltGlyphDefElement:!1,SVGAltGlyphElement:!1,SVGAltGlyphItemElement:!1,SVGAngle:!1,SVGAnimateColorElement:!1,SVGAnimateElement:!1,SVGAnimateMotionElement:!1,SVGAnimateTransformElement:!1,SVGAnimatedAngle:!1,SVGAnimatedBoolean:!1,SVGAnimatedEnumeration:!1,SVGAnimatedInteger:!1,SVGAnimatedLength:!1,SVGAnimatedLengthList:!1,SVGAnimatedNumber:!1,SVGAnimatedNumberList:!1,SVGAnimatedPathData:!1,SVGAnimatedPoints:!1,SVGAnimatedPreserveAspectRatio:!1,SVGAnimatedRect:!1,SVGAnimatedString:!1,SVGAnimatedTransformList:!1,SVGAnimationElement:!1,SVGCSSRule:!1,SVGCircleElement:!1,SVGClipPathElement:!1,SVGColor:!1,SVGColorProfileElement:!1,SVGColorProfileRule:!1,SVGComponentTransferFunctionElement:!1,SVGCursorElement:!1,SVGDefsElement:!1,SVGDescElement:!1,SVGDocument:!1,SVGElement:!1,SVGElementInstance:!1,SVGElementInstanceList:!1,SVGEllipseElement:!1,SVGExternalResourcesRequired:!1,SVGFEBlendElement:!1,SVGFEColorMatrixElement:!1,SVGFEComponentTransferElement:!1,SVGFECompositeElement:!1,SVGFEConvolveMatrixElement:!1,SVGFEDiffuseLightingElement:!1,SVGFEDisplacementMapElement:!1,SVGFEDistantLightElement:!1,SVGFEFloodElement:!1,SVGFEFuncAElement:!1,SVGFEFuncBElement:!1,SVGFEFuncGElement:!1,SVGFEFuncRElement:!1,SVGFEGaussianBlurElement:!1,SVGFEImageElement:!1,SVGFEMergeElement:!1,SVGFEMergeNodeElement:!1,SVGFEMorphologyElement:!1,SVGFEOffsetElement:!1,SVGFEPointLightElement:!1,SVGFESpecularLightingElement:!1,SVGFESpotLightElement:!1,SVGFETileElement:!1,SVGFETurbulenceElement:!1,SVGFilterElement:!1,SVGFilterPrimitiveStandardAttributes:!1,SVGFitToViewBox:!1,SVGFontElement:!1,SVGFontFaceElement:!1,SVGFontFaceFormatElement:!1,SVGFontFaceNameElement:!1,SVGFontFaceSrcElement:!1,SVGFontFaceUriElement:!1,SVGForeignObjectElement:!1,SVGGElement:!1,SVGGlyphElement:!1,SVGGlyphRefElement:!1,SVGGradientElement:!1,SVGHKernElement:!1,SVGICCColor:!1,SVGImageElement:!1,SVGLangSpace:!1,SVGLength:!1,SVGLengthList:!1,SVGLineElement:!1,SVGLinearGradientElement:!1,SVGLocatable:!1,SVGMPathElement:!1,SVGMarkerElement:!1,SVGMaskElement:!1,SVGMatrix:!1,SVGMetadataElement:!1,SVGMissingGlyphElement:!1,SVGNumber:!1,SVGNumberList:!1,SVGPaint:!1,SVGPathElement:!1,SVGPathSeg:!1,SVGPathSegArcAbs:!1,SVGPathSegArcRel:!1,SVGPathSegClosePath:!1,SVGPathSegCurvetoCubicAbs:!1,SVGPathSegCurvetoCubicRel:!1,SVGPathSegCurvetoCubicSmoothAbs:!1,SVGPathSegCurvetoCubicSmoothRel:!1,SVGPathSegCurvetoQuadraticAbs:!1,SVGPathSegCurvetoQuadraticRel:!1,SVGPathSegCurvetoQuadraticSmoothAbs:!1,SVGPathSegCurvetoQuadraticSmoothRel:!1,SVGPathSegLinetoAbs:!1,SVGPathSegLinetoHorizontalAbs:!1,SVGPathSegLinetoHorizontalRel:!1,SVGPathSegLinetoRel:!1,SVGPathSegLinetoVerticalAbs:!1,SVGPathSegLinetoVerticalRel:!1,SVGPathSegList:!1,SVGPathSegMovetoAbs:!1,SVGPathSegMovetoRel:!1,SVGPatternElement:!1,SVGPoint:!1,SVGPointList:!1,SVGPolygonElement:!1,SVGPolylineElement:!1,SVGPreserveAspectRatio:!1,SVGRadialGradientElement:!1,SVGRect:!1,SVGRectElement:!1,SVGRenderingIntent:!1,SVGSVGElement:!1,SVGScriptElement:!1,SVGSetElement:!1,SVGStopElement:!1,SVGStringList:!1,SVGStylable:!1,SVGStyleElement:!1,SVGSwitchElement:!1,SVGSymbolElement:!1,SVGTRefElement:!1,SVGTSpanElement:!1,SVGTests:!1,SVGTextContentElement:!1,SVGTextElement:!1,SVGTextPathElement:!1,SVGTextPositioningElement:!1,SVGTitleElement:!1,SVGTransform:!1,SVGTransformList:!1,SVGTransformable:!1,SVGURIReference:!1,SVGUnitTypes:!1,SVGUseElement:!1,SVGVKernElement:!1,SVGViewElement:!1,SVGViewSpec:!1,SVGZoomAndPan:!1,Text:!1,TextDecoder:!1,TextEncoder:!1,TimeEvent:!1,top:!1,URL:!1,WebGLActiveInfo:!1,WebGLBuffer:!1,WebGLContextEvent:!1,WebGLFramebuffer:!1,WebGLProgram:!1,WebGLRenderbuffer:!1,WebGLRenderingContext:!1,WebGLShader:!1,WebGLShaderPrecisionFormat:!1,WebGLTexture:!1,WebGLUniformLocation:!1,WebSocket:!1,window:!1,Window:!1,Worker:!1,XDomainRequest:!1,XMLHttpRequest:!1,XMLSerializer:!1,XPathEvaluator:!1,XPathException:!1,XPathExpression:!1,XPathNamespace:!1,XPathNSResolver:!1,XPathResult:!1},n.devel={alert:!1,confirm:!1,console:!1,Debug:!1,opera:!1,prompt:!1},n.worker={importScripts:!0,postMessage:!0,self:!0,FileReaderSync:!0},n.nonstandard={escape:!1,unescape:!1},n.couch={require:!1,respond:!1,getRow:!1,emit:!1,send:!1,start:!1,sum:!1,log:!1,exports:!1,module:!1,provides:!1},n.node={__filename:!1,__dirname:!1,GLOBAL:!1,global:!1,module:!1,require:!1,Buffer:!0,console:!0,exports:!0,process:!0,setTimeout:!0,clearTimeout:!0,setInterval:!0,clearInterval:!0,setImmediate:!0,clearImmediate:!0},n.browserify={__filename:!1,__dirname:!1,global:!1,module:!1,require:!1,Buffer:!0,exports:!0,process:!0},n.phantom={phantom:!0,require:!0,WebPage:!0,console:!0,exports:!0},n.qunit={asyncTest:!1,deepEqual:!1,equal:!1,expect:!1,module:!1,notDeepEqual:!1,notEqual:!1,notPropEqual:!1,notStrictEqual:!1,ok:!1,propEqual:!1,QUnit:!1,raises:!1,start:!1,stop:!1,strictEqual:!1,test:!1,"throws":!1},n.rhino={defineClass:!1,deserialize:!1,gc:!1,help:!1,importClass:!1,importPackage:!1,java:!1,load:!1,loadClass:!1,Packages:!1,print:!1,quit:!1,readFile:!1,readUrl:!1,runCommand:!1,seal:!1,serialize:!1,spawn:!1,sync:!1,toint32:!1,version:!1},n.shelljs={target:!1,echo:!1,exit:!1,cd:!1,pwd:!1,ls:!1,find:!1,cp:!1,rm:!1,mv:!1,mkdir:!1,test:!1,cat:!1,sed:!1,grep:!1,which:!1,dirs:!1,pushd:!1,popd:!1,env:!1,exec:!1,chmod:!1,config:!1,error:!1,tempdir:!1},n.typed={ArrayBuffer:!1,ArrayBufferView:!1,DataView:!1,Float32Array:!1,Float64Array:!1,Int16Array:!1,Int32Array:!1,Int8Array:!1,Uint16Array:!1,Uint32Array:!1,Uint8Array:!1,Uint8ClampedArray:!1},n.wsh={ActiveXObject:!0,Enumerator:!0,GetObject:!0,ScriptEngine:!0,ScriptEngineBuildVersion:!0,ScriptEngineMajorVersion:!0,ScriptEngineMinorVersion:!0,VBArray:!0,WSH:!0,WScript:!0,XDomainRequest:!0},n.dojo={dojo:!1,dijit:!1,dojox:!1,define:!1,require:!1},n.jquery={$:!1,jQuery:!1},n.mootools={$:!1,$$:!1,Asset:!1,Browser:!1,Chain:!1,Class:!1,Color:!1,Cookie:!1,Core:!1,Document:!1,DomReady:!1,DOMEvent:!1,DOMReady:!1,Drag:!1,Element:!1,Elements:!1,Event:!1,Events:!1,Fx:!1,Group:!1,Hash:!1,HtmlTable:!1,IFrame:!1,IframeShim:!1,InputValidator:!1,instanceOf:!1,Keyboard:!1,Locale:!1,Mask:!1,MooTools:!1,Native:!1,Options:!1,OverText:!1,Request:!1,Scroller:!1,Slick:!1,Slider:!1,Sortables:!1,Spinner:!1,Swiff:!1,Tips:!1,Type:!1,typeOf:!1,URI:!1,Window:!1},n.prototypejs={$:!1,$$:!1,$A:!1,$F:!1,$H:!1,$R:!1,$break:!1,$continue:!1,$w:!1,Abstract:!1,Ajax:!1,Class:!1,Enumerable:!1,Element:!1,Event:!1,Field:!1,Form:!1,Hash:!1,Insertion:!1,ObjectRange:!1,PeriodicalExecuter:!1,Position:!1,Prototype:!1,Selector:!1,Template:!1,Toggle:!1,Try:!1,Autocompleter:!1,Builder:!1,Control:!1,Draggable:!1,Draggables:!1,Droppables:!1,Effect:!1,Sortable:!1,SortableObserver:!1,Sound:!1,Scriptaculous:!1},n.yui={YUI:!1,Y:!1,YUI_config:!1},n.mocha={mocha:!1,describe:!1,xdescribe:!1,it:!1,xit:!1,context:!1,xcontext:!1,before:!1,after:!1,beforeEach:!1,afterEach:!1,suite:!1,test:!1,setup:!1,teardown:!1,suiteSetup:!1,suiteTeardown:!1},n.jasmine={jasmine:!1,describe:!1,xdescribe:!1,it:!1,xit:!1,beforeEach:!1,afterEach:!1,setFixtures:!1,loadFixtures:!1,spyOn:!1,expect:!1,runs:!1,waitsFor:!1,waits:!1,beforeAll:!1,afterAll:!1,fail:!1,fdescribe:!1,fit:!1,pending:!1}},{}]},{},["/node_modules/jshint/src/jshint.js"])}),ace.define("ace/mode/nrjavascript_worker",[],function(require,exports,module){"use strict";function startRegex(e){return RegExp("^("+e.join("|")+")")}var oop=require("../lib/oop"),Mirror=require("../worker/mirror").Mirror,lint=require("./javascript/jshint").JSHINT,disabledWarningsRe=startRegex(["Bad for in variable '(.+)'.",'Missing "use strict"']),errorsRe=startRegex(["Unexpected","Expected ","Confusing (plus|minus)","\\{a\\} unterminated regular expression","Unclosed ","Unmatched ","Unbegun comment","Bad invocation","Missing space after","Missing operator at"]),infoRe=startRegex(["Expected an assignment","Bad escapement of EOL","Unexpected comma","Unexpected space","Missing radix parameter.","A leading decimal point can","\\['{a}'\\] is better written in dot notation.","'{a}' used out of scope"]),NRJavaScriptWorker=exports.NRJavaScriptWorker=function(e){Mirror.call(this,e),this.setTimeout(500),this.setOptions()};oop.inherits(NRJavaScriptWorker,Mirror),function(){this.setOptions=function(e){this.options=e||{esnext:!0,moz:!0,devel:!0,browser:!0,node:!0,laxcomma:!0,laxbreak:!0,lastsemic:!0,onevar:!1,passfail:!1,maxerr:100,expr:!0,multistr:!0,globalstrict:!0},this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.changeOptions=function(e){oop.mixin(this.options,e),this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.isValidJS=function(str){try{eval("throw 0;"+str)}catch(e){if(e===0)return!0}return!1},this.onUpdate=function(){var e=this.doc.getValue();e=e.replace(/^#!.*\n/,"\n");if(!e)return this.sender.emit("annotate",[]);e="async function __nodered__(msg) {\n"+e+"\n}";var t=[],n=this.isValidJS(e)?"warning":"error";lint(e,this.options,this.options.globals);var r=lint.errors,i=!1;for(var s=0;s0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+ta)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-flows.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-flows.svg new file mode 100644 index 0000000..0b00692 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-flows.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-full-o.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-full-o.svg new file mode 100644 index 0000000..fc3221f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-full-o.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-full.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-full.svg new file mode 100644 index 0000000..e4448e1 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-nodes-o.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-nodes-o.svg new file mode 100644 index 0000000..af540dd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-nodes-o.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-nodes.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-nodes.svg new file mode 100644 index 0000000..12d4c89 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-nodes.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-reload.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-reload.svg new file mode 100644 index 0000000..00f3190 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/deploy-reload.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/grip.png b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/grip.png new file mode 100644 index 0000000..76c2e0d Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/grip.png differ diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/icons/arrow-in.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/icons/arrow-in.svg new file mode 100644 index 0000000..de75fbe --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/icons/arrow-in.svg @@ -0,0 +1 @@ + diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/node-red-256.png b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/node-red-256.png new file mode 100644 index 0000000..41f70a0 Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/node-red-256.png differ diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/node-red-icon-black.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/node-red-icon-black.svg new file mode 100644 index 0000000..613427a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/node-red-icon-black.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/node-red-icon.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/node-red-icon.svg new file mode 100644 index 0000000..020a903 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/node-red-icon.svg @@ -0,0 +1,33 @@ + + + + Node-RED Icon + + + + image/svg+xml + + Node-RED Icon + + + + Nick O'Leary + + + + + + + + + + + + + + + + + + + diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/node-red.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/node-red.svg new file mode 100644 index 0000000..c62b358 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/node-red.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/spin.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/spin.svg new file mode 100644 index 0000000..e609530 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/spin.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/subflow_tab.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/subflow_tab.svg new file mode 100644 index 0000000..0a0f4b4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/subflow_tab.svg @@ -0,0 +1 @@ + diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/09.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/09.svg new file mode 100644 index 0000000..8e91ec3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/09.svg @@ -0,0 +1 @@ + diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/az.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/az.svg new file mode 100644 index 0000000..9010581 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/az.svg @@ -0,0 +1 @@ + diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/bin.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/bin.svg new file mode 100644 index 0000000..efc427a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/bin.svg @@ -0,0 +1 @@ + diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/bool.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/bool.svg new file mode 100644 index 0000000..8eee384 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/bool.svg @@ -0,0 +1 @@ + diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/env.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/env.svg new file mode 100644 index 0000000..a24515f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/env.svg @@ -0,0 +1 @@ + diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/expr.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/expr.svg new file mode 100644 index 0000000..500ca39 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/expr.svg @@ -0,0 +1 @@ + diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/json.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/json.svg new file mode 100644 index 0000000..978c891 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/json.svg @@ -0,0 +1 @@ + diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/re.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/re.svg new file mode 100644 index 0000000..b44c592 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/re.svg @@ -0,0 +1 @@ + diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/target.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/target.svg new file mode 100644 index 0000000..41ed2e3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/images/typedInput/target.svg @@ -0,0 +1 @@ + diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/comms.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/comms.js new file mode 100644 index 0000000..75a018a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/comms.js @@ -0,0 +1,188 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +RED.comms = (function() { + + var errornotification = null; + var clearErrorTimer = null; + var connectCountdownTimer = null; + var connectCountdown = 10; + var subscriptions = {}; + var ws; + var pendingAuth = false; + var reconnectAttempts = 0; + var active = false; + + function connectWS() { + active = true; + var wspath; + + if (RED.settings.apiRootUrl) { + var m = /^(https?):\/\/(.*)$/.exec(RED.settings.apiRootUrl); + if (m) { + console.log(m); + wspath = "ws"+(m[1]==="https"?"s":"")+"://"+m[2]+"comms"; + } + } else { + var path = location.hostname; + var port = location.port; + if (port.length !== 0) { + path = path+":"+port; + } + path = path+document.location.pathname; + path = path+(path.slice(-1) == "/"?"":"/")+"comms"; + wspath = "ws"+(document.location.protocol=="https:"?"s":"")+"://"+path; + } + + var auth_tokens = RED.settings.get("auth-tokens"); + pendingAuth = (auth_tokens!=null); + + function completeConnection() { + for (var t in subscriptions) { + if (subscriptions.hasOwnProperty(t)) { + ws.send(JSON.stringify({subscribe:t})); + } + } + } + + ws = new WebSocket(wspath); + ws.onopen = function() { + reconnectAttempts = 0; + if (errornotification) { + clearErrorTimer = setTimeout(function() { + errornotification.close(); + errornotification = null; + },1000); + } + if (pendingAuth) { + ws.send(JSON.stringify({auth:auth_tokens.access_token})); + } else { + completeConnection(); + } + } + ws.onmessage = function(event) { + var message = JSON.parse(event.data); + if (message.auth) { + if (pendingAuth) { + if (message.auth === "ok") { + pendingAuth = false; + completeConnection(); + } else if (message.auth === "fail") { + // anything else is an error... + active = false; + RED.user.login({updateMenu:true},function() { + connectWS(); + }) + } + } else if (message.auth === "fail") { + // Our current session has expired + active = false; + RED.user.login({updateMenu:true},function() { + connectWS(); + }) + } + } else { + // Otherwise, 'message' is an array of actual comms messages + for (var m = 0; m < message.length; m++) { + var msg = message[m]; + if (msg.topic) { + for (var t in subscriptions) { + if (subscriptions.hasOwnProperty(t)) { + var re = new RegExp("^"+t.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$"); + if (re.test(msg.topic)) { + var subscribers = subscriptions[t]; + if (subscribers) { + for (var i=0;i 5 && errornotification == null) { + errornotification = RED.notify(RED._("notification.errors.lostConnection"),"error",true); + } + } else if (reconnectAttempts < 20) { + setTimeout(connectWS,2000); + } else { + connectCountdown = 60; + connectCountdownTimer = setInterval(function() { + connectCountdown--; + if (connectCountdown === 0) { + errornotification.update(RED._("notification.errors.lostConnection")); + clearInterval(connectCountdownTimer); + connectWS(); + } else { + var msg = RED._("notification.errors.lostConnectionReconnect",{time: connectCountdown})+' '+ RED._("notification.errors.lostConnectionTry")+''; + errornotification.update(msg,{silent:true}); + $(errornotification).find("a").on("click", function(e) { + e.preventDefault(); + errornotification.update(RED._("notification.errors.lostConnection"),{silent:true}); + clearInterval(connectCountdownTimer); + connectWS(); + }) + } + },1000); + } + + } + } + + function subscribe(topic,callback) { + if (subscriptions[topic] == null) { + subscriptions[topic] = []; + } + subscriptions[topic].push(callback); + if (ws && ws.readyState == 1) { + ws.send(JSON.stringify({subscribe:topic})); + } + } + + function unsubscribe(topic,callback) { + if (subscriptions[topic]) { + for (var i=0;i=0;i--) { + var r = undoEvent(ev.events[i]); + inverseEv.events.push(r); + } + } else if (ev.t == 'replace') { + inverseEv = { + t: 'replace', + config: RED.nodes.createCompleteNodeSet(), + changed: {}, + rev: RED.nodes.version() + }; + RED.nodes.clear(); + var imported = RED.nodes.import(ev.config); + imported[0].forEach(function(n) { + if (ev.changed[n.id]) { + n.changed = true; + inverseEv.changed[n.id] = true; + } + }) + + RED.nodes.version(ev.rev); + } else if (ev.t == 'add') { + inverseEv = { + t: "delete", + }; + if (ev.nodes) { + inverseEv.nodes = []; + for (i=0;i 0) { + subflow = RED.nodes.subflow(ev.subflowInputs[0].z); + subflow.in.push(ev.subflowInputs[0]); + subflow.in[0].dirty = true; + } + if (ev.subflowOutputs && ev.subflowOutputs.length > 0) { + subflow = RED.nodes.subflow(ev.subflowOutputs[0].z); + ev.subflowOutputs.sort(function(a,b) { return a.i-b.i}); + for (i=0;i= output.i) { + l.sourcePort++; + } + } + }); + } + } + if (ev.subflow) { + inverseEv.subflow = {}; + if (ev.subflow.hasOwnProperty('instances')) { + inverseEv.subflow.instances = []; + ev.subflow.instances.forEach(function(n) { + inverseEv.subflow.instances.push(n); + var node = RED.nodes.node(n.id); + if (node) { + node.changed = n.changed; + node.dirty = true; + } + }); + } + if (ev.subflow.hasOwnProperty('status')) { + subflow = RED.nodes.subflow(ev.subflow.id); + subflow.status = ev.subflow.status; + } + } + if (subflow) { + RED.nodes.filterNodes({type:"subflow:"+subflow.id}).forEach(function(n) { + n.inputs = subflow.in.length; + n.outputs = subflow.out.length; + while (n.outputs > n.ports.length) { + n.ports.push(n.ports.length); + } + n.resize = true; + n.dirty = true; + }); + } + if (ev.nodes) { + inverseEv.nodes = []; + for (i=0;i ev.subflow.inputCount) { + inverseEv.subflow.inputs = ev.node.in.slice(ev.subflow.inputCount); + ev.node.in.splice(ev.subflow.inputCount); + } else if (ev.subflow.inputs.length > 0) { + ev.node.in = ev.node.in.concat(ev.subflow.inputs); + } + } + if (ev.subflow.hasOwnProperty('outputCount')) { + inverseEv.subflow.outputCount = ev.node.out.length; + if (ev.node.out.length > ev.subflow.outputCount) { + inverseEv.subflow.outputs = ev.node.out.slice(ev.subflow.outputCount); + ev.node.out.splice(ev.subflow.outputCount); + } else if (ev.subflow.outputs.length > 0) { + ev.node.out = ev.node.out.concat(ev.subflow.outputs); + } + } + if (ev.subflow.hasOwnProperty('instances')) { + inverseEv.subflow.instances = []; + ev.subflow.instances.forEach(function(n) { + inverseEv.subflow.instances.push(n); + var node = RED.nodes.node(n.id); + if (node) { + node.changed = n.changed; + node.dirty = true; + } + }); + } + if (ev.subflow.hasOwnProperty('status')) { + if (ev.subflow.status) { + delete ev.node.status; + } + } + RED.editor.validateNode(ev.node); + RED.nodes.filterNodes({type:"subflow:"+ev.node.id}).forEach(function(n) { + n.inputs = ev.node.in.length; + n.outputs = ev.node.out.length; + RED.editor.updateNodeProperties(n); + RED.editor.validateNode(n); + }); + } else { + var outputMap; + if (ev.outputMap) { + outputMap = {}; + inverseEv.outputMap = {}; + for (var port in ev.outputMap) { + if (ev.outputMap.hasOwnProperty(port) && ev.outputMap[port] !== "-1") { + outputMap[ev.outputMap[port]] = port; + inverseEv.outputMap[ev.outputMap[port]] = port; + } + } + } + RED.editor.updateNodeProperties(ev.node,outputMap); + RED.editor.validateNode(ev.node); + } + if (ev.links) { + inverseEv.createdLinks = []; + for (i=0;i -1) { + return preferredLangs[i] + } + } + return 'end-US' + }, + loadNodeCatalog: function(namespace,done) { + var languageList = i18n.functions.toLanguages(localStorage.getItem("editor-language")||i18n.detectLanguage()); + var toLoad = languageList.length; + languageList.forEach(function(lang) { + $.ajax({ + headers: { + "Accept":"application/json" + }, + cache: false, + url: apiRootUrl+'nodes/'+namespace+'/messages?lng='+lang, + success: function(data) { + i18n.addResourceBundle(lang,namespace,data); + toLoad--; + if (toLoad === 0) { + done(); + } + } + }); + }) + + }, + + loadNodeCatalogs: function(done) { + var languageList = i18n.functions.toLanguages(localStorage.getItem("editor-language")||i18n.detectLanguage()); + var toLoad = languageList.length; + + languageList.forEach(function(lang) { + $.ajax({ + headers: { + "Accept":"application/json" + }, + cache: false, + url: apiRootUrl+'nodes/messages?lng='+lang, + success: function(data) { + var namespaces = Object.keys(data); + namespaces.forEach(function(ns) { + i18n.addResourceBundle(lang,ns,data[ns]); + }); + toLoad--; + if (toLoad === 0) { + done(); + } + } + }); + }) + } + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/jquery-addons.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/jquery-addons.js new file mode 100644 index 0000000..c2bcaa7 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/jquery-addons.js @@ -0,0 +1,35 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +/** + * Trigger enabled/disabled events when element.prop("disabled",false/true) is + * called. + * Used by RED.popover to hide a popover when the trigger element is disabled + * as a disabled element doesn't emit mouseleave + */ +jQuery.propHooks.disabled = { + set: function (element, value) { + if (element.disabled !== value) { + element.disabled = value; + if (value) { + $(element).trigger('disabled'); + } else { + $(element).trigger('enabled'); + } + } + } +}; diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/keymap.json b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/keymap.json new file mode 100644 index 0000000..2677321 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/keymap.json @@ -0,0 +1,58 @@ +{ + "*": { + "alt-shift-p":"core:manage-palette", + "ctrl-f": "core:search", + "ctrl-shift-f": "core:list-flows", + "ctrl-=": "core:zoom-in", + "ctrl--": "core:zoom-out", + "ctrl-0": "core:zoom-reset", + "ctrl-enter": "core:confirm-edit-tray", + "ctrl-escape": "core:cancel-edit-tray", + "ctrl-d": "core:deploy-flows", + "ctrl-g i": "core:show-info-tab", + "ctrl-g d": "core:show-debug-tab", + "ctrl-g c": "core:show-config-tab", + "ctrl-g x": "core:show-context-tab", + "ctrl-e": "core:show-export-dialog", + "ctrl-i": "core:show-import-dialog", + "ctrl-space": "core:toggle-sidebar", + "ctrl-p": "core:toggle-palette", + "ctrl-,": "core:show-user-settings", + "ctrl-alt-l": "core:clear-debug-messages", + "ctrl-alt-r": "core:show-remote-diff", + "ctrl-alt-n": "core:new-project", + "ctrl-alt-o": "core:open-project", + "ctrl-g v": "core:show-version-control-tab", + "ctrl-shift-l": "core:show-event-log", + "ctrl-shift-p":"core:show-action-list" + }, + "red-ui-sidebar-node-config": { + "backspace": "core:delete-config-selection", + "delete": "core:delete-config-selection", + "ctrl-a": "core:select-all-config-nodes", + "ctrl-z": "core:undo", + "ctrl-y": "core:redo" + }, + "red-ui-workspace": { + "backspace": "core:delete-selection", + "delete": "core:delete-selection", + "enter": "core:edit-selected-node", + "ctrl-c": "core:copy-selection-to-internal-clipboard", + "ctrl-x": "core:cut-selection-to-internal-clipboard", + "ctrl-v": "core:paste-from-internal-clipboard", + "ctrl-z": "core:undo", + "ctrl-y": "core:redo", + "ctrl-a": "core:select-all-nodes", + "shift-?": "core:show-help", + "up": "core:move-selection-up", + "right": "core:move-selection-right", + "down": "core:move-selection-down", + "left": "core:move-selection-left", + "shift-up": "core:step-selection-up", + "shift-right": "core:step-selection-right", + "shift-down": "core:step-selection-down", + "shift-left": "core:step-selection-left", + "ctrl-shift-j": "core:show-previous-tab", + "ctrl-shift-k": "core:show-next-tab" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/main.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/main.js new file mode 100644 index 0000000..7aeea16 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/main.js @@ -0,0 +1,24 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +$(function() { + if ((window.location.hostname !== "localhost") && (window.location.hostname !== "127.0.0.1")) { + document.title = document.title+" : "+window.location.hostname; + } + RED.init({ + apiRootUrl: "" + }); +}); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/nodes.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/nodes.js new file mode 100644 index 0000000..5c0778f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/nodes.js @@ -0,0 +1,1575 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.nodes = (function() { + + var node_defs = {}; + var nodes = []; + var nodeTabMap = {}; + + var configNodes = {}; + var links = []; + var defaultWorkspace; + var workspaces = {}; + var workspacesOrder =[]; + var subflows = {}; + var loadedFlowVersion = null; + + var initialLoad; + + var dirty = false; + + function setDirty(d) { + dirty = d; + RED.events.emit("nodes:change",{dirty:dirty}); + } + + var registry = (function() { + var moduleList = {}; + var nodeList = []; + var nodeSets = {}; + var typeToId = {}; + var nodeDefinitions = {}; + var iconSets = {}; + + nodeDefinitions['tab'] = { + defaults: { + label: {value:""}, + disabled: {value: false}, + info: {value: ""} + } + }; + + + var exports = { + setModulePendingUpdated: function(module,version) { + moduleList[module].pending_version = version; + RED.events.emit("registry:module-updated",{module:module,version:version}); + }, + getModule: function(module) { + return moduleList[module]; + }, + getNodeSetForType: function(nodeType) { + return exports.getNodeSet(typeToId[nodeType]); + }, + getModuleList: function() { + return moduleList; + }, + getNodeList: function() { + return nodeList; + }, + getNodeTypes: function() { + return Object.keys(nodeDefinitions); + }, + setNodeList: function(list) { + nodeList = []; + for(var i=0;i n.outputs)) { n.outputs = n.wires.length; } + if (n.outputs) { + for (var i=0;idiv:not(.node-input-env-container-row)"); + var height = size.height; + // for (var i=0; idiv.node-input-env-container-row"); + // height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); + $("ol.red-ui-editor-subflow-env-list").editableList('height',height); + }, + set:{ + module: "node-red" + } + }); + sf._def = RED.nodes.getType("subflow:"+sf.id); + } + function getSubflow(id) { + return subflows[id]; + } + function removeSubflow(sf) { + delete subflows[sf.id]; + delete nodeTabMap[sf.id]; + registry.removeNodeType("subflow:"+sf.id); + } + + function subflowContains(sfid,nodeid) { + for (var i=0;i 0) { + node.credentials = credentialSet; + } + } + } + if (n._def.category != "config") { + node.x = n.x; + node.y = n.y; + node.wires = []; + for(var i=0;i 0 && n.inputLabels && !/^\s*$/.test(n.inputLabels.join(""))) { + node.inputLabels = n.inputLabels.slice(); + } + if (n.outputs > 0 && n.outputLabels && !/^\s*$/.test(n.outputLabels.join(""))) { + node.outputLabels = n.outputLabels.slice(); + } + if ((!n._def.defaults || !n._def.defaults.hasOwnProperty("icon")) && n.icon) { + var defIcon = RED.utils.getDefaultNodeIcon(n._def, n); + if (n.icon !== defIcon.module+"/"+defIcon.file) { + node.icon = n.icon; + } + } + if ((!n._def.defaults || !n._def.defaults.hasOwnProperty("l")) && n.hasOwnProperty('l')) { + var isLink = /^link (in|out)$/.test(node.type); + if (isLink == n.l) { + node.l = n.l; + } + } + } + if (n.info) { + node.info = n.info; + } + return node; + } + + function convertSubflow(n) { + var node = {}; + node.id = n.id; + node.type = n.type; + node.name = n.name; + node.info = n.info; + node.category = n.category; + node.in = []; + node.out = []; + node.env = n.env; + node.color = n.color; + + n.in.forEach(function(p) { + var nIn = {x:p.x,y:p.y,wires:[]}; + var wires = links.filter(function(d) { return d.source === p }); + for (var i=0;i 0 && n.inputLabels && !/^\s*$/.test(n.inputLabels.join(""))) { + node.inputLabels = n.inputLabels.slice(); + } + if (node.out.length > 0 && n.outputLabels && !/^\s*$/.test(n.outputLabels.join(""))) { + node.outputLabels = n.outputLabels.slice(); + } + if (n.icon) { + if (n.icon !== "node-red/subflow.svg") { + node.icon = n.icon; + } + } + if (n.status) { + node.status = {x: n.status.x, y: n.status.y, wires:[]}; + links.forEach(function(d) { + if (d.target === n.status) { + if (d.source.type != "subflow") { + node.status.wires.push({id:d.source.id, port:d.sourcePort}) + } else { + node.status.wires.push({id:n.id, port:0}) + } + } + }); + } + + return node; + } + /** + * Converts the current node selection to an exportable JSON Object + **/ + function createExportableNodeSet(set, exportedSubflows, exportedConfigNodes) { + var nns = []; + exportedConfigNodes = exportedConfigNodes || {}; + exportedSubflows = exportedSubflows || {}; + for (var n=0;n 0) { + var typeList = "
  • "+unknownTypes.join("
  • ")+"
"; + RED.notify("

"+RED._("clipboard.importUnrecognised",{count:unknownTypes.length})+"

"+typeList,"error",false,10000); + } + + var activeWorkspace = RED.workspaces.active(); + //TODO: check the z of the subflow instance and check _that_ if it exists + var activeSubflow = getSubflow(activeWorkspace); + for (i=0;i node.outputs) { + if (!node._def.defaults.hasOwnProperty("outputs") || !isNaN(parseInt(n.outputs))) { + // If 'wires' is longer than outputs, clip wires + console.log("Warning: node.wires longer than node.outputs - trimming wires:",node.id," wires:",node.wires.length," outputs:",node.outputs); + node.wires = node.wires.slice(0,node.outputs); + } else { + // The node declares outputs in its defaults, but has not got a valid value + // Defer to the length of the wires array + node.outputs = node.wires.length; + } + } + for (d in node._def.defaults) { + if (node._def.defaults.hasOwnProperty(d) && d !== 'inputs' && d !== 'outputs') { + node[d] = n[d]; + node._config[d] = JSON.stringify(n[d]); + } + } + node._config.x = node.x; + node._config.y = node.y; + if (node._def.hasOwnProperty('credentials') && n.hasOwnProperty('credentials')) { + node.credentials = {}; + for (d in node._def.credentials) { + if (node._def.credentials.hasOwnProperty(d) && n.credentials.hasOwnProperty(d)) { + node.credentials[d] = n.credentials[d]; + } + } + } + } + } + addNode(node); + RED.editor.validateNode(node); + node_map[n.id] = node; + // If an 'unknown' config node, it will not have been caught by the + // proper config node handling, so needs adding to new_nodes here + if (node.type === "unknown" || node._def.category !== "config") { + new_nodes.push(node); + } + } + } + } + // TODO: make this a part of the node definition so it doesn't have to + // be hardcoded here + var nodeTypeArrayReferences = { + "catch":"scope", + "status":"scope", + "complete": "scope", + "link in":"links", + "link out":"links" + } + + // Remap all wires and config node references + for (i=0;i",node_map[wires[w2]].id); + } + } + } + } + delete n.wires; + } + for (var d3 in n._def.defaults) { + if (n._def.defaults.hasOwnProperty(d3)) { + if (n._def.defaults[d3].type && node_map[n[d3]]) { + n[d3] = node_map[n[d3]].id; + configNode = RED.nodes.node(n[d3]); + if (configNode && configNode.users.indexOf(n) === -1) { + configNode.users.push(n); + } + } else if (nodeTypeArrayReferences.hasOwnProperty(n.type) && nodeTypeArrayReferences[n.type] === d3 && n[d3] !== undefined && n[d3] !== null) { + for (var j = 0;j 0) { + var reimportList = []; + replaceNodeIds.forEach(function(id) { + var n = replaceNodes[id]; + if (configNodes.hasOwnProperty(n.id)) { + delete configNodes[n.id]; + } else { + nodes.splice(nodes.indexOf(n),1); + } + reimportList.push(convertNode(n)); + }); + + // Remove any links between nodes that are going to be reimported. + // This prevents a duplicate link from being added. + var removeLinks = []; + RED.nodes.eachLink(function(l) { + if (replaceNodes.hasOwnProperty(l.source.id) && replaceNodes.hasOwnProperty(l.target.id)) { + removeLinks.push(l); + } + }); + removeLinks.forEach(removeLink); + + + RED.view.redraw(true); + var result = importNodes(reimportList,false); + var newNodeMap = {}; + result[0].forEach(function(n) { + newNodeMap[n.id] = n; + }); + RED.nodes.eachLink(function(l) { + if (newNodeMap.hasOwnProperty(l.source.id)) { + l.source = newNodeMap[l.source.id]; + } + if (newNodeMap.hasOwnProperty(l.target.id)) { + l.target = newNodeMap[l.target.id]; + } + }); + RED.view.redraw(true); + } + }); + }, + registry:registry, + setNodeList: registry.setNodeList, + + getNodeSet: registry.getNodeSet, + addNodeSet: registry.addNodeSet, + removeNodeSet: registry.removeNodeSet, + enableNodeSet: registry.enableNodeSet, + disableNodeSet: registry.disableNodeSet, + + setIconSets: registry.setIconSets, + getIconSets: registry.getIconSets, + + registerType: registry.registerNodeType, + getType: registry.getNodeType, + convertNode: convertNode, + + add: addNode, + remove: removeNode, + clear: clear, + + moveNodeToTab: moveNodeToTab, + + addLink: addLink, + removeLink: removeLink, + + addWorkspace: addWorkspace, + removeWorkspace: removeWorkspace, + getWorkspaceOrder: function() { return workspacesOrder }, + setWorkspaceOrder: function(order) { workspacesOrder = order; }, + workspace: getWorkspace, + + addSubflow: addSubflow, + removeSubflow: removeSubflow, + subflow: getSubflow, + subflowContains: subflowContains, + + eachNode: function(cb) { + for (var n=0;n/.exec(nodeConfig.trim()); + var moduleId; + if (m) { + moduleId = m[1]; + } else { + moduleId = "unknown"; + } + try { + var hasDeferred = false; + + var nodeConfigEls = $("
"+nodeConfig+"
"); + var scripts = nodeConfigEls.find("script"); + var scriptCount = scripts.length; + scripts.each(function(i,el) { + var srcUrl = $(el).attr('src'); + if (srcUrl && !/^\s*(https?:|\/|\.)/.test(srcUrl)) { + $(el).remove(); + var newScript = document.createElement("script"); + newScript.onload = function() { + scriptCount--; + if (scriptCount === 0) { + $("#red-ui-editor-node-configs").append(nodeConfigEls); + done() + } + } + if ($(el).attr('type') === "module") { + newScript.type = "module"; + } + $("#red-ui-editor-node-configs").append(newScript); + newScript.src = RED.settings.apiRootUrl+srcUrl; + hasDeferred = true; + } else { + if (/\/ace.js$/.test(srcUrl) || /\/ext-language_tools.js$/.test(srcUrl)) { + // Block any attempts to load ace.js from a CDN - this will + // break the version of ace included in the editor. + // At the time of commit, the contrib-python nodes did this. + // This is a crude fix until the python nodes are fixed. + console.warn("Blocked attempt to load",srcUrl,"by",moduleId) + $(el).remove(); + } + scriptCount--; + } + }) + if (!hasDeferred) { + $("#red-ui-editor-node-configs").append(nodeConfigEls); + done(); + } + } catch(err) { + RED.notify(RED._("notification.errors.failedToAppendNode",{module:moduleId, error:err.toString()}),{ + type: "error", + timeout: 10000 + }); + console.log("["+moduleId+"] "+err.toString()); + done(); + } + } + + function loadNodeList() { + $.ajax({ + headers: { + "Accept":"application/json" + }, + cache: false, + url: 'nodes', + success: function(data) { + RED.nodes.setNodeList(data); + RED.i18n.loadNodeCatalogs(function() { + loadIconList(loadNodes); + }); + } + }); + } + + function loadIconList(done) { + $.ajax({ + headers: { + "Accept":"application/json" + }, + cache: false, + url: 'icons', + success: function(data) { + RED.nodes.setIconSets(data); + if (done) { + done(); + } + } + }); + } + + function loadNodes() { + var lang = localStorage.getItem("editor-language")||i18n.detectLanguage(); + + $.ajax({ + headers: { + "Accept":"text/html", + "Accept-Language": lang + }, + cache: false, + url: 'nodes', + success: function(data) { + var configs = data.trim().split(/(?=)/); + var stepConfig = function() { + if (configs.length === 0) { + $("#red-ui-editor").i18n(); + $("#red-ui-palette > .red-ui-palette-spinner").hide(); + $(".red-ui-palette-scroll").removeClass("hide"); + $("#red-ui-palette-search").removeClass("hide"); + loadFlows(function() { + if (RED.settings.theme("projects.enabled",false)) { + RED.projects.refresh(function(activeProject) { + RED.sidebar.info.refresh() + if (!activeProject) { + // Projects enabled but no active project + RED.menu.setDisabled('menu-item-projects-open',true); + RED.menu.setDisabled('menu-item-projects-settings',true); + if (activeProject === false) { + // User previously decline the migration to projects. + } else { // null/undefined + RED.projects.showStartup(); + } + } + completeLoad(); + }); + } else { + // Projects disabled by the user + RED.sidebar.info.refresh() + completeLoad(); + } + }); + } else { + var config = configs.shift(); + appendNodeConfig(config,stepConfig); + } + } + stepConfig(); + } + }); + } + + function loadFlows(done) { + $.ajax({ + headers: { + "Accept":"application/json", + }, + cache: false, + url: 'flows', + success: function(nodes) { + if (nodes) { + var currentHash = window.location.hash; + RED.nodes.version(nodes.rev); + RED.nodes.import(nodes.flows); + RED.nodes.dirty(false); + RED.view.redraw(true); + if (/^#flow\/.+$/.test(currentHash)) { + RED.workspaces.show(currentHash.substring(6)); + } + } + done(); + } + }); + } + + function completeLoad() { + var persistentNotifications = {}; + RED.comms.subscribe("notification/#",function(topic,msg) { + var parts = topic.split("/"); + var notificationId = parts[1]; + if (notificationId === "runtime-deploy") { + // handled in ui/deploy.js + return; + } + if (notificationId === "node") { + // handled below + return; + } + if (notificationId === "project-update") { + RED.nodes.clear(); + RED.history.clear(); + RED.view.redraw(true); + RED.projects.refresh(function() { + loadFlows(function() { + var project = RED.projects.getActiveProject(); + var message = { + "change-branch": RED._("notification.project.change-branch", {project: project.git.branches.local}), + "merge-abort": RED._("notification.project.merge-abort"), + "loaded": RED._("notification.project.loaded", {project: msg.project}), + "updated": RED._("notification.project.updated", {project: msg.project}), + "pull": RED._("notification.project.pull", {project: msg.project}), + "revert": RED._("notification.project.revert", {project: msg.project}), + "merge-complete": RED._("notification.project.merge-complete") + }[msg.action]; + RED.notify("

"+message+"

"); + RED.sidebar.info.refresh() + }); + }); + return; + } + + if (msg.text) { + msg.default = msg.text; + var text = RED._(msg.text,msg); + var options = { + type: msg.type, + fixed: msg.timeout === undefined, + timeout: msg.timeout, + id: notificationId + } + if (notificationId === "runtime-state") { + if (msg.error === "safe-mode") { + options.buttons = [ + { + text: RED._("common.label.close"), + click: function() { + persistentNotifications[notificationId].hideNotification(); + } + } + ] + } else if (msg.error === "missing-types") { + text+="
  • "+msg.types.map(RED.utils.sanitize).join("
  • ")+"
"; + if (!!RED.projects.getActiveProject()) { + options.buttons = [ + { + text: RED._("notification.label.manage-project-dep"), + click: function() { + persistentNotifications[notificationId].hideNotification(); + RED.projects.settings.show('deps'); + } + } + ] + // } else if (RED.settings.theme('palette.editable') !== false) { + } else { + options.buttons = [ + { + text: RED._("common.label.close"), + click: function() { + persistentNotifications[notificationId].hideNotification(); + } + } + ] + } + } else if (msg.error === "credentials_load_failed") { + if (RED.settings.theme("projects.enabled",false)) { + // projects enabled + if (RED.user.hasPermission("projects.write")) { + options.buttons = [ + { + text: RED._("notification.project.setupCredentials"), + click: function() { + persistentNotifications[notificationId].hideNotification(); + RED.projects.showCredentialsPrompt(); + } + } + ] + } + } else { + options.buttons = [ + { + text: RED._("common.label.close"), + click: function() { + persistentNotifications[notificationId].hideNotification(); + } + } + ] + } + } else if (msg.error === "missing_flow_file") { + if (RED.user.hasPermission("projects.write")) { + options.buttons = [ + { + text: RED._("notification.project.setupProjectFiles"), + click: function() { + persistentNotifications[notificationId].hideNotification(); + RED.projects.showFilesPrompt(); + } + } + ] + } + } else if (msg.error === "missing_package_file") { + if (RED.user.hasPermission("projects.write")) { + options.buttons = [ + { + text: RED._("notification.project.setupProjectFiles"), + click: function() { + persistentNotifications[notificationId].hideNotification(); + RED.projects.showFilesPrompt(); + } + } + ] + } + } else if (msg.error === "project_empty") { + if (RED.user.hasPermission("projects.write")) { + options.buttons = [ + { + text: RED._("notification.project.no"), + click: function() { + persistentNotifications[notificationId].hideNotification(); + } + }, + { + text: RED._("notification.project.createDefault"), + click: function() { + persistentNotifications[notificationId].hideNotification(); + RED.projects.createDefaultFileSet(); + } + } + ] + } + } else if (msg.error === "git_merge_conflict") { + RED.nodes.clear(); + RED.sidebar.versionControl.refresh(true); + if (RED.user.hasPermission("projects.write")) { + options.buttons = [ + { + text: RED._("notification.project.mergeConflict"), + click: function() { + persistentNotifications[notificationId].hideNotification(); + RED.sidebar.versionControl.showLocalChanges(); + } + } + ] + } + } + } + if (!persistentNotifications.hasOwnProperty(notificationId)) { + persistentNotifications[notificationId] = RED.notify(text,options); + } else { + persistentNotifications[notificationId].update(text,options); + } + } else if (persistentNotifications.hasOwnProperty(notificationId)) { + persistentNotifications[notificationId].close(); + delete persistentNotifications[notificationId]; + } + }); + RED.comms.subscribe("status/#",function(topic,msg) { + var parts = topic.split("/"); + var node = RED.nodes.node(parts[1]); + if (node) { + if (msg.hasOwnProperty("text") && /^[a-zA-Z]/.test(msg.text)) { + msg.text = node._(msg.text.toString(),{defaultValue:msg.text.toString()}); + } + node.status = msg; + node.dirtyStatus = true; + node.dirty = true; + RED.view.redraw(); + } + }); + RED.comms.subscribe("notification/node/#",function(topic,msg) { + var i,m; + var typeList; + var info; + if (topic == "notification/node/added") { + var addedTypes = []; + msg.forEach(function(m) { + var id = m.id; + RED.nodes.addNodeSet(m); + addedTypes = addedTypes.concat(m.types); + RED.i18n.loadNodeCatalog(id, function() { + $.get('nodes/'+id, function(data) { + appendNodeConfig(data); + }); + }); + }); + if (addedTypes.length) { + typeList = "
  • "+addedTypes.join("
  • ")+"
"; + RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success"); + } + loadIconList(); + } else if (topic == "notification/node/removed") { + for (i=0;i
  • ")+"
  • "; + RED.notify(RED._("palette.event.nodeRemoved", {count:m.types.length})+typeList,"success"); + } + } + loadIconList(); + } else if (topic == "notification/node/enabled") { + if (msg.types) { + info = RED.nodes.getNodeSet(msg.id); + if (info.added) { + RED.nodes.enableNodeSet(msg.id); + typeList = "
    • "+msg.types.join("
    • ")+"
    "; + RED.notify(RED._("palette.event.nodeEnabled", {count:msg.types.length})+typeList,"success"); + } else { + $.get('nodes/'+msg.id, function(data) { + appendNodeConfig(data); + typeList = "
    • "+msg.types.join("
    • ")+"
    "; + RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success"); + }); + } + } + } else if (topic == "notification/node/disabled") { + if (msg.types) { + RED.nodes.disableNodeSet(msg.id); + typeList = "
    • "+msg.types.join("
    • ")+"
    "; + RED.notify(RED._("palette.event.nodeDisabled", {count:msg.types.length})+typeList,"success"); + } + } else if (topic == "notification/node/upgraded") { + RED.notify(RED._("palette.event.nodeUpgraded", {module:msg.module,version:msg.version}),"success"); + RED.nodes.registry.setModulePendingUpdated(msg.module,msg.version); + } + }); + RED.comms.subscribe("event-log/#", function(topic,payload) { + var id = topic.substring(9); + RED.eventLog.log(id,payload); + }); + } + + function showAbout() { + $.get('red/about', function(data) { + var aboutHeader = '
    '+ + ''+ + '
    '; + + RED.sidebar.info.set(aboutHeader+RED.utils.renderMarkdown(data)); + RED.sidebar.info.show(); + }); + } + + function buildMainMenu() { + var menuOptions = []; + if (RED.settings.theme("projects.enabled",false)) { + menuOptions.push({id:"menu-item-projects-menu",label:RED._("menu.label.projects"),options:[ + {id:"menu-item-projects-new",label:RED._("menu.label.projects-new"),disabled:false,onselect:"core:new-project"}, + {id:"menu-item-projects-open",label:RED._("menu.label.projects-open"),disabled:false,onselect:"core:open-project"}, + {id:"menu-item-projects-settings",label:RED._("menu.label.projects-settings"),disabled:false,onselect:"core:show-project-settings"} + ]}); + } + menuOptions.push({id:"menu-item-view-menu",label:RED._("menu.label.view.view"),options:[ + {id:"menu-item-palette",label:RED._("menu.label.palette.show"),toggle:true,onselect:"core:toggle-palette", selected: true}, + {id:"menu-item-sidebar",label:RED._("menu.label.sidebar.show"),toggle:true,onselect:"core:toggle-sidebar", selected: true}, + {id:"menu-item-event-log",label:RED._("eventLog.title"),onselect:"core:show-event-log"}, + {id:"menu-item-action-list",label:RED._("keyboard.actionList"),onselect:"core:show-action-list"}, + null + ]}); + menuOptions.push(null); + if (RED.settings.theme("menu.menu-item-import-library", true)) { + menuOptions.push({id: "menu-item-import", label: RED._("menu.label.import"), onselect: "core:show-import-dialog"}); + } + if (RED.settings.theme("menu.menu-item-export-library", true)) { + menuOptions.push({id: "menu-item-export", label: RED._("menu.label.export"), onselect: "core:show-export-dialog"}); + } + menuOptions.push(null); + menuOptions.push({id:"menu-item-search",label:RED._("menu.label.search"),onselect:"core:search"}); + menuOptions.push(null); + menuOptions.push({id:"menu-item-config-nodes",label:RED._("menu.label.displayConfig"),onselect:"core:show-config-tab"}); + menuOptions.push({id:"menu-item-workspace",label:RED._("menu.label.flows"),options:[ + {id:"menu-item-workspace-add",label:RED._("menu.label.add"),onselect:"core:add-flow"}, + {id:"menu-item-workspace-edit",label:RED._("menu.label.rename"),onselect:"core:edit-flow"}, + {id:"menu-item-workspace-delete",label:RED._("menu.label.delete"),onselect:"core:remove-flow"} + ]}); + menuOptions.push({id:"menu-item-subflow",label:RED._("menu.label.subflows"), options: [ + {id:"menu-item-subflow-create",label:RED._("menu.label.createSubflow"),onselect:"core:create-subflow"}, + {id:"menu-item-subflow-convert",label:RED._("menu.label.selectionToSubflow"),disabled:true,onselect:"core:convert-to-subflow"}, + ]}); + menuOptions.push(null); + if (RED.settings.theme('palette.editable') !== false) { + menuOptions.push({id:"menu-item-edit-palette",label:RED._("menu.label.editPalette"),onselect:"core:manage-palette"}); + menuOptions.push(null); + } + + menuOptions.push({id:"menu-item-user-settings",label:RED._("menu.label.settings"),onselect:"core:show-user-settings"}); + menuOptions.push(null); + + if (RED.settings.theme("menu.menu-item-keyboard-shortcuts", true)) { + menuOptions.push({id: "menu-item-keyboard-shortcuts", label: RED._("menu.label.keyboardShortcuts"), onselect: "core:show-help"}); + } + menuOptions.push({id:"menu-item-help", + label: RED.settings.theme("menu.menu-item-help.label",RED._("menu.label.help")), + href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs") + }); + menuOptions.push({id:"menu-item-node-red-version", label:"v"+RED.settings.version, onselect: "core:show-about" }); + + + $('
  • ').appendTo(".red-ui-header-toolbar") + RED.menu.init({id:"red-ui-header-button-sidemenu",options: menuOptions}); + + } + + function loadEditor() { + + RED.workspaces.init(); + RED.statusBar.init(); + RED.view.init(); + RED.userSettings.init(); + RED.user.init(); + RED.notifications.init(); + RED.library.init(); + RED.keyboard.init(); + RED.palette.init(); + RED.eventLog.init(); + + if (RED.settings.theme('palette.editable') !== false) { + RED.palette.editor.init(); + } else { + console.log("Palette editor disabled"); + } + + RED.sidebar.init(); + + if (RED.settings.theme("projects.enabled",false)) { + RED.projects.init(); + } else { + console.log("Projects disabled"); + } + + RED.subflow.init(); + RED.clipboard.init(); + RED.search.init(); + RED.actionList.init(); + RED.editor.init(); + RED.diff.init(); + + + RED.deploy.init(RED.settings.theme("deployButton",null)); + + buildMainMenu(); + + RED.nodes.init(); + RED.comms.connect(); + + $("#red-ui-main-container").show(); + $(".red-ui-header-toolbar").show(); + + RED.actions.add("core:show-about", showAbout); + + loadNodeList(); + } + + function buildEditor(options) { + var header = $('
    ').appendTo(options.target); + var logo = $('').appendTo(header); + $('
      ').appendTo(header); + $('
      ').appendTo(header); + $('
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      ').appendTo(options.target); + $('
      ').appendTo(options.target); + $('
      ').appendTo(options.target); + $.getJSON(options.apiRootUrl+"theme", function(theme) { + if (theme.header) { + if (theme.header.url) { + logo = $("",{href:theme.header.url}).appendTo(logo); + } + if (theme.header.image) { + $('',{src:theme.header.image}).appendTo(logo); + } + if (theme.header.title) { + $('').html(theme.header.title).appendTo(logo); + } + } + }); + } + + var initialised = false; + + function init(options) { + if (initialised) { + throw new Error("RED already initialised"); + } + initialised = true; + ace.require("ace/ext/language_tools"); + options = options || {}; + options.apiRootUrl = options.apiRootUrl || ""; + if (options.apiRootUrl && !/\/$/.test(options.apiRootUrl)) { + options.apiRootUrl = options.apiRootUrl+"/"; + } + options.target = $("#red-ui-editor"); + options.target.addClass("red-ui-editor"); + + buildEditor(options); + RED.i18n.init(options, function() { + RED.settings.init(options, loadEditor); + }) + } + + return { + init: init + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/settings.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/settings.js new file mode 100644 index 0000000..7601655 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/settings.js @@ -0,0 +1,233 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +RED.settings = (function () { + + var loadedSettings = {}; + var userSettings = {}; + var settingsDirty = false; + var pendingSave; + + var hasLocalStorage = function () { + try { + return 'localStorage' in window && window['localStorage'] !== null; + } catch (e) { + return false; + } + }; + + var set = function (key, value) { + if (!hasLocalStorage()) { + return; + } + if (key === "auth-tokens") { + localStorage.setItem(key, JSON.stringify(value)); + } else { + RED.utils.setMessageProperty(userSettings,key,value); + saveUserSettings(); + } + }; + + /** + * If the key is not set in the localStorage it returns undefined + * Else return the JSON parsed value + * @param key + * @param defaultIfUndefined + * @returns {*} + */ + var get = function (key,defaultIfUndefined) { + if (!hasLocalStorage()) { + return undefined; + } + if (key === "auth-tokens") { + return JSON.parse(localStorage.getItem(key)); + } else { + var v; + try { + v = RED.utils.getMessageProperty(userSettings,key); + if (v === undefined) { + v = defaultIfUndefined; + } + } catch(err) { + v = defaultIfUndefined; + } + return v; + } + }; + + var remove = function (key) { + if (!hasLocalStorage()) { + return; + } + if (key === "auth-tokens") { + localStorage.removeItem(key); + } else { + delete userSettings[key]; + saveUserSettings(); + } + }; + + var setProperties = function(data) { + for (var prop in loadedSettings) { + if (loadedSettings.hasOwnProperty(prop) && RED.settings.hasOwnProperty(prop)) { + delete RED.settings[prop]; + } + } + for (prop in data) { + if (data.hasOwnProperty(prop)) { + RED.settings[prop] = data[prop]; + } + } + loadedSettings = data; + }; + + var setUserSettings = function(data) { + userSettings = data; + } + + var init = function (options, done) { + var accessTokenMatch = /[?&]access_token=(.*?)(?:$|&)/.exec(window.location.search); + if (accessTokenMatch) { + var accessToken = accessTokenMatch[1]; + RED.settings.set("auth-tokens",{access_token: accessToken}); + window.location.search = ""; + } + RED.settings.apiRootUrl = options.apiRootUrl; + + $.ajaxSetup({ + beforeSend: function(jqXHR,settings) { + // Only attach auth header for requests to relative paths + if (!/^\s*(https?:|\/|\.)/.test(settings.url)) { + if (options.apiRootUrl) { + settings.url = options.apiRootUrl+settings.url; + } + var auth_tokens = RED.settings.get("auth-tokens"); + if (auth_tokens) { + jqXHR.setRequestHeader("Authorization","Bearer "+auth_tokens.access_token); + } + jqXHR.setRequestHeader("Node-RED-API-Version","v2"); + } + } + }); + + load(done); + } + + var load = function(done) { + $.ajax({ + headers: { + "Accept": "application/json" + }, + dataType: "json", + cache: false, + url: 'settings', + success: function (data) { + setProperties(data); + if (!RED.settings.user || RED.settings.user.anonymous) { + RED.settings.remove("auth-tokens"); + } + console.log("Node-RED: " + data.version); + console.groupCollapsed("Versions"); + console.log("jQuery",$().jquery) + console.log("jQuery UI",$.ui.version); + console.log("ACE",ace.version); + console.log("D3",d3.version); + console.groupEnd(); + loadUserSettings(done); + }, + error: function(jqXHR,textStatus,errorThrown) { + if (jqXHR.status === 401) { + if (/[?&]access_token=(.*?)(?:$|&)/.test(window.location.search)) { + window.location.search = ""; + } + RED.user.login(function() { load(done); }); + } else { + console.log("Unexpected error loading settings:",jqXHR.status,textStatus); + } + } + }); + }; + + function loadUserSettings(done) { + $.ajax({ + headers: { + "Accept": "application/json" + }, + dataType: "json", + cache: false, + url: 'settings/user', + success: function (data) { + setUserSettings(data); + done(); + }, + error: function(jqXHR,textStatus,errorThrown) { + console.log("Unexpected error loading user settings:",jqXHR.status,textStatus); + } + }); + } + + function saveUserSettings() { + if (RED.user.hasPermission("settings.write")) { + if (pendingSave) { + clearTimeout(pendingSave); + } + pendingSave = setTimeout(function() { + pendingSave = null; + $.ajax({ + method: 'POST', + contentType: 'application/json', + url: 'settings/user', + data: JSON.stringify(userSettings), + success: function (data) { + }, + error: function(jqXHR,textStatus,errorThrown) { + console.log("Unexpected error saving user settings:",jqXHR.status,textStatus); + } + }); + },300); + } + } + + function theme(property,defaultValue) { + if (!RED.settings.editorTheme) { + return defaultValue; + } + var parts = property.split("."); + var v = RED.settings.editorTheme; + try { + for (var i=0;i= 0x05d0 && c <= 0x05ff)|| + (c >= 0x0600 && c <= 0x065f)|| + (c >= 0x066a && c <= 0x06ef)|| + (c >= 0x06fa && c <= 0x07ff)|| + (c >= 0xfb1d && c <= 0xfdff)|| + (c >= 0xfe70 && c <= 0xfefc); + } + + function isLatinChar(c){ + return (c > 64 && c < 91)||(c > 96 && c < 123) + } + + /** + * Determines the text direction of a given string. + * @param value - the string + */ + function resolveBaseTextDir(value) { + if (textDir == "auto") { + if (isRTLValue(value)) { + return "rtl"; + } else { + return "ltr"; + } + } + else { + return textDir; + } + } + + function onInputChange() { + $(this).attr("dir", resolveBaseTextDir($(this).val())); + } + + /** + * Adds event listeners to the Input to ensure its text-direction attribute + * is properly set based on its content. + * @param input - the input field + */ + function prepareInput(input) { + input.on("keyup",onInputChange).on("paste",onInputChange).on("cut",onInputChange); + // Set the initial text direction + onInputChange.call(input); + } + + /** + * Enforces the text direction of a given string by adding + * UCC (Unicode Control Characters) + * @param value - the string + */ + function enforceTextDirectionWithUCC(value) { + if (value) { + var dir = resolveBaseTextDir(value); + if (dir == "ltr") { + return LRE + value + PDF; + } + else if (dir == "rtl") { + return RLE + value + PDF; + } + } + return value; + } + + /** + * Enforces the text direction for all the spans with style red-ui-text-bidi-aware under + * workspace or sidebar div + */ + function enforceTextDirectionOnPage() { + $("#red-ui-workspace").find('span.red-ui-text-bidi-aware').each(function() { + $(this).attr("dir", resolveBaseTextDir($(this).html())); + }); + $("#red-ui-sidebar").find('span.red-ui-text-bidi-aware').each(function() { + $(this).attr("dir", resolveBaseTextDir($(this).text())); + }); + } + + /** + * Sets the text direction preference + * @param dir - the text direction preference + */ + function setTextDirection(dir) { + textDir = dir; + RED.nodes.eachNode(function(n) { n.dirty = true;}); + RED.view.redraw(); + RED.palette.refresh(); + enforceTextDirectionOnPage(); + } + + return { + setTextDirection: setTextDirection, + enforceTextDirectionWithUCC: enforceTextDirectionWithUCC, + resolveBaseTextDir: resolveBaseTextDir, + prepareInput: prepareInput + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/text/format.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/text/format.js new file mode 100644 index 0000000..0afe5a8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/text/format.js @@ -0,0 +1,1330 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.text.format = (function() { + + var TextSegment = (function() { + var TextSegment = function (obj) { + this.content = ""; + this.actual = ""; + this.textDirection = ""; + this.localGui = ""; + this.isVisible = true; + this.isSeparator = false; + this.isParsed = false; + this.keep = false; + this.inBounds = false; + this.inPoints = false; + var prop = ""; + for (prop in obj) { + if (obj.hasOwnProperty(prop)) { + this[prop] = obj[prop]; + } + } + }; + return TextSegment; + })(); + + var tools = (function() { + function initBounds(bounds) { + if (!bounds) { + return false; + } + if (typeof(bounds.start) === "undefined") { + bounds.start = ""; + } + if (typeof(bounds.end) === "undefined") { + bounds.end = ""; + } + if (typeof(bounds.startAfter) !== "undefined") { + bounds.start = bounds.startAfter; + bounds.after = true; + } else { + bounds.after = false; + } + if (typeof(bounds.endBefore) !== "undefined") { + bounds.end = bounds.endBefore; + bounds.before = true; + } else { + bounds.before = false; + } + var startPos = parseInt(bounds.startPos, 10); + if (!isNaN(startPos)) { + bounds.usePos = true; + } else { + bounds.usePos = false; + } + var bLength = parseInt(bounds.length, 10); + if (!isNaN(bLength)) { + bounds.useLength = true; + } else { + bounds.useLength = false; + } + bounds.loops = typeof(bounds.loops) !== "undefined" ? !!bounds.loops : true; + return true; + } + + function getBounds(segment, src) { + var bounds = {}; + for (var prop in src) { + if (src.hasOwnProperty(prop)) { + bounds[prop] = src[prop]; + } + } + var content = segment.content; + var usePos = bounds.usePos && bounds.startPos < content.length; + if (usePos) { + bounds.start = ""; + bounds.loops = false; + } + bounds.bStart = usePos ? bounds.startPos : bounds.start.length > 0 ? content.indexOf(bounds.start) : 0; + var useLength = bounds.useLength && bounds.length > 0 && bounds.bStart + bounds.length < content.length; + if (useLength) { + bounds.end = ""; + } + bounds.bEnd = useLength ? bounds.bStart + bounds.length : bounds.end.length > 0 ? + content.indexOf(bounds.end, bounds.bStart + bounds.start.length) + 1 : content.length; + if (!bounds.after) { + bounds.start = ""; + } + if (!bounds.before) { + bounds.end = ""; + } + return bounds; + } + + return { + handleSubcontents: function (segments, args, subs, origContent, locale) { // jshint unused: false + if (!subs.content || typeof(subs.content) !== "string" || subs.content.length === 0) { + return segments; + } + var sLoops = true; + if (typeof(subs.loops) !== "undefined") { + sLoops = !!subs.loops; + } + for (var j = 0; true; j++) { + if (j >= segments.length) { + break; + } + if (segments[j].isParsed || segments.keep || segments[j].isSeparator) { + continue; + } + var content = segments[j].content; + var start = content.indexOf(subs.content); + if (start < 0) { + continue; + } + var end; + var length = 0; + if (subs.continued) { + do { + length++; + end = content.indexOf(subs.content, start + length * subs.content.length); + } while (end === 0); + } else { + length = 1; + } + end = start + length * subs.content.length; + segments.splice(j, 1); + if (start > 0) { + segments.splice(j, 0, new TextSegment({ + content: content.substring(0, start), + localGui: args.dir, + keep: true + })); + j++; + } + segments.splice(j, 0, new TextSegment({ + content: content.substring(start, end), + textDirection: subs.subDir, + localGui: args.dir + })); + if (end < content.length) { + segments.splice(j + 1, 0, new TextSegment({ + content: content.substring(end, content.length), + localGui: args.dir, + keep: true + })); + } + if (!sLoops) { + break; + } + } + }, + + handleBounds: function (segments, args, aBounds, origContent, locale) { + for (var i = 0; i < aBounds.length; i++) { + if (!initBounds(aBounds[i])) { + continue; + } + for (var j = 0; true; j++) { + if (j >= segments.length) { + break; + } + if (segments[j].isParsed || segments[j].inBounds || segments.keep || segments[j].isSeparator) { + continue; + } + var bounds = getBounds(segments[j], aBounds[i]); + var start = bounds.bStart; + var end = bounds.bEnd; + if (start < 0 || end < 0) { + continue; + } + var content = segments[j].content; + + segments.splice(j, 1); + if (start > 0) { + segments.splice(j, 0, new TextSegment({ + content: content.substring(0, start), + localGui: args.dir, + keep: true + })); + j++; + } + if (bounds.start) { + segments.splice(j, 0, new TextSegment({ + content: bounds.start, + localGui: args.dir, + isSeparator: true + })); + j++; + } + segments.splice(j, 0, new TextSegment({ + content: content.substring(start + bounds.start.length, end - bounds.end.length), + textDirection: bounds.subDir, + localGui: args.dir, + inBounds: true + })); + if (bounds.end) { + j++; + segments.splice(j, 0, new TextSegment({ + content: bounds.end, + localGui: args.dir, + isSeparator: true + })); + } + if (end + bounds.end.length < content.length) { + segments.splice(j + 1, 0, new TextSegment({ + content: content.substring(end + bounds.end.length, content.length), + localGui: args.dir, + keep: true + })); + } + if (!bounds.loops) { + break; + } + } + } + for (i = 0; i < segments.length; i++) { + segments[i].inBounds = false; + } + return segments; + }, + + handleCases: function (segments, args, cases, origContent, locale) { + if (cases.length === 0) { + return segments; + } + var hArgs = {}; + for (var prop in args) { + if (args.hasOwnProperty(prop)) { + hArgs[prop] = args[prop]; + } + } + for (var i = 0; i < cases.length; i++) { + if (!cases[i].handler || typeof(cases[i].handler.handle) !== "function") { + cases[i].handler = args.commonHandler; + } + if (cases[i].args) { + hArgs.cases = cases[i].args.cases; + hArgs.points = cases[i].args.points; + hArgs.bounds = cases[i].args.bounds; + hArgs.subs = cases[i].args.subs; + } else { + hArgs.cases = []; + hArgs.points = []; + hArgs.bounds = []; + hArgs.subs = {}; + } + cases[i].handler.handle(origContent, segments, hArgs, locale); + } + return segments; + }, + + handlePoints: function (segments, args, points, origContent, locale) { //jshint unused: false + for (var i = 0; i < points.length; i++) { + for (var j = 0; true; j++) { + if (j >= segments.length) { + break; + } + if (segments[j].isParsed || segments[j].keep || segments[j].isSeparator) { + continue; + } + var content = segments[j].content; + var pos = content.indexOf(points[i]); + if (pos >= 0) { + segments.splice(j, 1); + if (pos > 0) { + segments.splice(j, 0, new TextSegment({ + content: content.substring(0, pos), + textDirection: args.subDir, + localGui: args.dir, + inPoints: true + })); + j++; + } + segments.splice(j, 0, new TextSegment({ + content: points[i], + localGui: args.dir, + isSeparator: true + })); + if (pos + points[i].length + 1 <= content.length) { + segments.splice(j + 1, 0, new TextSegment({ + content: content.substring(pos + points[i].length), + textDirection: args.subDir, + localGui: args.dir, + inPoints: true + })); + } + } + } + } + for (i = 0; i < segments.length; i++) { + if (segments[i].keep) { + segments[i].keep = false; + } else if(segments[i].inPoints){ + segments[i].isParsed = true; + segments[i].inPoints = false; + } + } + return segments; + } + }; + })(); + + var common = (function() { + return { + handle: function (content, segments, args, locale) { + var cases = []; + if (Array.isArray(args.cases)) { + cases = args.cases; + } + var points = []; + if (typeof(args.points) !== "undefined") { + if (Array.isArray(args.points)) { + points = args.points; + } else if (typeof(args.points) === "string") { + points = args.points.split(""); + } + } + var subs = {}; + if (typeof(args.subs) === "object") { + subs = args.subs; + } + var aBounds = []; + if (Array.isArray(args.bounds)) { + aBounds = args.bounds; + } + + tools.handleBounds(segments, args, aBounds, content, locale); + tools.handleSubcontents(segments, args, subs, content, locale); + tools.handleCases(segments, args, cases, content, locale); + tools.handlePoints(segments, args, points, content, locale); + return segments; + } + }; + })(); + + var misc = (function() { + var isBidiLocale = function (locale) { + var lang = !locale ? "" : locale.split("-")[0]; + if (!lang || lang.length < 2) { + return false; + } + return ["iw", "he", "ar", "fa", "ur"].some(function (bidiLang) { + return bidiLang === lang; + }); + }; + var LRE = "\u202A"; + var RLE = "\u202B"; + var PDF = "\u202C"; + var LRM = "\u200E"; + var RLM = "\u200F"; + var LRO = "\u202D"; + var RLO = "\u202E"; + + return { + LRE: LRE, + RLE: RLE, + PDF: PDF, + LRM: LRM, + RLM: RLM, + LRO: LRO, + RLO: RLO, + + getLocaleDetails: function (locale) { + if (!locale) { + locale = typeof navigator === "undefined" ? "" : + (navigator.language || + navigator.userLanguage || + ""); + } + locale = locale.toLowerCase(); + if (isBidiLocale(locale)) { + var full = locale.split("-"); + return {lang: full[0], country: full[1] ? full[1] : ""}; + } + return {lang: "not-bidi"}; + }, + + removeUcc: function (text) { + if (text) { + return text.replace(/[\u200E\u200F\u202A-\u202E]/g, ""); + } + return text; + }, + + removeTags: function (text) { + if (text) { + return text.replace(/<[^<]*>/g, ""); + } + return text; + }, + + getDirection: function (text, dir, guiDir, checkEnd) { + if (dir !== "auto" && (/^(rtl|ltr)$/i).test(dir)) { + return dir; + } + guiDir = (/^(rtl|ltr)$/i).test(guiDir) ? guiDir : "ltr"; + var txt = !checkEnd ? text : text.split("").reverse().join(""); + var fdc = /[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(txt); + return fdc ? (fdc[0] <= "z" ? "ltr" : "rtl") : guiDir; + }, + + hasArabicChar: function (text) { + var fdc = /[\u0600-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(text); + return !!fdc; + }, + + showMarks: function (text, guiDir) { + var result = ""; + for (var i = 0; i < text.length; i++) { + var c = "" + text.charAt(i); + switch (c) { + case LRM: + result += ""; + break; + case RLM: + result += ""; + break; + case LRE: + result += ""; + break; + case RLE: + result += ""; + break; + case LRO: + result += ""; + break; + case RLO: + result += ""; + break; + case PDF: + result += ""; + break; + default: + result += c; + } + } + var mark = typeof(guiDir) === "undefined" || !((/^(rtl|ltr)$/i).test(guiDir)) ? "" : + guiDir === "rtl" ? RLO : LRO; + return mark + result + (mark === "" ? "" : PDF); + }, + + hideMarks: function (text) { + var txt = text.replace(//g, this.LRM).replace(//g, this.RLM).replace(//g, this.LRE); + return txt.replace(//g, this.RLE).replace(//g, this.LRO).replace(//g, this.RLO).replace(//g, this.PDF); + }, + + showTags: function (text) { + return "" + text + ""; + }, + + hideTags: function (text) { + return text.replace(//g,"").replace(/<\/xmp>/g,""); + } + }; + })(); + + var stext = (function() { + var stt = {}; + + // args + // handler: main handler (default - dbidi/stt/handlers/common) + // guiDir: GUI direction (default - "ltr") + // dir: main stt direction (default - guiDir) + // subDir: direction of subsegments + // points: array of delimiters (default - []) + // bounds: array of definitions of bounds in which handler works + // subs: object defines special handling for some substring if found + // cases: array of additional modules with their args for handling special cases (default - []) + function parseAndDisplayStructure(content, fArgs, isHtml, locale) { + if (!content || !fArgs) { + return content; + } + return displayStructure(parseStructure(content, fArgs, locale), fArgs, isHtml); + } + + function checkArguments(fArgs, fullCheck) { + var args = Array.isArray(fArgs)? fArgs[0] : fArgs; + if (!args.guiDir) { + args.guiDir = "ltr"; + } + if (!args.dir) { + args.dir = args.guiDir; + } + if (!fullCheck) { + return args; + } + if (typeof(args.points) === "undefined") { + args.points = []; + } + if (!args.cases) { + args.cases = []; + } + if (!args.bounds) { + args.bounds = []; + } + args.commonHandler = common; + return args; + } + + function parseStructure(content, fArgs, locale) { + if (!content || !fArgs) { + return new TextSegment({content: ""}); + } + var args = checkArguments(fArgs, true); + var segments = [new TextSegment( + { + content: content, + actual: content, + localGui: args.dir + })]; + var parse = common.handle; + if (args.handler && typeof(args.handler) === "function") { + parse = args.handler.handle; + } + parse(content, segments, args, locale); + return segments; + } + + function displayStructure(segments, fArgs, isHtml) { + var args = checkArguments(fArgs, false); + if (isHtml) { + return getResultWithHtml(segments, args); + } + else { + return getResultWithUcc(segments, args); + } + } + + function getResultWithUcc(segments, args, isHtml) { + var result = ""; + var checkedDir = ""; + var prevDir = ""; + var stop = false; + for (var i = 0; i < segments.length; i++) { + if (segments[i].isVisible) { + var dir = segments[i].textDirection; + var lDir = segments[i].localGui; + if (lDir !== "" && prevDir === "") { + result += (lDir === "rtl" ? misc.RLE : misc.LRE); + } + else if(prevDir !== "" && (lDir === "" || lDir !== prevDir || stop)) { + result += misc.PDF + (i == segments.length - 1 && lDir !== ""? "" : args.dir === "rtl" ? misc.RLM : misc.LRM); + if (lDir !== "") { + result += (lDir === "rtl" ? misc.RLE : misc.LRE); + } + } + if (dir === "auto") { + dir = misc.getDirection(segments[i].content, dir, args.guiDir); + } + if ((/^(rtl|ltr)$/i).test(dir)) { + result += (dir === "rtl" ? misc.RLE : misc.LRE) + segments[i].content + misc.PDF; + checkedDir = dir; + } + else { + result += segments[i].content; + checkedDir = misc.getDirection(segments[i].content, dir, args.guiDir, true); + } + if (i < segments.length - 1) { + var locDir = lDir && segments[i+1].localGui? lDir : args.dir; + result += locDir === "rtl" ? misc.RLM : misc.LRM; + } + else if(prevDir !== "") { + result += misc.PDF; + } + prevDir = lDir; + stop = false; + } + else { + stop = true; + } + } + var sttDir = args.dir === "auto" ? misc.getDirection(segments[0].actual, args.dir, args.guiDir) : args.dir; + if (sttDir !== args.guiDir) { + result = (sttDir === "rtl" ? misc.RLE : misc.LRE) + result + misc.PDF; + } + return result; + } + + function getResultWithHtml(segments, args, isHtml) { + var result = ""; + var checkedDir = ""; + var prevDir = ""; + for (var i = 0; i < segments.length; i++) { + if (segments[i].isVisible) { + var dir = segments[i].textDirection; + var lDir = segments[i].localGui; + if (lDir !== "" && prevDir === "") { + result += "<bdi dir='" + (lDir === "rtl" ? "rtl" : "ltr") + "'>"; + } + else if(prevDir !== "" && (lDir === "" || lDir !== prevDir || stop)) { + result += "</bdi>" + (i == segments.length - 1 && lDir !== ""? "" : "<span style='unicode-bidi: embed; direction: " + (args.dir === "rtl" ? "rtl" : "ltr") + ";'></span>"); + if (lDir !== "") { + result += "<bdi dir='" + (lDir === "rtl" ? "rtl" : "ltr") + "'>"; + } + } + + if (dir === "auto") { + dir = misc.getDirection(segments[i].content, dir, args.guiDir); + } + if ((/^(rtl|ltr)$/i).test(dir)) { + //result += "<span style='unicode-bidi: embed; direction: " + (dir === "rtl" ? "rtl" : "ltr") + ";'>" + segments[i].content + "</span>"; + result += "<bdi dir='" + (dir === "rtl" ? "rtl" : "ltr") + "'>" + segments[i].content + "</bdi>"; + checkedDir = dir; + } + else { + result += segments[i].content; + checkedDir = misc.getDirection(segments[i].content, dir, args.guiDir, true); + } + if (i < segments.length - 1) { + var locDir = lDir && segments[i+1].localGui? lDir : args.dir; + result += "<span style='unicode-bidi: embed; direction: " + (locDir === "rtl" ? "rtl" : "ltr") + ";'></span>"; + } + else if(prevDir !== "") { + result += "</bdi>"; + } + prevDir = lDir; + stop = false; + } + else { + stop = true; + } + } + var sttDir = args.dir === "auto" ? misc.getDirection(segments[0].actual, args.dir, args.guiDir) : args.dir; + if (sttDir !== args.guiDir) { + result = "<bdi dir='" + (sttDir === "rtl" ? "rtl" : "ltr") + "'>" + result + "</bdi>"; + } + return result; + } + + //TBD ? + function restore(text, isHtml) { + return text; + } + + stt.parseAndDisplayStructure = parseAndDisplayStructure; + stt.parseStructure = parseStructure; + stt.displayStructure = displayStructure; + stt.restore = restore; + + return stt; + })(); + + var breadcrumb = (function() { + return { + format: function (text, args, isRtl, isHtml, locale, parseOnly) { + var fArgs = + { + guiDir: isRtl ? "rtl" : "ltr", + dir: args.dir ? args.dir : isRtl ? "rtl" : "ltr", + subs: { + content: ">", + continued: true, + subDir: isRtl ? "rtl" : "ltr" + }, + cases: [{ + args: { + subs: { + content: "<", + continued: true, + subDir: isRtl ? "ltr" : "rtl" + } + } + }] + }; + + if (!parseOnly) { + return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale); + } + else { + return stext.parseStructure(text, fArgs, !!isHtml, locale); + } + } + }; + })(); + + var comma = (function() { + return { + format: function (text, args, isRtl, isHtml, locale, parseOnly) { + var fArgs = + { + guiDir: isRtl ? "rtl" : "ltr", + dir: "ltr", + points: "," + }; + if (!parseOnly) { + return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale); + } + else { + return stext.parseStructure(text, fArgs, !!isHtml, locale); + } + } + }; + })(); + + var email = (function() { + function getDir(text, locale) { + if (misc.getLocaleDetails(locale).lang !== "ar") { + return "ltr"; + } + var ind = text.indexOf("@"); + if (ind > 0 && ind < text.length - 1) { + return misc.hasArabicChar(text.substring(ind + 1)) ? "rtl" : "ltr"; + } + return "ltr"; + } + + return { + format: function (text, args, isRtl, isHtml, locale, parseOnly) { + var fArgs = + { + guiDir: isRtl ? "rtl" : "ltr", + dir: getDir(text, locale), + points: "<>.:,;@", + cases: [{ + handler: common, + args: { + bounds: [{ + startAfter: "\"", + endBefore: "\"" + }, + { + startAfter: "(", + endBefore: ")" + } + ], + points: "" + } + }] + }; + if (!parseOnly) { + return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale); + } + else { + return stext.parseStructure(text, fArgs, !!isHtml, locale); + } + } + }; + })(); + + var filepath = (function() { + return { + format: function (text, args, isRtl, isHtml, locale, parseOnly) { + var fArgs = + { + guiDir: isRtl ? "rtl" : "ltr", + dir: "ltr", + points: "/\\:." + }; + if (!parseOnly) { + return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale); + } + else { + return stext.parseStructure(text, fArgs, !!isHtml, locale); + } + } + }; + })(); + + var formula = (function() { + return { + format: function (text, args, isRtl, isHtml, locale, parseOnly) { + var fArgs = + { + guiDir: isRtl ? "rtl" : "ltr", + dir: "ltr", + points: " /%^&[]<>=!?~:.,|()+-*{}", + }; + if (!parseOnly) { + return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale); + } + else { + return stext.parseStructure(text, fArgs, !!isHtml, locale); + } + } + }; + })(); + + + var sql = (function() { + return { + format: function (text, args, isRtl, isHtml, locale, parseOnly) { + var fArgs = + { + guiDir: isRtl ? "rtl" : "ltr", + dir: "ltr", + points: "\t!#%&()*+,-./:;<=>?|[]{}", + cases: [{ + handler: common, + args: { + bounds: [{ + startAfter: "/*", + endBefore: "*/" + }, + { + startAfter: "--", + end: "\n" + }, + { + startAfter: "--" + } + ] + } + }, + { + handler: common, + args: { + subs: { + content: " ", + continued: true + } + } + }, + { + handler: common, + args: { + bounds: [{ + startAfter: "'", + endBefore: "'" + }, + { + startAfter: "\"", + endBefore: "\"" + } + ] + } + } + ] + }; + if (!parseOnly) { + return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale); + } + else { + return stext.parseStructure(text, fArgs, !!isHtml, locale); + } + } + }; + })(); + + var underscore = (function() { + return { + format: function (text, args, isRtl, isHtml, locale, parseOnly) { + var fArgs = + { + guiDir: isRtl ? "rtl" : "ltr", + dir: "ltr", + points: "_" + }; + if (!parseOnly) { + return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale); + } + else { + return stext.parseStructure(text, fArgs, !!isHtml, locale); + } + } + }; + })(); + + var url = (function() { + return { + format: function (text, args, isRtl, isHtml, locale, parseOnly) { + var fArgs = + { + guiDir: isRtl ? "rtl" : "ltr", + dir: "ltr", + points: ":?#/@.[]=" + }; + if (!parseOnly) { + return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale); + } + else { + return stext.parseStructure(text, fArgs, !!isHtml, locale); + } + } + }; + })(); + + var word = (function() { + return { + format: function (text, args, isRtl, isHtml, locale, parseOnly) { + var fArgs = + { + guiDir: isRtl ? "rtl" : "ltr", + dir: args.dir ? args.dir : isRtl ? "rtl" : "ltr", + points: " ,.!?;:", + }; + if (!parseOnly) { + return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale); + } + else { + return stext.parseStructure(text, fArgs, !!isHtml, locale); + } + } + }; + })(); + + var xpath = (function() { + return { + format: function (text, args, isRtl, isHtml, locale, parseOnly) { + var fArgs = + { + guiDir: isRtl ? "rtl" : "ltr", + dir: "ltr", + points: " /[]<>=!:@.|()+-*", + cases: [{ + handler: common, + args: { + bounds: [{ + startAfter: "\"", + endBefore: "\"" + }, + { + startAfter: "'", + endBefore: "'" + } + ], + points: "" + } + } + ] + }; + if (!parseOnly) { + return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale); + } + else { + return stext.parseStructure(text, fArgs, !!isHtml, locale); + } + } + }; + })(); + + var custom = (function() { + return { + format: function (text, args, isRtl, isHtml, locale, parseOnly) { + var hArgs = {}; + var prop = ""; + var sArgs = Array.isArray(args)? args[0] : args; + for (prop in sArgs) { + if (sArgs.hasOwnProperty(prop)) { + hArgs[prop] = sArgs[prop]; + } + } + hArgs.guiDir = isRtl ? "rtl" : "ltr"; + hArgs.dir = hArgs.dir ? hArgs.dir : hArgs.guiDir; + if (!parseOnly) { + return stext.parseAndDisplayStructure(text, hArgs, !!isHtml, locale); + } + else { + return stext.parseStructure(text, hArgs, !!isHtml, locale); + } + } + }; + })(); + + var message = (function() { + var params = {msgLang: "en", msgDir: "", phLang: "", phDir: "", phPacking: ["{","}"], phStt: {type: "none", args: {}}, guiDir: ""}; + var parametersChecked = false; + + function getDirectionOfLanguage(lang) { + if (lang === "he" || lang === "iw" || lang === "ar") { + return "rtl"; + } + return "ltr"; + } + + function checkParameters(obj) { + if (obj.msgDir.length === 0) { + obj.msgDir = getDirectionOfLanguage(obj.msgLang); + } + obj.msgDir = obj.msgDir !== "ltr" && obj.msgDir !== "rtl" && obj.msgDir != "auto"? "ltr" : obj.msgDir; + if (obj.guiDir.length === 0) { + obj.guiDir = obj.msgDir; + } + obj.guiDir = obj.guiDir !== "rtl"? "ltr" : "rtl"; + if (obj.phDir.length === 0) { + obj.phDir = obj.phLang.length === 0? obj.msgDir : getDirectionOfLanguage(obj.phLang); + } + obj.phDir = obj.phDir !== "ltr" && obj.phDir !== "rtl" && obj.phDir != "auto"? "ltr" : obj.phDir; + if (typeof (obj.phPacking) === "string") { + obj.phPacking = obj.phPacking.split(""); + } + if (obj.phPacking.length < 2) { + obj.phPacking = ["{","}"]; + } + } + + return { + setDefaults: function (args) { + for (var prop in args) { + if (params.hasOwnProperty(prop)) { + params[prop] = args[prop]; + } + } + checkParameters(params); + parametersChecked = true; + }, + + format: function (text) { + if (!parametersChecked) { + checkParameters(params); + parametersChecked = true; + } + var isHtml = false; + var hasHtmlArg = false; + var spLength = params.phPacking[0].length; + var epLength = params.phPacking[1].length; + if (arguments.length > 0) { + var last = arguments[arguments.length-1]; + if (typeof (last) === "boolean") { + isHtml = last; + hasHtmlArg = true; + } + } + //Message + var re = new RegExp(params.phPacking[0] + "\\d+" + params.phPacking[1]); + var m; + var tSegments = []; + var offset = 0; + var txt = text; + while ((m = re.exec(txt)) != null) { + var lastIndex = txt.indexOf(m[0]) + m[0].length; + if (lastIndex > m[0].length) { + tSegments.push({text: txt.substring(0, lastIndex - m[0].length), ph: false}); + } + tSegments.push({text: m[0], ph: true}); + offset += lastIndex; + txt = txt.substring(lastIndex, txt.length); + } + if (offset < text.length) { + tSegments.push({text: text.substring(offset, text.length), ph: false}); + } + //Parameters + var tArgs = []; + for (var i = 1; i < arguments.length - (hasHtmlArg? 1 : 0); i++) { + var arg = arguments[i]; + var checkArr = arg; + var inLoop = false; + var indArr = 0; + if (Array.isArray(checkArr)) { + arg = checkArr[0]; + if (typeof(arg) === "undefined") { + continue; + } + inLoop = true; + } + do { + if (typeof (arg) === "string") { + tArgs.push({text: arg, dir: params.phDir, stt: params.stt}); + } + else if(typeof (arg) === "boolean") { + isHtml = arg; + } + else if(typeof (arg) === "object") { + tArgs.push(arg); + if (!arg.hasOwnProperty("text")) { + tArgs[tArgs.length-1].text = "{???}"; + } + if (!arg.hasOwnProperty("dir") || arg.dir.length === 0) { + tArgs[tArgs.length-1].dir = params.phDir; + } + if (!arg.hasOwnProperty("stt") || (typeof (arg.stt) === "string" && arg.stt.length === 0) || + (typeof (arg.stt) === "object" && Object.keys(arg.stt).length === 0)) { + tArgs[tArgs.length-1].stt = params.phStt; + } + } + else { + tArgs.push({text: "" + arg, dir: params.phDir, stt: params.phStt}); + } + if (inLoop) { + indArr++; + if (indArr == checkArr.length) { + inLoop = false; + } + else { + arg = checkArr[indArr]; + } + } + } while(inLoop); + } + //Indexing + var segments = []; + for (i = 0; i < tSegments.length; i++) { + var t = tSegments[i]; + if (!t.ph) { + segments.push(new TextSegment({content: t.text, textDirection: params.msgDir})); + } + else { + var ind = parseInt(t.text.substring(spLength, t.text.length - epLength)); + if (isNaN(ind) || ind >= tArgs.length) { + segments.push(new TextSegment({content: t.text, textDirection: params.msgDir})); + continue; + } + var sttType = "none"; + if (!tArgs[ind].stt) { + tArgs[ind].stt = params.phStt; + } + if (tArgs[ind].stt) { + if (typeof (tArgs[ind].stt) === "string") { + sttType = tArgs[ind].stt; + } + else if(tArgs[ind].stt.hasOwnProperty("type")) { + sttType = tArgs[ind].stt.type; + } + } + if (sttType.toLowerCase() !== "none") { + var sttSegs = getHandler(sttType).format(tArgs[ind].text, tArgs[ind].stt.args || {}, + params.msgDir === "rtl", false, params.msgLang, true); + for (var j = 0; j < sttSegs.length; j++) { + segments.push(sttSegs[j]); + } + segments.push(new TextSegment({isVisible: false})); + } + else { + segments.push(new TextSegment({content: tArgs[ind].text, textDirection: (tArgs[ind].dir? tArgs[ind].dir : params.phDir)})); + } + } + } + var result = stext.displayStructure(segments, {guiDir: params.guiDir, dir: params.msgDir}, isHtml); + return result; + } + }; + })(); + + var event = null; + + function getHandler(type) { + switch (type) { + case "breadcrumb" : + return breadcrumb; + case "comma" : + return comma; + case "email" : + return email; + case "filepath" : + return filepath; + case "formula" : + return formula; + case "sql" : + return sql; + case "underscore" : + return underscore; + case "url" : + return url; + case "word" : + return word; + case "xpath" : + return xpath; + default: + return custom; + } + } + + function isInputEventSupported(element) { + var agent = window.navigator.userAgent; + if (agent.indexOf("MSIE") >=0 || agent.indexOf("Trident") >=0 || agent.indexOf("Edge") >=0) { + return false; + } + var checked = document.createElement(element.tagName); + checked.contentEditable = true; + var isSupported = ("oninput" in checked); + if (!isSupported) { + checked.setAttribute('oninput', 'return;'); + isSupported = typeof checked['oninput'] == 'function'; + } + checked = null; + return isSupported; + } + + function attachElement(element, type, args, isRtl, locale) { + //if (!element || element.nodeType != 1 || !element.isContentEditable) + if (!element || element.nodeType != 1) { + return false; + } + if (!event) { + event = document.createEvent('Event'); + event.initEvent('TF', true, true); + } + element.setAttribute("data-tf-type", type); + var sArgs = args === "undefined"? "{}" : JSON.stringify(Array.isArray(args)? args[0] : args); + element.setAttribute("data-tf-args", sArgs); + var dir = "ltr"; + if (isRtl === "undefined") { + if (element.dir) { + dir = element.dir; + } + else if(element.style && element.style.direction) { + dir = element.style.direction; + } + isRtl = dir.toLowerCase() === "rtl"; + } + element.setAttribute("data-tf-dir", isRtl); + element.setAttribute("data-tf-locale", misc.getLocaleDetails(locale).lang); + if (isInputEventSupported(element)) { + var ehandler = element.oninput; + element.oninput = function(event) { + displayWithStructure(event.target); + }; + } + else { + element.onkeyup = function(e) { + displayWithStructure(e.target); + element.dispatchEvent(event); + }; + element.onmouseup = function(e) { + displayWithStructure(e.target); + element.dispatchEvent(event); + }; + } + displayWithStructure(element); + + return true; + } + + function detachElement(element) { + if (!element || element.nodeType != 1) { + return; + } + element.removeAttribute("data-tf-type"); + element.removeAttribute("data-tf-args"); + element.removeAttribute("data-tf-dir"); + element.removeAttribute("data-tf-locale"); + element.innerHTML = element.textContent || ""; + } + + function displayWithStructure(element) { + var txt = element.textContent || ""; + var selection = document.getSelection(); + if (txt.length === 0 || !selection || selection.rangeCount <= 0) { + element.dispatchEvent(event); + return; + } + + var range = selection.getRangeAt(0); + var tempRange = range.cloneRange(), startNode, startOffset; + startNode = range.startContainer; + startOffset = range.startOffset; + var textOffset = 0; + if (startNode.nodeType === 3) { + textOffset += startOffset; + } + tempRange.setStart(element,0); + tempRange.setEndBefore(startNode); + var div = document.createElement('div'); + div.appendChild(tempRange.cloneContents()); + textOffset += div.textContent.length; + + element.innerHTML = getHandler(element.getAttribute("data-tf-type")). + format(txt, JSON.parse(element.getAttribute("data-tf-args")), (element.getAttribute("data-tf-dir") === "true"? true : false), + true, element.getAttribute("data-tf-locale")); + var parent = element; + var node = element; + var newOffset = 0; + var inEnd = false; + selection.removeAllRanges(); + range.setStart(element,0); + range.setEnd(element,0); + while (node) { + if (node.nodeType === 3) { + if (newOffset + node.nodeValue.length >= textOffset) { + range.setStart(node, textOffset - newOffset); + break; + } + else { + newOffset += node.nodeValue.length; + node = node.nextSibling; + } + } + else if(node.hasChildNodes()) { + parent = node; + node = parent.firstChild; + continue; + } + else { + node = node.nextSibling; + } + while (!node) { + if (parent === element) { + inEnd = true; + break; + } + node = parent.nextSibling; + parent = parent.parentNode; + } + if (inEnd) { + break; + } + } + + selection.addRange(range); + element.dispatchEvent(event); + } + + return { + /*! + * Returns the HTML representation of a given structured text + * @param text - the structured text + * @param type - could be one of filepath, url, email + * @param args - pass additional arguments to the handler. generally null. + * @param isRtl - indicates if the GUI is mirrored + * @param locale - the browser locale + */ + getHtml: function (text, type, args, isRtl, locale) { + return getHandler(type).format(text, args, isRtl, true, locale); + }, + /*! + * Handle Structured text correct display for a given HTML element. + * @param element - the element : should be of type div contenteditable=true + * @param type - could be one of filepath, url, email + * @param args - pass additional arguments to the handler. generally null. + * @param isRtl - indicates if the GUI is mirrored + * @param locale - the browser locale + */ + attach: function (element, type, args, isRtl, locale) { + return attachElement(element, type, args, isRtl, locale); + } + }; +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/actionList.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/actionList.js new file mode 100644 index 0000000..ac8a068 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/actionList.js @@ -0,0 +1,230 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.actionList = (function() { + + var disabled = false; + var dialog = null; + var searchInput; + var searchResults; + var selected = -1; + var visible = false; + + var filterTerm = ""; + var filterTerms = []; + var previousActiveElement; + + function ensureSelectedIsVisible() { + var selectedEntry = searchResults.find("li.selected"); + if (selectedEntry.length === 1) { + var scrollWindow = searchResults.parent(); + var scrollHeight = scrollWindow.height(); + var scrollOffset = scrollWindow.scrollTop(); + var y = selectedEntry.position().top; + var h = selectedEntry.height(); + if (y+h > scrollHeight) { + scrollWindow.animate({scrollTop: '-='+(scrollHeight-(y+h)-10)},50); + } else if (y<0) { + scrollWindow.animate({scrollTop: '+='+(y-10)},50); + } + } + } + + function createDialog() { + dialog = $("<div>",{id:"red-ui-actionList",class:"red-ui-search"}).appendTo("#red-ui-main-container"); + var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(dialog); + searchInput = $('<input type="text" data-i18n="[placeholder]keyboard.filterActions">').appendTo(searchDiv).searchBox({ + change: function() { + filterTerm = $(this).val().trim(); + filterTerms = filterTerm.split(" "); + searchResults.editableList('filter'); + searchResults.find("li.selected").removeClass("selected"); + var children = searchResults.children(":visible"); + if (children.length) { + $(children[0]).addClass('selected'); + } + } + }); + + searchInput.on('keydown',function(evt) { + var selectedChild; + if (evt.keyCode === 40) { + // Down + selectedChild = searchResults.find("li.selected"); + if (!selectedChild.length) { + var children = searchResults.children(":visible"); + if (children.length) { + $(children[0]).addClass('selected'); + } + } else { + var nextChild = selectedChild.nextAll(":visible").first(); + if (nextChild.length) { + selectedChild.removeClass('selected'); + nextChild.addClass('selected'); + } + } + ensureSelectedIsVisible(); + evt.preventDefault(); + } else if (evt.keyCode === 38) { + // Up + selectedChild = searchResults.find("li.selected"); + var nextChild = selectedChild.prevAll(":visible").first(); + if (nextChild.length) { + selectedChild.removeClass('selected'); + nextChild.addClass('selected'); + } + ensureSelectedIsVisible(); + evt.preventDefault(); + } else if (evt.keyCode === 13) { + // Enter + selectedChild = searchResults.find("li.selected"); + selectCommand(searchResults.editableList('getItem',selectedChild)); + } + }); + searchInput.i18n(); + + var searchResultsDiv = $("<div>",{class:"red-ui-search-results-container"}).appendTo(dialog); + searchResults = $('<ol>',{style:"position: absolute;top: 5px;bottom: 5px;left: 5px;right: 5px;"}).appendTo(searchResultsDiv).editableList({ + addButton: false, + addItem: function(container,i,action) { + if (action.id === undefined) { + $('<div>',{class:"red-ui-search-empty"}).text(RED._('search.empty')).appendTo(container); + } else { + var div = $('<a>',{href:'#',class:"red-ui-search-result"}).appendTo(container); + var contentDiv = $('<div>',{class:"red-ui-search-result-action"}).appendTo(div); + + + $('<div>').text(action.label).appendTo(contentDiv); + // $('<div>',{class:"red-ui-search-result-node-type"}).text(node.type).appendTo(contentDiv); + // $('<div>',{class:"red-ui-search-result-node-id"}).text(node.id).appendTo(contentDiv); + if (action.key) { + $('<div>',{class:"red-ui-search-result-action-key"}).html(RED.keyboard.formatKey(action.key)).appendTo(contentDiv); + } + div.on("click", function(evt) { + evt.preventDefault(); + selectCommand(action); + }); + } + }, + scrollOnAdd: false, + filter: function(item) { + if (filterTerm !== "") { + var pos=0; + for (var i=0;i<filterTerms.length;i++) { + var j = item._label.indexOf(filterTerms[i],pos); + if (j > -1) { + pos = j; + } else { + return false; + } + } + return true; + } + return true; + } + }); + + } + + function selectCommand(command) { + hide(); + if (command) { + RED.actions.invoke(command.id); + } + } + + function show(v) { + if (disabled) { + return; + } + if (!visible) { + previousActiveElement = document.activeElement; + RED.keyboard.add("*","escape",function(){hide()}); + $("#red-ui-header-shade").show(); + $("#red-ui-editor-shade").show(); + $("#red-ui-palette-shade").show(); + $("#red-ui-sidebar-shade").show(); + $("#red-ui-sidebar-separator").hide(); + if (dialog === null) { + createDialog(); + } + dialog.slideDown(300); + searchInput.searchBox('value',v) + searchResults.editableList('empty'); + results = []; + var actions = RED.actions.list(); + actions.sort(function(A,B) { + return A.id.localeCompare(B.id); + }); + actions.forEach(function(action) { + action.label = action.id.replace(/:/,": ").replace(/-/g," ").replace(/(^| )./g,function() { return arguments[0].toUpperCase()}); + action._label = action.label.toLowerCase(); + searchResults.editableList('addItem',action) + }) + RED.events.emit("actionList:open"); + visible = true; + } + searchInput.trigger("focus"); + var children = searchResults.children(":visible"); + if (children.length) { + $(children[0]).addClass('selected'); + } + } + + function hide() { + if (visible) { + RED.keyboard.remove("escape"); + visible = false; + $("#red-ui-header-shade").hide(); + $("#red-ui-editor-shade").hide(); + $("#red-ui-palette-shade").hide(); + $("#red-ui-sidebar-shade").hide(); + $("#red-ui-sidebar-separator").show(); + if (dialog !== null) { + dialog.slideUp(200,function() { + searchInput.searchBox('value',''); + }); + } + RED.events.emit("actionList:close"); + if (previousActiveElement) { + $(previousActiveElement).trigger("focus"); + previousActiveElement = null; + } + } + } + + function init() { + RED.actions.add("core:show-action-list",show); + + RED.events.on("editor:open",function() { disabled = true; }); + RED.events.on("editor:close",function() { disabled = false; }); + RED.events.on("search:open",function() { disabled = true; }); + RED.events.on("search:close",function() { disabled = false; }); + RED.events.on("type-search:open",function() { disabled = true; }); + RED.events.on("type-search:close",function() { disabled = false; }); + + $("#red-ui-header-shade").on('mousedown',hide); + $("#red-ui-editor-shade").on('mousedown',hide); + $("#red-ui-palette-shade").on('mousedown',hide); + $("#red-ui-sidebar-shade").on('mousedown',hide); + } + + return { + init: init, + show: show, + hide: hide + }; + +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/actions.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/actions.js new file mode 100644 index 0000000..6da89a3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/actions.js @@ -0,0 +1,35 @@ +RED.actions = (function() { + var actions = { + + } + + function addAction(name,handler) { + actions[name] = handler; + } + function removeAction(name) { + delete actions[name]; + } + function getAction(name) { + return actions[name]; + } + function invokeAction(name,args) { + if (actions.hasOwnProperty(name)) { + actions[name](args); + } + } + function listActions() { + var result = []; + Object.keys(actions).forEach(function(action) { + var shortcut = RED.keyboard.getShortcut(action); + result.push({id:action,scope:shortcut?shortcut.scope:undefined,key:shortcut?shortcut.key:undefined,user:shortcut?shortcut.user:undefined}) + }) + return result; + } + return { + add: addAction, + remove: removeAction, + get: getAction, + invoke: invokeAction, + list: listActions + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js new file mode 100644 index 0000000..cdff629 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js @@ -0,0 +1,796 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +RED.clipboard = (function() { + + var dialog; + var dialogContainer; + var exportNodesDialog; + var importNodesDialog; + var disabled = false; + var popover; + var currentPopoverError; + var activeTab; + var libraryBrowser; + var examplesBrowser; + + function setupDialogs() { + dialog = $('<div id="red-ui-clipboard-dialog" class="hide"><form class="dialog-form form-horizontal"></form></div>') + .appendTo("#red-ui-editor") + .dialog({ + modal: true, + autoOpen: false, + width: 700, + resizable: false, + classes: { + "ui-dialog": "red-ui-editor-dialog", + "ui-dialog-titlebar-close": "hide", + "ui-widget-overlay": "red-ui-editor-dialog" + }, + buttons: [ + { + id: "red-ui-clipboard-dialog-cancel", + text: RED._("common.label.cancel"), + click: function() { + $( this ).dialog( "close" ); + } + }, + { + id: "red-ui-clipboard-dialog-download", + class: "primary", + text: RED._("clipboard.download"), + click: function() { + var element = document.createElement('a'); + element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent($("#red-ui-clipboard-dialog-export-text").val())); + element.setAttribute('download', "flows.json"); + element.style.display = 'none'; + document.body.appendChild(element); + element.click(); + document.body.removeChild(element); + $( this ).dialog( "close" ); + } + }, + { + id: "red-ui-clipboard-dialog-export", + class: "primary", + text: RED._("clipboard.export.copy"), + click: function() { + if (activeTab === "red-ui-clipboard-dialog-export-tab-clipboard") { + $("#red-ui-clipboard-dialog-export-text").select(); + document.execCommand("copy"); + document.getSelection().removeAllRanges(); + RED.notify(RED._("clipboard.nodesExported"),{id:"clipboard"}); + $( this ).dialog( "close" ); + } else { + var flowToExport = $("#red-ui-clipboard-dialog-export-text").val(); + var selectedPath = libraryBrowser.getSelected(); + if (!selectedPath.children) { + selectedPath = selectedPath.parent; + } + var filename = $("#red-ui-clipboard-dialog-tab-library-name").val().trim(); + var saveFlow = function() { + $.ajax({ + url:'library/'+selectedPath.library+'/'+selectedPath.type+'/'+selectedPath.path + filename, + type: "POST", + data: flowToExport, + contentType: "application/json; charset=utf-8" + }).done(function() { + $(dialog).dialog( "close" ); + RED.notify(RED._("library.exportedToLibrary"),"success"); + }).fail(function(xhr,textStatus,err) { + if (xhr.status === 401) { + RED.notify(RED._("library.saveFailed",{message:RED._("user.notAuthorized")}),"error"); + } else { + RED.notify(RED._("library.saveFailed",{message:xhr.responseText}),"error"); + } + }); + } + if (selectedPath.children) { + var exists = false; + selectedPath.children.forEach(function(f) { + if (f.label === filename) { + exists = true; + } + }); + if (exists) { + dialog.dialog("close"); + var notification = RED.notify(RED._("clipboard.export.exists",{file:RED.utils.sanitize(filename)}),{ + type: "warning", + fixed: true, + buttons: [{ + text: RED._("common.label.cancel"), + click: function() { + notification.hideNotification() + dialog.dialog( "open" ); + } + },{ + text: RED._("clipboard.export.overwrite"), + click: function() { + notification.hideNotification() + saveFlow(); + } + }] + }); + } else { + saveFlow(); + } + } else { + saveFlow(); + } + } + } + }, + { + id: "red-ui-clipboard-dialog-ok", + class: "primary", + text: RED._("common.label.import"), + click: function() { + var addNewFlow = ($("#red-ui-clipboard-dialog-import-opt > a.selected").attr('id') === 'red-ui-clipboard-dialog-import-opt-new'); + if (activeTab === "red-ui-clipboard-dialog-import-tab-clipboard") { + RED.view.importNodes($("#red-ui-clipboard-dialog-import-text").val(),addNewFlow); + } else { + var selectedPath; + if (activeTab === "red-ui-clipboard-dialog-import-tab-library") { + selectedPath = libraryBrowser.getSelected(); + } else { + selectedPath = examplesBrowser.getSelected(); + } + if (selectedPath.path) { + $.get('library/'+selectedPath.library+'/'+selectedPath.type+'/'+selectedPath.path, function(data) { + RED.view.importNodes(data,addNewFlow); + }); + } + } + $( this ).dialog( "close" ); + } + } + ], + close: function(e) { + if (popover) { + popover.close(true); + currentPopoverError = null; + } + } + }); + + dialogContainer = dialog.children(".dialog-form"); + + exportNodesDialog = + '<div class="form-row">'+ + '<label style="width:auto;margin-right: 10px;" data-i18n="common.label.export"></label>'+ + '<span id="red-ui-clipboard-dialog-export-rng-group" class="button-group">'+ + '<a id="red-ui-clipboard-dialog-export-rng-selected" class="red-ui-button toggle" href="#" data-i18n="clipboard.export.selected"></a>'+ + '<a id="red-ui-clipboard-dialog-export-rng-flow" class="red-ui-button toggle" href="#" data-i18n="clipboard.export.current"></a>'+ + '<a id="red-ui-clipboard-dialog-export-rng-full" class="red-ui-button toggle" href="#" data-i18n="clipboard.export.all"></a>'+ + '</span>'+ + '</div>'+ + '<div class="red-ui-clipboard-dialog-box">'+ + '<div class="red-ui-clipboard-dialog-tabs">'+ + '<ul id="red-ui-clipboard-dialog-export-tabs"></ul>'+ + '</div>'+ + '<div id="red-ui-clipboard-dialog-export-tabs-content" class="red-ui-clipboard-dialog-tabs-content">'+ + '<div id="red-ui-clipboard-dialog-export-tab-clipboard" class="red-ui-clipboard-dialog-tab-clipboard">'+ + '<div class="form-row">'+ + '<textarea readonly id="red-ui-clipboard-dialog-export-text"></textarea>'+ + '</div>'+ + '<div class="form-row" style="text-align: right;">'+ + '<span id="red-ui-clipboard-dialog-export-fmt-group" class="button-group">'+ + '<a id="red-ui-clipboard-dialog-export-fmt-mini" class="red-ui-button red-ui-button-small toggle" href="#" data-i18n="clipboard.export.compact"></a>'+ + '<a id="red-ui-clipboard-dialog-export-fmt-full" class="red-ui-button red-ui-button-small toggle" href="#" data-i18n="clipboard.export.formatted"></a>'+ + '</span>'+ + '</div>'+ + '</div>'+ + '<div id="red-ui-clipboard-dialog-export-tab-library" class="red-ui-clipboard-dialog-tab-library">'+ + '<div id="red-ui-clipboard-dialog-export-tab-library-browser"></div>'+ + '<div class="form-row">'+ + '<label data-i18n="clipboard.export.exportAs"></label><input id="red-ui-clipboard-dialog-tab-library-name" type="text">'+ + '</div>'+ + '</div>'+ + '</div>'+ + '</div>' + ; + + + importNodesDialog = + '<div class="red-ui-clipboard-dialog-box" style="margin-bottom: 12px">'+ + '<div class="red-ui-clipboard-dialog-tabs">'+ + '<ul id="red-ui-clipboard-dialog-import-tabs"></ul>'+ + '</div>'+ + '<div id="red-ui-clipboard-dialog-import-tabs-content" class="red-ui-clipboard-dialog-tabs-content">'+ + '<div id="red-ui-clipboard-dialog-import-tab-clipboard" class="red-ui-clipboard-dialog-tab-clipboard">'+ + '<div class="form-row"><span data-i18n="clipboard.pasteNodes"></span>'+ + ' <a class="red-ui-button" id="red-ui-clipboard-dialog-import-file-upload-btn"><i class="fa fa-upload"></i> <span data-i18n="clipboard.selectFile"></span></a>'+ + '<input type="file" id="red-ui-clipboard-dialog-import-file-upload" accept=".json" style="display:none">'+ + '</div>'+ + '<div class="form-row">'+ + '<textarea id="red-ui-clipboard-dialog-import-text"></textarea>'+ + '</div>'+ + '</div>'+ + '<div id="red-ui-clipboard-dialog-import-tab-library" class="red-ui-clipboard-dialog-tab-library"></div>'+ + '<div id="red-ui-clipboard-dialog-import-tab-examples" class="red-ui-clipboard-dialog-tab-library"></div>'+ + '</div>'+ + '</div>'+ + '<div class="form-row">'+ + '<label style="width:auto;margin-right: 10px;" data-i18n="clipboard.import.import"></label>'+ + '<span id="red-ui-clipboard-dialog-import-opt" class="button-group">'+ + '<a id="red-ui-clipboard-dialog-import-opt-current" class="red-ui-button toggle selected" href="#" data-i18n="clipboard.export.current"></a>'+ + '<a id="red-ui-clipboard-dialog-import-opt-new" class="red-ui-button toggle" href="#" data-i18n="clipboard.import.newFlow"></a>'+ + '</span>'+ + '</div>'; + + } + + var validateExportFilenameTimeout + function validateExportFilename() { + if (validateExportFilenameTimeout) { + clearTimeout(validateExportFilenameTimeout); + } + validateExportFilenameTimeout = setTimeout(function() { + var filenameInput = $("#red-ui-clipboard-dialog-tab-library-name"); + var filename = filenameInput.val().trim(); + var valid = filename.length > 0 && !/[\/\\]/.test(filename); + if (valid) { + filenameInput.removeClass("input-error"); + $("#red-ui-clipboard-dialog-export").button("enable"); + } else { + filenameInput.addClass("input-error"); + $("#red-ui-clipboard-dialog-export").button("disable"); + } + },100); + } + + var validateImportTimeout; + function validateImport() { + if (activeTab === "red-ui-clipboard-dialog-import-tab-clipboard") { + if (validateImportTimeout) { + clearTimeout(validateImportTimeout); + } + validateImportTimeout = setTimeout(function() { + var importInput = $("#red-ui-clipboard-dialog-import-text"); + var v = importInput.val().trim(); + if (v === "") { + popover.close(true); + currentPopoverError = null; + importInput.removeClass("input-error"); + $("#red-ui-clipboard-dialog-ok").button("disable"); + return; + } + try { + if (!/^\[[\s\S]*\]$/m.test(v)) { + throw new Error(RED._("clipboard.import.errors.notArray")); + } + var res = JSON.parse(v); + for (var i=0;i<res.length;i++) { + if (typeof res[i] !== "object") { + throw new Error(RED._("clipboard.import.errors.itemNotObject",{index:i})); + } + if (!res[i].hasOwnProperty('id')) { + throw new Error(RED._("clipboard.import.errors.missingId",{index:i})); + } + if (!res[i].hasOwnProperty('type')) { + throw new Error(RED._("clipboard.import.errors.missingType",{index:i})); + } + } + currentPopoverError = null; + popover.close(true); + importInput.removeClass("input-error"); + importInput.val(v); + $("#red-ui-clipboard-dialog-ok").button("enable"); + } catch(err) { + if (v !== "") { + importInput.addClass("input-error"); + var errString = err.toString(); + if (errString !== currentPopoverError) { + // Display the error as-is. + // Error messages are only in English. Each browser has its + // own set of messages with very little consistency. + // To provide translated messages this code will either need to: + // - reduce everything down to 'unexpected token at position x' + // which is the least useful, but most consistent message + // - use a custom/library parser that gives consistent messages + // which can be translated. + var message = $('<div class="red-ui-clipboard-import-error"></div>').text(errString); + var errorPos; + // Chrome error messages + var m = /at position (\d+)/i.exec(errString); + if (m) { + errorPos = parseInt(m[1]); + } else { + // Firefox error messages + m = /at line (\d+) column (\d+)/i.exec(errString); + if (m) { + var line = parseInt(m[1])-1; + var col = parseInt(m[2])-1; + var lines = v.split("\n"); + errorPos = 0; + for (var i=0;i<line;i++) { + errorPos += lines[i].length+1; + } + errorPos += col; + } else { + // Safari doesn't provide any position information + // IE: tbd + } + } + + if (errorPos !== undefined) { + v = v.replace(/\n/g,"↵"); + var index = parseInt(m[1]); + var parseError = $('<div>').appendTo(message); + var code = $('<pre>').appendTo(parseError); + $('<span>').text(v.substring(errorPos-12,errorPos)).appendTo(code) + $('<span class="error">').text(v.charAt(errorPos)).appendTo(code); + $('<span>').text(v.substring(errorPos+1,errorPos+12)).appendTo(code); + } + popover.close(true).setContent(message).open(); + currentPopoverError = errString; + } + } else { + currentPopoverError = null; + } + $("#red-ui-clipboard-dialog-ok").button("disable"); + } + },100); + } else { + var file = libraryBrowser.getSelected(); + if (file && file.label && !file.children) { + $("#red-ui-clipboard-dialog-ok").button("enable"); + } else { + $("#red-ui-clipboard-dialog-ok").button("disable"); + } + } + } + + function importNodes(mode) { + if (disabled) { + return; + } + mode = mode || "clipboard"; + + dialogContainer.empty(); + dialogContainer.append($(importNodesDialog)); + + var tabs = RED.tabs.create({ + id: "red-ui-clipboard-dialog-import-tabs", + vertical: true, + onchange: function(tab) { + $("#red-ui-clipboard-dialog-import-tabs-content").children().hide(); + $("#" + tab.id).show(); + activeTab = tab.id; + if (popover) { + popover.close(true); + currentPopoverError = null; + } + if (tab.id === "red-ui-clipboard-dialog-import-tab-clipboard") { + $("#red-ui-clipboard-dialog-import-text").trigger("focus"); + } else { + libraryBrowser.focus(); + } + validateImport(); + } + }); + tabs.addTab({ + id: "red-ui-clipboard-dialog-import-tab-clipboard", + label: RED._("clipboard.clipboard") + }); + tabs.addTab({ + id: "red-ui-clipboard-dialog-import-tab-library", + label: RED._("library.library") + }); + tabs.addTab({ + id: "red-ui-clipboard-dialog-import-tab-examples", + label: RED._("library.types.examples") + }); + + $("#red-ui-clipboard-dialog-tab-library-name").on("keyup", validateExportFilename); + $("#red-ui-clipboard-dialog-tab-library-name").on('paste',function() { setTimeout(validateExportFilename,10)}); + $("#red-ui-clipboard-dialog-export").button("enable"); + + libraryBrowser = RED.library.createBrowser({ + container: $("#red-ui-clipboard-dialog-import-tab-library"), + onselect: function(file) { + if (file && file.label && !file.children) { + $("#red-ui-clipboard-dialog-ok").button("enable"); + } else { + $("#red-ui-clipboard-dialog-ok").button("disable"); + } + }, + onconfirm: function(item) { + if (item && item.label && !item.children) { + $("#red-ui-clipboard-dialog-ok").trigger("click"); + } + } + }) + loadFlowLibrary(libraryBrowser,"local",RED._("library.types.local")); + + examplesBrowser = RED.library.createBrowser({ + container: $("#red-ui-clipboard-dialog-import-tab-examples"), + onselect: function(file) { + if (file && file.label && !file.children) { + $("#red-ui-clipboard-dialog-ok").button("enable"); + } else { + $("#red-ui-clipboard-dialog-ok").button("disable"); + } + }, + onconfirm: function(item) { + if (item && item.label && !item.children) { + $("#red-ui-clipboard-dialog-ok").trigger("click"); + } + } + }) + loadFlowLibrary(examplesBrowser,"_examples_",RED._("library.types.examples")); + + + dialogContainer.i18n(); + + $("#red-ui-clipboard-dialog-ok").show(); + $("#red-ui-clipboard-dialog-cancel").show(); + $("#red-ui-clipboard-dialog-export").hide(); + $("#red-ui-clipboard-dialog-download").hide(); + $("#red-ui-clipboard-dialog-ok").button("disable"); + $("#red-ui-clipboard-dialog-import-text").on("keyup", validateImport); + $("#red-ui-clipboard-dialog-import-text").on('paste',function() { setTimeout(validateImport,10)}); + + $("#red-ui-clipboard-dialog-import-opt > a").on("click", function(evt) { + evt.preventDefault(); + if ($(this).hasClass('disabled') || $(this).hasClass('selected')) { + return; + } + $(this).parent().children().removeClass('selected'); + $(this).addClass('selected'); + }); + + $("#red-ui-clipboard-dialog-import-file-upload").on("change", function() { + var fileReader = new FileReader(); + fileReader.onload = function () { + $("#red-ui-clipboard-dialog-import-text").val(fileReader.result); + validateImport(); + }; + fileReader.readAsText($(this).prop('files')[0]); + }) + $("#red-ui-clipboard-dialog-import-file-upload-btn").on("click", function(evt) { + evt.preventDefault(); + $("#red-ui-clipboard-dialog-import-file-upload").trigger("click"); + }) + + tabs.activateTab("red-ui-clipboard-dialog-import-tab-"+mode); + if (mode === 'clipboard') { + setTimeout(function() { + $("#red-ui-clipboard-dialog-import-text").trigger("focus"); + },100) + } + + + dialog.dialog("option","title",RED._("clipboard.importNodes")).dialog("open"); + popover = RED.popover.create({ + target: $("#red-ui-clipboard-dialog-import-text"), + trigger: "manual", + direction: "bottom", + content: "" + }); + } + + function exportNodes(mode) { + if (disabled) { + return; + } + + mode = mode || "clipboard"; + + dialogContainer.empty(); + dialogContainer.append($(exportNodesDialog)); + + var tabs = RED.tabs.create({ + id: "red-ui-clipboard-dialog-export-tabs", + vertical: true, + onchange: function(tab) { + $("#red-ui-clipboard-dialog-export-tabs-content").children().hide(); + $("#" + tab.id).show(); + activeTab = tab.id; + if (tab.id === "red-ui-clipboard-dialog-export-tab-clipboard") { + $("#red-ui-clipboard-dialog-export").button("option","label", RED._("clipboard.export.copy")) + $("#red-ui-clipboard-dialog-download").show(); + } else { + $("#red-ui-clipboard-dialog-export").button("option","label", RED._("clipboard.export.export")) + $("#red-ui-clipboard-dialog-download").hide(); + libraryBrowser.focus(); + } + + } + }); + tabs.addTab({ + id: "red-ui-clipboard-dialog-export-tab-clipboard", + label: RED._("clipboard.clipboard") + }); + tabs.addTab({ + id: "red-ui-clipboard-dialog-export-tab-library", + label: RED._("library.library") + }); + + $("#red-ui-clipboard-dialog-tab-library-name").on("keyup", validateExportFilename); + $("#red-ui-clipboard-dialog-tab-library-name").on('paste',function() { setTimeout(validateExportFilename,10)}); + $("#red-ui-clipboard-dialog-export").button("enable"); + + libraryBrowser = RED.library.createBrowser({ + container: $("#red-ui-clipboard-dialog-export-tab-library-browser"), + folderTools: true, + onselect: function(file) { + if (file && file.label && !file.children) { + $("#red-ui-clipboard-dialog-tab-library-name").val(file.label); + } + } + }) + loadFlowLibrary(libraryBrowser,"local",RED._("library.types.local")); + + $("#red-ui-clipboard-dialog-tab-library-name").val("flows.json").select(); + + dialogContainer.i18n(); + var format = RED.settings.flowFilePretty ? "red-ui-clipboard-dialog-export-fmt-full" : "red-ui-clipboard-dialog-export-fmt-mini"; + + $("#red-ui-clipboard-dialog-export-fmt-group > a").on("click", function(evt) { + evt.preventDefault(); + if ($(this).hasClass('disabled') || $(this).hasClass('selected')) { + $("#red-ui-clipboard-dialog-export-text").trigger("focus"); + return; + } + $(this).parent().children().removeClass('selected'); + $(this).addClass('selected'); + + var flow = $("#red-ui-clipboard-dialog-export-text").val(); + if (flow.length > 0) { + var nodes = JSON.parse(flow); + + format = $(this).attr('id'); + if (format === 'red-ui-clipboard-dialog-export-fmt-full') { + flow = JSON.stringify(nodes,null,4); + } else { + flow = JSON.stringify(nodes); + } + $("#red-ui-clipboard-dialog-export-text").val(flow); + setTimeout(function() { $("#red-ui-clipboard-dialog-export-text").scrollTop(0); },50); + + $("#red-ui-clipboard-dialog-export-text").trigger("focus"); + } + }); + + $("#red-ui-clipboard-dialog-export-rng-group > a").on("click", function(evt) { + evt.preventDefault(); + if ($(this).hasClass('disabled') || $(this).hasClass('selected')) { + return; + } + $(this).parent().children().removeClass('selected'); + $(this).addClass('selected'); + var type = $(this).attr('id'); + var flow = ""; + var nodes = null; + if (type === 'red-ui-clipboard-dialog-export-rng-selected') { + var selection = RED.workspaces.selection(); + if (selection.length > 0) { + nodes = []; + selection.forEach(function(n) { + nodes.push(n); + nodes = nodes.concat(RED.nodes.filterNodes({z:n.id})); + }); + } else { + nodes = RED.view.selection().nodes||[]; + } + // Don't include the subflow meta-port nodes in the exported selection + nodes = RED.nodes.createExportableNodeSet(nodes.filter(function(n) { return n.type !== 'subflow'})); + } else if (type === 'red-ui-clipboard-dialog-export-rng-flow') { + var activeWorkspace = RED.workspaces.active(); + nodes = RED.nodes.filterNodes({z:activeWorkspace}); + var parentNode = RED.nodes.workspace(activeWorkspace)||RED.nodes.subflow(activeWorkspace); + nodes.unshift(parentNode); + nodes = RED.nodes.createExportableNodeSet(nodes); + } else if (type === 'red-ui-clipboard-dialog-export-rng-full') { + nodes = RED.nodes.createCompleteNodeSet(false); + } + if (nodes !== null) { + if (format === "red-ui-clipboard-dialog-export-fmt-full") { + flow = JSON.stringify(nodes,null,4); + } else { + flow = JSON.stringify(nodes); + } + } + if (flow.length > 0) { + $("#red-ui-clipboard-dialog-export").removeClass('disabled'); + } else { + $("#red-ui-clipboard-dialog-export").addClass('disabled'); + } + $("#red-ui-clipboard-dialog-export-text").val(flow); + setTimeout(function() { $("#red-ui-clipboard-dialog-export-text").scrollTop(0); },50); + $("#red-ui-clipboard-dialog-export-text").trigger("focus"); + }) + + $("#red-ui-clipboard-dialog-ok").hide(); + $("#red-ui-clipboard-dialog-cancel").hide(); + $("#red-ui-clipboard-dialog-export").hide(); + var selection = RED.workspaces.selection(); + if (selection.length > 0) { + $("#red-ui-clipboard-dialog-export-rng-selected").trigger("click"); + } else { + selection = RED.view.selection(); + if (selection.nodes) { + $("#red-ui-clipboard-dialog-export-rng-selected").trigger("click"); + } else { + $("#red-ui-clipboard-dialog-export-rng-selected").addClass('disabled').removeClass('selected'); + $("#red-ui-clipboard-dialog-export-rng-flow").trigger("click"); + } + } + if (format === "red-ui-clipboard-dialog-export-fmt-full") { + $("#red-ui-clipboard-dialog-export-fmt-full").trigger("click"); + } else { + $("#red-ui-clipboard-dialog-export-fmt-mini").trigger("click"); + } + tabs.activateTab("red-ui-clipboard-dialog-export-tab-"+mode); + dialog.dialog("option","title",RED._("clipboard.exportNodes")).dialog( "open" ); + + $("#red-ui-clipboard-dialog-export-text").trigger("focus"); + $("#red-ui-clipboard-dialog-cancel").show(); + $("#red-ui-clipboard-dialog-export").show(); + $("#red-ui-clipboard-dialog-download").show(); + + } + + function loadFlowLibrary(browser,library,label) { + // if (includeExamples) { + // listing.push({ + // library: "_examples_", + // type: "flows", + // icon: 'fa fa-hdd-o', + // label: RED._("library.types.examples"), + // path: "", + // children: function(done,item) { + // RED.library.loadLibraryFolder("_examples_","flows","",function(children) { + // item.children = children; + // done(children); + // }) + // } + // }) + // } + browser.data([{ + library: library, + type: "flows", + icon: 'fa fa-hdd-o', + label: label, + path: "", + expanded: true, + children: function(done, item) { + RED.library.loadLibraryFolder(library,"flows","",function(children) { + item.children = children; + done(children); + }) + } + }], true); + + } + + function hideDropTarget() { + $("#red-ui-drop-target").hide(); + RED.keyboard.remove("escape"); + } + function copyText(value,element,msg) { + var truncated = false; + if (typeof value !== "string" ) { + value = JSON.stringify(value, function(key,value) { + if (value !== null && typeof value === 'object') { + if (value.__enc__) { + if (value.hasOwnProperty('data') && value.hasOwnProperty('length')) { + truncated = value.data.length !== value.length; + return value.data; + } + if (value.type === 'function' || value.type === 'internal') { + return undefined + } + if (value.type === 'number') { + // Handle NaN and Infinity - they are not permitted + // in JSON. We can either substitute with a String + // representation or null + return null; + } + } + } + return value; + }); + } + if (truncated) { + msg += "_truncated"; + } + $("#red-ui-clipboard-hidden").val(value).select(); + var result = document.execCommand("copy"); + if (result && element) { + var popover = RED.popover.create({ + target: element, + direction: 'left', + size: 'small', + content: RED._(msg) + }); + setTimeout(function() { + popover.close(); + },1000); + popover.open(); + } + return result; + } + return { + init: function() { + setupDialogs(); + + $('<input type="text" id="red-ui-clipboard-hidden" tabIndex="-1">').appendTo("#red-ui-editor"); + + RED.actions.add("core:show-export-dialog",exportNodes); + RED.actions.add("core:show-import-dialog",importNodes); + + RED.actions.add("core:show-library-export-dialog",function() { exportNodes('library') }); + RED.actions.add("core:show-library-import-dialog",function() { importNodes('library') }); + + RED.events.on("editor:open",function() { disabled = true; }); + RED.events.on("editor:close",function() { disabled = false; }); + RED.events.on("search:open",function() { disabled = true; }); + RED.events.on("search:close",function() { disabled = false; }); + RED.events.on("actionList:open",function() { disabled = true; }); + RED.events.on("actionList:close",function() { disabled = false; }); + RED.events.on("type-search:open",function() { disabled = true; }); + RED.events.on("type-search:close",function() { disabled = false; }); + + $('<div id="red-ui-drop-target"><div data-i18n="[append]workspace.dropFlowHere"><i class="fa fa-download"></i><br></div></div>').appendTo('#red-ui-editor'); + + $('#red-ui-workspace-chart').on("dragenter",function(event) { + if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1 || + $.inArray("Files",event.originalEvent.dataTransfer.types) != -1) { + $("#red-ui-drop-target").css({display:'table'}); + RED.keyboard.add("*", "escape" ,hideDropTarget); + } + }); + + $('#red-ui-drop-target').on("dragover",function(event) { + if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1 || + $.inArray("Files",event.originalEvent.dataTransfer.types) != -1) { + event.preventDefault(); + } + }) + .on("dragleave",function(event) { + hideDropTarget(); + }) + .on("drop",function(event) { + if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) { + var data = event.originalEvent.dataTransfer.getData("text/plain"); + data = data.substring(data.indexOf('['),data.lastIndexOf(']')+1); + RED.view.importNodes(data); + } else if ($.inArray("Files",event.originalEvent.dataTransfer.types) != -1) { + var files = event.originalEvent.dataTransfer.files; + if (files.length === 1) { + var file = files[0]; + var reader = new FileReader(); + reader.onload = (function(theFile) { + return function(e) { + RED.view.importNodes(e.target.result); + }; + })(file); + reader.readAsText(file); + } + } + hideDropTarget(); + event.preventDefault(); + }); + + }, + import: importNodes, + export: exportNodes, + copyText: copyText + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/checkboxSet.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/checkboxSet.js new file mode 100644 index 0000000..157c1e4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/checkboxSet.js @@ -0,0 +1,131 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +(function($) { + $.widget( "nodered.checkboxSet", { + _create: function() { + var that = this; + this.uiElement = this.element.wrap( "<span>" ).parent(); + this.uiElement.addClass("red-ui-checkboxSet"); + if (this.options.parent) { + this.parent = this.options.parent; + this.parent.checkboxSet('addChild',this.element); + } + this.children = []; + this.partialFlag = false; + this.stateValue = 0; + var initialState = this.element.prop('checked'); + this.options = [ + $('<span class="red-ui-checkboxSet-option hide"><i class="fa fa-square-o"></i></span>').appendTo(this.uiElement), + $('<span class="red-ui-checkboxSet-option hide"><i class="fa fa-check-square-o"></i></span>').appendTo(this.uiElement), + $('<span class="red-ui-checkboxSet-option hide"><i class="fa fa-minus-square-o"></i></span>').appendTo(this.uiElement) + ]; + if (initialState) { + this.options[1].show(); + } else { + this.options[0].show(); + } + + this.element.on("change", function() { + if (this.checked) { + that.options[0].hide(); + that.options[1].show(); + that.options[2].hide(); + } else { + that.options[1].hide(); + that.options[0].show(); + that.options[2].hide(); + } + var isChecked = this.checked; + that.children.forEach(function(child) { + child.checkboxSet('state',isChecked,false,true); + }) + }) + this.uiElement.on("click", function(e) { + e.stopPropagation(); + // state returns null for a partial state. Clicking on that should + // result in false. + that.state((that.state()===false)?true:false); + }) + if (this.parent) { + this.parent.checkboxSet('updateChild',this); + } + }, + _destroy: function() { + if (this.parent) { + this.parent.checkboxSet('removeChild',this.element); + } + }, + addChild: function(child) { + var that = this; + this.children.push(child); + }, + removeChild: function(child) { + var index = this.children.indexOf(child); + if (index > -1) { + this.children.splice(index,1); + } + }, + updateChild: function(child) { + var checkedCount = 0; + this.children.forEach(function(c,i) { + if (c.checkboxSet('state') === true) { + checkedCount++; + } + }); + if (checkedCount === 0) { + + this.state(false,true); + } else if (checkedCount === this.children.length) { + this.state(true,true); + } else { + this.state(null,true); + } + }, + disable: function() { + this.uiElement.addClass('disabled'); + }, + state: function(state,suppressEvent,suppressParentUpdate) { + + if (arguments.length === 0) { + return this.partialFlag?null:this.element.is(":checked"); + } else { + this.partialFlag = (state === null); + var trueState = this.partialFlag||state; + this.element.prop('checked',trueState); + if (state === true) { + this.options[0].hide(); + this.options[1].show(); + this.options[2].hide(); + } else if (state === false) { + this.options[2].hide(); + this.options[1].hide(); + this.options[0].show(); + } else if (state === null) { + this.options[0].hide(); + this.options[1].hide(); + this.options[2].show(); + } + if (!suppressEvent) { + this.element.trigger('change',null); + } + if (!suppressParentUpdate && this.parent) { + this.parent.checkboxSet('updateChild',this); + } + } + } + }) + +})(jQuery); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js new file mode 100644 index 0000000..06ccc97 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js @@ -0,0 +1,383 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +(function($) { + +/** + * options: + * - addButton : boolean|string - text for add label, default 'add' + * - height : number|'auto' + * - resize : function - called when list as a whole is resized + * - resizeItem : function(item) - called to resize individual item + * - sortable : boolean|string - string is the css selector for handle + * - sortItems : function(items) - when order of items changes + * - connectWith : css selector of other sortables + * - removable : boolean - whether to display delete button on items + * - addItem : function(row,index,itemData) - when an item is added + * - removeItem : function(itemData) - called when an item is removed + * - filter : function(itemData) - called for each item to determine if it should be shown + * - sort : function(itemDataA,itemDataB) - called to sort items + * - scrollOnAdd : boolean - whether to scroll to newly added items + * methods: + * - addItem(itemData) + * - insertItemAt : function(data,index) - add an item at the specified index + * - removeItem(itemData) + * - getItemAt(index) + * - indexOf(itemData) + * - width(width) + * - height(height) + * - items() + * - empty() + * - filter(filter) + * - sort(sort) + * - length() + */ + $.widget( "nodered.editableList", { + _create: function() { + var that = this; + + this.element.addClass('red-ui-editableList-list'); + this.uiWidth = this.element.width(); + this.uiContainer = this.element + .wrap( "<div>" ) + .parent(); + + if (this.options.header) { + this.options.header.addClass("red-ui-editableList-header"); + this.borderContainer = this.uiContainer.wrap("<div>").parent(); + this.borderContainer.prepend(this.options.header); + this.topContainer = this.borderContainer.wrap("<div>").parent(); + } else { + this.topContainer = this.uiContainer.wrap("<div>").parent(); + } + this.topContainer.addClass('red-ui-editableList'); + if (this.options.class) { + this.topContainer.addClass(this.options.class); + } + + if (this.options.addButton !== false) { + var addLabel; + if (typeof this.options.addButton === 'string') { + addLabel = this.options.addButton + } else { + if (RED && RED._) { + addLabel = RED._("editableList.add"); + } else { + addLabel = 'add'; + } + } + $('<a href="#" class="red-ui-button red-ui-button-small red-ui-editableList-addButton" style="margin-top: 4px;"><i class="fa fa-plus"></i> '+addLabel+'</a>') + .appendTo(this.topContainer) + .on("click", function(evt) { + evt.preventDefault(); + that.addItem({}); + }); + } + if (this.element.css("position") === "absolute") { + ["top","left","bottom","right"].forEach(function(s) { + var v = that.element.css(s); + if (v!=="auto" && v!=="") { + that.topContainer.css(s,v); + that.uiContainer.css(s,"0"); + that.element.css(s,'auto'); + } + }) + this.element.css("position","static"); + this.topContainer.css("position","absolute"); + this.uiContainer.css("position","absolute"); + + } + if (this.options.header) { + this.borderContainer.addClass("red-ui-editableList-border"); + } else { + this.uiContainer.addClass("red-ui-editableList-border"); + } + this.uiContainer.addClass("red-ui-editableList-container"); + + this.uiHeight = this.element.height(); + + this.activeFilter = this.options.filter||null; + this.activeSort = this.options.sort||null; + this.scrollOnAdd = this.options.scrollOnAdd; + if (this.scrollOnAdd === undefined) { + this.scrollOnAdd = true; + } + var minHeight = this.element.css("minHeight"); + if (minHeight !== '0px') { + this.uiContainer.css("minHeight",minHeight); + this.element.css("minHeight",0); + } + var maxHeight = this.element.css("maxHeight"); + if (maxHeight !== '0px') { + this.uiContainer.css("maxHeight",maxHeight); + this.element.css("maxHeight",null); + } + if (this.options.height !== 'auto') { + this.uiContainer.css("overflow-y","scroll"); + if (!isNaN(this.options.height)) { + this.uiHeight = this.options.height; + } + } + this.element.height('auto'); + + var attrStyle = this.element.attr('style'); + var m; + if ((m = /width\s*:\s*(\d+%)/i.exec(attrStyle)) !== null) { + this.element.width('100%'); + this.uiContainer.width(m[1]); + } + if (this.options.sortable) { + var handle = (typeof this.options.sortable === 'string')? + this.options.sortable : + ".red-ui-editableList-item-handle"; + var sortOptions = { + axis: "y", + update: function( event, ui ) { + if (that.options.sortItems) { + that.options.sortItems(that.items()); + } + }, + handle:handle, + cursor: "move", + tolerance: "pointer", + forcePlaceholderSize:true, + placeholder: "red-ui-editabelList-item-placeholder", + start: function(e, ui){ + ui.placeholder.height(ui.item.height()-4); + } + }; + if (this.options.connectWith) { + sortOptions.connectWith = this.options.connectWith; + } + + this.element.sortable(sortOptions); + } + + this._resize(); + + // this.menu = this._createMenu(this.types, function(v) { that.type(v) }); + // this.type(this.options.default||this.types[0].value); + }, + _resize: function() { + var currentFullHeight = this.topContainer.height(); + var innerHeight = this.uiContainer.height(); + var delta = currentFullHeight - innerHeight; + if (this.uiHeight !== 0) { + this.uiContainer.height(this.uiHeight-delta); + } + if (this.options.resize) { + this.options.resize(); + } + if (this.options.resizeItem) { + var that = this; + this.element.children().each(function(i) { + that.options.resizeItem($(this).find(".red-ui-editableList-item-content"),i); + }); + } + }, + _destroy: function() { + if (this.topContainer) { + var tc = this.topContainer; + delete this.topContainer; + tc.remove(); + } + }, + _refreshFilter: function() { + var that = this; + var count = 0; + if (!this.activeFilter) { + return this.element.children().show(); + } + var items = this.items(); + items.each(function (i,el) { + var data = el.data('data'); + try { + if (that.activeFilter(data)) { + el.parent().show(); + count++; + } else { + el.parent().hide(); + } + } catch(err) { + console.log(err); + el.parent().show(); + count++; + } + }); + return count; + }, + _refreshSort: function() { + if (this.activeSort) { + var items = this.element.children(); + var that = this; + items.sort(function(A,B) { + return that.activeSort($(A).find(".red-ui-editableList-item-content").data('data'),$(B).find(".red-ui-editableList-item-content").data('data')); + }); + $.each(items,function(idx,li) { + that.element.append(li); + }) + } + }, + width: function(desiredWidth) { + this.uiWidth = desiredWidth; + this._resize(); + }, + height: function(desiredHeight) { + this.uiHeight = desiredHeight; + this._resize(); + }, + getItemAt: function(index) { + var items = this.items(); + if (index >= 0 && index < items.length) { + return $(items[index]).data('data'); + } else { + return; + } + }, + indexOf: function(data) { + var items = this.items(); + for (var i=0;i<items.length;i++) { + if ($(items[i]).data('data') === data) { + return i + } + } + return -1 + }, + insertItemAt: function(data,index) { + var that = this; + data = data || {}; + var li = $('<li>'); + var added = false; + if (this.activeSort) { + var items = this.items(); + var skip = false; + items.each(function(i,el) { + if (added) { return } + var itemData = el.data('data'); + if (that.activeSort(data,itemData) < 0) { + li.insertBefore(el.closest("li")); + added = true; + } + }); + } + if (!added) { + if (index <= 0) { + li.prependTo(this.element); + } else if (index > that.element.children().length-1) { + li.appendTo(this.element); + } else { + li.insertBefore(this.element.children().eq(index)); + } + } + var row = $('<div/>').addClass("red-ui-editableList-item-content").appendTo(li); + row.data('data',data); + if (this.options.sortable === true) { + $('<i class="red-ui-editableList-item-handle fa fa-bars"></i>').appendTo(li); + li.addClass("red-ui-editableList-item-sortable"); + } + if (this.options.removable) { + var deleteButton = $('<a/>',{href:"#",class:"red-ui-editableList-item-remove red-ui-button red-ui-button-small"}).appendTo(li); + $('<i/>',{class:"fa fa-remove"}).appendTo(deleteButton); + li.addClass("red-ui-editableList-item-removable"); + deleteButton.on("click", function(evt) { + evt.preventDefault(); + var data = row.data('data'); + li.addClass("red-ui-editableList-item-deleting") + li.fadeOut(300, function() { + $(this).remove(); + if (that.options.removeItem) { + that.options.removeItem(data); + } + }); + }); + } + if (this.options.addItem) { + var index = that.element.children().length-1; + setTimeout(function() { + that.options.addItem(row,index,data); + if (that.activeFilter) { + try { + if (!that.activeFilter(data)) { + li.hide(); + } + } catch(err) { + } + } + + if (!that.activeSort && that.scrollOnAdd) { + setTimeout(function() { + that.uiContainer.scrollTop(that.element.height()); + },0); + } + },0); + } + }, + addItem: function(data) { + this.insertItemAt(data,this.element.children().length) + }, + addItems: function(items) { + for (var i=0; i<items.length;i++) { + this.addItem(items[i]); + } + }, + removeItem: function(data) { + var items = this.element.children().filter(function(f) { + return data === $(this).find(".red-ui-editableList-item-content").data('data'); + }); + items.remove(); + if (this.options.removeItem) { + this.options.removeItem(data); + } + }, + items: function() { + return this.element.children().map(function(i) { return $(this).find(".red-ui-editableList-item-content"); }); + }, + empty: function() { + this.element.empty(); + this.uiContainer.scrollTop(0); + }, + filter: function(filter) { + if (filter !== undefined) { + this.activeFilter = filter; + } + return this._refreshFilter(); + }, + sort: function(sort) { + if (sort !== undefined) { + this.activeSort = sort; + } + return this._refreshSort(); + }, + length: function() { + return this.element.children().length; + }, + show: function(item) { + var items = this.element.children().filter(function(f) { + return item === $(this).find(".red-ui-editableList-item-content").data('data'); + }); + if (items.length > 0) { + this.uiContainer.scrollTop(this.uiContainer.scrollTop()+items.position().top) + } + }, + getItem: function(li) { + var el = li.find(".red-ui-editableList-item-content"); + if (el.length) { + return el.data('data'); + } else { + return null; + } + } + }); +})(jQuery); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/menu.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/menu.js new file mode 100644 index 0000000..e73c822 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/menu.js @@ -0,0 +1,289 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.menu = (function() { + + var menuItems = {}; + + function createMenuItem(opt) { + var item; + + if (opt !== null && opt.id) { + var themeSetting = RED.settings.theme("menu."+opt.id); + if (themeSetting === false) { + return null; + } + } + + function setInitialState() { + var savedStateActive = RED.settings.get("menu-" + opt.id); + if (opt.setting) { + // May need to migrate pre-0.17 setting + + if (savedStateActive !== null) { + RED.settings.set(opt.setting,savedStateActive); + RED.settings.remove("menu-" + opt.id); + } else { + savedStateActive = RED.settings.get(opt.setting); + } + } + if (savedStateActive) { + link.addClass("active"); + triggerAction(opt.id,true); + } else if (savedStateActive === false) { + link.removeClass("active"); + triggerAction(opt.id,false); + } else if (opt.hasOwnProperty("selected")) { + if (opt.selected) { + link.addClass("active"); + } else { + link.removeClass("active"); + } + triggerAction(opt.id,opt.selected); + } + } + + if (opt === null) { + item = $('<li class="red-ui-menu-divider"></li>'); + } else { + item = $('<li></li>'); + + if (opt.group) { + item.addClass("red-ui-menu-group-"+opt.group); + + } + var linkContent = '<a '+(opt.id?'id="'+opt.id+'" ':'')+'tabindex="-1" href="#">'; + if (opt.toggle) { + linkContent += '<i class="fa fa-square pull-left"></i>'; + linkContent += '<i class="fa fa-check-square pull-left"></i>'; + + } + if (opt.icon !== undefined) { + if (/\.(png|svg)/.test(opt.icon)) { + linkContent += '<img src="'+opt.icon+'"/> '; + } else { + linkContent += '<i class="'+(opt.icon?opt.icon:'" style="display: inline-block;"')+'"></i> '; + } + } + + if (opt.sublabel) { + linkContent += '<span class="red-ui-menu-label-container"><span class="red-ui-menu-label">'+opt.label+'</span>'+ + '<span class="red-ui-menu-sublabel">'+opt.sublabel+'</span></span>' + } else { + linkContent += '<span class="red-ui-menu-label">'+opt.label+'</span>' + } + + linkContent += '</a>'; + + var link = $(linkContent).appendTo(item); + + menuItems[opt.id] = opt; + + if (opt.onselect) { + link.on("click", function(e) { + e.preventDefault(); + if ($(this).parent().hasClass("disabled")) { + return; + } + if (opt.toggle) { + if (opt.toggle === true) { + setSelected(opt.id, !isSelected(opt.id)); + } else { + setSelected(opt.id, true); + } + } else { + triggerAction(opt.id); + } + }); + if (opt.toggle) { + setInitialState(); + } + } else if (opt.href) { + link.attr("target","_blank").attr("href",opt.href); + } else if (!opt.options) { + item.addClass("disabled"); + link.on("click", function(event) { + event.preventDefault(); + }); + } + if (opt.options) { + item.addClass("red-ui-menu-dropdown-submenu pull-left"); + var submenu = $('<ul id="'+opt.id+'-submenu" class="red-ui-menu-dropdown"></ul>').appendTo(item); + + for (var i=0;i<opt.options.length;i++) { + var li = createMenuItem(opt.options[i]); + if (li) { + li.appendTo(submenu); + } + } + } + if (opt.disabled) { + item.addClass("disabled"); + } + } + + + return item; + + } + function createMenu(options) { + var topMenu = $("<ul/>",{class:"red-ui-menu red-ui-menu-dropdown pull-right"}); + + if (options.id) { + topMenu.attr({id:options.id+"-submenu"}); + var menuParent = $("#"+options.id); + if (menuParent.length === 1) { + topMenu.insertAfter(menuParent); + menuParent.on("click", function(evt) { + evt.stopPropagation(); + evt.preventDefault(); + if (topMenu.is(":visible")) { + $(document).off("click.red-ui-menu"); + topMenu.hide(); + } else { + $(document).on("click.red-ui-menu", function(evt) { + $(document).off("click.red-ui-menu"); + activeMenu = null; + topMenu.hide(); + }); + $(".red-ui-menu").hide(); + topMenu.show(); + } + }) + } + } + + var lastAddedSeparator = false; + for (var i=0;i<options.options.length;i++) { + var opt = options.options[i]; + if (opt !== null || !lastAddedSeparator) { + var li = createMenuItem(opt); + if (li) { + li.appendTo(topMenu); + lastAddedSeparator = (opt === null); + } + } + } + + return topMenu; + } + + function triggerAction(id, args) { + var opt = menuItems[id]; + var callback = opt.onselect; + if (typeof opt.onselect === 'string') { + callback = RED.actions.get(opt.onselect); + } + if (callback) { + callback.call(opt,args); + } else { + console.log("No callback for",id,opt.onselect); + } + } + + function isSelected(id) { + return $("#" + id).hasClass("active"); + } + + function setSelected(id,state) { + var alreadySet = false; + if (isSelected(id) == state) { + alreadySet = true; + } + var opt = menuItems[id]; + if (state) { + $("#"+id).addClass("active"); + } else { + $("#"+id).removeClass("active"); + } + if (opt) { + if (opt.toggle && typeof opt.toggle === "string") { + if (state) { + for (var m in menuItems) { + if (menuItems.hasOwnProperty(m)) { + var mi = menuItems[m]; + if (mi.id != opt.id && opt.toggle == mi.toggle) { + setSelected(mi.id,false); + } + } + } + } + } + if (!alreadySet && opt.onselect) { + triggerAction(opt.id,state); + } + if (!opt.local && !alreadySet) { + RED.settings.set(opt.setting||("menu-"+opt.id), state); + } + } + } + + function toggleSelected(id) { + setSelected(id,!isSelected(id)); + } + + function setDisabled(id,state) { + if (state) { + $("#"+id).parent().addClass("disabled"); + } else { + $("#"+id).parent().removeClass("disabled"); + } + } + + function addItem(id,opt) { + var item = createMenuItem(opt); + if (opt !== null && opt.group) { + var groupItems = $("#"+id+"-submenu").children(".red-ui-menu-group-"+opt.group); + if (groupItems.length === 0) { + item.appendTo("#"+id+"-submenu"); + } else { + for (var i=0;i<groupItems.length;i++) { + var groupItem = groupItems[i]; + var label = $(groupItem).find(".red-ui-menu-label").html(); + if (opt.label < label) { + $(groupItem).before(item); + break; + } + } + if (i === groupItems.length) { + item.appendTo("#"+id+"-submenu"); + } + } + } else { + item.appendTo("#"+id+"-submenu"); + } + } + function removeItem(id) { + $("#"+id).parent().remove(); + } + + function setAction(id,action) { + var opt = menuItems[id]; + if (opt) { + opt.onselect = action; + } + } + + return { + init: createMenu, + setSelected: setSelected, + isSelected: isSelected, + toggleSelected: toggleSelected, + setDisabled: setDisabled, + addItem: addItem, + removeItem: removeItem, + setAction: setAction + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/panels.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/panels.js new file mode 100644 index 0000000..5a82f9d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/panels.js @@ -0,0 +1,124 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +RED.panels = (function() { + + function createPanel(options) { + var container = options.container || $("#"+options.id); + var children = container.children(); + if (children.length !== 2) { + console.log(options.id); + throw new Error("Container must have exactly two children"); + } + var vertical = (!options.dir || options.dir === "vertical"); + container.addClass("red-ui-panels"); + if (!vertical) { + container.addClass("red-ui-panels-horizontal"); + } + var separator = $('<div class="red-ui-panels-separator"></div>').insertAfter(children[0]); + var startPosition; + var panelSizes = []; + var modifiedSizes = false; + var panelRatio = 0.5; + separator.draggable({ + axis: vertical?"y":"x", + containment: container, + scroll: false, + start:function(event,ui) { + startPosition = vertical?ui.position.top:ui.position.left; + + panelSizes = [ + vertical?$(children[0]).height():$(children[0]).width(), + vertical?$(children[1]).height():$(children[1]).width() + ]; + }, + drag: function(event,ui) { + var size = vertical?container.height():container.width(); + var delta = (vertical?ui.position.top:ui.position.left)-startPosition; + var newSizes = [panelSizes[0]+delta,panelSizes[1]-delta]; + if (vertical) { + $(children[0]).height(newSizes[0]); + $(children[1]).height(newSizes[1]); + ui.position.top -= delta; + } else { + $(children[0]).width(newSizes[0]); + $(children[1]).width(newSizes[1]); + ui.position.left -= delta; + } + if (options.resize) { + options.resize(newSizes[0],newSizes[1]); + } + panelRatio = newSizes[0]/(size-8); + }, + stop:function(event,ui) { + modifiedSizes = true; + } + }); + + var panel = { + ratio: function(ratio) { + panelRatio = ratio; + modifiedSizes = true; + if (ratio === 0 || ratio === 1) { + separator.hide(); + } else { + separator.show(); + } + if (vertical) { + panel.resize(container.height()); + } else { + panel.resize(container.width()); + } + }, + resize: function(size) { + var panelSizes; + if (vertical) { + panelSizes = [$(children[0]).outerHeight(),$(children[1]).outerHeight()]; + container.height(size); + } else { + panelSizes = [$(children[0]).outerWidth(),$(children[1]).outerWidth()]; + container.width(size); + } + if (modifiedSizes) { + var topPanelSize = panelRatio*(size-8); + var bottomPanelSize = size - topPanelSize - 8; + panelSizes = [topPanelSize,bottomPanelSize]; + if (vertical) { + $(children[0]).outerHeight(panelSizes[0]); + $(children[1]).outerHeight(panelSizes[1]); + } else { + $(children[0]).outerWidth(panelSizes[0]); + $(children[1]).outerWidth(panelSizes[1]); + } + } + if (options.resize) { + if (vertical) { + panelSizes = [$(children[0]).height(),$(children[1]).height()]; + } else { + panelSizes = [$(children[0]).width(),$(children[1]).width()]; + } + options.resize(panelSizes[0],panelSizes[1]); + } + } + } + return panel; + } + + return { + create: createPanel + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/popover.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/popover.js new file mode 100644 index 0000000..fca2f26 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/popover.js @@ -0,0 +1,329 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +RED.popover = (function() { + var deltaSizes = { + "default": { + top: 10, + topTop: 30, + leftRight: 17, + leftLeft: 25, + leftBottom: 8, + leftTop: 11 + }, + "small": { + top: 6, + topTop: 20, + leftRight: 8, + leftLeft: 26, + leftBottom: 8, + leftTop: 9 + } + } + function createPopover(options) { + var target = options.target; + var direction = options.direction || "right"; + var trigger = options.trigger; + var content = options.content; + var delay = options.delay || { show: 750, hide: 50 }; + var autoClose = options.autoClose; + var width = options.width||"auto"; + var size = options.size||"default"; + if (!deltaSizes[size]) { + throw new Error("Invalid RED.popover size value:",size); + } + + var timer = null; + var active; + var div; + + var openPopup = function(instant) { + if (active) { + var existingPopover = target.data("red-ui-popover"); + if (options.tooltip && existingPopover) { + active = false; + return; + } + div = $('<div class="red-ui-popover"></div>'); + if (size !== "default") { + div.addClass("red-ui-popover-size-"+size); + } + if (typeof content === 'function') { + var result = content.call(res); + if (result === null) { + return; + } + if (typeof result === 'string') { + div.text(result); + } else { + div.append(result); + } + } else { + div.html(content); + } + if (width !== "auto") { + div.width(width); + } + div.appendTo("body"); + + var targetPos = target.offset(); + var targetWidth = target.outerWidth(); + var targetHeight = target.outerHeight(); + var divHeight = div.height(); + var divWidth = div.width(); + + var viewportTop = $(window).scrollTop(); + var viewportLeft = $(window).scrollLeft(); + var viewportBottom = viewportTop + $(window).height(); + var viewportRight = viewportLeft + $(window).width(); + var top = 0; + var left = 0; + var d = direction; + if (d === 'right') { + top = targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top; + left = targetPos.left+targetWidth+deltaSizes[size].leftRight; + } else if (d === 'left') { + top = targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top; + left = targetPos.left-deltaSizes[size].leftLeft-divWidth; + } else if (d === 'bottom') { + top = targetPos.top+targetHeight+deltaSizes[size].top; + left = targetPos.left+targetWidth/2-divWidth/2 - deltaSizes[size].leftBottom; + if (left < 0) { + d = "right"; + top = targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top; + left = targetPos.left+targetWidth+deltaSizes[size].leftRight; + } else if (left+divWidth > viewportRight) { + d = "left"; + top = targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top; + left = targetPos.left-deltaSizes[size].leftLeft-divWidth; + if (top+divHeight+targetHeight/2 + 5 > viewportBottom) { + top -= (top+divHeight+targetHeight/2 - viewportBottom + 5) + } + } else if (top+divHeight > viewportBottom) { + d = 'top'; + top = targetPos.top-deltaSizes[size].topTop-divHeight; + left = targetPos.left+targetWidth/2-divWidth/2 - deltaSizes[size].leftTop; + } + } else if (d === 'top') { + top = targetPos.top-deltaSizes[size].topTop-divHeight; + left = targetPos.left+targetWidth/2-divWidth/2 - deltaSizes[size].leftTop; + if (top < 0) { + d = 'bottom'; + top = targetPos.top+targetHeight+deltaSizes[size].top; + left = targetPos.left+targetWidth/2-divWidth/2 - deltaSizes[size].leftBottom; + } + } + div.addClass('red-ui-popover-'+d).css({top: top, left: left}); + if (existingPopover) { + existingPopover.close(true); + } + target.data("red-ui-popover",res) + if (options.tooltip) { + div.on("mousedown", function(evt) { + closePopup(true); + }); + } + if (instant) { + div.show(); + } else { + div.fadeIn("fast"); + } + } + } + var closePopup = function(instant) { + $(document).off('mousedown.red-ui-popover'); + if (!active) { + if (div) { + if (instant) { + div.remove(); + } else { + div.fadeOut("fast",function() { + $(this).remove(); + }); + } + div = null; + target.removeData("red-ui-popover",res) + } + } + } + + if (trigger === 'hover') { + target.on('mouseenter',function(e) { + clearTimeout(timer); + active = true; + timer = setTimeout(openPopup,delay.show); + }); + target.on('mouseleave disabled', function(e) { + if (timer) { + clearTimeout(timer); + } + if (active) { + active = false; + setTimeout(closePopup,delay.hide); + } + }); + } else if (trigger === 'click') { + target.on("click", function(e) { + e.preventDefault(); + e.stopPropagation(); + active = !active; + if (!active) { + closePopup(); + } else { + openPopup(); + } + }); + if (autoClose) { + target.on('mouseleave disabled', function(e) { + if (timer) { + clearTimeout(timer); + } + if (active) { + active = false; + setTimeout(closePopup,autoClose); + } + }); + } + + } else if (trigger === 'modal') { + $(document).on('mousedown.red-ui-popover', function (event) { + var target = event.target; + while (target.nodeName !== 'BODY' && target !== div[0]) { + target = target.parentElement; + } + if (target.nodeName === 'BODY') { + active = false; + closePopup(); + } + }); + } else if (autoClose) { + setTimeout(function() { + active = false; + closePopup(); + },autoClose); + } + var res = { + setContent: function(_content) { + content = _content; + return res; + }, + open: function (instant) { + active = true; + openPopup(instant); + return res; + }, + close: function (instant) { + active = false; + closePopup(instant); + return res; + } + } + return res; + + } + + return { + create: createPopover, + tooltip: function(target,content, action) { + var label = content; + if (action) { + label = function() { + var label = content; + var shortcut = RED.keyboard.getShortcut(action); + if (shortcut && shortcut.key) { + label = $('<span>'+content+' <span class="red-ui-popover-key">'+RED.keyboard.formatKey(shortcut.key, true)+'</span></span>'); + } + return label; + } + } + return RED.popover.create({ + tooltip: true, + target:target, + trigger: "hover", + size: "small", + direction: "bottom", + content: label, + delay: { show: 750, hide: 50 } + }); + }, + panel: function(content) { + var panel = $('<div class="red-ui-editor-dialog red-ui-popover-panel"></div>'); + panel.css({ display: "none" }); + panel.appendTo(document.body); + content.appendTo(panel); + var closeCallback; + + function hide() { + $(document).off("mousedown.red-ui-popover-panel-close"); + panel.hide(); + panel.css({ + height: "auto" + }); + panel.remove(); + } + function show(options) { + var closeCallback = options.onclose; + var target = options.target; + var align = options.align || "left"; + + var pos = target.offset(); + var targetWidth = target.width(); + var targetHeight = target.height(); + var panelHeight = panel.height(); + var panelWidth = panel.width(); + + var top = (targetHeight+pos.top); + if (top+panelHeight > $(window).height()) { + top -= (top+panelHeight)-$(window).height() + 5; + } + if (top < 0) { + panelHeight.height(panelHeight+top) + top = 0; + } + if (align === "left") { + panel.css({ + top: top+"px", + left: (pos.left)+"px", + }); + } else if(align === "right") { + panel.css({ + top: top+"px", + left: (pos.left-panelWidth)+"px", + }); + } + panel.slideDown(100); + + $(document).on("mousedown.red-ui-popover-panel-close", function(event) { + if(!$(event.target).closest(panel).length && !$(event.target).closest(".red-ui-editor-dialog").length) { + if (closeCallback) { + closeCallback(); + } + hide(); + } + // if ($(event.target).closest(target).length) { + // event.preventDefault(); + // } + }) + } + return { + container: panel, + show:show, + hide:hide + } + } + } + +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/searchBox.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/searchBox.js new file mode 100644 index 0000000..b707ccb --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/searchBox.js @@ -0,0 +1,117 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +(function($) { + +/** + * options: + * - minimumLength : the minimum length of text before firing a change event + * - delay : delay, in ms, after a keystroke before firing change event + * + * methods: + * - value([val]) - gets the current value, or, if `val` is provided, sets the value + * - count - sets or clears a sub-label on the input. This can be used to provide + * a feedback on the number of matches, or number of available entries to search + * - change - trigger a change event + * + */ + + $.widget( "nodered.searchBox", { + _create: function() { + var that = this; + + this.currentTimeout = null; + this.lastSent = ""; + this.element.val(""); + this.element.addClass("red-ui-searchBox-input"); + this.uiContainer = this.element.wrap("<div>").parent(); + this.uiContainer.addClass("red-ui-searchBox-container"); + if (this.element.parents("form").length === 0) { + var form = this.element.wrap("<form>").parent(); + form.addClass("red-ui-searchBox-form"); + } + $('<i class="fa fa-search"></i>').prependTo(this.uiContainer); + this.clearButton = $('<a href="#"><i class="fa fa-times"></i></a>').appendTo(this.uiContainer); + this.clearButton.on("click",function(e) { + e.preventDefault(); + that.element.val(""); + that._change("",true); + that.element.trigger("focus"); + }); + + this.resultCount = $('<span>',{class:"red-ui-searchBox-resultCount hide"}).appendTo(this.uiContainer); + + this.element.val(""); + this.element.on("keydown",function(evt) { + if (evt.keyCode === 27) { + that.element.val(""); + } + }) + this.element.on("keyup",function(evt) { + that._change($(this).val()); + }); + + this.element.on("focus",function() { + $(document).one("mousedown",function() { + that.element.blur(); + }); + }); + + }, + _change: function(val,instant) { + var fireEvent = false; + if (val === "") { + this.clearButton.hide(); + fireEvent = true; + } else { + this.clearButton.show(); + fireEvent = (val.length >= (this.options.minimumLength||0)); + } + var current = this.element.val(); + fireEvent = fireEvent && current !== this.lastSent; + if (fireEvent) { + if (!instant && this.options.delay > 0) { + clearTimeout(this.currentTimeout); + var that = this; + this.currentTimeout = setTimeout(function() { + that.lastSent = that.element.val(); + that._trigger("change"); + },this.options.delay); + } else { + this.lastSent = this.element.val(); + this._trigger("change"); + } + } + }, + value: function(val) { + if (val === undefined) { + return this.element.val(); + } else { + this.element.val(val); + this._change(val); + } + }, + count: function(val) { + if (val === undefined || val === null || val === "") { + this.resultCount.text("").hide(); + } else { + this.resultCount.text(val).show(); + } + }, + change: function() { + this._trigger("change"); + } + }); +})(jQuery); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/stack.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/stack.js new file mode 100644 index 0000000..610f388 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/stack.js @@ -0,0 +1,169 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +RED.stack = (function() { + function createStack(options) { + var container = options.container; + container.addClass("red-ui-stack"); + var contentHeight = 0; + var entries = []; + + var visible = true; + // TODO: make this a singleton function - and watch out for stacks no longer + // in the DOM + var resizeStack = function() { + if (entries.length > 0) { + var headerHeight = 0; + entries.forEach(function(entry) { + headerHeight += entry.header.outerHeight(); + }); + + var height = container.innerHeight(); + contentHeight = height - headerHeight - (entries.length-1); + entries.forEach(function(e) { + e.contentWrap.height(contentHeight); + }); + } + } + if (options.fill && options.singleExpanded) { + $(window).on("resize", resizeStack); + $(window).on("focus", resizeStack); + } + return { + add: function(entry) { + entries.push(entry); + entry.container = $('<div class="red-ui-palette-category">').appendTo(container); + if (!visible) { + entry.container.hide(); + } + var header = $('<div class="red-ui-palette-header"></div>').appendTo(entry.container); + entry.header = header; + entry.contentWrap = $('<div></div>',{style:"position:relative"}).appendTo(entry.container); + if (options.fill) { + entry.contentWrap.css("height",contentHeight); + } + entry.content = $('<div></div>').appendTo(entry.contentWrap); + if (entry.collapsible !== false) { + header.on("click", function() { + if (options.singleExpanded) { + if (!entry.isExpanded()) { + for (var i=0;i<entries.length;i++) { + if (entries[i].isExpanded()) { + entries[i].collapse(); + } + } + entry.expand(); + } else if (entries.length === 2) { + if (entries[0] === entry) { + entries[0].collapse(); + entries[1].expand(); + } else { + entries[1].collapse(); + entries[0].expand(); + } + } + } else { + entry.toggle(); + } + }); + var icon = $('<i class="fa fa-angle-down"></i>').appendTo(header); + + if (entry.expanded) { + entry.container.addClass("expanded"); + icon.addClass("expanded"); + } else { + entry.contentWrap.hide(); + } + } else { + $('<i style="opacity: 0.5;" class="fa fa-angle-down expanded"></i>').appendTo(header); + header.css("cursor","default"); + } + entry.title = $('<span></span>').html(entry.title).appendTo(header); + + + + entry.toggle = function() { + if (entry.isExpanded()) { + entry.collapse(); + return false; + } else { + entry.expand(); + return true; + } + }; + entry.expand = function() { + if (!entry.isExpanded()) { + if (entry.onexpand) { + entry.onexpand.call(entry); + } + if (options.singleExpanded) { + entries.forEach(function(e) { + if (e !== entry) { + e.collapse(); + } + }) + } + + icon.addClass("expanded"); + entry.container.addClass("expanded"); + entry.contentWrap.slideDown(200); + return true; + } + }; + entry.collapse = function() { + if (entry.isExpanded()) { + icon.removeClass("expanded"); + entry.container.removeClass("expanded"); + entry.contentWrap.slideUp(200); + return true; + } + }; + entry.isExpanded = function() { + return entry.container.hasClass("expanded"); + }; + if (options.fill && options.singleExpanded) { + resizeStack(); + } + return entry; + }, + + hide: function() { + visible = false; + entries.forEach(function(entry) { + entry.container.hide(); + }); + return this; + }, + + show: function() { + visible = true; + entries.forEach(function(entry) { + entry.container.show(); + }); + return this; + }, + resize: function() { + if (resizeStack) { + resizeStack(); + } + } + } + } + + return { + create: createStack + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/tabs.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/tabs.js new file mode 100644 index 0000000..249d7da --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/tabs.js @@ -0,0 +1,706 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + + +RED.tabs = (function() { + + var defaultTabIcon = "fa fa-lemon-o"; + var dragActive = false; + var dblClickTime; + var dblClickArmed = false; + + function createTabs(options) { + var tabs = {}; + var pinnedTabsCount = 0; + var currentTabWidth; + var currentActiveTabWidth = 0; + var collapsibleMenu; + + var ul = options.element || $("#"+options.id); + var wrapper = ul.wrap( "<div>" ).parent(); + var scrollContainer = ul.wrap( "<div>" ).parent(); + wrapper.addClass("red-ui-tabs"); + if (options.vertical) { + wrapper.addClass("red-ui-tabs-vertical"); + } + if (options.addButton) { + wrapper.addClass("red-ui-tabs-add"); + var addButton = $('<div class="red-ui-tab-button red-ui-tabs-add"><a href="#"><i class="fa fa-plus"></i></a></div>').appendTo(wrapper); + addButton.find('a').on("click", function(evt) { + evt.preventDefault(); + if (typeof options.addButton === 'function') { + options.addButton(); + } else if (typeof options.addButton === 'string') { + RED.actions.invoke(options.addButton); + } + }) + if (typeof options.addButton === 'string') { + var l = options.addButton; + if (options.addButtonCaption) { + l = options.addButtonCaption + } + RED.popover.tooltip(addButton,l,options.addButton); + } + ul.on("dblclick", function(evt) { + var existingTabs = ul.children(); + var clickX = evt.clientX; + var targetIndex = 0; + existingTabs.each(function(index) { + var pos = $(this).offset(); + if (pos.left > clickX) { + return false; + } + targetIndex = index+1; + }) + if (typeof options.addButton === 'function') { + options.addButton({index:targetIndex}); + } else if (typeof options.addButton === 'string') { + RED.actions.invoke(options.addButton,{index:targetIndex}); + } + }); + } + if (options.searchButton) { + wrapper.addClass("red-ui-tabs-search"); + var searchButton = $('<div class="red-ui-tab-button red-ui-tabs-search"><a href="#"><i class="fa fa-list-ul"></i></a></div>').appendTo(wrapper); + searchButton.find('a').on("click", function(evt) { + evt.preventDefault(); + if (typeof options.searchButton === 'function') { + options.searchButton() + } else if (typeof options.searchButton === 'string') { + RED.actions.invoke(options.searchButton); + } + }) + if (typeof options.searchButton === 'string') { + var l = options.searchButton; + if (options.searchButtonCaption) { + l = options.searchButtonCaption + } + RED.popover.tooltip(searchButton,l,options.searchButton); + } + + } + var scrollLeft; + var scrollRight; + + if (options.scrollable) { + wrapper.addClass("red-ui-tabs-scrollable"); + scrollContainer.addClass("red-ui-tabs-scroll-container"); + scrollContainer.on("scroll",updateScroll); + scrollLeft = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-left"><a href="#" style="display:none;"><i class="fa fa-caret-left"></i></a></div>').appendTo(wrapper).find("a"); + scrollLeft.on('mousedown',function(evt) { scrollEventHandler(evt,'-=150') }).on('click',function(evt){ evt.preventDefault();}); + scrollRight = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-right"><a href="#" style="display:none;"><i class="fa fa-caret-right"></i></a></div>').appendTo(wrapper).find("a"); + scrollRight.on('mousedown',function(evt) { scrollEventHandler(evt,'+=150') }).on('click',function(evt){ evt.preventDefault();}); + } + + if (options.collapsible) { + // var dropDown = $('<div>',{class:"red-ui-tabs-select"}).appendTo(wrapper); + // ul.hide(); + wrapper.addClass("red-ui-tabs-collapsible"); + + var collapsedButtonsRow = $('<div class="red-ui-tab-link-buttons"></div>').appendTo(wrapper); + + if (options.menu !== false) { + var selectButton = $('<a href="#"><i class="fa fa-caret-down"></i></a>').appendTo(collapsedButtonsRow); + selectButton.addClass("red-ui-tab-link-button-menu") + selectButton.on("click", function(evt) { + evt.stopPropagation(); + evt.preventDefault(); + if (!collapsibleMenu) { + var pinnedOptions = []; + var options = []; + ul.children().each(function(i,el) { + var id = $(el).data('tabId'); + var opt = { + id:"red-ui-tabs-menu-option-"+id, + icon: tabs[id].iconClass || defaultTabIcon, + label: tabs[id].name, + onselect: function() { + activateTab(id); + } + }; + if (tabs[id].pinned) { + pinnedOptions.push(opt); + } else { + options.push(opt); + } + }); + options = pinnedOptions.concat(options); + collapsibleMenu = RED.menu.init({options: options}); + collapsibleMenu.css({ + position: "absolute" + }) + collapsibleMenu.appendTo("body"); + } + var elementPos = selectButton.offset(); + collapsibleMenu.css({ + top: (elementPos.top+selectButton.height()-2)+"px", + left: (elementPos.left - collapsibleMenu.width() + selectButton.width())+"px" + }) + if (collapsibleMenu.is(":visible")) { + $(document).off("click.red-ui-tabmenu"); + } else { + $(".red-ui-menu").hide(); + $(document).on("click.red-ui-tabmenu", function(evt) { + $(document).off("click.red-ui-tabmenu"); + collapsibleMenu.hide(); + }); + } + collapsibleMenu.toggle(); + }) + } + + } + + function scrollEventHandler(evt,dir) { + evt.preventDefault(); + if ($(this).hasClass('disabled')) { + return; + } + var currentScrollLeft = scrollContainer.scrollLeft(); + scrollContainer.animate( { scrollLeft: dir }, 100); + var interval = setInterval(function() { + var newScrollLeft = scrollContainer.scrollLeft() + if (newScrollLeft === currentScrollLeft) { + clearInterval(interval); + return; + } + currentScrollLeft = newScrollLeft; + scrollContainer.animate( { scrollLeft: dir }, 100); + },100); + $(this).one('mouseup',function() { + clearInterval(interval); + }) + } + + + ul.children().first().addClass("active"); + ul.children().addClass("red-ui-tab"); + + function getSelection() { + var selection = ul.find("li.red-ui-tab.selected"); + var selectedTabs = []; + selection.each(function() { + selectedTabs.push(tabs[$(this).find('a').attr('href').slice(1)]) + }) + return selectedTabs; + } + + function selectionChanged() { + options.onselect(getSelection()); + } + + function onTabClick(evt) { + if (dragActive) { + return + } + if (dblClickTime && Date.now()-dblClickTime < 400) { + dblClickTime = 0; + dblClickArmed = true; + return onTabDblClick.call(this,evt); + } + dblClickTime = Date.now(); + + var currentTab = ul.find("li.red-ui-tab.active"); + var thisTab = $(this).parent(); + var fireSelectionChanged = false; + if (options.onselect) { + if (evt.metaKey || evt.ctrlKey) { + if (thisTab.hasClass("selected")) { + thisTab.removeClass("selected"); + if (thisTab[0] !== currentTab[0]) { + // Deselect background tab + // - don't switch to it + selectionChanged(); + return; + } else { + // Deselect current tab + // - if nothing remains selected, do nothing + // - otherwise switch to first selected tab + var selection = ul.find("li.red-ui-tab.selected"); + if (selection.length === 0) { + selectionChanged(); + return; + } + thisTab = selection.first(); + } + } else { + if (!currentTab.hasClass("selected")) { + var currentTabObj = tabs[currentTab.find('a').attr('href').slice(1)]; + // Auto select current tab + currentTab.addClass("selected"); + } + thisTab.addClass("selected"); + } + fireSelectionChanged = true; + } else if (evt.shiftKey) { + if (currentTab[0] !== thisTab[0]) { + var firstTab,lastTab; + if (currentTab.index() < thisTab.index()) { + firstTab = currentTab; + lastTab = thisTab; + } else { + firstTab = thisTab; + lastTab = currentTab; + } + ul.find("li.red-ui-tab").removeClass("selected"); + firstTab.addClass("selected"); + lastTab.addClass("selected"); + firstTab.nextUntil(lastTab).addClass("selected"); + } + fireSelectionChanged = true; + } else { + var selection = ul.find("li.red-ui-tab.selected"); + if (selection.length > 0) { + selection.removeClass("selected"); + fireSelectionChanged = true; + } + } + } + + var thisTabA = thisTab.find("a"); + if (options.onclick) { + options.onclick(tabs[thisTabA.attr('href').slice(1)]); + } + activateTab(thisTabA); + if (fireSelectionChanged) { + selectionChanged(); + } + } + + function updateScroll() { + if (ul.children().length !== 0) { + var sl = scrollContainer.scrollLeft(); + var scWidth = scrollContainer.width(); + var ulWidth = ul.width(); + if (sl === 0) { + scrollLeft.hide(); + } else { + scrollLeft.show(); + } + if (sl === ulWidth-scWidth) { + scrollRight.hide(); + } else { + scrollRight.show(); + } + } + } + function onTabDblClick(evt) { + evt.preventDefault(); + if (evt.metaKey || evt.shiftKey) { + return; + } + if (options.ondblclick) { + options.ondblclick(tabs[$(this).attr('href').slice(1)]); + } + return false; + } + + function activateTab(link) { + if (typeof link === "string") { + link = ul.find("a[href='#"+link+"']"); + } + if (link.length === 0) { + return; + } + if (!link.parent().hasClass("active")) { + ul.children().removeClass("active"); + ul.children().css({"transition": "width 100ms"}); + link.parent().addClass("active"); + var parentId = link.parent().attr('id'); + wrapper.find(".red-ui-tab-link-button").removeClass("active selected"); + $("#"+parentId+"-link-button").addClass("active selected"); + if (options.scrollable) { + var pos = link.parent().position().left; + if (pos-21 < 0) { + scrollContainer.animate( { scrollLeft: '+='+(pos-50) }, 300); + } else if (pos + 120 > scrollContainer.width()) { + scrollContainer.animate( { scrollLeft: '+='+(pos + 140-scrollContainer.width()) }, 300); + } + } + if (options.onchange) { + options.onchange(tabs[link.attr('href').slice(1)]); + } + updateTabWidths(); + setTimeout(function() { + ul.children().css({"transition": ""}); + },100); + } + } + function activatePreviousTab() { + var previous = ul.find("li.active").prev(); + if (previous.length > 0) { + activateTab(previous.find("a")); + } + } + function activateNextTab() { + var next = ul.find("li.active").next(); + if (next.length > 0) { + activateTab(next.find("a")); + } + } + + function updateTabWidths() { + if (options.vertical) { + return; + } + var tabs = ul.find("li.red-ui-tab"); + var width = wrapper.width(); + var tabCount = tabs.length; + var tabWidth; + + if (options.collapsible) { + tabWidth = width - collapsedButtonsRow.width()-10; + if (tabWidth < 198) { + var delta = 198 - tabWidth; + var b = collapsedButtonsRow.find("a:last").prev(); + while (b.is(":not(:visible)")) { + b = b.prev(); + } + if (!b.hasClass("red-ui-tab-link-button-pinned")) { + b.hide(); + } + tabWidth = width - collapsedButtonsRow.width()-10; + } else { + var space = width - 198 - collapsedButtonsRow.width(); + if (space > 40) { + collapsedButtonsRow.find("a:not(:visible):first").show(); + tabWidth = width - collapsedButtonsRow.width()-10; + } + } + tabs.css({width:tabWidth}); + + } else { + var tabWidth = (width-12-(tabCount*6))/tabCount; + currentTabWidth = (100*tabWidth/width)+"%"; + currentActiveTabWidth = currentTabWidth+"%"; + if (options.scrollable) { + tabWidth = Math.max(tabWidth,140); + currentTabWidth = tabWidth+"px"; + currentActiveTabWidth = 0; + var listWidth = Math.max(wrapper.width(),12+(tabWidth+6)*tabCount); + ul.width(listWidth); + updateScroll(); + } else if (options.hasOwnProperty("minimumActiveTabWidth")) { + if (tabWidth < options.minimumActiveTabWidth) { + tabCount -= 1; + tabWidth = (width-12-options.minimumActiveTabWidth-(tabCount*6))/tabCount; + currentTabWidth = (100*tabWidth/width)+"%"; + currentActiveTabWidth = options.minimumActiveTabWidth+"px"; + } else { + currentActiveTabWidth = 0; + } + } + // if (options.collapsible) { + // console.log(currentTabWidth); + // } + + tabs.css({width:currentTabWidth}); + if (tabWidth < 50) { + // ul.find(".red-ui-tab-close").hide(); + ul.find(".red-ui-tab-icon").hide(); + ul.find(".red-ui-tab-label").css({paddingLeft:Math.min(12,Math.max(0,tabWidth-38))+"px"}) + } else { + // ul.find(".red-ui-tab-close").show(); + ul.find(".red-ui-tab-icon").show(); + ul.find(".red-ui-tab-label").css({paddingLeft:""}) + } + if (currentActiveTabWidth !== 0) { + ul.find("li.red-ui-tab.active").css({"width":options.minimumActiveTabWidth}); + // ul.find("li.red-ui-tab.active .red-ui-tab-close").show(); + ul.find("li.red-ui-tab.active .red-ui-tab-icon").show(); + ul.find("li.red-ui-tab.active .red-ui-tab-label").css({paddingLeft:""}) + } + } + + } + + ul.find("li.red-ui-tab a") + .on("mouseup",onTabClick) + .on("click", function(evt) {evt.preventDefault(); }) + .on("dblclick", function(evt) {evt.stopPropagation(); evt.preventDefault(); }) + + setTimeout(function() { + updateTabWidths(); + },0); + + + function removeTab(id) { + if (options.onselect) { + var selection = ul.find("li.red-ui-tab.selected"); + if (selection.length > 0) { + selection.removeClass("selected"); + selectionChanged(); + } + } + var li = ul.find("a[href='#"+id+"']").parent(); + if (li.hasClass("active")) { + var tab = li.prev(); + if (tab.length === 0) { + tab = li.next(); + } + activateTab(tab.find("a")); + } + li.remove(); + if (tabs[id].pinned) { + pinnedTabsCount--; + } + if (options.onremove) { + options.onremove(tabs[id]); + } + delete tabs[id]; + updateTabWidths(); + if (collapsibleMenu) { + collapsibleMenu.remove(); + collapsibleMenu = null; + } + } + + return { + addTab: function(tab,targetIndex) { + if (options.onselect) { + var selection = ul.find("li.red-ui-tab.selected"); + if (selection.length > 0) { + selection.removeClass("selected"); + selectionChanged(); + } + } + tabs[tab.id] = tab; + var li = $("<li/>",{class:"red-ui-tab"}); + if (ul.children().length === 0) { + targetIndex = undefined; + } + if (targetIndex === 0) { + li.prependTo(ul); + } else if (targetIndex > 0) { + li.insertAfter(ul.find("li:nth-child("+(targetIndex)+")")); + } else { + li.appendTo(ul); + } + li.attr('id',"red-ui-tab-"+(tab.id.replace(".","-"))); + li.data("tabId",tab.id); + + if (options.maximumTabWidth) { + li.css("maxWidth",options.maximumTabWidth+"px"); + } + var link = $("<a/>",{href:"#"+tab.id, class:"red-ui-tab-label"}).appendTo(li); + if (tab.icon) { + $('<img src="'+tab.icon+'" class="red-ui-tab-icon"/>').appendTo(link); + } else if (tab.iconClass) { + $('<i>',{class:"red-ui-tab-icon "+tab.iconClass}).appendTo(link); + } + var span = $('<span/>',{class:"red-ui-text-bidi-aware"}).text(tab.label).appendTo(link); + span.attr('dir', RED.text.bidi.resolveBaseTextDir(tab.label)); + if (options.collapsible) { + li.addClass("red-ui-tab-pinned"); + var pinnedLink = $('<a href="#'+tab.id+'" class="red-ui-tab-link-button"></a>'); + if (tab.pinned) { + if (pinnedTabsCount === 0) { + pinnedLink.prependTo(collapsedButtonsRow) + } else { + pinnedLink.insertAfter(collapsedButtonsRow.find("a.red-ui-tab-link-button-pinned:last")); + } + } else { + if (options.menu !== false) { + pinnedLink.insertBefore(collapsedButtonsRow.find("a:last")); + } else { + pinnedLink.appendTo(collapsedButtonsRow); + } + } + + pinnedLink.attr('id',li.attr('id')+"-link-button"); + if (tab.iconClass) { + $('<i>',{class:tab.iconClass}).appendTo(pinnedLink); + } else { + $('<i>',{class:defaultTabIcon}).appendTo(pinnedLink); + } + pinnedLink.on("click", function(evt) { + evt.preventDefault(); + activateTab(tab.id); + }); + if (tab.pinned) { + pinnedLink.addClass("red-ui-tab-link-button-pinned"); + pinnedTabsCount++; + } + RED.popover.tooltip($(pinnedLink), tab.name, tab.action); + + } + link.on("mouseup",onTabClick); + link.on("click", function(evt) { evt.preventDefault(); }) + link.on("dblclick", function(evt) { evt.stopPropagation(); evt.preventDefault(); }) + + + if (tab.closeable) { + li.addClass("red-ui-tabs-closeable") + var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close"}).appendTo(li); + closeLink.append('<i class="fa fa-times" />'); + closeLink.on("click",function(event) { + event.preventDefault(); + removeTab(tab.id); + }); + } + + var badges = $('<span class="red-ui-tabs-badges"></span>').appendTo(li); + if (options.onselect) { + $('<i class="red-ui-tabs-badge-changed fa fa-circle"></i>').appendTo(badges); + $('<i class="red-ui-tabs-badge-selected fa fa-check-circle"></i>').appendTo(badges); + } + if (options.onadd) { + options.onadd(tab); + } + link.attr("title",tab.label); + if (ul.find("li.red-ui-tab").length == 1) { + activateTab(link); + } + if (options.onreorder) { + var originalTabOrder; + var tabDragIndex; + var tabElements = []; + var startDragIndex; + + li.draggable({ + axis:"x", + distance: 20, + start: function(event,ui) { + if (dblClickArmed) { dblClickArmed = false; return false } + dragActive = true; + originalTabOrder = []; + tabElements = []; + ul.children().each(function(i) { + tabElements[i] = { + el:$(this), + text: $(this).text(), + left: $(this).position().left, + width: $(this).width() + }; + if ($(this).is(li)) { + tabDragIndex = i; + startDragIndex = i; + } + originalTabOrder.push($(this).data("tabId")); + }); + ul.children().each(function(i) { + if (i!==tabDragIndex) { + $(this).css({ + position: 'absolute', + left: tabElements[i].left+"px", + width: tabElements[i].width+2, + transition: "left 0.3s" + }); + } + + }) + if (!li.hasClass('active')) { + li.css({'zIndex':1}); + } + }, + drag: function(event,ui) { + ui.position.left += tabElements[tabDragIndex].left+scrollContainer.scrollLeft(); + var tabCenter = ui.position.left + tabElements[tabDragIndex].width/2 - scrollContainer.scrollLeft(); + for (var i=0;i<tabElements.length;i++) { + if (i === tabDragIndex) { + continue; + } + if (tabCenter > tabElements[i].left && tabCenter < tabElements[i].left+tabElements[i].width) { + if (i < tabDragIndex) { + tabElements[i].left += tabElements[tabDragIndex].width+8; + tabElements[tabDragIndex].el.detach().insertBefore(tabElements[i].el); + } else { + tabElements[i].left -= tabElements[tabDragIndex].width+8; + tabElements[tabDragIndex].el.detach().insertAfter(tabElements[i].el); + } + tabElements[i].el.css({left:tabElements[i].left+"px"}); + + tabElements.splice(i, 0, tabElements.splice(tabDragIndex, 1)[0]); + + tabDragIndex = i; + break; + } + } + }, + stop: function(event,ui) { + dragActive = false; + ul.children().css({position:"relative",left:"",transition:""}); + if (!li.hasClass('active')) { + li.css({zIndex:""}); + } + updateTabWidths(); + if (startDragIndex !== tabDragIndex) { + options.onreorder(originalTabOrder, $.makeArray(ul.children().map(function() { return $(this).data('tabId');}))); + } + activateTab(tabElements[tabDragIndex].el.data('tabId')); + } + }) + } + setTimeout(function() { + updateTabWidths(); + },10); + if (collapsibleMenu) { + collapsibleMenu.remove(); + collapsibleMenu = null; + } + }, + removeTab: removeTab, + activateTab: activateTab, + nextTab: activateNextTab, + previousTab: activatePreviousTab, + resize: updateTabWidths, + count: function() { + return ul.find("li.red-ui-tab").length; + }, + contains: function(id) { + return ul.find("a[href='#"+id+"']").length > 0; + }, + renameTab: function(id,label) { + tabs[id].label = label; + var tab = ul.find("a[href='#"+id+"']"); + tab.attr("title",label); + tab.find("span.red-ui-text-bidi-aware").text(label).attr('dir', RED.text.bidi.resolveBaseTextDir(label)); + updateTabWidths(); + }, + selection: getSelection, + order: function(order) { + var existingTabOrder = $.makeArray(ul.children().map(function() { return $(this).data('tabId');})); + if (existingTabOrder.length !== order.length) { + return + } + var i; + var match = true; + for (i=0;i<order.length;i++) { + if (order[i] !== existingTabOrder[i]) { + match = false; + break; + } + } + if (match) { + return; + } + var existingTabMap = {}; + var existingTabs = ul.children().detach().each(function() { + existingTabMap[$(this).data("tabId")] = $(this); + }); + for (i=0;i<order.length;i++) { + existingTabMap[order[i]].appendTo(ul); + } + } + + } + } + + return { + create: createTabs + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js new file mode 100644 index 0000000..398d35c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js @@ -0,0 +1,100 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +(function($) { + +/** + * options: + * - invertState : boolean - if "true" the button will show "enabled" when the + * checkbox is not selected and vice versa. + * - enabledIcon : string - the icon for "enabled" state, default "fa-check-square-o" + * - enabledLabel : string - the label for "enabled" state, default "Enabled" ("editor:workspace.enabled") + * - disabledIcon : string - the icon for "disabled" state, default "fa-square-o" + * - disabledLabel : string - the label for "disabled" state, default "Disabled" ("editor:workspace.disabled") + * - baseClass : string - the base css class to apply, default "red-ui-button" (alternative eg "red-ui-sidebar-header-button") + * - class : string - additional classes to apply to the button - eg "red-ui-button-small" + * methods: + * - + */ + $.widget( "nodered.toggleButton", { + _create: function() { + var that = this; + + var invertState = false; + if (this.options.hasOwnProperty("invertState")) { + invertState = this.options.invertState; + } + var baseClass = this.options.baseClass || "red-ui-button"; + var enabledIcon = this.options.enabledIcon || "fa-check-square-o"; + var disabledIcon = this.options.disabledIcon || "fa-square-o"; + var enabledLabel = this.options.hasOwnProperty('enabledLabel') ? this.options.enabledLabel : RED._("editor:workspace.enabled"); + var disabledLabel = this.options.hasOwnProperty('disabledLabel') ? this.options.disabledLabel : RED._("editor:workspace.disabled"); + + this.element.css("display","none"); + this.element.on("focus", function() { + that.button.focus(); + }); + this.button = $('<button type="button" class="red-ui-toggleButton '+baseClass+' toggle single"><i class="fa"></i> <span></span></button>'); + if (this.options.class) { + this.button.addClass(this.options.class) + } + this.element.after(this.button); + this.buttonIcon = this.button.find("i"); + this.buttonLabel = this.button.find("span"); + + // Quick hack to find the maximum width of the button + this.button.addClass("selected"); + this.buttonIcon.addClass(enabledIcon); + this.buttonLabel.text(enabledLabel); + var width = this.button.width(); + this.button.removeClass("selected"); + this.buttonIcon.removeClass(enabledIcon); + that.buttonIcon.addClass(disabledIcon); + that.buttonLabel.text(disabledLabel); + width = Math.max(width,this.button.width()); + this.buttonIcon.removeClass(disabledIcon); + + // Fix the width of the button so it doesn't jump around when toggled + if (width > 0) { + this.button.width(Math.ceil(width)); + } + + this.button.on("click",function(e) { + e.stopPropagation(); + if (that.buttonIcon.hasClass(disabledIcon)) { + that.element.prop("checked",!invertState); + } else { + that.element.prop("checked",invertState); + } + that.element.trigger("change"); + }) + + this.element.on("change", function(e) { + if ($(this).prop("checked") !== invertState) { + that.button.addClass("selected"); + that.buttonIcon.addClass(enabledIcon); + that.buttonIcon.removeClass(disabledIcon); + that.buttonLabel.text(enabledLabel); + } else { + that.button.removeClass("selected"); + that.buttonIcon.addClass(disabledIcon); + that.buttonIcon.removeClass(enabledIcon); + that.buttonLabel.text(disabledLabel); + } + }) + this.element.trigger("change"); + } + }); +})(jQuery); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js new file mode 100644 index 0000000..ed04733 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js @@ -0,0 +1,589 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +(function($) { + +/** + * options: + * - data : array - initial items to display in tree + * - multi : boolean - if true, .selected will return an array of results + * otherwise, returns the first selected item + * - sortable: boolean/string - TODO: see editableList + * - rootSortable: boolean - if 'sortable' is set, then setting this to + * false, prevents items being sorted to the + * top level of the tree + * + * methods: + * - data(items) - clears existing items and replaces with new data + * + * events: + * - treelistselect : function(event, item) {} + * - treelistconfirm : function(event,item) {} + * - treelistchangeparent: function(event,item, oldParent, newParent) {} + * + * data: + * [ + * { + * label: 'Local', // label for the item + * sublabel: 'Local', // a sub-label for the item + * icon: 'fa fa-rocket', // (optional) icon for the item + * selected: true/false, // (optional) if present, display checkbox accordingly + * children: [] | function(done,item) // (optional) an array of child items, or a function + * // that will call the `done` callback with an array + * // of child items + * expanded: true/false, // show the child items by default + * deferBuild: true/false, // don't build any ui elements for the item's children + * until it is expanded by the user. + * element: // custom dom element to use for the item - ignored if `label` is set + * } + * ] + * + * var treeList = $("<div>").css({width: "100%", height: "100%"}).treeList({data:[...]}) + * treeList.on('treelistselect', function(e,item) { console.log(item)}) + * treeList.treeList('data',[ ... ] ) + * + * + * After `data` has been added to the tree, each item is augmented the following + * properties and functions: + * + * item.parent - set to the parent item + * item.treeList.container + * item.treeList.label - the label element for the item + * item.treeList.depth - the depth in the tree (0 == root) + * item.treeList.parentList - the editableList instance this item is in + * item.treeList.remove() - removes the item from the tree + * item.treeList.makeLeaf(detachChildElements) - turns an element with children into a leaf node, + * removing the UI decoration etc. + * detachChildElements - any children with custom + * elements will be detached rather than removed + * so jQuery event handlers are preserved in case + * the child elements need to be reattached later + * item.treeList.makeParent(children) - turns an element into a parent node, adding the necessary + * UI decoration. + * item.treeList.insertChildAt(newItem,position,select) - adds a child item an the specified position. + * Optionally selects the item after adding. + * item.treeList.addChild(newItem,select) - appends a child item. + * Optionally selects the item after adding. + * item.treeList.expand(done) - expands the parent item to show children. Optional 'done' callback. + * item.treeList.collapse() - collapse the parent item to hide children. + * + * + * + * + */ + + $.widget( "nodered.treeList", { + _create: function() { + var that = this; + + this.element.addClass('red-ui-treeList'); + this.element.attr("tabIndex",0); + var wrapper = $('<div>',{class:'red-ui-treeList-container'}).appendTo(this.element); + this.element.on('keydown', function(evt) { + var selected = that._topList.find(".selected").parent().data('data'); + if (!selected && (evt.keyCode === 40 || evt.keyCode === 38)) { + that.select(that._data[0]); + return; + } + var target; + switch(evt.keyCode) { + case 13: // ENTER + if (selected.children) { + if (selected.treeList.container.hasClass("expanded")) { + selected.treeList.collapse() + } else { + selected.treeList.expand() + } + } else { + that._trigger("confirm",null,selected) + } + + break; + case 37: // LEFT + if (selected.children&& selected.treeList.container.hasClass("expanded")) { + selected.treeList.collapse() + } else if (selected.parent) { + target = selected.parent; + } + break; + case 38: // UP + target = that._getPreviousSibling(selected); + if (target) { + target = that._getLastDescendant(target); + } + if (!target && selected.parent) { + target = selected.parent; + } + break; + case 39: // RIGHT + if (selected.children) { + if (!selected.treeList.container.hasClass("expanded")) { + selected.treeList.expand() + } + } + break + case 40: //DOWN + if (selected.children && Array.isArray(selected.children) && selected.children.length > 0 && selected.treeList.container.hasClass("expanded")) { + target = selected.children[0]; + } else { + target = that._getNextSibling(selected); + while (!target && selected.parent) { + selected = selected.parent; + target = that._getNextSibling(selected); + } + } + break + } + if (target) { + that.select(target); + } + }); + this._data = []; + + this._topList = $('<ol class="red-ui-treeList-list">').css({ + position:'absolute', + top: 0, + left:0, + right:0, + bottom:0 + }).appendTo(wrapper); + + var topListOptions = { + addButton: false, + scrollOnAdd: false, + height: '100%', + addItem: function(container,i,item) { + that._addSubtree(that._topList,container,item,0); + } + }; + if (this.options.rootSortable !== false && !!this.options.sortable) { + topListOptions.sortable = this.options.sortable; + topListOptions.connectWith = '.red-ui-treeList-sortable'; + this._topList.addClass('red-ui-treeList-sortable'); + } + this._topList.editableList(topListOptions) + + + if (this.options.data) { + this.data(this.options.data); + } + }, + _getLastDescendant: function(item) { + // Gets the last visible descendant of the item + if (!item.children || !item.treeList.container.hasClass("expanded") || item.children.length === 0) { + return item; + } + return this._getLastDescendant(item.children[item.children.length-1]); + }, + _getPreviousSibling: function(item) { + var candidates; + if (!item.parent) { + candidates = this._data; + } else { + candidates = item.parent.children; + } + var index = candidates.indexOf(item); + if (index === 0) { + return null; + } else { + return candidates[index-1]; + } + }, + _getNextSibling: function(item) { + var candidates; + if (!item.parent) { + candidates = this._data; + } else { + candidates = item.parent.children; + } + var index = candidates.indexOf(item); + if (index === candidates.length - 1) { + return null; + } else { + return candidates[index+1]; + } + }, + _addChildren: function(container,parent,children,depth) { + var that = this; + var subtree = $('<ol class="red-ui-treeList-list">').appendTo(container).editableList({ + connectWith: ".red-ui-treeList-sortable", + sortable: that.options.sortable, + addButton: false, + scrollOnAdd: false, + height: 'auto', + addItem: function(container,i,item) { + that._addSubtree(subtree,container,item,depth+1); + }, + sortItems: function(data) { + var children = []; + var reparented = []; + data.each(function() { + var child = $(this).data('data'); + children.push(child); + var evt = that._fixDepths(parent,child); + if (evt) { + reparented.push(evt); + } + }) + if (Array.isArray(parent.children)) { + parent.children = children; + } + reparented.forEach(function(evt) { + that._trigger("changeparent",null,evt); + }); + that._trigger("sort",null,parent); + } + }); + if (!!that.options.sortable) { + subtree.addClass('red-ui-treeList-sortable'); + } + for (var i=0;i<children.length;i++) { + children[i].parent = parent; + subtree.editableList('addItem',children[i]) + } + return subtree; + }, + _fixDepths: function(parent,child) { + // If child has just been moved into parent in the UI + // this will fix up the internal data structures to match. + // The calling function must take care of getting child + // into the parent.children array. The rest is up to us. + var that = this; + var reparentedEvent = null; + if (child.parent !== parent) { + reparented = true; + var oldParent = child.parent; + child.parent = parent; + reparentedEvent = { + item: child, + old: oldParent, + } + } + if (child.depth !== parent.depth+1) { + child.depth = parent.depth+1; + var labelPaddingWidth = ((child.gutter?child.gutter.width()+2:0)+(child.depth*20)); + child.treeList.labelPadding.width(labelPaddingWidth+'px'); + if (child.element) { + $(child.element).css({ + width: "calc(100% - "+(labelPaddingWidth+20+(child.icon?20:0))+"px)" + }) + } + // This corrects all child item depths + if (child.children && Array.isArray(child.children)) { + child.children.forEach(function(item) { + that._fixDepths(child,item); + }) + } + } + return reparentedEvent; + }, + _addSubtree: function(parentList, container, item, depth) { + var that = this; + item.treeList = {}; + item.treeList.depth = depth; + item.treeList.container = container; + + item.treeList.parentList = parentList; + item.treeList.remove = function() { + parentList.editableList('removeItem',item); + if (item.parent) { + var index = item.parent.children.indexOf(item); + item.parent.children.splice(index,1) + that._trigger("sort",null,item.parent); + } + } + + var label = $("<div>",{class:"red-ui-treeList-label"}).appendTo(container); + item.treeList.label = label; + if (item.class) { + label.addClass(item.class); + } + if (item.gutter) { + item.gutter.css({ + position: 'absolute' + }).appendTo(label) + + } + var labelPaddingWidth = (item.gutter?item.gutter.width()+2:0)+(depth*20); + item.treeList.labelPadding = $('<span>').css({ + display: "inline-block", + width: labelPaddingWidth+'px' + }).appendTo(label); + + label.on('mouseover',function(e) { that._trigger('itemmouseover',e,item); }) + label.on('mouseout',function(e) { that._trigger('itemmouseout',e,item); }) + label.on('mouseenter',function(e) { that._trigger('itemmouseenter',e,item); }) + label.on('mouseleave',function(e) { that._trigger('itemmouseleave',e,item); }) + + item.treeList.makeLeaf = function(detachChildElements) { + if (!treeListIcon.children().length) { + // Already a leaf + return + } + if (detachChildElements && item.children) { + var detachChildren = function(item) { + if (item.children) { + item.children.forEach(function(child) { + if (child.element) { + child.element.detach(); + } + if (child.gutter) { + child.gutter.detach(); + } + detachChildren(child); + }); + } + } + detachChildren(item); + } + treeListIcon.empty(); + if (!item.deferBuild) { + item.treeList.childList.remove(); + delete item.treeList.childList; + } + label.off("click.red-ui-treeList-expand"); + treeListIcon.off("click.red-ui-treeList-expand"); + delete item.children; + container.removeClass("expanded"); + } + item.treeList.makeParent = function(children) { + if (treeListIcon.children().length) { + // Already a parent because we've got the angle-right icon + return; + } + $('<i class="fa fa-angle-right" />').appendTo(treeListIcon); + treeListIcon.on("click.red-ui-treeList-expand", function(e) { + e.stopPropagation(); + e.preventDefault(); + if (container.hasClass("expanded")) { + item.treeList.collapse(); + } else { + item.treeList.expand(); + } + }); + // $('<span class="red-ui-treeList-icon"><i class="fa fa-folder-o" /></span>').appendTo(label); + label.on("click.red-ui-treeList-expand", function(e) { + if (container.hasClass("expanded")) { + if (item.hasOwnProperty('selected') || label.hasClass("selected")) { + item.treeList.collapse(); + } + } else { + item.treeList.expand(); + } + }) + if (!item.children) { + item.children = children||[]; + item.treeList.childList = that._addChildren(container,item,item.children,depth).hide(); + } + } + item.treeList.insertChildAt = function(newItem,position,select) { + newItem.parent = item; + item.children.splice(position,0,newItem); + + if (!item.deferBuild) { + item.treeList.childList.editableList('insertItemAt',newItem,position) + if (select) { + setTimeout(function() { + that.select(newItem) + },100); + } + that._trigger("sort",null,item); + } + } + item.treeList.addChild = function(newItem,select) { + item.treeList.insertChildAt(newItem,item.children.length,select); + } + item.treeList.expand = function(done) { + if (!item.children) { + return; + } + if (container.hasClass("expanded")) { + if (done) { done() } + return; + } + if (!container.hasClass("built") && (item.deferBuild || typeof item.children === 'function')) { + container.addClass('built'); + var childrenAdded = false; + var spinner; + var startTime = 0; + var completeBuild = function(children) { + childrenAdded = true; + item.treeList.childList = that._addChildren(container,item,children,depth).hide(); + var delta = Date.now() - startTime; + if (delta < 400) { + setTimeout(function() { + item.treeList.childList.slideDown('fast'); + if (spinner) { + spinner.remove(); + } + },400-delta); + } else { + item.treeList.childList.slideDown('fast'); + if (spinner) { + spinner.remove(); + } + } + if (done) { done() } + that._trigger("childrenloaded",null,item) + } + if (typeof item.children === 'function') { + item.children(completeBuild,item); + } else { + delete item.deferBuild; + completeBuild(item.children); + } + if (!childrenAdded) { + startTime = Date.now(); + spinner = $('<div class="red-ui-treeList-spinner">').css({ + "background-position": (35+depth*20)+'px 50%' + }).appendTo(container); + } + + } else { + if (that._loadingData) { + item.treeList.childList.show(); + } else { + item.treeList.childList.slideDown('fast'); + } + if (done) { done() } + } + container.addClass("expanded"); + } + item.treeList.collapse = function() { + if (!item.children) { + return; + } + item.treeList.childList.slideUp('fast'); + container.removeClass("expanded"); + } + + var treeListIcon = $('<span class="red-ui-treeList-icon"></span>').appendTo(label); + if (item.children) { + item.treeList.makeParent(); + } + + if (item.hasOwnProperty('selected')) { + var selectWrapper = $('<span class="red-ui-treeList-icon"></span>').appendTo(label); + var cb = $('<input class="red-ui-treeList-checkbox" type="checkbox">').prop('checked',item.selected).appendTo(selectWrapper); + label.toggleClass("selected",item.selected); + cb.on('click', function(e) { + e.stopPropagation(); + }); + cb.on('change', function(e) { + item.selected = this.checked; + label.toggleClass("selected",this.checked); + that._trigger("select",e,item); + }) + if (!item.children) { + label.on("click", function(e) { + e.stopPropagation(); + cb.trigger("click"); + }) + } + item.treeList.select = function(v) { + if (v !== item.selected) { + cb.trigger("click"); + } + } + } else { + label.on("click", function(e) { + that._topList.find(".selected").removeClass("selected"); + label.addClass("selected"); + that._trigger("select",e,item) + }) + label.on("dblclick", function(e) { + if (!item.children) { + that._trigger("confirm",e,item); + } + }) + } + if (item.icon) { + $('<span class="red-ui-treeList-icon"><i class="'+item.icon+'" /></span>').appendTo(label); + } + if (item.hasOwnProperty('label') || item.hasOwnProperty('sublabel')) { + if (item.hasOwnProperty('label')) { + $('<span class="red-ui-treeList-label-text"></span>').text(item.label).appendTo(label); + } + if (item.hasOwnProperty('sublabel')) { + $('<span class="red-ui-treeList-sublabel-text"></span>').text(item.sublabel).appendTo(label); + } + + } else if (item.element) { + $(item.element).appendTo(label); + $(item.element).css({ + width: "calc(100% - "+(labelPaddingWidth+20+(item.icon?20:0))+"px)" + }) + } + if (item.children) { + if (Array.isArray(item.children) && !item.deferBuild) { + item.treeList.childList = that._addChildren(container,item,item.children,depth).hide(); + } + if (item.expanded) { + item.treeList.expand(); + } + } + }, + empty: function() { + this._topList.editableList('empty'); + }, + data: function(items) { + var that = this; + if (items !== undefined) { + this._data = items; + this._topList.editableList('empty'); + this._loadingData = true; + for (var i=0; i<items.length;i++) { + this._topList.editableList('addItem',items[i]); + } + setTimeout(function() { + delete that._loadingData; + },200); + this._trigger("select") + + } else { + return this._data; + } + }, + show: function(id) { + for (var i=0;i<this._data.length;i++) { + if (this._data[i].id === id) { + this._topList.editableList('show',this._data[i]); + } + } + }, + select: function(item) { + this._topList.find(".selected").removeClass("selected"); + item.treeList.label.addClass("selected"); + this._trigger("select",null,item) + + }, + selected: function() { + var s = this._topList.find(".selected"); + if (this.options.multi) { + var res = []; + s.each(function() { + res.push($(this).parent().data('data')); + }) + return res; + } + if (s.length) { + return s.parent().data('data'); + } else { + return undefined; + } + } + }); + +})(jQuery); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js new file mode 100644 index 0000000..cb4de12 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js @@ -0,0 +1,919 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +(function($) { + var contextParse = function(v) { + var parts = RED.utils.parseContextKey(v); + return { + option: parts.store, + value: parts.key + } + } + var contextExport = function(v,opt) { + if (!opt) { + return v; + } + var store = ((typeof opt === "string")?opt:opt.value) + if (store !== RED.settings.context.default) { + return "#:("+store+")::"+v; + } else { + return v; + } + } + var mapDeprecatedIcon = function(icon) { + if (/^red\/images\/typedInput\/.+\.png$/.test(icon)) { + icon = icon.replace(/.png$/,".svg"); + } + return icon; + } + var allOptions = { + msg: {value:"msg",label:"msg.",validate:RED.utils.validatePropertyExpression}, + flow: {value:"flow",label:"flow.",hasValue:true, + options:[], + validate:RED.utils.validatePropertyExpression, + parse: contextParse, + export: contextExport + }, + global: {value:"global",label:"global.",hasValue:true, + options:[], + validate:RED.utils.validatePropertyExpression, + parse: contextParse, + export: contextExport + }, + str: {value:"str",label:"string",icon:"red/images/typedInput/az.svg"}, + num: {value:"num",label:"number",icon:"red/images/typedInput/09.svg",validate:/^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$/}, + bool: {value:"bool",label:"boolean",icon:"red/images/typedInput/bool.svg",options:["true","false"]}, + json: { + value:"json", + label:"JSON", + icon:"red/images/typedInput/json.svg", + validate: function(v) { try{JSON.parse(v);return true;}catch(e){return false;}}, + expand: function() { + var that = this; + var value = this.value(); + try { + value = JSON.stringify(JSON.parse(value),null,4); + } catch(err) { + } + RED.editor.editJSON({ + value: value, + complete: function(v) { + var value = v; + try { + value = JSON.stringify(JSON.parse(v)); + } catch(err) { + } + that.value(value); + } + }) + } + }, + re: {value:"re",label:"regular expression",icon:"red/images/typedInput/re.svg"}, + date: {value:"date",label:"timestamp",icon:"fa fa-clock-o",hasValue:false}, + jsonata: { + value: "jsonata", + label: "expression", + icon: "red/images/typedInput/expr.svg", + validate: function(v) { try{jsonata(v);return true;}catch(e){return false;}}, + expand:function() { + var that = this; + RED.editor.editExpression({ + value: this.value().replace(/\t/g,"\n"), + complete: function(v) { + that.value(v.replace(/\n/g,"\t")); + } + }) + } + }, + bin: { + value: "bin", + label: "buffer", + icon: "red/images/typedInput/bin.svg", + expand: function() { + var that = this; + RED.editor.editBuffer({ + value: this.value(), + complete: function(v) { + that.value(v); + } + }) + } + }, + env: { + value: "env", + label: "env variable", + icon: "red/images/typedInput/env.svg" + }, + node: { + value: "node", + label: "node", + icon: "red/images/typedInput/target.svg", + valueLabel: function(container,value) { + var node = RED.nodes.node(value); + var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).css({ + "margin-top": "2px", + "margin-left": "3px" + }).appendTo(container); + var nodeLabel = $('<span>').css({ + "line-height": "32px", + "margin-left": "6px" + }).appendTo(container); + if (node) { + var colour = RED.utils.getNodeColor(node.type,node._def); + var icon_url = RED.utils.getNodeIcon(node._def,node); + if (node.type === 'tab') { + colour = "#C0DEED"; + } + nodeDiv.css('backgroundColor',colour); + var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv); + RED.utils.createIconElement(icon_url, iconContainer, true); + var l = RED.utils.getNodeLabel(node,node.id); + nodeLabel.text(l); + } else { + nodeDiv.css({ + 'backgroundColor': '#eee', + 'border-style' : 'dashed' + }); + + } + }, + expand: function() { + var that = this; + RED.tray.hide(); + RED.view.selectNodes({ + single: true, + selected: [that.value()], + onselect: function(selection) { + that.value(selection.id); + RED.tray.show(); + }, + oncancel: function() { + RED.tray.show(); + } + }) + } + } + }; + var nlsd = false; + + $.widget( "nodered.typedInput", { + _create: function() { + try { + if (!nlsd && RED && RED._) { + for (var i in allOptions) { + if (allOptions.hasOwnProperty(i)) { + allOptions[i].label = RED._("typedInput.type."+i,{defaultValue:allOptions[i].label}); + } + } + var contextStores = RED.settings.context.stores; + var contextOptions = contextStores.map(function(store) { + return {value:store,label: store, icon:'<i class="red-ui-typedInput-icon fa fa-database"></i>'} + }) + if (contextOptions.length < 2) { + allOptions.flow.options = []; + allOptions.global.options = []; + } else { + allOptions.flow.options = contextOptions; + allOptions.global.options = contextOptions; + } + } + nlsd = true; + var that = this; + + this.disarmClick = false; + this.input = $('<input class="red-ui-typedInput-input" type="text"></input>'); + this.input.insertAfter(this.element); + this.input.val(this.element.val()); + this.element.addClass('red-ui-typedInput'); + this.uiWidth = this.element.outerWidth(); + this.elementDiv = this.input.wrap("<div>").parent().addClass('red-ui-typedInput-input-wrap'); + this.uiSelect = this.elementDiv.wrap( "<div>" ).parent(); + var attrStyle = this.element.attr('style'); + var m; + if ((m = /width\s*:\s*(calc\s*\(.*\)|\d+(%|px))/i.exec(attrStyle)) !== null) { + this.input.css('width','100%'); + this.uiSelect.width(m[1]); + this.uiWidth = null; + } else { + this.uiSelect.width(this.uiWidth); + } + ["Right","Left"].forEach(function(d) { + var m = that.element.css("margin"+d); + that.uiSelect.css("margin"+d,m); + that.input.css("margin"+d,0); + }); + + ["type","placeholder","autocomplete","data-i18n"].forEach(function(d) { + var m = that.element.attr(d); + that.input.attr(d,m); + }); + + this.uiSelect.addClass("red-ui-typedInput-container"); + + this.element.attr('type','hidden'); + + this.options.types = this.options.types||Object.keys(allOptions); + + this.selectTrigger = $('<button class="red-ui-typedInput-type-select" tabindex="0"></button>').prependTo(this.uiSelect); + $('<i class="red-ui-typedInput-icon fa fa-caret-down"></i>').toggle(this.options.types.length > 1).appendTo(this.selectTrigger); + + this.selectLabel = $('<span class="red-ui-typedInput-type-label"></span>').appendTo(this.selectTrigger); + + this.valueLabelContainer = $('<div class="red-ui-typedInput-value-label">').appendTo(this.uiSelect) + + this.types(this.options.types); + + if (this.options.typeField) { + this.typeField = $(this.options.typeField).hide(); + var t = this.typeField.val(); + if (t && this.typeMap[t]) { + this.options.default = t; + } + } else { + this.typeField = $("<input>",{type:'hidden'}).appendTo(this.uiSelect); + } + + this.input.on('focus', function() { + that.uiSelect.addClass('red-ui-typedInput-focus'); + }); + this.input.on('blur', function() { + that.uiSelect.removeClass('red-ui-typedInput-focus'); + }); + this.input.on('change', function() { + that.validate(); + that.element.val(that.value()); + that.element.trigger('change',that.propertyType,that.value()); + }); + this.input.on('keydown', function(evt) { + if (evt.keyCode >= 37 && evt.keyCode <= 40) { + evt.stopPropagation(); + } + }) + this.selectTrigger.on("click", function(event) { + event.preventDefault(); + event.stopPropagation(); + that._showTypeMenu(); + }); + this.selectTrigger.on('keydown',function(evt) { + if (evt.keyCode === 40) { + // Down + that._showTypeMenu(); + } + evt.stopPropagation(); + }).on('focus', function() { + that.uiSelect.addClass('red-ui-typedInput-focus'); + }) + + // explicitly set optionSelectTrigger display to inline-block otherwise jQ sets it to 'inline' + this.optionSelectTrigger = $('<button tabindex="0" class="red-ui-typedInput-option-trigger" style="display:inline-block"><span class="red-ui-typedInput-option-caret"><i class="red-ui-typedInput-icon fa fa-caret-down"></i></span></button>').appendTo(this.uiSelect); + this.optionSelectLabel = $('<span class="red-ui-typedInput-option-label"></span>').prependTo(this.optionSelectTrigger); + RED.popover.tooltip(this.optionSelectLabel,function() { + return that.optionValue; + }); + this.optionSelectTrigger.on("click", function(event) { + event.preventDefault(); + event.stopPropagation(); + that._showOptionSelectMenu(); + }).on('keydown', function(evt) { + if (evt.keyCode === 40) { + // Down + that._showOptionSelectMenu(); + } + evt.stopPropagation(); + }).on('blur', function() { + that.uiSelect.removeClass('red-ui-typedInput-focus'); + }).on('focus', function() { + that.uiSelect.addClass('red-ui-typedInput-focus'); + }); + + this.optionExpandButton = $('<button tabindex="0" class="red-ui-typedInput-option-expand" style="display:inline-block"></button>').appendTo(this.uiSelect); + this.optionExpandButtonIcon = $('<i class="red-ui-typedInput-icon fa fa-ellipsis-h"></i>').appendTo(this.optionExpandButton); + this.type(this.options.default||this.typeList[0].value); + }catch(err) { + console.log(err.stack); + } + }, + _showTypeMenu: function() { + if (this.typeList.length > 1) { + this._showMenu(this.menu,this.selectTrigger); + var selected = this.menu.find("[value='"+this.propertyType+"']"); + setTimeout(function() { + selected.trigger("focus"); + },120); + } else { + this.input.trigger("focus"); + } + }, + _showOptionSelectMenu: function() { + if (this.optionMenu) { + this.optionMenu.css({ + minWidth:this.optionSelectLabel.width() + }); + + this._showMenu(this.optionMenu,this.optionSelectTrigger); + var selectedOption = this.optionMenu.find("[value='"+this.optionValue+"']"); + if (selectedOption.length === 0) { + selectedOption = this.optionMenu.children(":first"); + } + selectedOption.trigger("focus"); + + } + }, + _hideMenu: function(menu) { + $(document).off("mousedown.red-ui-typedInput-close-property-select"); + menu.hide(); + menu.css({ + height: "auto" + }); + + if (menu.opts.multiple) { + var selected = []; + menu.find('input[type="checkbox"]').each(function() { + if ($(this).prop("checked")) { + selected.push($(this).data('value')) + } + }) + menu.callback(selected); + } + + if (this.elementDiv.is(":visible")) { + this.input.trigger("focus"); + } else if (this.optionSelectTrigger.is(":visible")){ + this.optionSelectTrigger.trigger("focus"); + } else { + this.selectTrigger.trigger("focus"); + } + }, + _createMenu: function(menuOptions,opts,callback) { + var that = this; + var menu = $("<div>").addClass("red-ui-typedInput-options red-ui-editor-dialog"); + menu.opts = opts; + menu.callback = callback; + menuOptions.forEach(function(opt) { + if (typeof opt === 'string') { + opt = {value:opt,label:opt}; + } + var op = $('<a href="#"></a>').attr("value",opt.value).appendTo(menu); + if (opt.label) { + op.text(opt.label); + } + if (opt.icon) { + if (opt.icon.indexOf("<") === 0) { + $(opt.icon).prependTo(op); + } else if (opt.icon.indexOf("/") !== -1) { + $('<img>',{src:mapDeprecatedIcon(opt.icon),style:"margin-right: 4px; height: 18px;"}).prependTo(op); + } else { + $('<i>',{class:"red-ui-typedInput-icon "+opt.icon}).prependTo(op); + } + } else { + op.css({paddingLeft: "18px"}); + } + if (!opt.icon && !opt.label) { + op.text(opt.value); + } + var cb; + if (opts.multiple) { + cb = $('<input type="checkbox">').css("pointer-events","none").data('value',opt.value).prependTo(op).on("mousedown", function(evt) { evt.preventDefault() }); + } + + op.on("click", function(event) { + event.preventDefault(); + event.stopPropagation(); + if (!opts.multiple) { + callback(opt.value); + that._hideMenu(menu); + } else { + cb.prop("checked",!cb.prop("checked")); + } + }); + }); + menu.css({ + display: "none" + }); + menu.appendTo(document.body); + + menu.on('keydown', function(evt) { + if (evt.keyCode === 40) { + evt.preventDefault(); + // DOWN + $(this).children(":focus").next().trigger("focus"); + } else if (evt.keyCode === 38) { + evt.preventDefault(); + // UP + $(this).children(":focus").prev().trigger("focus"); + } else if (evt.keyCode === 27) { + // ESCAPE + evt.preventDefault(); + that._hideMenu(menu); + } + evt.stopPropagation(); + }) + return menu; + + }, + _showMenu: function(menu,relativeTo) { + if (this.disarmClick) { + this.disarmClick = false; + return + } + if (menu.opts.multiple) { + var selected = {}; + this.value().split(",").forEach(function(f) { + selected[f] = true; + }) + menu.find('input[type="checkbox"]').each(function() { + $(this).prop("checked",selected[$(this).data('value')]) + }) + } + + + var that = this; + var pos = relativeTo.offset(); + var height = relativeTo.height(); + var menuHeight = menu.height(); + var top = (height+pos.top); + if (top+menuHeight > $(window).height()) { + top -= (top+menuHeight)-$(window).height()+5; + } + if (top < 0) { + menu.height(menuHeight+top) + top = 0; + } + menu.css({ + top: top+"px", + left: (pos.left)+"px", + }); + menu.slideDown(100); + this._delay(function() { + that.uiSelect.addClass('red-ui-typedInput-focus'); + $(document).on("mousedown.red-ui-typedInput-close-property-select", function(event) { + if(!$(event.target).closest(menu).length) { + that._hideMenu(menu); + } + if ($(event.target).closest(relativeTo).length) { + that.disarmClick = true; + event.preventDefault(); + } + }) + }); + }, + _getLabelWidth: function(label, done) { + var labelWidth = label.outerWidth(); + if (labelWidth === 0) { + var wrapper = $('<div class="red-ui-editor"></div>').css({ + position:"absolute", + "white-space": "nowrap", + top:-2000 + }).appendTo(document.body); + var container = $('<div class="red-ui-typedInput-container"></div>').appendTo(wrapper); + var newTrigger = label.clone().appendTo(container); + setTimeout(function() { + labelWidth = newTrigger.outerWidth(); + wrapper.remove(); + done(labelWidth); + },50) + } else { + done(labelWidth); + } + }, + _resize: function() { + var that = this; + if (this.uiWidth !== null) { + this.uiSelect.width(this.uiWidth); + } + var type = this.typeMap[this.propertyType]; + if (type && type.hasValue === false) { + this.selectTrigger.addClass("red-ui-typedInput-full-width"); + } else { + this.selectTrigger.removeClass("red-ui-typedInput-full-width"); + this._getLabelWidth(this.selectTrigger, function(labelWidth) { + that.elementDiv.css('left',labelWidth+"px"); + that.valueLabelContainer.css('left',labelWidth+"px"); + if (that.optionExpandButton.shown) { + that.elementDiv.css('right',"22px"); + that.valueLabelContainer.css('right',"22px"); + } else { + that.elementDiv.css('right','0'); + that.valueLabelContainer.css('right','0'); + that.input.css({ + 'border-top-right-radius': '4px', + 'border-bottom-right-radius': '4px' + }); + } + if (that.optionSelectTrigger) { + if (type && type.options && type.hasValue === true) { + that.optionSelectLabel.css({'left':'auto'}) + that._getLabelWidth(that.optionSelectLabel, function(lw) { + that.optionSelectTrigger.css({'width':(23+lw)+"px"}); + that.elementDiv.css('right',(23+lw)+"px"); + that.input.css({ + 'border-top-right-radius': 0, + 'border-bottom-right-radius': 0 + }); + }); + } else { + that.optionSelectLabel.css({'left':'0'}) + that.optionSelectTrigger.css({'width':'calc( 100% - '+labelWidth+'px )'}); + if (!that.optionExpandButton.shown) { + that.elementDiv.css({'right':0}); + that.input.css({ + 'border-top-right-radius': '4px', + 'border-bottom-right-radius': '4px' + }); + } + } + } + }); + } + }, + _updateOptionSelectLabel: function(o) { + var opt = this.typeMap[this.propertyType]; + this.optionSelectLabel.empty(); + if (this.typeMap[this.propertyType].valueLabel) { + if (opt.multiple) { + this.typeMap[this.propertyType].valueLabel.call(this,this.optionSelectLabel,o); + } else { + this.typeMap[this.propertyType].valueLabel.call(this,this.optionSelectLabel,o.value); + } + } else if (!opt.multiple) { + if (o.icon) { + if (o.icon.indexOf("<") === 0) { + $(o.icon).prependTo(this.optionSelectLabel); + } else if (o.icon.indexOf("/") !== -1) { + // url + $('<img>',{src:mapDeprecatedIcon(o.icon),style:"height: 18px;"}).prependTo(this.optionSelectLabel); + } else { + // icon class + $('<i>',{class:"red-ui-typedInput-icon "+o.icon}).prependTo(this.optionSelectLabel); + } + } else if (o.label) { + this.optionSelectLabel.text(o.label); + } else { + this.optionSelectLabel.text(o.value); + } + if (opt.hasValue) { + this.optionValue = o.value; + this._resize(); + this.input.trigger('change',this.propertyType,this.value()); + } + } else { + this.optionSelectLabel.text(o.length+" selected"); + } + }, + _destroy: function() { + if (this.optionMenu) { + this.optionMenu.remove(); + } + this.menu.remove(); + this.uiSelect.remove(); + }, + types: function(types) { + var that = this; + var currentType = this.type(); + this.typeMap = {}; + this.typeList = types.map(function(opt) { + var result; + if (typeof opt === 'string') { + result = allOptions[opt]; + } else { + result = opt; + } + that.typeMap[result.value] = result; + return result; + }); + this.selectTrigger.toggleClass("disabled", this.typeList.length === 1); + this.selectTrigger.find(".fa-caret-down").toggle(this.typeList.length > 1) + if (this.menu) { + this.menu.remove(); + } + this.menu = this._createMenu(this.typeList,{},function(v) { that.type(v) }); + if (currentType && !this.typeMap.hasOwnProperty(currentType)) { + this.type(this.typeList[0].value); + } else { + this.propertyType = null; + this.type(currentType); + } + setTimeout(function() {that._resize();},0); + }, + width: function(desiredWidth) { + this.uiWidth = desiredWidth; + this._resize(); + }, + value: function(value) { + var that = this; + var opt = this.typeMap[this.propertyType]; + if (!arguments.length) { + var v = this.input.val(); + if (opt.export) { + v = opt.export(v,this.optionValue) + } + return v; + } else { + var selectedOption = []; + if (opt.options) { + var checkValues = [value]; + if (opt.multiple) { + selectedOption = []; + checkValues = value.split(","); + } + checkValues.forEach(function(value) { + for (var i=0;i<opt.options.length;i++) { + var op = opt.options[i]; + if (typeof op === "string") { + if (op === value || op === ""+value) { + selectedOption.push(that.activeOptions[op]); + break; + } + } else if (op.value === value) { + selectedOption.push(op); + break; + } + } + }) + this.input.val(value); + if (!opt.multiple) { + if (selectedOption.length === 0) { + selectedOption = [{value:""}]; + } + this._updateOptionSelectLabel(selectedOption[0]) + } else { + this._updateOptionSelectLabel(selectedOption) + } + } else { + this.input.val(value); + if (opt.valueLabel) { + this.valueLabelContainer.empty(); + opt.valueLabel.call(this,this.valueLabelContainer,value); + } + } + this.input.trigger('change',this.type(),value); + } + }, + type: function(type) { + if (!arguments.length) { + return this.propertyType; + } else { + var that = this; + var opt = this.typeMap[type]; + if (opt && this.propertyType !== type) { + this.propertyType = type; + if (this.typeField) { + this.typeField.val(type); + } + this.selectLabel.empty(); + var image; + if (opt.icon && opt.showLabel !== false) { + if (opt.icon.indexOf("<") === 0) { + $(opt.icon).prependTo(this.selectLabel); + } + else if (opt.icon.indexOf("/") !== -1) { + image = new Image(); + image.onload = function() { that._resize(); } + image.onerror = function() { that._resize(); } + image.name = opt.icon; + image.src = mapDeprecatedIcon(opt.icon); + $('<img>',{src:mapDeprecatedIcon(opt.icon),style:"margin-right: 4px;height: 18px;"}).prependTo(this.selectLabel); + } + else { + $('<i>',{class:"red-ui-typedInput-icon "+opt.icon}).prependTo(this.selectLabel); + } + } + if (opt.hasValue === false || (opt.showLabel !== false && !opt.icon)) { + this.selectLabel.text(opt.label); + } + if (this.optionMenu) { + this.optionMenu.remove(); + this.optionMenu = null; + } + if (opt.options) { + if (this.optionExpandButton) { + this.optionExpandButton.hide(); + this.optionExpandButton.shown = false; + } + if (this.optionSelectTrigger) { + this.optionSelectTrigger.show(); + if (!opt.hasValue) { + this.elementDiv.hide(); + this.valueLabelContainer.hide(); + } else { + this.elementDiv.show(); + this.valueLabelContainer.hide(); + } + this.activeOptions = {}; + opt.options.forEach(function(o) { + if (typeof o === 'string') { + that.activeOptions[o] = {label:o,value:o}; + } else { + that.activeOptions[o.value] = o; + } + }); + + if (!that.activeOptions.hasOwnProperty(that.optionValue)) { + that.optionValue = null; + } + + var op; + if (!opt.hasValue) { + var validValue = false; + var currentVal = this.input.val(); + if (!opt.multiple) { + for (var i=0;i<opt.options.length;i++) { + op = opt.options[i]; + if (typeof op === "string" && op === currentVal) { + that._updateOptionSelectLabel({value:currentVal}); + validValue = true; + break; + } else if (op.value === currentVal) { + that._updateOptionSelectLabel(op); + validValue = true; + break; + } + } + if (!validValue) { + op = opt.options[0]; + if (typeof op === "string") { + this.value(op); + that._updateOptionSelectLabel({value:op}); + } else { + this.value(op.value); + that._updateOptionSelectLabel(op); + } + } + } else { + // Check to see if value is a valid csv of + // options. + var currentValues = {}; + currentVal.split(",").forEach(function(v) { + if (v) { + currentValues[v] = true; + } + }); + for (var i=0;i<opt.options.length;i++) { + op = opt.options[i]; + delete currentValues[op.value||op]; + } + if (!$.isEmptyObject(currentValues)) { + // Invalid, set to default/empty + this.value((opt.default||[]).join(",")); + } + } + } else { + var selectedOption = this.optionValue||opt.options[0]; + if (opt.parse) { + var parts = opt.parse(this.input.val()); + if (parts.option) { + selectedOption = parts.option; + if (!this.activeOptions.hasOwnProperty(selectedOption)) { + parts.option = Object.keys(this.activeOptions)[0]; + selectedOption = parts.option + } + } + this.input.val(parts.value); + if (opt.export) { + this.element.val(opt.export(parts.value,parts.option||selectedOption)); + } + } + if (typeof selectedOption === "string") { + this.optionValue = selectedOption; + if (!this.activeOptions.hasOwnProperty(selectedOption)) { + selectedOption = Object.keys(this.activeOptions)[0]; + } + if (!selectedOption) { + this.optionSelectTrigger.hide(); + } else { + this._updateOptionSelectLabel(this.activeOptions[selectedOption]); + } + } else if (selectedOption) { + this.optionValue = selectedOption.value; + this._updateOptionSelectLabel(selectedOption); + } else { + this.optionSelectTrigger.hide(); + } + } + this.optionMenu = this._createMenu(opt.options,opt,function(v){ + if (!opt.multiple) { + that._updateOptionSelectLabel(that.activeOptions[v]); + if (!opt.hasValue) { + that.value(that.activeOptions[v].value) + } + } else { + that._updateOptionSelectLabel(v); + if (!opt.hasValue) { + that.value(v.join(",")) + } + } + }); + } + this._trigger("typechange",null,this.propertyType); + this.input.trigger('change',this.propertyType,this.value()); + } else { + if (this.optionSelectTrigger) { + this.optionSelectTrigger.hide(); + } + if (opt.hasValue === false) { + this.oldValue = this.input.val(); + this.input.val(""); + this.elementDiv.hide(); + this.valueLabelContainer.hide(); + } else if (opt.valueLabel) { + this.valueLabelContainer.show(); + this.valueLabelContainer.empty(); + opt.valueLabel.call(this,this.valueLabelContainer,this.input.val()); + this.elementDiv.hide(); + } else { + if (this.oldValue !== undefined) { + this.input.val(this.oldValue); + delete this.oldValue; + } + this.valueLabelContainer.hide(); + this.elementDiv.show(); + } + if (this.optionExpandButton) { + if (opt.expand) { + if (opt.expand.icon) { + this.optionExpandButtonIcon.removeClass().addClass("red-ui-typedInput-icon fa "+opt.expand.icon) + } else { + this.optionExpandButtonIcon.removeClass().addClass("red-ui-typedInput-icon fa fa-ellipsis-h") + } + this.optionExpandButton.shown = true; + this.optionExpandButton.show(); + this.optionExpandButton.off('click'); + this.optionExpandButton.on('click',function(evt) { + evt.preventDefault(); + if (typeof opt.expand === 'function') { + opt.expand.call(that); + } else { + var container = $('<div>'); + var content = opt.expand.content.call(that,container); + var panel = RED.popover.panel(container); + panel.container.css({ + width:that.valueLabelContainer.width() + }); + if (opt.expand.minWidth) { + panel.container.css({ + minWidth: opt.expand.minWidth+"px" + }); + } + panel.show({ + target:that.optionExpandButton, + onclose:content.onclose, + align: "right" + }); + } + }) + } else { + this.optionExpandButton.shown = false; + this.optionExpandButton.hide(); + } + } + this._trigger("typechange",null,this.propertyType); + this.input.trigger('change',this.propertyType,this.value()); + } + if (!image) { + this._resize(); + } + } + } + }, + validate: function() { + var result; + var value = this.value(); + var type = this.type(); + if (this.typeMap[type] && this.typeMap[type].validate) { + var val = this.typeMap[type].validate; + if (typeof val === 'function') { + result = val(value); + } else { + result = val.test(value); + } + } else { + result = true; + } + if (result) { + this.uiSelect.removeClass('input-error'); + } else { + this.uiSelect.addClass('input-error'); + } + return result; + }, + show: function() { + this.uiSelect.show(); + this._resize(); + }, + hide: function() { + this.uiSelect.hide(); + } + }); +})(jQuery); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js new file mode 100644 index 0000000..9e91410 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js @@ -0,0 +1,516 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +RED.deploy = (function() { + + var deploymentTypes = { + "full":{img:"red/images/deploy-full-o.svg"}, + "nodes":{img:"red/images/deploy-nodes-o.svg"}, + "flows":{img:"red/images/deploy-flows-o.svg"} + } + + var ignoreDeployWarnings = { + unknown: false, + unusedConfig: false, + invalid: false + } + + var deploymentType = "full"; + + var deployInflight = false; + + var currentDiff = null; + + function changeDeploymentType(type) { + deploymentType = type; + $("#red-ui-header-button-deploy-icon").attr("src",deploymentTypes[type].img); + } + + /** + * options: + * type: "default" - Button with drop-down options - no further customisation available + * type: "simple" - Button without dropdown. Customisations: + * label: the text to display - default: "Deploy" + * icon : the icon to use. Null removes the icon. default: "red/images/deploy-full-o.svg" + */ + function init(options) { + options = options || {}; + var type = options.type || "default"; + + if (type == "default") { + $('<li><span class="red-ui-deploy-button-group button-group">'+ + '<a id="red-ui-header-button-deploy" class="red-ui-deploy-button disabled" href="#">'+ + '<span class="red-ui-deploy-button-content">'+ + '<img id="red-ui-header-button-deploy-icon" src="red/images/deploy-full-o.svg"> '+ + '<span>'+RED._("deploy.deploy")+'</span>'+ + '</span>'+ + '<span class="red-ui-deploy-button-spinner hide">'+ + '<img src="red/images/spin.svg"/>'+ + '</span>'+ + '</a>'+ + '<a id="red-ui-header-button-deploy-options" class="red-ui-deploy-button" href="#"><i class="fa fa-caret-down"></i></a>'+ + '</span></li>').prependTo(".red-ui-header-toolbar"); + RED.menu.init({id:"red-ui-header-button-deploy-options", + options: [ + {id:"deploymenu-item-full",toggle:"deploy-type",icon:"red/images/deploy-full.svg",label:RED._("deploy.full"),sublabel:RED._("deploy.fullDesc"),selected: true, onselect:function(s) { if(s){changeDeploymentType("full")}}}, + {id:"deploymenu-item-flow",toggle:"deploy-type",icon:"red/images/deploy-flows.svg",label:RED._("deploy.modifiedFlows"),sublabel:RED._("deploy.modifiedFlowsDesc"), onselect:function(s) {if(s){changeDeploymentType("flows")}}}, + {id:"deploymenu-item-node",toggle:"deploy-type",icon:"red/images/deploy-nodes.svg",label:RED._("deploy.modifiedNodes"),sublabel:RED._("deploy.modifiedNodesDesc"),onselect:function(s) { if(s){changeDeploymentType("nodes")}}}, + null, + {id:"deploymenu-item-reload", icon:"red/images/deploy-reload.svg",label:RED._("deploy.restartFlows"),sublabel:RED._("deploy.restartFlowsDesc"),onselect:"core:restart-flows"}, + + ] + }); + } else if (type == "simple") { + var label = options.label || RED._("deploy.deploy"); + var icon = 'red/images/deploy-full-o.svg'; + if (options.hasOwnProperty('icon')) { + icon = options.icon; + } + + $('<li><span class="red-ui-deploy-button-group button-group">'+ + '<a id="red-ui-header-button-deploy" class="red-ui-deploy-button disabled" href="#">'+ + '<span class="red-ui-deploy-button-content">'+ + (icon?'<img id="red-ui-header-button-deploy-icon" src="'+icon+'"> ':'')+ + '<span>'+label+'</span>'+ + '</span>'+ + '<span class="red-ui-deploy-button-spinner hide">'+ + '<img src="red/images/spin.svg"/>'+ + '</span>'+ + '</a>'+ + '</span></li>').prependTo(".red-ui-header-toolbar"); + } + + $('#red-ui-header-button-deploy').on("click", function(event) { + event.preventDefault(); + save(); + }); + + RED.actions.add("core:deploy-flows",save); + if (type === "default") { + RED.actions.add("core:restart-flows",restart); + RED.actions.add("core:set-deploy-type-to-full",function() { RED.menu.setSelected("deploymenu-item-full",true);}); + RED.actions.add("core:set-deploy-type-to-modified-flows",function() { RED.menu.setSelected("deploymenu-item-flow",true); }); + RED.actions.add("core:set-deploy-type-to-modified-nodes",function() { RED.menu.setSelected("deploymenu-item-node",true); }); + } + + + + RED.events.on('nodes:change',function(state) { + if (state.dirty) { + window.onbeforeunload = function() { + return RED._("deploy.confirm.undeployedChanges"); + } + $("#red-ui-header-button-deploy").removeClass("disabled"); + } else { + window.onbeforeunload = null; + $("#red-ui-header-button-deploy").addClass("disabled"); + } + }); + + var activeNotifyMessage; + RED.comms.subscribe("notification/runtime-deploy",function(topic,msg) { + if (!activeNotifyMessage) { + var currentRev = RED.nodes.version(); + if (currentRev === null || deployInflight || currentRev === msg.revision) { + return; + } + var message = $('<p>').text(RED._('deploy.confirm.backgroundUpdate')); + activeNotifyMessage = RED.notify(message,{ + modal: true, + fixed: true, + buttons: [ + { + text: RED._('deploy.confirm.button.ignore'), + click: function() { + activeNotifyMessage.close(); + activeNotifyMessage = null; + } + }, + { + text: RED._('deploy.confirm.button.review'), + class: "primary", + click: function() { + activeNotifyMessage.close(); + var nns = RED.nodes.createCompleteNodeSet(); + resolveConflict(nns,false); + activeNotifyMessage = null; + } + } + ] + }); + } + }); + } + + function getNodeInfo(node) { + var tabLabel = ""; + if (node.z) { + var tab = RED.nodes.workspace(node.z); + if (!tab) { + tab = RED.nodes.subflow(node.z); + tabLabel = tab.name; + } else { + tabLabel = tab.label; + } + } + var label = RED.utils.getNodeLabel(node,node.id); + return {tab:tabLabel,type:node.type,label:label}; + } + function sortNodeInfo(A,B) { + if (A.tab < B.tab) { return -1;} + if (A.tab > B.tab) { return 1;} + if (A.type < B.type) { return -1;} + if (A.type > B.type) { return 1;} + if (A.name < B.name) { return -1;} + if (A.name > B.name) { return 1;} + return 0; + } + + function resolveConflict(currentNodes, activeDeploy) { + var message = $('<div>'); + $('<p data-i18n="deploy.confirm.conflict"></p>').appendTo(message); + var conflictCheck = $('<div class="red-ui-deploy-dialog-confirm-conflict-row">'+ + '<img src="red/images/spin.svg"/><div data-i18n="deploy.confirm.conflictChecking"></div>'+ + '</div>').appendTo(message); + var conflictAutoMerge = $('<div class="red-ui-deploy-dialog-confirm-conflict-row">'+ + '<i class="fa fa-check"></i><div data-i18n="deploy.confirm.conflictAutoMerge"></div>'+ + '</div>').hide().appendTo(message); + var conflictManualMerge = $('<div class="red-ui-deploy-dialog-confirm-conflict-row">'+ + '<i class="fa fa-exclamation"></i><div data-i18n="deploy.confirm.conflictManualMerge"></div>'+ + '</div>').hide().appendTo(message); + + message.i18n(); + currentDiff = null; + var buttons = [ + { + text: RED._("common.label.cancel"), + click: function() { + conflictNotification.close(); + } + }, + { + id: "red-ui-deploy-dialog-confirm-deploy-review", + text: RED._("deploy.confirm.button.review"), + class: "primary disabled", + click: function() { + if (!$("#red-ui-deploy-dialog-confirm-deploy-review").hasClass('disabled')) { + RED.diff.showRemoteDiff(); + conflictNotification.close(); + } + } + }, + { + id: "red-ui-deploy-dialog-confirm-deploy-merge", + text: RED._("deploy.confirm.button.merge"), + class: "primary disabled", + click: function() { + if (!$("#red-ui-deploy-dialog-confirm-deploy-merge").hasClass('disabled')) { + RED.diff.mergeDiff(currentDiff); + conflictNotification.close(); + } + } + } + ]; + if (activeDeploy) { + buttons.push({ + id: "red-ui-deploy-dialog-confirm-deploy-overwrite", + text: RED._("deploy.confirm.button.overwrite"), + class: "primary", + click: function() { + save(true,activeDeploy); + conflictNotification.close(); + } + }) + } + var conflictNotification = RED.notify(message,{ + modal: true, + fixed: true, + width: 600, + buttons: buttons + }); + + var now = Date.now(); + RED.diff.getRemoteDiff(function(diff) { + var ellapsed = Math.max(1000 - (Date.now()-now), 0); + currentDiff = diff; + setTimeout(function() { + conflictCheck.hide(); + var d = Object.keys(diff.conflicts); + if (d.length === 0) { + conflictAutoMerge.show(); + $("#red-ui-deploy-dialog-confirm-deploy-merge").removeClass('disabled') + } else { + conflictManualMerge.show(); + } + $("#red-ui-deploy-dialog-confirm-deploy-review").removeClass('disabled') + },ellapsed); + }) + } + function cropList(list) { + if (list.length > 5) { + var remainder = list.length - 5; + list = list.slice(0,5); + list.push(RED._("deploy.confirm.plusNMore",{count:remainder})); + } + return list; + } + function sanitize(html) { + return html.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;") + } + function restart() { + var startTime = Date.now(); + $(".red-ui-deploy-button-content").css('opacity',0); + $(".red-ui-deploy-button-spinner").show(); + var deployWasEnabled = !$("#red-ui-header-button-deploy").hasClass("disabled"); + $("#red-ui-header-button-deploy").addClass("disabled"); + deployInflight = true; + $("#red-ui-header-shade").show(); + $("#red-ui-editor-shade").show(); + $("#red-ui-palette-shade").show(); + $("#red-ui-sidebar-shade").show(); + + $.ajax({ + url:"flows", + type: "POST", + headers: { + "Node-RED-Deployment-Type":"reload" + } + }).done(function(data,textStatus,xhr) { + if (deployWasEnabled) { + $("#red-ui-header-button-deploy").removeClass("disabled"); + } + RED.notify('<p>'+RED._("deploy.successfulRestart")+'</p>',"success"); + }).fail(function(xhr,textStatus,err) { + if (deployWasEnabled) { + $("#red-ui-header-button-deploy").removeClass("disabled"); + } + if (xhr.status === 401) { + RED.notify(RED._("deploy.deployFailed",{message:RED._("user.notAuthorized")}),"error"); + } else if (xhr.status === 409) { + resolveConflict(nns, true); + } else if (xhr.responseText) { + RED.notify(RED._("deploy.deployFailed",{message:xhr.responseText}),"error"); + } else { + RED.notify(RED._("deploy.deployFailed",{message:RED._("deploy.errors.noResponse")}),"error"); + } + }).always(function() { + deployInflight = false; + var delta = Math.max(0,300-(Date.now()-startTime)); + setTimeout(function() { + $(".red-ui-deploy-button-content").css('opacity',1); + $(".red-ui-deploy-button-spinner").hide(); + $("#red-ui-header-shade").hide(); + $("#red-ui-editor-shade").hide(); + $("#red-ui-palette-shade").hide(); + $("#red-ui-sidebar-shade").hide(); + },delta); + }); + } + function save(skipValidation,force) { + if (!$("#red-ui-header-button-deploy").hasClass("disabled")) { + if (!RED.user.hasPermission("flows.write")) { + RED.notify(RED._("user.errors.deploy"),"error"); + return; + } + if (!skipValidation) { + var hasUnknown = false; + var hasInvalid = false; + var hasUnusedConfig = false; + + var unknownNodes = []; + var invalidNodes = []; + + RED.nodes.eachNode(function(node) { + if (!node.valid && !node.d) { + invalidNodes.push(getNodeInfo(node)); + } + if (node.type === "unknown") { + if (unknownNodes.indexOf(node.name) == -1) { + unknownNodes.push(node.name); + } + } + }); + hasUnknown = unknownNodes.length > 0; + hasInvalid = invalidNodes.length > 0; + + var unusedConfigNodes = []; + RED.nodes.eachConfig(function(node) { + if ((node._def.hasUsers !== false) && (node.users.length === 0)) { + unusedConfigNodes.push(getNodeInfo(node)); + hasUnusedConfig = true; + } + }); + + var showWarning = false; + var notificationMessage; + var notificationButtons = []; + var notification; + if (hasUnknown && !ignoreDeployWarnings.unknown) { + showWarning = true; + notificationMessage = "<p>"+RED._('deploy.confirm.unknown')+"</p>"+ + '<ul class="red-ui-deploy-dialog-confirm-list"><li>'+cropList(unknownNodes).map(function(n) { return sanitize(n) }).join("</li><li>")+"</li></ul><p>"+ + RED._('deploy.confirm.confirm')+ + "</p>"; + + notificationButtons= [ + { + id: "red-ui-deploy-dialog-confirm-deploy-deploy", + text: RED._("deploy.confirm.button.confirm"), + class: "primary", + click: function() { + save(true); + notification.close(); + } + } + ]; + } else if (hasInvalid && !ignoreDeployWarnings.invalid) { + showWarning = true; + invalidNodes.sort(sortNodeInfo); + + notificationMessage = "<p>"+RED._('deploy.confirm.improperlyConfigured')+"</p>"+ + '<ul class="red-ui-deploy-dialog-confirm-list"><li>'+cropList(invalidNodes.map(function(A) { return sanitize( (A.tab?"["+A.tab+"] ":"")+A.label+" ("+A.type+")")})).join("</li><li>")+"</li></ul><p>"+ + RED._('deploy.confirm.confirm')+ + "</p>"; + notificationButtons= [ + { + id: "red-ui-deploy-dialog-confirm-deploy-deploy", + text: RED._("deploy.confirm.button.confirm"), + class: "primary", + click: function() { + save(true); + notification.close(); + } + } + ]; + } + if (showWarning) { + notificationButtons.unshift( + { + text: RED._("common.label.cancel"), + click: function() { + notification.close(); + } + } + ); + notification = RED.notify(notificationMessage,{ + modal: true, + fixed: true, + buttons:notificationButtons + }); + return; + } + } + + var nns = RED.nodes.createCompleteNodeSet(); + + var startTime = Date.now(); + $(".red-ui-deploy-button-content").css('opacity',0); + $(".red-ui-deploy-button-spinner").show(); + $("#red-ui-header-button-deploy").addClass("disabled"); + + var data = {flows:nns}; + + if (!force) { + data.rev = RED.nodes.version(); + } + + deployInflight = true; + $("#red-ui-header-shade").show(); + $("#red-ui-editor-shade").show(); + $("#red-ui-palette-shade").show(); + $("#red-ui-sidebar-shade").show(); + $.ajax({ + url:"flows", + type: "POST", + data: JSON.stringify(data), + contentType: "application/json; charset=utf-8", + headers: { + "Node-RED-Deployment-Type":deploymentType + } + }).done(function(data,textStatus,xhr) { + RED.nodes.dirty(false); + RED.nodes.version(data.rev); + RED.nodes.originalFlow(nns); + if (hasUnusedConfig) { + RED.notify( + '<p>'+RED._("deploy.successfulDeploy")+'</p>'+ + '<p>'+RED._("deploy.unusedConfigNodes")+' <a href="#" onclick="RED.sidebar.config.show(true); return false;">'+RED._("deploy.unusedConfigNodesLink")+'</a></p>',"success",false,6000); + } else { + RED.notify('<p>'+RED._("deploy.successfulDeploy")+'</p>',"success"); + } + RED.nodes.eachNode(function(node) { + if (node.changed) { + node.dirty = true; + node.changed = false; + } + if (node.moved) { + node.dirty = true; + node.moved = false; + } + if(node.credentials) { + delete node.credentials; + } + }); + RED.nodes.eachConfig(function (confNode) { + confNode.changed = false; + if (confNode.credentials) { + delete confNode.credentials; + } + }); + RED.nodes.eachSubflow(function(subflow) { + subflow.changed = false; + }); + RED.nodes.eachWorkspace(function(ws) { + ws.changed = false; + }); + // Once deployed, cannot undo back to a clean state + RED.history.markAllDirty(); + RED.view.redraw(); + RED.events.emit("deploy"); + }).fail(function(xhr,textStatus,err) { + RED.nodes.dirty(true); + $("#red-ui-header-button-deploy").removeClass("disabled"); + if (xhr.status === 401) { + RED.notify(RED._("deploy.deployFailed",{message:RED._("user.notAuthorized")}),"error"); + } else if (xhr.status === 409) { + resolveConflict(nns, true); + } else if (xhr.responseText) { + RED.notify(RED._("deploy.deployFailed",{message:xhr.responseText}),"error"); + } else { + RED.notify(RED._("deploy.deployFailed",{message:RED._("deploy.errors.noResponse")}),"error"); + } + }).always(function() { + deployInflight = false; + var delta = Math.max(0,300-(Date.now()-startTime)); + setTimeout(function() { + $(".red-ui-deploy-button-content").css('opacity',1); + $(".red-ui-deploy-button-spinner").hide(); + $("#red-ui-header-shade").hide(); + $("#red-ui-editor-shade").hide(); + $("#red-ui-palette-shade").hide(); + $("#red-ui-sidebar-shade").hide(); + },delta); + }); + } + } + return { + init: init, + setDeployInflight: function(state) { + deployInflight = state; + } + + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/diff.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/diff.js new file mode 100644 index 0000000..13a157e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/diff.js @@ -0,0 +1,2224 @@ +RED.diff = (function() { + + var currentDiff = {}; + var diffVisible = false; + var diffList; + + function init() { + + // RED.actions.add("core:show-current-diff",showLocalDiff); + RED.actions.add("core:show-remote-diff",showRemoteDiff); + // RED.keyboard.add("*","ctrl-shift-l","core:show-current-diff"); + // RED.keyboard.add("*","ctrl-shift-r","core:show-remote-diff"); + + + // RED.actions.add("core:show-test-flow-diff-1",function(){showTestFlowDiff(1)}); + // RED.keyboard.add("*","ctrl-shift-f 1","core:show-test-flow-diff-1"); + // + // RED.actions.add("core:show-test-flow-diff-2",function(){showTestFlowDiff(2)}); + // RED.keyboard.add("*","ctrl-shift-f 2","core:show-test-flow-diff-2"); + // RED.actions.add("core:show-test-flow-diff-3",function(){showTestFlowDiff(3)}); + // RED.keyboard.add("*","ctrl-shift-f 3","core:show-test-flow-diff-3"); + + } + function createDiffTable(container,CurrentDiff) { + var diffList = $('<ol class="red-ui-diff-list"></ol>').appendTo(container); + diffList.editableList({ + addButton: false, + height: "auto", + scrollOnAdd: false, + addItem: function(container,i,object) { + var localDiff = object.diff; + var remoteDiff = object.remoteDiff; + var tab = object.tab.n; + var def = object.def; + var conflicts = CurrentDiff.conflicts; + + var tabDiv = $('<div>',{class:"red-ui-diff-list-flow"}).appendTo(container); + tabDiv.addClass('collapsed'); + var titleRow = $('<div>',{class:"red-ui-diff-list-flow-title"}).appendTo(tabDiv); + var nodesDiv = $('<div>').appendTo(tabDiv); + var originalCell = $('<div>',{class:"red-ui-diff-list-node-cell"}).appendTo(titleRow); + var localCell = $('<div>',{class:"red-ui-diff-list-node-cell red-ui-diff-list-node-local"}).appendTo(titleRow); + var remoteCell; + var selectState; + + if (remoteDiff) { + remoteCell = $('<div>',{class:"red-ui-diff-list-node-cell red-ui-diff-list-node-remote"}).appendTo(titleRow); + } + $('<span class="red-ui-diff-list-chevron"><i class="fa fa-angle-down"></i></span>').appendTo(originalCell); + createNodeIcon(tab,def).appendTo(originalCell); + var tabForLabel = (object.newTab || object.tab).n; + var titleSpan = $('<span>',{class:"red-ui-diff-list-flow-title-meta"}).appendTo(originalCell); + if (tabForLabel.type === 'tab') { + titleSpan.text(tabForLabel.label||tabForLabel.id); + } else if (tab.type === 'subflow') { + titleSpan.text((tabForLabel.name||tabForLabel.id)); + } else { + titleSpan.text(RED._("diff.globalNodes")); + } + var flowStats = { + local: { + addedCount:0, + deletedCount:0, + changedCount:0, + unchangedCount: 0 + }, + remote: { + addedCount:0, + deletedCount:0, + changedCount:0, + unchangedCount: 0 + }, + conflicts: 0 + } + if (object.newTab || object.remoteTab) { + var localTabNode = { + node: localDiff.newConfig.all[tab.id], + all: localDiff.newConfig.all, + diff: localDiff + } + var remoteTabNode; + if (remoteDiff) { + remoteTabNode = { + node:remoteDiff.newConfig.all[tab.id]||null, + all: remoteDiff.newConfig.all, + diff: remoteDiff + } + } + if (tab.type !== undefined) { + var div = $("<div>",{class:"red-ui-diff-list-node red-ui-diff-list-node-props collapsed"}).appendTo(nodesDiv); + var row = $("<div>",{class:"red-ui-diff-list-node-header"}).appendTo(div); + var originalNodeDiv = $("<div>",{class:"red-ui-diff-list-node-cell"}).appendTo(row); + var localNodeDiv = $("<div>",{class:"red-ui-diff-list-node-cell red-ui-diff-list-node-local"}).appendTo(row); + var localChanged = false; + var remoteChanged = false; + + if (!localDiff.newConfig.all[tab.id]) { + localNodeDiv.addClass("red-ui-diff-empty"); + } else if (localDiff.added[tab.id]) { + localNodeDiv.addClass("red-ui-diff-status-added"); + localChanged = true; + $('<span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> <span data-i18n="diff.type.added"></span></span>').appendTo(localNodeDiv); + } else if (localDiff.changed[tab.id]) { + localNodeDiv.addClass("red-ui-diff-status-changed"); + localChanged = true; + $('<span class="red-ui-diff-status"><i class="fa fa-square"></i> <span data-i18n="diff.type.changed"></span></span>').appendTo(localNodeDiv); + } else { + localNodeDiv.addClass("red-ui-diff-status-unchanged"); + $('<span class="red-ui-diff-status"><i class="fa fa-square-o"></i> <span data-i18n="diff.type.unchanged"></span></span>').appendTo(localNodeDiv); + } + + var remoteNodeDiv; + if (remoteDiff) { + remoteNodeDiv = $("<div>",{class:"red-ui-diff-list-node-cell red-ui-diff-list-node-remote"}).appendTo(row); + if (!remoteDiff.newConfig.all[tab.id]) { + remoteNodeDiv.addClass("red-ui-diff-empty"); + if (remoteDiff.deleted[tab.id]) { + remoteChanged = true; + } + } else if (remoteDiff.added[tab.id]) { + remoteNodeDiv.addClass("red-ui-diff-status-added"); + remoteChanged = true; + $('<span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> <span data-i18n="diff.type.added"></span></span>').appendTo(remoteNodeDiv); + } else if (remoteDiff.changed[tab.id]) { + remoteNodeDiv.addClass("red-ui-diff-status-changed"); + remoteChanged = true; + $('<span class="red-ui-diff-status"><i class="fa fa-square"></i> <span data-i18n="diff.type.changed"></span></span>').appendTo(remoteNodeDiv); + } else { + remoteNodeDiv.addClass("red-ui-diff-status-unchanged"); + $('<span class="red-ui-diff-status"><i class="fa fa-square-o"></i> <span data-i18n="diff.type.unchanged"></span></span>').appendTo(remoteNodeDiv); + } + } + $('<span class="red-ui-diff-list-chevron"><i class="fa fa-angle-down"></i></span>').appendTo(originalNodeDiv); + $('<span>').text(RED._("diff.flowProperties")).appendTo(originalNodeDiv); + + row.on("click", function(evt) { + evt.preventDefault(); + $(this).parent().toggleClass('collapsed'); + }); + + createNodePropertiesTable(def,tab,localTabNode,remoteTabNode,conflicts).appendTo(div); + selectState = ""; + if (conflicts[tab.id]) { + flowStats.conflicts++; + + if (!localNodeDiv.hasClass("red-ui-diff-empty")) { + $('<span class="red-ui-diff-status-conflict"><span class="red-ui-diff-status"><i class="fa fa-exclamation"></i></span></span>').prependTo(localNodeDiv); + } + if (!remoteNodeDiv.hasClass("red-ui-diff-empty")) { + $('<span class="red-ui-diff-status-conflict"><span class="red-ui-diff-status"><i class="fa fa-exclamation"></i></span></span>').prependTo(remoteNodeDiv); + } + div.addClass("red-ui-diff-list-node-conflict"); + } else { + selectState = CurrentDiff.resolutions[tab.id]; + } + // Tab properties row + createNodeConflictRadioBoxes(tab,div,localNodeDiv,remoteNodeDiv,true,!conflicts[tab.id],selectState,CurrentDiff); + } + } + // var stats = $('<span>',{class:"red-ui-diff-list-flow-stats"}).appendTo(titleRow); + var localNodeCount = 0; + var remoteNodeCount = 0; + var seen = {}; + object.tab.nodes.forEach(function(node) { + seen[node.id] = true; + createNodeDiffRow(node,flowStats,CurrentDiff).appendTo(nodesDiv) + }); + if (object.newTab) { + localNodeCount = object.newTab.nodes.length; + object.newTab.nodes.forEach(function(node) { + if (!seen[node.id]) { + seen[node.id] = true; + createNodeDiffRow(node,flowStats,CurrentDiff).appendTo(nodesDiv) + } + }); + } + if (object.remoteTab) { + remoteNodeCount = object.remoteTab.nodes.length; + object.remoteTab.nodes.forEach(function(node) { + if (!seen[node.id]) { + createNodeDiffRow(node,flowStats,CurrentDiff).appendTo(nodesDiv) + } + }); + } + titleRow.on("click", function(evt) { + // if (titleRow.parent().find(".red-ui-diff-list-node:not(.hide)").length > 0) { + titleRow.parent().toggleClass('collapsed'); + if ($(this).parent().hasClass('collapsed')) { + $(this).parent().find('.red-ui-diff-list-node').addClass('collapsed'); + $(this).parent().find('.red-ui-debug-msg-element').addClass('collapsed'); + } + // } + }) + + if (localDiff.deleted[tab.id]) { + $('<span class="red-ui-diff-status-deleted"><span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> <span data-i18n="diff.type.flowDeleted"></span></span></span>').appendTo(localCell); + } else if (object.newTab) { + if (localDiff.added[tab.id]) { + $('<span class="red-ui-diff-status-added"><span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> <span data-i18n="diff.type.flowAdded"></span></span></span>').appendTo(localCell); + } else { + if (tab.id) { + if (localDiff.changed[tab.id]) { + flowStats.local.changedCount++; + } else { + flowStats.local.unchangedCount++; + } + } + var localStats = $('<span>',{class:"red-ui-diff-list-flow-stats"}).appendTo(localCell); + $('<span class="red-ui-diff-status"></span>').text(RED._('diff.nodeCount',{count:localNodeCount})).appendTo(localStats); + + if (flowStats.conflicts + flowStats.local.addedCount + flowStats.local.changedCount + flowStats.local.deletedCount > 0) { + $('<span class="red-ui-diff-status"> [ </span>').appendTo(localStats); + if (flowStats.conflicts > 0) { + $('<span class="red-ui-diff-status-conflict"><span class="red-ui-diff-status"><i class="fa fa-exclamation"></i> '+flowStats.conflicts+'</span></span>').appendTo(localStats); + } + if (flowStats.local.addedCount > 0) { + $('<span class="red-ui-diff-status-added"><span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> '+flowStats.local.addedCount+'</span></span>').appendTo(localStats); + } + if (flowStats.local.changedCount > 0) { + $('<span class="red-ui-diff-status-changed"><span class="red-ui-diff-status"><i class="fa fa-square"></i> '+flowStats.local.changedCount+'</span></span>').appendTo(localStats); + } + if (flowStats.local.deletedCount > 0) { + $('<span class="red-ui-diff-status-deleted"><span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> '+flowStats.local.deletedCount+'</span></span>').appendTo(localStats); + } + $('<span class="red-ui-diff-status"> ] </span>').appendTo(localStats); + } + + } + } else { + localCell.addClass("red-ui-diff-empty"); + } + + if (remoteDiff) { + if (remoteDiff.deleted[tab.id]) { + $('<span class="red-ui-diff-status-deleted"><span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> <span data-i18n="diff.type.flowDeleted"></span></span></span>').appendTo(remoteCell); + } else if (object.remoteTab) { + if (remoteDiff.added[tab.id]) { + $('<span class="red-ui-diff-status-added"><span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> <span data-i18n="diff.type.flowAdded"></span></span></span>').appendTo(remoteCell); + } else { + if (tab.id) { + if (remoteDiff.changed[tab.id]) { + flowStats.remote.changedCount++; + } else { + flowStats.remote.unchangedCount++; + } + } + var remoteStats = $('<span>',{class:"red-ui-diff-list-flow-stats"}).appendTo(remoteCell); + $('<span class="red-ui-diff-status"></span>').text(RED._('diff.nodeCount',{count:remoteNodeCount})).appendTo(remoteStats); + if (flowStats.conflicts + flowStats.remote.addedCount + flowStats.remote.changedCount + flowStats.remote.deletedCount > 0) { + $('<span class="red-ui-diff-status"> [ </span>').appendTo(remoteStats); + if (flowStats.conflicts > 0) { + $('<span class="red-ui-diff-status-conflict"><span class="red-ui-diff-status"><i class="fa fa-exclamation"></i> '+flowStats.conflicts+'</span></span>').appendTo(remoteStats); + } + if (flowStats.remote.addedCount > 0) { + $('<span class="red-ui-diff-status-added"><span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> '+flowStats.remote.addedCount+'</span></span>').appendTo(remoteStats); + } + if (flowStats.remote.changedCount > 0) { + $('<span class="red-ui-diff-status-changed"><span class="red-ui-diff-status"><i class="fa fa-square"></i> '+flowStats.remote.changedCount+'</span></span>').appendTo(remoteStats); + } + if (flowStats.remote.deletedCount > 0) { + $('<span class="red-ui-diff-status-deleted"><span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> '+flowStats.remote.deletedCount+'</span></span>').appendTo(remoteStats); + } + $('<span class="red-ui-diff-status"> ] </span>').appendTo(remoteStats); + } + } + } else { + remoteCell.addClass("red-ui-diff-empty"); + } + selectState = ""; + if (flowStats.conflicts > 0) { + titleRow.addClass("red-ui-diff-list-node-conflict"); + } else { + selectState = CurrentDiff.resolutions[tab.id]; + } + if (tab.id) { + var hide = !(flowStats.conflicts > 0 &&(localDiff.deleted[tab.id] || remoteDiff.deleted[tab.id])); + // Tab parent row + createNodeConflictRadioBoxes(tab,titleRow,localCell,remoteCell, false, hide, selectState, CurrentDiff); + } + } + + if (tabDiv.find(".red-ui-diff-list-node").length === 0) { + tabDiv.addClass("red-ui-diff-list-flow-empty"); + } + container.i18n(); + } + }); + return diffList; + } + function buildDiffPanel(container,diff,options) { + var diffPanel = $('<div class="red-ui-diff-panel"></div>').appendTo(container); + var diffHeaders = $('<div class="red-ui-diff-panel-headers"></div>').appendTo(diffPanel); + if (options.mode === "merge") { + diffPanel.addClass("red-ui-diff-panel-merge"); + } + var diffList = createDiffTable(diffPanel, diff); + + var localDiff = diff.localDiff; + var remoteDiff = diff.remoteDiff; + var conflicts = diff.conflicts; + + var currentConfig = localDiff.currentConfig; + var newConfig = localDiff.newConfig; + + + if (remoteDiff !== undefined) { + diffPanel.addClass('red-ui-diff-three-way'); + var localTitle = options.oldRevTitle || RED._('diff.local'); + var remoteTitle = options.newRevTitle || RED._('diff.remote'); + $('<div></div>').text(localTitle).appendTo(diffHeaders); + $('<div></div>').text(remoteTitle).appendTo(diffHeaders); + } else { + diffPanel.removeClass('red-ui-diff-three-way'); + } + + return { + list: diffList, + finish: function() { + var el = { + diff: localDiff, + def: { + category: 'config', + color: '#f0f0f0' + }, + tab: { + n: {}, + nodes: currentConfig.globals + }, + newTab: { + n: {}, + nodes: newConfig.globals + } + }; + if (remoteDiff !== undefined) { + el.remoteTab = { + n:{}, + nodes:remoteDiff.newConfig.globals + }; + el.remoteDiff = remoteDiff; + } + diffList.editableList('addItem',el); + + var seenTabs = {}; + + currentConfig.tabOrder.forEach(function(tabId) { + var tab = currentConfig.tabs[tabId]; + var el = { + diff: localDiff, + def: RED.nodes.getType('tab'), + tab:tab + }; + if (newConfig.tabs.hasOwnProperty(tabId)) { + el.newTab = newConfig.tabs[tabId]; + } + if (remoteDiff !== undefined) { + el.remoteTab = remoteDiff.newConfig.tabs[tabId]; + el.remoteDiff = remoteDiff; + } + seenTabs[tabId] = true; + diffList.editableList('addItem',el) + }); + newConfig.tabOrder.forEach(function(tabId) { + if (!seenTabs[tabId]) { + seenTabs[tabId] = true; + var tab = newConfig.tabs[tabId]; + var el = { + diff: localDiff, + def: RED.nodes.getType('tab'), + tab:tab, + newTab: tab + }; + if (remoteDiff !== undefined) { + el.remoteDiff = remoteDiff; + } + diffList.editableList('addItem',el) + } + }); + if (remoteDiff !== undefined) { + remoteDiff.newConfig.tabOrder.forEach(function(tabId) { + if (!seenTabs[tabId]) { + var tab = remoteDiff.newConfig.tabs[tabId]; + // TODO how to recognise this is a remotely added flow + var el = { + diff: localDiff, + remoteDiff: remoteDiff, + def: RED.nodes.getType('tab'), + tab:tab, + remoteTab:tab + }; + diffList.editableList('addItem',el) + } + }); + } + var subflowId; + for (subflowId in currentConfig.subflows) { + if (currentConfig.subflows.hasOwnProperty(subflowId)) { + seenTabs[subflowId] = true; + el = { + diff: localDiff, + def: { + defaults:{}, + icon:"subflow.svg", + category: "subflows", + color: "#DDAA99" + }, + tab:currentConfig.subflows[subflowId] + } + if (newConfig.subflows.hasOwnProperty(subflowId)) { + el.newTab = newConfig.subflows[subflowId]; + } + if (remoteDiff !== undefined) { + el.remoteTab = remoteDiff.newConfig.subflows[subflowId]; + el.remoteDiff = remoteDiff; + } + diffList.editableList('addItem',el) + } + } + for (subflowId in newConfig.subflows) { + if (newConfig.subflows.hasOwnProperty(subflowId) && !seenTabs[subflowId]) { + seenTabs[subflowId] = true; + el = { + diff: localDiff, + def: { + defaults:{}, + icon:"subflow.svg", + category: "subflows", + color: "#DDAA99" + }, + tab:newConfig.subflows[subflowId], + newTab:newConfig.subflows[subflowId] + } + if (remoteDiff !== undefined) { + el.remoteDiff = remoteDiff; + } + diffList.editableList('addItem',el) + } + } + if (remoteDiff !== undefined) { + for (subflowId in remoteDiff.newConfig.subflows) { + if (remoteDiff.newConfig.subflows.hasOwnProperty(subflowId) && !seenTabs[subflowId]) { + el = { + diff: localDiff, + remoteDiff: remoteDiff, + def: { + defaults:{}, + icon:"subflow.svg", + category: "subflows", + color: "#DDAA99" + }, + tab:remoteDiff.newConfig.subflows[subflowId], + remoteTab: remoteDiff.newConfig.subflows[subflowId] + } + diffList.editableList('addItem',el) + } + } + } + } + }; + } + function formatWireProperty(wires,allNodes) { + var result = $("<div>",{class:"red-ui-diff-list-wires"}) + var list = $("<ol></ol>"); + var c = 0; + wires.forEach(function(p,i) { + var port = $("<li>").appendTo(list); + if (p && p.length > 0) { + $("<span>").text(i+1).appendTo(port); + var links = $("<ul>").appendTo(port); + p.forEach(function(d) { + c++; + var entry = $("<li>").appendTo(links); + var node = allNodes[d]; + if (node) { + var def = RED.nodes.getType(node.type)||{}; + createNode(node,def).appendTo(entry); + } else { + entry.text(d); + } + }) + } else { + port.text('none'); + } + }) + if (c === 0) { + result.text("none"); + } else { + list.appendTo(result); + } + return result; + } + function createNodeIcon(node,def) { + var nodeDiv = $("<div>",{class:"red-ui-diff-list-node-icon"}); + var colour = RED.utils.getNodeColor(node.type,def); + var icon_url = RED.utils.getNodeIcon(def,node); + if (node.type === 'tab') { + colour = "#C0DEED"; + } + nodeDiv.css('backgroundColor',colour); + + var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv); + RED.utils.createIconElement(icon_url, iconContainer, false); + + return nodeDiv; + } + function createNode(node,def) { + var nodeTitleDiv = $("<div>",{class:"red-ui-diff-list-node-title"}) + createNodeIcon(node,def).appendTo(nodeTitleDiv); + var nodeLabel = node.label || node.name || node.id; + $('<div>',{class:"red-ui-diff-list-node-description"}).text(nodeLabel).appendTo(nodeTitleDiv); + return nodeTitleDiv; + } + function createNodeDiffRow(node,stats,CurrentDiff) { + var localDiff = CurrentDiff.localDiff; + var remoteDiff = CurrentDiff.remoteDiff; + var conflicted = CurrentDiff.conflicts[node.id]; + + var hasChanges = false; // exists in original and local/remote but with changes + var unChanged = true; // existing in original,local,remote unchanged + var localChanged = false; + + if (localDiff.added[node.id]) { + stats.local.addedCount++; + unChanged = false; + } + if (remoteDiff && remoteDiff.added[node.id]) { + stats.remote.addedCount++; + unChanged = false; + } + if (localDiff.deleted[node.id]) { + stats.local.deletedCount++; + unChanged = false; + } + if (remoteDiff && remoteDiff.deleted[node.id]) { + stats.remote.deletedCount++; + unChanged = false; + } + if (localDiff.changed[node.id]) { + stats.local.changedCount++; + hasChanges = true; + unChanged = false; + } + if (remoteDiff && remoteDiff.changed[node.id]) { + stats.remote.changedCount++; + hasChanges = true; + unChanged = false; + } + // console.log(node.id,localDiff.added[node.id],remoteDiff.added[node.id],localDiff.deleted[node.id],remoteDiff.deleted[node.id],localDiff.changed[node.id],remoteDiff.changed[node.id]) + var def = RED.nodes.getType(node.type); + if (def === undefined) { + if (/^subflow:/.test(node.type)) { + def = { + icon:"subflow.svg", + category: "subflows", + color: "#DDAA99", + defaults:{name:{value:""}} + } + } else { + def = {}; + } + } + var div = $("<div>",{class:"red-ui-diff-list-node collapsed"}); + var row = $("<div>",{class:"red-ui-diff-list-node-header"}).appendTo(div); + + var originalNodeDiv = $("<div>",{class:"red-ui-diff-list-node-cell"}).appendTo(row); + var localNodeDiv = $("<div>",{class:"red-ui-diff-list-node-cell red-ui-diff-list-node-local"}).appendTo(row); + var remoteNodeDiv; + var chevron; + if (remoteDiff) { + remoteNodeDiv = $("<div>",{class:"red-ui-diff-list-node-cell red-ui-diff-list-node-remote"}).appendTo(row); + } + $('<span class="red-ui-diff-list-chevron"><i class="fa fa-angle-down"></i></span>').appendTo(originalNodeDiv); + + if (unChanged) { + stats.local.unchangedCount++; + createNode(node,def).appendTo(originalNodeDiv); + localNodeDiv.addClass("red-ui-diff-status-unchanged"); + $('<span class="red-ui-diff-status"><i class="fa fa-square-o"></i> <span data-i18n="diff.type.unchanged"></span></span>').appendTo(localNodeDiv); + if (remoteDiff) { + stats.remote.unchangedCount++; + remoteNodeDiv.addClass("red-ui-diff-status-unchanged"); + $('<span class="red-ui-diff-status"><i class="fa fa-square-o"></i> <span data-i18n="diff.type.unchanged"></span></span>').appendTo(remoteNodeDiv); + } + div.addClass("red-ui-diff-status-unchanged"); + } else if (localDiff.added[node.id]) { + localNodeDiv.addClass("red-ui-diff-status-added"); + if (remoteNodeDiv) { + remoteNodeDiv.addClass("red-ui-diff-empty"); + } + $('<span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> <span data-i18n="diff.type.added"></span></span>').appendTo(localNodeDiv); + createNode(node,def).appendTo(originalNodeDiv); + } else if (remoteDiff && remoteDiff.added[node.id]) { + localNodeDiv.addClass("red-ui-diff-empty"); + remoteNodeDiv.addClass("red-ui-diff-status-added"); + $('<span class="red-ui-diff-status"><i class="fa fa-plus-square"></i> <span data-i18n="diff.type.added"></span></span>').appendTo(remoteNodeDiv); + createNode(node,def).appendTo(originalNodeDiv); + } else { + createNode(node,def).appendTo(originalNodeDiv); + if (localDiff.moved[node.id]) { + var localN = localDiff.newConfig.all[node.id]; + if (!localDiff.deleted[node.z] && node.z !== localN.z && node.z !== "" && !localDiff.newConfig.all[node.z]) { + localNodeDiv.addClass("red-ui-diff-empty"); + } else { + localNodeDiv.addClass("red-ui-diff-status-moved"); + var localMovedMessage = ""; + if (node.z === localN.z) { + localMovedMessage = RED._("diff.type.movedFrom",{id:(localDiff.currentConfig.all[node.id].z||'global')}); + } else { + localMovedMessage = RED._("diff.type.movedTo",{id:(localN.z||'global')}); + } + $('<span class="red-ui-diff-status"><i class="fa fa-caret-square-o-right"></i> '+localMovedMessage+'</span>').appendTo(localNodeDiv); + } + localChanged = true; + } else if (localDiff.deleted[node.z]) { + localNodeDiv.addClass("red-ui-diff-empty"); + localChanged = true; + } else if (localDiff.deleted[node.id]) { + localNodeDiv.addClass("red-ui-diff-status-deleted"); + $('<span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> <span data-i18n="diff.type.deleted"></span></span>').appendTo(localNodeDiv); + localChanged = true; + } else if (localDiff.changed[node.id]) { + if (localDiff.newConfig.all[node.id].z !== node.z) { + localNodeDiv.addClass("red-ui-diff-empty"); + } else { + localNodeDiv.addClass("red-ui-diff-status-changed"); + $('<span class="red-ui-diff-status"><i class="fa fa-square"></i> <span data-i18n="diff.type.changed"></span></span>').appendTo(localNodeDiv); + localChanged = true; + } + } else { + if (localDiff.newConfig.all[node.id].z !== node.z) { + localNodeDiv.addClass("red-ui-diff-empty"); + } else { + stats.local.unchangedCount++; + localNodeDiv.addClass("red-ui-diff-status-unchanged"); + $('<span class="red-ui-diff-status"><i class="fa fa-square-o"></i> <span data-i18n="diff.type.unchanged"></span></span>').appendTo(localNodeDiv); + } + } + + if (remoteDiff) { + if (remoteDiff.moved[node.id]) { + var remoteN = remoteDiff.newConfig.all[node.id]; + if (!remoteDiff.deleted[node.z] && node.z !== remoteN.z && node.z !== "" && !remoteDiff.newConfig.all[node.z]) { + remoteNodeDiv.addClass("red-ui-diff-empty"); + } else { + remoteNodeDiv.addClass("red-ui-diff-status-moved"); + var remoteMovedMessage = ""; + if (node.z === remoteN.z) { + remoteMovedMessage = RED._("diff.type.movedFrom",{id:(remoteDiff.currentConfig.all[node.id].z||'global')}); + } else { + remoteMovedMessage = RED._("diff.type.movedTo",{id:(remoteN.z||'global')}); + } + $('<span class="red-ui-diff-status"><i class="fa fa-caret-square-o-right"></i> '+remoteMovedMessage+'</span>').appendTo(remoteNodeDiv); + } + } else if (remoteDiff.deleted[node.z]) { + remoteNodeDiv.addClass("red-ui-diff-empty"); + } else if (remoteDiff.deleted[node.id]) { + remoteNodeDiv.addClass("red-ui-diff-status-deleted"); + $('<span class="red-ui-diff-status"><i class="fa fa-minus-square"></i> <span data-i18n="diff.type.deleted"></span></span>').appendTo(remoteNodeDiv); + } else if (remoteDiff.changed[node.id]) { + if (remoteDiff.newConfig.all[node.id].z !== node.z) { + remoteNodeDiv.addClass("red-ui-diff-empty"); + } else { + remoteNodeDiv.addClass("red-ui-diff-status-changed"); + $('<span class="red-ui-diff-status"><i class="fa fa-square"></i> <span data-i18n="diff.type.changed"></span></span>').appendTo(remoteNodeDiv); + } + } else { + if (remoteDiff.newConfig.all[node.id].z !== node.z) { + remoteNodeDiv.addClass("red-ui-diff-empty"); + } else { + stats.remote.unchangedCount++; + remoteNodeDiv.addClass("red-ui-diff-status-unchanged"); + $('<span class="red-ui-diff-status"><i class="fa fa-square-o"></i> <span data-i18n="diff.type.unchanged"></span></span>').appendTo(remoteNodeDiv); + } + } + } + } + var localNode = { + node: localDiff.newConfig.all[node.id], + all: localDiff.newConfig.all, + diff: localDiff + }; + var remoteNode; + if (remoteDiff) { + remoteNode = { + node:remoteDiff.newConfig.all[node.id]||null, + all: remoteDiff.newConfig.all, + diff: remoteDiff + } + } + + var selectState = ""; + + if (conflicted) { + stats.conflicts++; + if (!localNodeDiv.hasClass("red-ui-diff-empty")) { + $('<span class="red-ui-diff-status-conflict"><span class="red-ui-diff-status"><i class="fa fa-exclamation"></i></span></span>').prependTo(localNodeDiv); + } + if (!remoteNodeDiv.hasClass("red-ui-diff-empty")) { + $('<span class="red-ui-diff-status-conflict"><span class="red-ui-diff-status"><i class="fa fa-exclamation"></i></span></span>').prependTo(remoteNodeDiv); + } + div.addClass("red-ui-diff-list-node-conflict"); + } else { + selectState = CurrentDiff.resolutions[node.id]; + } + // Node row + createNodeConflictRadioBoxes(node,div,localNodeDiv,remoteNodeDiv,false,!conflicted,selectState,CurrentDiff); + row.on("click", function(evt) { + $(this).parent().toggleClass('collapsed'); + + if($(this).siblings('.red-ui-diff-list-node-properties').length === 0) { + createNodePropertiesTable(def,node,localNode,remoteNode).appendTo(div); + } + }); + + return div; + } + function createNodePropertiesTable(def,node,localNodeObj,remoteNodeObj) { + var propertyElements = {}; + var localNode = localNodeObj.node; + var remoteNode; + if (remoteNodeObj) { + remoteNode = remoteNodeObj.node; + } + + var nodePropertiesDiv = $("<div>",{class:"red-ui-diff-list-node-properties"}); + var nodePropertiesTable = $("<table>").appendTo(nodePropertiesDiv); + var nodePropertiesTableCols = $('<colgroup><col/><col/></colgroup>').appendTo(nodePropertiesTable); + if (remoteNode !== undefined) { + $("<col/>").appendTo(nodePropertiesTableCols); + } + var nodePropertiesTableBody = $("<tbody>").appendTo(nodePropertiesTable); + + var row; + var localCell, remoteCell; + var element; + var currentValue, localValue, remoteValue; + var localChanged = false; + var remoteChanged = false; + var localChanges = 0; + var remoteChanges = 0; + var conflict = false; + var status; + + row = $("<tr>").appendTo(nodePropertiesTableBody); + $("<td>",{class:"red-ui-diff-list-cell-label"}).text("id").appendTo(row); + localCell = $("<td>",{class:"red-ui-diff-list-cell red-ui-diff-list-node-local"}).appendTo(row); + if (localNode) { + localCell.addClass("red-ui-diff-status-unchanged"); + $('<span class="red-ui-diff-status"></span>').appendTo(localCell); + element = $('<span class="red-ui-diff-list-element"></span>').appendTo(localCell); + propertyElements['local.id'] = RED.utils.createObjectElement(localNode.id).appendTo(element); + } else { + localCell.addClass("red-ui-diff-empty"); + } + if (remoteNode !== undefined) { + remoteCell = $("<td>",{class:"red-ui-diff-list-cell red-ui-diff-list-node-remote"}).appendTo(row); + remoteCell.addClass("red-ui-diff-status-unchanged"); + if (remoteNode) { + $('<span class="red-ui-diff-status"></span>').appendTo(remoteCell); + element = $('<span class="red-ui-diff-list-element"></span>').appendTo(remoteCell); + propertyElements['remote.id'] = RED.utils.createObjectElement(remoteNode.id).appendTo(element); + } else { + remoteCell.addClass("red-ui-diff-empty"); + } + } + + + if (node.hasOwnProperty('x')) { + if (localNode) { + if (localNode.x !== node.x || localNode.y !== node.y) { + localChanged = true; + localChanges++; + } + } + if (remoteNode) { + if (remoteNode.x !== node.x || remoteNode.y !== node.y) { + remoteChanged = true; + remoteChanges++; + } + } + if ( (remoteChanged && localChanged && (localNode.x !== remoteNode.x || localNode.y !== remoteNode.y)) || + (!localChanged && remoteChanged && localNodeObj.diff.deleted[node.id]) || + (localChanged && !remoteChanged && remoteNodeObj.diff.deleted[node.id]) + ) { + conflict = true; + } + row = $("<tr>").appendTo(nodePropertiesTableBody); + $("<td>",{class:"red-ui-diff-list-cell-label"}).text("position").appendTo(row); + localCell = $("<td>",{class:"red-ui-diff-list-cell red-ui-diff-list-node-local"}).appendTo(row); + if (localNode) { + localCell.addClass("red-ui-diff-status-"+(localChanged?"changed":"unchanged")); + $('<span class="red-ui-diff-status">'+(localChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(localCell); + element = $('<span class="red-ui-diff-list-element"></span>').appendTo(localCell); + propertyElements['local.position'] = RED.utils.createObjectElement({x:localNode.x,y:localNode.y}, + { + path: "position", + exposeApi: true, + ontoggle: function(path,state) { + if (propertyElements['remote.'+path]) { + propertyElements['remote.'+path].prop('expand')(path,state) + } + } + } + ).appendTo(element); + } else { + localCell.addClass("red-ui-diff-empty"); + } + + if (remoteNode !== undefined) { + remoteCell = $("<td>",{class:"red-ui-diff-list-cell red-ui-diff-list-node-remote"}).appendTo(row); + remoteCell.addClass("red-ui-diff-status-"+(remoteChanged?"changed":"unchanged")); + if (remoteNode) { + $('<span class="red-ui-diff-status">'+(remoteChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(remoteCell); + element = $('<span class="red-ui-diff-list-element"></span>').appendTo(remoteCell); + propertyElements['remote.position'] = RED.utils.createObjectElement({x:remoteNode.x,y:remoteNode.y}, + { + path: "position", + exposeApi: true, + ontoggle: function(path,state) { + if (propertyElements['local.'+path]) { + propertyElements['local.'+path].prop('expand')(path,state); + } + } + } + ).appendTo(element); + } else { + remoteCell.addClass("red-ui-diff-empty"); + } + } + } + // + localChanged = remoteChanged = conflict = false; + if (node.hasOwnProperty('wires')) { + currentValue = JSON.stringify(node.wires); + if (localNode) { + localValue = JSON.stringify(localNode.wires); + if (currentValue !== localValue) { + localChanged = true; + localChanges++; + } + } + if (remoteNode) { + remoteValue = JSON.stringify(remoteNode.wires); + if (currentValue !== remoteValue) { + remoteChanged = true; + remoteChanges++; + } + } + if ( (remoteChanged && localChanged && (localValue !== remoteValue)) || + (!localChanged && remoteChanged && localNodeObj.diff.deleted[node.id]) || + (localChanged && !remoteChanged && remoteNodeObj.diff.deleted[node.id]) + ){ + conflict = true; + } + row = $("<tr>").appendTo(nodePropertiesTableBody); + $("<td>",{class:"red-ui-diff-list-cell-label"}).text("wires").appendTo(row); + localCell = $("<td>",{class:"red-ui-diff-list-cell red-ui-diff-list-node-local"}).appendTo(row); + if (localNode) { + if (!conflict) { + localCell.addClass("red-ui-diff-status-"+(localChanged?"changed":"unchanged")); + $('<span class="red-ui-diff-status">'+(localChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(localCell); + } else { + localCell.addClass("red-ui-diff-status-conflict"); + $('<span class="red-ui-diff-status"><i class="fa fa-exclamation"></i></span>').appendTo(localCell); + } + formatWireProperty(localNode.wires,localNodeObj.all).appendTo(localCell); + } else { + localCell.addClass("red-ui-diff-empty"); + } + + if (remoteNode !== undefined) { + remoteCell = $("<td>",{class:"red-ui-diff-list-cell red-ui-diff-list-node-remote"}).appendTo(row); + if (remoteNode) { + if (!conflict) { + remoteCell.addClass("red-ui-diff-status-"+(remoteChanged?"changed":"unchanged")); + $('<span class="red-ui-diff-status">'+(remoteChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(remoteCell); + } else { + remoteCell.addClass("red-ui-diff-status-conflict"); + $('<span class="red-ui-diff-status"><i class="fa fa-exclamation"></i></span>').appendTo(remoteCell); + } + formatWireProperty(remoteNode.wires,remoteNodeObj.all).appendTo(remoteCell); + } else { + remoteCell.addClass("red-ui-diff-empty"); + } + } + } + var properties = Object.keys(node).filter(function(p) { return p!='inputLabels'&&p!='outputLabels'&&p!='z'&&p!='wires'&&p!=='x'&&p!=='y'&&p!=='id'&&p!=='type'&&(!def.defaults||!def.defaults.hasOwnProperty(p))}); + if (def.defaults) { + properties = properties.concat(Object.keys(def.defaults)); + } + if (node.type !== 'tab') { + properties = properties.concat(['inputLabels','outputLabels']); + } + if ( ((localNode && localNode.hasOwnProperty('icon')) || (remoteNode && remoteNode.hasOwnProperty('icon'))) && + properties.indexOf('icon') === -1 + ) { + properties.unshift('icon'); + } + + + properties.forEach(function(d) { + localChanged = false; + remoteChanged = false; + conflict = false; + currentValue = JSON.stringify(node[d]); + if (localNode) { + localValue = JSON.stringify(localNode[d]); + if (currentValue !== localValue) { + localChanged = true; + localChanges++; + } + } + if (remoteNode) { + remoteValue = JSON.stringify(remoteNode[d]); + if (currentValue !== remoteValue) { + remoteChanged = true; + remoteChanges++; + } + } + + if ( (remoteChanged && localChanged && (localValue !== remoteValue)) || + (!localChanged && remoteChanged && localNodeObj.diff.deleted[node.id]) || + (localChanged && !remoteChanged && remoteNodeObj.diff.deleted[node.id]) + ){ + conflict = true; + } + + row = $("<tr>").appendTo(nodePropertiesTableBody); + var propertyNameCell = $("<td>",{class:"red-ui-diff-list-cell-label"}).text(d).appendTo(row); + localCell = $("<td>",{class:"red-ui-diff-list-cell red-ui-diff-list-node-local"}).appendTo(row); + if (localNode) { + if (!conflict) { + localCell.addClass("red-ui-diff-status-"+(localChanged?"changed":"unchanged")); + $('<span class="red-ui-diff-status">'+(localChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(localCell); + } else { + localCell.addClass("red-ui-diff-status-conflict"); + $('<span class="red-ui-diff-status"><i class="fa fa-exclamation"></i></span>').appendTo(localCell); + } + element = $('<span class="red-ui-diff-list-element"></span>').appendTo(localCell); + propertyElements['local.'+d] = RED.utils.createObjectElement(localNode[d], + { + path: d, + exposeApi: true, + ontoggle: function(path,state) { + if (propertyElements['remote.'+d]) { + propertyElements['remote.'+d].prop('expand')(path,state) + } + } + } + ).appendTo(element); + } else { + localCell.addClass("red-ui-diff-empty"); + } + if (remoteNode !== undefined) { + remoteCell = $("<td>",{class:"red-ui-diff-list-cell red-ui-diff-list-node-remote"}).appendTo(row); + if (remoteNode) { + if (!conflict) { + remoteCell.addClass("red-ui-diff-status-"+(remoteChanged?"changed":"unchanged")); + $('<span class="red-ui-diff-status">'+(remoteChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(remoteCell); + } else { + remoteCell.addClass("red-ui-diff-status-conflict"); + $('<span class="red-ui-diff-status"><i class="fa fa-exclamation"></i></span>').appendTo(remoteCell); + } + element = $('<span class="red-ui-diff-list-element"></span>').appendTo(remoteCell); + propertyElements['remote.'+d] = RED.utils.createObjectElement(remoteNode[d], + { + path: d, + exposeApi: true, + ontoggle: function(path,state) { + if (propertyElements['local.'+d]) { + propertyElements['local.'+d].prop('expand')(path,state) + } + } + } + ).appendTo(element); + } else { + remoteCell.addClass("red-ui-diff-empty"); + } + } + if (localNode && remoteNode && typeof localNode[d] === "string") { + if (/\n/.test(localNode[d]) || /\n/.test(remoteNode[d])) { + $('<button class="red-ui-button red-ui-button-small red-ui-diff-text-diff-button"><i class="fa fa-file-o"> <i class="fa fa-caret-left"></i> <i class="fa fa-caret-right"></i> <i class="fa fa-file-o"></i></button>').on("click", function() { + showTextDiff(localNode[d],remoteNode[d]); + }).appendTo(propertyNameCell); + } + } + + + }); + return nodePropertiesDiv; + } + function createNodeConflictRadioBoxes(node,row,localDiv,remoteDiv,propertiesTable,hide,state,diff) { + var safeNodeId = "red-ui-diff-selectbox-"+node.id.replace(/\./g,'-')+(propertiesTable?"-props":""); + var className = ""; + if (node.z||propertiesTable) { + className = "red-ui-diff-selectbox-tab-"+(propertiesTable?node.id:node.z).replace(/\./g,'-'); + } + var titleRow = !propertiesTable && (node.type === 'tab' || node.type === 'subflow'); + var changeHandler = function(evt) { + var className; + if (node.type === undefined) { + // TODO: handle globals + } else if (titleRow) { + className = "red-ui-diff-selectbox-tab-"+node.id.replace(/\./g,'-'); + $("."+className+"-"+this.value).prop('checked',true); + if (this.value === 'local') { + $("."+className+"-"+this.value).closest(".red-ui-diff-list-node").addClass("red-ui-diff-select-local"); + $("."+className+"-"+this.value).closest(".red-ui-diff-list-node").removeClass("red-ui-diff-select-remote"); + } else { + $("."+className+"-"+this.value).closest(".red-ui-diff-list-node").removeClass("red-ui-diff-select-local"); + $("."+className+"-"+this.value).closest(".red-ui-diff-list-node").addClass("red-ui-diff-select-remote"); + } + } else { + // Individual node or properties table + var parentId = "red-ui-diff-selectbox-"+(propertiesTable?node.id:node.z).replace(/\./g,'-'); + $('#'+parentId+"-local").prop('checked',false); + $('#'+parentId+"-remote").prop('checked',false); + var titleRowDiv = $('#'+parentId+"-local").closest(".red-ui-diff-list-flow").find(".red-ui-diff-list-flow-title"); + titleRowDiv.removeClass("red-ui-diff-select-local"); + titleRowDiv.removeClass("red-ui-diff-select-remote"); + } + if (this.value === 'local') { + row.removeClass("red-ui-diff-select-remote"); + row.addClass("red-ui-diff-select-local"); + } else if (this.value === 'remote') { + row.addClass("red-ui-diff-select-remote"); + row.removeClass("red-ui-diff-select-local"); + } + refreshConflictHeader(diff); + } + + var localSelectDiv = $('<label>',{class:"red-ui-diff-selectbox",for:safeNodeId+"-local"}).on("click", function(e) { e.stopPropagation();}).appendTo(localDiv); + var localRadio = $('<input>',{class:"red-ui-diff-selectbox-input "+className+"-local",id:safeNodeId+"-local",type:'radio',value:"local",name:safeNodeId}).data('node-id',node.id).on("change", changeHandler).appendTo(localSelectDiv); + var remoteSelectDiv = $('<label>',{class:"red-ui-diff-selectbox",for:safeNodeId+"-remote"}).on("click", function(e) { e.stopPropagation();}).appendTo(remoteDiv); + var remoteRadio = $('<input>',{class:"red-ui-diff-selectbox-input "+className+"-remote",id:safeNodeId+"-remote",type:'radio',value:"remote",name:safeNodeId}).data('node-id',node.id).on("change", changeHandler).appendTo(remoteSelectDiv); + if (state === 'local') { + localRadio.prop('checked',true); + } else if (state === 'remote') { + remoteRadio.prop('checked',true); + } + if (hide||localDiv.hasClass("red-ui-diff-empty") || remoteDiv.hasClass("red-ui-diff-empty")) { + localSelectDiv.hide(); + remoteSelectDiv.hide(); + } + + } + function refreshConflictHeader(currentDiff) { + var resolutionCount = 0; + $(".red-ui-diff-selectbox>input:checked").each(function() { + if (currentDiff.conflicts[$(this).data('node-id')]) { + resolutionCount++; + } + currentDiff.resolutions[$(this).data('node-id')] = $(this).val(); + }) + var conflictCount = Object.keys(currentDiff.conflicts).length; + if (conflictCount - resolutionCount === 0) { + $("#red-ui-diff-dialog-toolbar-resolved-conflicts").html('<span class="red-ui-diff-status-added"><span class="red-ui-diff-status"><i class="fa fa-check"></i></span></span> '+RED._("diff.unresolvedCount",{count:conflictCount - resolutionCount})); + } else { + $("#red-ui-diff-dialog-toolbar-resolved-conflicts").html('<span class="red-ui-diff-status-conflict"><span class="red-ui-diff-status"><i class="fa fa-exclamation"></i></span></span> '+RED._("diff.unresolvedCount",{count:conflictCount - resolutionCount})); + } + if (conflictCount === resolutionCount) { + $("#red-ui-diff-view-diff-merge").removeClass('disabled'); + $("#red-ui-diff-view-resolve-diff").removeClass('disabled'); + } + } + function getRemoteDiff(callback) { + $.ajax({ + headers: { + "Accept":"application/json", + }, + cache: false, + url: 'flows', + success: function(nodes) { + var localFlow = RED.nodes.createCompleteNodeSet(); + var originalFlow = RED.nodes.originalFlow(); + var remoteFlow = nodes.flows; + var localDiff = generateDiff(originalFlow,localFlow); + var remoteDiff = generateDiff(originalFlow,remoteFlow); + remoteDiff.rev = nodes.rev; + callback(resolveDiffs(localDiff,remoteDiff)) + } + }); + + } + // function showLocalDiff() { + // var nns = RED.nodes.createCompleteNodeSet(); + // var originalFlow = RED.nodes.originalFlow(); + // var diff = generateDiff(originalFlow,nns); + // showDiff(diff); + // } + function showRemoteDiff(diff) { + if (diff === undefined) { + getRemoteDiff(showRemoteDiff); + } else { + showDiff(diff,{mode:'merge'}); + } + } + function parseNodes(nodeList) { + var tabOrder = []; + var tabs = {}; + var subflows = {}; + var globals = []; + var all = {}; + + nodeList.forEach(function(node) { + all[node.id] = node; + if (node.type === 'tab') { + tabOrder.push(node.id); + tabs[node.id] = {n:node,nodes:[]}; + } else if (node.type === 'subflow') { + subflows[node.id] = {n:node,nodes:[]}; + } + }); + + nodeList.forEach(function(node) { + if (node.type !== 'tab' && node.type !== 'subflow') { + if (tabs[node.z]) { + tabs[node.z].nodes.push(node); + } else if (subflows[node.z]) { + subflows[node.z].nodes.push(node); + } else { + globals.push(node); + } + } + }); + + return { + all: all, + tabOrder: tabOrder, + tabs: tabs, + subflows: subflows, + globals: globals + } + } + function generateDiff(currentNodes,newNodes) { + var currentConfig = parseNodes(currentNodes); + var newConfig = parseNodes(newNodes); + var added = {}; + var deleted = {}; + var changed = {}; + var moved = {}; + + Object.keys(currentConfig.all).forEach(function(id) { + var node = RED.nodes.workspace(id)||RED.nodes.subflow(id)||RED.nodes.node(id); + if (!newConfig.all.hasOwnProperty(id)) { + deleted[id] = true; + } else if (JSON.stringify(currentConfig.all[id]) !== JSON.stringify(newConfig.all[id])) { + changed[id] = true; + + if (currentConfig.all[id].z !== newConfig.all[id].z) { + moved[id] = true; + } + } + }); + Object.keys(newConfig.all).forEach(function(id) { + if (!currentConfig.all.hasOwnProperty(id)) { + added[id] = true; + } + }); + + var diff = { + currentConfig: currentConfig, + newConfig: newConfig, + added: added, + deleted: deleted, + changed: changed, + moved: moved + }; + return diff; + } + function resolveDiffs(localDiff,remoteDiff) { + var conflicted = {}; + var resolutions = {}; + var diff = { + localDiff: localDiff, + remoteDiff: remoteDiff, + conflicts: conflicted, + resolutions: resolutions + } + var seen = {}; + var id,node; + for (id in localDiff.currentConfig.all) { + if (localDiff.currentConfig.all.hasOwnProperty(id)) { + seen[id] = true; + var localNode = localDiff.newConfig.all[id]; + if (localDiff.changed[id] && remoteDiff.deleted[id]) { + conflicted[id] = true; + } else if (localDiff.deleted[id] && remoteDiff.changed[id]) { + conflicted[id] = true; + } else if (localDiff.changed[id] && remoteDiff.changed[id]) { + var remoteNode = remoteDiff.newConfig.all[id]; + if (JSON.stringify(localNode) !== JSON.stringify(remoteNode)) { + conflicted[id] = true; + } + } + if (!conflicted[id]) { + if (remoteDiff.added[id]||remoteDiff.changed[id]||remoteDiff.deleted[id]) { + resolutions[id] = 'remote'; + } else { + resolutions[id] = 'local'; + } + } + } + } + for (id in localDiff.added) { + if (localDiff.added.hasOwnProperty(id)) { + node = localDiff.newConfig.all[id]; + if (remoteDiff.deleted[node.z]) { + conflicted[id] = true; + // conflicted[node.z] = true; + } else { + resolutions[id] = 'local'; + } + } + } + for (id in remoteDiff.added) { + if (remoteDiff.added.hasOwnProperty(id)) { + node = remoteDiff.newConfig.all[id]; + if (localDiff.deleted[node.z]) { + conflicted[id] = true; + // conflicted[node.z] = true; + } else { + resolutions[id] = 'remote'; + } + } + } + // console.log(diff.resolutions); + // console.log(conflicted); + return diff; + } + + function showDiff(diff,options) { + if (diffVisible) { + return; + } + options = options || {}; + var mode = options.mode || 'merge'; + + var localDiff = diff.localDiff; + var remoteDiff = diff.remoteDiff; + var conflicts = diff.conflicts; + // currentDiff = diff; + + var trayOptions = { + title: options.title||RED._("diff.reviewChanges"), + width: Infinity, + overlay: true, + buttons: [ + { + text: RED._((options.mode === 'merge')?"common.label.cancel":"common.label.close"), + click: function() { + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + // trayWidth = dimensions.width; + }, + open: function(tray) { + var trayBody = tray.find('.red-ui-tray-body'); + var toolbar = $('<div class="red-ui-diff-dialog-toolbar">'+ + '<span><span id="red-ui-diff-dialog-toolbar-resolved-conflicts"></span></span> '+ + '</div>').prependTo(trayBody); + var diffContainer = $('<div class="red-ui-diff-container"></div>').appendTo(trayBody); + var diffTable = buildDiffPanel(diffContainer,diff,options); + diffTable.list.hide(); + if (remoteDiff) { + $("#red-ui-diff-view-diff-merge").show(); + if (Object.keys(conflicts).length === 0) { + $("#red-ui-diff-view-diff-merge").removeClass('disabled'); + } else { + $("#red-ui-diff-view-diff-merge").addClass('disabled'); + } + } else { + $("#red-ui-diff-view-diff-merge").hide(); + } + refreshConflictHeader(diff); + // console.log("--------------"); + // console.log(localDiff); + // console.log(remoteDiff); + + setTimeout(function() { + diffTable.finish(); + diffTable.list.show(); + },300); + $("#red-ui-sidebar-shade").show(); + }, + close: function() { + diffVisible = false; + $("#red-ui-sidebar-shade").hide(); + + }, + show: function() { + + } + } + if (options.mode === 'merge') { + trayOptions.buttons.push( + { + id: "red-ui-diff-view-diff-merge", + text: RED._("deploy.confirm.button.merge"), + class: "primary disabled", + click: function() { + if (!$("#red-ui-diff-view-diff-merge").hasClass('disabled')) { + refreshConflictHeader(diff); + mergeDiff(diff); + RED.tray.close(); + } + } + } + ); + } + + RED.tray.show(trayOptions); + } + + function applyDiff(diff) { + var currentConfig = diff.localDiff.currentConfig; + var localDiff = diff.localDiff; + var remoteDiff = diff.remoteDiff; + var conflicts = diff.conflicts; + var resolutions = diff.resolutions; + var id; + + for (id in conflicts) { + if (conflicts.hasOwnProperty(id)) { + if (!resolutions.hasOwnProperty(id)) { + console.log(diff); + throw new Error("No resolution for conflict on node",id); + } + } + } + + var newConfig = []; + var node; + var nodeChangedStates = {}; + var localChangedStates = {}; + for (id in localDiff.newConfig.all) { + if (localDiff.newConfig.all.hasOwnProperty(id)) { + node = RED.nodes.node(id); + if (resolutions[id] === 'local') { + if (node) { + nodeChangedStates[id] = node.changed; + } + newConfig.push(localDiff.newConfig.all[id]); + } else if (resolutions[id] === 'remote') { + if (!remoteDiff.deleted[id] && remoteDiff.newConfig.all.hasOwnProperty(id)) { + if (node) { + nodeChangedStates[id] = node.changed; + } + localChangedStates[id] = 1; + newConfig.push(remoteDiff.newConfig.all[id]); + } + } else { + console.log("Unresolved",id) + } + } + } + for (id in remoteDiff.added) { + if (remoteDiff.added.hasOwnProperty(id)) { + node = RED.nodes.node(id); + if (node) { + nodeChangedStates[id] = node.changed; + } + if (!localDiff.added.hasOwnProperty(id)) { + localChangedStates[id] = 2; + newConfig.push(remoteDiff.newConfig.all[id]); + } + } + } + return { + config: newConfig, + nodeChangedStates: nodeChangedStates, + localChangedStates: localChangedStates + } + } + + function mergeDiff(diff) { + //console.log(diff); + var appliedDiff = applyDiff(diff); + + var newConfig = appliedDiff.config; + var nodeChangedStates = appliedDiff.nodeChangedStates; + var localChangedStates = appliedDiff.localChangedStates; + + var isDirty = RED.nodes.dirty(); + + var historyEvent = { + t:"replace", + config: RED.nodes.createCompleteNodeSet(), + changed: nodeChangedStates, + dirty: isDirty, + rev: RED.nodes.version() + } + + RED.history.push(historyEvent); + + var originalFlow = RED.nodes.originalFlow(); + // originalFlow is what the editor things it loaded + // - add any newly added nodes from remote diff as they are now part of the record + for (var id in diff.remoteDiff.added) { + if (diff.remoteDiff.added.hasOwnProperty(id)) { + if (diff.remoteDiff.newConfig.all.hasOwnProperty(id)) { + originalFlow.push(JSON.parse(JSON.stringify(diff.remoteDiff.newConfig.all[id]))); + } + } + } + + RED.nodes.clear(); + var imported = RED.nodes.import(newConfig); + + // Restore the original flow so subsequent merge resolutions can properly + // identify new-vs-old + RED.nodes.originalFlow(originalFlow); + imported[0].forEach(function(n) { + if (nodeChangedStates[n.id] || localChangedStates[n.id]) { + n.changed = true; + } + }) + + RED.nodes.version(diff.remoteDiff.rev); + + if (isDirty) { + RED.nodes.dirty(true); + } + + RED.view.redraw(true); + RED.palette.refresh(); + RED.workspaces.refresh(); + RED.sidebar.config.refresh(); + } + + function showTestFlowDiff(index) { + if (index === 1) { + var localFlow = RED.nodes.createCompleteNodeSet(); + var originalFlow = RED.nodes.originalFlow(); + showTextDiff(JSON.stringify(localFlow,null,4),JSON.stringify(originalFlow,null,4)) + } else if (index === 2) { + var local = "1\n2\n3\n4\n5\nA\n6\n7\n8\n9\n"; + var remote = "1\nA\n2\n3\nD\nE\n6\n7\n8\n9\n"; + showTextDiff(local,remote); + } else if (index === 3) { + var local = "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22"; + var remote = "1\nTWO\nTHREE\nEXTRA\n4\n5\n6\n7\n8\n9\n10\n11\n12\nTHIRTEEN\n14\n15\n16\n17\n18\n19\n20\n21\n22"; + showTextDiff(local,remote); + } + } + + function showTextDiff(textA,textB) { + var trayOptions = { + title: RED._("diff.compareChanges"), + width: Infinity, + overlay: true, + buttons: [ + { + text: RED._("common.label.close"), + click: function() { + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + // trayWidth = dimensions.width; + }, + open: function(tray) { + var trayBody = tray.find('.red-ui-tray-body'); + var diffPanel = $('<div class="red-ui-diff-text"></div>').appendTo(trayBody); + + var codeTable = $("<table>",{class:"red-ui-diff-text-content"}).appendTo(diffPanel); + $('<colgroup><col width="50"><col width="50%"><col width="50"><col width="50%"></colgroup>').appendTo(codeTable); + var codeBody = $('<tbody>').appendTo(codeTable); + var diffSummary = diffText(textA||"",textB||""); + var aIndex = 0; + var bIndex = 0; + var diffLength = Math.max(diffSummary.a.length, diffSummary.b.length); + + var diffLines = []; + var diffBlocks = []; + var currentBlock; + var blockLength = 0; + var blockType = 0; + + for (var i=0;i<diffLength;i++) { + var diffLine = diffSummary[i]; + var Adiff = (aIndex < diffSummary.a.length)?diffSummary.a[aIndex]:{type:2,line:""}; + var Bdiff = (bIndex < diffSummary.b.length)?diffSummary.b[bIndex]:{type:2,line:""}; + if (Adiff.type === 0 && Bdiff.type !== 0) { + Adiff = {type:2,line:""}; + bIndex++; + } else if (Bdiff.type === 0 && Adiff.type !== 0) { + Bdiff = {type:2,line:""}; + aIndex++; + } else { + aIndex++; + bIndex++; + } + diffLines.push({ + a: Adiff, + b: Bdiff + }); + if (currentBlock === undefined) { + currentBlock = {start:i,end:i}; + blockLength = 0; + blockType = (Adiff.type === 0 && Bdiff.type === 0)?0:1; + } else { + if (Adiff.type === 0 && Bdiff.type === 0) { + // Unchanged line + if (blockType === 0) { + // still unchanged - extend the block + currentBlock.end = i; + blockLength++; + } else if (blockType === 1) { + // end of a change + currentBlock.end = i; + blockType = 2; + blockLength = 0; + } else if (blockType === 2) { + // post-change unchanged + currentBlock.end = i; + blockLength++; + if (blockLength === 8) { + currentBlock.end -= 5; // rollback the end + diffBlocks.push(currentBlock); + currentBlock = {start:i-5,end:i-5}; + blockType = 0; + blockLength = 0; + } + } + } else { + // in a change + currentBlock.end = i; + blockLength++; + if (blockType === 0) { + if (currentBlock.end > 3) { + currentBlock.end -= 3; + currentBlock.empty = true; + diffBlocks.push(currentBlock); + currentBlock = {start:i-3,end:i-3}; + } + blockType = 1; + } else if (blockType === 2) { + // we were in unchanged, but hit a change again + blockType = 1; + } + } + } + } + if (blockType === 0) { + currentBlock.empty = true; + } + currentBlock.end = diffLength; + diffBlocks.push(currentBlock); + console.table(diffBlocks); + var diffRow; + for (var b = 0; b<diffBlocks.length; b++) { + currentBlock = diffBlocks[b]; + if (currentBlock.empty) { + diffRow = createExpandLine(currentBlock.start,currentBlock.end,diffLines).appendTo(codeBody); + } else { + for (var i=currentBlock.start;i<currentBlock.end;i++) { + var row = createDiffLine(diffLines[i]).appendTo(codeBody); + if (i === currentBlock.start) { + row.addClass("start-block"); + } else if (i === currentBlock.end-1) { + row.addClass("end-block"); + } + } + } + } + + }, + close: function() { + diffVisible = false; + + }, + show: function() { + + } + } + RED.tray.show(trayOptions); + } + + function createExpandLine(start,end,diffLines) { + diffRow = $('<tr class="red-ui-diff-text-header red-ui-diff-text-expand">'); + var content = $('<td colspan="4"> <i class="fa fa-arrows-v"></i> </td>').appendTo(diffRow); + var label = $('<span></span>').appendTo(content); + if (end < diffLines.length-1) { + label.text("@@ -"+(diffLines[end-1].a.i+1)+" +"+(diffLines[end-1].b.i+1)); + } + diffRow.on("click", function(evt) { + // console.log(start,end,diffLines.length); + if (end - start > 20) { + var startPos = $(this).offset(); + // console.log(startPos); + if (start > 0) { + for (var i=start;i<start+10;i++) { + createDiffLine(diffLines[i]).addClass("unchanged").insertBefore($(this)); + } + start += 10; + } + if (end < diffLines.length-1) { + for (var i=end-1;i>end-11;i--) { + createDiffLine(diffLines[i]).addClass("unchanged").insertAfter($(this)); + } + end -= 10; + } + if (end < diffLines.length-1) { + label.text("@@ -"+(diffLines[end-1].a.i+1)+" +"+(diffLines[end-1].b.i+1)); + } + var endPos = $(this).offset(); + var delta = endPos.top - startPos.top; + $(".red-ui-diff-text").scrollTop($(".red-ui-diff-text").scrollTop() + delta); + } else { + for (var i=start;i<end;i++) { + createDiffLine(diffLines[i]).addClass("unchanged").insertBefore($(this)); + } + $(this).remove(); + } + }); + return diffRow; + } + + function createDiffLine(diffLine) { + var diffRow = $('<tr>'); + var Adiff = diffLine.a; + var Bdiff = diffLine.b; + //console.log(diffLine); + var cellNo = $('<td class="lineno">').text(Adiff.type === 2?"":Adiff.i).appendTo(diffRow); + var cellLine = $('<td class="linetext">').text(Adiff.line).appendTo(diffRow); + if (Adiff.type === 2) { + cellNo.addClass('blank'); + cellLine.addClass('blank'); + } else if (Adiff.type === 4) { + cellNo.addClass('added'); + cellLine.addClass('added'); + } else if (Adiff.type === 1) { + cellNo.addClass('removed'); + cellLine.addClass('removed'); + } + cellNo = $('<td class="lineno">').text(Bdiff.type === 2?"":Bdiff.i).appendTo(diffRow); + cellLine = $('<td class="linetext">').text(Bdiff.line).appendTo(diffRow); + if (Bdiff.type === 2) { + cellNo.addClass('blank'); + cellLine.addClass('blank'); + } else if (Bdiff.type === 4) { + cellNo.addClass('added'); + cellLine.addClass('added'); + } else if (Bdiff.type === 1) { + cellNo.addClass('removed'); + cellLine.addClass('removed'); + } + return diffRow; + } + + function diffText(string1, string2,ignoreWhitespace) { + var lines1 = string1.split(/\r?\n/); + var lines2 = string2.split(/\r?\n/); + var i = lines1.length; + var j = lines2.length; + var k; + var m; + var diffSummary = {a:[],b:[]}; + var diffMap = []; + for (k = 0; k < i + 1; k++) { + diffMap[k] = []; + for (m = 0; m < j + 1; m++) { + diffMap[k][m] = 0; + } + } + var c = 0; + for (k = i - 1; k >= 0; k--) { + for (m = j - 1; m >=0; m--) { + c++; + if (compareLines(lines1[k],lines2[m],ignoreWhitespace) !== 1) { + diffMap[k][m] = diffMap[k+1][m+1]+1; + } else { + diffMap[k][m] = Math.max(diffMap[(k + 1)][m], diffMap[k][(m + 1)]); + } + } + } + //console.log(c); + k = 0; + m = 0; + + while ((k < i) && (m < j)) { + var n = compareLines(lines1[k],lines2[m],ignoreWhitespace); + if (n !== 1) { + var d = 0; + if (n===0) { + d = 0; + } else if (n==2) { + d = 3; + } + diffSummary.a.push({i:k+1,j:m+1,line:lines1[k],type:d}); + diffSummary.b.push({i:m+1,j:k+1,line:lines2[m],type:d}); + k++; + m++; + } else if (diffMap[(k + 1)][m] >= diffMap[k][(m + 1)]) { + diffSummary.a.push({i:k+1,line:lines1[k],type:1}); + k++; + } else { + diffSummary.b.push({i:m+1,line:lines2[m],type:4}); + m++; + } + } + while ((k < i) || (m < j)) { + if (k == i) { + diffSummary.b.push({i:m+1,line:lines2[m],type:4}); + m++; + } else if (m == j) { + diffSummary.a.push({i:k+1,line:lines1[k],type:1}); + k++; + } + } + return diffSummary; + } + + function compareLines(string1, string2, ignoreWhitespace) { + if (ignoreWhitespace) { + if (string1 === string2) { + return 0; + } + return string1.trim() === string2.trime() ? 2 : 1; + } + return string1 === string2 ? 0 : 1; + } + + function createUnifiedDiffTable(files,commitOptions) { + var diffPanel = $('<div></div>'); + files.forEach(function(file) { + var hunks = file.hunks; + var isBinary = file.binary; + var codeTable = $("<table>",{class:"red-ui-diff-text-content"}).appendTo(diffPanel); + $('<colgroup><col width="50"><col width="50"><col width="100%"></colgroup>').appendTo(codeTable); + var codeBody = $('<tbody>').appendTo(codeTable); + + var diffFileRow = $('<tr class="red-ui-diff-text-file-header">').appendTo(codeBody); + var content = $('<td colspan="3"></td>').appendTo(diffFileRow); + + var chevron = $('<i class="red-ui-diff-list-chevron fa fa-angle-down"></i>').appendTo(content); + diffFileRow.on("click", function(e) { + diffFileRow.toggleClass("collapsed"); + var isCollapsed = diffFileRow.hasClass("collapsed"); + diffFileRow.nextUntil(".red-ui-diff-text-file-header").toggle(!isCollapsed); + }) + var label = $('<span class="filename"></span>').text(file.file).appendTo(content); + + var conflictHeader; + var unresolvedConflicts = 0; + var resolvedConflicts = 0; + var conflictResolutions = {}; + if (commitOptions.project.files && commitOptions.project.files.flow === file.file) { + if (commitOptions.unmerged) { + $('<span style="float: right;"><span id="red-ui-diff-dialog-toolbar-resolved-conflicts"></span></span>').appendTo(content); + } + var diffRow = $('<tr class="red-ui-diff-text-header">').appendTo(codeBody); + var flowDiffContent = $('<td class="red-ui-diff-flow-diff" colspan="3"></td>').appendTo(diffRow); + + var projectName = commitOptions.project.name; + var filename = commitOptions.project.files.flow; + var commonVersionUrl = "projects/"+projectName+"/files/"+commitOptions.commonRev+"/"+filename; + var oldVersionUrl = "projects/"+projectName+"/files/"+commitOptions.oldRev+"/"+filename; + var newVersionUrl = "projects/"+projectName+"/files/"+commitOptions.newRev+"/"+filename; + var promises = [$.Deferred(),$.Deferred(),$.Deferred()]; + if (commitOptions.commonRev) { + var commonVersionUrl = "projects/"+projectName+"/files/"+commitOptions.commonRev+"/"+filename; + $.ajax({dataType: "json",url: commonVersionUrl}).then(function(data) { promises[0].resolve(data); }).fail(function() { promises[0].resolve(null);}) + } else { + promises[0].resolve(null); + } + + $.ajax({dataType: "json",url: oldVersionUrl}).then(function(data) { promises[1].resolve(data); }).fail(function() { promises[1].resolve({content:"[]"});}) + $.ajax({dataType: "json",url: newVersionUrl}).then(function(data) { promises[2].resolve(data); }).fail(function() { promises[2].resolve({content:"[]"});}) + $.when.apply($,promises).always(function(commonVersion, oldVersion,newVersion) { + var commonFlow; + var oldFlow; + var newFlow; + if (commonVersion) { + try { + commonFlow = JSON.parse(commonVersion.content||"[]"); + } catch(err) { + console.log(RED._("diff.commonVersionError"),commonVersionUrl); + console.log(err); + return; + } + } + try { + oldFlow = JSON.parse(oldVersion.content||"[]"); + } catch(err) { + console.log(RED._("diff.oldVersionError"),oldVersionUrl); + console.log(err); + return; + } + if (!commonFlow) { + commonFlow = oldFlow; + } + try { + newFlow = JSON.parse(newVersion.content||"[]"); + } catch(err) { + console.log(RED._("diff.newVersionError"),newFlow); + console.log(err); + return; + } + var localDiff = generateDiff(commonFlow,oldFlow); + var remoteDiff = generateDiff(commonFlow,newFlow); + commitOptions.currentDiff = resolveDiffs(localDiff,remoteDiff); + var diffTable = buildDiffPanel(flowDiffContent,commitOptions.currentDiff,{ + title: filename, + mode: commitOptions.commonRev?'merge':'view', + oldRevTitle: commitOptions.oldRevTitle, + newRevTitle: commitOptions.newRevTitle + }); + diffTable.list.hide(); + refreshConflictHeader(commitOptions.currentDiff); + setTimeout(function() { + diffTable.finish(); + diffTable.list.show(); + },300); + // var flowDiffRow = $("<tr>").insertAfter(diffRow); + // var content = $('<td colspan="3"></td>').appendTo(flowDiffRow); + // currentDiff = diff; + // var diffTable = buildDiffPanel(content,diff,{mode:"view"}).finish(); + }); + + + + } else + + if (isBinary) { + var diffBinaryRow = $('<tr class="red-ui-diff-text-header">').appendTo(codeBody); + var binaryContent = $('<td colspan="3"></td>').appendTo(diffBinaryRow); + $('<span></span>').text(RED._("diff.noBinaryFileShowed")).appendTo(binaryContent); + + } else { + if (commitOptions.unmerged) { + conflictHeader = $('<span style="float: right;">'+RED._("diff.conflictHeader",{resolved:resolvedConflicts, unresolved:unresolvedConflicts})+'</span>').appendTo(content); + } + hunks.forEach(function(hunk) { + var diffRow = $('<tr class="red-ui-diff-text-header">').appendTo(codeBody); + var content = $('<td colspan="3"></td>').appendTo(diffRow); + var label = $('<span></span>').text(hunk.header).appendTo(content); + var isConflict = hunk.conflict; + var localLine = hunk.localStartLine; + var remoteLine = hunk.remoteStartLine; + if (isConflict) { + unresolvedConflicts++; + } + + hunk.lines.forEach(function(lineText,lineNumber) { + // if (lineText[0] === '\\' || lineText === "") { + // // Comment line - bail out of this hunk + // break; + // } + + var actualLineNumber = hunk.diffStart + lineNumber; + var isMergeHeader = isConflict && /^\+\+(<<<<<<<|=======$|>>>>>>>)/.test(lineText); + var diffRow = $('<tr>').appendTo(codeBody); + var localLineNo = $('<td class="lineno">').appendTo(diffRow); + var remoteLineNo; + if (!isMergeHeader) { + remoteLineNo = $('<td class="lineno">').appendTo(diffRow); + } else { + localLineNo.attr('colspan',2); + } + var line = $('<td class="linetext">').appendTo(diffRow); + var prefixStart = 0; + var prefixEnd = 1; + if (isConflict) { + prefixEnd = 2; + } + if (!isMergeHeader) { + var changeMarker = lineText[0]; + if (isConflict && !commitOptions.unmerged && changeMarker === ' ') { + changeMarker = lineText[1]; + } + $('<span class="prefix">').text(changeMarker).appendTo(line); + var handledlLine = false; + if (isConflict && commitOptions.unmerged) { + $('<span class="prefix">').text(lineText[1]).appendTo(line); + if (lineText[0] === '+') { + localLineNo.text(localLine++); + handledlLine = true; + } + if (lineText[1] === '+') { + remoteLineNo.text(remoteLine++); + handledlLine = true; + } + } else { + if (lineText[0] === '+' || (isConflict && lineText[1] === '+')) { + localLineNo.addClass("added"); + remoteLineNo.addClass("added"); + line.addClass("added"); + remoteLineNo.text(remoteLine++); + handledlLine = true; + } else if (lineText[0] === '-' || (isConflict && lineText[1] === '-')) { + localLineNo.addClass("removed"); + remoteLineNo.addClass("removed"); + line.addClass("removed"); + localLineNo.text(localLine++); + handledlLine = true; + } + } + if (!handledlLine) { + line.addClass("unchanged"); + if (localLine > 0 && lineText[0] !== '\\' && lineText !== "") { + localLineNo.text(localLine++); + } + if (remoteLine > 0 && lineText[0] !== '\\' && lineText !== "") { + remoteLineNo.text(remoteLine++); + } + } + $('<span>').text(lineText.substring(prefixEnd)).appendTo(line); + } else { + diffRow.addClass("mergeHeader"); + var isSeparator = /^\+\+=======$/.test(lineText); + if (!isSeparator) { + var isOurs = /^..<<<<<<</.test(lineText); + if (isOurs) { + $('<span>').text("<<<<<<< Local Changes").appendTo(line); + hunk.localChangeStart = actualLineNumber; + } else { + hunk.remoteChangeEnd = actualLineNumber; + $('<span>').text(">>>>>>> Remote Changes").appendTo(line); + + } + diffRow.addClass("mergeHeader-"+(isOurs?"ours":"theirs")); + $('<button class="red-ui-button red-ui-button-small" style="float: right; margin-right: 20px;"><i class="fa fa-angle-double-'+(isOurs?"down":"up")+'"></i> use '+(isOurs?"local":"remote")+' changes</button>') + .appendTo(line) + .on("click", function(evt) { + evt.preventDefault(); + resolvedConflicts++; + var addedRows; + var midRow; + if (isOurs) { + addedRows = diffRow.nextUntil(".mergeHeader-separator"); + midRow = addedRows.last().next(); + midRow.nextUntil(".mergeHeader").remove(); + midRow.next().remove(); + } else { + addedRows = diffRow.prevUntil(".mergeHeader-separator"); + midRow = addedRows.last().prev(); + midRow.prevUntil(".mergeHeader").remove(); + midRow.prev().remove(); + } + midRow.remove(); + diffRow.remove(); + addedRows.find(".linetext").addClass('added'); + conflictHeader.empty(); + $('<span>'+RED._("diff.conflictHeader",{resolved:resolvedConflicts, unresolved:unresolvedConflicts})+'</span>').appendTo(conflictHeader); + + conflictResolutions[file.file] = conflictResolutions[file.file] || {}; + conflictResolutions[file.file][hunk.localChangeStart] = { + changeStart: hunk.localChangeStart, + separator: hunk.changeSeparator, + changeEnd: hunk.remoteChangeEnd, + selection: isOurs?"A":"B" + } + if (commitOptions.resolveConflict) { + commitOptions.resolveConflict({ + conflicts: unresolvedConflicts, + resolved: resolvedConflicts, + resolutions: conflictResolutions + }); + } + }) + } else { + hunk.changeSeparator = actualLineNumber; + diffRow.addClass("mergeHeader-separator"); + } + } + }); + }); + } + }); + return diffPanel; + } + + function showCommitDiff(options) { + var commit = parseCommitDiff(options.commit); + var trayOptions = { + title: RED._("diff.viewCommitDiff"), + width: Infinity, + overlay: true, + buttons: [ + { + text: RED._("common.label.close"), + click: function() { + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + // trayWidth = dimensions.width; + }, + open: function(tray) { + var trayBody = tray.find('.red-ui-tray-body'); + var diffPanel = $('<div class="red-ui-diff-text"></div>').appendTo(trayBody); + + var codeTable = $("<table>",{class:"red-ui-diff-text-content"}).appendTo(diffPanel); + $('<colgroup><col width="50"><col width="50"><col width="100%"></colgroup>').appendTo(codeTable); + var codeBody = $('<tbody>').appendTo(codeTable); + + var diffRow = $('<tr class="red-ui-diff-text-commit-header">').appendTo(codeBody); + var content = $('<td colspan="3"></td>').appendTo(diffRow); + + $("<h3>").text(commit.title).appendTo(content); + $('<div class="commit-body"></div>').text(commit.comment).appendTo(content); + var summary = $('<div class="commit-summary"></div>').appendTo(content); + $('<div style="float: right">').text("Commit "+commit.sha).appendTo(summary); + $('<div>').text((commit.authorName||commit.author)+" - "+options.date).appendTo(summary); + + if (commit.files) { + createUnifiedDiffTable(commit.files,options).appendTo(diffPanel); + } + + + }, + close: function() { + diffVisible = false; + }, + show: function() { + + } + } + RED.tray.show(trayOptions); + } + function showUnifiedDiff(options) { + var diff = options.diff; + var title = options.title; + var files = parseUnifiedDiff(diff); + + var currentResolution; + if (options.unmerged) { + options.resolveConflict = function(results) { + currentResolution = results; + if (results.conflicts === results.resolved) { + $("#red-ui-diff-view-resolve-diff").removeClass('disabled'); + } + } + } + + var trayOptions = { + title: title|| RED._("diff.compareChanges"), + width: Infinity, + overlay: true, + buttons: [ + { + text: RED._((options.unmerged)?"common.label.cancel":"common.label.close"), + click: function() { + if (options.oncancel) { + options.oncancel(); + } + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + // trayWidth = dimensions.width; + }, + open: function(tray) { + var trayBody = tray.find('.red-ui-tray-body'); + var diffPanel = $('<div class="red-ui-diff-text"></div>').appendTo(trayBody); + createUnifiedDiffTable(files,options).appendTo(diffPanel); + }, + close: function() { + diffVisible = false; + }, + show: function() { + + } + } + if (options.unmerged) { + trayOptions.buttons.push( + { + id: "red-ui-diff-view-resolve-diff", + text: RED._("diff.saveConflict"), + class: "primary disabled", + click: function() { + if (!$("#red-ui-diff-view-resolve-diff").hasClass('disabled')) { + if (options.currentDiff) { + // This is a flow file. Need to apply the diff + // and generate the new flow. + var result = applyDiff(options.currentDiff); + currentResolution = { + resolutions:{} + }; + currentResolution.resolutions[options.project.files.flow] = JSON.stringify(result.config,"",4); + } + if (options.onresolve) { + options.onresolve(currentResolution); + } + RED.tray.close(); + } + } + } + ); + } + RED.tray.show(trayOptions); + } + + function parseCommitDiff(diff) { + var result = {}; + var lines = diff.split("\n"); + var comment = []; + for (var i=0;i<lines.length;i++) { + if (/^commit /.test(lines[i])) { + result.sha = lines[i].substring(7); + } else if (/^Author: /.test(lines[i])) { + result.author = lines[i].substring(8); + var m = /^(.*) <(.*)>$/.exec(result.author); + if (m) { + result.authorName = m[1]; + result.authorEmail = m[2]; + } + } else if (/^Date: /.test(lines[i])) { + result.date = lines[i].substring(8); + } else if (/^ /.test(lines[i])) { + if (!result.title) { + result.title = lines[i].substring(4); + } else { + if (lines[i].length !== 4 || comment.length > 0) { + comment.push(lines[i].substring(4)); + } + } + } else if (/^diff /.test(lines[i])) { + result.files = parseUnifiedDiff(lines.slice(i)); + break; + } + } + result.comment = comment.join("\n"); + return result; + } + function parseUnifiedDiff(diff) { + var lines; + if (Array.isArray(diff)) { + lines = diff; + } else { + lines = diff.split("\n"); + } + var diffHeader = /^diff (?:(?:--git a\/(.*) b\/(.*))|(?:--cc (.*)))$/; + var fileHeader = /^\+\+\+ b\/(.*)\t?/; + var binaryFile = /^Binary files /; + var hunkHeader = /^@@ -((\d+)(,(\d+))?) \+((\d+)(,(\d+))?) @@ ?(.*)$/; + var conflictHunkHeader = /^@+ -((\d+)(,(\d+))?) -((\d+)(,(\d+))?) \+((\d+)(,(\d+))?) @+/; + var files = []; + var currentFile; + var hunks = []; + var currentHunk; + for (var i=0;i<lines.length;i++) { + var line = lines[i]; + var diffLine = diffHeader.exec(line); + if (diffLine) { + if (currentHunk) { + currentFile.hunks.push(currentHunk); + files.push(currentFile); + } + currentHunk = null; + currentFile = { + file: diffLine[1]||diffLine[3], + hunks: [] + } + } else if (binaryFile.test(line)) { + if (currentFile) { + currentFile.binary = true; + } + } else { + var fileLine = fileHeader.exec(line); + if (fileLine) { + currentFile.file = fileLine[1]; + } else { + var hunkLine = hunkHeader.exec(line); + if (hunkLine) { + if (currentHunk) { + currentFile.hunks.push(currentHunk); + } + currentHunk = { + header: line, + localStartLine: hunkLine[2], + localLength: hunkLine[4]||1, + remoteStartLine: hunkLine[6], + remoteLength: hunkLine[8]||1, + lines: [], + conflict: false + } + continue; + } + hunkLine = conflictHunkHeader.exec(line); + if (hunkLine) { + if (currentHunk) { + currentFile.hunks.push(currentHunk); + } + currentHunk = { + header: line, + localStartLine: hunkLine[2], + localLength: hunkLine[4]||1, + remoteStartLine: hunkLine[6], + remoteLength: hunkLine[8]||1, + diffStart: parseInt(hunkLine[10]), + lines: [], + conflict: true + } + continue; + } + if (currentHunk) { + currentHunk.lines.push(line); + } + } + } + } + if (currentHunk) { + currentFile.hunks.push(currentHunk); + } + files.push(currentFile); + return files; + } + + return { + init: init, + getRemoteDiff: getRemoteDiff, + showRemoteDiff: showRemoteDiff, + showUnifiedDiff: showUnifiedDiff, + showCommitDiff: showCommitDiff, + mergeDiff: mergeDiff + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js new file mode 100644 index 0000000..6641e9b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js @@ -0,0 +1,2580 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +/** + * @namespace RED.editor + */ +RED.editor = (function() { + + var editStack = []; + var editing_node = null; + var editing_config_node = null; + var subflowEditor; + + var customEditTypes = {}; + + var editTrayWidthCache = {}; + + function getCredentialsURL(nodeType, nodeID) { + var dashedType = nodeType.replace(/\s+/g, '-'); + return 'credentials/' + dashedType + "/" + nodeID; + } + + /** + * Validate a node + * @param node - the node being validated + * @returns {boolean} whether the node is valid. Sets node.dirty if needed + */ + function validateNode(node) { + var oldValue = node.valid; + var oldChanged = node.changed; + node.valid = true; + var subflow; + var isValid; + var validationErrors; + var hasChanged; + if (node.type.indexOf("subflow:")===0) { + subflow = RED.nodes.subflow(node.type.substring(8)); + isValid = subflow.valid; + hasChanged = subflow.changed; + if (isValid === undefined) { + isValid = validateNode(subflow); + hasChanged = subflow.changed; + } + validationErrors = validateNodeProperties(node, node._def.defaults, node); + node.valid = isValid && validationErrors.length === 0; + node.changed = node.changed || hasChanged; + node.validationErrors = validationErrors; + } else if (node._def) { + validationErrors = validateNodeProperties(node, node._def.defaults, node); + if (node._def._creds) { + validationErrors = validationErrors.concat(validateNodeProperties(node, node._def.credentials, node._def._creds)) + } + node.valid = (validationErrors.length === 0); + node.validationErrors = validationErrors; + } else if (node.type == "subflow") { + var subflowNodes = RED.nodes.filterNodes({z:node.id}); + for (var i=0;i<subflowNodes.length;i++) { + isValid = subflowNodes[i].valid; + hasChanged = subflowNodes[i].changed; + if (isValid === undefined) { + isValid = validateNode(subflowNodes[i]); + hasChanged = subflowNodes[i].changed; + } + node.valid = node.valid && isValid; + node.changed = node.changed || hasChanged; + } + var subflowInstances = RED.nodes.filterNodes({type:"subflow:"+node.id}); + var modifiedTabs = {}; + for (i=0;i<subflowInstances.length;i++) { + subflowInstances[i].valid = node.valid; + subflowInstances[i].changed = subflowInstances[i].changed || node.changed; + subflowInstances[i].dirty = true; + modifiedTabs[subflowInstances[i].z] = true; + } + Object.keys(modifiedTabs).forEach(function(id) { + var subflow = RED.nodes.subflow(id); + if (subflow) { + validateNode(subflow); + } + }); + } + if (oldValue !== node.valid || oldChanged !== node.changed) { + node.dirty = true; + subflow = RED.nodes.subflow(node.z); + if (subflow) { + validateNode(subflow); + } + } + return node.valid; + } + + /** + * Validate a node's properties for the given set of property definitions + * @param node - the node being validated + * @param definition - the node property definitions (either def.defaults or def.creds) + * @param properties - the node property values to validate + * @returns {array} an array of invalid properties + */ + function validateNodeProperties(node, definition, properties) { + var result = []; + for (var prop in definition) { + if (definition.hasOwnProperty(prop)) { + if (!validateNodeProperty(node, definition, prop, properties[prop])) { + result.push(prop); + } + } + } + return result; + } + + /** + * Validate a individual node property + * @param node - the node being validated + * @param definition - the node property definitions (either def.defaults or def.creds) + * @param property - the property name being validated + * @param value - the property value being validated + * @returns {boolean} whether the node proprty is valid + */ + function validateNodeProperty(node,definition,property,value) { + var valid = true; + // Check for $(env-var) and consider it valid + if (/^\$\([a-zA-Z_][a-zA-Z0-9_]*\)$/.test(value)) { + return true; + } + // Check for ${env-var} and consider it valid + if (/^\$\{[a-zA-Z_][a-zA-Z0-9_]*\}$/.test(value)) { + return true; + } + if ("required" in definition[property] && definition[property].required) { + valid = value !== ""; + } + if (valid && "validate" in definition[property]) { + try { + valid = definition[property].validate.call(node,value); + } catch(err) { + console.log("Validation error:",node.type,node.id,"property: "+property,"value:",value,err); + } + } + if (valid && definition[property].type && RED.nodes.getType(definition[property].type) && !("validate" in definition[property])) { + if (!value || value == "_ADD_") { + valid = definition[property].hasOwnProperty("required") && !definition[property].required; + } else { + var configNode = RED.nodes.node(value); + valid = (configNode !== null && (configNode.valid == null || configNode.valid)); + } + } + return valid; + } + + + function validateNodeEditor(node,prefix) { + for (var prop in node._def.defaults) { + if (node._def.defaults.hasOwnProperty(prop)) { + validateNodeEditorProperty(node,node._def.defaults,prop,prefix); + } + } + if (node._def.credentials) { + for (prop in node._def.credentials) { + if (node._def.credentials.hasOwnProperty(prop)) { + validateNodeEditorProperty(node,node._def.credentials,prop,prefix); + } + } + } + } + + function validateNodeEditorProperty(node,defaults,property,prefix) { + var input = $("#"+prefix+"-"+property); + if (input.length > 0) { + var value = input.val(); + if (defaults[property].hasOwnProperty("format") && defaults[property].format !== "" && input[0].nodeName === "DIV") { + value = input.text(); + } + if (!validateNodeProperty(node, defaults, property,value)) { + input.addClass("input-error"); + } else { + input.removeClass("input-error"); + } + } + } + + /** + * Called when the node's properties have changed. + * Marks the node as dirty and needing a size check. + * Removes any links to non-existant outputs. + * @param node - the node that has been updated + * @param outputMap - (optional) a map of old->new port numbers if wires should be moved + * @returns {array} the links that were removed due to this update + */ + function updateNodeProperties(node, outputMap) { + node.resize = true; + node.dirty = true; + node.dirtyStatus = true; + var removedLinks = []; + if (node.ports) { + if (outputMap) { + RED.nodes.eachLink(function(l) { + if (l.source === node && outputMap.hasOwnProperty(l.sourcePort)) { + if (outputMap[l.sourcePort] === "-1") { + removedLinks.push(l); + } else { + l.sourcePort = outputMap[l.sourcePort]; + } + } + }); + } + if (node.outputs < node.ports.length) { + while (node.outputs < node.ports.length) { + node.ports.pop(); + } + RED.nodes.eachLink(function(l) { + if (l.source === node && l.sourcePort >= node.outputs && removedLinks.indexOf(l) === -1) { + removedLinks.push(l); + } + }); + } else if (node.outputs > node.ports.length) { + while (node.outputs > node.ports.length) { + node.ports.push(node.ports.length); + } + } + } + node.inputs = Math.min(1,Math.max(0,parseInt(node.inputs))); + if (isNaN(node.inputs)) { + node.inputs = 0; + } + if (node.inputs === 0) { + removedLinks = removedLinks.concat(RED.nodes.filterLinks({target:node})); + } + for (var l=0;l<removedLinks.length;l++) { + RED.nodes.removeLink(removedLinks[l]); + } + return removedLinks; + } + + /** + * Create a config-node select box for this property + * @param node - the node being edited + * @param property - the name of the field + * @param type - the type of the config-node + */ + function prepareConfigNodeSelect(node,property,type,prefix) { + var input = $("#"+prefix+"-"+property); + if (input.length === 0 ) { + return; + } + var newWidth = input.width(); + var attrStyle = input.attr('style'); + var m; + if ((m = /width\s*:\s*(\d+(%|[a-z]+))/i.exec(attrStyle)) !== null) { + newWidth = m[1]; + } else { + newWidth = "70%"; + } + var outerWrap = $("<div></div>").css({display:'inline-block',position:'relative'}); + var selectWrap = $("<div></div>").css({position:'absolute',left:0,right:'40px'}).appendTo(outerWrap); + var select = $('<select id="'+prefix+'-'+property+'"></select>').appendTo(selectWrap); + + outerWrap.width(newWidth).height(input.height()); + if (outerWrap.width() === 0) { + outerWrap.width("70%"); + } + input.replaceWith(outerWrap); + // set the style attr directly - using width() on FF causes a value of 114%... + select.attr('style',"width:100%"); + updateConfigNodeSelect(property,type,node[property],prefix); + $('<a id="'+prefix+'-lookup-'+property+'" class="red-ui-button"><i class="fa fa-pencil"></i></a>') + .css({position:'absolute',right:0,top:0}) + .appendTo(outerWrap); + $('#'+prefix+'-lookup-'+property).on("click", function(e) { + showEditConfigNodeDialog(property,type,select.find(":selected").val(),prefix); + e.preventDefault(); + }); + var label = ""; + var configNode = RED.nodes.node(node[property]); + var node_def = RED.nodes.getType(type); + + if (configNode) { + label = RED.utils.getNodeLabel(configNode,configNode.id); + } + input.val(label); + } + + /** + * Create a config-node button for this property + * @param node - the node being edited + * @param property - the name of the field + * @param type - the type of the config-node + */ + function prepareConfigNodeButton(node,property,type,prefix) { + var input = $("#"+prefix+"-"+property); + input.val(node[property]); + input.attr("type","hidden"); + + var button = $("<a>",{id:prefix+"-edit-"+property, class:"red-ui-button"}); + input.after(button); + + if (node[property]) { + button.text(RED._("editor.configEdit")); + } else { + button.text(RED._("editor.configAdd")); + } + + button.on("click", function(e) { + showEditConfigNodeDialog(property,type,input.val()||"_ADD_",prefix); + e.preventDefault(); + }); + } + + /** + * Populate the editor dialog input field for this property + * @param node - the node being edited + * @param property - the name of the field + * @param prefix - the prefix to use in the input element ids (node-input|node-config-input) + * @param definition - the definition of the field + */ + function preparePropertyEditor(node,property,prefix,definition) { + var input = $("#"+prefix+"-"+property); + if (input.length === 0) { + return; + } + if (input.attr('type') === "checkbox") { + input.prop('checked',node[property]); + } + else { + var val = node[property]; + if (val == null) { + val = ""; + } + if (definition !== undefined && definition[property].hasOwnProperty("format") && definition[property].format !== "" && input[0].nodeName === "DIV") { + input.html(RED.text.format.getHtml(val, definition[property].format, {}, false, "en")); + RED.text.format.attach(input[0], definition[property].format, {}, false, "en"); + } else { + input.val(val); + if (input[0].nodeName === 'INPUT' || input[0].nodeName === 'TEXTAREA') { + RED.text.bidi.prepareInput(input); + } + } + } + } + + /** + * Add an on-change handler to revalidate a node field + * @param node - the node being edited + * @param definition - the definition of the node + * @param property - the name of the field + * @param prefix - the prefix to use in the input element ids (node-input|node-config-input) + */ + function attachPropertyChangeHandler(node,definition,property,prefix) { + var input = $("#"+prefix+"-"+property); + if (definition !== undefined && "format" in definition[property] && definition[property].format !== "" && input[0].nodeName === "DIV") { + $("#"+prefix+"-"+property).on('change keyup', function(event,skipValidation) { + if (!skipValidation) { + validateNodeEditor(node,prefix); + } + }); + } else { + $("#"+prefix+"-"+property).on("change", function(event,skipValidation) { + if (!skipValidation) { + validateNodeEditor(node,prefix); + } + }); + } + } + + /** + * Assign the value to each credential field + * @param node + * @param credDef + * @param credData + * @param prefix + */ + function populateCredentialsInputs(node, credDef, credData, prefix) { + var cred; + for (cred in credDef) { + if (credDef.hasOwnProperty(cred)) { + if (credDef[cred].type == 'password') { + if (credData[cred]) { + $('#' + prefix + '-' + cred).val(credData[cred]); + } else if (credData['has_' + cred]) { + $('#' + prefix + '-' + cred).val('__PWRD__'); + } + else { + $('#' + prefix + '-' + cred).val(''); + } + } else { + preparePropertyEditor(credData, cred, prefix, credDef); + } + attachPropertyChangeHandler(node, credDef, cred, prefix); + } + } + } + + /** + * Update the node credentials from the edit form + * @param node - the node containing the credentials + * @param credDefinition - definition of the credentials + * @param prefix - prefix of the input fields + * @return {boolean} whether anything has changed + */ + function updateNodeCredentials(node, credDefinition, prefix) { + var changed = false; + if(!node.credentials) { + node.credentials = {_:{}}; + } + + for (var cred in credDefinition) { + if (credDefinition.hasOwnProperty(cred)) { + var input = $("#" + prefix + '-' + cred); + var value = input.val(); + if (credDefinition[cred].type == 'password') { + node.credentials['has_' + cred] = (value !== ""); + if (value == '__PWRD__') { + continue; + } + changed = true; + + } + node.credentials[cred] = value; + if (value != node.credentials._[cred]) { + changed = true; + } + } + } + return changed; + } + + /** + * Prepare all of the editor dialog fields + * @param node - the node being edited + * @param definition - the node definition + * @param prefix - the prefix to use in the input element ids (node-input|node-config-input) + */ + function prepareEditDialog(node,definition,prefix,done) { + for (var d in definition.defaults) { + if (definition.defaults.hasOwnProperty(d)) { + if (definition.defaults[d].type) { + var configTypeDef = RED.nodes.getType(definition.defaults[d].type); + if (configTypeDef) { + if (configTypeDef.exclusive) { + prepareConfigNodeButton(node,d,definition.defaults[d].type,prefix); + } else { + prepareConfigNodeSelect(node,d,definition.defaults[d].type,prefix); + } + } else { + console.log("Unknown type:", definition.defaults[d].type); + preparePropertyEditor(node,d,prefix,definition.defaults); + } + } else { + preparePropertyEditor(node,d,prefix,definition.defaults); + } + attachPropertyChangeHandler(node,definition.defaults,d,prefix); + } + } + var completePrepare = function() { + if (definition.oneditprepare) { + try { + definition.oneditprepare.call(node); + } catch(err) { + console.log("oneditprepare",node.id,node.type,err.toString()); + } + } + // Now invoke any change handlers added to the fields - passing true + // to prevent full node validation from being triggered each time + for (var d in definition.defaults) { + if (definition.defaults.hasOwnProperty(d)) { + $("#"+prefix+"-"+d).trigger("change",[true]); + } + } + if (definition.credentials) { + for (d in definition.credentials) { + if (definition.credentials.hasOwnProperty(d)) { + $("#"+prefix+"-"+d).trigger("change",[true]); + } + } + } + validateNodeEditor(node,prefix); + if (done) { + done(); + } + } + + if (definition.credentials) { + if (node.credentials) { + populateCredentialsInputs(node, definition.credentials, node.credentials, prefix); + completePrepare(); + } else { + $.getJSON(getCredentialsURL(node.type, node.id), function (data) { + node.credentials = data; + node.credentials._ = $.extend(true,{},data); + populateCredentialsInputs(node, definition.credentials, node.credentials, prefix); + completePrepare(); + }); + } + } else { + completePrepare(); + } + } + + function getEditStackTitle() { + var label; + for (var i=editStack.length-1;i<editStack.length;i++) { + var node = editStack[i]; + label = node.type; + if (node.type === '_expression') { + label = RED._("expressionEditor.title"); + } else if (node.type === '_js') { + label = RED._("jsEditor.title"); + } else if (node.type === '_text') { + label = RED._("textEditor.title"); + } else if (node.type === '_json') { + label = RED._("jsonEditor.title"); + } else if (node.type === '_markdown') { + label = RED._("markdownEditor.title"); + } else if (node.type === '_buffer') { + label = RED._("bufferEditor.title"); + } else if (node.type === 'subflow') { + label = RED._("subflow.editSubflow",{name:RED.utils.sanitize(node.name)}) + } else if (node.type.indexOf("subflow:")===0) { + var subflow = RED.nodes.subflow(node.type.substring(8)); + label = RED._("subflow.editSubflowInstance",{name:RED.utils.sanitize(subflow.name)}) + } else if (node._def !== undefined) { + if (typeof node._def.paletteLabel !== "undefined") { + try { + label = RED.utils.sanitize((typeof node._def.paletteLabel === "function" ? node._def.paletteLabel.call(node._def) : node._def.paletteLabel)||""); + } catch(err) { + console.log("Definition error: "+node.type+".paletteLabel",err); + } + } + if (i === editStack.length-1) { + if (RED.nodes.node(node.id)) { + label = RED._("editor.editNode",{type:RED.utils.sanitize(label)}); + } else { + label = RED._("editor.addNewConfig",{type:RED.utils.sanitize(label)}); + } + } + } + } + return label; + } + + function isSameObj(env0, env1) { + return (JSON.stringify(env0) === JSON.stringify(env1)); + } + + function buildEditForm(container,formId,type,ns,node) { + var dialogForm = $('<form id="'+formId+'" class="form-horizontal" autocomplete="off"></form>').appendTo(container); + dialogForm.html($("script[data-template-name='"+type+"']").html()); + ns = ns||"node-red"; + dialogForm.find('[data-i18n]').each(function() { + var current = $(this).attr("data-i18n"); + var keys = current.split(";"); + for (var i=0;i<keys.length;i++) { + var key = keys[i]; + if (key.indexOf(":") === -1) { + var prefix = ""; + if (key.indexOf("[")===0) { + var parts = key.split("]"); + prefix = parts[0]+"]"; + key = parts[1]; + } + keys[i] = prefix+ns+":"+key; + } + } + $(this).attr("data-i18n",keys.join(";")); + }); + + if (type === "subflow-template" || type === "subflow") { + RED.subflow.buildEditForm(dialogForm,type,node); + } + + // Add dummy fields to prevent 'Enter' submitting the form in some + // cases, and also prevent browser auto-fill of password + // - the elements cannot be hidden otherwise Chrome will ignore them. + // - the elements need to have id's that imply password/username + $('<span style="position: absolute; top: -2000px;"><input id="red-ui-trap-password" type="password"/></span>').prependTo(dialogForm); + $('<span style="position: absolute; top: -2000px;"><input id="red-ui-trap-username" type="text"/></span>').prependTo(dialogForm); + dialogForm.on("submit", function(e) { e.preventDefault();}); + dialogForm.find('input').attr("autocomplete","off"); + return dialogForm; + } + + function refreshLabelForm(container,node) { + + var inputPlaceholder = node._def.inputLabels?RED._("editor.defaultLabel"):RED._("editor.noDefaultLabel"); + var outputPlaceholder = node._def.outputLabels?RED._("editor.defaultLabel"):RED._("editor.noDefaultLabel"); + + var inputsDiv = $("#red-ui-editor-node-label-form-inputs"); + var outputsDiv = $("#red-ui-editor-node-label-form-outputs"); + + var inputCount; + var formInputs = $("#node-input-inputs").val(); + if (formInputs === undefined) { + if (node.type === 'subflow') { + inputCount = node.in.length; + } else { + inputCount = node.inputs || node._def.inputs || 0; + } + } else { + inputCount = Math.min(1,Math.max(0,parseInt(formInputs))); + if (isNaN(inputCount)) { + inputCount = 0; + } + } + + var children = inputsDiv.children(); + var childCount = children.length; + if (childCount === 1 && $(children[0]).hasClass('red-ui-editor-node-label-form-none')) { + childCount--; + } + + if (childCount < inputCount) { + if (childCount === 0) { + // remove the 'none' placeholder + $(children[0]).remove(); + } + for (i = childCount;i<inputCount;i++) { + buildLabelRow("input",i,"",inputPlaceholder).appendTo(inputsDiv); + } + } else if (childCount > inputCount) { + for (i=inputCount;i<childCount;i++) { + $(children[i]).remove(); + } + if (inputCount === 0) { + buildLabelRow().appendTo(inputsDiv); + } + } + + var outputCount; + var i; + var formOutputs = $("#node-input-outputs").val(); + + if (formOutputs === undefined) { + if (node.type === 'subflow') { + outputCount = node.out.length; + } else { + inputCount = node.outputs || node._def.outputs || 0; + } + } else if (isNaN(formOutputs)) { + var outputMap = JSON.parse(formOutputs); + var keys = Object.keys(outputMap); + children = outputsDiv.children(); + childCount = children.length; + if (childCount === 1 && $(children[0]).hasClass('red-ui-editor-node-label-form-none')) { + childCount--; + } + + outputCount = 0; + var rows = []; + keys.forEach(function(p) { + var row = $("#red-ui-editor-node-label-form-output-"+p).parent(); + if (row.length === 0 && outputMap[p] !== -1) { + if (childCount === 0) { + $(children[0]).remove(); + childCount = -1; + } + row = buildLabelRow("output",p,"",outputPlaceholder); + } else { + row.detach(); + } + if (outputMap[p] !== -1) { + outputCount++; + rows.push({i:parseInt(outputMap[p]),r:row}); + } + }); + rows.sort(function(A,B) { + return A.i-B.i; + }) + rows.forEach(function(r,i) { + r.r.find("label").text((i+1)+"."); + r.r.appendTo(outputsDiv); + }) + if (rows.length === 0) { + buildLabelRow("output",i,"").appendTo(outputsDiv); + } else { + + } + } else { + outputCount = Math.max(0,parseInt(formOutputs)); + } + children = outputsDiv.children(); + childCount = children.length; + if (childCount === 1 && $(children[0]).hasClass('red-ui-editor-node-label-form-none')) { + childCount--; + } + if (childCount < outputCount) { + if (childCount === 0) { + // remove the 'none' placeholder + $(children[0]).remove(); + } + for (i = childCount;i<outputCount;i++) { + buildLabelRow("output",i,"").appendTo(outputsDiv); + } + } else if (childCount > outputCount) { + for (i=outputCount;i<childCount;i++) { + $(children[i]).remove(); + } + if (outputCount === 0) { + buildLabelRow().appendTo(outputsDiv); + } + } + } + function buildLabelRow(type, index, value, placeHolder) { + var result = $('<div>',{class:"red-ui-editor-node-label-form-row"}); + if (type === undefined) { + $('<span>').text(RED._("editor.noDefaultLabel")).appendTo(result); + result.addClass("red-ui-editor-node-label-form-none"); + } else { + result.addClass(""); + var id = "red-ui-editor-node-label-form-"+type+"-"+index; + $('<label>',{for:id}).text((index+1)+".").appendTo(result); + var input = $('<input>',{type:"text",id:id, placeholder: placeHolder}).val(value).appendTo(result); + var clear = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-times"></i></button>').appendTo(result); + clear.on("click", function(evt) { + evt.preventDefault(); + input.val(""); + }) + } + return result; + } + function showIconPicker(container, backgroundColor, iconPath, faOnly, done) { + var picker = $('<div class="red-ui-icon-picker">'); + var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(picker); + searchInput = $('<input type="text">').attr("placeholder",RED._("editor.searchIcons")).appendTo(searchDiv).searchBox({ + delay: 50, + change: function() { + var searchTerm = $(this).val().trim(); + if (searchTerm === "") { + iconList.find(".red-ui-icon-list-module").show(); + iconList.find(".red-ui-icon-list-icon").show(); + } else { + iconList.find(".red-ui-icon-list-module").hide(); + iconList.find(".red-ui-icon-list-icon").each(function(i,n) { + if ($(n).data('icon').indexOf(searchTerm) === -1) { + $(n).hide(); + } else { + $(n).show(); + } + }); + } + } + }); + + var row = $('<div>').appendTo(picker); + var iconList = $('<div class="red-ui-icon-list">').appendTo(picker); + var metaRow = $('<div class="red-ui-icon-meta"></div>').appendTo(picker); + var summary = $('<span>').appendTo(metaRow); + var resetButton = $('<button type="button" class="red-ui-button red-ui-button-small">'+RED._("editor.useDefault")+'</button>').appendTo(metaRow).on("click", function(e) { + e.preventDefault(); + iconPanel.hide(); + done(null); + }); + if (!backgroundColor && faOnly) { + iconList.addClass("red-ui-icon-list-dark"); + } + setTimeout(function() { + var iconSets = RED.nodes.getIconSets(); + Object.keys(iconSets).forEach(function(moduleName) { + if (faOnly && (moduleName !== "font-awesome")) { + return; + } + var icons = iconSets[moduleName]; + if (icons.length > 0) { + // selectIconModule.append($("<option></option>").val(moduleName).text(moduleName)); + var header = $('<div class="red-ui-icon-list-module"></div>').text(moduleName).appendTo(iconList); + $('<i class="fa fa-cube"></i>').prependTo(header); + icons.forEach(function(icon) { + var iconDiv = $('<div>',{class:"red-ui-icon-list-icon"}).appendTo(iconList); + var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(iconDiv); + var icon_url = RED.settings.apiRootUrl+"icons/"+moduleName+"/"+icon; + iconDiv.data('icon',icon_url); + if (backgroundColor) { + nodeDiv.css({ + 'backgroundColor': backgroundColor + }); + } + var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv); + RED.utils.createIconElement(icon_url, iconContainer, true); + + if (iconPath.module === moduleName && iconPath.file === icon) { + iconDiv.addClass("selected"); + } + iconDiv.on("mouseover", function() { + summary.text(icon); + }) + iconDiv.on("mouseout", function() { + summary.html("&nbsp;"); + }) + iconDiv.on("click", function() { + iconPanel.hide(); + done(moduleName+"/"+icon); + }) + }) + } + }); + setTimeout(function() { + spinner.remove(); + },50); + },300); + var spinner = RED.utils.addSpinnerOverlay(iconList,true); + var iconPanel = RED.popover.panel(picker); + iconPanel.show({ + target: container + }) + + + picker.slideDown(100); + searchInput.trigger("focus"); + } + + function createColorPicker(colorRow, color) { + + var colorButton = $('<button type="button" class="red-ui-button red-ui-editor-node-appearance-button">').appendTo(colorRow); + $('<i class="fa fa-caret-down"></i>').appendTo(colorButton); + + var colorDisp = $('<div>',{class:"red-ui-search-result-node"}).appendTo(colorButton); + + var selector = $("<input/>", { + id: "red-ui-editor-node-color", + type: "text", + value: color + }).css({ + marginLeft: "10px", + width: "150px", + }).appendTo(colorRow); + + selector.on("change", function (e) { + var color = selector.val(); + $(".red-ui-editor-node-appearance-button .red-ui-search-result-node").css({ + "background-color": color + }); + }); + selector.trigger("change"); + colorButton.on("click", function (e) { + var recommendedColors = [ + "#DDAA99", + "#3FADB5", "#87A980", "#A6BBCF", + "#AAAA66", "#C0C0C0", "#C0DEED", + "#C7E9C0", "#D7D7A0", "#D8BFD8", + "#DAC4B4", "#DEB887", "#DEBD5C", + "#E2D96E", "#E6E0F8", "#E7E7AE", + "#E9967A", "#F3B567", "#FDD0A2", + "#FDF0C2", "#FFAAAA", "#FFCC66", + "#FFF0F0", "#FFFFFF" + ].map(function(c) { + var r = parseInt(c.substring(1, 3), 16) / 255; + var g = parseInt(c.substring(3, 5), 16) / 255; + var b = parseInt(c.substring(5, 7), 16) / 255; + return { + hex: c, + r: r, + g: g, + b: b, + l: 0.3 * r + 0.59 * g + 0.11 * b + } + }); + // Sort by luminosity. + recommendedColors.sort(function (a, b) { + return a.l - b.l; + }); + + var numColors = recommendedColors.length; + var width = 30; + var height = 30; + var margin = 2; + var perRow = 6; + var picker = $("<div/>", { + class: "red-ui-color-picker" + }).css({ + width: ((width+margin+margin)*perRow)+"px", + height: Math.ceil(numColors/perRow)*(height+margin+margin)+"+px" + }); + var count = 0; + var row = null; + recommendedColors.forEach(function (col) { + if ((count % perRow) == 0) { + row = $("<div/>").appendTo(picker); + } + var button = $("<button/>", { + }).css({ + width: width+"px", + height: height+"px", + margin: margin+"px", + backgroundColor: col.hex, + "border-style": "solid", + "border-width": "1px", + "border-color": col.luma<0.92?col.hex:'#ccc' + }).appendTo(row); + button.on("click", function (e) { + e.preventDefault(); + colorPanel.hide(); + selector.val(col.hex); + selector.trigger("change"); + }); + count++; + }); + var colorPanel = RED.popover.panel(picker); + colorPanel.show({ + target: colorButton + }) + }); + } + + function buildAppearanceForm(container,node) { + var dialogForm = $('<form class="dialog-form form-horizontal" autocomplete="off"></form>').appendTo(container); + + var i,row; + + if (node.type === "subflow") { + var categoryRow = $("<div/>", { + class: "form-row" + }).appendTo(dialogForm); + $("<label/>", { + for: "subflow-appearance-input-category", + "data-i18n": "editor:subflow.category" + }).appendTo(categoryRow); + var categorySelector = $("<select/>", { + id: "subflow-appearance-input-category" + }).css({ + width: "250px" + }).appendTo(categoryRow); + $("<input/>", { + type: "text", + id: "subflow-appearance-input-custom-category" + }).css({ + display: "none", + "margin-left": "10px", + width: "calc(100% - 250px)" + }).appendTo(categoryRow); + + var categories = RED.palette.getCategories(); + categories.sort(function(A,B) { + return A.label.localeCompare(B.label); + }) + categories.forEach(function(cat) { + categorySelector.append($("<option/>").val(cat.id).text(cat.label)); + }) + categorySelector.append($("<option/>").attr('disabled',true).text("---")); + categorySelector.append($("<option/>").val("_custom_").text(RED._("palette.addCategory"))); + + $("#subflow-appearance-input-category").on("change", function() { + var val = $(this).val(); + if (val === "_custom_") { + $("#subflow-appearance-input-category").width(120); + $("#subflow-appearance-input-custom-category").show(); + } else { + $("#subflow-appearance-input-category").width(250); + $("#subflow-appearance-input-custom-category").hide(); + } + }) + + $("#subflow-appearance-input-category").val(node.category||"subflows"); + var userCount = 0; + var subflowType = "subflow:"+node.id; + + RED.nodes.eachNode(function(n) { + if (n.type === subflowType) { + userCount++; + } + }); + $("#red-ui-editor-subflow-user-count") + .text(RED._("subflow.subflowInstances", {count:userCount})).show(); + } + + $('<div class="form-row">'+ + '<label for="node-input-show-label-btn" data-i18n="editor.label"></label>'+ + '<span style="margin-right: 2px;"/>'+ + '<input type="checkbox" id="node-input-show-label"/>'+ + '</div>').appendTo(dialogForm); + + $("#node-input-show-label").toggleButton({ + enabledLabel: RED._("editor.show"), + disabledLabel: RED._("editor.hide") + }) + + if (!node.hasOwnProperty("l")) { + // Show label if type not link + node.l = !/^link (in|out)$/.test(node._def.type); + } + $("#node-input-show-label").prop("checked",node.l).trigger("change"); + + if (node.type === "subflow") { + // subflow template can select its color + var color = node.color ? node.color : "#DDAA99"; + var colorRow = $("<div/>", { + class: "form-row" + }).appendTo(dialogForm); + $("<label/>").text(RED._("editor.color")).appendTo(colorRow); + createColorPicker(colorRow, color); + } + + + // If a node has icon property in defaults, the icon of the node cannot be modified. (e.g, ui_button node in dashboard) + if ((!node._def.defaults || !node._def.defaults.hasOwnProperty("icon"))) { + var iconRow = $('<div class="form-row"></div>').appendTo(dialogForm); + $('<label data-i18n="editor.settingIcon">').appendTo(iconRow); + + var iconButton = $('<button type="button" class="red-ui-button red-ui-editor-node-appearance-button">').appendTo(iconRow); + $('<i class="fa fa-caret-down"></i>').appendTo(iconButton); + var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(iconButton); + var colour = RED.utils.getNodeColor(node.type, node._def); + var icon_url = RED.utils.getNodeIcon(node._def,node); + nodeDiv.css('backgroundColor',colour); + var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv); + RED.utils.createIconElement(icon_url, iconContainer, true); + + iconButton.on("click", function(e) { + e.preventDefault(); + var iconPath; + var icon = $("#red-ui-editor-node-icon").val()||""; + if (icon) { + iconPath = RED.utils.separateIconPath(icon); + } else { + iconPath = RED.utils.getDefaultNodeIcon(node._def, node); + } + var backgroundColor = RED.utils.getNodeColor(node.type, node._def); + if (node.type === "subflow") { + backgroundColor = $("#red-ui-editor-node-color").val(); + } + showIconPicker(iconButton,backgroundColor,iconPath,false,function(newIcon) { + $("#red-ui-editor-node-icon").val(newIcon||""); + var icon_url = RED.utils.getNodeIcon(node._def,{type:node.type,icon:newIcon}); + RED.utils.createIconElement(icon_url, iconContainer, true); + }); + }); + + RED.popover.tooltip(iconButton, function() { + return $("#red-ui-editor-node-icon").val() || RED._("editor.default"); + }) + $('<input type="hidden" id="red-ui-editor-node-icon">').val(node.icon).appendTo(iconRow); + } + + + $('<div class="form-row"><span data-i18n="editor.portLabels"></span></div>').appendTo(dialogForm); + + var inputCount = node.inputs || node._def.inputs || 0; + var outputCount = node.outputs || node._def.outputs || 0; + if (node.type === 'subflow') { + inputCount = node.in.length; + outputCount = node.out.length; + } + + var inputLabels = node.inputLabels || []; + var outputLabels = node.outputLabels || []; + + var inputPlaceholder = node._def.inputLabels?RED._("editor.defaultLabel"):RED._("editor.noDefaultLabel"); + var outputPlaceholder = node._def.outputLabels?RED._("editor.defaultLabel"):RED._("editor.noDefaultLabel"); + + $('<div class="form-row"><span style="margin-left: 50px;" data-i18n="editor.labelInputs"></span><div id="red-ui-editor-node-label-form-inputs"></div></div>').appendTo(dialogForm); + var inputsDiv = $("#red-ui-editor-node-label-form-inputs"); + if (inputCount > 0) { + for (i=0;i<inputCount;i++) { + buildLabelRow("input",i,inputLabels[i],inputPlaceholder).appendTo(inputsDiv); + } + } else { + buildLabelRow().appendTo(inputsDiv); + } + $('<div class="form-row"><span style="margin-left: 50px;" data-i18n="editor.labelOutputs"></span><div id="red-ui-editor-node-label-form-outputs"></div></div>').appendTo(dialogForm); + var outputsDiv = $("#red-ui-editor-node-label-form-outputs"); + if (outputCount > 0) { + for (i=0;i<outputCount;i++) { + buildLabelRow("output",i,outputLabels[i],outputPlaceholder).appendTo(outputsDiv); + } + } else { + buildLabelRow().appendTo(outputsDiv); + } + } + + + function updateLabels(editing_node, changes, outputMap) { + var inputLabels = $("#red-ui-editor-node-label-form-inputs").children().find("input"); + var outputLabels = $("#red-ui-editor-node-label-form-outputs").children().find("input"); + + var hasNonBlankLabel = false; + var changed = false; + var newValue = inputLabels.map(function() { + var v = $(this).val(); + hasNonBlankLabel = hasNonBlankLabel || v!== ""; + return v; + }).toArray().slice(0,editing_node.inputs); + if ((editing_node.inputLabels === undefined && hasNonBlankLabel) || + (editing_node.inputLabels !== undefined && JSON.stringify(newValue) !== JSON.stringify(editing_node.inputLabels))) { + changes.inputLabels = editing_node.inputLabels; + editing_node.inputLabels = newValue; + changed = true; + } + hasNonBlankLabel = false; + newValue = new Array(editing_node.outputs); + outputLabels.each(function() { + var index = $(this).attr('id').substring("red-ui-editor-node-label-form-output-".length); + if (outputMap && outputMap.hasOwnProperty(index)) { + index = parseInt(outputMap[index]); + if (index === -1) { + return; + } + } + var v = $(this).val(); + hasNonBlankLabel = hasNonBlankLabel || v!== ""; + newValue[index] = v; + }); + + if ((editing_node.outputLabels === undefined && hasNonBlankLabel) || + (editing_node.outputLabels !== undefined && JSON.stringify(newValue) !== JSON.stringify(editing_node.outputLabels))) { + changes.outputLabels = editing_node.outputLabels; + editing_node.outputLabels = newValue; + changed = true; + } + return changed; + } + + function buildDescriptionForm(container,node) { + var dialogForm = $('<form class="dialog-form form-horizontal" autocomplete="off"></form>').appendTo(container); + var toolbarRow = $('<div></div>').appendTo(dialogForm); + var row = $('<div class="form-row node-text-editor-row" style="position:relative; padding-top: 4px; height: 100%"></div>').appendTo(dialogForm); + $('<div style="height: 100%" class="node-text-editor" id="node-info-input-info-editor" ></div>').appendTo(row); + var nodeInfoEditor = RED.editor.createEditor({ + id: "node-info-input-info-editor", + mode: 'ace/mode/markdown', + value: "" + }); + if (node.info) { + nodeInfoEditor.getSession().setValue(node.info, -1); + } + return nodeInfoEditor; + } + + function showEditDialog(node) { + var editing_node = node; + var isDefaultIcon; + var defaultIcon; + var nodeInfoEditor; + var finishedBuilding = false; + + editStack.push(node); + RED.view.state(RED.state.EDITING); + var type = node.type; + if (node.type.substring(0,8) == "subflow:") { + type = "subflow"; + } + var trayOptions = { + title: getEditStackTitle(), + buttons: [ + { + id: "node-dialog-delete", + class: 'leftButton', + text: RED._("common.label.delete"), + click: function() { + var startDirty = RED.nodes.dirty(); + var removedNodes = []; + var removedLinks = []; + var removedEntities = RED.nodes.remove(editing_node.id); + removedNodes.push(editing_node); + removedNodes = removedNodes.concat(removedEntities.nodes); + removedLinks = removedLinks.concat(removedEntities.links); + + var historyEvent = { + t:'delete', + nodes:removedNodes, + links:removedLinks, + changes: {}, + dirty: startDirty + } + + RED.nodes.dirty(true); + RED.view.redraw(true); + RED.history.push(historyEvent); + RED.tray.close(); + } + }, + { + id: "node-dialog-cancel", + text: RED._("common.label.cancel"), + click: function() { + if (editing_node._def) { + if (editing_node._def.oneditcancel) { + try { + editing_node._def.oneditcancel.call(editing_node); + } catch(err) { + console.log("oneditcancel",editing_node.id,editing_node.type,err.toString()); + } + } + + for (var d in editing_node._def.defaults) { + if (editing_node._def.defaults.hasOwnProperty(d)) { + var def = editing_node._def.defaults[d]; + if (def.type) { + var configTypeDef = RED.nodes.getType(def.type); + if (configTypeDef && configTypeDef.exclusive) { + var input = $("#node-input-"+d).val()||""; + if (input !== "" && !editing_node[d]) { + // This node has an exclusive config node that + // has just been added. As the user is cancelling + // the edit, need to delete the just-added config + // node so that it doesn't get orphaned. + RED.nodes.remove(input); + } + } + } + } + + } + } + RED.tray.close(); + } + }, + { + id: "node-dialog-ok", + text: RED._("common.label.done"), + class: "primary", + click: function() { + var changes = {}; + var changed = false; + var wasDirty = RED.nodes.dirty(); + var d; + var outputMap; + + if (editing_node._def.oneditsave) { + var oldValues = {}; + for (d in editing_node._def.defaults) { + if (editing_node._def.defaults.hasOwnProperty(d)) { + if (typeof editing_node[d] === "string" || typeof editing_node[d] === "number") { + oldValues[d] = editing_node[d]; + } else { + oldValues[d] = $.extend(true,{},{v:editing_node[d]}).v; + } + } + } + try { + var rc = editing_node._def.oneditsave.call(editing_node); + if (rc === true) { + changed = true; + } + } catch(err) { + console.log("oneditsave",editing_node.id,editing_node.type,err.toString()); + } + + for (d in editing_node._def.defaults) { + if (editing_node._def.defaults.hasOwnProperty(d)) { + if (oldValues[d] === null || typeof oldValues[d] === "string" || typeof oldValues[d] === "number") { + if (oldValues[d] !== editing_node[d]) { + changes[d] = oldValues[d]; + changed = true; + } + } else { + if (JSON.stringify(oldValues[d]) !== JSON.stringify(editing_node[d])) { + changes[d] = oldValues[d]; + changed = true; + } + } + } + } + } + + var newValue; + if (editing_node._def.defaults) { + for (d in editing_node._def.defaults) { + if (editing_node._def.defaults.hasOwnProperty(d)) { + var input = $("#node-input-"+d); + if (input.attr('type') === "checkbox") { + newValue = input.prop('checked'); + } else if (input.prop("nodeName") === "select" && input.attr("multiple") === "multiple") { + // An empty select-multiple box returns null. + // Need to treat that as an empty array. + newValue = input.val(); + if (newValue == null) { + newValue = []; + } + } else if ("format" in editing_node._def.defaults[d] && editing_node._def.defaults[d].format !== "" && input[0].nodeName === "DIV") { + newValue = input.text(); + } else { + newValue = input.val(); + } + if (newValue != null) { + if (d === "outputs") { + if (newValue.trim() === "") { + continue; + } + if (isNaN(newValue)) { + outputMap = JSON.parse(newValue); + var outputCount = 0; + var outputsChanged = false; + var keys = Object.keys(outputMap); + keys.forEach(function(p) { + if (isNaN(p)) { + // New output; + outputCount ++; + delete outputMap[p]; + } else { + outputMap[p] = outputMap[p]+""; + if (outputMap[p] !== "-1") { + outputCount++; + if (outputMap[p] !== p) { + // Output moved + outputsChanged = true; + } else { + delete outputMap[p]; + } + } else { + // Output removed + outputsChanged = true; + } + } + }); + + newValue = outputCount; + if (outputsChanged) { + changed = true; + } + } else { + newValue = parseInt(newValue); + } + } + if (editing_node._def.defaults[d].type) { + if (newValue == "_ADD_") { + newValue = ""; + } + } + if (editing_node[d] != newValue) { + if (editing_node._def.defaults[d].type) { + // Change to a related config node + var configNode = RED.nodes.node(editing_node[d]); + if (configNode) { + var users = configNode.users; + users.splice(users.indexOf(editing_node),1); + } + configNode = RED.nodes.node(newValue); + if (configNode) { + configNode.users.push(editing_node); + } + } + changes[d] = editing_node[d]; + editing_node[d] = newValue; + changed = true; + } + } + } + } + } + if (editing_node._def.credentials) { + var prefix = 'node-input'; + var credDefinition = editing_node._def.credentials; + var credsChanged = updateNodeCredentials(editing_node,credDefinition,prefix); + changed = changed || credsChanged; + } + // if (editing_node.hasOwnProperty("_outputs")) { + // outputMap = editing_node._outputs; + // delete editing_node._outputs; + // if (Object.keys(outputMap).length > 0) { + // changed = true; + // } + // } + var removedLinks = updateNodeProperties(editing_node,outputMap); + + if (updateLabels(editing_node, changes, outputMap)) { + changed = true; + } + + if (!editing_node._def.defaults || !editing_node._def.defaults.hasOwnProperty("icon")) { + var icon = $("#red-ui-editor-node-icon").val()||"" + if (!isDefaultIcon) { + if (icon !== editing_node.icon) { + changes.icon = editing_node.icon; + editing_node.icon = icon; + changed = true; + } + } else { + if (icon !== "" && icon !== defaultIcon) { + changes.icon = editing_node.icon; + editing_node.icon = icon; + changed = true; + } else { + var iconPath = RED.utils.getDefaultNodeIcon(editing_node._def, editing_node); + var currentDefaultIcon = iconPath.module+"/"+iconPath.file; + if (defaultIcon !== currentDefaultIcon) { + changes.icon = editing_node.icon; + editing_node.icon = currentDefaultIcon; + changed = true; + } + } + } + } + + if (!$("#node-input-show-label").prop('checked')) { + // Not checked - hide label + if (!/^link (in|out)$/.test(node.type)) { + // Not a link node - default state is true + if (node.l !== false) { + changes.l = node.l + changed = true; + } + node.l = false; + } else { + // A link node - default state is false + if (node.hasOwnProperty('l') && node.l) { + changes.l = node.l + changed = true; + } + delete node.l; + } + } else { + // Checked - show label + if (!/^link (in|out)$/.test(node.type)) { + // Not a link node - default state is true + if (node.hasOwnProperty('l') && !node.l) { + changes.l = node.l + changed = true; + } + delete node.l; + } else { + if (!node.l) { + changes.l = node.l + changed = true; + } + node.l = true; + } + } + if ($("#node-input-node-disabled").prop('checked')) { + if (node.d !== true) { + changes.d = node.d; + changed = true; + node.d = true; + } + } else { + if (node.d === true) { + changes.d = node.d; + changed = true; + delete node.d; + } + } + + node.resize = true; + + var oldInfo = node.info; + if (nodeInfoEditor) { + var newInfo = nodeInfoEditor.getValue(); + if (!!oldInfo) { + // Has existing info property + if (newInfo.trim() === "") { + // New value is blank - remove the property + changed = true; + changes.info = oldInfo; + delete node.info; + } else if (newInfo !== oldInfo) { + // New value is different + changed = true; + changes.info = oldInfo; + node.info = newInfo; + } + } else { + // No existing info + if (newInfo.trim() !== "") { + // New value is not blank + changed = true; + changes.info = undefined; + node.info = newInfo; + } + } + } + + if (type === "subflow") { + var old_env = editing_node.env; + var new_env = RED.subflow.exportSubflowInstanceEnv(editing_node); + if (!isSameObj(old_env, new_env)) { + editing_node.env = new_env; + changes.env = editing_node.env; + changed = true; + } + } + + if (changed) { + var wasChanged = editing_node.changed; + editing_node.changed = true; + RED.nodes.dirty(true); + + var activeSubflow = RED.nodes.subflow(RED.workspaces.active()); + var subflowInstances = null; + if (activeSubflow) { + subflowInstances = []; + RED.nodes.eachNode(function(n) { + if (n.type == "subflow:"+RED.workspaces.active()) { + subflowInstances.push({ + id:n.id, + changed:n.changed + }); + n.changed = true; + n.dirty = true; + updateNodeProperties(n); + } + }); + } + var historyEvent = { + t:'edit', + node:editing_node, + changes:changes, + links:removedLinks, + dirty:wasDirty, + changed:wasChanged + }; + if (outputMap) { + historyEvent.outputMap = outputMap; + } + if (subflowInstances) { + historyEvent.subflow = { + instances:subflowInstances + } + } + RED.history.push(historyEvent); + } + editing_node.dirty = true; + validateNode(editing_node); + RED.events.emit("editor:save",editing_node); + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + editTrayWidthCache[type] = dimensions.width; + $(".red-ui-tray-content").height(dimensions.height - 50); + var form = $(".red-ui-tray-content form").height(dimensions.height - 50 - 40); + if (editing_node && editing_node._def.oneditresize) { + try { + editing_node._def.oneditresize.call(editing_node,{width:form.width(),height:form.height()}); + } catch(err) { + console.log("oneditresize",editing_node.id,editing_node.type,err.toString()); + } + } + }, + open: function(tray, done) { + var trayFooter = tray.find(".red-ui-tray-footer"); + var trayBody = tray.find('.red-ui-tray-body'); + trayBody.parent().css('overflow','hidden'); + + var trayFooterLeft = $('<div class="red-ui-tray-footer-left"></div>').appendTo(trayFooter) + + $('<input id="node-input-node-disabled" type="checkbox">').prop("checked",!!node.d).appendTo(trayFooterLeft).toggleButton({ + enabledIcon: "fa-circle-thin", + disabledIcon: "fa-ban", + invertState: true + }) + + var editorTabEl = $('<ul></ul>').appendTo(trayBody); + var editorContent = $('<div></div>').appendTo(trayBody); + + var editorTabs = RED.tabs.create({ + element:editorTabEl, + onchange:function(tab) { + editorContent.children().hide(); + if (tab.onchange) { + tab.onchange.call(tab); + } + tab.content.show(); + if (finishedBuilding) { + RED.tray.resize(); + } + }, + collapsible: true, + menu: false + }); + if (editing_node) { + RED.sidebar.info.refresh(editing_node); + } + var ns; + if (node._def.set.module === "node-red") { + ns = "node-red"; + } else { + ns = node._def.set.id; + } + var iconPath = RED.utils.getDefaultNodeIcon(node._def,node); + defaultIcon = iconPath.module+"/"+iconPath.file; + if (node.icon && node.icon !== defaultIcon) { + isDefaultIcon = false; + } else { + isDefaultIcon = true; + } + + var nodePropertiesTab = { + id: "editor-tab-properties", + label: RED._("editor-tab.properties"), + name: RED._("editor-tab.properties"), + content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-cog" + }; + buildEditForm(nodePropertiesTab.content,"dialog-form",type,ns,node); + editorTabs.addTab(nodePropertiesTab); + + if (/^subflow:/.test(node.type)) { + var subflowPropertiesTab = { + id: "editor-subflow-envProperties", + label: RED._("editor-tab.envProperties"), + name: RED._("editor-tab.envProperties"), + content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-list" + }; + + RED.subflow.buildPropertiesForm(subflowPropertiesTab.content,node); + editorTabs.addTab(subflowPropertiesTab); + } + + if (!node._def.defaults || !node._def.defaults.hasOwnProperty('info')) { + var descriptionTab = { + id: "editor-tab-description", + label: RED._("editor-tab.description"), + name: RED._("editor-tab.description"), + content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-file-text-o", + onchange: function() { + nodeInfoEditor.focus(); + } + }; + editorTabs.addTab(descriptionTab); + nodeInfoEditor = buildDescriptionForm(descriptionTab.content,node); + } + + var appearanceTab = { + id: "editor-tab-appearance", + label: RED._("editor-tab.appearance"), + name: RED._("editor-tab.appearance"), + content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-object-group", + onchange: function() { + refreshLabelForm(this.content,node); + } + }; + buildAppearanceForm(appearanceTab.content,node); + editorTabs.addTab(appearanceTab); + + prepareEditDialog(node,node._def,"node-input", function() { + trayBody.i18n(); + finishedBuilding = true; + done(); + }); + }, + close: function() { + if (RED.view.state() != RED.state.IMPORT_DRAGGING) { + RED.view.state(RED.state.DEFAULT); + } + if (editing_node) { + RED.sidebar.info.refresh(editing_node); + } + RED.workspaces.refresh(); + if (nodeInfoEditor) { + nodeInfoEditor.destroy(); + nodeInfoEditor = null; + } + RED.view.redraw(true); + editStack.pop(); + }, + show: function() { + if (editing_node) { + RED.sidebar.info.refresh(editing_node); + } + } + } + if (editTrayWidthCache.hasOwnProperty(type)) { + trayOptions.width = editTrayWidthCache[type]; + } + + if (type === 'subflow') { + var id = editing_node.type.substring(8); + trayOptions.buttons.unshift({ + class: 'leftButton', + text: RED._("subflow.edit"), + click: function() { + RED.workspaces.show(id); + $("#node-dialog-ok").trigger("click"); + } + }); + } + + RED.tray.show(trayOptions); + } + /** + * name - name of the property that holds this config node + * type - type of config node + * id - id of config node to edit. _ADD_ for a new one + * prefix - the input prefix of the parent property + */ + function showEditConfigNodeDialog(name,type,id,prefix) { + var adding = (id == "_ADD_"); + var node_def = RED.nodes.getType(type); + var editing_config_node = RED.nodes.node(id); + var nodeInfoEditor; + var finishedBuilding = false; + + var ns; + if (node_def.set.module === "node-red") { + ns = "node-red"; + } else { + ns = node_def.set.id; + } + var configNodeScope = ""; // default to global + var activeSubflow = RED.nodes.subflow(RED.workspaces.active()); + if (activeSubflow) { + configNodeScope = activeSubflow.id; + } + if (editing_config_node == null) { + editing_config_node = { + id: RED.nodes.id(), + _def: node_def, + type: type, + z: configNodeScope, + users: [] + } + for (var d in node_def.defaults) { + if (node_def.defaults[d].value) { + editing_config_node[d] = JSON.parse(JSON.stringify(node_def.defaults[d].value)); + } + } + editing_config_node["_"] = node_def._; + } + editStack.push(editing_config_node); + + RED.view.state(RED.state.EDITING); + var trayOptions = { + title: getEditStackTitle(), //(adding?RED._("editor.addNewConfig", {type:type}):RED._("editor.editConfig", {type:type})), + resize: function(dimensions) { + $(".red-ui-tray-content").height(dimensions.height - 50); + if (editing_config_node && editing_config_node._def.oneditresize) { + var form = $("#node-config-dialog-edit-form"); + try { + editing_config_node._def.oneditresize.call(editing_config_node,{width:form.width(),height:form.height()}); + } catch(err) { + console.log("oneditresize",editing_config_node.id,editing_config_node.type,err.toString()); + } + } + }, + open: function(tray, done) { + var trayHeader = tray.find(".red-ui-tray-header"); + var trayBody = tray.find('.red-ui-tray-body'); + var trayFooter = tray.find(".red-ui-tray-footer"); + + var trayFooterLeft = $('<div class="red-ui-tray-footer-left"></div>').appendTo(trayFooter) + + $('<input id="node-config-input-node-disabled" type="checkbox">').prop("checked",!!editing_config_node.d).appendTo(trayFooterLeft).toggleButton({ + enabledIcon: "fa-circle-thin", + disabledIcon: "fa-ban", + invertState: true + }) + + if (node_def.hasUsers !== false) { + $('<span><i class="fa fa-info-circle"></i> <span id="red-ui-editor-config-user-count"></span></span>').css("margin-left", "10px").appendTo(trayFooterLeft); + } + trayFooter.append('<span class="red-ui-tray-footer-right"><span id="red-ui-editor-config-scope-warning" data-i18n="[title]editor.errors.scopeChange"><i class="fa fa-warning"></i></span><select id="red-ui-editor-config-scope"></select></span>'); + + var editorTabEl = $('<ul></ul>').appendTo(trayBody); + var editorContent = $('<div></div>').appendTo(trayBody); + + var editorTabs = RED.tabs.create({ + element:editorTabEl, + onchange:function(tab) { + editorContent.children().hide(); + if (tab.onchange) { + tab.onchange.call(tab); + } + tab.content.show(); + if (finishedBuilding) { + RED.tray.resize(); + } + }, + collapsible: true, + menu: false + }); + + var nodePropertiesTab = { + id: "editor-tab-cproperties", + label: RED._("editor-tab.properties"), + name: RED._("editor-tab.properties"), + content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-cog" + }; + editorTabs.addTab(nodePropertiesTab); + buildEditForm(nodePropertiesTab.content,"node-config-dialog-edit-form",type,ns); + + if (!node_def.defaults || !node_def.defaults.hasOwnProperty('info')) { + var descriptionTab = { + id: "editor-tab-description", + label: RED._("editor-tab.description"), + name: RED._("editor-tab.description"), + content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-file-text-o", + onchange: function() { + nodeInfoEditor.focus(); + } + }; + editorTabs.addTab(descriptionTab); + nodeInfoEditor = buildDescriptionForm(descriptionTab.content,editing_config_node); + } + + + prepareEditDialog(editing_config_node,node_def,"node-config-input", function() { + if (editing_config_node._def.exclusive) { + $("#red-ui-editor-config-scope").hide(); + } else { + $("#red-ui-editor-config-scope").show(); + } + $("#red-ui-editor-config-scope-warning").hide(); + + var nodeUserFlows = {}; + editing_config_node.users.forEach(function(n) { + nodeUserFlows[n.z] = true; + }); + var flowCount = Object.keys(nodeUserFlows).length; + var tabSelect = $("#red-ui-editor-config-scope").empty(); + tabSelect.off("change"); + tabSelect.append('<option value=""'+(!editing_config_node.z?" selected":"")+' data-i18n="sidebar.config.global"></option>'); + tabSelect.append('<option disabled data-i18n="sidebar.config.flows"></option>'); + RED.nodes.eachWorkspace(function(ws) { + var workspaceLabel = ws.label; + if (nodeUserFlows[ws.id]) { + workspaceLabel = "* "+workspaceLabel; + } + $('<option value="'+ws.id+'"'+(ws.id==editing_config_node.z?" selected":"")+'></option>').text(workspaceLabel).appendTo(tabSelect); + }); + tabSelect.append('<option disabled data-i18n="sidebar.config.subflows"></option>'); + RED.nodes.eachSubflow(function(ws) { + var workspaceLabel = ws.name; + if (nodeUserFlows[ws.id]) { + workspaceLabel = "* "+workspaceLabel; + } + $('<option value="'+ws.id+'"'+(ws.id==editing_config_node.z?" selected":"")+'></option>').text(workspaceLabel).appendTo(tabSelect); + }); + if (flowCount > 0) { + tabSelect.on('change',function() { + var newScope = $(this).val(); + if (newScope === '') { + // global scope - everyone can use it + $("#red-ui-editor-config-scope-warning").hide(); + } else if (!nodeUserFlows[newScope] || flowCount > 1) { + // a user will loose access to it + $("#red-ui-editor-config-scope-warning").show(); + } else { + $("#red-ui-editor-config-scope-warning").hide(); + } + }); + } + if (node_def.hasUsers !== false) { + $("#red-ui-editor-config-user-count").text(RED._("editor.nodesUse", {count:editing_config_node.users.length})).parent().show(); + } + trayBody.i18n(); + trayFooter.i18n(); + finishedBuilding = true; + done(); + }); + }, + close: function() { + RED.workspaces.refresh(); + if (nodeInfoEditor) { + nodeInfoEditor.destroy(); + nodeInfoEditor = null; + } + editStack.pop(); + }, + show: function() { + if (editing_config_node) { + RED.sidebar.info.refresh(editing_config_node); + } + } + } + trayOptions.buttons = [ + { + id: "node-config-dialog-cancel", + text: RED._("common.label.cancel"), + click: function() { + var configType = type; + var configId = editing_config_node.id; + var configAdding = adding; + var configTypeDef = RED.nodes.getType(configType); + if (configTypeDef.oneditcancel) { + // TODO: what to pass as this to call + if (configTypeDef.oneditcancel) { + var cn = RED.nodes.node(configId); + if (cn) { + try { + configTypeDef.oneditcancel.call(cn,false); + } catch(err) { + console.log("oneditcancel",cn.id,cn.type,err.toString()); + } + } else { + try { + configTypeDef.oneditcancel.call({id:configId},true); + } catch(err) { + console.log("oneditcancel",configId,configType,err.toString()); + } + } + } + } + RED.tray.close(); + } + }, + { + id: "node-config-dialog-ok", + text: adding?RED._("editor.configAdd"):RED._("editor.configUpdate"), + class: "primary", + click: function() { + var configProperty = name; + var configId = editing_config_node.id; + var configType = type; + var configAdding = adding; + var configTypeDef = RED.nodes.getType(configType); + var d; + var input; + var scope = $("#red-ui-editor-config-scope").val(); + + if (configTypeDef.oneditsave) { + try { + configTypeDef.oneditsave.call(editing_config_node); + } catch(err) { + console.log("oneditsave",editing_config_node.id,editing_config_node.type,err.toString()); + } + } + + for (d in configTypeDef.defaults) { + if (configTypeDef.defaults.hasOwnProperty(d)) { + var newValue; + input = $("#node-config-input-"+d); + if (input.attr('type') === "checkbox") { + newValue = input.prop('checked'); + } else if ("format" in configTypeDef.defaults[d] && configTypeDef.defaults[d].format !== "" && input[0].nodeName === "DIV") { + newValue = input.text(); + } else { + newValue = input.val(); + } + if (newValue != null && newValue !== editing_config_node[d]) { + if (editing_config_node._def.defaults[d].type) { + if (newValue == "_ADD_") { + newValue = ""; + } + // Change to a related config node + var configNode = RED.nodes.node(editing_config_node[d]); + if (configNode) { + var users = configNode.users; + users.splice(users.indexOf(editing_config_node),1); + } + configNode = RED.nodes.node(newValue); + if (configNode) { + configNode.users.push(editing_config_node); + } + } + editing_config_node[d] = newValue; + } + } + } + + if (nodeInfoEditor) { + editing_config_node.info = nodeInfoEditor.getValue(); + + var oldInfo = editing_config_node.info; + if (nodeInfoEditor) { + var newInfo = nodeInfoEditor.getValue(); + if (!!oldInfo) { + // Has existing info property + if (newInfo.trim() === "") { + // New value is blank - remove the property + delete editing_config_node.info; + } else if (newInfo !== oldInfo) { + // New value is different + editing_config_node.info = newInfo; + } + } else { + // No existing info + if (newInfo.trim() !== "") { + // New value is not blank + editing_config_node.info = newInfo; + } + } + } + } + editing_config_node.label = configTypeDef.label; + editing_config_node.z = scope; + + if ($("#node-config-input-node-disabled").prop('checked')) { + if (editing_config_node.d !== true) { + editing_config_node.d = true; + } + } else { + if (editing_config_node.d === true) { + delete editing_config_node.d; + } + } + + if (scope) { + // Search for nodes that use this one that are no longer + // in scope, so must be removed + editing_config_node.users = editing_config_node.users.filter(function(n) { + var keep = true; + for (var d in n._def.defaults) { + if (n._def.defaults.hasOwnProperty(d)) { + if (n._def.defaults[d].type === editing_config_node.type && + n[d] === editing_config_node.id && + n.z !== scope) { + keep = false; + // Remove the reference to this node + // and revalidate + n[d] = null; + n.dirty = true; + n.changed = true; + validateNode(n); + } + } + } + return keep; + }); + } + + if (configAdding) { + RED.nodes.add(editing_config_node); + } + + if (configTypeDef.credentials) { + updateNodeCredentials(editing_config_node,configTypeDef.credentials,"node-config-input"); + } + validateNode(editing_config_node); + var validatedNodes = {}; + validatedNodes[editing_config_node.id] = true; + + var userStack = editing_config_node.users.slice(); + while(userStack.length > 0) { + var user = userStack.pop(); + if (!validatedNodes[user.id]) { + validatedNodes[user.id] = true; + if (user.users) { + userStack = userStack.concat(user.users); + } + validateNode(user); + } + } + RED.nodes.dirty(true); + RED.view.redraw(true); + if (!configAdding) { + RED.events.emit("editor:save",editing_config_node); + } + RED.tray.close(function() { + updateConfigNodeSelect(configProperty,configType,editing_config_node.id,prefix); + }); + } + } + ]; + + if (!adding) { + trayOptions.buttons.unshift({ + class: 'leftButton', + text: RED._("editor.configDelete"), //'<i class="fa fa-trash"></i>', + click: function() { + var configProperty = name; + var configId = editing_config_node.id; + var configType = type; + var configTypeDef = RED.nodes.getType(configType); + + try { + + if (configTypeDef.ondelete) { + // Deprecated: never documented but used by some early nodes + console.log("Deprecated API warning: config node type ",configType," has an ondelete function - should be oneditdelete"); + configTypeDef.ondelete.call(editing_config_node); + } + if (configTypeDef.oneditdelete) { + configTypeDef.oneditdelete.call(editing_config_node); + } + } catch(err) { + console.log("oneditdelete",editing_config_node.id,editing_config_node.type,err.toString()); + } + + var historyEvent = { + t:'delete', + nodes:[editing_config_node], + changes: {}, + dirty: RED.nodes.dirty() + } + for (var i=0;i<editing_config_node.users.length;i++) { + var user = editing_config_node.users[i]; + historyEvent.changes[user.id] = { + changed: user.changed, + valid: user.valid + }; + for (var d in user._def.defaults) { + if (user._def.defaults.hasOwnProperty(d) && user[d] == configId) { + historyEvent.changes[user.id][d] = configId + user[d] = ""; + user.changed = true; + user.dirty = true; + } + } + validateNode(user); + } + RED.nodes.remove(configId); + RED.nodes.dirty(true); + RED.view.redraw(true); + RED.history.push(historyEvent); + RED.tray.close(function() { + updateConfigNodeSelect(configProperty,configType,"",prefix); + }); + } + }); + } + + RED.tray.show(trayOptions); + } + + function defaultConfigNodeSort(A,B) { + if (A.__label__ < B.__label__) { + return -1; + } else if (A.__label__ > B.__label__) { + return 1; + } + return 0; + } + + function updateConfigNodeSelect(name,type,value,prefix) { + // if prefix is null, there is no config select to update + if (prefix) { + var button = $("#"+prefix+"-edit-"+name); + if (button.length) { + if (value) { + button.text(RED._("editor.configEdit")); + } else { + button.text(RED._("editor.configAdd")); + } + $("#"+prefix+"-"+name).val(value); + } else { + + var select = $("#"+prefix+"-"+name); + var node_def = RED.nodes.getType(type); + select.children().remove(); + + var activeWorkspace = RED.nodes.workspace(RED.workspaces.active()); + if (!activeWorkspace) { + activeWorkspace = RED.nodes.subflow(RED.workspaces.active()); + } + + var configNodes = []; + + RED.nodes.eachConfig(function(config) { + if (config.type == type && (!config.z || config.z === activeWorkspace.id)) { + var label = RED.utils.getNodeLabel(config,config.id); + config.__label__ = label+(config.d?" ["+RED._("workspace.disabled")+"]":""); + configNodes.push(config); + } + }); + var configSortFn = defaultConfigNodeSort; + if (typeof node_def.sort == "function") { + configSortFn = node_def.sort; + } + try { + configNodes.sort(configSortFn); + } catch(err) { + console.log("Definition error: "+node_def.type+".sort",err); + } + + configNodes.forEach(function(cn) { + $('<option value="'+cn.id+'"'+(value==cn.id?" selected":"")+'></option>').text(RED.text.bidi.enforceTextDirectionWithUCC(cn.__label__)).appendTo(select); + delete cn.__label__; + }); + + select.append('<option value="_ADD_"'+(value===""?" selected":"")+'>'+RED._("editor.addNewType", {type:type})+'</option>'); + window.setTimeout(function() { select.trigger("change");},50); + } + } + } + + function showEditSubflowDialog(subflow) { + var editing_node = subflow; + editStack.push(subflow); + RED.view.state(RED.state.EDITING); + var subflowEditor; + var finishedBuilding = false; + var trayOptions = { + title: getEditStackTitle(), + buttons: [ + { + id: "node-dialog-cancel", + text: RED._("common.label.cancel"), + click: function() { + RED.tray.close(); + } + }, + { + id: "node-dialog-ok", + class: "primary", + text: RED._("common.label.done"), + click: function() { + var i; + var changes = {}; + var changed = false; + var wasDirty = RED.nodes.dirty(); + + var newName = $("#subflow-input-name").val(); + + if (newName != editing_node.name) { + changes['name'] = editing_node.name; + editing_node.name = newName; + changed = true; + } + + var newDescription = subflowEditor.getValue(); + + if (newDescription != editing_node.info) { + changes['info'] = editing_node.info; + editing_node.info = newDescription; + changed = true; + } + if (updateLabels(editing_node, changes, null)) { + changed = true; + } + var icon = $("#red-ui-editor-node-icon").val()||""; + if ((editing_node.icon === undefined && icon !== "node-red/subflow.svg") || + (editing_node.icon !== undefined && editing_node.icon !== icon)) { + changes.icon = editing_node.icon; + editing_node.icon = icon; + changed = true; + } + var newCategory = $("#subflow-appearance-input-category").val().trim(); + if (newCategory === "_custom_") { + newCategory = $("#subflow-appearance-input-custom-category").val().trim(); + if (newCategory === "") { + newCategory = editing_node.category; + } + } + if (newCategory === 'subflows') { + newCategory = ''; + } + if (newCategory != editing_node.category) { + changes['category'] = editing_node.category; + editing_node.category = newCategory; + changed = true; + } + + var oldColor = editing_node.color; + var newColor = $("#red-ui-editor-node-color").val(); + if (oldColor !== newColor) { + editing_node.color = newColor; + changes.color = newColor; + changed = true; + RED.utils.clearNodeColorCache(); + if (editing_node.type === "subflow") { + var nodeDefinition = RED.nodes.getType( + "subflow:" + editing_node.id + ); + nodeDefinition["color"] = newColor; + } + } + + var old_env = editing_node.env; + var new_env = RED.subflow.exportSubflowTemplateEnv($("#node-input-env-container").editableList("items")); + if (!isSameObj(old_env, new_env)) { + editing_node.env = new_env; + changes.env = editing_node.env; + changed = true; + } + RED.palette.refresh(); + + if (changed) { + var wasChanged = editing_node.changed; + editing_node.changed = true; + validateNode(editing_node); + var subflowInstances = []; + RED.nodes.eachNode(function(n) { + if (n.type == "subflow:"+editing_node.id) { + subflowInstances.push({ + id:n.id, + changed:n.changed + }) + n._def.color = editing_node.color; + n.changed = true; + n.dirty = true; + updateNodeProperties(n); + validateNode(n); + } + }); + RED.nodes.dirty(true); + var historyEvent = { + t:'edit', + node:editing_node, + changes:changes, + dirty:wasDirty, + changed:wasChanged, + subflow: { + instances:subflowInstances + } + }; + + RED.history.push(historyEvent); + } + editing_node.dirty = true; + RED.tray.close(); + } + } + ], + resize: function(size) { + $(".red-ui-tray-content").height(size.height - 50); + var envContainer = $("#node-input-env-container"); + if (envContainer.length) { + // var form = $(".red-ui-tray-content form").height(size.height - 50 - 40); + var rows = $("#dialog-form>div:not(#subflow-env-tabs-content)"); + var height = size.height; + for (var i=0; i<rows.size(); i++) { + height -= $(rows[i]).outerHeight(true); + } + // var editorRow = $("#dialog-form>div.node-input-env-container-row"); + // height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); + $("#node-input-env-container").editableList('height',height-95); + } + }, + open: function(tray) { + var trayFooter = tray.find(".red-ui-tray-footer"); + var trayFooterLeft = $("<div/>", { + class: "red-ui-tray-footer-left" + }).appendTo(trayFooter) + var trayBody = tray.find('.red-ui-tray-body'); + trayBody.parent().css('overflow','hidden'); + + if (editing_node.type === "subflow") { + var span = $("<span/>").css({ + "margin-left": "10px" + }).appendTo(trayFooterLeft); + $("<i/>", { + class: "fa fa-info-circle" + }).appendTo(span); + $("<span/>").text(" ").appendTo(span); + $("<i/>", { + id: "red-ui-editor-subflow-user-count" + }).appendTo(span); + } + + if (editing_node) { + RED.sidebar.info.refresh(editing_node); + } + + var editorTabEl = $('<ul></ul>').appendTo(trayBody); + var editorContent = $('<div></div>').appendTo(trayBody); + + var editorTabs = RED.tabs.create({ + element:editorTabEl, + onchange:function(tab) { + editorContent.children().hide(); + if (tab.onchange) { + tab.onchange.call(tab); + } + tab.content.show(); + if (finishedBuilding) { + RED.tray.resize(); + } + }, + collapsible: true, + menu: false + }); + + var nodePropertiesTab = { + id: "editor-tab-properties", + label: RED._("editor-tab.properties"), + name: RED._("editor-tab.properties"), + content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-cog" + }; + buildEditForm(nodePropertiesTab.content,"dialog-form","subflow-template", undefined, editing_node); + editorTabs.addTab(nodePropertiesTab); + + var descriptionTab = { + id: "editor-tab-description", + label: RED._("editor-tab.description"), + name: RED._("editor-tab.description"), + content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-file-text-o", + onchange: function() { + subflowEditor.focus(); + } + }; + editorTabs.addTab(descriptionTab); + subflowEditor = buildDescriptionForm(descriptionTab.content,editing_node); + + var appearanceTab = { + id: "editor-tab-appearance", + label: RED._("editor-tab.appearance"), + name: RED._("editor-tab.appearance"), + content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-object-group", + onchange: function() { + refreshLabelForm(this.content,editing_node); + } + }; + buildAppearanceForm(appearanceTab.content,editing_node); + editorTabs.addTab(appearanceTab); + + $("#subflow-input-name").val(subflow.name); + RED.text.bidi.prepareInput($("#subflow-input-name")); + + trayBody.i18n(); + finishedBuilding = true; + }, + close: function() { + if (RED.view.state() != RED.state.IMPORT_DRAGGING) { + RED.view.state(RED.state.DEFAULT); + } + RED.sidebar.info.refresh(editing_node); + RED.workspaces.refresh(); + subflowEditor.destroy(); + subflowEditor = null; + editStack.pop(); + editing_node = null; + }, + show: function() { + } + } + RED.tray.show(trayOptions); + } + + function showTypeEditor(type, options) { + if (customEditTypes.hasOwnProperty(type)) { + if (editStack.length > 0) { + options.parent = editStack[editStack.length-1].id; + } + editStack.push({type:type}); + options.title = options.title || getEditStackTitle(); + options.onclose = function() { + editStack.pop(); + } + customEditTypes[type].show(options); + } else { + console.log("Unknown type editor:",type); + } + } + + function createEditor(options) { + var el = options.element || $("#"+options.id)[0]; + var toolbarRow = $("<div>").appendTo(el); + el = $("<div>").appendTo(el).addClass("red-ui-editor-text-container")[0]; + var editor = ace.edit(el); + editor.setTheme("ace/theme/tomorrow"); + var session = editor.getSession(); + session.on("changeAnnotation", function () { + var annotations = session.getAnnotations() || []; + var i = annotations.length; + var len = annotations.length; + while (i--) { + if (/doctype first\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); } + else if (/Unexpected End of file\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); } + } + if (len > annotations.length) { session.setAnnotations(annotations); } + }); + if (options.mode) { + session.setMode(options.mode); + } + if (options.foldStyle) { + session.setFoldStyle(options.foldStyle); + } else { + session.setFoldStyle('markbeginend'); + } + if (options.options) { + editor.setOptions(options.options); + } else { + editor.setOptions({ + enableBasicAutocompletion:true, + enableSnippets:true, + tooltipFollowsMouse: false + }); + } + if (options.readOnly) { + editor.setOption('readOnly',options.readOnly); + editor.container.classList.add("ace_read-only"); + } + if (options.hasOwnProperty('lineNumbers')) { + editor.renderer.setOption('showGutter',options.lineNumbers); + } + editor.$blockScrolling = Infinity; + if (options.value) { + session.setValue(options.value,-1); + } + if (options.globals) { + setTimeout(function() { + if (!!session.$worker) { + session.$worker.send("setOptions", [{globals: options.globals, esversion:6, sub:true, asi:true, maxerr:1000}]); + } + },100); + } + if (options.mode === 'ace/mode/markdown') { + $(el).addClass("red-ui-editor-text-container-toolbar"); + editor.toolbar = customEditTypes['_markdown'].buildToolbar(toolbarRow,editor); + if (options.expandable !== false) { + var expandButton = $('<button type="button" class="red-ui-button" style="float: right;"><i class="fa fa-expand"></i></button>').appendTo(editor.toolbar); + RED.popover.tooltip(expandButton, RED._("markdownEditor.expand")); + expandButton.on("click", function(e) { + e.preventDefault(); + var value = editor.getValue(); + RED.editor.editMarkdown({ + value: value, + width: "Infinity", + cursor: editor.getCursorPosition(), + complete: function(v,cursor) { + editor.setValue(v, -1); + editor.gotoLine(cursor.row+1,cursor.column,false); + setTimeout(function() { + editor.focus(); + },300); + } + }) + }); + } + var helpButton = $('<button type="button" class="red-ui-editor-text-help red-ui-button red-ui-button-small"><i class="fa fa-question"></i></button>').appendTo($(el).parent()); + RED.popover.create({ + target: helpButton, + trigger: 'click', + size: "small", + direction: "left", + content: RED._("markdownEditor.format"), + autoClose: 50 + }); + session.setUseWrapMode(true); + } + return editor; + } + + return { + init: function() { + ace.config.set('basePath', 'vendor/ace'); + RED.tray.init(); + RED.actions.add("core:confirm-edit-tray", function() { + $(document.activeElement).blur(); + $("#node-dialog-ok").trigger("click"); + $("#node-config-dialog-ok").trigger("click"); + }); + RED.actions.add("core:cancel-edit-tray", function() { + $(document.activeElement).blur(); + $("#node-dialog-cancel").trigger("click"); + $("#node-config-dialog-cancel").trigger("click"); + }); + }, + edit: showEditDialog, + editConfig: showEditConfigNodeDialog, + editSubflow: showEditSubflowDialog, + editJavaScript: function(options) { showTypeEditor("_js",options) }, + editExpression: function(options) { showTypeEditor("_expression", options) }, + editJSON: function(options) { showTypeEditor("_json", options) }, + editMarkdown: function(options) { showTypeEditor("_markdown", options) }, + editText: function(options) { showTypeEditor("_text", options) }, + editBuffer: function(options) { showTypeEditor("_buffer", options) }, + buildEditForm: buildEditForm, + validateNode: validateNode, + updateNodeProperties: updateNodeProperties, // TODO: only exposed for edit-undo + + showIconPicker:showIconPicker, + + /** + * Show a type editor. + * @param {string} type - the type to display + * @param {object} options - options for the editor + * @function + * @memberof RED.editor + */ + showTypeEditor: showTypeEditor, + + /** + * Register a type editor. + * @param {string} type - the type name + * @param {object} definition - the editor definition + * @function + * @memberof RED.editor + */ + registerTypeEditor: function(type, definition) { + customEditTypes[type] = definition; + }, + + /** + * Create a editor ui component + * @param {object} options - the editor options + * @function + * @memberof RED.editor + */ + createEditor: createEditor + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/buffer.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/buffer.js new file mode 100644 index 0000000..ec5b78c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/buffer.js @@ -0,0 +1,210 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +(function() { + + var template = '<script type="text/x-red" data-template-name="_buffer"><div id="red-ui-editor-type-buffer-panels"><div id="red-ui-editor-type-buffer-panel-str" class="red-ui-panel"><div class="form-row" style="margin-bottom: 3px; text-align: right;"><button class="red-ui-editor-type-buffer-type red-ui-button red-ui-button-small"><i class="fa fa-exclamation-circle"></i> <span id="red-ui-editor-type-buffer-type-string" data-i18n="bufferEditor.modeString"></span><span id="red-ui-editor-type-buffer-type-array" data-i18n="bufferEditor.modeArray"></span></button></div><div class="form-row node-text-editor-row"><div class="node-text-editor" id="red-ui-editor-type-buffer-str"></div></div></div><div id="red-ui-editor-type-buffer-panel-bin" class="red-ui-panel"><div class="form-row node-text-editor-row" style="margin-top: 10px"><div class="node-text-editor" id="red-ui-editor-type-buffer-bin"></div></div></div></div></script>'; + + function stringToUTF8Array(str) { + var data = []; + var i=0, l = str.length; + for (i=0; i<l; i++) { + var char = str.charCodeAt(i); + if (char < 0x80) { + data.push(char); + } else if (char < 0x800) { + data.push(0xc0 | (char >> 6)); + data.push(0x80 | (char & 0x3f)); + } else if (char < 0xd800 || char >= 0xe000) { + data.push(0xe0 | (char >> 12)); + data.push(0x80 | ((char>>6) & 0x3f)); + data.push(0x80 | (char & 0x3f)); + } else { + i++; + char = 0x10000 + (((char & 0x3ff)<<10) | (str.charAt(i) & 0x3ff)); + data.push(0xf0 | (char >>18)); + data.push(0x80 | ((char>>12) & 0x3f)); + data.push(0x80 | ((char>>6) & 0x3f)); + data.push(0x80 | (char & 0x3f)); + } + } + return data; + } + + + var definition = { + show: function(options) { + var value = options.value; + var onComplete = options.complete; + var type = "_buffer" + if ($("script[data-template-name='"+type+"']").length === 0) { + $(template).appendTo("#red-ui-editor-node-configs"); + } + RED.view.state(RED.state.EDITING); + var bufferStringEditor = []; + var bufferBinValue; + + var panels; + + var trayOptions = { + title: options.title, + width: "inherit", + buttons: [ + { + id: "node-dialog-cancel", + text: RED._("common.label.cancel"), + click: function() { + RED.tray.close(); + } + }, + { + id: "node-dialog-ok", + text: RED._("common.label.done"), + class: "primary", + click: function() { + onComplete(JSON.stringify(bufferBinValue)); + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + var height = $("#dialog-form").height(); + if (panels) { + panels.resize(height); + } + }, + open: function(tray) { + var trayBody = tray.find('.red-ui-tray-body'); + var dialogForm = RED.editor.buildEditForm(tray.find('.red-ui-tray-body'),'dialog-form',type,'editor'); + + bufferStringEditor = RED.editor.createEditor({ + id: 'red-ui-editor-type-buffer-str', + value: "", + mode:"ace/mode/text" + }); + bufferStringEditor.getSession().setValue(value||"",-1); + + bufferBinEditor = RED.editor.createEditor({ + id: 'red-ui-editor-type-buffer-bin', + value: "", + mode:"ace/mode/text", + readOnly: true + }); + + var changeTimer; + var buildBuffer = function(data) { + var valid = true; + var isString = typeof data === 'string'; + var binBuffer = []; + if (isString) { + bufferBinValue = stringToUTF8Array(data); + } else { + bufferBinValue = data; + } + var i=0,l=bufferBinValue.length; + var c = 0; + for(i=0;i<l;i++) { + var d = parseInt(bufferBinValue[i]); + if (!isString && (isNaN(d) || d < 0 || d > 255)) { + valid = false; + break; + } + if (i>0) { + if (i%8 === 0) { + if (i%16 === 0) { + binBuffer.push("\n"); + } else { + binBuffer.push(" "); + } + } else { + binBuffer.push(" "); + } + } + binBuffer.push((d<16?"0":"")+d.toString(16).toUpperCase()); + } + if (valid) { + $("#red-ui-editor-type-buffer-type-string").toggle(isString); + $("#red-ui-editor-type-buffer-type-array").toggle(!isString); + bufferBinEditor.setValue(binBuffer.join(""),1); + } + return valid; + } + var bufferStringUpdate = function() { + var value = bufferStringEditor.getValue(); + var isValidArray = false; + if (/^[\s]*\[[\s\S]*\][\s]*$/.test(value)) { + isValidArray = true; + try { + var data = JSON.parse(value); + isValidArray = buildBuffer(data); + } catch(err) { + isValidArray = false; + } + } + if (!isValidArray) { + buildBuffer(value); + } + + } + bufferStringEditor.getSession().on('change', function() { + clearTimeout(changeTimer); + changeTimer = setTimeout(bufferStringUpdate,200); + }); + + bufferStringUpdate(); + + dialogForm.i18n(); + + panels = RED.panels.create({ + id:"red-ui-editor-type-buffer-panels", + resize: function(p1Height,p2Height) { + var p1 = $("#red-ui-editor-type-buffer-panel-str"); + p1Height -= $(p1.children()[0]).outerHeight(true); + var editorRow = $(p1.children()[1]); + p1Height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); + $("#red-ui-editor-type-buffer-str").css("height",(p1Height-5)+"px"); + bufferStringEditor.resize(); + + var p2 = $("#red-ui-editor-type-buffer-panel-bin"); + editorRow = $(p2.children()[0]); + p2Height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); + $("#red-ui-editor-type-buffer-bin").css("height",(p2Height-5)+"px"); + bufferBinEditor.resize(); + } + }); + + $(".red-ui-editor-type-buffer-type").on("click", function(e) { + e.preventDefault(); + RED.sidebar.info.set(RED._("bufferEditor.modeDesc")); + RED.sidebar.info.show(); + }) + + + }, + close: function() { + if (options.onclose) { + options.onclose(); + } + bufferStringEditor.destroy(); + bufferBinEditor.destroy(); + }, + show: function() {} + } + RED.tray.show(trayOptions); + } + } + RED.editor.registerTypeEditor("_buffer", definition); + +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/expression.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/expression.js new file mode 100644 index 0000000..9a9765c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/expression.js @@ -0,0 +1,354 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +(function() { + + + var template = '<script type="text/x-red" data-template-name="_expression">'+ + '<div id="red-ui-editor-type-expression-panels">'+ + '<div id="red-ui-editor-type-expression-panel-expr" class="red-ui-panel">'+ + '<div class="form-row" style="margin-bottom: 3px; text-align: right;"><button class="red-ui-editor-type-expression-legacy red-ui-button red-ui-button-small"><i class="fa fa-exclamation-circle"></i> <span data-i18n="expressionEditor.compatMode"></span></button><button id="red-ui-editor-type-expression-reformat" class="red-ui-button red-ui-button-small"><span data-i18n="expressionEditor.format"></span></button></div>'+ + '<div class="form-row node-text-editor-row"><div class="node-text-editor" id="red-ui-editor-type-expression"></div></div>'+ + '</div>'+ + '<div id="red-ui-editor-type-expression-panel-info" class="red-ui-panel">'+ + '<div class="form-row">'+ + '<ul id="red-ui-editor-type-expression-tabs"></ul>'+ + '<div id="red-ui-editor-type-expression-tab-help" class="red-ui-editor-type-expression-tab-content hide">'+ + '<div>'+ + '<select id="red-ui-editor-type-expression-func"></select>'+ + '<button id="red-ui-editor-type-expression-func-insert" class="red-ui-button" data-i18n="expressionEditor.insert"></button>'+ + '</div>'+ + '<div id="red-ui-editor-type-expression-help"></div>'+ + '</div>'+ + '<div id="red-ui-editor-type-expression-tab-test" class="red-ui-editor-type-expression-tab-content hide">'+ + '<div>'+ + '<span style="display: inline-block; width: calc(50% - 5px);"><span data-i18n="expressionEditor.data"></span><button style="float: right; margin-right: 5px;" id="node-input-example-reformat" class="red-ui-button red-ui-button-small"><span data-i18n="jsonEditor.format"></span></button></span>'+ + '<span style="display: inline-block; margin-left: 10px; width: calc(50% - 5px);" data-i18n="expressionEditor.result"></span>'+ + '</div>'+ + '<div style="display: inline-block; width: calc(50% - 5px);" class="node-text-editor" id="red-ui-editor-type-expression-test-data"></div>'+ + '<div style="display: inline-block; margin-left: 10px; width:calc(50% - 5px);" class="node-text-editor" id="red-ui-editor-type-expression-test-result"></div>'+ + '</div>'+ + '</div>'+ + '</div>'+ + '</div>'+ + '</script>'; + var expressionTestCache = {}; + + var definition = { + show: function(options) { + var expressionTestCacheId = options.parent||"_"; + var value = options.value; + var onComplete = options.complete; + var type = "_expression" + if ($("script[data-template-name='"+type+"']").length === 0) { + $(template).appendTo("#red-ui-editor-node-configs"); + } + RED.view.state(RED.state.EDITING); + var expressionEditor; + var testDataEditor; + var testResultEditor + var panels; + + var trayOptions = { + title: options.title, + width: "inherit", + buttons: [ + { + id: "node-dialog-cancel", + text: RED._("common.label.cancel"), + click: function() { + RED.tray.close(); + } + }, + { + id: "node-dialog-ok", + text: RED._("common.label.done"), + class: "primary", + click: function() { + $("#red-ui-editor-type-expression-help").text(""); + onComplete(expressionEditor.getValue()); + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + var height = $("#dialog-form").height(); + if (panels) { + panels.resize(height); + } + + }, + open: function(tray) { + var trayBody = tray.find('.red-ui-tray-body'); + trayBody.addClass("red-ui-editor-type-expression") + var dialogForm = RED.editor.buildEditForm(tray.find('.red-ui-tray-body'),'dialog-form','_expression','editor'); + var funcSelect = $("#red-ui-editor-type-expression-func"); + Object.keys(jsonata.functions).forEach(function(f) { + funcSelect.append($("<option></option>").val(f).text(f)); + }) + funcSelect.on("change", function(e) { + var f = $(this).val(); + var args = RED._('jsonata:'+f+".args",{defaultValue:''}); + var title = "<h5>"+f+"("+args+")</h5>"; + var body = RED.utils.renderMarkdown(RED._('jsonata:'+f+'.desc',{defaultValue:''})); + $("#red-ui-editor-type-expression-help").html(title+"<p>"+body+"</p>"); + + }) + expressionEditor = RED.editor.createEditor({ + id: 'red-ui-editor-type-expression', + value: "", + mode:"ace/mode/jsonata", + options: { + enableBasicAutocompletion:true, + enableSnippets:true, + enableLiveAutocompletion: true + } + }); + var currentToken = null; + var currentTokenPos = -1; + var currentFunctionMarker = null; + + expressionEditor.getSession().setValue(value||"",-1); + expressionEditor.on("changeSelection", function() { + var c = expressionEditor.getCursorPosition(); + var token = expressionEditor.getSession().getTokenAt(c.row,c.column); + if (token !== currentToken || (token && /paren/.test(token.type) && c.column !== currentTokenPos)) { + currentToken = token; + var r,p; + var scopedFunction = null; + if (token && token.type === 'keyword') { + r = c.row; + scopedFunction = token; + } else { + var depth = 0; + var next = false; + if (token) { + if (token.type === 'paren.rparen') { + // If this is a block of parens ')))', set + // depth to offset against the cursor position + // within the block + currentTokenPos = c.column; + depth = c.column - (token.start + token.value.length); + } + r = c.row; + p = token.index; + } else { + r = c.row-1; + p = -1; + } + while ( scopedFunction === null && r > -1) { + var rowTokens = expressionEditor.getSession().getTokens(r); + if (p === -1) { + p = rowTokens.length-1; + } + while (p > -1) { + var type = rowTokens[p].type; + if (next) { + if (type === 'keyword') { + scopedFunction = rowTokens[p]; + // console.log("HIT",scopedFunction); + break; + } + next = false; + } + if (type === 'paren.lparen') { + depth-=rowTokens[p].value.length; + } else if (type === 'paren.rparen') { + depth+=rowTokens[p].value.length; + } + if (depth < 0) { + next = true; + depth = 0; + } + // console.log(r,p,depth,next,rowTokens[p]); + p--; + } + if (!scopedFunction) { + r--; + } + } + } + expressionEditor.session.removeMarker(currentFunctionMarker); + if (scopedFunction) { + //console.log(token,.map(function(t) { return t.type})); + funcSelect.val(scopedFunction.value).trigger("change"); + } + } + }); + + dialogForm.i18n(); + $("#red-ui-editor-type-expression-func-insert").on("click", function(e) { + e.preventDefault(); + var pos = expressionEditor.getCursorPosition(); + var f = funcSelect.val(); + var snippet = jsonata.getFunctionSnippet(f); + expressionEditor.insertSnippet(snippet); + expressionEditor.focus(); + }); + $("#red-ui-editor-type-expression-reformat").on("click", function(evt) { + evt.preventDefault(); + var v = expressionEditor.getValue()||""; + try { + v = jsonata.format(v); + } catch(err) { + // TODO: do an optimistic auto-format + } + expressionEditor.getSession().setValue(v||"",-1); + }); + funcSelect.change(); + + var tabs = RED.tabs.create({ + element: $("#red-ui-editor-type-expression-tabs"), + onchange:function(tab) { + $(".red-ui-editor-type-expression-tab-content").hide(); + tab.content.show(); + trayOptions.resize(); + } + }) + + tabs.addTab({ + id: 'expression-help', + label: RED._('expressionEditor.functionReference'), + content: $("#red-ui-editor-type-expression-tab-help") + }); + tabs.addTab({ + id: 'expression-tests', + label: RED._('expressionEditor.test'), + content: $("#red-ui-editor-type-expression-tab-test") + }); + testDataEditor = RED.editor.createEditor({ + id: 'red-ui-editor-type-expression-test-data', + value: expressionTestCache[expressionTestCacheId] || '{\n "payload": "hello world"\n}', + mode:"ace/mode/json", + lineNumbers: false + }); + var changeTimer; + $(".red-ui-editor-type-expression-legacy").on("click", function(e) { + e.preventDefault(); + RED.sidebar.info.set(RED._("expressionEditor.compatModeDesc")); + RED.sidebar.info.show(); + }) + var testExpression = function() { + var value = testDataEditor.getValue(); + var parsedData; + var currentExpression = expressionEditor.getValue(); + var expr; + var usesContext = false; + var legacyMode = /(^|[^a-zA-Z0-9_'"])msg([^a-zA-Z0-9_'"]|$)/.test(currentExpression); + $(".red-ui-editor-type-expression-legacy").toggle(legacyMode); + try { + expr = jsonata(currentExpression); + expr.assign('flowContext',function(val) { + usesContext = true; + return null; + }); + expr.assign('globalContext',function(val) { + usesContext = true; + return null; + }); + } catch(err) { + testResultEditor.setValue(RED._("expressionEditor.errors.invalid-expr",{message:err.message}),-1); + return; + } + try { + parsedData = JSON.parse(value); + } catch(err) { + testResultEditor.setValue(RED._("expressionEditor.errors.invalid-msg",{message:err.toString()})) + return; + } + + try { + var result = expr.evaluate(legacyMode?{msg:parsedData}:parsedData); + if (usesContext) { + testResultEditor.setValue(RED._("expressionEditor.errors.context-unsupported"),-1); + return; + } + + var formattedResult; + if (result !== undefined) { + formattedResult = JSON.stringify(result,null,4); + } else { + formattedResult = RED._("expressionEditor.noMatch"); + } + testResultEditor.setValue(formattedResult,-1); + } catch(err) { + testResultEditor.setValue(RED._("expressionEditor.errors.eval",{message:err.message}),-1); + } + } + + testDataEditor.getSession().on('change', function() { + clearTimeout(changeTimer); + changeTimer = setTimeout(testExpression,200); + expressionTestCache[expressionTestCacheId] = testDataEditor.getValue(); + }); + expressionEditor.getSession().on('change', function() { + clearTimeout(changeTimer); + changeTimer = setTimeout(testExpression,200); + }); + + testResultEditor = RED.editor.createEditor({ + id: 'red-ui-editor-type-expression-test-result', + value: "", + mode:"ace/mode/json", + lineNumbers: false, + readOnly: true + }); + panels = RED.panels.create({ + id:"red-ui-editor-type-expression-panels", + resize: function(p1Height,p2Height) { + var p1 = $("#red-ui-editor-type-expression-panel-expr"); + p1Height -= $(p1.children()[0]).outerHeight(true); + var editorRow = $(p1.children()[1]); + p1Height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); + $("#red-ui-editor-type-expression").css("height",(p1Height-5)+"px"); + expressionEditor.resize(); + + var p2 = $("#red-ui-editor-type-expression-panel-info > .form-row > div:first-child"); + p2Height -= p2.outerHeight(true) + 20; + $(".red-ui-editor-type-expression-tab-content").height(p2Height); + $("#red-ui-editor-type-expression-test-data").css("height",(p2Height-5)+"px"); + testDataEditor.resize(); + $("#red-ui-editor-type-expression-test-result").css("height",(p2Height-5)+"px"); + testResultEditor.resize(); + } + }); + + $("#node-input-example-reformat").on("click", function(evt) { + evt.preventDefault(); + var v = testDataEditor.getValue()||""; + try { + v = JSON.stringify(JSON.parse(v),null,4); + } catch(err) { + // TODO: do an optimistic auto-format + } + testDataEditor.getSession().setValue(v||"",-1); + }); + + testExpression(); + }, + close: function() { + if (options.onclose) { + options.onclose(); + } + expressionEditor.destroy(); + testDataEditor.destroy(); + }, + show: function() {} + } + RED.tray.show(trayOptions); + } + } + RED.editor.registerTypeEditor("_expression", definition); +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/js.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/js.js new file mode 100644 index 0000000..6906ade --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/js.js @@ -0,0 +1,104 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +(function() { + + + var template = '<script type="text/x-red" data-template-name="_js"><div class="form-row node-text-editor-row"><div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-js"></div></div></script>'; + + var definition = { + show: function(options) { + var value = options.value; + var onComplete = options.complete; + var type = "_js" + if ($("script[data-template-name='"+type+"']").length === 0) { + $(template).appendTo("#red-ui-editor-node-configs"); + } + RED.view.state(RED.state.EDITING); + var expressionEditor; + var changeTimer; + + var trayOptions = { + title: options.title, + width: options.width||"inherit", + buttons: [ + { + id: "node-dialog-cancel", + text: RED._("common.label.cancel"), + click: function() { + RED.tray.close(); + } + }, + { + id: "node-dialog-ok", + text: RED._("common.label.done"), + class: "primary", + click: function() { + onComplete(expressionEditor.getValue(),expressionEditor.getCursorPosition()); + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + var rows = $("#dialog-form>div:not(.node-text-editor-row)"); + var editorRow = $("#dialog-form>div.node-text-editor-row"); + var height = $("#dialog-form").height(); + for (var i=0;i<rows.size();i++) { + height -= $(rows[i]).outerHeight(true); + } + $(".node-text-editor").css("height",height+"px"); + expressionEditor.resize(); + }, + open: function(tray) { + var trayBody = tray.find('.red-ui-tray-body'); + var dialogForm = RED.editor.buildEditForm(tray.find('.red-ui-tray-body'),'dialog-form',type,'editor'); + expressionEditor = RED.editor.createEditor({ + id: 'node-input-js', + mode: options.mode || 'ace/mode/javascript', + value: value, + globals: { + msg:true, + context:true, + RED: true, + util: true, + flow: true, + global: true, + console: true, + Buffer: true, + setTimeout: true, + clearTimeout: true, + setInterval: true, + clearInterval: true + } + }); + if (options.cursor) { + expressionEditor.gotoLine(options.cursor.row+1,options.cursor.column,false); + } + dialogForm.i18n(); + }, + close: function() { + expressionEditor.destroy(); + if (options.onclose) { + options.onclose(); + } + }, + show: function() {} + } + RED.tray.show(trayOptions); + } + } + RED.editor.registerTypeEditor("_js", definition); + +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/json.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/json.js new file mode 100644 index 0000000..67b5850 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/json.js @@ -0,0 +1,616 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +(function() { + + + // var template = '<script type="text/x-red" data-template-name="_json"></script>'; + var template = '<script type="text/x-red" data-template-name="_json">'+ + '<ul id="red-ui-editor-type-json-tabs"></ul>'+ + '<div id="red-ui-editor-type-json-tab-raw" class="red-ui-editor-type-json-tab-content hide">'+ + '<div class="form-row" style="margin-bottom: 3px; text-align: right;">'+ + '<button id="node-input-json-reformat" class="red-ui-button red-ui-button-small"><span data-i18n="jsonEditor.format"></span></button>'+ + '</div>'+ + '<div class="form-row node-text-editor-row">'+ + '<div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-json"></div>'+ + '</div>'+ + '</div>'+ + '<div id="red-ui-editor-type-json-tab-ui" class="red-ui-editor-type-json-tab-content hide">'+ + '<div id="red-ui-editor-type-json-tab-ui-container"></div>'+ + '</div>'+ + '</script>'; + + var activeTab; + + function insertNewItem(parent,index,copyIndex) { + var newValue = ""; + + if (parent.children.length > 0) { + switch (parent.children[Math.max(0,Math.min(parent.children.length-1,copyIndex))].type) { + case 'string': newValue = ""; break; + case 'number': newValue = 0; break; + case 'boolean': newValue = true; break; + case 'null': newValue = null; break; + case 'object': newValue = {}; break; + case 'array': newValue = []; break; + } + } + var newKey; + if (parent.type === 'array') { + newKey = parent.children.length; + } else { + var usedKeys = {}; + parent.children.forEach(function(child) { usedKeys[child.key] = true }) + var keyRoot = "item"; + var keySuffix = 2; + newKey = keyRoot; + while(usedKeys[newKey]) { + newKey = keyRoot+"-"+(keySuffix++); + } + } + var newItem = handleItem(newKey,newValue,parent.depth+1,parent); + parent.treeList.insertChildAt(newItem, index, true); + parent.treeList.expand(); + } + function showObjectMenu(button,item) { + var elementPos = button.offset(); + var options = []; + if (item.parent) { + options.push({id:"red-ui-editor-type-json-menu-insert-above", icon:"fa fa-toggle-up", label:RED._('jsonEditor.insertAbove'),onselect:function(){ + var index = item.parent.children.indexOf(item); + insertNewItem(item.parent,index,index); + }}); + options.push({id:"red-ui-editor-type-json-menu-insert-below", icon:"fa fa-toggle-down", label:RED._('jsonEditor.insertBelow'),onselect:function(){ + var index = item.parent.children.indexOf(item)+1; + insertNewItem(item.parent,index,index-1); + }}); + } + if (item.type === 'array' || item.type === 'object') { + options.push({id:"red-ui-editor-type-json-menu-add-child", icon:"fa fa-plus", label:RED._('jsonEditor.addItem'),onselect:function(){ + insertNewItem(item,item.children.length,item.children.length-1); + }}); + } + if (item.parent) { + options.push({id:"red-ui-editor-type-json-menu-copy-path", icon:"fa fa-terminal", label:RED._('jsonEditor.copyPath'),onselect:function(){ + var i = item; + var path = ""; + var newPath; + while(i.parent) { + if (i.parent.type === "array") { + newPath = "["+i.key+"]"; + } else { + if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(i.key)) { + newPath = i.key; + } else { + newPath = "[\""+i.key.replace(/"/,"\\\"")+"\"]" + } + } + path = newPath+(path.length>0 && path[0] !== "["?".":"")+path; + i = i.parent; + } + RED.clipboard.copyText(path,item.element,"clipboard.copyMessagePath"); + }}); + + options.push({id:"red-ui-editor-type-json-menu-duplicate", icon:"fa fa-copy", label:RED._("jsonEditor.duplicate"),onselect:function(){ + var newKey = item.key; + if (item.parent.type === 'array') { + newKey = item.parent.children.length; + } else { + var m = /^(.*?)(-(\d+))?$/.exec(newKey); + var usedKeys = {}; + item.parent.children.forEach(function(child) { usedKeys[child.key] = true }) + var keyRoot = m[1]; + var keySuffix = 2; + if (m[3] !== undefined) { + keySuffix = parseInt(m[3]); + } + newKey = keyRoot; + while(usedKeys[newKey]) { + newKey = keyRoot+"-"+(keySuffix++); + } + } + var newItem = handleItem(newKey,convertToObject(item),item.parent.depth+1,item.parent); + var index = item.parent.children.indexOf(item)+1; + + item.parent.treeList.insertChildAt(newItem, index, true); + item.parent.treeList.expand(); + }}); + + options.push({id:"red-ui-editor-type-json-menu-delete", icon:"fa fa-times", label:RED._('common.label.delete'),onselect:function(){ + item.treeList.remove(); + }}); + } + if (item.type === 'array' || item.type === 'object') { + options.push(null) + options.push({id:"red-ui-editor-type-json-menu-expand-children",icon:"fa fa-angle-double-down", label:RED._('jsonEditor.expandItems'),onselect:function(){ + item.treeList.expand(); + item.children.forEach(function(child) { + child.treeList.expand(); + }) + }}); + options.push({id:"red-ui-editor-type-json-menu-collapse-children",icon:"fa fa-angle-double-up", label:RED._('jsonEditor.collapseItems'),onselect:function(){ + item.treeList.collapse(); + item.children.forEach(function(child) { + child.treeList.collapse(); + }) + }}); + } + + var menuOptionMenu = RED.menu.init({ + id:"red-ui-editor-type-json-menu", + options: options + }); + menuOptionMenu.css({ + position: "absolute" + }) + menuOptionMenu.on('mouseleave', function(){ $(this).hide() }); + menuOptionMenu.on('mouseup', function() { $(this).hide() }); + menuOptionMenu.appendTo("body"); + var top = elementPos.top; + var height = menuOptionMenu.height(); + var winHeight = $(window).height(); + if (top+height > winHeight) { + top -= (top+height)-winHeight + 20; + } + menuOptionMenu.css({ + top: top+"px", + left: elementPos.left+"px" + }) + menuOptionMenu.show(); + } + + function parseObject(obj,depth,parent) { + var result = []; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + result.push(handleItem(prop,obj[prop],depth,parent)); + } + } + return result; + } + function parseArray(obj,depth,parent) { + var result = []; + var l = obj.length; + for (var i=0;i<l;i++) { + result.push(handleItem(i,obj[i],depth,parent)); + } + return result; + } + function handleItem(key,val,depth,parent) { + var item = {depth:depth, type: typeof val}; + var container = $('<span class="red-ui-editor-type-json-editor-label">'); + if (key != null) { + item.key = key; + var keyText; + if (typeof key === 'string') { + keyText = '"'+key+'"'; + } else { + keyText = key; + } + var keyLabel = $('<span class="red-ui-debug-msg-object-key red-ui-editor-type-json-editor-label-key">').text(keyText).appendTo(container); + keyLabel.addClass('red-ui-debug-msg-type-'+(typeof key)); + if (parent && parent.type === "array") { + keyLabel.addClass("red-ui-editor-type-json-editor-label-array-key") + } + + keyLabel.on("click", function(evt) { + if (item.parent.type === 'array') { + return; + } + evt.preventDefault(); + evt.stopPropagation(); + var w = Math.max(150,keyLabel.width()); + var keyInput = $('<input type="text" class="red-ui-editor-type-json-editor-key">').css({width:w+"px"}).val(""+item.key).insertAfter(keyLabel).typedInput({types:['str']}); + $(document).on("mousedown.nr-ui-json-editor", function(evt) { + var typedInputElement = keyInput.next(".red-ui-typedInput-container")[0]; + var target = evt.target; + while (target.nodeName !== 'BODY' && target !== typedInputElement && !$(target).hasClass("red-ui-typedInput-options")) { + target = target.parentElement; + } + if (target.nodeName === 'BODY') { + var newKey = keyInput.typedInput("value"); + item.key = newKey; + var keyText; + if (typeof newKey === 'string') { + keyText = '"'+newKey+'"'; + } else { + keyText = newKey; + } + keyLabel.text(keyText); + keyInput.remove(); + keyLabel.show(); + $(document).off("mousedown.nr-ui-json-editor"); + $(document).off("keydown.nr-ui-json-editor"); + } + }); + $(document).on("keydown.nr-ui-json-editor",function(evt) { + if (evt.keyCode === 27) { + // Escape + keyInput.remove(); + keyLabel.show(); + $(document).off("mousedown.nr-ui-json-editor"); + $(document).off("keydown.nr-ui-json-editor"); + } + }); + keyLabel.hide(); + }); + $('<span>').text(" : ").appendTo(container); + } + + if (Array.isArray(val)) { + item.expanded = depth < 2; + item.type = "array"; + item.deferBuild = depth >= 2; + item.children = parseArray(val,depth+1,item); + } else if (val !== null && item.type === "object") { + item.expanded = depth < 2; + item.children = parseObject(val,depth+1,item); + item.deferBuild = depth >= 2; + } else { + item.value = val; + if (val === null) { + item.type = 'null' + } + } + + var valType; + var valValue = ""; + var valClass; + switch(item.type) { + case 'string': valType = 'str'; valValue = '"'+item.value+'"'; valClass = "red-ui-debug-msg-type-string"; break; + case 'number': valType = 'num'; valValue = item.value; valClass = "red-ui-debug-msg-type-number";break; + case 'boolean': valType = 'bool'; valValue = item.value; valClass = "red-ui-debug-msg-type-other";break; + case 'null': valType = item.type; valValue = item.type; valClass = "red-ui-debug-msg-type-null";break; + case 'object': + valType = item.type; + valValue = item.type;//+"{"+item.children.length+"}"; + valClass = "red-ui-debug-msg-type-meta"; + break; + case 'array': + valType = item.type; + valValue = item.type+"["+item.children.length+"]"; + valClass = "red-ui-debug-msg-type-meta"; + break; + } + // + var orphanedChildren; + var valueLabel = $('<span class="red-ui-editor-type-json-editor-label-value">').addClass(valClass).text(valValue).appendTo(container); + valueLabel.on("click", function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + if (valType === 'str') { + valValue = valValue.substring(1,valValue.length-1); + } else if (valType === 'array') { + valValue = ""; + } else if (valType === 'object') { + valValue = ""; + } + var w = Math.max(150,valueLabel.width()); + var val = $('<input type="text" class="red-ui-editor-type-json-editor-value">').css({width:w+"px"}).val(""+valValue).insertAfter(valueLabel).typedInput({ + types:[ + 'str','num','bool', + {value:"null",label:RED._("common.type.null"),hasValue:false}, + {value:"array",label:RED._("common.type.array"),hasValue:false,icon:"red/images/typedInput/json.png"}, + {value:"object",label:RED._("common.type.object"),hasValue:false,icon:"red/images/typedInput/json.png"} + ], + default: valType + }); + $(document).on("mousedown.nr-ui-json-editor", function(evt) { + var typedInputElement = val.next(".red-ui-typedInput-container")[0]; + var target = evt.target; + while (target.nodeName !== 'BODY' && target !== typedInputElement && !$(target).hasClass("red-ui-typedInput-options")) { + target = target.parentElement; + } + if (target.nodeName === 'BODY') { + valType = val.typedInput("type"); + valValue = val.typedInput("value"); + if (valType === 'num') { + valValue = valValue.trim(); + if (isNaN(valValue)) { + valType = 'str'; + } else if (valValue === "") { + valValue = 0; + } + } + item.value = valValue; + var valClass; + switch(valType) { + case 'str': if (item.children) { orphanedChildren = item.children } item.treeList.makeLeaf(true); item.type = "string"; valClass = "red-ui-debug-msg-type-string"; valValue = '"'+valValue+'"'; break; + case 'num': if (item.children) { orphanedChildren = item.children } item.treeList.makeLeaf(true); item.type = "number"; valClass = "red-ui-debug-msg-type-number"; break; + case 'bool': if (item.children) { orphanedChildren = item.children } item.treeList.makeLeaf(true); item.type = "boolean"; valClass = "red-ui-debug-msg-type-other"; item.value = (valValue === "true"); break; + case 'null': if (item.children) { orphanedChildren = item.children } item.treeList.makeLeaf(true); item.type = "null"; valClass = "red-ui-debug-msg-type-null"; item.value = valValue = "null"; break; + case 'object': + item.treeList.makeParent(orphanedChildren); + item.type = "object"; + valClass = "red-ui-debug-msg-type-meta"; + item.value = valValue = "object"; + item.children.forEach(function(child,i) { + if (child.hasOwnProperty('_key')) { + child.key = child._key; + delete child._key; + var keyText; + var keyLabel = child.element.find(".red-ui-editor-type-json-editor-label-key"); + keyLabel.removeClass("red-ui-editor-type-json-editor-label-array-key"); + if (typeof child.key === 'string') { + keyText = '"'+child.key+'"'; + keyLabel.addClass('red-ui-debug-msg-type-string'); + keyLabel.removeClass('red-ui-debug-msg-type-number'); + } else { + keyText = child.key; + keyLabel.removeClass('red-ui-debug-msg-type-string'); + keyLabel.addClass('red-ui-debug-msg-type-number'); + } + keyLabel.text(keyText); + } + }) + break; + case 'array': + item.treeList.makeParent(orphanedChildren); + item.type = "array"; + valClass = "red-ui-debug-msg-type-meta"; + item.value = valValue = "array["+(item.children.length)+"]"; + item.children.forEach(function(child,i) { + child._key = child.key; + child.key = i; + child.element.find(".red-ui-editor-type-json-editor-label-key") + .addClass("red-ui-editor-type-json-editor-label-array-key") + .text(""+child.key) + .removeClass('red-ui-debug-msg-type-string') + .addClass('red-ui-debug-msg-type-number'); + }) + break; + } + valueLabel.text(valValue).removeClass().addClass("red-ui-editor-type-json-editor-label-value "+valClass); + val.remove(); + valueLabel.show(); + $(document).off("mousedown.nr-ui-json-editor"); + $(document).off("keydown.nr-ui-json-editor"); + } + }) + + $(document).on("keydown.nr-ui-json-editor",function(evt) { + if (evt.keyCode === 27) { + // Escape + val.remove(); + valueLabel.show(); + if (valType === 'str') { + valValue = '"'+valValue+'"'; + } + $(document).off("mousedown.nr-ui-json-editor"); + $(document).off("keydown.nr-ui-json-editor"); + } + }); + valueLabel.hide(); + }) + item.gutter = $('<span class="red-ui-editor-type-json-editor-item-gutter"></span>'); + + if (parent) {//red-ui-editor-type-json-editor-item-handle + $('<span class="red-ui-editor-type-json-editor-item-handle"><i class="fa fa-bars"></span>').appendTo(item.gutter); + } else { + $('<span></span>').appendTo(item.gutter); + } + $('<button type="button" class="editor-button editor-button-small"><i class="fa fa-caret-down"></button>').appendTo(item.gutter).on("click", function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + showObjectMenu($(this), item); + }); + item.element = container; + return item; + } + function convertToObject(item) { + var element; + switch (item.type) { + case 'string': element = item.value; break; + case 'number': element = Number(item.value); break; + case 'boolean': element = item.value; break; + case 'null': element = null; break; + case 'object': + element = {}; + item.children.forEach(function(child) { + element[child.key] = convertToObject(child); + }) + break; + case 'array': + element = item.children.map(function(child) { + return convertToObject(child); + }) + break; + } + return element; + } + + var definition = { + show: function(options) { + var value = options.value; + var onComplete = options.complete; + var type = "_json" + if ($("script[data-template-name='"+type+"']").length === 0) { + $(template).appendTo("#red-ui-editor-node-configs"); + } + RED.view.state(RED.state.EDITING); + var expressionEditor; + var changeTimer; + + var checkValid = function() { + var v = expressionEditor.getValue(); + try { + JSON.parse(v); + $("#node-dialog-ok").removeClass('disabled'); + return true; + } catch(err) { + $("#node-dialog-ok").addClass('disabled'); + return false; + } + } + var rootNode; + + var trayOptions = { + title: options.title, + width: options.width||700, + buttons: [ + { + id: "node-dialog-cancel", + text: RED._("common.label.cancel"), + click: function() { + RED.tray.close(); + } + }, + { + id: "node-dialog-ok", + text: RED._("common.label.done"), + class: "primary", + click: function() { + if (options.requireValid && !checkValid()) { + return; + } + var result; + if (activeTab === "json-ui") { + if (rootNode) { + result = JSON.stringify(convertToObject(rootNode),null,4); + } else { + result = expressionEditor.getValue(); + } + } else if (activeTab === "json-raw") { + result = expressionEditor.getValue(); + } + if (onComplete) { onComplete(result) } + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + var height = $(".red-ui-editor-type-json-tab-content").height(); + $(".node-text-editor").css("height",(height-45)+"px"); + expressionEditor.resize(); + }, + open: function(tray) { + var trayBody = tray.find('.red-ui-tray-body'); + var dialogForm = RED.editor.buildEditForm(tray.find('.red-ui-tray-body'),'dialog-form',type,'editor'); + + var container = $("#red-ui-editor-type-json-tab-ui-container").css({"height":"100%"}); + var filterDepth = Infinity; + var list = $('<div class="red-ui-debug-msg-payload red-ui-editor-type-json-editor">').appendTo(container).treeList({ + rootSortable: false, + sortable: ".red-ui-editor-type-json-editor-item-handle", + }).on("treelistchangeparent", function(event, evt) { + if (evt.old.type === 'array') { + evt.old.element.find(".red-ui-editor-type-json-editor-label-type").text("array["+evt.old.children.length+"]"); + } + if (evt.item.parent.type === 'array') { + evt.item.parent.element.find(".red-ui-editor-type-json-editor-label-type").text("array["+evt.item.parent.children.length+"]"); + } + }).on("treelistsort", function(event, item) { + item.children.forEach(function(child,i) { + if (item.type === 'array') { + child.key = i; + child.element.find(".red-ui-editor-type-json-editor-label-key") + .text(child.key) + .removeClass('red-ui-debug-msg-type-string') + .addClass('red-ui-debug-msg-type-number'); + } else { + child.element.find(".red-ui-editor-type-json-editor-label-key") + .text('"'+child.key+'"') + .removeClass('red-ui-debug-msg-type-number') + .addClass('red-ui-debug-msg-type-string'); + } + }) + }); + + + expressionEditor = RED.editor.createEditor({ + id: 'node-input-json', + value: "", + mode:"ace/mode/json" + }); + expressionEditor.getSession().setValue(value||"",-1); + if (options.requireValid) { + expressionEditor.getSession().on('change', function() { + clearTimeout(changeTimer); + changeTimer = setTimeout(checkValid,200); + }); + checkValid(); + } + $("#node-input-json-reformat").on("click", function(evt) { + evt.preventDefault(); + var v = expressionEditor.getValue()||""; + try { + v = JSON.stringify(JSON.parse(v),null,4); + } catch(err) { + // TODO: do an optimistic auto-format + } + expressionEditor.getSession().setValue(v||"",-1); + }); + dialogForm.i18n(); + + var finishedBuild = false; + var tabs = RED.tabs.create({ + element: $("#red-ui-editor-type-json-tabs"), + onchange:function(tab) { + activeTab = tab.id; + $(".red-ui-editor-type-json-tab-content").hide(); + if (finishedBuild) { + if (tab.id === "json-raw") { + if (rootNode) { + var result = JSON.stringify(convertToObject(rootNode),null,4); + expressionEditor.getSession().setValue(result||"",-1); + } + + } else if (tab.id === "json-ui") { + var raw = expressionEditor.getValue().trim() ||"{}"; + try { + var parsed = JSON.parse(raw); + rootNode = handleItem(null,parsed,0,null); + rootNode.class = "red-ui-editor-type-json-root-node" + list.treeList('data',[rootNode]); + } catch(err) { + rootNode = null; + list.treeList('data',[{ + label: RED._("jsonEditor.error.invalidJSON")+err.toString() + }]); + } + } + } + tab.content.show(); + trayOptions.resize(); + } + }) + + tabs.addTab({ + id: 'json-raw', + label: RED._('jsonEditor.rawMode'), + content: $("#red-ui-editor-type-json-tab-raw") + }); + tabs.addTab({ + id: 'json-ui', + label: RED._('jsonEditor.uiMode'), + content: $("#red-ui-editor-type-json-tab-ui") + }); + finishedBuild = true; + + + }, + close: function() { + // expressionEditor.destroy(); + if (options.onclose) { + options.onclose(); + } + }, + show: function() {} + } + RED.tray.show(trayOptions); + } + } + RED.editor.registerTypeEditor("_json", definition); +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/markdown.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/markdown.js new file mode 100644 index 0000000..f89c8f3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/markdown.js @@ -0,0 +1,216 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +(function() { + + var toolbarTemplate = '<div style="margin-bottom: 5px">'+ + '<span class="button-group">'+ + '<button type="button" class="red-ui-button" data-style="h1" style="font-size:1.1em; font-weight: bold">h1</button>'+ + '<button type="button" class="red-ui-button" data-style="h2" style="font-size:1.0em; font-weight: bold">h2</button>'+ + '<button type="button" class="red-ui-button" data-style="h3" style="font-size:0.9em; font-weight: bold">h3</button>'+ + '</span>'+ + '<span class="button-group">'+ + '<button type="button" class="red-ui-button" data-style="b"><i class="fa fa-bold"></i></button>'+ + '<button type="button" class="red-ui-button" data-style="i"><i class="fa fa-italic"></i></button>'+ + '<button type="button" class="red-ui-button" data-style="code"><i class="fa fa-code"></i></button>'+ + '</span>'+ + '<span class="button-group">'+ + '<button type="button" class="red-ui-button" data-style="ol"><i class="fa fa-list-ol"></i></button>'+ + '<button type="button" class="red-ui-button" data-style="ul"><i class="fa fa-list-ul"></i></button>'+ + '<button type="button" class="red-ui-button" data-style="bq"><i class="fa fa-quote-left"></i></button>'+ + '<button type="button" class="red-ui-button" data-style="hr"><i class="fa fa-minus"></i></button>'+ + '<button type="button" class="red-ui-button" data-style="link"><i class="fa fa-link"></i></button>'+ + '</span>'+ + '</div>'; + + var template = '<script type="text/x-red" data-template-name="_markdown">'+ + '<div id="red-ui-editor-type-markdown-panels">'+ + '<div id="red-ui-editor-type-markdown-panel-editor" class="red-ui-panel">'+ + '<div style="height: 100%; margin: auto;">'+ + '<div id="red-ui-editor-type-markdown-toolbar"></div>'+ + '<div class="node-text-editor" style="height: 100%" id="red-ui-editor-type-markdown"></div>'+ + '</div>'+ + '</div>'+ + '<div class="red-ui-panel">'+ + '<div class="red-ui-editor-type-markdown-panel-preview red-ui-help"></div>'+ + '</div>'+ + '</script>'; + + + var panels; + + var definition = { + show: function(options) { + var value = options.value; + var onComplete = options.complete; + var type = "_markdown" + if ($("script[data-template-name='"+type+"']").length === 0) { + $(template).appendTo("#red-ui-editor-node-configs"); + } + + + RED.view.state(RED.state.EDITING); + var expressionEditor; + + var trayOptions = { + title: options.title, + width: options.width||Infinity, + buttons: [ + { + id: "node-dialog-cancel", + text: RED._("common.label.cancel"), + click: function() { + RED.tray.close(); + } + }, + { + id: "node-dialog-ok", + text: RED._("common.label.done"), + class: "primary", + click: function() { + onComplete(expressionEditor.getValue(),expressionEditor.getCursorPosition()); + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + var width = $("#dialog-form").width(); + if (panels) { + panels.resize(width); + } + + }, + open: function(tray) { + var trayBody = tray.find('.red-ui-tray-body'); + trayBody.addClass("red-ui-editor-type-markdown-editor") + var dialogForm = RED.editor.buildEditForm(tray.find('.red-ui-tray-body'),'dialog-form',type,'editor'); + expressionEditor = RED.editor.createEditor({ + id: 'red-ui-editor-type-markdown', + value: value, + mode:"ace/mode/markdown", + expandable: false + }); + var changeTimer; + expressionEditor.getSession().on("change", function() { + clearTimeout(changeTimer); + changeTimer = setTimeout(function() { + var currentScrollTop = $(".red-ui-editor-type-markdown-panel-preview").scrollTop(); + $(".red-ui-editor-type-markdown-panel-preview").html(RED.utils.renderMarkdown(expressionEditor.getValue())); + $(".red-ui-editor-type-markdown-panel-preview").scrollTop(currentScrollTop); + },200); + }) + if (options.header) { + options.header.appendTo(tray.find('#red-ui-editor-type-markdown-title')); + } + + if (value) { + $(".red-ui-editor-type-markdown-panel-preview").html(RED.utils.renderMarkdown(expressionEditor.getValue())); + } + panels = RED.panels.create({ + id:"red-ui-editor-type-markdown-panels", + dir: "horizontal", + resize: function(p1Width,p2Width) { + expressionEditor.resize(); + } + }); + panels.ratio(1); + + $('<span class="button-group" style="float:right">'+ + '<button type="button" id="node-btn-markdown-preview" class="red-ui-button toggle single"><i class="fa fa-eye"></i></button>'+ + '</span>').appendTo(expressionEditor.toolbar); + + $("#node-btn-markdown-preview").on("click", function(e) { + e.preventDefault(); + if ($(this).hasClass("selected")) { + $(this).removeClass("selected"); + panels.ratio(1); + } else { + $(this).addClass("selected"); + panels.ratio(0.5); + } + }); + RED.popover.tooltip($("#node-btn-markdown-preview"), RED._("markdownEditor.toggle-preview")); + + if (options.cursor) { + expressionEditor.gotoLine(options.cursor.row+1,options.cursor.column,false); + } + + dialogForm.i18n(); + }, + close: function() { + expressionEditor.destroy(); + if (options.onclose) { + options.onclose(); + } + }, + show: function() {} + } + RED.tray.show(trayOptions); + }, + + buildToolbar: function(container, editor) { + var styleActions = { + 'h1': { newline: true, before:"# ", tooltip:RED._("markdownEditor.heading1")}, + 'h2': { newline: true, before:"## ", tooltip:RED._("markdownEditor.heading2")}, + 'h3': { newline: true, before:"### ", tooltip:RED._("markdownEditor.heading3")}, + 'b': { before:"**", after: "**", tooltip: RED._("markdownEditor.bold")}, + 'i': { before:"_", after: "_", tooltip: RED._("markdownEditor.italic")}, + 'code': { before:"`", after: "`", tooltip: RED._("markdownEditor.code")}, + 'ol': { before:" * ", newline: true, tooltip: RED._("markdownEditor.ordered-list")}, + 'ul': { before:" - ", newline: true, tooltip: RED._("markdownEditor.unordered-list")}, + 'bq': { before:"> ", newline: true, tooltip: RED._("markdownEditor.quote")}, + 'link': { before:"[", after: "]()", tooltip: RED._("markdownEditor.link")}, + 'hr': { before:"\n---\n\n", tooltip: RED._("markdownEditor.horizontal-rule")} + } + var toolbar = $(toolbarTemplate).appendTo(container); + toolbar.find('button[data-style]').each(function(el) { + var style = styleActions[$(this).data('style')]; + $(this).on("click", function(e) { + e.preventDefault(); + var current = editor.getSelectedText(); + var range = editor.selection.getRange(); + if (style.newline) { + var offset = 0; + var beforeOffset = ((style.before||"").match(/\n/g)||[]).length; + var afterOffset = ((style.after||"").match(/\n/g)||[]).length; + for (var i = range.start.row; i<= range.end.row+offset; i++) { + if (style.before) { + editor.session.insert({row:i, column:0},style.before); + offset += beforeOffset; + i += beforeOffset; + } + if (style.after) { + editor.session.insert({row:i, column:Infinity},style.after); + offset += afterOffset; + i += afterOffset; + } + } + } else { + editor.session.replace(editor.selection.getRange(), (style.before||"")+current+(style.after||"")); + if (current === "") { + editor.gotoLine(range.start.row+1,range.start.column+(style.before||"").length,false); + } + } + editor.focus(); + }); + if (style.tooltip) { + RED.popover.tooltip($(this),style.tooltip); + } + }) + return toolbar; + } + } + RED.editor.registerTypeEditor("_markdown", definition); +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/text.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/text.js new file mode 100644 index 0000000..1824091 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/editors/text.js @@ -0,0 +1,90 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +(function() { + + + var template = '<script type="text/x-red" data-template-name="_text"><div class="form-row node-text-editor-row"><div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-text"></div></div></script>'; + + var definition = { + show: function(options) { + var value = options.value; + var onComplete = options.complete; + var type = "_text" + if ($("script[data-template-name='"+type+"']").length === 0) { + $(template).appendTo("#red-ui-editor-node-configs"); + } + RED.view.state(RED.state.EDITING); + var expressionEditor; + var changeTimer; + + var trayOptions = { + title: options.title, + width: options.width||"inherit", + buttons: [ + { + id: "node-dialog-cancel", + text: RED._("common.label.cancel"), + click: function() { + RED.tray.close(); + } + }, + { + id: "node-dialog-ok", + text: RED._("common.label.done"), + class: "primary", + click: function() { + onComplete(expressionEditor.getValue(),expressionEditor.getCursorPosition()); + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + var rows = $("#dialog-form>div:not(.node-text-editor-row)"); + var editorRow = $("#dialog-form>div.node-text-editor-row"); + var height = $("#dialog-form").height(); + // for (var i=0;i<rows.size();i++) { + // height -= $(rows[i]).outerHeight(true); + // } + // height -= (parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom"))); + $(".node-text-editor").css("height",height+"px"); + expressionEditor.resize(); + }, + open: function(tray) { + var trayBody = tray.find('.red-ui-tray-body'); + var dialogForm = RED.editor.buildEditForm(tray.find('.red-ui-tray-body'),'dialog-form',type,'editor'); + expressionEditor = RED.editor.createEditor({ + id: 'node-input-text', + value: "", + mode:"ace/mode/"+(options.mode||"text") + }); + expressionEditor.getSession().setValue(value||"",-1); + if (options.cursor) { + expressionEditor.gotoLine(options.cursor.row+1,options.cursor.column,false); + } + }, + close: function() { + expressionEditor.destroy(); + if (options.onclose) { + options.onclose(); + } + }, + show: function() {} + } + RED.tray.show(trayOptions); + } + } + RED.editor.registerTypeEditor("_text", definition); +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/event-log.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/event-log.js new file mode 100644 index 0000000..1b9d396 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/event-log.js @@ -0,0 +1,121 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.eventLog = (function() { + + var template = '<script type="text/x-red" data-template-name="_eventLog"><div class="form-row node-text-editor-row"><div style="height: 100%;min-height: 150px;" class="node-text-editor" id="red-ui-event-log-editor"></div></div></script>'; + + var eventLogEditor; + var backlog = []; + var shown = false; + + function appendLogLine(line) { + backlog.push(line); + if (backlog.length > 500) { + backlog = backlog.slice(-500); + } + if (eventLogEditor) { + eventLogEditor.getSession().insert({ + row: eventLogEditor.getSession().getLength(), + column: 0 + }, "\n" + line); + eventLogEditor.scrollToLine(eventLogEditor.getSession().getLength()); + } + } + return { + init: function() { + $(template).appendTo("#red-ui-editor-node-configs"); + RED.actions.add("core:show-event-log",RED.eventLog.show); + }, + show: function() { + if (shown) { + return; + } + shown = true; + var type = "_eventLog" + + var trayOptions = { + title: RED._("eventLog.title"), + width: Infinity, + buttons: [ + { + id: "node-dialog-close", + text: RED._("common.label.close"), + click: function() { + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + var rows = $("#dialog-form>div:not(.node-text-editor-row)"); + var editorRow = $("#dialog-form>div.node-text-editor-row"); + var height = $("#dialog-form").height(); + for (var i=0;i<rows.size();i++) { + height -= $(rows[i]).outerHeight(true); + } + height -= (parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom"))); + $(".node-text-editor").css("height",height+"px"); + eventLogEditor.resize(); + }, + open: function(tray) { + var trayBody = tray.find('.red-ui-tray-body'); + var dialogForm = RED.editor.buildEditForm(tray.find('.red-ui-tray-body'),'dialog-form',type,'editor'); + eventLogEditor = RED.editor.createEditor({ + id: 'red-ui-event-log-editor', + value: backlog.join("\n"), + lineNumbers: false, + readOnly: true, + options: { + showPrintMargin: false + } + }); + setTimeout(function() { + eventLogEditor.scrollToLine(eventLogEditor.getSession().getLength()); + },200); + dialogForm.i18n(); + }, + close: function() { + eventLogEditor.destroy(); + eventLogEditor = null; + shown = false; + }, + show: function() {} + } + RED.tray.show(trayOptions); + }, + log: function(id,payload) { + var ts = (new Date(payload.ts)).toISOString()+" "; + if (payload.type) { + ts += "["+payload.type+"] " + } + if (payload.data) { + var data = payload.data; + if (data.endsWith('\n')) { + data = data.substring(0,data.length-1); + } + var lines = data.split(/\n/); + lines.forEach(function(line) { + appendLogLine(ts+line); + }) + } + }, + startEvent: function(name) { + backlog.push(""); + backlog.push("-----------------------------------------------------------"); + backlog.push((new Date()).toISOString()+" "+name); + backlog.push(""); + } + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/keyboard.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/keyboard.js new file mode 100644 index 0000000..3e79f6e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/keyboard.js @@ -0,0 +1,585 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.keyboard = (function() { + + var isMac = /Mac/i.test(window.navigator.platform); + + var handlers = {}; + var partialState; + + var keyMap = { + "left":37, + "up":38, + "right":39, + "down":40, + "escape":27, + "enter": 13, + "backspace": 8, + "delete": 46, + "space": 32, + ";":186, + "=":187, + ",":188, + "-":189, + ".":190, + "/":191, + "\\":220, + "'":222, + "?":191 // <- QWERTY specific + } + var metaKeyCodes = { + 16:true, + 17:true, + 18: true, + 91:true, + 93: true + } + var actionToKeyMap = {} + var defaultKeyMap = {}; + + // FF generates some different keycodes because reasons. + var firefoxKeyCodeMap = { + 59:186, + 61:187, + 173:189 + } + + function migrateOldKeymap() { + if ('localStorage' in window && window['localStorage'] !== null) { + var oldKeyMap = localStorage.getItem("keymap"); + if (oldKeyMap !== null) { + localStorage.removeItem("keymap"); + var currentEditorSettings = RED.settings.get('editor') || {}; + currentEditorSettings.keymap = JSON.parse(oldKeyMap); + RED.settings.set('editor',currentEditorSettings); + } + } + } + function init() { + // Migrate from pre-0.18 + migrateOldKeymap(); + + var currentEditorSettings = RED.settings.get('editor') || {}; + var userKeymap = currentEditorSettings.keymap || {}; + + $.getJSON("red/keymap.json",function(data) { + for (var scope in data) { + if (data.hasOwnProperty(scope)) { + var keys = data[scope]; + for (var key in keys) { + if (keys.hasOwnProperty(key)) { + if (!userKeymap.hasOwnProperty(keys[key])) { + addHandler(scope,key,keys[key],false); + } + defaultKeyMap[keys[key]] = { + scope:scope, + key:key, + user:false + }; + } + } + } + } + for (var action in userKeymap) { + if (userKeymap.hasOwnProperty(action) && userKeymap[action]) { + var obj = userKeymap[action]; + if (obj.hasOwnProperty('key')) { + var scope = obj.scope; + if (scope === "workspace") { + scope = "red-ui-workspace"; + } + addHandler(scope, obj.key, action, true); + } + } + } + }); + + RED.userSettings.add({ + id:'keyboard', + title: RED._("keyboard.keyboard"), + get: getSettingsPane, + focus: function() { + setTimeout(function() { + $("#red-ui-settings-tab-keyboard-filter").trigger("focus"); + },200); + } + }) + } + + function revertToDefault(action) { + var currentAction = actionToKeyMap[action]; + if (currentAction) { + removeHandler(currentAction.key); + } + if (defaultKeyMap.hasOwnProperty(action)) { + var obj = defaultKeyMap[action]; + addHandler(obj.scope, obj.key, action, false); + } + } + function parseKeySpecifier(key) { + var parts = key.toLowerCase().split("-"); + var modifiers = {}; + var keycode; + var blank = 0; + for (var i=0;i<parts.length;i++) { + switch(parts[i]) { + case "ctrl": + case "cmd": + modifiers.ctrl = true; + modifiers.meta = true; + break; + case "alt": + modifiers.alt = true; + break; + case "shift": + modifiers.shift = true; + break; + case "": + blank++; + keycode = keyMap["-"]; + break; + default: + if (keyMap.hasOwnProperty(parts[i])) { + keycode = keyMap[parts[i]]; + } else if (parts[i].length > 1) { + return null; + } else { + keycode = parts[i].toUpperCase().charCodeAt(0); + } + break; + } + } + return [keycode,modifiers]; + } + + function matchHandlerToEvent(evt,handler) { + var target = evt.target; + var depth = 0; + while (target.nodeName !== 'BODY' && target.id !== handler.scope) { + target = target.parentElement; + depth++; + } + if (target.nodeName === 'BODY' && handler.scope !== "*") { + depth = -1; + } + return depth; + } + + function resolveKeyEvent(evt) { + var slot = partialState||handlers; + if (evt.ctrlKey || evt.metaKey) { + slot = slot.ctrl; + } + if (slot && evt.shiftKey) { + slot = slot.shift; + } + if (slot && evt.altKey) { + slot = slot.alt; + } + var keyCode = firefoxKeyCodeMap[evt.keyCode] || evt.keyCode; + if (slot && slot[keyCode]) { + var handler = slot[keyCode]; + if (!handler.handlers) { + if (partialState) { + partialState = null; + return resolveKeyEvent(evt); + } else if (Object.keys(handler).length > 0) { + partialState = handler; + evt.preventDefault(); + return null; + } else { + return null; + } + } else { + var depth = Infinity; + var matchedHandler; + var i = 0; + var l = handler.handlers.length; + for (i=0;i<l;i++) { + var d = matchHandlerToEvent(evt,handler.handlers[i]); + if (d > -1 && d < depth) { + depth = d; + matchedHandler = handler.handlers[i]; + } + } + handler = matchedHandler; + } + partialState = null; + return handler; + } else if (partialState) { + partialState = null; + return resolveKeyEvent(evt); + } + } + d3.select(window).on("keydown",function() { + if (metaKeyCodes[d3.event.keyCode]) { + return; + } + var handler = resolveKeyEvent(d3.event); + if (handler && handler.ondown) { + if (typeof handler.ondown === "string") { + RED.actions.invoke(handler.ondown); + } else { + handler.ondown(); + } + d3.event.preventDefault(); + } + }); + + function addHandler(scope,key,modifiers,ondown) { + var mod = modifiers; + var cbdown = ondown; + if (typeof modifiers == "function" || typeof modifiers === "string") { + mod = {}; + cbdown = modifiers; + } + var keys = []; + var i=0; + if (typeof key === 'string') { + if (typeof cbdown === 'string') { + actionToKeyMap[cbdown] = {scope:scope,key:key}; + if (typeof ondown === 'boolean') { + actionToKeyMap[cbdown].user = ondown; + } + } + var parts = key.split(" "); + for (i=0;i<parts.length;i++) { + var parsedKey = parseKeySpecifier(parts[i]); + if (parsedKey) { + keys.push(parsedKey); + } else { + return; + } + } + } else { + keys.push([key,mod]) + } + var slot = handlers; + for (i=0;i<keys.length;i++) { + key = keys[i][0]; + mod = keys[i][1]; + if (mod.ctrl) { + slot.ctrl = slot.ctrl||{}; + slot = slot.ctrl; + } + if (mod.shift) { + slot.shift = slot.shift||{}; + slot = slot.shift; + } + if (mod.alt) { + slot.alt = slot.alt||{}; + slot = slot.alt; + } + slot[key] = slot[key] || {}; + slot = slot[key]; + //slot[key] = {scope: scope, ondown:cbdown}; + } + slot.handlers = slot.handlers || []; + slot.handlers.push({scope:scope,ondown:cbdown}) + slot.scope = scope; + slot.ondown = cbdown; + } + + function removeHandler(key,modifiers) { + var mod = modifiers || {}; + var keys = []; + var i=0; + if (typeof key === 'string') { + + var parts = key.split(" "); + for (i=0;i<parts.length;i++) { + var parsedKey = parseKeySpecifier(parts[i]); + if (parsedKey) { + keys.push(parsedKey); + } else { + console.log("Unrecognised key specifier:",key) + return; + } + } + } else { + keys.push([key,mod]) + } + var slot = handlers; + for (i=0;i<keys.length;i++) { + key = keys[i][0]; + mod = keys[i][1]; + if (mod.ctrl) { + slot = slot.ctrl; + } + if (slot && mod.shift) { + slot = slot.shift; + } + if (slot && mod.alt) { + slot = slot.alt; + } + if (!slot[key]) { + return; + } + slot = slot[key]; + } + if (typeof slot.ondown === "string") { + if (typeof modifiers === 'boolean' && modifiers) { + actionToKeyMap[slot.ondown] = {user: modifiers} + } else { + delete actionToKeyMap[slot.ondown]; + } + } + delete slot.scope; + delete slot.ondown; + // TODO: this wipes everything! Need to have something to identify handler + delete slot.handlers; + } + + var cmdCtrlKey = '<span class="help-key">'+(isMac?'&#8984;':'Ctrl')+'</span>'; + + function formatKey(key,plain) { + var formattedKey = isMac?key.replace(/ctrl-?/,"&#8984;"):key; + formattedKey = isMac?formattedKey.replace(/alt-?/,"&#8997;"):key; + formattedKey = formattedKey.replace(/shift-?/,"&#8679;") + formattedKey = formattedKey.replace(/left/,"&#x2190;") + formattedKey = formattedKey.replace(/up/,"&#x2191;") + formattedKey = formattedKey.replace(/right/,"&#x2192;") + formattedKey = formattedKey.replace(/down/,"&#x2193;") + if (plain) { + return formattedKey; + } + return '<span class="help-key-block"><span class="help-key">'+formattedKey.split(" ").join('</span> <span class="help-key">')+'</span></span>'; + } + + function validateKey(key) { + key = key.trim(); + var parts = key.split(" "); + for (i=0;i<parts.length;i++) { + var parsedKey = parseKeySpecifier(parts[i]); + if (!parsedKey) { + return false; + } + } + return true; + } + + function editShortcut(e) { + e.preventDefault(); + var container = $(this); + var object = container.data('data'); + + + if (!container.hasClass('keyboard-shortcut-entry-expanded')) { + endEditShortcut(); + + var key = container.find(".keyboard-shortcut-entry-key"); + var scope = container.find(".keyboard-shortcut-entry-scope"); + container.addClass('keyboard-shortcut-entry-expanded'); + + var keyInput = $('<input type="text">').attr('placeholder',RED._('keyboard.unassigned')).val(object.key||"").appendTo(key); + keyInput.on("keyup",function(e) { + if (e.keyCode === 13) { + return endEditShortcut(); + } + var currentVal = $(this).val(); + currentVal = currentVal.trim(); + var valid = (currentVal === "" || RED.keyboard.validateKey(currentVal)); + $(this).toggleClass("input-error",!valid); + }) + + var scopeSelect = $('<select><option value="*" data-i18n="keyboard.global"></option><option value="red-ui-workspace" data-i18n="keyboard.workspace"></option></select>').appendTo(scope); + scopeSelect.i18n(); + if (object.scope === "workspace") { + object.scope = "red-ui-workspace"; + } + scopeSelect.val(object.scope||'*'); + + var div = $('<div class="keyboard-shortcut-edit button-group-vertical"></div>').appendTo(scope); + var okButton = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-check"></i></button>').appendTo(div); + var revertButton = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-reply"></i></button>').appendTo(div); + + okButton.on("click", function(e) { + e.stopPropagation(); + endEditShortcut(); + }); + revertButton.on("click", function(e) { + e.stopPropagation(); + RED.keyboard.revertToDefault(object.id); + container.empty(); + container.removeClass('keyboard-shortcut-entry-expanded'); + var shortcut = RED.keyboard.getShortcut(object.id); + var userKeymap = RED.settings.get('keymap') || {}; + + var currentEditorSettings = RED.settings.get('editor') || {}; + var userKeymap = currentEditorSettings.keymap || {}; + userKeymap[object.id] = null; + currentEditorSettings.keymap = userKeymap; + RED.settings.set('editor',currentEditorSettings); + + var obj = { + id:object.id, + scope:shortcut?shortcut.scope:undefined, + key:shortcut?shortcut.key:undefined, + user:shortcut?shortcut.user:undefined + } + buildShortcutRow(container,obj); + }) + + keyInput.trigger("focus"); + } + } + + function endEditShortcut(cancel) { + var container = $('.keyboard-shortcut-entry-expanded'); + if (container.length === 1) { + var object = container.data('data'); + var keyInput = container.find(".keyboard-shortcut-entry-key input"); + var scopeSelect = container.find(".keyboard-shortcut-entry-scope select"); + if (!cancel) { + var key = keyInput.val().trim(); + var scope = scopeSelect.val(); + var valid = (key === "" || RED.keyboard.validateKey(key)); + if (valid) { + var current = RED.keyboard.getShortcut(object.id); + if ((!current && key) || (current && (current.scope !== scope || current.key !== key))) { + var keyDiv = container.find(".keyboard-shortcut-entry-key"); + var scopeDiv = container.find(".keyboard-shortcut-entry-scope"); + keyDiv.empty(); + scopeDiv.empty(); + if (object.key) { + RED.keyboard.remove(object.key,true); + } + container.find(".keyboard-shortcut-entry-text i").css("opacity",1); + if (key === "") { + keyDiv.parent().addClass("keyboard-shortcut-entry-unassigned"); + keyDiv.append($('<span>').text(RED._('keyboard.unassigned')) ); + delete object.key; + delete object.scope; + } else { + keyDiv.parent().removeClass("keyboard-shortcut-entry-unassigned"); + keyDiv.append(RED.keyboard.formatKey(key)) + $("<span>").text(scope).appendTo(scopeDiv); + object.key = key; + object.scope = scope; + RED.keyboard.add(object.scope,object.key,object.id,true); + } + + var currentEditorSettings = RED.settings.get('editor') || {}; + var userKeymap = currentEditorSettings.keymap || {}; + userKeymap[object.id] = RED.keyboard.getShortcut(object.id); + currentEditorSettings.keymap = userKeymap; + RED.settings.set('editor',currentEditorSettings); + } + } + } + keyInput.remove(); + scopeSelect.remove(); + $('.keyboard-shortcut-edit').remove(); + container.removeClass('keyboard-shortcut-entry-expanded'); + } + } + + function buildShortcutRow(container,object) { + var item = $('<div class="keyboard-shortcut-entry">').appendTo(container); + container.data('data',object); + + var text = object.id.replace(/(^.+:([a-z]))|(-([a-z]))/g,function() { + if (arguments[5] === 0) { + return arguments[2].toUpperCase(); + } else { + return " "+arguments[4].toUpperCase(); + } + }); + var label = $('<div>').addClass("keyboard-shortcut-entry-text").text(text).appendTo(item); + + var user = $('<i class="fa fa-user"></i>').prependTo(label); + + if (!object.user) { + user.css("opacity",0); + } + + var key = $('<div class="keyboard-shortcut-entry-key">').appendTo(item); + if (object.key) { + key.append(RED.keyboard.formatKey(object.key)); + } else { + item.addClass("keyboard-shortcut-entry-unassigned"); + key.append($('<span>').text(RED._('keyboard.unassigned')) ); + } + + var scope = $('<div class="keyboard-shortcut-entry-scope">').appendTo(item); + + $("<span>").text(object.scope === '*'?'global':object.scope||"").appendTo(scope); + container.on("click", editShortcut); + } + + function getSettingsPane() { + var pane = $('<div id="red-ui-settings-tab-keyboard"></div>'); + + $('<div class="keyboard-shortcut-entry keyboard-shortcut-list-header">'+ + '<div class="keyboard-shortcut-entry-key keyboard-shortcut-entry-text"><input autocomplete="off" name="keyboard-filter" id="red-ui-settings-tab-keyboard-filter" type="text" data-i18n="[placeholder]keyboard.filterActions"></div>'+ + '<div class="keyboard-shortcut-entry-key" data-i18n="keyboard.shortcut"></div>'+ + '<div class="keyboard-shortcut-entry-scope" data-i18n="keyboard.scope"></div>'+ + '</div>').appendTo(pane); + + pane.find("#red-ui-settings-tab-keyboard-filter").searchBox({ + delay: 100, + change: function() { + var filterValue = $(this).val().trim(); + if (filterValue === "") { + shortcutList.editableList('filter', null); + } else { + filterValue = filterValue.replace(/\s/g,""); + shortcutList.editableList('filter', function(data) { + return data.id.toLowerCase().replace(/^.*:/,"").replace("-","").indexOf(filterValue) > -1; + }) + } + } + }); + + var shortcutList = $('<ol class="keyboard-shortcut-list"></ol>').css({ + position: "absolute", + top: "32px", + bottom: "0", + left: "0", + right: "0" + }).appendTo(pane).editableList({ + addButton: false, + scrollOnAdd: false, + addItem: function(container,i,object) { + buildShortcutRow(container,object); + }, + + }); + var shortcuts = RED.actions.list(); + shortcuts.sort(function(A,B) { + var Aid = A.id.replace(/^.*:/,"").replace(/[ -]/g,"").toLowerCase(); + var Bid = B.id.replace(/^.*:/,"").replace(/[ -]/g,"").toLowerCase(); + return Aid.localeCompare(Bid); + }); + shortcuts.forEach(function(s) { + shortcutList.editableList('addItem',s); + }); + return pane; + } + + return { + init: init, + add: addHandler, + remove: removeHandler, + getShortcut: function(actionName) { + return actionToKeyMap[actionName]; + }, + revertToDefault: revertToDefault, + formatKey: formatKey, + validateKey: validateKey + } + +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/library.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/library.js new file mode 100644 index 0000000..e25223f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/library.js @@ -0,0 +1,592 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.library = (function() { + + var loadLibraryBrowser; + var saveLibraryBrowser; + var libraryEditor; + var activeLibrary; + + var _libraryLookup = '<div id="red-ui-library-dialog-load" class="hide">'+ + '<form class="form-horizontal">'+ + '<div style="height: 400px; position:relative; ">'+ + '<div id="red-ui-library-dialog-load-panes">'+ + '<div class="red-ui-panel" id="red-ui-library-dialog-load-browser"></div>'+ + '<div class="red-ui-panel">'+ + '<div id="red-ui-library-dialog-load-preview">'+ + '<div class="red-ui-panel" id="red-ui-library-dialog-load-preview-text"></div>'+ + '<div class="red-ui-panel" id="red-ui-library-dialog-load-preview-details">'+ + '<table id="red-ui-library-dialog-load-preview-details-table" class="red-ui-info-table"></table>'+ + '</div>'+ + '</div>'+ + '</div>'+ + '</div>'+ + '</div>'+ + '</form>'+ + '</div>' + + + var _librarySave = '<div id="red-ui-library-dialog-save" class="hide">'+ + '<form class="form-horizontal">'+ + '<div style="height: 400px; position:relative; ">'+ + '<div id="red-ui-library-dialog-save-browser"></div>'+ + '<div class="form-row">'+ + '<label data-i18n="clipboard.export.exportAs"></label><input id="red-ui-library-dialog-save-filename" type="text">'+ + '</div>'+ + '</div>'+ + '</form>'+ + '</div>' + + function saveToLibrary() { + var elementPrefix = activeLibrary.elementPrefix || "node-input-"; + var name = $("#"+elementPrefix+"name").val().trim(); + if (name === "") { + name = RED._("library.unnamedType",{type:activeLibrary.type}); + } + var filename = $("#red-ui-library-dialog-save-filename").val().trim() + var selectedPath = saveLibraryBrowser.getSelected(); + if (!selectedPath.children) { + selectedPath = selectedPath.parent; + } + + var queryArgs = []; + var data = {}; + for (var i=0; i<activeLibrary.fields.length; i++) { + var field = activeLibrary.fields[i]; + if (field == "name") { + data.name = name; + } else { + data[field] = $("#"+elementPrefix+field).val(); + } + } + data.text = activeLibrary.editor.getValue(); + var saveFlow = function() { + $.ajax({ + url:"library/"+selectedPath.library+'/'+selectedPath.type+'/'+selectedPath.path + filename, + type: "POST", + data: JSON.stringify(data), + contentType: "application/json; charset=utf-8" + }).done(function(data,textStatus,xhr) { + RED.notify(RED._("library.savedType", {type:activeLibrary.type}),"success"); + }).fail(function(xhr,textStatus,err) { + if (xhr.status === 401) { + RED.notify(RED._("library.saveFailed",{message:RED._("user.notAuthorized")}),"error"); + } else { + RED.notify(RED._("library.saveFailed",{message:xhr.responseText}),"error"); + } + }); + } + if (selectedPath.children) { + var exists = false; + selectedPath.children.forEach(function(f) { + if (f.label === filename) { + exists = true; + } + }); + if (exists) { + $( "#red-ui-library-dialog-save" ).dialog("close"); + var notification = RED.notify(RED._("clipboard.export.exists",{file:RED.utils.sanitize(filename)}),{ + type: "warning", + fixed: true, + buttons: [{ + text: RED._("common.label.cancel"), + click: function() { + notification.hideNotification() + $( "#red-ui-library-dialog-save" ).dialog( "open" ); + } + },{ + text: RED._("clipboard.export.overwrite"), + click: function() { + notification.hideNotification() + saveFlow(); + } + }] + }); + } else { + saveFlow(); + } + } else { + saveFlow(); + } + } + + function loadLibraryFolder(library,type,root,done) { + $.getJSON("library/"+library+"/"+type+"/"+root,function(data) { + var items = data.map(function(d) { + if (typeof d === "string") { + return { + library: library, + type: type, + icon: 'fa fa-folder', + label: d, + path: root+d+"/", + children: function(done, item) { + loadLibraryFolder(library,type,root+d+"/", function(children) { + item.children = children; // TODO: should this be done by treeList for us + done(children); + }) + } + }; + } else { + return { + library: library, + type: type, + icon: 'fa fa-file-o', + label: d.fn, + path: root+d.fn, + props: d + }; + } + }); + items.sort(function(A,B){ + if (A.children && !B.children) { + return -1; + } else if (!A.children && B.children) { + return 1; + } else { + return A.label.localeCompare(B.label); + } + }); + done(items); + }); + } + + var validateExportFilenameTimeout; + function validateExportFilename(filenameInput) { + if (validateExportFilenameTimeout) { + clearTimeout(validateExportFilenameTimeout); + } + validateExportFilenameTimeout = setTimeout(function() { + var filename = filenameInput.val().trim(); + var valid = filename.length > 0 && !/[\/\\]/.test(filename); + if (valid) { + filenameInput.removeClass("input-error"); + $("#red-ui-library-dialog-save-button").button("enable"); + } else { + filenameInput.addClass("input-error"); + $("#red-ui-library-dialog-save-button").button("disable"); + } + },100); + } + + function createUI(options) { + var libraryData = {}; + var elementPrefix = options.elementPrefix || "node-input-"; + + // Orion editor has set/getText + // ACE editor has set/getValue + // normalise to set/getValue + if (options.editor.setText) { + // Orion doesn't like having pos passed in, so proxy the call to drop it + options.editor.setValue = function(text,pos) { + options.editor.setText.call(options.editor,text); + } + } + if (options.editor.getText) { + options.editor.getValue = options.editor.getText; + } + + // Add the library button to the name <input> in the edit dialog + $('#'+elementPrefix+"name").css("width","calc(100% - 52px)").after( + '<div style="margin-left:5px; display: inline-block;position: relative;">'+ + '<a id="node-input-'+options.type+'-lookup" class="red-ui-button"><i class="fa fa-book"></i> <i class="fa fa-caret-down"></i></a>'+ + '</div>' + + // '<ul class="red-ui-menu-dropdown pull-right" role="menu">'+ + // '<li><a id="node-input-'+options.type+'-menu-open-library" tabindex="-1" href="#">'+RED._("library.openLibrary")+'</a></li>'+ + // '<li><a id="node-input-'+options.type+'-menu-save-library" tabindex="-1" href="#">'+RED._("library.saveToLibrary")+'</a></li>'+ + // '</ul></div>' + ); + RED.menu.init({id:'node-input-'+options.type+'-lookup', options: [ + { id:'node-input-'+options.type+'-menu-open-library', + label: RED._("library.openLibrary"), + onselect: function() { + activeLibrary = options; + loadLibraryFolder("local",options.url, "", function(items) { + var listing = [{ + library: "local", + type: options.url, + icon: 'fa fa-hdd-o', + label: RED._("library.types.local"), + path: "", + expanded: true, + writable: false, + children: [{ + library: "local", + type: options.url, + icon: 'fa fa-cube', + label: options.type, + path: "", + expanded: true, + children: items + }] + }] + loadLibraryBrowser.data(listing); + setTimeout(function() { + loadLibraryBrowser.select(listing[0].children[0]); + },200); + }); + libraryEditor = ace.edit('red-ui-library-dialog-load-preview-text',{ + useWorker: false + }); + libraryEditor.setTheme("ace/theme/tomorrow"); + if (options.mode) { + libraryEditor.getSession().setMode(options.mode); + } + libraryEditor.setOptions({ + readOnly: true, + highlightActiveLine: false, + highlightGutterLine: false + }); + libraryEditor.renderer.$cursorLayer.element.style.opacity=0; + libraryEditor.$blockScrolling = Infinity; + + $( "#red-ui-library-dialog-load" ).dialog("option","title",RED._("library.typeLibrary", {type:options.type})).dialog( "open" ); + } + }, + { id:'node-input-'+options.type+'-menu-save-library', + label: RED._("library.saveToLibrary"), + onselect: function() { + activeLibrary = options; + //var found = false; + var name = $("#"+elementPrefix+"name").val().replace(/(^\s*)|(\s*$)/g,""); + var filename = name.replace(/[^\w-]/g,"-"); + if (filename === "") { + filename = "unnamed-"+options.type; + } + $("#red-ui-library-dialog-save-filename").attr("value",filename+"."+(options.ext||"txt")); + + loadLibraryFolder("local",options.url, "", function(items) { + var listing = [{ + library: "local", + type: options.url, + icon: 'fa fa-hdd-o', + label: RED._("library.types.local"), + path: "", + expanded: true, + writable: false, + children: [{ + library: "local", + type: options.url, + icon: 'fa fa-cube', + label: options.type, + path: "", + expanded: true, + children: items + }] + }] + saveLibraryBrowser.data(listing); + setTimeout(function() { + saveLibraryBrowser.select(listing[0].children[0]); + },200); + }); + $( "#red-ui-library-dialog-save" ).dialog( "open" ); + } + } + ]}) + } + + function exportFlow() { + console.warn("Deprecated call to RED.library.export"); + } + + var menuOptionMenu; + function createBrowser(options) { + var panes = $('<div class="red-ui-library-browser"></div>').appendTo(options.container); + var dirList = $("<div>").css({width: "100%", height: "100%"}).appendTo(panes) + .treeList({}).on('treelistselect', function(event, item) { + if (options.onselect) { + options.onselect(item); + } + }).on('treelistconfirm', function(event, item) { + if (options.onconfirm) { + options.onconfirm(item); + } + }); + var itemTools = $("<div>").css({position: "absolute",bottom:"6px",right:"8px"}); + var menuButton = $('<button class="red-ui-button red-ui-button-small" type="button"><i class="fa fa-ellipsis-h"></i></button>') + .on("click", function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + var elementPos = menuButton.offset(); + + var menuOptionMenu = RED.menu.init({id:"red-ui-library-browser-menu", + options: [ + {id:"red-ui-library-browser-menu-addFolder",label:RED._("library.newFolder"), onselect: function() { + var defaultFolderName = "new-folder"; + var defaultFolderNameMatches = {}; + + var selected = dirList.treeList('selected'); + if (!selected.children) { + selected = selected.parent; + } + var complete = function() { + selected.children.forEach(function(c) { + if (/^new-folder/.test(c.label)) { + defaultFolderNameMatches[c.label] = true + } + }); + var folderIndex = 2; + while(defaultFolderNameMatches[defaultFolderName]) { + defaultFolderName = "new-folder-"+(folderIndex++) + } + + selected.treeList.expand(); + var input = $('<input type="text" class="red-ui-treeList-input">').val(defaultFolderName); + var newItem = { + icon: "fa fa-folder-o", + children:[], + path: selected.path, + element: input + } + var confirmAdd = function() { + var val = input.val().trim(); + if (val === "") { + cancelAdd(); + return; + } else { + for (var i=0;i<selected.children.length;i++) { + if (selected.children[i].label === val) { + cancelAdd(); + return; + } + } + } + newItem.treeList.remove(); + var finalItem = { + library: selected.library, + type: selected.type, + icon: "fa fa-folder", + children:[], + label: val, + path: newItem.path+val+"/" + } + selected.treeList.addChild(finalItem,true); + } + var cancelAdd = function() { + newItem.treeList.remove(); + } + input.on('keydown', function(evt) { + evt.stopPropagation(); + if (evt.keyCode === 13) { + confirmAdd(); + } else if (evt.keyCode === 27) { + cancelAdd(); + } + }) + input.on("blur", function() { + confirmAdd(); + }) + selected.treeList.addChild(newItem); + setTimeout(function() { + input.trigger("focus"); + input.select(); + },400); + } + selected.treeList.expand(complete); + + } }, + // null, + // {id:"red-ui-library-browser-menu-rename",label:"Rename", onselect: function() {} }, + // {id:"red-ui-library-browser-menu-delete",label:"Delete", onselect: function() {} } + ] + }).on('mouseleave', function(){ $(this).remove(); dirList.focus() }) + .on('mouseup', function() { var self = $(this);self.hide(); dirList.focus(); setTimeout(function() { self.remove() },100)}) + .appendTo("body"); + menuOptionMenu.css({ + position: "absolute", + top: elementPos.top+"px", + left: (elementPos.left - menuOptionMenu.width() + 20)+"px" + }).show(); + + }).appendTo(itemTools); + if (options.folderTools) { + dirList.on('treelistselect', function(event, item) { + if (item.writable !== false && item.treeList) { + itemTools.appendTo(item.treeList.label); + } + }); + } + + return { + select: function(item) { + dirList.treeList('select',item); + }, + getSelected: function() { + return dirList.treeList('selected'); + }, + focus: function() { + dirList.focus(); + }, + data: function(content,selectFirst) { + dirList.treeList('data',content); + if (selectFirst) { + setTimeout(function() { + dirList.treeList('select',content[0]); + },100); + } + } + } + } + + return { + init: function() { + + $(_librarySave).appendTo("#red-ui-editor").i18n(); + $(_libraryLookup).appendTo("#red-ui-editor").i18n(); + + $( "#red-ui-library-dialog-save" ).dialog({ + title: RED._("library.saveToLibrary"), + modal: true, + autoOpen: false, + width: 800, + resizable: false, + classes: { + "ui-dialog": "red-ui-editor-dialog", + "ui-dialog-titlebar-close": "hide", + "ui-widget-overlay": "red-ui-editor-dialog" + }, + buttons: [ + { + text: RED._("common.label.cancel"), + click: function() { + $( this ).dialog( "close" ); + } + }, + { + id: "red-ui-library-dialog-save-button", + text: RED._("common.label.save"), + class: "primary", + click: function() { + saveToLibrary(false); + $( this ).dialog( "close" ); + } + } + ] + }); + + saveLibraryBrowser = RED.library.createBrowser({ + container: $("#red-ui-library-dialog-save-browser"), + folderTools: true, + onselect: function(item) { + if (item.label) { + if (!item.children) { + $("#red-ui-library-dialog-save-filename").val(item.label); + item = item.parent; + } + if (item.writable === false) { + $("#red-ui-library-dialog-save-button").button("disable"); + } else { + $("#red-ui-library-dialog-save-button").button("enable"); + } + } + } + }); + $("#red-ui-library-dialog-save-filename").on("keyup", function() { validateExportFilename($(this))}); + $("#red-ui-library-dialog-save-filename").on('paste',function() { var input = $(this); setTimeout(function() { validateExportFilename(input)},10)}); + + $( "#red-ui-library-dialog-load" ).dialog({ + modal: true, + autoOpen: false, + width: 800, + resizable: false, + classes: { + "ui-dialog": "red-ui-editor-dialog", + "ui-dialog-titlebar-close": "hide", + "ui-widget-overlay": "red-ui-editor-dialog" + }, + buttons: [ + { + text: RED._("common.label.cancel"), + click: function() { + $( this ).dialog( "close" ); + } + }, + { + text: RED._("common.label.load"), + class: "primary", + click: function() { + if (selectedLibraryItem) { + var elementPrefix = activeLibrary.elementPrefix || "node-input-"; + for (var i=0; i<activeLibrary.fields.length; i++) { + var field = activeLibrary.fields[i]; + $("#"+elementPrefix+field).val(selectedLibraryItem[field]); + } + activeLibrary.editor.setValue(libraryEditor.getValue(),-1); + } + $( this ).dialog( "close" ); + } + } + ], + open: function(e) { + $(this).parent().find(".ui-dialog-titlebar-close").hide(); + }, + close: function(e) { + if (libraryEditor) { + libraryEditor.destroy(); + libraryEditor = null; + } + } + }); + loadLibraryBrowser = RED.library.createBrowser({ + container: $("#red-ui-library-dialog-load-browser"), + onselect: function(file) { + var table = $("#red-ui-library-dialog-load-preview-details-table").empty(); + selectedLibraryItem = file.props; + if (file && file.label && !file.children) { + $.get("library/"+file.library+"/"+file.type+"/"+file.path, function(data) { + //TODO: nls + sanitize + var propRow = $('<tr class="red-ui-help-info-row"><td>Type</td><td></td></tr>').appendTo(table); + $(propRow.children()[1]).text(activeLibrary.type); + if (file.props.hasOwnProperty('name')) { + propRow = $('<tr class="red-ui-help-info-row"><td>Name</td><td>'+file.props.name+'</td></tr>').appendTo(table); + $(propRow.children()[1]).text(file.props.name); + } + for (var p in file.props) { + if (file.props.hasOwnProperty(p) && p !== 'name' && p !== 'fn') { + propRow = $('<tr class="red-ui-help-info-row"><td></td><td></td></tr>').appendTo(table); + $(propRow.children()[0]).text(p); + RED.utils.createObjectElement(file.props[p]).appendTo(propRow.children()[1]); + } + } + libraryEditor.setValue(data,-1); + }); + } else { + libraryEditor.setValue("",-1); + } + } + }); + RED.panels.create({ + container:$("#red-ui-library-dialog-load-panes"), + dir: "horizontal", + resize: function() { + libraryEditor.resize(); + } + }); + RED.panels.create({ + container:$("#red-ui-library-dialog-load-preview"), + dir: "vertical", + resize: function() { + libraryEditor.resize(); + } + }); + }, + create: createUI, + createBrowser:createBrowser, + export: exportFlow, + loadLibraryFolder: loadLibraryFolder + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/notifications.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/notifications.js new file mode 100644 index 0000000..e252570 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/notifications.js @@ -0,0 +1,277 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.notifications = (function() { + + /* + If RED.notifications.hide is set to true, all notifications will be hidden. + This is to help with UI testing in certain cases and not intended for the + end-user. + + // Example usage for a modal dialog with buttons + var myNotification = RED.notify("This is the message to display",{ + modal: true, + fixed: true, + type: 'warning', // 'compact', 'success', 'warning', 'error' + buttons: [ + { + text: "cancel", + click: function(e) { + myNotification.close(); + } + }, + { + text: "okay", + class:"primary", + click: function(e) { + myNotification.close(); + } + } + ] + }); + */ + + var persistentNotifications = {}; + + var currentNotifications = []; + var c = 0; + function notify(msg,type,fixed,timeout) { + var options = {}; + if (type !== null && typeof type === 'object') { + options = type; + fixed = options.fixed; + timeout = options.timeout; + type = options.type; + } + + if (options.id && persistentNotifications.hasOwnProperty(options.id)) { + persistentNotifications[options.id].update(msg,options); + return persistentNotifications[options.id]; + } + + if (options.modal) { + $("#red-ui-full-shade").show(); + } + + if (currentNotifications.length > 4) { + var ll = currentNotifications.length; + for (var i = 0;ll > 4 && i<currentNotifications.length;i+=1) { + var notifiction = currentNotifications[i]; + if (!notifiction.fixed) { + window.clearTimeout(notifiction.timeoutid); + notifiction.close(); + ll -= 1; + } + } + } + var n = document.createElement("div"); + n.id="red-ui-notification-"+c; + n.className = "red-ui-notification"; + n.fixed = fixed; + if (type) { + n.className = "red-ui-notification red-ui-notification-"+type; + } + if (options.width) { + var parentWidth = $("#red-ui-notifications").width(); + if (options.width > parentWidth) { + var margin = -(options.width-parentWidth)/2; + $(n).css({ + width: options.width+"px", + marginLeft: margin+"px" + }) + } + } + n.style.display = "none"; + if (typeof msg === "string") { + if (!/<p>/i.test(msg)) { + msg = "<p>"+msg+"</p>"; + } + n.innerHTML = msg; + } else { + $(n).append(msg); + } + if (options.buttons) { + var buttonSet = $('<div class="ui-dialog-buttonset"></div>').appendTo(n) + options.buttons.forEach(function(buttonDef) { + var b = $('<button>').html(buttonDef.text).on("click", buttonDef.click).appendTo(buttonSet); + if (buttonDef.id) { + b.attr('id',buttonDef.id); + } + if (buttonDef.class) { + b.addClass(buttonDef.class); + } + }) + } + + + $("#red-ui-notifications").append(n); + if (!RED.notifications.hide) { + $(n).slideDown(300); + } + n.close = (function() { + var nn = n; + return function() { + if (nn.closed) { + return; + } + nn.closed = true; + currentNotifications.splice(currentNotifications.indexOf(nn),1); + if (options.id) { + delete persistentNotifications[options.id]; + if (Object.keys(persistentNotifications).length === 0) { + notificationButtonWrapper.hide(); + } + } + if (!RED.notifications.hide) { + $(nn).slideUp(300, function() { + nn.parentNode.removeChild(nn); + }); + } else { + nn.parentNode.removeChild(nn); + } + if (options.modal) { + $("#red-ui-full-shade").hide(); + } + }; + })(); + n.hideNotification = (function() { + var nn = n; + return function() { + if (nn.closed) { + return + } + nn.hidden = true; + if (!RED.notifications.hide) { + $(nn).slideUp(300); + } + } + })(); + n.showNotification = (function() { + var nn = n; + return function() { + if (nn.closed || !nn.hidden) { + return + } + nn.hidden = false; + if (!RED.notifications.hide) { + $(nn).slideDown(300); + } + } + })(); + + n.update = (function() { + var nn = n; + return function(msg,options) { + if (typeof msg === "string") { + if (!/<p>/i.test(msg)) { + msg = "<p>"+msg+"</p>"; + } + nn.innerHTML = msg; + } else { + $(nn).empty().append(msg); + } + var timeout; + if (typeof options === 'number') { + timeout = options; + } else if (options !== undefined) { + if (!options.fixed) { + timeout = options.timeout || 5000; + } + if (options.buttons) { + var buttonSet = $('<div style="margin-top: 20px;" class="ui-dialog-buttonset"></div>').appendTo(nn) + options.buttons.forEach(function(buttonDef) { + var b = $('<button>').text(buttonDef.text).on("click", buttonDef.click).appendTo(buttonSet); + if (buttonDef.id) { + b.attr('id',buttonDef.id); + } + if (buttonDef.class) { + b.addClass(buttonDef.class); + } + }) + } + } + if (timeout !== undefined && timeout > 0) { + window.clearTimeout(nn.timeoutid); + nn.timeoutid = window.setTimeout(nn.close,timeout); + } else { + window.clearTimeout(nn.timeoutid); + } + if (nn.hidden) { + nn.showNotification(); + } else if (!options || !options.silent){ + $(nn).addClass("red-ui-notification-shake-horizontal"); + setTimeout(function() { + $(nn).removeClass("red-ui-notification-shake-horizontal"); + },300); + } + + } + })(); + + if (!fixed) { + $(n).on("click", (function() { + var nn = n; + return function() { + nn.close(); + window.clearTimeout(nn.timeoutid); + }; + })()); + n.timeoutid = window.setTimeout(n.close,timeout||5000); + } + currentNotifications.push(n); + if (options.id) { + persistentNotifications[options.id] = n; + if (options.fixed) { + notificationButtonWrapper.show(); + } + } + c+=1; + return n; + } + + RED.notify = notify; + + + function hidePersistent() { + for(var i in persistentNotifications) { + if (persistentNotifications.hasOwnProperty(i)) { + persistentNotifications[i].hideNotification(); + } + } + } + function showPersistent() { + for(var i in persistentNotifications) { + if (persistentNotifications.hasOwnProperty(i)) { + persistentNotifications[i].showNotification(); + } + } + } + + var notificationButtonWrapper; + + return { + init: function() { + $('<div id="red-ui-notifications"></div>').appendTo("#red-ui-editor"); + + notificationButtonWrapper = $('<li></li>').prependTo(".red-ui-header-toolbar").hide(); + $('<a class="button" href="#"><i class="fa fa-warning"></i></a>') + .appendTo(notificationButtonWrapper) + .on("click", function() { + showPersistent(); + }) + }, + notify: notify + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js new file mode 100644 index 0000000..b2dd38e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js @@ -0,0 +1,1069 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.palette.editor = (function() { + + var disabled = false; + + var editorTabs; + var filterInput; + var searchInput; + var nodeList; + var packageList; + var loadedList = []; + var filteredList = []; + var loadedIndex = {}; + + var typesInUse = {}; + var nodeEntries = {}; + var eventTimers = {}; + var activeFilter = ""; + + function semVerCompare(A,B) { + var aParts = A.split(".").map(function(m) { return parseInt(m);}); + var bParts = B.split(".").map(function(m) { return parseInt(m);}); + for (var i=0;i<3;i++) { + var j = aParts[i]-bParts[i]; + if (j<0) { return -1 } + if (j>0) { return 1 } + } + return 0; + } + + function delayCallback(start,callback) { + var delta = Date.now() - start; + if (delta < 300) { + delta = 300; + } else { + delta = 0; + } + setTimeout(function() { + callback(); + },delta); + } + function changeNodeState(id,state,shade,callback) { + shade.show(); + var start = Date.now(); + $.ajax({ + url:"nodes/"+id, + type: "PUT", + data: JSON.stringify({ + enabled: state + }), + contentType: "application/json; charset=utf-8" + }).done(function(data,textStatus,xhr) { + delayCallback(start,function() { + shade.hide(); + callback(); + }); + }).fail(function(xhr,textStatus,err) { + delayCallback(start,function() { + shade.hide(); + callback(xhr); + }); + }) + } + function installNodeModule(id,version,callback) { + var requestBody = { + module: id + }; + if (version) { + requestBody.version = version; + } + $.ajax({ + url:"nodes", + type: "POST", + data: JSON.stringify(requestBody), + contentType: "application/json; charset=utf-8" + }).done(function(data,textStatus,xhr) { + callback(); + }).fail(function(xhr,textStatus,err) { + callback(xhr); + }); + } + function removeNodeModule(id,callback) { + $.ajax({ + url:"nodes/"+id, + type: "DELETE" + }).done(function(data,textStatus,xhr) { + callback(); + }).fail(function(xhr,textStatus,err) { + callback(xhr); + }) + } + + function refreshNodeModuleList() { + for (var id in nodeEntries) { + if (nodeEntries.hasOwnProperty(id)) { + _refreshNodeModule(id); + } + } + } + + function refreshNodeModule(module) { + if (!eventTimers.hasOwnProperty(module)) { + eventTimers[module] = setTimeout(function() { + delete eventTimers[module]; + _refreshNodeModule(module); + },100); + } + } + + + function getContrastingBorder(rgbColor){ + var parts = /^rgba?\(\s*(\d+),\s*(\d+),\s*(\d+)[,)]/.exec(rgbColor); + if (parts) { + var r = parseInt(parts[1]); + var g = parseInt(parts[2]); + var b = parseInt(parts[3]); + var yiq = ((r*299)+(g*587)+(b*114))/1000; + if (yiq > 160) { + r = Math.floor(r*0.8); + g = Math.floor(g*0.8); + b = Math.floor(b*0.8); + return "rgb("+r+","+g+","+b+")"; + } + } + return rgbColor; + } + + function formatUpdatedAt(dateString) { + var now = new Date(); + var d = new Date(dateString); + var delta = (Date.now() - new Date(dateString).getTime())/1000; + + if (delta < 60) { + return RED._('palette.editor.times.seconds'); + } + delta = Math.floor(delta/60); + if (delta < 10) { + return RED._('palette.editor.times.minutes'); + } + if (delta < 60) { + return RED._('palette.editor.times.minutesV',{count:delta}); + } + + delta = Math.floor(delta/60); + + if (delta < 24) { + return RED._('palette.editor.times.hoursV',{count:delta}); + } + + delta = Math.floor(delta/24); + + if (delta < 7) { + return RED._('palette.editor.times.daysV',{count:delta}) + } + var weeks = Math.floor(delta/7); + var days = delta%7; + + if (weeks < 4) { + return RED._('palette.editor.times.weeksV',{count:weeks}) + } + + var months = Math.floor(weeks/4); + weeks = weeks%4; + + if (months < 12) { + return RED._('palette.editor.times.monthsV',{count:months}) + } + var years = Math.floor(months/12); + months = months%12; + + if (months === 0) { + return RED._('palette.editor.times.yearsV',{count:years}) + } else { + return RED._('palette.editor.times.year'+(years>1?'s':'')+'MonthsV',{y:years,count:months}) + } + } + + + function _refreshNodeModule(module) { + if (!nodeEntries.hasOwnProperty(module)) { + nodeEntries[module] = {info:RED.nodes.registry.getModule(module)}; + var index = [module]; + for (var s in nodeEntries[module].info.sets) { + if (nodeEntries[module].info.sets.hasOwnProperty(s)) { + index.push(s); + index = index.concat(nodeEntries[module].info.sets[s].types) + } + } + nodeEntries[module].index = index.join(",").toLowerCase(); + nodeList.editableList('addItem', nodeEntries[module]); + } else { + var moduleInfo = nodeEntries[module].info; + var nodeEntry = nodeEntries[module].elements; + if (nodeEntry) { + var activeTypeCount = 0; + var typeCount = 0; + var errorCount = 0; + nodeEntry.errorList.empty(); + nodeEntries[module].totalUseCount = 0; + nodeEntries[module].setUseCount = {}; + + for (var setName in moduleInfo.sets) { + if (moduleInfo.sets.hasOwnProperty(setName)) { + var inUseCount = 0; + var set = moduleInfo.sets[setName]; + var setElements = nodeEntry.sets[setName]; + if (set.err) { + errorCount++; + $("<li>").text(set.err).appendTo(nodeEntry.errorList); + } + if (set.enabled) { + activeTypeCount += set.types.length; + } + typeCount += set.types.length; + for (var i=0;i<moduleInfo.sets[setName].types.length;i++) { + var t = moduleInfo.sets[setName].types[i]; + inUseCount += (typesInUse[t]||0); + var swatch = setElements.swatches[t]; + if (set.enabled) { + var def = RED.nodes.getType(t); + if (def && def.color) { + swatch.css({background:RED.utils.getNodeColor(t,def)}); + swatch.css({border: "1px solid "+getContrastingBorder(swatch.css('backgroundColor'))}) + } + } + } + nodeEntries[module].setUseCount[setName] = inUseCount; + nodeEntries[module].totalUseCount += inUseCount; + + if (inUseCount > 0) { + setElements.enableButton.text(RED._('palette.editor.inuse')); + setElements.enableButton.addClass('disabled'); + } else { + setElements.enableButton.removeClass('disabled'); + if (set.enabled) { + setElements.enableButton.text(RED._('palette.editor.disable')); + } else { + setElements.enableButton.text(RED._('palette.editor.enable')); + } + } + setElements.setRow.toggleClass("red-ui-palette-module-set-disabled",!set.enabled); + } + } + + if (errorCount === 0) { + nodeEntry.errorRow.hide() + } else { + nodeEntry.errorRow.show(); + } + + var nodeCount = (activeTypeCount === typeCount)?typeCount:activeTypeCount+" / "+typeCount; + nodeEntry.setCount.text(RED._('palette.editor.nodeCount',{count:typeCount,label:nodeCount})); + + if (nodeEntries[module].totalUseCount > 0) { + nodeEntry.enableButton.text(RED._('palette.editor.inuse')); + nodeEntry.enableButton.addClass('disabled'); + nodeEntry.removeButton.hide(); + } else { + nodeEntry.enableButton.removeClass('disabled'); + if (moduleInfo.local) { + nodeEntry.removeButton.css('display', 'inline-block'); + } + if (activeTypeCount === 0) { + nodeEntry.enableButton.text(RED._('palette.editor.enableall')); + } else { + nodeEntry.enableButton.text(RED._('palette.editor.disableall')); + } + nodeEntry.container.toggleClass("disabled",(activeTypeCount === 0)); + } + } + if (moduleInfo.pending_version) { + nodeEntry.versionSpan.html(moduleInfo.version+' <i class="fa fa-long-arrow-right"></i> '+moduleInfo.pending_version).appendTo(nodeEntry.metaRow) + nodeEntry.updateButton.text(RED._('palette.editor.updated')).addClass('disabled').css('display', 'inline-block'); + } else if (loadedIndex.hasOwnProperty(module)) { + if (semVerCompare(loadedIndex[module].version,moduleInfo.version) === 1) { + nodeEntry.updateButton.show(); + nodeEntry.updateButton.text(RED._('palette.editor.update',{version:loadedIndex[module].version})); + } else { + nodeEntry.updateButton.hide(); + } + } else { + nodeEntry.updateButton.hide(); + } + } + + } + + function filterChange(val) { + activeFilter = val.toLowerCase(); + var visible = nodeList.editableList('filter'); + var size = nodeList.editableList('length'); + if (val === "") { + filterInput.searchBox('count'); + } else { + filterInput.searchBox('count',visible+" / "+size); + } + } + + + var catalogueCount; + var catalogueLoadStatus = []; + var catalogueLoadStart; + var catalogueLoadErrors = false; + + var activeSort = sortModulesRelevance; + + function handleCatalogResponse(err,catalog,index,v) { + catalogueLoadStatus.push(err||v); + if (!err) { + if (v.modules) { + v.modules.forEach(function(m) { + loadedIndex[m.id] = m; + m.index = [m.id]; + if (m.keywords) { + m.index = m.index.concat(m.keywords); + } + if (m.types) { + m.index = m.index.concat(m.types); + } + if (m.updated_at) { + m.timestamp = new Date(m.updated_at).getTime(); + } else { + m.timestamp = 0; + } + m.index = m.index.join(",").toLowerCase(); + }) + loadedList = loadedList.concat(v.modules); + } + searchInput.searchBox('count',loadedList.length); + } else { + catalogueLoadErrors = true; + } + if (catalogueCount > 1) { + $(".red-ui-palette-module-shade-status").html(RED._('palette.editor.loading')+"<br>"+catalogueLoadStatus.length+"/"+catalogueCount); + } + if (catalogueLoadStatus.length === catalogueCount) { + if (catalogueLoadErrors) { + RED.notify(RED._('palette.editor.errors.catalogLoadFailed',{url: catalog}),"error",false,8000); + } + var delta = 250-(Date.now() - catalogueLoadStart); + setTimeout(function() { + $("#red-ui-palette-module-install-shade").hide(); + },Math.max(delta,0)); + + } + } + + function initInstallTab() { + if (loadedList.length === 0) { + loadedList = []; + loadedIndex = {}; + packageList.editableList('empty'); + + $(".red-ui-palette-module-shade-status").text(RED._('palette.editor.loading')); + var catalogues = RED.settings.theme('palette.catalogues')||['https://catalogue.nodered.org/catalogue.json']; + catalogueLoadStatus = []; + catalogueLoadErrors = false; + catalogueCount = catalogues.length; + if (catalogues.length > 1) { + $(".red-ui-palette-module-shade-status").html(RED._('palette.editor.loading')+"<br>0/"+catalogues.length); + } + $("#red-ui-palette-module-install-shade").show(); + catalogueLoadStart = Date.now(); + var handled = 0; + catalogues.forEach(function(catalog,index) { + $.getJSON(catalog, {_: new Date().getTime()},function(v) { + handleCatalogResponse(null,catalog,index,v); + refreshNodeModuleList(); + }).fail(function(jqxhr, textStatus, error) { + console.warn("Error loading catalog",catalog,":",error); + handleCatalogResponse(jqxhr,catalog,index); + }).always(function() { + handled++; + if (handled === catalogueCount) { + searchInput.searchBox('change'); + } + }) + }); + } + } + + function refreshFilteredItems() { + packageList.editableList('empty'); + var currentFilter = searchInput.searchBox('value').trim(); + if (currentFilter === ""){ + packageList.editableList('addItem',{count:loadedList.length}) + return; + } + filteredList.sort(activeSort); + for (var i=0;i<Math.min(10,filteredList.length);i++) { + packageList.editableList('addItem',filteredList[i]); + } + if (filteredList.length === 0) { + packageList.editableList('addItem',{}); + } + + if (filteredList.length > 10) { + packageList.editableList('addItem',{start:10,more:filteredList.length-10}) + } + } + function sortModulesRelevance(A,B) { + var currentFilter = searchInput.searchBox('value').trim(); + if (currentFilter === "") { + return sortModulesAZ(A,B); + } + var i = A.info.index.indexOf(currentFilter) - B.info.index.indexOf(currentFilter); + if (i === 0) { + return sortModulesAZ(A,B); + } + return i; + } + function sortModulesAZ(A,B) { + return A.info.id.localeCompare(B.info.id); + } + function sortModulesRecent(A,B) { + return -1 * (A.info.timestamp-B.info.timestamp); + } + + + function init() { + if (RED.settings.theme('palette.editable') === false) { + return; + } + createSettingsPane(); + + RED.userSettings.add({ + id:'palette', + title: RED._("palette.editor.palette"), + get: getSettingsPane, + close: function() { + settingsPane.detach(); + }, + focus: function() { + editorTabs.resize(); + setTimeout(function() { + filterInput.trigger("focus"); + },200); + } + }) + + RED.actions.add("core:manage-palette",function() { + RED.userSettings.show('palette'); + }); + + RED.events.on('registry:module-updated', function(ns) { + refreshNodeModule(ns.module); + }); + RED.events.on('registry:node-set-enabled', function(ns) { + refreshNodeModule(ns.module); + }); + RED.events.on('registry:node-set-disabled', function(ns) { + refreshNodeModule(ns.module); + }); + RED.events.on('registry:node-type-added', function(nodeType) { + if (!/^subflow:/.test(nodeType)) { + var ns = RED.nodes.registry.getNodeSetForType(nodeType); + refreshNodeModule(ns.module); + } + }); + RED.events.on('registry:node-type-removed', function(nodeType) { + if (!/^subflow:/.test(nodeType)) { + var ns = RED.nodes.registry.getNodeSetForType(nodeType); + refreshNodeModule(ns.module); + } + }); + RED.events.on('registry:node-set-added', function(ns) { + refreshNodeModule(ns.module); + for (var i=0;i<filteredList.length;i++) { + if (filteredList[i].info.id === ns.module) { + var installButton = filteredList[i].elements.installButton; + installButton.addClass('disabled'); + installButton.text(RED._('palette.editor.installed')); + break; + } + } + }); + RED.events.on('registry:node-set-removed', function(ns) { + var module = RED.nodes.registry.getModule(ns.module); + if (!module) { + var entry = nodeEntries[ns.module]; + if (entry) { + nodeList.editableList('removeItem', entry); + delete nodeEntries[ns.module]; + for (var i=0;i<filteredList.length;i++) { + if (filteredList[i].info.id === ns.module) { + var installButton = filteredList[i].elements.installButton; + installButton.removeClass('disabled'); + installButton.text(RED._('palette.editor.install')); + break; + } + } + } + } + }); + RED.events.on('nodes:add', function(n) { + if (!/^subflow:/.test(n.type)) { + typesInUse[n.type] = (typesInUse[n.type]||0)+1; + if (typesInUse[n.type] === 1) { + var ns = RED.nodes.registry.getNodeSetForType(n.type); + refreshNodeModule(ns.module); + } + } + }) + RED.events.on('nodes:remove', function(n) { + if (typesInUse.hasOwnProperty(n.type)) { + typesInUse[n.type]--; + if (typesInUse[n.type] === 0) { + delete typesInUse[n.type]; + var ns = RED.nodes.registry.getNodeSetForType(n.type); + refreshNodeModule(ns.module); + } + } + }) + } + + var settingsPane; + + function getSettingsPane() { + initInstallTab(); + editorTabs.activateTab('nodes'); + return settingsPane; + } + + + + function createSettingsPane() { + settingsPane = $('<div id="red-ui-settings-tab-palette"></div>'); + var content = $('<div id="red-ui-palette-editor">'+ + '<ul id="red-ui-palette-editor-tabs"></ul>'+ + '</div>').appendTo(settingsPane); + + editorTabs = RED.tabs.create({ + element: settingsPane.find('#red-ui-palette-editor-tabs'), + onchange:function(tab) { + content.find(".red-ui-palette-editor-tab").hide(); + tab.content.show(); + if (filterInput) { + filterInput.searchBox('value',""); + } + if (searchInput) { + searchInput.searchBox('value',""); + } + if (tab.id === 'install') { + if (searchInput) { + searchInput.trigger("focus"); + } + } else { + if (filterInput) { + filterInput.trigger("focus"); + } + } + }, + minimumActiveTabWidth: 110 + }); + + + var modulesTab = $('<div>',{class:"red-ui-palette-editor-tab"}).appendTo(content); + + editorTabs.addTab({ + id: 'nodes', + label: RED._('palette.editor.tab-nodes'), + content: modulesTab + }) + + var filterDiv = $('<div>',{class:"red-ui-palette-search"}).appendTo(modulesTab); + filterInput = $('<input type="text" data-i18n="[placeholder]palette.filter"></input>') + .appendTo(filterDiv) + .searchBox({ + delay: 200, + change: function() { + filterChange($(this).val()); + } + }); + + + nodeList = $('<ol>',{id:"red-ui-palette-module-list", style:"position: absolute;top: 35px;bottom: 0;left: 0;right: 0px;"}).appendTo(modulesTab).editableList({ + addButton: false, + scrollOnAdd: false, + sort: function(A,B) { + return A.info.name.localeCompare(B.info.name); + }, + filter: function(data) { + if (activeFilter === "" ) { + return true; + } + + return (activeFilter==="")||(data.index.indexOf(activeFilter) > -1); + }, + addItem: function(container,i,object) { + var entry = object.info; + if (entry) { + var headerRow = $('<div>',{class:"red-ui-palette-module-header"}).appendTo(container); + var titleRow = $('<div class="red-ui-palette-module-meta red-ui-palette-module-name"><i class="fa fa-cube"></i></div>').appendTo(headerRow); + $('<span>').text(entry.name).appendTo(titleRow); + var metaRow = $('<div class="red-ui-palette-module-meta red-ui-palette-module-version"><i class="fa fa-tag"></i></div>').appendTo(headerRow); + var versionSpan = $('<span>').text(entry.version).appendTo(metaRow); + + var errorRow = $('<div class="red-ui-palette-module-meta red-ui-palette-module-errors"><i class="fa fa-warning"></i></div>').hide().appendTo(headerRow); + var errorList = $('<ul class="red-ui-palette-module-error-list"></ul>').appendTo(errorRow); + var buttonRow = $('<div>',{class:"red-ui-palette-module-meta"}).appendTo(headerRow); + var setButton = $('<a href="#" class="red-ui-button red-ui-button-small red-ui-palette-module-set-button"><i class="fa fa-angle-right red-ui-palette-module-node-chevron"></i> </a>').appendTo(buttonRow); + var setCount = $('<span>').appendTo(setButton); + var buttonGroup = $('<div>',{class:"red-ui-palette-module-button-group"}).appendTo(buttonRow); + + var updateButton = $('<a href="#" class="red-ui-button red-ui-button-small"></a>').text(RED._('palette.editor.update')).appendTo(buttonGroup); + updateButton.attr('id','up_'+Math.floor(Math.random()*1000000000)); + updateButton.on("click", function(evt) { + evt.preventDefault(); + if ($(this).hasClass('disabled')) { + return; + } + update(entry,loadedIndex[entry.name].version,container,function(err){}); + }) + + + var removeButton = $('<a href="#" class="red-ui-button red-ui-button-small"></a>').text(RED._('palette.editor.remove')).appendTo(buttonGroup); + removeButton.attr('id','up_'+Math.floor(Math.random()*1000000000)); + removeButton.on("click", function(evt) { + evt.preventDefault(); + remove(entry,container,function(err){}); + }) + if (!entry.local) { + removeButton.hide(); + } + var enableButton = $('<a href="#" class="red-ui-button red-ui-button-small"></a>').text(RED._('palette.editor.disableall')).appendTo(buttonGroup); + + var contentRow = $('<div>',{class:"red-ui-palette-module-content"}).appendTo(container); + var shade = $('<div class="red-ui-palette-module-shade hide"><img src="red/images/spin.svg" class="red-ui-palette-spinner"/></div>').appendTo(container); + + object.elements = { + updateButton: updateButton, + removeButton: removeButton, + enableButton: enableButton, + errorRow: errorRow, + errorList: errorList, + setCount: setCount, + container: container, + shade: shade, + versionSpan: versionSpan, + sets: {} + } + setButton.on("click", function(evt) { + evt.preventDefault(); + if (container.hasClass('expanded')) { + container.removeClass('expanded'); + contentRow.slideUp(); + } else { + container.addClass('expanded'); + contentRow.slideDown(); + } + }) + + var setList = Object.keys(entry.sets) + setList.sort(function(A,B) { + return A.toLowerCase().localeCompare(B.toLowerCase()); + }); + setList.forEach(function(setName) { + var set = entry.sets[setName]; + var setRow = $('<div>',{class:"red-ui-palette-module-set"}).appendTo(contentRow); + var buttonGroup = $('<div>',{class:"red-ui-palette-module-set-button-group"}).appendTo(setRow); + var typeSwatches = {}; + set.types.forEach(function(t) { + var typeDiv = $('<div>',{class:"red-ui-palette-module-type"}).appendTo(setRow); + typeSwatches[t] = $('<span>',{class:"red-ui-palette-module-type-swatch"}).appendTo(typeDiv); + $('<span>',{class:"red-ui-palette-module-type-node"}).text(t).appendTo(typeDiv); + }) + var enableButton = $('<a href="#" class="red-ui-button red-ui-button-small"></a>').appendTo(buttonGroup); + enableButton.on("click", function(evt) { + evt.preventDefault(); + if (object.setUseCount[setName] === 0) { + var currentSet = RED.nodes.registry.getNodeSet(set.id); + shade.show(); + var newState = !currentSet.enabled + changeNodeState(set.id,newState,shade,function(xhr){ + if (xhr) { + if (xhr.responseJSON) { + RED.notify(RED._('palette.editor.errors.'+(newState?'enable':'disable')+'Failed',{module: id,message:xhr.responseJSON.message})); + } + } + }); + } + }) + + object.elements.sets[set.name] = { + setRow: setRow, + enableButton: enableButton, + swatches: typeSwatches + }; + }); + enableButton.on("click", function(evt) { + evt.preventDefault(); + if (object.totalUseCount === 0) { + changeNodeState(entry.name,(container.hasClass('disabled')),shade,function(xhr){ + if (xhr) { + if (xhr.responseJSON) { + RED.notify(RED._('palette.editor.errors.installFailed',{module: id,message:xhr.responseJSON.message})); + } + } + }); + } + }) + refreshNodeModule(entry.name); + } else { + $('<div>',{class:"red-ui-search-empty"}).text(RED._('search.empty')).appendTo(container); + } + } + }); + + + + var installTab = $('<div>',{class:"red-ui-palette-editor-tab hide"}).appendTo(content); + + editorTabs.addTab({ + id: 'install', + label: RED._('palette.editor.tab-install'), + content: installTab + }) + + var toolBar = $('<div>',{class:"red-ui-palette-editor-toolbar"}).appendTo(installTab); + + var searchDiv = $('<div>',{class:"red-ui-palette-search"}).appendTo(installTab); + searchInput = $('<input type="text" data-i18n="[placeholder]palette.search"></input>') + .appendTo(searchDiv) + .searchBox({ + delay: 300, + change: function() { + var searchTerm = $(this).val().trim().toLowerCase(); + if (searchTerm.length > 0) { + filteredList = loadedList.filter(function(m) { + return (m.index.indexOf(searchTerm) > -1); + }).map(function(f) { return {info:f}}); + refreshFilteredItems(); + searchInput.searchBox('count',filteredList.length+" / "+loadedList.length); + } else { + searchInput.searchBox('count',loadedList.length); + packageList.editableList('empty'); + packageList.editableList('addItem',{count:loadedList.length}); + + } + } + }); + + + $('<span>').text(RED._("palette.editor.sort")+' ').appendTo(toolBar); + var sortGroup = $('<span class="button-group"></span>').appendTo(toolBar); + var sortRelevance = $('<a href="#" class="red-ui-palette-editor-install-sort-option red-ui-sidebar-header-button-toggle selected"><i class="fa fa-sort-amount-desc"></i></a>').appendTo(sortGroup); + var sortAZ = $('<a href="#" class="red-ui-palette-editor-install-sort-option red-ui-sidebar-header-button-toggle" data-i18n="palette.editor.sortAZ"></a>').appendTo(sortGroup); + var sortRecent = $('<a href="#" class="red-ui-palette-editor-install-sort-option red-ui-sidebar-header-button-toggle" data-i18n="palette.editor.sortRecent"></a>').appendTo(sortGroup); + + + var sortOpts = [ + {button: sortRelevance, func: sortModulesRelevance}, + {button: sortAZ, func: sortModulesAZ}, + {button: sortRecent, func: sortModulesRecent} + ] + sortOpts.forEach(function(opt) { + opt.button.on("click", function(e) { + e.preventDefault(); + if ($(this).hasClass("selected")) { + return; + } + $(".red-ui-palette-editor-install-sort-option").removeClass("selected"); + $(this).addClass("selected"); + activeSort = opt.func; + refreshFilteredItems(); + }); + }); + + var refreshSpan = $('<span>').appendTo(toolBar); + var refreshButton = $('<a href="#" class="red-ui-sidebar-header-button"><i class="fa fa-refresh"></i></a>').appendTo(refreshSpan); + refreshButton.on("click", function(e) { + e.preventDefault(); + loadedList = []; + loadedIndex = {}; + initInstallTab(); + }) + + packageList = $('<ol>',{style:"position: absolute;top: 79px;bottom: 0;left: 0;right: 0px;"}).appendTo(installTab).editableList({ + addButton: false, + scrollOnAdd: false, + addItem: function(container,i,object) { + if (object.count) { + $('<div>',{class:"red-ui-search-empty"}).text(RED._('palette.editor.moduleCount',{count:object.count})).appendTo(container); + return + } + if (object.more) { + container.addClass('red-ui-palette-module-more'); + var moreRow = $('<div>',{class:"red-ui-palette-module-header palette-module"}).appendTo(container); + var moreLink = $('<a href="#"></a>').text(RED._('palette.editor.more',{count:object.more})).appendTo(moreRow); + moreLink.on("click", function(e) { + e.preventDefault(); + packageList.editableList('removeItem',object); + for (var i=object.start;i<Math.min(object.start+10,object.start+object.more);i++) { + packageList.editableList('addItem',filteredList[i]); + } + if (object.more > 10) { + packageList.editableList('addItem',{start:object.start+10, more:object.more-10}) + } + }) + return; + } + if (object.info) { + var entry = object.info; + var headerRow = $('<div>',{class:"red-ui-palette-module-header"}).appendTo(container); + var titleRow = $('<div class="red-ui-palette-module-meta red-ui-palette-module-name"><i class="fa fa-cube"></i></div>').appendTo(headerRow); + $('<span>').text(entry.name||entry.id).appendTo(titleRow); + $('<a target="_blank" class="red-ui-palette-module-link"><i class="fa fa-external-link"></i></a>').attr('href',entry.url).appendTo(titleRow); + var descRow = $('<div class="red-ui-palette-module-meta"></div>').appendTo(headerRow); + $('<div>',{class:"red-ui-palette-module-description"}).text(entry.description).appendTo(descRow); + var metaRow = $('<div class="red-ui-palette-module-meta"></div>').appendTo(headerRow); + $('<span class="red-ui-palette-module-version"><i class="fa fa-tag"></i> '+entry.version+'</span>').appendTo(metaRow); + $('<span class="red-ui-palette-module-updated"><i class="fa fa-calendar"></i> '+formatUpdatedAt(entry.updated_at)+'</span>').appendTo(metaRow); + + var duplicateType = false; + if (entry.types && entry.types.length > 0) { + + for (var i=0;i<entry.types.length;i++) { + var nodeset = RED.nodes.registry.getNodeSetForType(entry.types[i]); + if (nodeset) { + duplicateType = nodeset.module; + break; + } + } + // $('<div>',{class:"red-ui-palette-module-meta"}).text(entry.types.join(",")).appendTo(headerRow); + } + + var buttonRow = $('<div>',{class:"red-ui-palette-module-meta"}).appendTo(headerRow); + var buttonGroup = $('<div>',{class:"red-ui-palette-module-button-group"}).appendTo(buttonRow); + var installButton = $('<a href="#" class="red-ui-button red-ui-button-small"></a>').text(RED._('palette.editor.install')).appendTo(buttonGroup); + installButton.on("click", function(e) { + e.preventDefault(); + if (!$(this).hasClass('disabled')) { + install(entry,container,function(xhr) {}); + } + }) + if (nodeEntries.hasOwnProperty(entry.id)) { + installButton.addClass('disabled'); + installButton.text(RED._('palette.editor.installed')); + } else if (duplicateType) { + installButton.addClass('disabled'); + installButton.text(RED._('palette.editor.conflict')); + RED.popover.create({ + target:installButton, + content: RED._('palette.editor.conflictTip',{module:duplicateType}), + trigger:"hover", + direction:"bottom", + delay:{show:750,hide:50} + }) + } + + object.elements = { + installButton:installButton + } + } else { + $('<div>',{class:"red-ui-search-empty"}).text(RED._('search.empty')).appendTo(container); + } + } + }); + + $('<div id="red-ui-palette-module-install-shade" class="red-ui-palette-module-shade hide"><div class="red-ui-palette-module-shade-status"></div><img src="red/images/spin.svg" class="red-ui-palette-spinner"/></div>').appendTo(installTab); + } + function update(entry,version,container,done) { + if (RED.settings.theme('palette.editable') === false) { + done(new Error('Palette not editable')); + return; + } + var notification = RED.notify(RED._("palette.editor.confirm.update.body",{module:entry.name}),{ + modal: true, + fixed: true, + buttons: [ + { + text: RED._("common.label.cancel"), + click: function() { + notification.close(); + } + }, + { + text: RED._("palette.editor.confirm.button.update"), + class: "primary red-ui-palette-module-install-confirm-button-update", + click: function() { + var spinner = RED.utils.addSpinnerOverlay(container, true); + var buttonRow = $('<div style="position: relative;bottom: calc(50% + 17px); padding-right: 10px;text-align: right;"></div>').appendTo(spinner); + $('<button class="red-ui-button"></button>').text(RED._("eventLog.view")).appendTo(buttonRow).on("click", function(evt) { + evt.preventDefault(); + RED.actions.invoke("core:show-event-log"); + }); + RED.eventLog.startEvent(RED._("palette.editor.confirm.button.install")+" : "+entry.name+" "+version); + installNodeModule(entry.name,version,function(xhr) { + spinner.remove(); + if (xhr) { + if (xhr.responseJSON) { + var notification = RED.notify(RED._('palette.editor.errors.updateFailed',{module: entry.name,message:xhr.responseJSON.message}),{ + type: 'error', + modal: true, + fixed: true, + buttons: [ + { + text: RED._("common.label.close"), + click: function() { + notification.close(); + } + },{ + text: RED._("eventLog.view"), + click: function() { + notification.close(); + RED.actions.invoke("core:show-event-log"); + } + } + ] + }); + } + } + done(xhr); + }); + notification.close(); + } + } + ] + }) + } + function remove(entry,container,done) { + if (RED.settings.theme('palette.editable') === false) { + done(new Error('Palette not editable')); + return; + } + var notification = RED.notify(RED._("palette.editor.confirm.remove.body",{module:entry.name}),{ + modal: true, + fixed: true, + buttons: [ + { + text: RED._("common.label.cancel"), + click: function() { + notification.close(); + } + }, + { + text: RED._("palette.editor.confirm.button.remove"), + class: "primary red-ui-palette-module-install-confirm-button-remove", + click: function() { + var spinner = RED.utils.addSpinnerOverlay(container, true); + var buttonRow = $('<div style="position: relative;bottom: calc(50% + 17px); padding-right: 10px;text-align: right;"></div>').appendTo(spinner); + $('<button class="red-ui-button"></button>').text(RED._("eventLog.view")).appendTo(buttonRow).on("click", function(evt) { + evt.preventDefault(); + RED.actions.invoke("core:show-event-log"); + }); + RED.eventLog.startEvent(RED._("palette.editor.confirm.button.remove")+" : "+entry.name); + removeNodeModule(entry.name, function(xhr) { + spinner.remove(); + if (xhr) { + if (xhr.responseJSON) { + var notification = RED.notify(RED._('palette.editor.errors.removeFailed',{module: entry.name,message:xhr.responseJSON.message}),{ + type: 'error', + modal: true, + fixed: true, + buttons: [ + { + text: RED._("common.label.close"), + click: function() { + notification.close(); + } + },{ + text: RED._("eventLog.view"), + click: function() { + notification.close(); + RED.actions.invoke("core:show-event-log"); + } + } + ] + }); } + } + }) + notification.close(); + } + } + ] + }) + } + function install(entry,container,done) { + if (RED.settings.theme('palette.editable') === false) { + done(new Error('Palette not editable')); + return; + } + var buttons = [ + { + text: RED._("common.label.cancel"), + click: function() { + notification.close(); + } + } + ]; + if (entry.url) { + buttons.push({ + text: RED._("palette.editor.confirm.button.review"), + class: "primary red-ui-palette-module-install-confirm-button-install", + click: function() { + var url = entry.url||""; + window.open(url); + } + }); + } + buttons.push({ + text: RED._("palette.editor.confirm.button.install"), + class: "primary red-ui-palette-module-install-confirm-button-install", + click: function() { + var spinner = RED.utils.addSpinnerOverlay(container, true); + + var buttonRow = $('<div style="position: relative;bottom: calc(50% + 17px); padding-right: 10px;text-align: right;"></div>').appendTo(spinner); + $('<button class="red-ui-button"></button>').text(RED._("eventLog.view")).appendTo(buttonRow).on("click", function(evt) { + evt.preventDefault(); + RED.actions.invoke("core:show-event-log"); + }); + RED.eventLog.startEvent(RED._("palette.editor.confirm.button.install")+" : "+entry.id+" "+entry.version); + installNodeModule(entry.id,entry.version,function(xhr) { + spinner.remove(); + if (xhr) { + if (xhr.responseJSON) { + var notification = RED.notify(RED._('palette.editor.errors.installFailed',{module: entry.id,message:xhr.responseJSON.message}),{ + type: 'error', + modal: true, + fixed: true, + buttons: [ + { + text: RED._("common.label.close"), + click: function() { + notification.close(); + } + },{ + text: RED._("eventLog.view"), + click: function() { + notification.close(); + RED.actions.invoke("core:show-event-log"); + } + } + ] + }); + } + } + done(xhr); + }); + notification.close(); + } + }); + + var notification = RED.notify(RED._("palette.editor.confirm.install.body",{module:entry.id}),{ + modal: true, + fixed: true, + buttons: buttons + }) + } + + return { + init: init, + install: install + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js new file mode 100644 index 0000000..b70854b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js @@ -0,0 +1,651 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +RED.palette = (function() { + + var exclusion = ['config','unknown','deprecated']; + var coreCategories = [ + 'subflows', + 'common', + 'function', + 'network', + 'input', + 'output', + 'sequence', + 'parser', + 'storage', + 'analysis', + 'social', + 'advanced' + ]; + + var categoryContainers = {}; + var sidebarControls; + + function createCategory(originalCategory,rootCategory,category,ns) { + if ($("#red-ui-palette-base-category-"+rootCategory).length === 0) { + createCategoryContainer(originalCategory,rootCategory, ns+":palette.label."+rootCategory); + } + $("#red-ui-palette-container-"+rootCategory).show(); + if ($("#red-ui-palette-"+category).length === 0) { + $("#red-ui-palette-base-category-"+rootCategory).append('<div id="red-ui-palette-'+category+'"></div>'); + } + } + function createCategoryContainer(originalCategory,category, labelId) { + var label = RED._(labelId, {defaultValue:category}); + label = (label || category).replace(/_/g, " "); + var catDiv = $('<div id="red-ui-palette-container-'+category+'" class="red-ui-palette-category hide">'+ + '<div id="red-ui-palette-header-'+category+'" class="red-ui-palette-header"><i class="expanded fa fa-angle-down"></i><span>'+label+'</span></div>'+ + '<div class="red-ui-palette-content" id="red-ui-palette-base-category-'+category+'">'+ + '<div id="red-ui-palette-'+category+'"></div>'+ + '<div id="red-ui-palette-'+category+'-input"></div>'+ + '<div id="red-ui-palette-'+category+'-output"></div>'+ + '<div id="red-ui-palette-'+category+'-function"></div>'+ + '</div>'+ + '</div>').appendTo("#red-ui-palette-container"); + catDiv.data('category',originalCategory); + catDiv.data('label',label); + categoryContainers[category] = { + container: catDiv, + close: function() { + catDiv.removeClass("red-ui-palette-open"); + catDiv.addClass("red-ui-palette-closed"); + $("#red-ui-palette-base-category-"+category).slideUp(); + $("#red-ui-palette-header-"+category+" i").removeClass("expanded"); + }, + open: function() { + catDiv.addClass("red-ui-palette-open"); + catDiv.removeClass("red-ui-palette-closed"); + $("#red-ui-palette-base-category-"+category).slideDown(); + $("#red-ui-palette-header-"+category+" i").addClass("expanded"); + }, + toggle: function() { + if (catDiv.hasClass("red-ui-palette-open")) { + categoryContainers[category].close(); + } else { + categoryContainers[category].open(); + } + } + }; + + $("#red-ui-palette-header-"+category).on('click', function(e) { + categoryContainers[category].toggle(); + }); + } + + function setLabel(type, el,label, info) { + var nodeWidth = 82; + var nodeHeight = 25; + var lineHeight = 20; + var portHeight = 10; + + el.attr("data-palette-label",label); + + label = RED.utils.sanitize(label); + + + var words = label.split(/[ -]/); + + var displayLines = []; + + var currentLine = ""; + for (var i=0;i<words.length;i++) { + var word = words[i]; + var sep = (i == 0) ? "" : " "; + var newWidth = RED.view.calculateTextWidth(currentLine+sep+word, "red-ui-palette-label", 0); + if (newWidth < nodeWidth) { + currentLine += sep +word; + } else { + if (i > 0) { + displayLines.push(currentLine); + } + while (true) { + var wordWidth = RED.view.calculateTextWidth(word, "red-ui-palette-label", 0); + if (wordWidth >= nodeWidth) { + // break word if too wide + for(var j = word.length; j > 0; j--) { + var s = word.substring(0, j); + var width = RED.view.calculateTextWidth(s, "red-ui-palette-label", 0); + if (width < nodeWidth) { + displayLines.push(s); + word = word.substring(j); + break; + } + } + } + else { + currentLine = word; + break; + } + } + } + } + displayLines.push(currentLine); + + var lines = displayLines.join("<br/>"); + var multiLineNodeHeight = 8+(lineHeight*displayLines.length); + el.css({height:multiLineNodeHeight+"px"}); + + var labelElement = el.find(".red-ui-palette-label"); + labelElement.html(lines).attr('dir', RED.text.bidi.resolveBaseTextDir(lines)); + + el.find(".red-ui-palette-port").css({top:(multiLineNodeHeight/2-5)+"px"}); + + var popOverContent; + try { + var l = "<p><b>"+RED.text.bidi.enforceTextDirectionWithUCC(label)+"</b></p>"; + popOverContent = $('<div></div>').append($(l+(info?info:$("script[data-help-name='"+type+"']").html()||"<p>"+RED._("palette.noInfo")+"</p>").trim()) + .filter(function(n) { + return (this.nodeType == 1 && this.nodeName == "P") || (this.nodeType == 3 && this.textContent.trim().length > 0) + }).slice(0,2)); + popOverContent.find("a").each(function(){ + var linkText = $(this).text(); + $(this).before(linkText); + $(this).remove(); + }); + + var typeInfo = RED.nodes.getType(type); + + if (typeInfo) { + var metaData = ""; + if (typeInfo && !/^subflow:/.test(type)) { + metaData = typeInfo.set.module+" : "; + } + metaData += type; + $('<p>',{style:"font-size: 0.8em"}).text(metaData).appendTo(popOverContent); + } + } catch(err) { + // Malformed HTML may cause errors. TODO: need to understand what can break + // NON-NLS: internal debug + console.log("Error generating pop-over label for ",type); + console.log(err.toString()); + popOverContent = "<p><b>"+label+"</b></p><p>"+RED._("palette.noInfo")+"</p>"; + } + + el.data('popover').setContent(popOverContent); + } + + function setIcon(element,sf) { + var icon_url = RED.utils.getNodeIcon(sf._def); + var iconContainer = element.find(".red-ui-palette-icon-container"); + RED.utils.createIconElement(icon_url, iconContainer, true); + } + + function getPaletteNode(type) { + return $(".red-ui-palette-node[data-palette-type='"+type+"']"); + } + + function escapeCategory(category) { + return category.replace(/[ /.]/g,"_"); + } + function addNodeType(nt,def) { + if (getPaletteNode(nt).length) { + return; + } + var nodeCategory = def.category; + + if (exclusion.indexOf(nodeCategory)===-1) { + + var originalCategory = nodeCategory; + var category = escapeCategory(nodeCategory); + var rootCategory = category.split("-")[0]; + + var d = $('<div>',{class:"red-ui-palette-node"}).attr("data-palette-type",nt).data('category',rootCategory); + + var label = nt;///^(.*?)([ -]in|[ -]out)?$/.exec(nt)[1]; + if (typeof def.paletteLabel !== "undefined") { + try { + label = (typeof def.paletteLabel === "function" ? def.paletteLabel.call(def) : def.paletteLabel)||""; + } catch(err) { + console.log("Definition error: "+nt+".paletteLabel",err); + } + } + + $('<div/>', { + class: "red-ui-palette-label"+(((!def.align && def.inputs !== 0 && def.outputs === 0) || "right" === def.align) ? " red-ui-palette-label-right" : "") + }).appendTo(d); + + + if (def.icon) { + var icon_url = RED.utils.getNodeIcon(def); + var iconContainer = $('<div/>', { + class: "red-ui-palette-icon-container"+(((!def.align && def.inputs !== 0 && def.outputs === 0) || "right" === def.align) ? " red-ui-palette-icon-container-right" : "") + }).appendTo(d); + RED.utils.createIconElement(icon_url, iconContainer, true); + } + + d.css("backgroundColor", RED.utils.getNodeColor(nt,def)); + + if (def.outputs > 0) { + var portOut = document.createElement("div"); + portOut.className = "red-ui-palette-port red-ui-palette-port-output"; + d.append(portOut); + } + + if (def.inputs > 0) { + var portIn = document.createElement("div"); + portIn.className = "red-ui-palette-port red-ui-palette-port-input"; + d.append(portIn); + } + + createCategory(nodeCategory,rootCategory,category,(coreCategories.indexOf(rootCategory) !== -1)?"node-red":def.set.id); + + $("#red-ui-palette-"+category).append(d); + + d.on("mousedown", function(e) { e.preventDefault();}); + + var popover = RED.popover.create({ + target:d, + trigger: "hover", + width: "300px", + content: "hi", + delay: { show: 750, hide: 50 } + }); + + d.data('popover',popover); + + // $(d).popover({ + // title:d.type, + // placement:"right", + // trigger: "hover", + // delay: { show: 750, hide: 50 }, + // html: true, + // container:'body' + // }); + d.on("click", function() { + RED.view.focus(); + var helpText; + if (nt.indexOf("subflow:") === 0) { + helpText = RED.utils.renderMarkdown(RED.nodes.subflow(nt.substring(8)).info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>'); + } else { + helpText = $("script[data-help-name='"+d.attr("data-palette-type")+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>'); + } + // Don't look too closely. RED.sidebar.info.set will set the 'Description' + // section of the sidebar. Pass in the title of the Help section so it looks + // right. + RED.sidebar.info.set(helpText,RED._("sidebar.info.nodeHelp")); + }); + var chart = $("#red-ui-workspace-chart"); + var chartSVG = $("#red-ui-workspace-chart>svg").get(0); + var activeSpliceLink; + var mouseX; + var mouseY; + var spliceTimer; + var paletteWidth; + var paletteTop; + $(d).draggable({ + helper: 'clone', + appendTo: '#red-ui-editor', + revert: 'invalid', + revertDuration: 200, + containment:'#red-ui-main-container', + start: function() { + paletteWidth = $("#red-ui-palette").width(); + paletteTop = $("#red-ui-palette").parent().position().top + $("#red-ui-palette-container").position().top; + RED.view.focus(); + }, + stop: function() { d3.select('.red-ui-flow-link-splice').classed('red-ui-flow-link-splice',false); if (spliceTimer) { clearTimeout(spliceTimer); spliceTimer = null;}}, + drag: function(e,ui) { + var paletteNode = getPaletteNode(nt); + ui.originalPosition.left = paletteNode.offset().left; + + if (def.inputs > 0 && def.outputs > 0) { + mouseX = ui.position.left - paletteWidth + (ui.helper.width()/2) + chart.scrollLeft(); + mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop(); + if (!spliceTimer) { + spliceTimer = setTimeout(function() { + var nodes = []; + var bestDistance = Infinity; + var bestLink = null; + if (chartSVG.getIntersectionList) { + var svgRect = chartSVG.createSVGRect(); + svgRect.x = mouseX; + svgRect.y = mouseY; + svgRect.width = 1; + svgRect.height = 1; + nodes = chartSVG.getIntersectionList(svgRect,chartSVG); + mouseX /= RED.view.scale(); + mouseY /= RED.view.scale(); + } else { + // Firefox doesn't do getIntersectionList and that + // makes us sad + mouseX /= RED.view.scale(); + mouseY /= RED.view.scale(); + nodes = RED.view.getLinksAtPoint(mouseX,mouseY); + } + + for (var i=0;i<nodes.length;i++) { + var node = d3.select(nodes[i]); + if (node.classed('red-ui-flow-link-background') && !node.classed('red-ui-flow-link-link')) { + var length = nodes[i].getTotalLength(); + for (var j=0;j<length;j+=10) { + var p = nodes[i].getPointAtLength(j); + var d2 = ((p.x-mouseX)*(p.x-mouseX))+((p.y-mouseY)*(p.y-mouseY)); + if (d2 < 200 && d2 < bestDistance) { + bestDistance = d2; + bestLink = nodes[i]; + } + } + } + } + if (activeSpliceLink && activeSpliceLink !== bestLink) { + d3.select(activeSpliceLink.parentNode).classed('red-ui-flow-link-splice',false); + } + if (bestLink) { + d3.select(bestLink.parentNode).classed('red-ui-flow-link-splice',true) + } else { + d3.select('.red-ui-flow-link-splice').classed('red-ui-flow-link-splice',false); + } + if (activeSpliceLink !== bestLink) { + if (bestLink) { + $(ui.helper).data('splice',d3.select(bestLink).data()[0]); + } else { + $(ui.helper).removeData('splice'); + } + } + activeSpliceLink = bestLink; + spliceTimer = null; + },200); + } + } + } + }); + + var nodeInfo = null; + if (nt.indexOf("subflow:") === 0) { + d.on("dblclick", function(e) { + RED.workspaces.show(nt.substring(8)); + e.preventDefault(); + }); + nodeInfo = RED.utils.renderMarkdown(def.info||""); + } + setLabel(nt,d,label,nodeInfo); + + var categoryNode = $("#red-ui-palette-container-"+rootCategory); + if (categoryNode.find(".red-ui-palette-node").length === 1) { + categoryContainers[rootCategory].open(); + } + + } + } + + function removeNodeType(nt) { + var paletteNode = getPaletteNode(nt); + var categoryNode = paletteNode.closest(".red-ui-palette-category"); + paletteNode.remove(); + if (categoryNode.find(".red-ui-palette-node").length === 0) { + if (categoryNode.find("i").hasClass("expanded")) { + categoryNode.find(".red-ui-palette-content").slideToggle(); + categoryNode.find("i").toggleClass("expanded"); + } + } + } + + function hideNodeType(nt) { + var paletteNode = getPaletteNode(nt); + paletteNode.hide(); + var categoryNode = paletteNode.closest(".red-ui-palette-category"); + var cl = categoryNode.find(".red-ui-palette-node"); + var c = 0; + for (var i = 0; i < cl.length; i++) { + if ($(cl[i]).css('display') === 'none') { c += 1; } + } + if (c === cl.length) { categoryNode.hide(); } + } + + function showNodeType(nt) { + var paletteNode = getPaletteNode(nt); + var categoryNode = paletteNode.closest(".red-ui-palette-category"); + categoryNode.show(); + paletteNode.show(); + } + + function refreshNodeTypes() { + RED.nodes.eachSubflow(function(sf) { + var paletteNode = getPaletteNode('subflow:'+sf.id); + var portInput = paletteNode.find(".red-ui-palette-port-input"); + var portOutput = paletteNode.find(".red-ui-palette-port-output"); + + var paletteLabel = paletteNode.find(".red-ui-palette-label"); + paletteLabel.attr("class","red-ui-palette-label" + (((!sf._def.align && sf.in.length !== 0 && sf.out.length === 0) || "right" === sf._def.align) ? " red-ui-palette-label-right" : "")); + + var paletteIconContainer = paletteNode.find(".red-ui-palette-icon-container"); + paletteIconContainer.attr("class","red-ui-palette-icon-container" + (((!sf._def.align && sf.in.length !== 0 && sf.out.length === 0) || "right" === sf._def.align) ? " red-ui-palette-icon-container-right" : "")); + + if (portInput.length === 0 && sf.in.length > 0) { + var portIn = document.createElement("div"); + portIn.className = "red-ui-palette-port red-ui-palette-port-input"; + paletteNode.append(portIn); + } else if (portInput.length !== 0 && sf.in.length === 0) { + portInput.remove(); + } + + if (portOutput.length === 0 && sf.out.length > 0) { + var portOut = document.createElement("div"); + portOut.className = "red-ui-palette-port red-ui-palette-port-output"; + paletteNode.append(portOut); + } else if (portOutput.length !== 0 && sf.out.length === 0) { + portOutput.remove(); + } + setLabel(sf.type+":"+sf.id,paletteNode,sf.name,RED.utils.renderMarkdown(sf.info||"")); + setIcon(paletteNode,sf); + + var currentCategory = paletteNode.data('category'); + var newCategory = (sf.category||"subflows"); + if (currentCategory !== newCategory) { + var category = escapeCategory(newCategory); + createCategory(newCategory,category,category,"node-red"); + + var currentCategoryNode = paletteNode.closest(".red-ui-palette-category"); + var newCategoryNode = $("#red-ui-palette-"+category); + newCategoryNode.append(paletteNode); + if (newCategoryNode.find(".red-ui-palette-node").length === 1) { + categoryContainers[category].open(); + } + + paletteNode.data('category',newCategory); + if (currentCategoryNode.find(".red-ui-palette-node").length === 0) { + if (currentCategoryNode.find("i").hasClass("expanded")) { + currentCategoryNode.find(".red-ui-palette-content").slideToggle(); + currentCategoryNode.find("i").toggleClass("expanded"); + } + } + } + + paletteNode.css("backgroundColor", sf.color); + }); + } + + function filterChange(val) { + var re = new RegExp(val.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'),'i'); + $("#red-ui-palette-container .red-ui-palette-node").each(function(i,el) { + var currentLabel = $(el).attr("data-palette-label"); + var type = $(el).attr("data-palette-type"); + if (val === "" || re.test(type) || re.test(currentLabel)) { + $(this).show(); + } else { + $(this).hide(); + } + }); + + for (var category in categoryContainers) { + if (categoryContainers.hasOwnProperty(category)) { + if (categoryContainers[category].container + .find(".red-ui-palette-node") + .filter(function() { return $(this).css('display') !== 'none'}).length === 0) { + categoryContainers[category].close(); + categoryContainers[category].container.slideUp(); + } else { + categoryContainers[category].open(); + categoryContainers[category].container.show(); + } + } + } + } + + function init() { + + $('<img src="red/images/spin.svg" class="red-ui-palette-spinner hide"/>').appendTo("#red-ui-palette"); + $('<div id="red-ui-palette-search" class="red-ui-palette-search hide"><input type="text" data-i18n="[placeholder]palette.filter"></input></div>').appendTo("#red-ui-palette"); + $('<div id="red-ui-palette-container" class="red-ui-palette-scroll hide"></div>').appendTo("#red-ui-palette"); + $('<div class="red-ui-component-footer"></div>').appendTo("#red-ui-palette"); + $('<div id="red-ui-palette-shade" class="hide"></div>').appendTo("#red-ui-palette"); + + + RED.events.on('registry:node-type-added', function(nodeType) { + var def = RED.nodes.getType(nodeType); + addNodeType(nodeType,def); + if (def.onpaletteadd && typeof def.onpaletteadd === "function") { + def.onpaletteadd.call(def); + } + }); + RED.events.on('registry:node-type-removed', function(nodeType) { + removeNodeType(nodeType); + }); + RED.events.on('registry:node-set-enabled', function(nodeSet) { + for (var j=0;j<nodeSet.types.length;j++) { + showNodeType(nodeSet.types[j]); + var def = RED.nodes.getType(nodeSet.types[j]); + if (def && def.onpaletteadd && typeof def.onpaletteadd === "function") { + def.onpaletteadd.call(def); + } + } + }); + RED.events.on('registry:node-set-disabled', function(nodeSet) { + for (var j=0;j<nodeSet.types.length;j++) { + hideNodeType(nodeSet.types[j]); + var def = RED.nodes.getType(nodeSet.types[j]); + if (def && def.onpaletteremove && typeof def.onpaletteremove === "function") { + def.onpaletteremove.call(def); + } + } + }); + RED.events.on('registry:node-set-removed', function(nodeSet) { + if (nodeSet.added) { + for (var j=0;j<nodeSet.types.length;j++) { + removeNodeType(nodeSet.types[j]); + var def = RED.nodes.getType(nodeSet.types[j]); + if (def && def.onpaletteremove && typeof def.onpaletteremove === "function") { + def.onpaletteremove.call(def); + } + } + } + }); + + $("#red-ui-palette > .red-ui-palette-spinner").show(); + + + $("#red-ui-palette-search input").searchBox({ + delay: 100, + change: function() { + filterChange($(this).val()); + } + }) + + sidebarControls = $('<div class="red-ui-sidebar-control-left"><i class="fa fa-chevron-left"></i></div>').appendTo($("#red-ui-palette")); + RED.popover.tooltip(sidebarControls,RED._("keyboard.togglePalette"),"core:toggle-palette"); + + sidebarControls.on("click", function() { + RED.menu.toggleSelected("menu-item-palette"); + }) + $("#red-ui-palette").on("mouseenter", function() { + sidebarControls.toggle("slide", { direction: "left" }, 200); + }) + $("#red-ui-palette").on("mouseleave", function() { + sidebarControls.stop(false,true); + sidebarControls.hide(); + }) + var userCategories = []; + if (RED.settings.paletteCategories) { + userCategories = RED.settings.paletteCategories; + } else if (RED.settings.theme('palette.categories')) { + userCategories = RED.settings.theme('palette.categories'); + } + if (!Array.isArray(userCategories)) { + userCategories = []; + } + + var addedCategories = {}; + userCategories.forEach(function(category){ + addedCategories[category] = true; + createCategoryContainer(category, escapeCategory(category), "palette.label."+escapeCategory(category)); + }); + coreCategories.forEach(function(category){ + if (!addedCategories[category]) { + createCategoryContainer(category, escapeCategory(category), "palette.label."+escapeCategory(category)); + } + }); + + var paletteFooterButtons = $('<span class="button-group"></span>').appendTo("#red-ui-palette .red-ui-component-footer"); + var paletteCollapseAll = $('<button type="button" class="red-ui-footer-button"><i class="fa fa-angle-double-up"></i></button>').appendTo(paletteFooterButtons); + paletteCollapseAll.on("click", function(e) { + e.preventDefault(); + for (var cat in categoryContainers) { + if (categoryContainers.hasOwnProperty(cat)) { + categoryContainers[cat].close(); + } + } + }); + RED.popover.tooltip(paletteCollapseAll,RED._('palette.actions.collapse-all')); + + var paletteExpandAll = $('<button type="button" class="red-ui-footer-button"><i class="fa fa-angle-double-down"></i></button>').appendTo(paletteFooterButtons); + paletteExpandAll.on("click", function(e) { + e.preventDefault(); + for (var cat in categoryContainers) { + if (categoryContainers.hasOwnProperty(cat)) { + categoryContainers[cat].open(); + } + } + }); + RED.popover.tooltip(paletteExpandAll,RED._('palette.actions.expand-all')); + + RED.actions.add("core:toggle-palette", function(state) { + if (state === undefined) { + RED.menu.toggleSelected("menu-item-palette"); + } else { + togglePalette(state); + } + }); + } + function togglePalette(state) { + if (!state) { + $("#red-ui-main-container").addClass("red-ui-palette-closed"); + sidebarControls.hide(); + sidebarControls.find("i").addClass("fa-chevron-right").removeClass("fa-chevron-left"); + } else { + $("#red-ui-main-container").removeClass("red-ui-palette-closed"); + sidebarControls.find("i").removeClass("fa-chevron-right").addClass("fa-chevron-left"); + } + setTimeout(function() { $(window).trigger("resize"); } ,200); + } + + function getCategories() { + var categories = []; + $("#red-ui-palette-container .red-ui-palette-category").each(function(i,d) { + categories.push({id:$(d).data('category'),label:$(d).data('label')}); + }) + return categories; + } + return { + init: init, + add:addNodeType, + remove:removeNodeType, + hide:hideNodeType, + show:showNodeType, + refresh:refreshNodeTypes, + getCategories: getCategories + }; +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js new file mode 100644 index 0000000..f0944c8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js @@ -0,0 +1,1664 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +RED.projects.settings = (function() { + + var trayWidth = 700; + var settingsVisible = false; + + var panes = []; + + function addPane(options) { + panes.push(options); + } + + // TODO: DRY - tab-info.js + function addTargetToExternalLinks(el) { + $(el).find("a").each(function(el) { + var href = $(this).attr('href'); + if (/^https?:/.test(href)) { + $(this).attr('target','_blank'); + } + }); + return el; + } + + function show(initialTab) { + if (settingsVisible) { + return; + } + if (!RED.user.hasPermission("projects.write")) { + RED.notify(RED._("user.errors.notAuthorized"),"error"); + return; + } + + settingsVisible = true; + + var trayOptions = { + title: RED._("sidebar.project.projectSettings.title"), + buttons: [ + { + id: "node-dialog-ok", + text: RED._("common.label.close"), + class: "primary", + click: function() { + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + trayWidth = dimensions.width; + }, + open: function(tray) { + var project = RED.projects.getActiveProject(); + + var trayBody = tray.find('.red-ui-tray-body'); + var settingsContent = $('<div></div>').appendTo(trayBody); + var tabContainer = $('<div></div>',{class:"red-ui-settings-tabs-container"}).appendTo(settingsContent); + + $('<ul></ul>',{id:"user-settings-tabs"}).appendTo(tabContainer); + var settingsTabs = RED.tabs.create({ + id: "user-settings-tabs", + vertical: true, + onchange: function(tab) { + setTimeout(function() { + tabContents.children().hide(); + $("#" + tab.id).show(); + if (tab.pane.focus) { + tab.pane.focus(); + } + },50); + } + }); + var tabContents = $('<div></div>',{class:"red-ui-settings-tabs-content"}).appendTo(settingsContent); + + panes.forEach(function(pane) { + settingsTabs.addTab({ + id: "red-ui-project-settings-tab-"+pane.id, + label: pane.title, + pane: pane + }); + pane.get(project).hide().appendTo(tabContents); + }); + settingsContent.i18n(); + settingsTabs.activateTab("red-ui-project-settings-tab-"+(initialTab||'main')) + $("#red-ui-sidebar-shade").show(); + }, + close: function() { + settingsVisible = false; + panes.forEach(function(pane) { + if (pane.close) { + pane.close(); + } + }); + $("#red-ui-sidebar-shade").hide(); + + }, + show: function() {} + } + if (trayWidth !== null) { + trayOptions.width = trayWidth; + } + RED.tray.show(trayOptions); + } + + function editDescription(activeProject, container) { + RED.editor.editMarkdown({ + title: RED._('sidebar.project.editDescription'), + header: $('<span><i class="fa fa-book"></i> README.md</span>'), + value: activeProject.description, + complete: function(v) { + container.empty(); + var spinner = utils.addSpinnerOverlay(container); + var done = function(err,res) { + if (err) { + return editDescription(activeProject, container); + } + activeProject.description = v; + updateProjectDescription(activeProject, container); + } + utils.sendRequest({ + url: "projects/"+activeProject.name, + type: "PUT", + responses: { + 0: function(error) { + done(error,null); + }, + 200: function(data) { + done(null,data); + RED.sidebar.versionControl.refresh(true); + }, + 400: { + '*': function(error) { + utils.reportUnexpectedError(error); + done(error,null); + } + }, + } + },{description:v}).always(function() { + spinner.remove(); + }); + } + }); + } + function updateProjectDescription(activeProject, container) { + container.empty(); + var desc; + if (activeProject.description) { + desc = RED.utils.renderMarkdown(activeProject.description); + } else { + desc = '<span class="red-ui-help-info-none">' + RED._("sidebar.project.noDescriptionAvailable") + '</span>'; + } + var description = addTargetToExternalLinks($('<span class="red-ui-text-bidi-aware" dir=\"'+RED.text.bidi.resolveBaseTextDir(desc)+'">'+desc+'</span>')).appendTo(container); + description.find(".red-ui-text-bidi-aware").contents().filter(function() { return this.nodeType === 3 && this.textContent.trim() !== "" }).wrap( "<span></span>" ); + } + + function editSummary(activeProject, summary, container) { + var editButton = container.prev(); + editButton.hide(); + container.empty(); + var bg = $('<span class="button-row" style="position: relative; float: right; margin-right:0;"></span>').appendTo(container); + var input = $('<input type="text" style="width: calc(100% - 150px); margin-right: 10px;">').val(summary||"").appendTo(container); + $('<button class="red-ui-button">' + RED._("common.label.cancel") + '</button>') + .appendTo(bg) + .on("click", function(evt) { + evt.preventDefault(); + updateProjectSummary(activeProject.summary, container); + editButton.show(); + }); + $('<button class="red-ui-button">' + RED._("common.label.save") + '</button>') + .appendTo(bg) + .on("click", function(evt) { + evt.preventDefault(); + var v = input.val(); + updateProjectSummary(v, container); + var spinner = utils.addSpinnerOverlay(container); + var done = function(err,res) { + if (err) { + spinner.remove(); + return editSummary(activeProject, summary, container); + } + activeProject.summary = v; + spinner.remove(); + updateProjectSummary(activeProject.summary, container); + editButton.show(); + } + utils.sendRequest({ + url: "projects/"+activeProject.name, + type: "PUT", + responses: { + 0: function(error) { + done(error,null); + }, + 200: function(data) { + RED.sidebar.versionControl.refresh(true); + done(null,data); + }, + 400: { + '*': function(error) { + utils.reportUnexpectedError(error); + done(error,null); + } + }, + } + },{summary:v}); + }); + } + function updateProjectSummary(summary, container) { + container.empty(); + if (summary) { + container.text(summary).removeClass('node-info-node'); + } else { + container.text(RED._("sidebar.project.noSummaryAvailable")).addClass('red-ui-help-info-none'); + } + } + + function createMainPane(activeProject) { + + var pane = $('<div id="red-ui-project-settings-tab-main" class="red-ui-project-settings-tab-pane red-ui-help"></div>'); + $('<h1>').text(activeProject.name).appendTo(pane); + var summary = $('<div style="position: relative">').appendTo(pane); + var summaryContent = $('<div></div>').appendTo(summary); + updateProjectSummary(activeProject.summary, summaryContent); + if (RED.user.hasPermission("projects.write")) { + $('<button class="red-ui-button red-ui-button-small" style="float: right;">' + RED._('sidebar.project.editDescription') + '</button>') + .prependTo(summary) + .on("click", function(evt) { + evt.preventDefault(); + editSummary(activeProject, activeProject.summary, summaryContent); + }); + } + $('<hr>').appendTo(pane); + + var description = $('<div class="red-ui-help" style="position: relative"></div>').appendTo(pane); + var descriptionContent = $('<div>',{style:"min-height: 200px"}).appendTo(description); + + updateProjectDescription(activeProject, descriptionContent); + + if (RED.user.hasPermission("projects.write")) { + $('<button class="red-ui-button red-ui-button-small" style="float: right;">' + RED._('sidebar.project.editReadme') + '</button>') + .prependTo(description) + .on("click", function(evt) { + evt.preventDefault(); + editDescription(activeProject, descriptionContent); + }); + } + return pane; + } + function updateProjectDependencies(activeProject,depsList) { + depsList.editableList('empty'); + + var totalCount = 0; + var unknownCount = 0; + var unusedCount = 0; + var notInstalledCount = 0; + + for (var m in modulesInUse) { + if (modulesInUse.hasOwnProperty(m)) { + depsList.editableList('addItem',{ + id: modulesInUse[m].module, + version: modulesInUse[m].version, + count: modulesInUse[m].count, + known: activeProject.dependencies.hasOwnProperty(m), + installed: true + }); + totalCount++; + if (modulesInUse[m].count === 0) { + unusedCount++; + } + if (!activeProject.dependencies.hasOwnProperty(m)) { + unknownCount++; + } + } + } + + if (activeProject.dependencies) { + for (var m in activeProject.dependencies) { + if (activeProject.dependencies.hasOwnProperty(m) && !modulesInUse.hasOwnProperty(m)) { + var installed = !!RED.nodes.registry.getModule(m); + depsList.editableList('addItem',{ + id: m, + version: activeProject.dependencies[m], //RED.nodes.registry.getModule(module).version, + count: 0, + known: true, + installed: installed + }); + totalCount++; + if (installed) { + unusedCount++; + } else { + notInstalledCount++; + } + } + } + } + // if (notInstalledCount > 0) { + // depsList.editableList('addItem',{index:1, label:"Missing dependencies"}); // TODO: nls + // } + // if (unknownCount > 0) { + // depsList.editableList('addItem',{index:1, label:"Unlisted dependencies"}); // TODO: nls + // } + // if (unusedCount > 0) { + // depsList.editableList('addItem',{index:3, label:"Unused dependencies"}); // TODO: nls + // } + if (totalCount === 0) { + depsList.editableList('addItem',{index:0, label:RED._("sidebar.project.projectSettings.none")}); + } + + } + + function saveDependencies(depsList,container,dependencies,complete) { + var activeProject = RED.projects.getActiveProject(); + var spinner = utils.addSpinnerOverlay(container).addClass('red-ui-component-spinner-contain'); + var done = function(err,res) { + spinner.remove(); + if (err) { + return complete(err); + } + activeProject.dependencies = dependencies; + RED.sidebar.versionControl.refresh(true); + complete(); + } + utils.sendRequest({ + url: "projects/"+activeProject.name, + type: "PUT", + responses: { + 0: function(error) { + done(error,null); + }, + 200: function(data) { + RED.sidebar.versionControl.refresh(true); + done(null,data); + }, + 400: { + '*': function(error) { + done(error,null); + } + }, + } + },{dependencies:dependencies}); + } + function editDependencies(activeProject,depsJSON,container,depsList) { + var json = depsJSON||JSON.stringify(activeProject.dependencies||{},"",4); + if (json === "{}") { + json = "{\n\n}"; + } + RED.editor.editJSON({ + title: RED._('sidebar.project.editDependencies'), + value: json, + requireValid: true, + complete: function(v) { + try { + var parsed = JSON.parse(v); + saveDependencies(depsList,container,parsed,function(err) { + if (err) { + return editDependencies(activeProject,v,container,depsList); + } + activeProject.dependencies = parsed; + updateProjectDependencies(activeProject,depsList); + }); + } catch(err) { + editDependencies(activeProject,v,container,depsList); + } + } + }); + } + + function createDependenciesPane(activeProject) { + var pane = $('<div id="red-ui-project-settings-tab-deps" class="red-ui-project-settings-tab-pane red-ui-help"></div>'); + if (RED.user.hasPermission("projects.write")) { + $('<button class="red-ui-button red-ui-button-small" style="margin-top:10px;float: right;">' + RED._("sidebar.project.projectSettings.edit") + '</button>') + .appendTo(pane) + .on("click", function(evt) { + evt.preventDefault(); + editDependencies(activeProject,null,pane,depsList) + }); + } + var depsList = $("<ol>",{style:"position: absolute;top: 60px;bottom: 20px;left: 20px;right: 20px;"}).appendTo(pane); + depsList.editableList({ + addButton: false, + addItem: function(row,index,entry) { + // console.log(entry); + var headerRow = $('<div>',{class:"red-ui-palette-module-header"}).appendTo(row); + if (entry.label) { + if (entry.index === 0) { + headerRow.addClass("red-ui-search-empty") + } else { + row.parent().addClass("red-ui-palette-module-section"); + } + headerRow.text(entry.label); + // if (RED.user.hasPermission("projects.write")) { + // if (entry.index === 1) { + // var addButton = $('<button class="red-ui-button red-ui-button-small red-ui-palette-module-button">add to project</button>').appendTo(headerRow).on("click", function(evt) { + // evt.preventDefault(); + // var deps = $.extend(true, {}, activeProject.dependencies); + // for (var m in modulesInUse) { + // if (modulesInUse.hasOwnProperty(m) && !modulesInUse[m].known) { + // deps[m] = modulesInUse[m].version; + // } + // } + // editDependencies(activeProject,JSON.stringify(deps,"",4),pane,depsList); + // }); + // } else if (entry.index === 3) { + // var removeButton = $('<button class="red-ui-button red-ui-button-small red-ui-palette-module-button">remove from project</button>').appendTo(headerRow).on("click", function(evt) { + // evt.preventDefault(); + // var deps = $.extend(true, {}, activeProject.dependencies); + // for (var m in activeProject.dependencies) { + // if (activeProject.dependencies.hasOwnProperty(m) && !modulesInUse.hasOwnProperty(m)) { + // delete deps[m]; + // } + // } + // editDependencies(activeProject,JSON.stringify(deps,"",4),pane,depsList); + // }); + // } + // } + } else { + headerRow.addClass("red-ui-palette-module-header"); + if (!entry.installed) { + headerRow.addClass("red-ui-palette-module-not-installed"); + } else if (entry.count === 0) { + headerRow.addClass("red-ui-palette-module-unused"); + } else if (!entry.known) { + headerRow.addClass("red-ui-palette-module-unknown"); + } + + entry.element = headerRow; + var titleRow = $('<div class="red-ui-palette-module-meta red-ui-palette-module-name"></div>').appendTo(headerRow); + var iconClass = "fa-cube"; + if (!entry.installed) { + iconClass = "fa-warning"; + } + var icon = $('<i class="fa '+iconClass+'"></i>').appendTo(titleRow); + entry.icon = icon; + $('<span>').text(entry.id).appendTo(titleRow); + var metaRow = $('<div class="red-ui-palette-module-meta red-ui-palette-module-version"><i class="fa fa-tag"></i></div>').appendTo(headerRow); + var versionSpan = $('<span>').text(entry.version).appendTo(metaRow); + metaRow = $('<div class="red-ui-palette-module-meta"></div>').appendTo(headerRow); + var buttons = $('<div class="red-ui-palette-module-button-group"></div>').appendTo(metaRow); + if (RED.user.hasPermission("projects.write")) { + if (!entry.installed && RED.settings.theme('palette.editable') !== false) { + $('<a href="#" class="red-ui-button red-ui-button-small">' + RED._("sidebar.project.projectSettings.install") + '</a>').appendTo(buttons) + .on("click", function(evt) { + evt.preventDefault(); + RED.palette.editor.install(entry,row,function(err) { + if (!err) { + entry.installed = true; + var spinner = RED.utils.addSpinnerOverlay(row,true); + setTimeout(function() { + depsList.editableList('removeItem',entry); + refreshModuleInUseCounts(); + if (modulesInUse.hasOwnProperty(entry.id)) { + entry.count = modulesInUse[entry.id].count; + } else { + entry.count = 0; + } + depsList.editableList('addItem',entry); + },500); + } + }); + }) + } else if (entry.known && entry.count === 0) { + $('<a href="#" class="red-ui-button red-ui-button-small">' + RED._("sidebar.project.projectSettings.removeFromProject") + '</a>').appendTo(buttons) + .on("click", function(evt) { + evt.preventDefault(); + var deps = $.extend(true, {}, activeProject.dependencies); + delete deps[entry.id]; + saveDependencies(depsList,row,deps,function(err) { + if (!err) { + row.fadeOut(200,function() { + depsList.editableList('removeItem',entry); + }); + } else { + console.log(err); + } + }); + }); + } else if (!entry.known) { + $('<a href="#" class="red-ui-button red-ui-button-small">' + RED._("sidebar.project.projectSettings.addToProject") + '</a>').appendTo(buttons) + .on("click", function(evt) { + evt.preventDefault(); + var deps = $.extend(true, {}, activeProject.dependencies); + deps[entry.id] = modulesInUse[entry.id].version; + saveDependencies(depsList,row,deps,function(err) { + if (!err) { + buttons.remove(); + headerRow.removeClass("red-ui-palette-module-unknown"); + } else { + console.log(err); + } + }); + }); + } + } + } + }, + sort: function(A,B) { + return A.id.localeCompare(B.id); + // if (A.index && B.index) { + // return A.index - B.index; + // } + // var Acategory = A.index?A.index:(A.known?(A.count>0?0:4):2); + // var Bcategory = B.index?B.index:(B.known?(B.count>0?0:4):2); + // if (Acategory === Bcategory) { + // return A.id.localeCompare(B.id); + // } else { + // return Acategory - Bcategory; + // } + } + }); + + updateProjectDependencies(activeProject,depsList); + return pane; + + } + + function showProjectFileListing(row,activeProject,current,selectFilter,done) { + var dialog; + var dialogBody; + var filesList; + var selected; + var container = $('<div class="red-ui-projects-file-listing-container"></div>',{style:"position: relative; min-height: 175px; height: 175px;"}).hide().appendTo(row); + var spinner = utils.addSpinnerOverlay(container); + $.getJSON("projects/"+activeProject.name+"/files",function(result) { + var fileNames = Object.keys(result); + fileNames = fileNames.filter(function(fn) { + return !result[fn].status || !/D/.test(result[fn].status); + }) + var files = {}; + fileNames.sort(); + fileNames.forEach(function(file) { + file.split("/").reduce(function(r,v,i,arr) { if (v) { if (i<arr.length-1) { r[v] = r[v]||{};} else { r[v] = true }return r[v];}},files); + }); + var sortFiles = function(key,value,fullPath) { + var result = { + name: key||"/", + path: fullPath+(fullPath?"/":"")+key, + }; + if (value === true) { + result.type = 'f'; + return result; + } + result.type = 'd'; + result.children = []; + result.path = result.path; + var files = Object.keys(value); + files.forEach(function(file) { + result.children.push(sortFiles(file,value[file],result.path)); + }) + result.children.sort(function(A,B) { + if (A.hasOwnProperty("children") && !B.hasOwnProperty("children")) { + return -1; + } else if (!A.hasOwnProperty("children") && B.hasOwnProperty("children")) { + return 1; + } + return A.name.localeCompare(B.name); + }) + return result; + } + var files = sortFiles("",files,"") + + createFileSubList(container,files.children,current,selectFilter,done,"height: 175px"); + spinner.remove(); + }); + return container; + } + + function createFileSubList(container, files, current, selectFilter, onselect, style) { + style = style || ""; + var list = $('<ol>',{class:"red-ui-projects-dialog-file-list", style:style}).appendTo(container).editableList({ + addButton: false, + scrollOnAdd: false, + addItem: function(row,index,entry) { + var header = $('<div></div>',{class:"red-ui-projects-dialog-file-list-entry"}).appendTo(row); + if (entry.children) { + $('<span class="red-ui-projects-dialog-file-list-entry-folder"><i class="fa fa-angle-right"></i> <i class="fa fa-folder-o"></i></span>').appendTo(header); + if (entry.children.length > 0) { + var children = $('<div></div>',{style:"padding-left: 20px;"}).appendTo(row); + if (current.indexOf(entry.path+"/") === 0) { + header.addClass("expanded"); + } else { + children.hide(); + } + createFileSubList(children,entry.children,current,selectFilter,onselect); + header.addClass("selectable"); + header.on("click", function(e) { + if ($(this).hasClass("expanded")) { + $(this).removeClass("expanded"); + children.slideUp(200); + } else { + $(this).addClass("expanded"); + children.slideDown(200); + } + + }); + + } + } else { + var fileIcon = "fa-file-o"; + var fileClass = ""; + if (/\.json$/i.test(entry.name)) { + fileIcon = "fa-file-code-o" + } else if (/\.md$/i.test(entry.name)) { + fileIcon = "fa-book"; + } else if (/^\.git/i.test(entry.name)) { + fileIcon = "fa-code-fork"; + header.addClass("red-ui-projects-dialog-file-list-entry-file-type-git"); + } + $('<span class="red-ui-projects-dialog-file-list-entry-file"> <i class="fa '+fileIcon+'"></i></span>').appendTo(header); + if (selectFilter(entry)) { + header.addClass("selectable"); + if (entry.path === current) { + header.addClass("selected"); + } + header.on("click", function(e) { + $(".red-ui-projects-dialog-file-list-entry.selected").removeClass("selected"); + $(this).addClass("selected"); + onselect(entry.path,true); + }) + header.on("dblclick", function(e) { + e.preventDefault(); + onselect(entry.path,true); + }) + } else { + header.addClass("unselectable"); + } + } + $('<span class="red-ui-projects-dialog-file-list-entry-name" style=""></span>').text(entry.name).appendTo(header); + } + }); + if (!style) { + list.parent().css("overflow-y",""); + } + files.forEach(function(f) { + list.editableList('addItem',f); + }) + } + + // function editFiles(activeProject, container,flowFile, flowFileLabel) { + // var editButton = container.children().first(); + // editButton.hide(); + // + // var flowFileInput = $('<input id="" type="text" style="width: calc(100% - 300px);">').val(flowFile).insertAfter(flowFileLabel); + // + // var flowFileInputSearch = $('<button class="red-ui-button" style="margin-left: 10px"><i class="fa fa-folder-open-o"></i></button>') + // .insertAfter(flowFileInput) + // .on("click", function(e) { + // showProjectFileListing(activeProject,'Select flow file',flowFileInput.val(),function(result) { + // flowFileInput.val(result); + // checkFiles(); + // }) + // }) + // + // var checkFiles = function() { + // saveButton.toggleClass('disabled',flowFileInput.val()===""); + // saveButton.prop('disabled',flowFileInput.val()===""); + // } + // flowFileInput.on("change keyup paste",checkFiles); + // flowFileLabel.hide(); + // + // var bg = $('<span class="button-group" style="position: relative; float: right; margin-right:0;"></span>').prependTo(container); + // $('<button class="red-ui-button">Cancel</button>') + // .appendTo(bg) + // .on("click", function(evt) { + // evt.preventDefault(); + // + // flowFileLabel.show(); + // flowFileInput.remove(); + // flowFileInputSearch.remove(); + // bg.remove(); + // editButton.show(); + // }); + // var saveButton = $('<button class="red-ui-button">Save</button>') + // .appendTo(bg) + // .on("click", function(evt) { + // evt.preventDefault(); + // var newFlowFile = flowFileInput.val(); + // var newCredsFile = credentialsFileInput.val(); + // var spinner = utils.addSpinnerOverlay(container); + // var done = function(err,res) { + // if (err) { + // spinner.remove(); + // return; + // } + // activeProject.summary = v; + // spinner.remove(); + // flowFileLabel.text(newFlowFile); + // flowFileLabel.show(); + // flowFileInput.remove(); + // flowFileInputSearch.remove(); + // bg.remove(); + // editButton.show(); + // } + // // utils.sendRequest({ + // // url: "projects/"+activeProject.name, + // // type: "PUT", + // // responses: { + // // 0: function(error) { + // // done(error,null); + // // }, + // // 200: function(data) { + // // done(null,data); + // // }, + // // 400: { + // // 'unexpected_error': function(error) { + // // done(error,null); + // // } + // // }, + // // } + // // },{summary:v}); + // }); + // + // + // checkFiles(); + // + // } + + function createFilesSection(activeProject,pane) { + var title = $('<h3></h3>').text(RED._("sidebar.project.projectSettings.files")).appendTo(pane); + var filesContainer = $('<div class="red-ui-settings-section"></div>').appendTo(pane); + if (RED.user.hasPermission("projects.write")) { + var editFilesButton = $('<button type="button" id="red-ui-project-settings-tab-settings-file-edit" class="red-ui-button red-ui-button-small" style="float: right;">' + RED._('sidebar.project.projectSettings.edit') + '</button>') + .appendTo(title) + .on("click", function(evt) { + evt.preventDefault(); + formButtons.show(); + editFilesButton.hide(); + // packageFileLabelText.hide(); + + if (!activeProject.files.package) { + packageFileSubLabel.find(".red-ui-projects-edit-form-sublabel-text").text(RED._("sidebar.project.projectSettings.packageCreate")); + packageFileSubLabel.show(); + } + + packageFileInputSearch.show(); + // packageFileInputCreate.show(); + flowFileLabelText.hide(); + flowFileInput.show(); + flowFileInputSearch.show(); + + flowFileInputResize(); + + // credentialStateLabel.parent().hide(); + credentialStateLabel.addClass("uneditable-input"); + $(".red-ui-settings-row-credentials").show(); + credentialStateLabel.css('height','auto'); + credentialFormRows.hide(); + credentialSecretButtons.show(); + }); + } + var row; + + // Flow files + row = $('<div class="red-ui-settings-row"></div>').appendTo(filesContainer); + $('<label for=""></label>').text(RED._("sidebar.project.projectSettings.package")).appendTo(row); + var packageFileLabel = $('<div class="uneditable-input" style="padding:0">').appendTo(row); + var packageFileLabelText = $('<span style="display:inline-block; padding: 6px">').text(activeProject.files.package||"package.json").appendTo(packageFileLabel); + var packageFileInput = $('<input type="hidden">').val(activeProject.files.package||"package.json").appendTo(packageFileLabel); + + var packageFileInputSearch = $('<button type="button" class="red-ui-button toggle single" style="border-top-right-radius: 4px; border-bottom-right-radius: 4px; width: 36px; height: 34px; position: absolute; top: -1px; right: -1px;"><i class="fa fa-folder-open-o"></i></button>') + .hide() + .appendTo(packageFileLabel) + .on("click", function(e) { + if ($(this).hasClass('selected')) { + $(this).removeClass('selected'); + packageFileLabel.find('.red-ui-projects-file-listing-container').slideUp(200,function() { + $(this).remove(); + packageFileLabel.css('height',''); + }); + packageFileLabel.css('color',''); + } else { + $(this).addClass('selected'); + packageFileLabel.css('color','inherit'); + var fileList = showProjectFileListing(packageFileLabel,activeProject,packageFileInput.val(), + function(entry) { return entry.children || /package\.json$/.test(entry.path); }, + function(result,close) { + if (result) { + packageFileInput.val(result); + packageFileLabelText.text(result); + var rootDir = result.substring(0,result.length - 12); + flowFileLabelPrefixText.text(rootDir); + credFileLabelPrefixText.text(rootDir); + flowFileInputResize(); + packageFileSubLabel.hide(); + } + if (close) { + $(packageFileInputSearch).trigger("click"); + } + checkFiles(); + }); + packageFileLabel.css('height','auto'); + setTimeout(function() { + fileList.slideDown(200); + },50); + + } + }) + RED.popover.tooltip(packageFileInputSearch,RED._("sidebar.project.projectSettings.selectFile")); + var packageFileSubLabel = $('<label style="margin-left: 110px" class="red-ui-projects-edit-form-sublabel"><small><span class="form-warning"><i class="fa fa-warning"></i> <span class="red-ui-projects-edit-form-sublabel-text"></span></small></label>').appendTo(row).hide(); + if (!activeProject.files.package) { + packageFileSubLabel.find(".red-ui-projects-edit-form-sublabel-text").text(RED._("sidebar.project.projectSettings.fileNotExist")); + packageFileSubLabel.show(); + } + + + var projectPackage = activeProject.files.package||"package.json"; + var projectRoot = projectPackage.substring(0,projectPackage.length - 12); + + // Flow files + row = $('<div class="red-ui-settings-row"></div>').appendTo(filesContainer); + $('<label for=""></label>').text(RED._("sidebar.project.projectSettings.flow")).appendTo(row); + var flowFileLabel = $('<div class="uneditable-input" style="padding:0">').appendTo(row); + var flowFileLabelPrefixText = $('<span style="display:inline-block; padding: 6px 0 6px 6px">').text(projectRoot).appendTo(flowFileLabel); + var flowFileName = "flows.json"; + if (activeProject.files.flow) { + if (activeProject.files.flow.indexOf(projectRoot) === 0) { + flowFileName = activeProject.files.flow.substring(projectRoot.length); + } else { + flowFileName = activeProject.files.flow; + } + } + var flowFileLabelText = $('<span style="display:inline-block; padding: 6px 6px 6px 0">').text(flowFileName).appendTo(flowFileLabel); + var flowFileInputResize = function() { + flowFileInput.css({ + "width": "calc(100% - "+(flowFileInputSearch.width() + flowFileLabelPrefixText.width())+"px)" + }); + } + var flowFileInput = $('<input type="text" style="padding-left:1px; margin-top: -2px; margin-bottom: 0;border: none;">').val(flowFileName).hide().appendTo(flowFileLabel); + var flowFileInputSearch = $('<button type="button" class="red-ui-button toggle single" style="border-top-right-radius: 4px; border-bottom-right-radius: 4px; width: 36px; height: 34px; position: absolute; top: -1px; right: -1px;"><i class="fa fa-folder-open-o"></i></button>') + .hide() + .appendTo(flowFileLabel) + .on("click", function(e) { + if ($(this).hasClass('selected')) { + $(this).removeClass('selected'); + flowFileLabel.find('.red-ui-projects-file-listing-container').slideUp(200,function() { + $(this).remove(); + flowFileLabel.css('height',''); + }); + flowFileLabel.css('color',''); + } else { + $(this).addClass('selected'); + flowFileLabel.css('color','inherit'); + var packageFile = packageFileInput.val(); + var packagePrefix = packageFile.substring(0,packageFile.length - 12); + var re = new RegExp("^"+packagePrefix+".*\.json$"); + var fileList = showProjectFileListing(flowFileLabel, + activeProject, + flowFileInput.val(), + function(entry) { return !/package.json$/.test(entry.path) && re.test(entry.path) && !/_cred\.json$/.test(entry.path) }, + function(result,isDblClick) { + if (result) { + flowFileInput.val(result.substring(packagePrefix.length)); + + } + if (isDblClick) { + $(flowFileInputSearch).trigger("click"); + } + checkFiles(); + } + ); + flowFileLabel.css('height','auto'); + setTimeout(function() { + fileList.slideDown(200); + },50); + + } + }) + RED.popover.tooltip(flowFileInputSearch,RED._("sidebar.project.projectSettings.selectFile")); + + row = $('<div class="red-ui-settings-row"></div>').appendTo(filesContainer); + $('<label for=""></label>').text(RED._("sidebar.project.projectSettings.credentials")).appendTo(row); + + var credFileName = "flows_cred.json"; + if (activeProject.files.credentials) { + if (activeProject.files.flow.indexOf(projectRoot) === 0) { + credFileName = activeProject.files.credentials.substring(projectRoot.length); + } else { + credFileName = activeProject.files.credentials; + } + } + + var credFileLabel = $('<div class="uneditable-input" style="padding:0">').appendTo(row); + var credFileLabelPrefixText = $('<span style="display:inline-block;padding: 6px 0 6px 6px">').text(projectRoot).appendTo(credFileLabel); + var credFileLabelText = $('<span style="display:inline-block; padding: 6px 6px 6px 0">').text(credFileName).appendTo(credFileLabel); + + var credFileInput = $('<input type="hidden">').val(credFileName).insertAfter(credFileLabel); + + var checkFiles = function() { + var saveDisabled; + var currentFlowValue = flowFileInput.val(); + var m = /^(.+?)(\.[^.]*)?$/.exec(currentFlowValue); + if (m) { + credFileLabelText.text(m[1]+"_cred"+(m[2]||".json")); + } else if (currentFlowValue === "") { + credFileLabelText.text(""); + } + credFileInput.val(credFileLabelText.text()); + var isFlowInvalid = currentFlowValue==="" || + /\.\./.test(currentFlowValue) || + /\/$/.test(currentFlowValue); + + saveDisabled = isFlowInvalid || credFileLabelText.text()===""; + + if (credentialSecretExistingInput.is(":visible")) { + credentialSecretExistingInput.toggleClass("input-error", credentialSecretExistingInput.val() === ""); + saveDisabled = saveDisabled || credentialSecretExistingInput.val() === ""; + } + if (credentialSecretNewInput.is(":visible")) { + credentialSecretNewInput.toggleClass("input-error", credentialSecretNewInput.val() === ""); + saveDisabled = saveDisabled || credentialSecretNewInput.val() === ""; + } + + + flowFileInput.toggleClass("input-error", isFlowInvalid); + // credFileInput.toggleClass("input-error",credFileInput.text()===""); + saveButton.toggleClass('disabled',saveDisabled); + saveButton.prop('disabled',saveDisabled); + } + flowFileInput.on("change keyup paste",checkFiles); + + + // if (!activeProject.files.package) { + // $('<span class="form-warning"><i class="fa fa-warning"></i> Missing</span>').appendTo(packageFileLabelText); + // } + // if (!activeProject.files.flow) { + // $('<span class="form-warning"><i class="fa fa-warning"></i> Missing</span>').appendTo(flowFileLabelText); + // } + // if (!activeProject.files.credentials) { + // $('<span class="form-warning"><i class="fa fa-warning"></i> Missing</span>').appendTo(credFileLabel); + // } + + + row = $('<div class="red-ui-settings-row"></div>').appendTo(filesContainer); + + $('<label></label>').appendTo(row); + var credentialStateLabel = $('<span><i class="user-settings-credentials-state-icon fa"></i> <span class="user-settings-credentials-state"></span></span>').appendTo(row); + var credentialSecretButtons = $('<span class="button-group" style="margin-left: -72px;">').hide().appendTo(row); + + credentialStateLabel.css('color','#666'); + credentialSecretButtons.css('vertical-align','top'); + var credentialSecretResetButton = $('<button type="button" class="red-ui-button" style="vertical-align: top; width: 36px; margin-bottom: 10px"><i class="fa fa-trash-o"></i></button>') + .appendTo(credentialSecretButtons) + .on("click", function(e) { + e.preventDefault(); + if (!$(this).hasClass('selected')) { + credentialSecretNewInput.val(""); + credentialSecretExistingRow.hide(); + credentialSecretNewRow.show(); + $(this).addClass("selected"); + credentialSecretEditButton.removeClass("selected"); + credentialResetLabel.show(); + credentialResetWarning.show(); + credentialSetLabel.hide(); + credentialChangeLabel.hide(); + + credentialFormRows.show(); + } else { + $(this).removeClass("selected"); + credentialFormRows.hide(); + } + checkFiles(); + }); + RED.popover.tooltip(credentialSecretResetButton,RED._("sidebar.project.projectSettings.resetTheEncryptionKey")); + + var credentialSecretEditButton = $('<button type="button" class="red-ui-button" style="border-top-right-radius: 4px; border-bottom-right-radius: 4px; vertical-align: top; width: 36px; margin-bottom: 10px"><i class="fa fa-pencil"></i></button>') + .appendTo(credentialSecretButtons) + .on("click", function(e) { + e.preventDefault(); + if (!$(this).hasClass('selected')) { + credentialSecretExistingInput.val(""); + credentialSecretNewInput.val(""); + if (activeProject.settings.credentialSecretInvalid || !activeProject.settings.credentialsEncrypted) { + credentialSetLabel.show(); + credentialChangeLabel.hide(); + credentialSecretExistingRow.hide(); + } else { + credentialSecretExistingRow.show(); + credentialSetLabel.hide(); + credentialChangeLabel.show(); + } + credentialSecretNewRow.show(); + credentialSecretEditButton.addClass("selected"); + credentialSecretResetButton.removeClass("selected"); + + credentialResetLabel.hide(); + credentialResetWarning.hide(); + credentialFormRows.show(); + } else { + $(this).removeClass("selected"); + credentialFormRows.hide(); + } + checkFiles(); + }) + + RED.popover.tooltip(credentialSecretEditButton,RED._("sidebar.project.projectSettings.changeTheEncryptionKey")); + + row = $('<div class="red-ui-settings-row red-ui-settings-row-credentials"></div>').hide().appendTo(filesContainer); + + + + var credentialFormRows = $('<div>',{style:"margin-top:10px"}).hide().appendTo(credentialStateLabel); + + var credentialSetLabel = $('<div style="margin: 20px 0 10px 5px;">' + RED._("sidebar.project.projectSettings.setTheEncryptionKey") + '</div>').hide().appendTo(credentialFormRows); + var credentialChangeLabel = $('<div style="margin: 20px 0 10px 5px;">' + RED._("sidebar.project.projectSettings.changeTheEncryptionKey") + '</div>').hide().appendTo(credentialFormRows); + var credentialResetLabel = $('<div style="margin: 20px 0 10px 5px;">' + RED._("sidebar.project.projectSettings.resetTheEncryptionKey") + '</div>').hide().appendTo(credentialFormRows); + + var credentialSecretExistingRow = $('<div class="red-ui-settings-row red-ui-settings-row-credentials"></div>').appendTo(credentialFormRows); + $('<label for=""></label>').text(RED._("sidebar.project.projectSettings.currentKey")).appendTo(credentialSecretExistingRow); + var credentialSecretExistingInput = $('<input type="password">').appendTo(credentialSecretExistingRow) + .on("change keyup paste",function() { + if (popover) { + popover.close(); + popover = null; + } + checkFiles(); + }); + + var credentialSecretNewRow = $('<div class="red-ui-settings-row red-ui-settings-row-credentials"></div>').appendTo(credentialFormRows); + + + $('<label for=""></label>').text(RED._("sidebar.project.projectSettings.newKey")).appendTo(credentialSecretNewRow); + var credentialSecretNewInput = $('<input type="password">').appendTo(credentialSecretNewRow).on("change keyup paste",checkFiles); + + var credentialResetWarning = $('<div class="form-tips form-warning" style="margin: 10px;"><i class="fa fa-warning"></i>' + RED._("sidebar.project.projectSettings.credentialsAlert") + '</div>').hide().appendTo(credentialFormRows); + + + var hideEditForm = function() { + editFilesButton.show(); + formButtons.hide(); + // packageFileLabelText.show(); + packageFileInputSearch.hide(); + // packageFileInputCreate.hide(); + flowFileLabelText.show(); + flowFileInput.hide(); + flowFileInputSearch.hide(); + + // credentialStateLabel.parent().show(); + credentialStateLabel.removeClass("uneditable-input"); + credentialStateLabel.css('height',''); + + flowFileInputSearch.removeClass('selected'); + flowFileLabel.find('.red-ui-projects-file-listing-container').remove(); + flowFileLabel.css('height',''); + flowFileLabel.css('color',''); + + $(".red-ui-settings-row-credentials").hide(); + credentialFormRows.hide(); + credentialSecretButtons.hide(); + credentialSecretResetButton.removeClass("selected"); + credentialSecretEditButton.removeClass("selected"); + + + } + + var formButtons = $('<span class="button-row" style="position: relative; float: right; margin-right:0;"></span>').hide().appendTo(filesContainer); + $('<button type="button" class="red-ui-button">' + RED._("common.label.cancel") + '</button>') + .appendTo(formButtons) + .on("click", function(evt) { + evt.preventDefault(); + var projectPackage = activeProject.files.package||"package.json"; + var projectRoot = projectPackage.substring(0,projectPackage.length - 12); + flowFileLabelPrefixText.text(projectRoot); + credFileLabelPrefixText.text(projectRoot); + packageFileLabelText.text(activeProject.files.package||"package.json"); + if (!activeProject.files.package) { + packageFileSubLabel.find(".red-ui-projects-edit-form-sublabel-text").text(RED._("sidebar.project.projectSettings.fileNotExist")); + packageFileSubLabel.show(); + } else { + packageFileSubLabel.hide(); + } + flowFileInput.val(flowFileLabelText.text()); + credFileLabelText.text(credFileName); + hideEditForm(); + }); + var saveButton = $('<button type="button" class="red-ui-button">' + RED._("common.label.save") + '</button>') + .appendTo(formButtons) + .on("click", function(evt) { + evt.preventDefault(); + var spinner = utils.addSpinnerOverlay(filesContainer); + var done = function(err) { + spinner.remove(); + if (err) { + utils.reportUnexpectedError(err); + return; + } + flowFileLabelText.text(flowFileInput.val()); + credFileLabelText.text(credFileInput.val()); + packageFileSubLabel.hide(); + hideEditForm(); + } + var rootPath = packageFileInput.val(); + rootPath = rootPath.substring(0,rootPath.length-12); + var payload = { + files: { + package: packageFileInput.val(), + flow: rootPath+flowFileInput.val(), + credentials: rootPath+credFileInput.val() + } + } + + if (credentialSecretResetButton.hasClass('selected')) { + payload.resetCredentialSecret = true; + } + if (credentialSecretResetButton.hasClass('selected') || credentialSecretEditButton.hasClass('selected')) { + payload.credentialSecret = credentialSecretNewInput.val(); + if (credentialSecretExistingInput.is(":visible")) { + payload.currentCredentialSecret = credentialSecretExistingInput.val(); + } + } + RED.deploy.setDeployInflight(true); + utils.sendRequest({ + url: "projects/"+activeProject.name, + type: "PUT", + responses: { + 0: function(error) { + done(error); + }, + 200: function(data) { + activeProject = data; + RED.sidebar.versionControl.refresh(true); + updateForm(); + done(); + }, + 400: { + 'credentials_load_failed': function(error) { + done(error); + }, + 'missing_current_credential_key': function(error) { + credentialSecretExistingInput.addClass("input-error"); + popover = RED.popover.create({ + target: credentialSecretExistingInput, + direction: 'right', + size: 'small', + content: "Incorrect key", + autoClose: 3000 + }).open(); + done(error); + }, + '*': function(error) { + done(error); + } + }, + } + },payload).always(function() { + setTimeout(function() { + RED.deploy.setDeployInflight(false); + },500); + }); + }); + var updateForm = function() { + if (activeProject.settings.credentialSecretInvalid) { + credentialStateLabel.find(".user-settings-credentials-state-icon").removeClass().addClass("user-settings-credentials-state-icon fa fa-warning"); + credentialStateLabel.find(".user-settings-credentials-state").text(RED._("sidebar.project.projectSettings.invalidEncryptionKey")); + } else if (activeProject.settings.credentialsEncrypted) { + credentialStateLabel.find(".user-settings-credentials-state-icon").removeClass().addClass("user-settings-credentials-state-icon fa fa-lock"); + credentialStateLabel.find(".user-settings-credentials-state").text(RED._("sidebar.project.projectSettings.encryptionEnabled")); + } else { + credentialStateLabel.find(".user-settings-credentials-state-icon").removeClass().addClass("user-settings-credentials-state-icon fa fa-unlock"); + credentialStateLabel.find(".user-settings-credentials-state").text(RED._("sidebar.project.projectSettings.encryptionDisabled")); + } + credentialSecretResetButton.toggleClass('disabled',!activeProject.settings.credentialSecretInvalid && !activeProject.settings.credentialsEncrypted); + credentialSecretResetButton.prop('disabled',!activeProject.settings.credentialSecretInvalid && !activeProject.settings.credentialsEncrypted); + } + + checkFiles(); + updateForm(); + } + + function createLocalBranchListSection(activeProject,pane) { + var localBranchContainer = $('<div class="red-ui-settings-section"></div>').appendTo(pane); + $('<h4></h4>').text(RED._("sidebar.project.projectSettings.branches")).appendTo(localBranchContainer); + + var row = $('<div class="red-ui-settings-row red-ui-projects-dialog-list"></div>').appendTo(localBranchContainer); + + + var branchList = $('<ol>').appendTo(row).editableList({ + height: 'auto', + addButton: false, + scrollOnAdd: false, + addItem: function(row,index,entry) { + var container = $('<div class="red-ui-projects-dialog-list-entry">').appendTo(row); + if (entry.empty) { + container.addClass('red-ui-search-empty'); + container.text(RED._("sidebar.project.projectSettings.noBranches")); + return; + } + if (entry.current) { + container.addClass("current"); + } + $('<span class="entry-icon"><i class="fa fa-code-fork"></i></span>').appendTo(container); + var content = $('<span>').appendTo(container); + var topRow = $('<div>').appendTo(content); + $('<span class="entry-name">').text(entry.name).appendTo(topRow); + if (entry.commit) { + $('<span class="entry-detail">').text(entry.commit.sha).appendTo(topRow); + } + if (entry.remote) { + var bottomRow = $('<div>').appendTo(content); + + $('<span class="entry-detail entry-remote-name">').text(entry.remote||"").appendTo(bottomRow); + if (entry.status.ahead+entry.status.behind > 0) { + $('<span class="entry-detail">'+ + '<i class="fa fa-long-arrow-up"></i> <span>'+entry.status.ahead+'</span> '+ + '<i class="fa fa-long-arrow-down"></i> <span>'+entry.status.behind+'</span>'+ + '</span>').appendTo(bottomRow); + } + } + + if (!entry.current) { + var tools = $('<span class="entry-tools">').appendTo(container); + $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-trash"></i></button>') + .appendTo(tools) + .on("click", function(e) { + e.preventDefault(); + var spinner = utils.addSpinnerOverlay(row).addClass('red-ui-component-spinner-contain'); + var notification = RED.notify(RED._("sidebar.project.projectSettings.deleteConfirm", { name: entry.name }), { + type: "warning", + modal: true, + fixed: true, + buttons: [ + { + text: RED._("common.label.cancel"), + click: function() { + spinner.remove(); + notification.close(); + } + },{ + text: 'Delete branch', + click: function() { + notification.close(); + var url = "projects/"+activeProject.name+"/branches/"+entry.name; + var options = { + url: url, + type: "DELETE", + responses: { + 200: function(data) { + row.fadeOut(200,function() { + branchList.editableList('removeItem',entry); + spinner.remove(); + }); + }, + 400: { + 'git_delete_branch_unmerged': function(error) { + notification = RED.notify(RED._("sidebar.project.projectSettings.unmergedConfirm", { name: entry.name }), { + type: "warning", + modal: true, + fixed: true, + buttons: [ + { + text: RED._("common.label.cancel"), + click: function() { + spinner.remove(); + notification.close(); + } + },{ + text: RED._("sidebar.project.projectSettings.deleteUnmergedBranch"), + click: function() { + options.url += "?force=true"; + notification.close(); + utils.sendRequest(options); + } + } + ] + }); + }, + '*': function(error) { + utils.reportUnexpectedError(error); + spinner.remove(); + } + }, + } + } + utils.sendRequest(options); + } + } + + ] + }) + }) + } + + } + }); + + $.getJSON("projects/"+activeProject.name+"/branches",function(result) { + if (result.branches) { + if (result.branches.length > 0) { + result.branches.sort(function(A,B) { + if (A.current) { return -1 } + if (B.current) { return 1 } + return A.name.localeCompare(B.name); + }); + result.branches.forEach(function(branch) { + branchList.editableList('addItem',branch); + }) + } else { + branchList.editableList('addItem',{empty:true}); + } + } + }) + } + + function createRemoteRepositorySection(activeProject,pane) { + $('<h3></h3>').text(RED._("sidebar.project.projectSettings.versionControl")).appendTo(pane); + + createLocalBranchListSection(activeProject,pane); + + var repoContainer = $('<div class="red-ui-settings-section"></div>').appendTo(pane); + var title = $('<h4></h4>').text(RED._("sidebar.project.projectSettings.gitRemotes")).appendTo(repoContainer); + + var editRepoButton = $('<button class="red-ui-button red-ui-button-small" style="float: right; margin-right: 10px;">' + RED._("sidebar.project.projectSettings.addRemote") + '</button>') + .appendTo(title) + .on("click", function(evt) { + editRepoButton.attr('disabled',true); + addRemoteDialog.slideDown(200, function() { + addRemoteDialog[0].scrollIntoView(); + if (isEmpty) { + remoteNameInput.val('origin'); + remoteURLInput.trigger("focus"); + } else { + remoteNameInput.trigger("focus"); + } + validateForm(); + }); + }); + + + var emptyItem = { empty: true }; + var isEmpty = true; + var row = $('<div class="red-ui-settings-row"></div>').appendTo(repoContainer); + var addRemoteDialog = $('<div class="red-ui-projects-dialog-list-dialog"></div>').hide().appendTo(row); + row = $('<div class="red-ui-settings-row red-ui-projects-dialog-list"></div>').appendTo(repoContainer); + var remotesList = $('<ol>').appendTo(row); + remotesList.editableList({ + addButton: false, + height: 'auto', + addItem: function(row,index,entry) { + + var container = $('<div class="red-ui-projects-dialog-list-entry">').appendTo(row); + if (entry.empty) { + container.addClass('red-ui-search-empty'); + container.text(RED._("sidebar.project.projectSettings.noRemotes")); + return; + } else { + $('<span class="entry-icon"><i class="fa fa-globe"></i></span>').appendTo(container); + var content = $('<span>').appendTo(container); + $('<div class="entry-name">').text(entry.name).appendTo(content); + if (entry.urls.fetch === entry.urls.push) { + $('<div class="entry-detail">').text(entry.urls.fetch).appendTo(content); + } else { + $('<div class="entry-detail">').text("fetch: "+entry.urls.fetch).appendTo(content); + $('<div class="entry-detail">').text("push: "+entry.urls.push).appendTo(content); + + } + var tools = $('<span class="entry-tools">').appendTo(container); + $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-trash"></i></button>') + .appendTo(tools) + .on("click", function(e) { + e.preventDefault(); + var spinner = utils.addSpinnerOverlay(row).addClass('red-ui-component-spinner-contain'); + var notification = RED.notify(RED._("sidebar.project.projectSettings.deleteRemoteConfrim", { name: entry.name }), { + type: "warning", + modal: true, + fixed: true, + buttons: [ + { + text: RED._("common.label.cancel"), + click: function() { + spinner.remove(); + notification.close(); + } + },{ + text: RED._("sidebar.project.projectSettings.deleteRemote"), + click: function() { + notification.close(); + + if (activeProject.git.branches.remote && activeProject.git.branches.remote.indexOf(entry.name+"/") === 0) { + delete activeProject.git.branches.remote; + } + if (activeProject.git.branches.remoteAlt && activeProject.git.branches.remoteAlt.indexOf(entry.name+"/") === 0) { + delete activeProject.git.branches.remoteAlt; + } + + var url = "projects/"+activeProject.name+"/remotes/"+entry.name; + var options = { + url: url, + type: "DELETE", + responses: { + 200: function(data) { + row.fadeOut(200,function() { + remotesList.editableList('removeItem',entry); + setTimeout(spinner.remove, 100); + if (data.remotes.length === 0) { + delete activeProject.git.remotes; + isEmpty = true; + remotesList.editableList('addItem',emptyItem); + } else { + activeProject.git.remotes = {}; + data.remotes.forEach(function(remote) { + var name = remote.name; + delete remote.name; + activeProject.git.remotes[name] = remote; + }); + } + delete activeProject.git.branches.remoteAlt; + RED.sidebar.versionControl.refresh(); + }); + }, + 400: { + '*': function(error) { + utils.reportUnexpectedError(error); + spinner.remove(); + } + }, + } + } + utils.sendRequest(options); + } + } + + ] + }) + }); + } + + + } + }); + + var validateForm = function() { + var validName = /^[a-zA-Z0-9\-_]+$/.test(remoteNameInput.val()); + var repo = remoteURLInput.val(); + // var validRepo = /^(?:file|git|ssh|https?|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?[\w\.@:\/~_-]+(?:\.git)?(?:\/?|\#[\d\w\.\-_]+?)$/.test(remoteURLInput.val()); + var validRepo = repo.length > 0 && !/\s/.test(repo); + if (/^https?:\/\/[^/]+@/i.test(repo)) { + remoteURLLabel.text(RED._("sidebar.project.projectSettings.urlRule2")); + validRepo = false; + } else { + remoteURLLabel.text(RED._("sidebar.project.projectSettings.urlRule")); + } + saveButton.attr('disabled',(!validName || !validRepo)) + remoteNameInput.toggleClass('input-error',remoteNameInputChanged&&!validName); + remoteURLInput.toggleClass('input-error',remoteURLInputChanged&&!validRepo); + if (popover) { + popover.close(); + popover = null; + } + }; + var popover; + var remoteNameInputChanged = false; + var remoteURLInputChanged = false; + + $('<div class="red-ui-projects-dialog-list-dialog-header">').text(RED._('sidebar.project.projectSettings.addRemote2')).appendTo(addRemoteDialog); + + row = $('<div class="red-ui-settings-row"></div>').appendTo(addRemoteDialog); + $('<label for=""></label>').text(RED._("sidebar.project.projectSettings.remoteName")).appendTo(row); + var remoteNameInput = $('<input type="text">').appendTo(row).on("change keyup paste",function() { + remoteNameInputChanged = true; + validateForm(); + }); + $('<label class="red-ui-projects-edit-form-sublabel"><small>' + RED._("sidebar.project.projectSettings.nameRule") + '</small></label>').appendTo(row).find("small"); + row = $('<div class="red-ui-settings-row"></div>').appendTo(addRemoteDialog); + $('<label for=""></label>').text(RED._("sidebar.project.projectSettings.url")).appendTo(row); + var remoteURLInput = $('<input type="text">').appendTo(row).on("change keyup paste",function() { + remoteURLInputChanged = true; + validateForm() + }); + var remoteURLLabel = $('<label class="red-ui-projects-edit-form-sublabel"><small>' + RED._("sidebar.project.projectSettings.urlRule") +'</small></label>').appendTo(row).find("small"); + + var hideEditForm = function() { + editRepoButton.attr('disabled',false); + addRemoteDialog.hide(); + remoteNameInput.val(""); + remoteURLInput.val(""); + if (popover) { + popover.close(); + popover = null; + } + } + var formButtons = $('<span class="button-row" style="position: relative; float: right; margin: 10px;"></span>') + .appendTo(addRemoteDialog); + $('<button class="red-ui-button">' + RED._("common.label.cancel") + '</button>') + .appendTo(formButtons) + .on("click", function(evt) { + evt.preventDefault(); + hideEditForm(); + }); + var saveButton = $('<button class="red-ui-button">' + RED._("sidebar.project.projectSettings.addRemote2") + '</button>') + .appendTo(formButtons) + .on("click", function(evt) { + evt.preventDefault(); + var spinner = utils.addSpinnerOverlay(addRemoteDialog).addClass('red-ui-component-spinner-contain'); + + var payload = { + name: remoteNameInput.val(), + url: remoteURLInput.val() + } + var done = function(err) { + spinner.remove(); + if (err) { + return; + } + hideEditForm(); + } + // console.log(JSON.stringify(payload,null,4)); + RED.deploy.setDeployInflight(true); + utils.sendRequest({ + url: "projects/"+activeProject.name+"/remotes", + type: "POST", + responses: { + 0: function(error) { + done(error); + }, + 200: function(data) { + activeProject.git.remotes = {}; + data.remotes.forEach(function(remote) { + var name = remote.name; + delete remote.name; + activeProject.git.remotes[name] = remote; + }); + updateForm(); + RED.sidebar.versionControl.refresh(); + done(); + }, + 400: { + 'git_remote_already_exists': function(error) { + popover = RED.popover.create({ + target: remoteNameInput, + direction: 'right', + size: 'small', + content: "Remote already exists", + autoClose: 6000 + }).open(); + remoteNameInput.addClass('input-error'); + done(error); + }, + '*': function(error) { + utils.reportUnexpectedError(error); + done(error); + } + }, + } + },payload); + }); + + var updateForm = function() { + remotesList.editableList('empty'); + var count = 0; + if (activeProject.git.hasOwnProperty('remotes')) { + for (var name in activeProject.git.remotes) { + if (activeProject.git.remotes.hasOwnProperty(name)) { + count++; + remotesList.editableList('addItem',{name:name,urls:activeProject.git.remotes[name]}); + } + } + } + isEmpty = (count === 0); + if (isEmpty) { + remotesList.editableList('addItem',emptyItem); + } + } + updateForm(); + } + + + + function createSettingsPane(activeProject) { + var pane = $('<div id="red-ui-project-settings-tab-settings" class="red-ui-project-settings-tab-pane red-ui-help"></div>'); + createFilesSection(activeProject,pane); + // createLocalRepositorySection(activeProject,pane); + createRemoteRepositorySection(activeProject,pane); + return pane; + } + + function refreshModuleInUseCounts() { + modulesInUse = {}; + RED.nodes.eachNode(_updateModulesInUse); + RED.nodes.eachConfig(_updateModulesInUse); + } + + function _updateModulesInUse(n) { + if (!/^subflow:/.test(n.type)) { + var module = RED.nodes.registry.getNodeSetForType(n.type).module; + if (module !== 'node-red') { + if (!modulesInUse.hasOwnProperty(module)) { + modulesInUse[module] = { + module: module, + version: RED.nodes.registry.getModule(module).version, + count: 0, + known: false + } + } + modulesInUse[module].count++; + } + } + } + + var popover; + var utils; + var modulesInUse = {}; + function init(_utils) { + utils = _utils; + addPane({ + id:'main', + title: RED._("sidebar.project.name"), + get: createMainPane, + close: function() { } + }); + addPane({ + id:'deps', + title: RED._("sidebar.project.dependencies"), + get: createDependenciesPane, + close: function() { } + }); + addPane({ + id:'settings', + title: RED._("sidebar.project.settings"), + get: createSettingsPane, + close: function() { + if (popover) { + popover.close(); + popover = null; + } + } + }); + + RED.events.on('nodes:add', _updateModulesInUse); + RED.events.on('nodes:remove', function(n) { + if (!/^subflow:/.test(n.type)) { + var module = RED.nodes.registry.getNodeSetForType(n.type).module; + if (module !== 'node-red' && modulesInUse.hasOwnProperty(module)) { + modulesInUse[module].count--; + if (modulesInUse[module].count === 0) { + if (!modulesInUse[module].known) { + delete modulesInUse[module]; + } + } + } + } + }) + + + + } + return { + init: init, + show: show, + switchProject: function(name) { + // TODO: not ideal way to trigger this; should there be an editor-wide event? + modulesInUse = {}; + } + }; +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectUserSettings.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectUserSettings.js new file mode 100644 index 0000000..170aace --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectUserSettings.js @@ -0,0 +1,418 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +RED.projects.userSettings = (function() { + + var gitUsernameInput; + var gitEmailInput; + + function createGitUserSection(pane) { + + var currentGitSettings = RED.settings.get('git') || {}; + currentGitSettings.user = currentGitSettings.user || {}; + + var title = $('<h3></h3>').text(RED._("editor:sidebar.project.userSettings.committerDetail")).appendTo(pane); + + var gitconfigContainer = $('<div class="red-ui-settings-section"></div>').appendTo(pane); + $('<div class="red-ui-settings-section-description"></div>').appendTo(gitconfigContainer).text(RED._("editor:sidebar.project.userSettings.committerTip")); + + var row = $('<div class="red-ui-settings-row"></div>').appendTo(gitconfigContainer); + $('<label for="user-settings-gitconfig-username"></label>').text(RED._("editor:sidebar.project.userSettings.userName")).appendTo(row); + gitUsernameInput = $('<input type="text" id="user-settings-gitconfig-username">').appendTo(row); + gitUsernameInput.val(currentGitSettings.user.name||""); + + row = $('<div class="red-ui-settings-row"></div>').appendTo(gitconfigContainer); + $('<label for="user-settings-gitconfig-email"></label>').text(RED._("editor:sidebar.project.userSettings.email")).appendTo(row); + gitEmailInput = $('<input type="text" id="user-settings-gitconfig-email">').appendTo(row); + gitEmailInput.val(currentGitSettings.user.email||""); + } + + + function createSSHKeySection(pane) { + var container = $('<div class="red-ui-settings-section"></div>').appendTo(pane); + var popover; + var title = $('<h3></h3>').text(RED._("editor:sidebar.project.userSettings.sshKeys")).appendTo(container); + var subtitle = $('<div class="red-ui-settings-section-description"></div>').appendTo(container).text(RED._("editor:sidebar.project.userSettings.sshKeysTip")); + + var addKeyButton = $('<button id="user-settings-gitconfig-add-key" class="red-ui-button red-ui-button-small" style="float: right; margin-right: 10px;">'+RED._("editor:sidebar.project.userSettings.add")+'</button>') + .appendTo(subtitle) + .on("click", function(evt) { + addKeyButton.attr('disabled',true); + saveButton.attr('disabled',true); + // bg.children().removeClass("selected"); + // addLocalButton.trigger("click"); + addKeyDialog.slideDown(200); + keyNameInput.trigger("focus"); + }); + + var validateForm = function() { + var valid = /^[a-zA-Z0-9\-_]+$/.test(keyNameInput.val()); + keyNameInput.toggleClass('input-error',keyNameInputChanged&&!valid); + + // var selectedButton = bg.find(".selected"); + // if (selectedButton[0] === addLocalButton[0]) { + // valid = valid && localPublicKeyPathInput.val().length > 0 && localPrivateKeyPathInput.val().length > 0; + // } else if (selectedButton[0] === uploadButton[0]) { + // valid = valid && publicKeyInput.val().length > 0 && privateKeyInput.val().length > 0; + // } else if (selectedButton[0] === generateButton[0]) { + var passphrase = passphraseInput.val(); + var validPassphrase = passphrase.length === 0 || passphrase.length >= 8; + passphraseInput.toggleClass('input-error',!validPassphrase); + if (!validPassphrase) { + passphraseInputSubLabel.text(RED._("editor:sidebar.project.userSettings.passphraseShort")); + } else if (passphrase.length === 0) { + passphraseInputSubLabel.text(RED._("editor:sidebar.project.userSettings.optional")); + } else { + passphraseInputSubLabel.text(""); + } + valid = valid && validPassphrase; + // } + + saveButton.attr('disabled',!valid); + + if (popover) { + popover.close(); + popover = null; + } + }; + + var row = $('<div class="red-ui-settings-row"></div>').appendTo(container); + var addKeyDialog = $('<div class="red-ui-projects-dialog-list-dialog"></div>').hide().appendTo(row); + $('<div class="red-ui-projects-dialog-list-dialog-header">').text(RED._("editor:sidebar.project.userSettings.addSshKey")).appendTo(addKeyDialog); + var addKeyDialogBody = $('<div>').appendTo(addKeyDialog); + + row = $('<div class="red-ui-settings-row"></div>').appendTo(addKeyDialogBody); + $('<div class="red-ui-settings-section-description"></div>').appendTo(row).text(RED._("editor:sidebar.project.userSettings.addSshKeyTip")); + // var bg = $('<div></div>',{class:"button-group", style:"text-align: center"}).appendTo(row); + // var addLocalButton = $('<button class="red-ui-button toggle selected">use local key</button>').appendTo(bg); + // var uploadButton = $('<button class="red-ui-button toggle">upload key</button>').appendTo(bg); + // var generateButton = $('<button class="red-ui-button toggle">generate key</button>').appendTo(bg); + // bg.children().on("click", function(e) { + // e.preventDefault(); + // if ($(this).hasClass("selected")) { + // return; + // } + // bg.children().removeClass("selected"); + // $(this).addClass("selected"); + // if (this === addLocalButton[0]) { + // addLocalKeyPane.show(); + // generateKeyPane.hide(); + // uploadKeyPane.hide(); + // } else if (this === uploadButton[0]) { + // addLocalKeyPane.hide(); + // generateKeyPane.hide(); + // uploadKeyPane.show(); + // } else if (this === generateButton[0]){ + // addLocalKeyPane.hide(); + // generateKeyPane.show(); + // uploadKeyPane.hide(); + // } + // validateForm(); + // }) + + + row = $('<div class="red-ui-settings-row"></div>').appendTo(addKeyDialogBody); + $('<label for=""></label>').text(RED._("editor:sidebar.project.userSettings.name")).appendTo(row); + var keyNameInputChanged = false; + var keyNameInput = $('<input type="text">').appendTo(row).on("change keyup paste",function() { + keyNameInputChanged = true; + validateForm(); + }); + $('<label class="red-ui-projects-edit-form-sublabel"><small>'+RED._("editor:sidebar.project.userSettings.nameRule")+'</small></label>').appendTo(row).find("small"); + + var generateKeyPane = $('<div>').appendTo(addKeyDialogBody); + row = $('<div class="red-ui-settings-row"></div>').appendTo(generateKeyPane); + $('<label for=""></label>').text(RED._("editor:sidebar.project.userSettings.passphrase")).appendTo(row); + var passphraseInput = $('<input type="password">').appendTo(row).on("change keyup paste",validateForm); + var passphraseInputSubLabel = $('<label class="red-ui-projects-edit-form-sublabel"><small>'+RED._("editor:sidebar.project.userSettings.optional")+'</small></label>').appendTo(row).find("small"); + + // var addLocalKeyPane = $('<div>').hide().appendTo(addKeyDialogBody); + // row = $('<div class="red-ui-settings-row"></div>').appendTo(addLocalKeyPane); + // $('<label for=""></label>').text('Public key').appendTo(row); + // var localPublicKeyPathInput = $('<input type="text">').appendTo(row).on("change keyup paste",validateForm); + // $('<label class="red-ui-projects-edit-form-sublabel"><small>Public key file path, for example: ~/.ssh/id_rsa.pub</small></label>').appendTo(row).find("small"); + // row = $('<div class="red-ui-settings-row"></div>').appendTo(addLocalKeyPane); + // $('<label for=""></label>').text('Private key').appendTo(row); + // var localPrivateKeyPathInput = $('<input type="text">').appendTo(row).on("change keyup paste",validateForm); + // $('<label class="red-ui-projects-edit-form-sublabel"><small>Private key file path, for example: ~/.ssh/id_rsa</small></label>').appendTo(row).find("small"); + // + // var uploadKeyPane = $('<div>').hide().appendTo(addKeyDialogBody); + // row = $('<div class="red-ui-settings-row"></div>').appendTo(uploadKeyPane); + // $('<label for=""></label>').text('Public key').appendTo(row); + // var publicKeyInput = $('<textarea>').appendTo(row).on("change keyup paste",validateForm); + // $('<label class="red-ui-projects-edit-form-sublabel"><small>Paste in public key contents, for example: ~/.ssh/id_rsa.pub</small></label>').appendTo(row).find("small"); + // row = $('<div class="red-ui-settings-row"></div>').appendTo(uploadKeyPane); + // $('<label for=""></label>').text('Private key').appendTo(row); + // var privateKeyInput = $('<textarea>').appendTo(row).on("change keyup paste",validateForm); + // $('<label class="red-ui-projects-edit-form-sublabel"><small>Paste in private key contents, for example: ~/.ssh/id_rsa</small></label>').appendTo(row).find("small"); + + + + + var hideEditForm = function() { + addKeyButton.attr('disabled',false); + addKeyDialog.hide(); + + keyNameInput.val(""); + keyNameInputChanged = false; + passphraseInput.val(""); + // localPublicKeyPathInput.val(""); + // localPrivateKeyPathInput.val(""); + // publicKeyInput.val(""); + // privateKeyInput.val(""); + if (popover) { + popover.close(); + popover = null; + } + } + var formButtons = $('<span class="button-row" style="position: relative; float: right; margin: 10px;"></span>').appendTo(addKeyDialog); + $('<button class="red-ui-button">'+RED._("editor:sidebar.project.userSettings.cancel")+'</button>') + .appendTo(formButtons) + .on("click", function(evt) { + evt.preventDefault(); + hideEditForm(); + }); + var saveButton = $('<button class="red-ui-button">'+RED._("editor:sidebar.project.userSettings.generate")+'</button>') + .appendTo(formButtons) + .on("click", function(evt) { + evt.preventDefault(); + var spinner = utils.addSpinnerOverlay(addKeyDialog).addClass('red-ui-component-spinner-contain'); + var payload = { + name: keyNameInput.val() + }; + + // var selectedButton = bg.find(".selected"); + // if (selectedButton[0] === addLocalButton[0]) { + // payload.type = "local"; + // payload.publicKeyPath = localPublicKeyPathInput.val(); + // payload.privateKeyPath = localPrivateKeyPathInput.val(); + // } else if (selectedButton[0] === uploadButton[0]) { + // payload.type = "upload"; + // payload.publicKey = publicKeyInput.val(); + // payload.privateKey = privateKeyInput.val(); + // } else if (selectedButton[0] === generateButton[0]) { + payload.type = "generate"; + payload.comment = gitEmailInput.val(); + payload.password = passphraseInput.val(); + payload.size = 4096; + // } + var done = function(err) { + spinner.remove(); + if (err) { + return; + } + hideEditForm(); + } + // console.log(JSON.stringify(payload,null,4)); + RED.deploy.setDeployInflight(true); + utils.sendRequest({ + url: "settings/user/keys", + type: "POST", + responses: { + 0: function(error) { + done(error); + }, + 200: function(data) { + refreshSSHKeyList(payload.name); + done(); + }, + 400: { + 'unexpected_error': function(error) { + console.log(error); + done(error); + } + }, + } + },payload); + }); + + row = $('<div class="red-ui-settings-row red-ui-projects-dialog-list"></div>').appendTo(container); + var emptyItem = { empty: true }; + var expandKey = function(container,entry) { + var row = $('<div class="red-ui-projects-dialog-ssh-public-key">',{style:"position:relative"}).appendTo(container); + var keyBox = $('<pre>',{style:"min-height: 80px"}).appendTo(row); + var spinner = utils.addSpinnerOverlay(keyBox).addClass('red-ui-component-spinner-contain'); + var options = { + url: 'settings/user/keys/'+entry.name, + type: "GET", + responses: { + 200: function(data) { + keyBox.text(data.publickey); + spinner.remove(); + }, + 400: { + 'unexpected_error': function(error) { + console.log(error); + spinner.remove(); + } + }, + } + } + utils.sendRequest(options); + + var formButtons = $('<span class="button-row" style="position: relative; float: right; margin: 10px;"></span>').appendTo(row); + $('<button class="red-ui-button red-ui-button-small">'+RED._("editor:sidebar.project.userSettings.copyPublicKey")+'</button>') + .appendTo(formButtons) + .on("click", function(evt) { + try { + evt.stopPropagation(); + evt.preventDefault(); + document.getSelection().selectAllChildren(keyBox[0]); + var ret = document.execCommand('copy'); + document.getSelection().empty(); + } catch(err) { + + } + + }); + + return row; + } + var keyList = $('<ol class="red-ui-projects-dialog-ssh-key-list">').appendTo(row).editableList({ + height: 'auto', + addButton: false, + scrollOnAdd: false, + addItem: function(row,index,entry) { + var container = $('<div class="red-ui-projects-dialog-list-entry">').appendTo(row); + if (entry.empty) { + container.addClass('red-ui-search-empty'); + container.text(RED._("editor:sidebar.project.userSettings.noSshKeys")); + return; + } + var topRow = $('<div class="red-ui-projects-dialog-ssh-key-header">').appendTo(container); + $('<span class="entry-icon"><i class="fa fa-key"></i></span>').appendTo(topRow); + $('<span class="entry-name">').text(entry.name).appendTo(topRow); + var tools = $('<span class="button-row entry-tools">').appendTo(topRow); + var expandedRow; + topRow.on("click", function(e) { + if (expandedRow) { + expandedRow.slideUp(200,function() { + expandedRow.remove(); + expandedRow = null; + }) + } else { + expandedRow = expandKey(container,entry); + } + }) + if (!entry.system) { + $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-trash"></i></button>') + .appendTo(tools) + .on("click", function(e) { + e.stopPropagation(); + var spinner = utils.addSpinnerOverlay(row).addClass('red-ui-component-spinner-contain'); + var notification = RED.notify(RED._("editor:sidebar.project.userSettings.deleteConfirm", {name:entry.name}), { + type: 'warning', + modal: true, + fixed: true, + buttons: [ + { + text: RED._("common.label.cancel"), + click: function() { + spinner.remove(); + notification.close(); + } + }, + { + text: RED._("editor:sidebar.project.userSettings.delete"), + click: function() { + notification.close(); + var url = "settings/user/keys/"+entry.name; + var options = { + url: url, + type: "DELETE", + responses: { + 200: function(data) { + row.fadeOut(200,function() { + keyList.editableList('removeItem',entry); + setTimeout(spinner.remove, 100); + if (keyList.editableList('length') === 0) { + keyList.editableList('addItem',emptyItem); + } + }); + }, + 400: { + 'unexpected_error': function(error) { + console.log(error); + spinner.remove(); + } + }, + } + } + utils.sendRequest(options); + } + } + ] + }); + }); + } + if (entry.expand) { + expandedRow = expandKey(container,entry); + } + } + }); + + var refreshSSHKeyList = function(justAdded) { + $.getJSON("settings/user/keys",function(result) { + if (result.keys) { + result.keys.sort(function(A,B) { + return A.name.localeCompare(B.name); + }); + keyList.editableList('empty'); + result.keys.forEach(function(key) { + if (key.name === justAdded) { + key.expand = true; + } + keyList.editableList('addItem',key); + }); + if (keyList.editableList('length') === 0) { + keyList.editableList('addItem',emptyItem); + } + + } + }) + } + refreshSSHKeyList(); + + } + + function createSettingsPane(activeProject) { + var pane = $('<div id="red-ui-settings-tab-gitconfig" class="project-settings-tab-pane red-ui-help"></div>'); + createGitUserSection(pane); + createSSHKeySection(pane); + return pane; + } + + var utils; + function init(_utils) { + utils = _utils; + RED.userSettings.add({ + id:'gitconfig', + title: RED._("editor:sidebar.project.userSettings.gitConfig"), + get: createSettingsPane, + close: function() { + var currentGitSettings = RED.settings.get('git') || {}; + currentGitSettings.user = currentGitSettings.user || {}; + currentGitSettings.user.name = gitUsernameInput.val(); + currentGitSettings.user.email = gitEmailInput.val(); + RED.settings.set('git', currentGitSettings); + } + }); + } + + return { + init: init, + }; +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js new file mode 100644 index 0000000..da54a81 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js @@ -0,0 +1,2409 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.projects = (function() { + + var dialog; + var dialogBody; + + var activeProject; + function reportUnexpectedError(error) { + var notification; + if (error.code === 'git_missing_user') { + notification = RED.notify("<p>"+RED._("projects.errors.no-username-email")+"</p>",{ + fixed: true, + type:'error', + buttons: [ + { + text: RED._("common.label.cancel"), + click: function() { + notification.close(); + } + }, + { + text: RED._("projects.config-git"), + click: function() { + RED.userSettings.show('gitconfig'); + notification.close(); + } + } + ] + }) + } else { + console.log(error); + notification = RED.notify("<p>"+RED._("projects.errors.unexpected")+":</p><p>"+error.message+"</p><small>"+RED._("projects.errors.code")+": "+error.code+"</small>",{ + fixed: true, + modal: true, + type: 'error', + buttons: [ + { + text: RED._("common.label.close"), + click: function() { + notification.close(); + } + } + ] + }) + } + } + var screens = {}; + function initScreens() { + var migrateProjectHeader = $('<div class="red-ui-projects-dialog-screen-start-hero"></div>'); + $('<span><i class="fa fa-files-o fa-2x"></i> &nbsp; &nbsp; <i class="fa fa-long-arrow-right fa-2x"></i> &nbsp; &nbsp; <i class="fa fa-archive fa-2x"></i></span>').appendTo(migrateProjectHeader) + $('<hr>').appendTo(migrateProjectHeader); + + var createProjectOptions = {}; + + screens = { + 'welcome': { + content: function(options) { + + var container = $('<div class="red-ui-projects-dialog-screen-start"></div>'); + + migrateProjectHeader.appendTo(container); + + var body = $('<div class="red-ui-projects-dialog-screen-start-body"></div>').appendTo(container); + $('<p>').text(RED._("projects.welcome.hello")).appendTo(body); + $('<p>').text(RED._("projects.welcome.desc0")).appendTo(body); + $('<p>').text(RED._("projects.welcome.desc1")).appendTo(body); + $('<p>').text(RED._("projects.welcome.desc2")).appendTo(body); + + var row = $('<div style="text-align: center"></div>').appendTo(body); + var createAsEmpty = $('<button data-type="empty" class="red-ui-button red-ui-projects-dialog-screen-create-type"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-asterisk"></i><br/>'+RED._("projects.welcome.create")+'</button>').appendTo(row); + var createAsClone = $('<button data-type="clone" class="red-ui-button red-ui-projects-dialog-screen-create-type"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-git"></i><br/>'+RED._("projects.welcome.clone")+'</button>').appendTo(row); + + createAsEmpty.on("click", function(e) { + e.preventDefault(); + createProjectOptions = { + action: "create" + } + show('git-config'); + }) + + createAsClone.on("click", function(e) { + e.preventDefault(); + createProjectOptions = { + action: "clone" + } + show('git-config'); + }) + + return container; + }, + buttons: [ + { + // id: "red-ui-clipboard-dialog-cancel", + text: RED._("projects.welcome.openExistingProject"), + class: "secondary", + click: function() { + createProjectOptions = { + action: "open" + } + show('git-config'); + } + }, + + { + // id: "red-ui-clipboard-dialog-cancel", + text: RED._("projects.welcome.not-right-now"), + click: function() { + createProjectOptions = {}; + $( this ).dialog( "close" ); + } + } + ] + }, + 'git-config': (function() { + var gitUsernameInput; + var gitEmailInput; + return { + content: function(options) { + var isGlobalConfig = false; + var existingGitSettings = RED.settings.get('git'); + if (existingGitSettings && existingGitSettings.user) { + existingGitSettings = existingGitSettings.user; + } else if (RED.settings.git && RED.settings.git.globalUser) { + isGlobalConfig = true; + existingGitSettings = RED.settings.git.globalUser; + } + + var validateForm = function() { + var name = gitUsernameInput.val().trim(); + var email = gitEmailInput.val().trim(); + var valid = name.length > 0 && email.length > 0; + $("#red-ui-projects-dialog-git-config").prop('disabled',!valid).toggleClass('disabled ui-button-disabled ui-state-disabled',!valid); + + } + + var container = $('<div class="red-ui-projects-dialog-screen-start"></div>'); + migrateProjectHeader.appendTo(container); + var body = $('<div class="red-ui-projects-dialog-screen-start-body"></div>').appendTo(container); + + $('<p>').text(RED._("projects.git-config.setup")).appendTo(body); + $('<p>').text(RED._("projects.git-config.desc0")).appendTo(body); + $('<p>').text(RED._("projects.git-config.desc1")).appendTo(body); + + if (isGlobalConfig) { + $('<p>').text(RED._("projects.git-config.desc2")).appendTo(body); + } + $('<p>').text(RED._("projects.git-config.desc3")).appendTo(body); + + var row = $('<div class="form-row"></div>').appendTo(body); + $('<label for="">'+RED._("projects.git-config.username")+'</label>').appendTo(row); + gitUsernameInput = $('<input type="text">').val((existingGitSettings&&existingGitSettings.name)||"").appendTo(row); + // $('<div style="position:relative;"></div>').text("This does not need to be your real name").appendTo(row); + gitUsernameInput.on("change keyup paste",validateForm); + + row = $('<div class="form-row"></div>').appendTo(body); + $('<label for="">'+RED._("projects.git-config.email")+'</label>').appendTo(row); + gitEmailInput = $('<input type="text">').val((existingGitSettings&&existingGitSettings.email)||"").appendTo(row); + gitEmailInput.on("change keyup paste",validateForm); + // $('<div style="position:relative;"></div>').text("Something something email").appendTo(row); + setTimeout(function() { + gitUsernameInput.trigger("focus"); + validateForm(); + },50); + return container; + }, + buttons: [ + { + // id: "red-ui-clipboard-dialog-cancel", + text: RED._("common.label.back"), + click: function() { + show('welcome'); + } + }, + { + id: "red-ui-projects-dialog-git-config", + text: RED._("common.label.next"), + class: "primary", + click: function() { + var currentGitSettings = RED.settings.get('git') || {}; + currentGitSettings.user = currentGitSettings.user || {}; + currentGitSettings.user.name = gitUsernameInput.val(); + currentGitSettings.user.email = gitEmailInput.val(); + RED.settings.set('git', currentGitSettings); + if (createProjectOptions.action === "create") { + show('project-details'); + } else if (createProjectOptions.action === "clone") { + show('clone-project'); + } else if (createProjectOptions.action === "open") { + show('create',{screen:'open'}) + } + } + } + ] + }; + })(), + 'project-details': (function() { + var projectNameInput; + var projectSummaryInput; + return { + content: function(options) { + var projectList = null; + var projectNameValid; + + var pendingFormValidation = false; + $.getJSON("projects", function(data) { + projectList = {}; + data.projects.forEach(function(p) { + projectList[p] = true; + if (pendingFormValidation) { + pendingFormValidation = false; + validateForm(); + } + }) + }); + var container = $('<div class="red-ui-projects-dialog-screen-start"></div>'); + migrateProjectHeader.appendTo(container); + var body = $('<div class="red-ui-projects-dialog-screen-start-body"></div>').appendTo(container); + + $('<p>').text(RED._("projects.project-details.create")).appendTo(body); + $('<p>').text(RED._("projects.project-details.desc0")).appendTo(body); + $('<p>').text(RED._("projects.project-details.desc1")).appendTo(body); + $('<p>').text(RED._("projects.project-details.desc2")).appendTo(body); + + var validateForm = function() { + var projectName = projectNameInput.val(); + var valid = true; + if (projectNameInputChanged) { + if (projectList === null) { + pendingFormValidation = true; + return; + } + projectNameStatus.empty(); + if (!/^[a-zA-Z0-9\-_]+$/.test(projectName) || projectList[projectName]) { + projectNameInput.addClass("input-error"); + $('<i style="margin-top: 8px;" class="fa fa-exclamation-triangle"></i>').appendTo(projectNameStatus); + projectNameValid = false; + valid = false; + if (projectList[projectName]) { + projectNameSublabel.text(RED._("projects.project-details.already-exists")); + } else { + projectNameSublabel.text(RED._("projects.project-details.must-contain")); + } + } else { + projectNameInput.removeClass("input-error"); + $('<i style="margin-top: 8px;" class="fa fa-check"></i>').appendTo(projectNameStatus); + projectNameSublabel.text(RED._("projects.project-details.must-contain")); + projectNameValid = true; + } + projectNameLastChecked = projectName; + } + valid = projectNameValid; + $("#red-ui-projects-dialog-create-name").prop('disabled',!valid).toggleClass('disabled ui-button-disabled ui-state-disabled',!valid); + } + + var row = $('<div class="form-row"></div>').appendTo(body); + $('<label for="red-ui-projects-dialog-screen-create-project-name">'+RED._("projects.project-details.project-name")+'</label>').appendTo(row); + + var subrow = $('<div style="position:relative;"></div>').appendTo(row); + projectNameInput = $('<input id="red-ui-projects-dialog-screen-create-project-name" type="text"></input>').val(createProjectOptions.name||"").appendTo(subrow); + var projectNameStatus = $('<div class="red-ui-projects-dialog-screen-input-status"></div>').appendTo(subrow); + + var projectNameInputChanged = false; + var projectNameLastChecked = ""; + var projectNameValid; + var checkProjectName; + var autoInsertedName = ""; + + + projectNameInput.on("change keyup paste",function() { + projectNameInputChanged = (projectNameInput.val() !== projectNameLastChecked); + if (checkProjectName) { + clearTimeout(checkProjectName); + } else if (projectNameInputChanged) { + projectNameStatus.empty(); + $('<img src="red/images/spin.svg"/>').appendTo(projectNameStatus); + if (projectNameInput.val() === '') { + validateForm(); + return; + } + } + checkProjectName = setTimeout(function() { + validateForm(); + checkProjectName = null; + },300) + }); + projectNameSublabel = $('<label class="red-ui-projects-edit-form-sublabel"><small>'+RED._("projects.project-details.must-contain")+'</small></label>').appendTo(row).find("small"); + + // Empty Project + row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-empty"></div>').appendTo(body); + $('<label for="red-ui-projects-dialog-screen-create-project-desc">'+RED._("projects.project-details.desc")+'</label>').appendTo(row); + projectSummaryInput = $('<input id="red-ui-projects-dialog-screen-create-project-desc" type="text">').val(createProjectOptions.summary||"").appendTo(row); + $('<label class="red-ui-projects-edit-form-sublabel"><small>'+RED._("projects.project-details.opt")+'</small></label>').appendTo(row); + + setTimeout(function() { + projectNameInput.trigger("focus"); + projectNameInput.trigger("change"); + },50); + return container; + }, + buttons: function(options) { + return [ + { + text: RED._("common.label.back"), + click: function() { + show('git-config'); + } + }, + { + id: "red-ui-projects-dialog-create-name", + disabled: true, + text: RED._("common.label.next"), + class: "primary disabled", + click: function() { + createProjectOptions.name = projectNameInput.val(); + createProjectOptions.summary = projectSummaryInput.val(); + show('default-files', options); + } + } + ] + } + }; + })(), + 'clone-project': (function() { + var projectNameInput; + var projectSummaryInput; + var projectFlowFileInput; + var projectSecretInput; + var projectSecretSelect; + var copyProject; + var projectRepoInput; + var projectCloneSecret; + var emptyProjectCredentialInput; + var projectRepoUserInput; + var projectRepoPasswordInput; + var projectNameSublabel; + var projectRepoSSHKeySelect; + var projectRepoPassphrase; + var projectRepoRemoteName + var projectRepoBranch; + var selectedProject; + + return { + content: function(options) { + var container = $('<div class="red-ui-projects-dialog-screen-start"></div>'); + migrateProjectHeader.appendTo(container); + var body = $('<div class="red-ui-projects-dialog-screen-start-body"></div>').appendTo(container); + $('<p>').text(RED._("projects.clone-project.clone")).appendTo(body); + $('<p>').text(RED._("projects.clone-project.desc0")).appendTo(body); + + var projectList = null; + var pendingFormValidation = false; + $.getJSON("projects", function(data) { + projectList = {}; + data.projects.forEach(function(p) { + projectList[p] = true; + if (pendingFormValidation) { + pendingFormValidation = false; + validateForm(); + } + }) + }); + + + var validateForm = function() { + var projectName = projectNameInput.val(); + var valid = true; + if (projectNameInputChanged) { + if (projectList === null) { + pendingFormValidation = true; + return; + } + projectNameStatus.empty(); + if (!/^[a-zA-Z0-9\-_]+$/.test(projectName) || projectList[projectName]) { + projectNameInput.addClass("input-error"); + $('<i style="margin-top: 8px;" class="fa fa-exclamation-triangle"></i>').appendTo(projectNameStatus); + projectNameValid = false; + valid = false; + if (projectList[projectName]) { + projectNameSublabel.text(RED._("projects.clone-project.already-exists")); + } else { + projectNameSublabel.text(RED._("projects.clone-project.must-contain")); + } + } else { + projectNameInput.removeClass("input-error"); + $('<i style="margin-top: 8px;" class="fa fa-check"></i>').appendTo(projectNameStatus); + projectNameSublabel.text(RED._("projects.clone-project.must-contain")); + projectNameValid = true; + } + projectNameLastChecked = projectName; + } + valid = projectNameValid; + + var repo = projectRepoInput.val(); + + // var validRepo = /^(?:file|git|ssh|https?|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?[\w\.@:\/~_-]+(?:\/?|\#[\d\w\.\-_]+?)$/.test(repo); + var validRepo = repo.length > 0 && !/\s/.test(repo); + if (/^https?:\/\/[^/]+@/i.test(repo)) { + $("#red-ui-projects-dialog-screen-create-project-repo-label small").text(RED._("projects.clone-project.no-info-in-url")); + validRepo = false; + } + if (!validRepo) { + if (projectRepoChanged) { + projectRepoInput.addClass("input-error"); + } + valid = false; + } else { + projectRepoInput.removeClass("input-error"); + } + if (/^https?:\/\//.test(repo)) { + $(".red-ui-projects-dialog-screen-create-row-creds").show(); + $(".red-ui-projects-dialog-screen-create-row-sshkey").hide(); + } else if (/^(?:ssh|[\S]+?@[\S]+?):(?:\/\/)?/.test(repo)) { + $(".red-ui-projects-dialog-screen-create-row-creds").hide(); + $(".red-ui-projects-dialog-screen-create-row-sshkey").show(); + // if ( !getSelectedSSHKey(projectRepoSSHKeySelect) ) { + // valid = false; + // } + } else { + $(".red-ui-projects-dialog-screen-create-row-creds").hide(); + $(".red-ui-projects-dialog-screen-create-row-sshkey").hide(); + } + + $("#red-ui-projects-dialog-clone-project").prop('disabled',!valid).toggleClass('disabled ui-button-disabled ui-state-disabled',!valid); + } + + var row; + + row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-empty red-ui-projects-dialog-screen-create-row-clone"></div>').appendTo(body); + $('<label for="red-ui-projects-dialog-screen-create-project-name">'+RED._("projects.clone-project.project-name")+'</label>').appendTo(row); + + var subrow = $('<div style="position:relative;"></div>').appendTo(row); + projectNameInput = $('<input id="red-ui-projects-dialog-screen-create-project-name" type="text"></input>').appendTo(subrow); + var projectNameStatus = $('<div class="red-ui-projects-dialog-screen-input-status"></div>').appendTo(subrow); + + var projectNameInputChanged = false; + var projectNameLastChecked = ""; + var projectNameValid; + var checkProjectName; + var autoInsertedName = ""; + + + projectNameInput.on("change keyup paste",function() { + projectNameInputChanged = (projectNameInput.val() !== projectNameLastChecked); + if (checkProjectName) { + clearTimeout(checkProjectName); + } else if (projectNameInputChanged) { + projectNameStatus.empty(); + $('<img src="red/images/spin.svg"/>').appendTo(projectNameStatus); + if (projectNameInput.val() === '') { + validateForm(); + return; + } + } + checkProjectName = setTimeout(function() { + validateForm(); + checkProjectName = null; + },300) + }); + projectNameSublabel = $('<label class="red-ui-projects-edit-form-sublabel"><small>'+RED._("projects.clone-project.must-contain")+'</small></label>').appendTo(row).find("small"); + + row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-clone"></div>').appendTo(body); + $('<label for="red-ui-projects-dialog-screen-create-project-repo">'+RED._("projects.clone-project.git-url")+'</label>').appendTo(row); + projectRepoInput = $('<input id="red-ui-projects-dialog-screen-create-project-repo" type="text" placeholder="https://git.example.com/path/my-project.git"></input>').appendTo(row); + $('<label id="red-ui-projects-dialog-screen-create-project-repo-label" class="red-ui-projects-edit-form-sublabel"><small>'+RED._("projects.clone-project.protocols")+'</small></label>').appendTo(row); + var projectRepoChanged = false; + var lastProjectRepo = ""; + projectRepoInput.on("change keyup paste",function() { + projectRepoChanged = true; + var repo = $(this).val(); + if (lastProjectRepo !== repo) { + $("#red-ui-projects-dialog-screen-create-project-repo-label small").text(RED._("projects.clone-project.protocols")); + } + lastProjectRepo = repo; + + var m = /\/([^/]+?)(?:\.git)?$/.exec(repo); + if (m) { + var projectName = projectNameInput.val(); + if (projectName === "" || projectName === autoInsertedName) { + autoInsertedName = m[1]; + projectNameInput.val(autoInsertedName); + projectNameInput.trigger("change"); + } + } + validateForm(); + }); + + var cloneAuthRows = $('<div class="red-ui-projects-dialog-screen-create-row"></div>').appendTo(body); + row = $('<div class="form-row red-ui-projects-dialog-screen-create-row-auth-error"></div>').hide().appendTo(cloneAuthRows); + $('<div><i class="fa fa-warning"></i> '+RED._("projects.clone-project.auth-failed")+'</div>').appendTo(row); + + // Repo credentials - username/password ---------------- + row = $('<div class="hide form-row red-ui-projects-dialog-screen-create-row-creds"></div>').hide().appendTo(cloneAuthRows); + + var subrow = $('<div style="width: calc(50% - 10px); display:inline-block;"></div>').appendTo(row); + $('<label for="red-ui-projects-dialog-screen-create-project-repo-user">'+RED._("projects.clone-project.username")+'</label>').appendTo(subrow); + projectRepoUserInput = $('<input id="red-ui-projects-dialog-screen-create-project-repo-user" type="text"></input>').appendTo(subrow); + + subrow = $('<div style="width: calc(50% - 10px); margin-left: 20px; display:inline-block;"></div>').appendTo(row); + $('<label for="red-ui-projects-dialog-screen-create-project-repo-pass">'+RED._("projects.clone-project.passwd")+'</label>').appendTo(subrow); + projectRepoPasswordInput = $('<input id="red-ui-projects-dialog-screen-create-project-repo-pass" type="password"></input>').appendTo(subrow); + // ----------------------------------------------------- + + // Repo credentials - key/passphrase ------------------- + row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-sshkey"></div>').hide().appendTo(cloneAuthRows); + subrow = $('<div style="width: calc(50% - 10px); display:inline-block;"></div>').appendTo(row); + $('<label for="red-ui-projects-dialog-screen-create-project-repo-passphrase">'+RED._("projects.clone-project.ssh-key")+'</label>').appendTo(subrow); + projectRepoSSHKeySelect = $("<select>",{style:"width: 100%"}).appendTo(subrow); + + $.getJSON("settings/user/keys", function(data) { + var count = 0; + data.keys.forEach(function(key) { + projectRepoSSHKeySelect.append($("<option></option>").val(key.name).text(key.name)); + count++; + }); + if (count === 0) { + projectRepoSSHKeySelect.addClass("input-error"); + projectRepoSSHKeySelect.attr("disabled",true); + sshwarningRow.show(); + } else { + projectRepoSSHKeySelect.removeClass("input-error"); + projectRepoSSHKeySelect.attr("disabled",false); + sshwarningRow.hide(); + } + }); + subrow = $('<div style="width: calc(50% - 10px); margin-left: 20px; display:inline-block;"></div>').appendTo(row); + $('<label for="red-ui-projects-dialog-screen-create-project-repo-passphrase">'+RED._("projects.clone-project.passphrase")+'</label>').appendTo(subrow); + projectRepoPassphrase = $('<input id="red-ui-projects-dialog-screen-create-project-repo-passphrase" type="password"></input>').appendTo(subrow); + + subrow = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-sshkey"></div>').appendTo(cloneAuthRows); + var sshwarningRow = $('<div class="red-ui-projects-dialog-screen-create-row-auth-error-no-keys"></div>').hide().appendTo(subrow); + $('<div class="form-row"><i class="fa fa-warning"></i> '+RED._("projects.clone-project.ssh-key-desc")+'</div>').appendTo(sshwarningRow); + subrow = $('<div style="text-align: center">').appendTo(sshwarningRow); + $('<button class="red-ui-button">'+RED._("projects.clone-project.ssh-key-add")+'</button>').appendTo(subrow).on("click", function(e) { + e.preventDefault(); + dialog.dialog( "close" ); + RED.userSettings.show('gitconfig'); + setTimeout(function() { + $("#user-settings-gitconfig-add-key").trigger("click"); + },500); + }); + // ----------------------------------------------------- + + + // Secret - clone + row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-clone"></div>').appendTo(body); + $('<label>'+RED._("projects.clone-project.credential-key")+'</label>').appendTo(row); + projectSecretInput = $('<input type="password"></input>').appendTo(row); + + + + return container; + }, + buttons: function(options) { + return [ + { + text: RED._("common.label.back"), + click: function() { + show('git-config'); + } + }, + { + id: "red-ui-projects-dialog-clone-project", + disabled: true, + text: RED._("common.label.clone"), + class: "primary disabled", + click: function() { + var projectType = $(".red-ui-projects-dialog-screen-create-type.selected").data('type'); + var projectData = { + name: projectNameInput.val(), + } + projectData.credentialSecret = projectSecretInput.val(); + var repoUrl = projectRepoInput.val(); + var metaData = {}; + if (/^(?:ssh|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?/.test(repoUrl)) { + var selected = projectRepoSSHKeySelect.val();//false;//getSelectedSSHKey(projectRepoSSHKeySelect); + if ( selected ) { + projectData.git = { + remotes: { + 'origin': { + url: repoUrl, + keyFile: selected, + passphrase: projectRepoPassphrase.val() + } + } + }; + } + else { + console.log(RED._("projects.clone-project.cant-get-ssh-key")); + return; + } + } + else { + projectData.git = { + remotes: { + 'origin': { + url: repoUrl, + username: projectRepoUserInput.val(), + password: projectRepoPasswordInput.val() + } + } + }; + } + + $(".red-ui-projects-dialog-screen-create-row-auth-error").hide(); + $("#red-ui-projects-dialog-screen-create-project-repo-label small").text(RED._("projects.clone-project.protocols")); + + projectRepoUserInput.removeClass("input-error"); + projectRepoPasswordInput.removeClass("input-error"); + projectRepoSSHKeySelect.removeClass("input-error"); + projectRepoPassphrase.removeClass("input-error"); + + RED.deploy.setDeployInflight(true); + RED.projects.settings.switchProject(projectData.name); + + sendRequest({ + url: "projects", + type: "POST", + handleAuthFail: false, + responses: { + 200: function(data) { + dialog.dialog( "close" ); + }, + 400: { + 'project_exists': function(error) { + console.log(RED._("projects.clone-project.already-exists2")); + }, + 'git_error': function(error) { + console.log(RED._("projects.clone-project.git-error"),error); + }, + 'git_connection_failed': function(error) { + projectRepoInput.addClass("input-error"); + $("#red-ui-projects-dialog-screen-create-project-repo-label small").text(RED._("projects.clone-project.connection-failed")); + }, + 'git_not_a_repository': function(error) { + projectRepoInput.addClass("input-error"); + $("#red-ui-projects-dialog-screen-create-project-repo-label small").text(RED._("projects.clone-project.not-git-repo")); + }, + 'git_repository_not_found': function(error) { + projectRepoInput.addClass("input-error"); + $("#red-ui-projects-dialog-screen-create-project-repo-label small").text(RED._("projects.clone-project.repo-not-found")); + }, + 'git_auth_failed': function(error) { + $(".red-ui-projects-dialog-screen-create-row-auth-error").show(); + + projectRepoUserInput.addClass("input-error"); + projectRepoPasswordInput.addClass("input-error"); + // getRepoAuthDetails(req); + projectRepoSSHKeySelect.addClass("input-error"); + projectRepoPassphrase.addClass("input-error"); + }, + 'missing_flow_file': function(error) { + // This is handled via a runtime notification. + dialog.dialog("close"); + }, + 'missing_package_file': function(error) { + // This is handled via a runtime notification. + dialog.dialog("close"); + }, + 'project_empty': function(error) { + // This is handled via a runtime notification. + dialog.dialog("close"); + }, + 'credentials_load_failed': function(error) { + // This is handled via a runtime notification. + dialog.dialog("close"); + }, + '*': function(error) { + reportUnexpectedError(error); + $( dialog ).dialog( "close" ); + } + } + } + },projectData).then(function() { + RED.events.emit("project:change", {name:name}); + }).always(function() { + setTimeout(function() { + RED.deploy.setDeployInflight(false); + },500); + }) + + } + } + ] + } + } + })(), + 'default-files': (function() { + var projectFlowFileInput; + var projectCredentialFileInput; + return { + content: function(options) { + var container = $('<div class="red-ui-projects-dialog-screen-start"></div>'); + migrateProjectHeader.appendTo(container); + var body = $('<div class="red-ui-projects-dialog-screen-start-body"></div>').appendTo(container); + + $('<p>').text(RED._("projects.default-files.create")).appendTo(body); + $('<p>').text(RED._("projects.default-files.desc0")).appendTo(body); + $('<p>').text(RED._("projects.default-files.desc1")).appendTo(body); + if (!options.existingProject && RED.settings.files) { + $('<p>').text(RED._("projects.default-files.desc2")).appendTo(body); + } + + var validateForm = function() { + var valid = true; + var flowFile = projectFlowFileInput.val(); + if (flowFile === "" || !/\.json$/.test(flowFile)) { + valid = false; + if (!projectFlowFileInput.hasClass("input-error")) { + projectFlowFileInput.addClass("input-error"); + projectFlowFileInput.next().empty().append('<i style="margin-top: 8px;" class="fa fa-exclamation-triangle"></i>'); + } + projectCredentialFileInput.text(""); + if (!projectCredentialFileInput.hasClass("input-error")) { + projectCredentialFileInput.addClass("input-error"); + projectCredentialFileInput.next().empty().append('<i style="margin-top: 8px;" class="fa fa-exclamation-triangle"></i>'); + } + } else { + if (projectFlowFileInput.hasClass("input-error")) { + projectFlowFileInput.removeClass("input-error"); + projectFlowFileInput.next().empty(); + } + if (projectCredentialFileInput.hasClass("input-error")) { + projectCredentialFileInput.removeClass("input-error"); + projectCredentialFileInput.next().empty(); + } + projectCredentialFileInput.text(flowFile.substring(0,flowFile.length-5)+"_cred.json"); + } + $("#red-ui-projects-dialog-create-default-files").prop('disabled',!valid).toggleClass('disabled ui-button-disabled ui-state-disabled',!valid); + } + var row = $('<div class="form-row"></div>').appendTo(body); + $('<label for="red-ui-projects-dialog-screen-create-project-file">'+RED._("projects.default-files.flow-file")+'</label>').appendTo(row); + var subrow = $('<div style="position:relative;"></div>').appendTo(row); + var defaultFlowFile = (createProjectOptions.files &&createProjectOptions.files.flow) || (RED.settings.files && RED.settings.files.flow)||"flow.json"; + projectFlowFileInput = $('<input id="red-ui-projects-dialog-screen-create-project-file" type="text">').val(defaultFlowFile) + .on("change keyup paste",validateForm) + .appendTo(subrow); + $('<div class="red-ui-projects-dialog-screen-input-status"></div>').appendTo(subrow); + $('<label class="red-ui-projects-edit-form-sublabel"><small>*.json</small></label>').appendTo(row); + + var defaultCredentialsFile = (createProjectOptions.files &&createProjectOptions.files.credentials) || (RED.settings.files && RED.settings.files.credentials)||"flow_cred.json"; + row = $('<div class="form-row"></div>').appendTo(body); + $('<label for="red-ui-projects-dialog-screen-create-project-credfile">'+RED._("projects.default-files.credentials-file")+'</label>').appendTo(row); + subrow = $('<div style="position:relative;"></div>').appendTo(row); + projectCredentialFileInput = $('<div style="width: 100%" class="uneditable-input" id="red-ui-projects-dialog-screen-create-project-credentials">').text(defaultCredentialsFile) + .appendTo(subrow); + $('<div class="red-ui-projects-dialog-screen-input-status"></div>').appendTo(subrow); + + setTimeout(function() { + projectFlowFileInput.trigger("focus"); + validateForm(); + },50); + + return container; + }, + buttons: function(options) { + return [ + { + // id: "red-ui-clipboard-dialog-cancel", + text: RED._(options.existingProject ? "common.label.cancel": "common.label.back"), + click: function() { + if (options.existingProject) { + $(this).dialog('close'); + } else { + show('project-details',options); + } + } + }, + { + id: "red-ui-projects-dialog-create-default-files", + text: RED._("common.label.next"), + class: "primary", + click: function() { + createProjectOptions.files = { + flow: projectFlowFileInput.val(), + credentials: projectCredentialFileInput.text() + } + if (!options.existingProject) { + createProjectOptions.migrateFiles = true; + } + show('encryption-config',options); + } + } + ] + } + } + })(), + 'encryption-config': (function() { + var emptyProjectCredentialInput; + return { + content: function(options) { + + var container = $('<div class="red-ui-projects-dialog-screen-start"></div>'); + migrateProjectHeader.appendTo(container); + var body = $('<div class="red-ui-projects-dialog-screen-start-body"></div>').appendTo(container); + + $('<p>').text(RED._("projects.encryption-config.setup")).appendTo(body); + if (options.existingProject) { + $('<p>').text(RED._("projects.encryption-config.desc0")).appendTo(body); + $('<p>').text(RED._("projects.encryption-config.desc1")).appendTo(body); + } else { + if (RED.settings.flowEncryptionType === 'disabled') { + $('<p>').text(RED._("projects.encryption-config.desc2")).appendTo(body); + $('<p>').text(RED._("projects.encryption-config.desc3")).appendTo(body); + $('<p>').text(RED._("projects.encryption-config.desc4")).appendTo(body); + } else { + if (RED.settings.flowEncryptionType === 'user') { + $('<p>').text(RED._("projects.encryption-config.desc5")).appendTo(body); + } else if (RED.settings.flowEncryptionType === 'system') { + $('<p>').text(RED._("projects.encryption-config.desc6")).appendTo(body); + } + $('<p>').text(RED._("projects.encryption-config.desc7")).appendTo(body); + } + } + + // var row = $('<div class="form-row"></div>').appendTo(body); + // $('<label for="">Username</label>').appendTo(row); + // var gitUsernameInput = $('<input type="text">').val(currentGitSettings.user.name||"").appendTo(row); + // // $('<div style="position:relative;"></div>').text("This does not need to be your real name").appendTo(row); + // + // row = $('<div class="form-row"></div>').appendTo(body); + // $('<label for="">Email</label>').appendTo(row); + // var gitEmailInput = $('<input type="text">').val(currentGitSettings.user.email||"").appendTo(row); + // // $('<div style="position:relative;"></div>').text("Something something email").appendTo(row); + + var validateForm = function() { + var valid = true; + var encryptionState = $("input[name=projects-encryption-type]:checked").val(); + if (encryptionState === 'enabled') { + var encryptionKeyType = $("input[name=projects-encryption-key]:checked").val(); + if (encryptionKeyType === 'custom') { + valid = valid && emptyProjectCredentialInput.val()!==''; + } + } + $("#red-ui-projects-dialog-create-encryption").prop('disabled',!valid).toggleClass('disabled ui-button-disabled ui-state-disabled',!valid); + } + + + var row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-empty"></div>').appendTo(body); + $('<label>'+RED._("projects.encryption-config.credentials")+'</label>').appendTo(row); + + var credentialsBox = $('<div class="red-ui-projects-dialog-credentials-box">').appendTo(row); + var credentialsRightBox = $('<div class="red-ui-projects-dialog-credentials-box-right">').appendTo(credentialsBox); + var credentialsLeftBox = $('<div class="red-ui-projects-dialog-credentials-box-left">').appendTo(credentialsBox); + + var credentialsEnabledBox = $('<div class="form-row red-ui-projects-dialog-credentials-box-enabled"></div>').appendTo(credentialsLeftBox); + $('<label class="red-ui-projects-edit-form-inline-label"><input type="radio" name="projects-encryption-type" value="enabled"> <i class="fa fa-lock"></i> <span>'+RED._("projects.encryption-config.enable")+'</span></label>').appendTo(credentialsEnabledBox); + var credentialsDisabledBox = $('<div class="form-row red-ui-projects-dialog-credentials-box-disabled"></div>').appendTo(credentialsLeftBox); + $('<label class="red-ui-projects-edit-form-inline-label"><input type="radio" name="projects-encryption-type" value="disabled"> <i class="fa fa-unlock"></i> <span>'+RED._("projects.encryption-config.disable")+'</span></label>').appendTo(credentialsDisabledBox); + + credentialsLeftBox.find("input[name=projects-encryption-type]").on("click", function(e) { + var val = $(this).val(); + var toEnable; + var toDisable; + if (val === 'enabled') { + toEnable = credentialsEnabledBox; + toDisable = credentialsDisabledBox; + $(".projects-encryption-enabled-row").show(); + $(".projects-encryption-disabled-row").hide(); + if ($("input[name=projects-encryption-key]:checked").val() === 'custom') { + emptyProjectCredentialInput.trigger("focus"); + } + + } else { + toDisable = credentialsEnabledBox; + toEnable = credentialsDisabledBox; + $(".projects-encryption-enabled-row").hide(); + $(".projects-encryption-disabled-row").show(); + } + + toEnable.removeClass("disabled"); + toDisable.addClass("disabled"); + validateForm(); + }) + + row = $('<div class="form-row projects-encryption-enabled-row"></div>').appendTo(credentialsRightBox); + $('<label class="red-ui-projects-edit-form-inline-label '+((RED.settings.flowEncryptionType !== 'user')?'disabled':'')+'" style="margin-left: 5px"><input '+((RED.settings.flowEncryptionType !== 'user')?RED._("projects.encryption-config.disabled"):'')+' type="radio" style="vertical-align: middle; margin-top:0; margin-right: 10px;" value="default" name="projects-encryption-key"> <span style="vertical-align: middle;">'+RED._("projects.encryption-config.copy")+'</span></label>').appendTo(row); + row = $('<div class="form-row projects-encryption-enabled-row"></div>').appendTo(credentialsRightBox); + $('<label class="red-ui-projects-edit-form-inline-label" style="margin-left: 5px"><input type="radio" style="vertical-align: middle; margin-top:0; margin-right: 10px;" value="custom" name="projects-encryption-key"> <span style="vertical-align: middle;">'+RED._("projects.encryption-config.use-custom")+'</span></label>').appendTo(row); + row = $('<div class="projects-encryption-enabled-row"></div>').appendTo(credentialsRightBox); + emptyProjectCredentialInput = $('<input disabled type="password" style="margin-left: 25px; width: calc(100% - 30px);"></input>').appendTo(row); + emptyProjectCredentialInput.on("change keyup paste", validateForm); + + row = $('<div class="form-row projects-encryption-disabled-row"></div>').hide().appendTo(credentialsRightBox); + $('<div class="" style="padding: 5px 20px;"><i class="fa fa-warning"></i> '+RED._("projects.encryption-config.desc8")+'</div>').appendTo(row); + + credentialsRightBox.find("input[name=projects-encryption-key]").on("click", function() { + var val = $(this).val(); + emptyProjectCredentialInput.attr("disabled",val === 'default'); + if (val === "custom") { + emptyProjectCredentialInput.trigger("focus"); + } + validateForm(); + }); + + setTimeout(function() { + credentialsLeftBox.find("input[name=projects-encryption-type][value=enabled]").trigger("click"); + if (RED.settings.flowEncryptionType !== 'user') { + credentialsRightBox.find("input[name=projects-encryption-key][value=custom]").trigger("click"); + } else { + credentialsRightBox.find("input[name=projects-encryption-key][value=default]").trigger("click"); + } + validateForm(); + },100); + + return container; + }, + buttons: function(options) { + return [ + { + // id: "red-ui-clipboard-dialog-cancel", + text: RED._("common.label.back"), + click: function() { + show('default-files',options); + } + }, + { + id: "red-ui-projects-dialog-create-encryption", + text: RED._(options.existingProject?"projects.encryption-config.create-project-files":"projects.encryption-config.create-project"), + class: "primary disabled", + disabled: true, + click: function() { + var encryptionState = $("input[name=projects-encryption-type]:checked").val(); + if (encryptionState === 'enabled') { + var encryptionKeyType = $("input[name=projects-encryption-key]:checked").val(); + if (encryptionKeyType === 'custom') { + createProjectOptions.credentialSecret = emptyProjectCredentialInput.val(); + } else { + // If 'use existing', leave createProjectOptions.credentialSecret blank + // - that will trigger it to use the existing key + // TODO: this option should be disabled if encryption is disabled + } + } else { + // Disabled encryption by explicitly setting credSec to false + createProjectOptions.credentialSecret = false; + } + RED.deploy.setDeployInflight(true); + RED.projects.settings.switchProject(createProjectOptions.name); + + var method = "POST"; + var url = "projects"; + + if (options.existingProject) { + createProjectOptions.initialise = true; + method = "PUT"; + url = "projects/"+activeProject.name; + } + var self = this; + sendRequest({ + url: url, + type: method, + requireCleanWorkspace: true, + handleAuthFail: false, + responses: { + 200: function(data) { + createProjectOptions = {}; + if (options.existingProject) { + $( self ).dialog( "close" ); + } else { + show('create-success'); + RED.menu.setDisabled('menu-item-projects-open',false); + RED.menu.setDisabled('menu-item-projects-settings',false); + } + }, + 400: { + 'project_exists': function(error) { + console.log(RED._("projects.encryption-config.already-exists")); + }, + 'git_error': function(error) { + console.log(RED._("projects.encryption-config.git-error"),error); + }, + 'git_connection_failed': function(error) { + projectRepoInput.addClass("input-error"); + }, + 'git_auth_failed': function(error) { + projectRepoUserInput.addClass("input-error"); + projectRepoPasswordInput.addClass("input-error"); + // getRepoAuthDetails(req); + console.log(RED._("projects.encryption-config.git-auth-error"),error); + }, + '*': function(error) { + reportUnexpectedError(error); + $( dialog ).dialog( "close" ); + } + } + } + },createProjectOptions).always(function() { + setTimeout(function() { + RED.deploy.setDeployInflight(false); + },500); + }) + } + } + ]; + } + } + })(), + 'create-success': { + content: function(options) { + + var container = $('<div class="red-ui-projects-dialog-screen-start"></div>'); + migrateProjectHeader.appendTo(container); + var body = $('<div class="red-ui-projects-dialog-screen-start-body"></div>').appendTo(container); + + $('<p>').text(RED._("projects.create-success.success")).appendTo(body); + $('<p>').text(RED._("projects.create-success.desc0")).appendTo(body); + $('<p>').text(RED._("projects.create-success.desc1")).appendTo(body); + $('<p>').text(RED._("projects.create-success.desc2")).appendTo(body); + + return container; + }, + buttons: [ + { + text: RED._("common.label.done"), + click: function() { + $( this ).dialog( "close" ); + } + } + ] + }, + 'create': (function() { + var projectNameInput; + var projectSummaryInput; + var projectFlowFileInput; + var projectSecretInput; + var projectSecretSelect; + var copyProject; + var projectRepoInput; + var projectCloneSecret; + var emptyProjectCredentialInput; + var projectRepoUserInput; + var projectRepoPasswordInput; + var projectNameSublabel; + var projectRepoSSHKeySelect; + var projectRepoPassphrase; + var projectRepoRemoteName + var projectRepoBranch; + var selectedProject; + + return { + title: RED._("projects.create.projects"), + content: function(options) { + var projectList = null; + selectedProject = null; + var pendingFormValidation = false; + $.getJSON("projects", function(data) { + projectList = {}; + data.projects.forEach(function(p) { + projectList[p] = true; + if (pendingFormValidation) { + pendingFormValidation = false; + validateForm(); + } + }) + }); + + var container = $('<div class="red-ui-projects-dialog-screen-create"></div>'); + var row; + + var validateForm = function() { + var projectName = projectNameInput.val(); + var valid = true; + if (projectNameInputChanged) { + if (projectList === null) { + pendingFormValidation = true; + return; + } + projectNameStatus.empty(); + if (!/^[a-zA-Z0-9\-_]+$/.test(projectName) || projectList[projectName]) { + projectNameInput.addClass("input-error"); + $('<i style="margin-top: 8px;" class="fa fa-exclamation-triangle"></i>').appendTo(projectNameStatus); + projectNameValid = false; + valid = false; + if (projectList[projectName]) { + projectNameSublabel.text(RED._("projects.create.already-exists")); + } else { + projectNameSublabel.text(RED._("projects.create.must-contain")); + } + } else { + projectNameInput.removeClass("input-error"); + $('<i style="margin-top: 8px;" class="fa fa-check"></i>').appendTo(projectNameStatus); + projectNameSublabel.text(RED._("projects.create.must-contain")); + projectNameValid = true; + } + projectNameLastChecked = projectName; + } + valid = projectNameValid; + + var projectType = $(".red-ui-projects-dialog-screen-create-type.selected").data('type'); + if (projectType === 'copy') { + if (!copyProject) { + valid = false; + } + } else if (projectType === 'clone') { + var repo = projectRepoInput.val(); + + // var validRepo = /^(?:file|git|ssh|https?|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?[\w\.@:\/~_-]+(?:\/?|\#[\d\w\.\-_]+?)$/.test(repo); + var validRepo = repo.length > 0 && !/\s/.test(repo); + if (/^https?:\/\/[^/]+@/i.test(repo)) { + $("#red-ui-projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.no-info-in-url")); + validRepo = false; + } + if (!validRepo) { + if (projectRepoChanged) { + projectRepoInput.addClass("input-error"); + } + valid = false; + } else { + projectRepoInput.removeClass("input-error"); + } + if (/^https?:\/\//.test(repo)) { + $(".red-ui-projects-dialog-screen-create-row-creds").show(); + $(".red-ui-projects-dialog-screen-create-row-sshkey").hide(); + } else if (/^(?:ssh|[\S]+?@[\S]+?):(?:\/\/)?/.test(repo)) { + $(".red-ui-projects-dialog-screen-create-row-creds").hide(); + $(".red-ui-projects-dialog-screen-create-row-sshkey").show(); + // if ( !getSelectedSSHKey(projectRepoSSHKeySelect) ) { + // valid = false; + // } + } else { + $(".red-ui-projects-dialog-screen-create-row-creds").hide(); + $(".red-ui-projects-dialog-screen-create-row-sshkey").hide(); + } + + + } else if (projectType === 'empty') { + var flowFile = projectFlowFileInput.val(); + if (flowFile === "" || !/\.json$/.test(flowFile)) { + valid = false; + if (!projectFlowFileInput.hasClass("input-error")) { + projectFlowFileInput.addClass("input-error"); + projectFlowFileInput.next().empty().append('<i style="margin-top: 8px;" class="fa fa-exclamation-triangle"></i>'); + } + } else { + if (projectFlowFileInput.hasClass("input-error")) { + projectFlowFileInput.removeClass("input-error"); + projectFlowFileInput.next().empty(); + } + } + + var encryptionState = $("input[name=projects-encryption-type]:checked").val(); + if (encryptionState === 'enabled') { + var encryptionKeyType = $("input[name=projects-encryption-key]:checked").val(); + if (encryptionKeyType === 'custom') { + valid = valid && emptyProjectCredentialInput.val()!=='' + } + } + } else if (projectType === 'open') { + valid = !!selectedProject; + } + + $("#red-ui-projects-dialog-create").prop('disabled',!valid).toggleClass('disabled ui-button-disabled ui-state-disabled',!valid); + } + + row = $('<div class="form-row button-group"></div>').appendTo(container); + + var openProject = $('<button data-type="open" class="red-ui-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-folder-open"></i><br/>'+RED._("projects.create.open")+'</button>').appendTo(row); + var createAsEmpty = $('<button data-type="empty" class="red-ui-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-asterisk"></i><br/>'+RED._("projects.create.create")+'</button>').appendTo(row); + // var createAsCopy = $('<button data-type="copy" class="red-ui-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i class="fa fa-long-arrow-right fa-2x"></i><i class="fa fa-archive fa-2x"></i><br/>Copy existing</button>').appendTo(row); + var createAsClone = $('<button data-type="clone" class="red-ui-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-git"></i><br/>'+RED._("projects.create.clone")+'</button>').appendTo(row); + // var createAsClone = $('<button data-type="clone" class="red-ui-button red-ui-projects-dialog-screen-create-type toggle"><i class="fa fa-git fa-2x"></i><i class="fa fa-arrows-h fa-2x"></i><i class="fa fa-archive fa-2x"></i><br/>Clone Repository</button>').appendTo(row); + row.find(".red-ui-projects-dialog-screen-create-type").on("click", function(evt) { + evt.preventDefault(); + container.find(".red-ui-projects-dialog-screen-create-type").removeClass('selected'); + $(this).addClass('selected'); + container.find(".red-ui-projects-dialog-screen-create-row").hide(); + container.find(".red-ui-projects-dialog-screen-create-row-"+$(this).data('type')).show(); + validateForm(); + projectNameInput.trigger("focus"); + switch ($(this).data('type')) { + case "open": $("#red-ui-projects-dialog-create").text(RED._("projects.create.open")); break; + case "empty": $("#red-ui-projects-dialog-create").text(RED._("projects.create.create")); break; + case "clone": $("#red-ui-projects-dialog-create").text(RED._("projects.create.clone")); break; + } + }) + + row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-open"></div>').hide().appendTo(container); + createProjectList({ + canSelectActive: false, + dblclick: function(project) { + selectedProject = project; + $("#red-ui-projects-dialog-create").trigger("click"); + }, + select: function(project) { + selectedProject = project; + validateForm(); + }, + delete: function(project) { + if (projectList) { + delete projectList[project.name]; + } + selectedProject = null; + + validateForm(); + } + }).appendTo(row); + + row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-empty red-ui-projects-dialog-screen-create-row-clone"></div>').appendTo(container); + $('<label for="red-ui-projects-dialog-screen-create-project-name">'+RED._("projects.create.project-name")+'</label>').appendTo(row); + + var subrow = $('<div style="position:relative;"></div>').appendTo(row); + projectNameInput = $('<input id="red-ui-projects-dialog-screen-create-project-name" type="text"></input>').appendTo(subrow); + var projectNameStatus = $('<div class="red-ui-projects-dialog-screen-input-status"></div>').appendTo(subrow); + + var projectNameInputChanged = false; + var projectNameLastChecked = ""; + var projectNameValid; + var checkProjectName; + var autoInsertedName = ""; + + + projectNameInput.on("change keyup paste",function() { + projectNameInputChanged = (projectNameInput.val() !== projectNameLastChecked); + if (checkProjectName) { + clearTimeout(checkProjectName); + } else if (projectNameInputChanged) { + projectNameStatus.empty(); + $('<img src="red/images/spin.svg"/>').appendTo(projectNameStatus); + if (projectNameInput.val() === '') { + validateForm(); + return; + } + } + checkProjectName = setTimeout(function() { + validateForm(); + checkProjectName = null; + },300) + }); + projectNameSublabel = $('<label class="red-ui-projects-edit-form-sublabel"><small>'+RED._("projects.create.must-contain")+'</small></label>').appendTo(row).find("small"); + + // Empty Project + row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-empty"></div>').appendTo(container); + $('<label for="red-ui-projects-dialog-screen-create-project-desc">'+RED._("projects.create.desc")+'</label>').appendTo(row); + projectSummaryInput = $('<input id="red-ui-projects-dialog-screen-create-project-desc" type="text">').appendTo(row); + $('<label class="red-ui-projects-edit-form-sublabel"><small>'+RED._("projects.create.opt")+'</small></label>').appendTo(row); + + row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-empty"></div>').appendTo(container); + $('<label for="red-ui-projects-dialog-screen-create-project-file">'+RED._("projects.create.flow-file")+'</label>').appendTo(row); + subrow = $('<div style="position:relative;"></div>').appendTo(row); + projectFlowFileInput = $('<input id="red-ui-projects-dialog-screen-create-project-file" type="text">').val("flow.json") + .on("change keyup paste",validateForm) + .appendTo(subrow); + $('<div class="red-ui-projects-dialog-screen-input-status"></div>').appendTo(subrow); + $('<label class="red-ui-projects-edit-form-sublabel"><small>*.json</small></label>').appendTo(row); + + row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-empty"></div>').appendTo(container); + $('<label>'+RED._("projects.create.credentials")+'</label>').appendTo(row); + + var credentialsBox = $('<div class="red-ui-projects-dialog-credentials-box">').appendTo(row); + var credentialsRightBox = $('<div class="red-ui-projects-dialog-credentials-box-right">').appendTo(credentialsBox); + var credentialsLeftBox = $('<div class="red-ui-projects-dialog-credentials-box-left">').appendTo(credentialsBox); + + var credentialsEnabledBox = $('<div class="form-row red-ui-projects-dialog-credentials-box-enabled"></div>').appendTo(credentialsLeftBox); + $('<label class="red-ui-projects-edit-form-inline-label"><input type="radio" name="projects-encryption-type" value="enabled"> <i class="fa fa-lock"></i> <span>'+RED._("projects.encryption-config.enable")+'</span></label>').appendTo(credentialsEnabledBox); + var credentialsDisabledBox = $('<div class="form-row red-ui-projects-dialog-credentials-box-disabled disabled"></div>').appendTo(credentialsLeftBox); + $('<label class="red-ui-projects-edit-form-inline-label"><input type="radio" name="projects-encryption-type" value="disabled"> <i class="fa fa-unlock"></i> <span>'+RED._("projects.encryption-config.disable")+'</span></label>').appendTo(credentialsDisabledBox); + + credentialsLeftBox.find("input[name=projects-encryption-type]").on("click", function(e) { + var val = $(this).val(); + var toEnable; + var toDisable; + if (val === 'enabled') { + toEnable = credentialsEnabledBox; + toDisable = credentialsDisabledBox; + $(".projects-encryption-enabled-row").show(); + $(".projects-encryption-disabled-row").hide(); + if ($("input[name=projects-encryption-key]:checked").val() === 'custom') { + emptyProjectCredentialInput.trigger("focus"); + } + } else { + toDisable = credentialsEnabledBox; + toEnable = credentialsDisabledBox; + $(".projects-encryption-enabled-row").hide(); + $(".projects-encryption-disabled-row").show(); + + } + toEnable.removeClass("disabled"); + toDisable.addClass("disabled"); + validateForm(); + }) + + row = $('<div class="form-row projects-encryption-enabled-row"></div>').appendTo(credentialsRightBox); + $('<label class="red-ui-projects-edit-form-inline-label">'+RED._("projects.create.encryption-key")+'</label>').appendTo(row); + // row = $('<div class="projects-encryption-enabled-row"></div>').appendTo(credentialsRightBox); + emptyProjectCredentialInput = $('<input type="password"></input>').appendTo(row); + emptyProjectCredentialInput.on("change keyup paste", validateForm); + $('<label class="red-ui-projects-edit-form-sublabel"><small>'+RED._("projects.create.desc0")+'</small></label>').appendTo(row); + + + row = $('<div class="form-row projects-encryption-disabled-row"></div>').hide().appendTo(credentialsRightBox); + $('<div class="" style="padding: 5px 20px;"><i class="fa fa-warning"></i> '+RED._("projects.create.desc1")+'</div>').appendTo(row); + + credentialsRightBox.find("input[name=projects-encryption-key]").on("click", function() { + var val = $(this).val(); + emptyProjectCredentialInput.attr("disabled",val === 'default'); + if (val === "custom") { + emptyProjectCredentialInput.trigger("focus"); + } + validateForm(); + }) + + // Clone Project + row = $('<div class="hide form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-clone"></div>').appendTo(container); + $('<label for="red-ui-projects-dialog-screen-create-project-repo">'+RED._("projects.create.git-url")+'</label>').appendTo(row); + projectRepoInput = $('<input id="red-ui-projects-dialog-screen-create-project-repo" type="text" placeholder="https://git.example.com/path/my-project.git"></input>').appendTo(row); + $('<label id="red-ui-projects-dialog-screen-create-project-repo-label" class="red-ui-projects-edit-form-sublabel"><small>'+RED._("projects.create.protocols")+'</small></label>').appendTo(row); + + var projectRepoChanged = false; + var lastProjectRepo = ""; + projectRepoInput.on("change keyup paste",function() { + projectRepoChanged = true; + var repo = $(this).val(); + if (lastProjectRepo !== repo) { + $("#red-ui-projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.protocols")); + } + lastProjectRepo = repo; + + var m = /\/([^/]+?)(?:\.git)?$/.exec(repo); + if (m) { + var projectName = projectNameInput.val(); + if (projectName === "" || projectName === autoInsertedName) { + autoInsertedName = m[1]; + projectNameInput.val(autoInsertedName); + projectNameInput.trigger("change"); + } + } + validateForm(); + }); + + + var cloneAuthRows = $('<div class="hide red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-clone"></div>').hide().appendTo(container); + row = $('<div class="form-row red-ui-projects-dialog-screen-create-row-auth-error"></div>').hide().appendTo(cloneAuthRows); + $('<div><i class="fa fa-warning"></i> '+RED._("projects.create.auth-failed")+'</div>').appendTo(row); + + // Repo credentials - username/password ---------------- + row = $('<div class="hide form-row red-ui-projects-dialog-screen-create-row-creds"></div>').hide().appendTo(cloneAuthRows); + + var subrow = $('<div style="width: calc(50% - 10px); display:inline-block;"></div>').appendTo(row); + $('<label for="red-ui-projects-dialog-screen-create-project-repo-user">'+RED._("projects.create.username")+'</label>').appendTo(subrow); + projectRepoUserInput = $('<input id="red-ui-projects-dialog-screen-create-project-repo-user" type="text"></input>').appendTo(subrow); + + subrow = $('<div style="width: calc(50% - 10px); margin-left: 20px; display:inline-block;"></div>').appendTo(row); + $('<label for="red-ui-projects-dialog-screen-create-project-repo-pass">'+RED._("projects.create.password")+'</label>').appendTo(subrow); + projectRepoPasswordInput = $('<input id="red-ui-projects-dialog-screen-create-project-repo-pass" type="password"></input>').appendTo(subrow); + // ----------------------------------------------------- + + // Repo credentials - key/passphrase ------------------- + row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-sshkey"></div>').hide().appendTo(cloneAuthRows); + subrow = $('<div style="width: calc(50% - 10px); display:inline-block;"></div>').appendTo(row); + $('<label for="red-ui-projects-dialog-screen-create-project-repo-passphrase">'+RED._("projects.create.ssh-key")+'</label>').appendTo(subrow); + projectRepoSSHKeySelect = $("<select>",{style:"width: 100%"}).appendTo(subrow); + + $.getJSON("settings/user/keys", function(data) { + var count = 0; + data.keys.forEach(function(key) { + projectRepoSSHKeySelect.append($("<option></option>").val(key.name).text(key.name)); + count++; + }); + if (count === 0) { + projectRepoSSHKeySelect.addClass("input-error"); + projectRepoSSHKeySelect.attr("disabled",true); + sshwarningRow.show(); + } else { + projectRepoSSHKeySelect.removeClass("input-error"); + projectRepoSSHKeySelect.attr("disabled",false); + sshwarningRow.hide(); + } + }); + subrow = $('<div style="width: calc(50% - 10px); margin-left: 20px; display:inline-block;"></div>').appendTo(row); + $('<label for="red-ui-projects-dialog-screen-create-project-repo-passphrase">'+RED._("projects.create.passphrase")+'</label>').appendTo(subrow); + projectRepoPassphrase = $('<input id="red-ui-projects-dialog-screen-create-project-repo-passphrase" type="password"></input>').appendTo(subrow); + + subrow = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-sshkey"></div>').appendTo(cloneAuthRows); + var sshwarningRow = $('<div class="red-ui-projects-dialog-screen-create-row-auth-error-no-keys"></div>').hide().appendTo(subrow); + $('<div class="form-row"><i class="fa fa-warning"></i> '+RED._("projects.create.desc2")+'</div>').appendTo(sshwarningRow); + subrow = $('<div style="text-align: center">').appendTo(sshwarningRow); + $('<button class="red-ui-button">'+RED._("projects.create.add-ssh-key")+'</button>').appendTo(subrow).on("click", function(e) { + e.preventDefault(); + $('#red-ui-projects-dialog-cancel').trigger("click"); + RED.userSettings.show('gitconfig'); + setTimeout(function() { + $("#user-settings-gitconfig-add-key").trigger("click"); + },500); + }); + // ----------------------------------------------------- + + + // Secret - clone + row = $('<div class="hide form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-clone"></div>').appendTo(container); + $('<label>'+RED._("projects.create.credentials-encryption-key")+'</label>').appendTo(row); + projectSecretInput = $('<input type="password"></input>').appendTo(row); + + + switch(options.screen||"empty") { + case "empty": createAsEmpty.trigger("click"); break; + case "open": openProject.trigger("click"); break; + case "clone": createAsClone.trigger("click"); break; + } + + setTimeout(function() { + if ((options.screen||"empty") !== "open") { + projectNameInput.trigger("focus"); + } else { + $("#red-ui-projects-dialog-project-list-search").trigger("focus"); + } + },50); + return container; + }, + buttons: function(options) { + var initialLabel; + switch (options.screen||"empty") { + case "open": initialLabel = RED._("projects.create.open"); break; + case "empty": initialLabel = RED._("projects.create.create"); break; + case "clone": initialLabel = RED._("projects.create.clone"); break; + } + return [ + { + id: "red-ui-projects-dialog-cancel", + text: RED._("common.label.cancel"), + click: function() { + $( this ).dialog( "close" ); + } + }, + { + id: "red-ui-projects-dialog-create", + text: initialLabel, + class: "primary disabled", + disabled: true, + click: function() { + var projectType = $(".red-ui-projects-dialog-screen-create-type.selected").data('type'); + var projectData = { + name: projectNameInput.val(), + } + if (projectType === 'empty') { + projectData.summary = projectSummaryInput.val(); + projectData.files = { + flow: projectFlowFileInput.val() + }; + var encryptionState = $("input[name=projects-encryption-type]:checked").val(); + if (encryptionState === 'enabled') { + projectData.credentialSecret = emptyProjectCredentialInput.val(); + } else { + // Disabled encryption by explicitly setting credSec to false + projectData.credentialSecret = false; + } + + + } else if (projectType === 'copy') { + projectData.copy = copyProject.name; + } else if (projectType === 'clone') { + projectData.credentialSecret = projectSecretInput.val(); + var repoUrl = projectRepoInput.val(); + var metaData = {}; + if (/^(?:ssh|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?/.test(repoUrl)) { + var selected = projectRepoSSHKeySelect.val();//false;//getSelectedSSHKey(projectRepoSSHKeySelect); + if ( selected ) { + projectData.git = { + remotes: { + 'origin': { + url: repoUrl, + keyFile: selected, + passphrase: projectRepoPassphrase.val() + } + } + }; + } + else { + console.log(RED._("projects.create.cant-get-ssh-key-path")); + return; + } + } + else { + projectData.git = { + remotes: { + 'origin': { + url: repoUrl, + username: projectRepoUserInput.val(), + password: projectRepoPasswordInput.val() + } + } + }; + } + } else if (projectType === 'open') { + return switchProject(selectedProject.name,function(err,data) { + dialog.dialog( "close" ); + if (err) { + if (err.code !== 'credentials_load_failed') { + console.log(RED._("projects.create.unexpected_error"),err) + } + } + }) + } + + $(".red-ui-projects-dialog-screen-create-row-auth-error").hide(); + $("#red-ui-projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.protocols")); + + projectRepoUserInput.removeClass("input-error"); + projectRepoPasswordInput.removeClass("input-error"); + projectRepoSSHKeySelect.removeClass("input-error"); + projectRepoPassphrase.removeClass("input-error"); + + RED.deploy.setDeployInflight(true); + RED.projects.settings.switchProject(projectData.name); + + sendRequest({ + url: "projects", + type: "POST", + handleAuthFail: false, + responses: { + 200: function(data) { + dialog.dialog( "close" ); + }, + 400: { + 'project_exists': function(error) { + console.log(RED._("projects.create.already-exists-2")); + }, + 'git_error': function(error) { + console.log(RED._("projects.create.git-error"),error); + }, + 'git_connection_failed': function(error) { + projectRepoInput.addClass("input-error"); + $("#red-ui-projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.con-failed")); + }, + 'git_not_a_repository': function(error) { + projectRepoInput.addClass("input-error"); + $("#red-ui-projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.not-git")); + }, + 'git_repository_not_found': function(error) { + projectRepoInput.addClass("input-error"); + $("#red-ui-projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.no-resource")); + }, + 'git_auth_failed': function(error) { + $(".red-ui-projects-dialog-screen-create-row-auth-error").show(); + + projectRepoUserInput.addClass("input-error"); + projectRepoPasswordInput.addClass("input-error"); + // getRepoAuthDetails(req); + projectRepoSSHKeySelect.addClass("input-error"); + projectRepoPassphrase.addClass("input-error"); + }, + 'missing_flow_file': function(error) { + // This is handled via a runtime notification. + dialog.dialog("close"); + }, + 'missing_package_file': function(error) { + // This is handled via a runtime notification. + dialog.dialog("close"); + }, + 'project_empty': function(error) { + // This is handled via a runtime notification. + dialog.dialog("close"); + }, + 'credentials_load_failed': function(error) { + // This is handled via a runtime notification. + dialog.dialog("close"); + }, + '*': function(error) { + reportUnexpectedError(error); + $( dialog ).dialog( "close" ); + } + } + } + },projectData).then(function() { + RED.events.emit("project:change", {name:name}); + }).always(function() { + setTimeout(function() { + RED.deploy.setDeployInflight(false); + },500); + }) + } + } + ] + } + } + })() + } + } + + function switchProject(name,done) { + RED.deploy.setDeployInflight(true); + RED.projects.settings.switchProject(name); + sendRequest({ + url: "projects/"+name, + type: "PUT", + responses: { + 200: function(data) { + done(null,data); + }, + 400: { + '*': done + }, + } + },{active:true}).then(function() { + RED.events.emit("project:change", {name:name}); + }).always(function() { + setTimeout(function() { + RED.deploy.setDeployInflight(false); + },500); + }) + } + + function deleteProject(row,name,done) { + var cover = $('<div>').css({ + background:"white", + position:"absolute", + top:0,right:0,bottom:0,left:"100%", + overflow:"hidden", + padding: "5px 20px", + transition: "left 0.4s", + whitespace: "nowrap", + width:"1000px" + }).on("click", function(evt) { evt.stopPropagation(); }).appendTo(row); + $('<span>').css({"lineHeight":"40px"}).text(RED._("projects.delete.confirm")).appendTo(cover); + $('<button style="margin-left:20px" class="red-ui-button">'+RED._("common.label.cancel")+'</button>') + .appendTo(cover) + .on("click", function(e) { + e.stopPropagation(); + cover.remove(); + done(true); + }); + $('<button style="margin-left:20px" class="red-ui-button primary">'+RED._("common.label.delete")+'</button>') + .appendTo(cover) + .on("click", function(e) { + e.stopPropagation(); + cover.remove(); + sendRequest({ + url: "projects/"+name, + type: "DELETE", + responses: { + 200: function(data) { + done(false); + }, + 400: { + 'unexpected_error': function(error) { + cover.remove(); + done(true); + } + } + } + }); + }); + + setTimeout(function() { + cover.css("left",0); + },50); + // + } + + function show(s,options) { + if (!dialog) { + RED.projects.init(); + } + var screen = screens[s]; + var container = screen.content(options||{}); + + dialogBody.empty(); + var buttons = screen.buttons; + if (typeof buttons === 'function') { + buttons = buttons(options||{}); + } + dialog.dialog('option','buttons',buttons); + dialogBody.append(container); + dialog.dialog('option','title',screen.title||""); + dialog.dialog("open"); + dialog.dialog({position: { 'my': 'center top', 'at': 'center top+20', 'of': window }}); + } + + function createProjectList(options) { + options = options||{}; + var height = options.height || "300px"; + var container = $('<div></div>',{class:"red-ui-projects-dialog-project-list-container" }); + var filterTerm = ""; + + var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(container); + var searchInput = $('<input id="red-ui-projects-dialog-project-list-search" type="text" placeholder="'+RED._("projects.create-project-list.search")+'">').appendTo(searchDiv).searchBox({ + //data-i18n="[placeholder]menu.label.searchInput" + delay: 200, + change: function() { + filterTerm = $(this).val().toLowerCase(); + list.editableList('filter'); + if (selectedListItem && !selectedListItem.is(":visible")) { + selectedListItem.children().children().removeClass('selected'); + selectedListItem = list.children(":visible").first(); + selectedListItem.children().children().addClass('selected'); + if (options.select) { + options.select(selectedListItem.children().data('data')); + } + } else { + selectedListItem = list.children(":visible").first(); + selectedListItem.children().children().addClass('selected'); + if (options.select) { + options.select(selectedListItem.children().data('data')); + } + } + ensureSelectedIsVisible(); + } + }); + var selectedListItem; + + searchInput.on('keydown',function(evt) { + if (evt.keyCode === 40) { + evt.preventDefault(); + // Down + var next = selectedListItem; + if (selectedListItem) { + do { + next = next.next(); + } while(next.length !== 0 && !next.is(":visible")); + if (next.length === 0) { + return; + } + selectedListItem.children().children().removeClass('selected'); + } else { + next = list.children(":visible").first(); + } + selectedListItem = next; + selectedListItem.children().children().addClass('selected'); + if (options.select) { + options.select(selectedListItem.children().data('data')); + } + ensureSelectedIsVisible(); + } else if (evt.keyCode === 38) { + evt.preventDefault(); + // Up + var prev = selectedListItem; + if (selectedListItem) { + do { + prev = prev.prev(); + } while(prev.length !== 0 && !prev.is(":visible")); + if (prev.length === 0) { + return; + } + selectedListItem.children().children().removeClass('selected'); + } else { + prev = list.children(":visible").first(); + } + selectedListItem = prev; + selectedListItem.children().children().addClass('selected'); + if (options.select) { + options.select(selectedListItem.children().data('data')); + } + ensureSelectedIsVisible(); + } else if (evt.keyCode === 13) { + evt.preventDefault(); + // Enter + if (selectedListItem) { + if (options.dblclick) { + options.dblclick(selectedListItem.children().data('data')); + } + } + } + }); + + searchInput.i18n(); + + var ensureSelectedIsVisible = function() { + var selectedEntry = list.find(".red-ui-projects-dialog-project-list-entry.selected").parent().parent(); + if (selectedEntry.length === 1) { + var scrollWindow = listContainer; + var scrollHeight = scrollWindow.height(); + var scrollOffset = scrollWindow.scrollTop(); + var y = selectedEntry.position().top; + var h = selectedEntry.height(); + if (y+h > scrollHeight) { + scrollWindow.animate({scrollTop: '-='+(scrollHeight-y-h)},50); + } else if (y<0) { + scrollWindow.animate({scrollTop: '+='+y},50); + } + } + } + + var listContainer = $('<div></div>',{class:"red-ui-projects-dialog-project-list-inner-container" }).appendTo(container); + + var list = $('<ol>',{class:"red-ui-projects-dialog-project-list"}).appendTo(listContainer).editableList({ + addButton: false, + height:"auto", + scrollOnAdd: false, + addItem: function(row,index,entry) { + var header = $('<div></div>',{class:"red-ui-projects-dialog-project-list-entry"}).appendTo(row); + $('<span class="red-ui-projects-dialog-project-list-entry-icon"><i class="fa fa-archive"></i></span>').appendTo(header); + $('<span class="red-ui-projects-dialog-project-list-entry-name" style=""></span>').text(entry.name).appendTo(header); + if (activeProject && activeProject.name === entry.name) { + header.addClass("projects-list-entry-current"); + $('<span class="red-ui-projects-dialog-project-list-entry-current">'+RED._("projects.create-project-list.current")+'</span>').appendTo(header); + if (options.canSelectActive === false) { + // active project cannot be selected; so skip the rest + return + } + } + + header.addClass("selectable"); + + var tools = $('<div class="red-ui-projects-dialog-project-list-entry-tools"></div>').appendTo(header); + $('<button class="red-ui-button red-ui-button-small" style="float: right;"><i class="fa fa-trash"></i></button>') + .appendTo(tools) + .on("click", function(e) { + e.stopPropagation(); + e.preventDefault(); + deleteProject(row,entry.name, function(cancelled) { + if (!cancelled) { + row.fadeOut(300,function() { + list.editableList('removeItem',entry); + if (options.delete) { + options.delete(entry); + } + }); + } + }) + }); + + + row.on("click", function(evt) { + $('.red-ui-projects-dialog-project-list-entry').removeClass('selected'); + header.addClass('selected'); + selectedListItem = row.parent(); + if (options.select) { + options.select(entry); + } + ensureSelectedIsVisible(); + searchInput.trigger("focus"); + }) + if (options.dblclick) { + row.on("dblclick", function(evt) { + evt.preventDefault(); + options.dblclick(entry); + }) + } + }, + filter: function(data) { + if (filterTerm === "") { return true; } + return data.name.toLowerCase().indexOf(filterTerm) !== -1; + } + }); + $.getJSON("projects", function(data) { + data.projects.forEach(function(project) { + list.editableList('addItem',{name:project}); + }); + }) + return container; + } + + + + function requireCleanWorkspace(done) { + if (RED.nodes.dirty()) { + var message = RED._("projects.require-clean.confirm"); + var cleanNotification = RED.notify(message,{ + type:"info", + fixed: true, + modal: true, + buttons: [ + { + //id: "node-dialog-delete", + //class: 'leftButton', + text: RED._("common.label.cancel"), + click: function() { + cleanNotification.close(); + done(true); + } + },{ + text: RED._("common.label.cont"), + click: function() { + cleanNotification.close(); + done(false); + } + } + ] + }); + + } + } + + function sendRequest(options,body) { + // dialogBody.hide(); + // console.log(options.url,body); + if (options.requireCleanWorkspace && RED.nodes.dirty()) { + var thenCallback; + var alwaysCallback; + requireCleanWorkspace(function(cancelled) { + if (cancelled) { + if (options.cancel) { + options.cancel(); + if (alwaysCallback) { + alwaysCallback(); + } + } + } else { + delete options.requireCleanWorkspace; + sendRequest(options,body).then(function() { + if (thenCallback) { + thenCallback(); + } + }).always(function() { + if (alwaysCallback) { + alwaysCallback(); + } + + }) + } + }) + // What follows is a very hacky Promise-like api thats good enough + // for our needs. + return { + then: function(done) { + thenCallback = done; + return { always: function(done) { alwaysCallback = done; }} + }, + always: function(done) { alwaysCallback = done; } + } + } + + var start = Date.now(); + // TODO: this is specific to the dialog-based requests + $(".red-ui-component-spinner").show(); + $("#red-ui-projects-dialog").parent().find(".ui-dialog-buttonset").children().css("visibility","hidden") + if (body) { + options.data = JSON.stringify(body); + options.contentType = "application/json; charset=utf-8"; + } + var resultCallback; + var resultCallbackArgs; + return $.ajax(options).done(function(data,textStatus,xhr) { + if (options.responses && options.responses[200]) { + resultCallback = options.responses[200]; + resultCallbackArgs = data; + } + }).fail(function(xhr,textStatus,err) { + var responses; + + if (options.responses && options.responses[xhr.status]) { + responses = options.responses[xhr.status]; + if (typeof responses === 'function') { + resultCallback = responses; + resultCallbackArgs = {error:responses.statusText}; + return; + } else if (options.handleAuthFail !== false && (xhr.responseJSON.code === 'git_auth_failed' || xhr.responseJSON.code === 'git_host_key_verification_failed')) { + if (xhr.responseJSON.code === 'git_auth_failed') { + var url = activeProject.git.remotes[xhr.responseJSON.remote||options.remote||'origin'].fetch; + + var message = $('<div>'+ + '<div class="form-row">'+RED._("projects.send-req.auth-req")+':</div>'+ + '<div class="form-row"><div style="margin-left: 20px;">'+url+'</div></div>'+ + '</div>'); + + var isSSH = false; + if (/^https?:\/\//.test(url)) { + $('<div class="form-row"><label for="projects-user-auth-username">'+RED._("projects.send-req.username")+'</label><input id="projects-user-auth-username" type="text"></input></div>'+ + '<div class="form-row"><label for=projects-user-auth-password">'+RED._("projects.send-req.password")+'</label><input id="projects-user-auth-password" type="password"></input></div>').appendTo(message); + } else if (/^(?:ssh|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?/.test(url)) { + isSSH = true; + var row = $('<div class="form-row"></div>').appendTo(message); + $('<label for="projects-user-auth-key">SSH Key</label>').appendTo(row); + var projectRepoSSHKeySelect = $('<select id="projects-user-auth-key">').width('70%').appendTo(row); + $.getJSON("settings/user/keys", function(data) { + var count = 0; + data.keys.forEach(function(key) { + projectRepoSSHKeySelect.append($("<option></option>").val(key.name).text(key.name)); + count++; + }); + if (count === 0) { + //TODO: handle no keys yet setup + } + }); + row = $('<div class="form-row"></div>').appendTo(message); + $('<label for="projects-user-auth-passphrase">'+RED._("projects.send-req.passphrase")+'</label>').appendTo(row); + $('<input id="projects-user-auth-passphrase" type="password"></input>').appendTo(row); + } + + var notification = RED.notify(message,{ + type:"error", + fixed: true, + modal: true, + buttons: [ + { + //id: "node-dialog-delete", + //class: 'leftButton', + text: RED._("common.label.cancel"), + click: function() { + notification.close(); + } + },{ + text: '<span><i class="fa fa-refresh"></i> ' +RED._("projects.send-req.retry") +'</span>', + click: function() { + body = body || {}; + var authBody = {}; + if (isSSH) { + authBody.keyFile = $('#projects-user-auth-key').val(); + authBody.passphrase = $('#projects-user-auth-passphrase').val(); + } else { + authBody.username = $('#projects-user-auth-username').val(); + authBody.password = $('#projects-user-auth-password').val(); + } + var done = function(err) { + if (err) { + console.log(RED._("projects.send-req.update-failed")); + console.log(err); + } else { + sendRequest(options,body); + notification.close(); + } + + } + sendRequest({ + url: "projects/"+activeProject.name+"/remotes/"+(xhr.responseJSON.remote||options.remote||'origin'), + type: "PUT", + responses: { + 0: function(error) { + done(error,null); + }, + 200: function(data) { + done(null,data); + }, + 400: { + 'unexpected_error': function(error) { + done(error,null); + } + }, + } + },{auth:authBody}); + } + } + ] + }); + return; + } else if (xhr.responseJSON.code === 'git_host_key_verification_failed') { + var message = $('<div>'+ + '<div class="form-row">'+RED._("projects.send-req.host-key-verify-failed")+'</div>'+ + '</div>'); + var notification = RED.notify(message,{ + type:"error", + fixed: true, + modal: true, + buttons: [ + { + text: RED._("common.label.close"), + click: function() { + notification.close(); + } + } + ] + }); + return; + } + } else if (responses[xhr.responseJSON.code]) { + resultCallback = responses[xhr.responseJSON.code]; + resultCallbackArgs = xhr.responseJSON; + return; + } else if (responses['*']) { + resultCallback = responses['*']; + resultCallbackArgs = xhr.responseJSON; + return; + } + } + console.log(responses) + console.log(RED._("projects.send-req.unhandled")+":"); + console.log(xhr); + console.log(textStatus); + console.log(err); + }).always(function() { + var delta = Date.now() - start; + delta = Math.max(0,500-delta); + setTimeout(function() { + // dialogBody.show(); + $(".red-ui-component-spinner").hide(); + $("#red-ui-projects-dialog").parent().find(".ui-dialog-buttonset").children().css("visibility","") + if (resultCallback) { + resultCallback(resultCallbackArgs) + } + },delta); + }); + } + + function createBranchList(options) { + var branchFilterTerm = ""; + var branchFilterCreateItem; + var branches = []; + var branchPrefix = ""; + var container = $('<div class="red-ui-projects-branch-list">').appendTo(options.container); + + var branchFilter = $('<input type="text">').attr('placeholder',options.placeholder).appendTo(container).searchBox({ + delay: 200, + change: function() { + branchFilterTerm = $(this).val(); + if (/(\.\.|\/\.|[?*[~^: \\]|\/\/|\/.$|\/$)/.test(branchFilterTerm)) { + if (!branchFilterCreateItem.hasClass("input-error")) { + branchFilterCreateItem.addClass("input-error"); + branchFilterCreateItem.find("i").addClass("fa-warning").removeClass("fa-code-fork"); + } + branchFilterCreateItem.find("span").text(RED._("projects.create-branch-list.invalid")+": "+branchPrefix+branchFilterTerm); + } else { + if (branchFilterCreateItem.hasClass("input-error")) { + branchFilterCreateItem.removeClass("input-error"); + branchFilterCreateItem.find("i").removeClass("fa-warning").addClass("fa-code-fork"); + } + branchFilterCreateItem.find(".red-ui-sidebar-vc-branch-list-entry-create-name").text(branchPrefix+branchFilterTerm); + } + branchList.editableList("filter"); + } + }); + var branchList = $("<ol>",{style:"height: 130px;"}).appendTo(container); + branchList.editableList({ + addButton: false, + scrollOnAdd: false, + addItem: function(row,index,entry) { + var container = $('<div class="red-ui-sidebar-vc-branch-list-entry">').appendTo(row); + if (!entry.hasOwnProperty('commit')) { + branchFilterCreateItem = container; + $('<i class="fa fa-code-fork"></i>').appendTo(container); + $('<span>').text(RED._("projects.create-branch-list.create")+":").appendTo(container); + $('<div class="red-ui-sidebar-vc-branch-list-entry-create-name" style="margin-left: 10px;">').text(entry.name).appendTo(container); + } else { + $('<i class="fa fa-code-fork"></i>').appendTo(container); + $('<span>').text(entry.name).appendTo(container); + if (entry.current) { + container.addClass("selected"); + $('<span class="current"></span>').text(options.currentLabel||RED._("projects.create-branch-list.current")).appendTo(container); + } + } + container.on("click", function(evt) { + evt.preventDefault(); + if ($(this).hasClass('input-error')) { + return; + } + var body = {}; + if (!entry.hasOwnProperty('commit')) { + body.name = branchFilter.val(); + body.create = true; + if (options.remote) { + body.name = options.remote()+"/"+body.name; + } + } else { + if ($(this).hasClass('selected')) { + body.current = true; + } + body.name = entry.name; + } + if (options.onselect) { + options.onselect(body); + } + }); + }, + filter: function(data) { + var isCreateEntry = (!data.hasOwnProperty('commit')); + return ( + isCreateEntry && + ( + branchFilterTerm !== "" && + branches.indexOf(branchPrefix+branchFilterTerm) === -1 + ) + ) || + ( + !isCreateEntry && + data.name.indexOf(branchFilterTerm) !== -1 + ); + } + }); + return { + refresh: function(url) { + branchFilter.searchBox("value",""); + branchList.editableList('empty'); + var start = Date.now(); + var spinner = addSpinnerOverlay(container).addClass("red-ui-component-spinner-contain"); + if (options.remote) { + branchPrefix = options.remote()+"/"; + } else { + branchPrefix = ""; + } + + sendRequest({ + url: url, + type: "GET", + responses: { + 0: function(error) { + console.log(error); + }, + 200: function(result) { + branches = result.branches; + result.branches.forEach(function(b) { + branchList.editableList('addItem',b); + }); + branchList.editableList('addItem',{}); + setTimeout(function() { + spinner.remove(); + },Math.max(300-(Date.now() - start),0)); + }, + 400: { + 'git_connection_failed': function(error) { + RED.notify(error.message,'error'); + }, + 'git_not_a_repository': function(error) { + RED.notify(error.message,'error'); + }, + 'git_repository_not_found': function(error) { + RED.notify(error.message,'error'); + }, + 'unexpected_error': function(error) { + reportUnexpectedError(error); + } + } + } + }) + }, + // addItem: function(data) { branchList.editableList('addItem',data) }, + filter: function() { branchList.editableList('filter') }, + focus: function() { branchFilter.trigger("focus") } + } + } + + function addSpinnerOverlay(container) { + var spinner = $('<div class="red-ui-component-spinner"><img src="red/images/spin.svg"/></div>').appendTo(container); + return spinner; + } + + function init() { + dialog = $('<div id="red-ui-projects-dialog" class="hide red-ui-projects-edit-form"><form class="form-horizontal"></form><div class="red-ui-component-spinner hide"><img src="red/images/spin.svg"/></div></div>') + .appendTo("#red-ui-editor") + .dialog({ + modal: true, + autoOpen: false, + width: 600, + resizable: false, + classes: { + "ui-dialog": "red-ui-editor-dialog", + "ui-dialog-titlebar-close": "hide", + "ui-widget-overlay": "red-ui-editor-dialog" + } + }); + dialogBody = dialog.find("form"); + + RED.actions.add("core:new-project",RED.projects.newProject); + RED.actions.add("core:open-project",RED.projects.selectProject); + RED.actions.add("core:show-project-settings",RED.projects.settings.show); + var projectsAPI = { + sendRequest:sendRequest, + createBranchList:createBranchList, + addSpinnerOverlay:addSpinnerOverlay, + reportUnexpectedError:reportUnexpectedError + }; + RED.projects.settings.init(projectsAPI); + RED.projects.userSettings.init(projectsAPI); + RED.sidebar.versionControl.init(projectsAPI); + initScreens(); + // initSidebar(); + } + + function createDefaultFileSet() { + if (!activeProject) { + throw new Error(RED._("projects.create-default-file-set.no-active")); + } else if (!activeProject.empty) { + throw new Error(RED._("projects.create-default-file-set.no-empty")); + } + if (!RED.user.hasPermission("projects.write")) { + RED.notify(RED._("user.errors.notAuthorized"),"error"); + return; + } + createProjectOptions = {}; + show('default-files',{existingProject: true}); + } + function createDefaultPackageFile() { + RED.deploy.setDeployInflight(true); + RED.projects.settings.switchProject(activeProject.name); + + var method = "PUT"; + var url = "projects/"+activeProject.name; + var createProjectOptions = { + initialise: true + }; + sendRequest({ + url: url, + type: method, + requireCleanWorkspace: true, + handleAuthFail: false, + responses: { + 200: function(data) { }, + 400: { + 'git_error': function(error) { + console.log(RED._("projects.create-default-file-set.git-error"),error); + }, + 'missing_flow_file': function(error) { + // This is a natural next error - but let the runtime event + // trigger the dialog rather than double-report it. + $( dialog ).dialog( "close" ); + }, + '*': function(error) { + reportUnexpectedError(error); + $( dialog ).dialog( "close" ); + } + } + } + },createProjectOptions).always(function() { + setTimeout(function() { + RED.deploy.setDeployInflight(false); + },500); + }) + } + + function refresh(done) { + $.getJSON("projects",function(data) { + if (data.active) { + $.getJSON("projects/"+data.active, function(project) { + activeProject = project; + RED.sidebar.versionControl.refresh(true); + if (done) { + done(activeProject); + } + }); + } else { + if (done) { + done(null); + } + } + }); + } + + + function showNewProjectScreen() { + createProjectOptions = {}; + if (!activeProject) { + show('welcome'); + } else { + show('create',{screen:'empty'}) + } + } + + return { + init: init, + showStartup: function() { + if (!RED.user.hasPermission("projects.write")) { + RED.notify(RED._("user.errors.notAuthorized"),"error"); + return; + } + show('welcome'); + }, + newProject: function() { + if (!RED.user.hasPermission("projects.write")) { + RED.notify(RED._("user.errors.notAuthorized"),"error"); + return; + } + + if (RED.nodes.dirty()) { + return requireCleanWorkspace(function(cancelled) { + if (!cancelled) { + showNewProjectScreen(); + } + }) + } else { + showNewProjectScreen(); + } + }, + selectProject: function() { + if (!RED.user.hasPermission("projects.write")) { + RED.notify(RED._("user.errors.notAuthorized"),"error"); + return; + } + if (RED.nodes.dirty()) { + return requireCleanWorkspace(function(cancelled) { + if (!cancelled) { + show('create',{screen:'open'}) + } + }) + } else { + show('create',{screen:'open'}) + } + }, + showCredentialsPrompt: function() { //TODO: rename this function + if (!RED.user.hasPermission("projects.write")) { + RED.notify(RED._("user.errors.notAuthorized"),"error"); + return; + } + RED.projects.settings.show('settings'); + }, + showFilesPrompt: function() { //TODO: rename this function + if (!RED.user.hasPermission("projects.write")) { + RED.notify(RED._("user.errors.notAuthorized"),"error"); + return; + } + RED.projects.settings.show('settings'); + setTimeout(function() { + $("#project-settings-tab-settings-file-edit").trigger("click"); + },200) + }, + showProjectDependencies: function() { + RED.projects.settings.show('deps'); + }, + createDefaultFileSet: createDefaultFileSet, + createDefaultPackageFile: createDefaultPackageFile, + // showSidebar: showSidebar, + refresh: refresh, + editProject: function() { + RED.projects.settings.show(); + }, + getActiveProject: function() { + return activeProject; + } + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/projects/tab-versionControl.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/projects/tab-versionControl.js new file mode 100644 index 0000000..e367e9c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/projects/tab-versionControl.js @@ -0,0 +1,1397 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.sidebar.versionControl = (function() { + + var sidebarContent; + var sections; + + var allChanges = {}; + + var unstagedChangesList; + var stageAllButton; + var stagedChangesList; + var unstageAllButton; + var unstagedChanges; + var stagedChanges; + var bulkChangeSpinner; + var unmergedContent; + var unmergedChangesList; + var commitButton; + var localChanges; + + var localCommitList; + var localCommitListShade; + // var remoteCommitList; + + var isMerging; + + function viewFileDiff(entry,state) { + var activeProject = RED.projects.getActiveProject(); + var diffTarget = (state === 'staged')?"index":"tree"; + utils.sendRequest({ + url: "projects/"+activeProject.name+"/diff/"+diffTarget+"/"+encodeURIComponent(entry.file), + type: "GET", + responses: { + 0: function(error) { + console.log(error); + // done(error,null); + }, + 200: function(data) { + var title; + if (state === 'unstaged') { + title = RED._("sidebar.project.versionControl.unstagedChanges")+' : '+entry.file + } else if (state === 'staged') { + title = RED._("sidebar.project.versionControl.stagedChanges")+' : '+entry.file + } else { + title = RED._("sidebar.project.versionControl.resolveConflicts")+' : '+entry.file + } + var options = { + diff: data.diff, + title: title, + unmerged: state === 'unmerged', + project: activeProject + } + if (state == 'unstaged') { + options.oldRevTitle = entry.indexStatus === " "?RED._("sidebar.project.versionControl.head"):RED._("sidebar.project.versionControl.staged"); + options.newRevTitle = RED._("sidebar.project.versionControl.unstaged"); + options.oldRev = entry.indexStatus === " "?"@":":0"; + options.newRev = "_"; + } else if (state === 'staged') { + options.oldRevTitle = RED._("sidebar.project.versionControl.head"); + options.newRevTitle = RED._("sidebar.project.versionControl.staged"); + options.oldRev = "@"; + options.newRev = ":0"; + } else { + options.oldRevTitle = RED._("sidebar.project.versionControl.local"); + options.newRevTitle = RED._("sidebar.project.versionControl.remote"); + options.commonRev = ":1"; + options.oldRev = ":2"; + options.newRev = ":3"; + options.onresolve = function(resolution) { + utils.sendRequest({ + url: "projects/"+activeProject.name+"/resolve/"+encodeURIComponent(entry.file), + type: "POST", + responses: { + 0: function(error) { + console.log(error); + // done(error,null); + }, + 200: function(data) { + refresh(true); + }, + 400: { + 'unexpected_error': function(error) { + console.log(error); + // done(error,null); + } + }, + } + },{resolutions:resolution.resolutions[entry.file]}); + } + } + RED.diff.showUnifiedDiff(options); + }, + 400: { + 'unexpected_error': function(error) { + console.log(error); + // done(error,null); + } + } + } + }) + } + + function createChangeEntry(row, entry, status, state) { + row.addClass("red-ui-sidebar-vc-change-entry"); + var container = $('<div>').appendTo(row); + if (entry.label) { + row.addClass('red-ui-help-info-none'); + container.text(entry.label); + if (entry.button) { + container.css({ + display: "inline-block", + maxWidth: "300px", + textAlign: "left" + }) + var toolbar = $('<div style="float: right; margin: 5px; height: 50px;"></div>').appendTo(container); + + $('<button class="red-ui-button red-ui-button-small"></button>').text(entry.button.label) + .appendTo(toolbar) + .on("click", entry.button.click); + } + return; + } + + + var icon = $('<i class=""></i>').appendTo(container); + var entryLink = $('<a href="#">') + .appendTo(container) + .on("click", function(e) { + e.preventDefault(); + viewFileDiff(entry,state); + }); + var label = $('<span>').appendTo(entryLink); + + var entryTools = $('<div class="red-ui-sidebar-vc-change-entry-tools">').appendTo(row); + var bg; + var revertButton; + if (state === 'unstaged') { + bg = $('<span class="button-group" style="margin-right: 5px;"></span>').appendTo(entryTools); + revertButton = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-reply"></i></button>') + .appendTo(bg) + .on("click", function(evt) { + evt.preventDefault(); + + var spinner = utils.addSpinnerOverlay(container).addClass('red-ui-component-spinner-contain'); + var notification = RED.notify(RED._("sidebar.project.versionControl.revert",{file:entry.file}), { + type: "warning", + modal: true, + fixed: true, + buttons: [ + { + text: RED._("common.label.cancel"), + click: function() { + spinner.remove(); + notification.close(); + } + },{ + text: RED._("sidebar.project.versionControl.revertChanges"), + click: function() { + notification.close(); + var activeProject = RED.projects.getActiveProject(); + var url = "projects/"+activeProject.name+"/files/_/"+entry.file; + var options = { + url: url, + type: "DELETE", + responses: { + 200: function(data) { + spinner.remove(); + }, + 400: { + 'unexpected_error': function(error) { + spinner.remove(); + console.log(error); + // done(error,null); + } + } + } + } + RED.deploy.setDeployInflight(true); + utils.sendRequest(options).always(function() { + setTimeout(function() { + RED.deploy.setDeployInflight(false); + },500); + }); + } + } + + ] + }) + }); + RED.popover.tooltip(revertButton,RED._("sidebar.project.versionControl.revertChanges")); + } + bg = $('<span class="button-group"></span>').appendTo(entryTools); + if (state !== 'unmerged') { + var stageButton = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-'+((state==='unstaged')?"plus":"minus")+'"></i></button>') + .appendTo(bg) + .on("click", function(evt) { + evt.preventDefault(); + var activeProject = RED.projects.getActiveProject(); + entry.spinner = utils.addSpinnerOverlay(row).addClass('projects-version-control-spinner-sidebar'); + utils.sendRequest({ + url: "projects/"+activeProject.name+"/stage/"+encodeURIComponent(entry.file), + type: (state==='unstaged')?"POST":"DELETE", + responses: { + 0: function(error) { + console.log(error); + // done(error,null); + }, + 200: function(data) { + refreshFiles(data); + }, + 400: { + 'unexpected_error': function(error) { + console.log(error); + // done(error,null); + } + }, + } + },{}); + }); + RED.popover.tooltip(stageButton,RED._("sidebar.project.versionControl."+((state==='unstaged')?"stage":"unstage")+"Change")); + } + entry["update"+((state==='unstaged')?"Unstaged":"Staged")] = function(entry,status) { + container.removeClass(); + var iconClass = ""; + if (status === 'A') { + container.addClass("red-ui-diff-state-added"); + iconClass = "fa-plus-square"; + } else if (status === '?') { + container.addClass("red-ui-diff-state-unchanged"); + iconClass = "fa-question-circle-o"; + } else if (status === 'D') { + container.addClass("red-ui-diff-state-deleted"); + iconClass = "fa-minus-square"; + } else if (status === 'M') { + container.addClass("red-ui-diff-state-changed"); + iconClass = "fa-square"; + } else if (status === 'R') { + container.addClass("red-ui-diff-state-changed"); + iconClass = "fa-toggle-right"; + } else if (status === 'U') { + container.addClass("red-ui-diff-state-conflicted"); + iconClass = "fa-exclamation-triangle"; + } else { + iconClass = "fa-exclamation-triangle" + } + label.empty(); + $('<span>').text(entry.file.replace(/\\(.)/g,"$1")).appendTo(label); + + if (entry.oldName) { + $('<i class="fa fa-long-arrow-right"></i>').prependTo(label); + $('<span>').text(entry.oldName.replace(/\\(.)/g,"$1")).prependTo(label); + // label.text(entry.oldName+" -> "+entry.file); + } + // console.log(entry.file,status,iconClass); + + icon.removeClass(); + icon.addClass("fa "+iconClass); + if (entry.spinner) { + entry.spinner.remove(); + delete entry.spinner; + } + + if (revertButton) { + revertButton.toggle(status !== '?'); + } + entryLink.toggleClass("disabled",(status === 'D' || status === '?')); + } + entry["update"+((state==='unstaged')?"Unstaged":"Staged")](entry, status); + } + var utils; + var emptyStagedItem; + var emptyMergedItem; + function init(_utils) { + utils = _utils; + + RED.actions.add("core:show-version-control-tab",show); + RED.events.on("deploy", function() { + var activeProject = RED.projects.getActiveProject(); + if (activeProject) { + // TODO: this is a full refresh of the files - should be able to + // just do an incremental refresh + allChanges = {}; + unstagedChangesList.editableList('empty'); + stagedChangesList.editableList('empty'); + unmergedChangesList.editableList('empty'); + + $.getJSON("projects/"+activeProject.name+"/status",function(result) { + refreshFiles(result); + }); + } + }); + RED.events.on("login",function() { + refresh(true); + }); + sidebarContent = $('<div>', {class:"red-ui-sidebar-vc"}); + var stackContainer = $("<div>",{class:"red-ui-sidebar-vc-stack"}).appendTo(sidebarContent); + sections = RED.stack.create({ + container: stackContainer, + fill: true, + singleExpanded: true + }); + + localChanges = sections.add({ + title: RED._("sidebar.project.versionControl.localChanges"), + collapsible: true + }); + localChanges.expand(); + localChanges.content.css({height:"100%"}); + + var bg = $('<div style="float: right"></div>').appendTo(localChanges.header); + var refreshButton = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-refresh"></i></button>') + .appendTo(bg) + .on("click", function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + refresh(true); + }); + RED.popover.tooltip(refreshButton,RED._("sidebar.project.versionControl.refreshChanges")); + + emptyStagedItem = { label: RED._("sidebar.project.versionControl.none") }; + emptyMergedItem = { label: RED._("sidebar.project.versionControl.conflictResolve") }; + + var unstagedContent = $('<div class="red-ui-sidebar-vc-change-container"></div>').appendTo(localChanges.content); + var header = $('<div class="red-ui-sidebar-vc-change-header">'+RED._("sidebar.project.versionControl.localFiles")+'</div>').appendTo(unstagedContent); + stageAllButton = $('<button class="red-ui-button red-ui-button-small" style="position: absolute; right: 5px; top: 5px;"><i class="fa fa-plus"></i> '+RED._("sidebar.project.versionControl.all")+'</button>') + .appendTo(header) + .on("click", function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + var toStage = Object.keys(allChanges).filter(function(fn) { + return allChanges[fn].treeStatus !== ' '; + }); + updateBulk(toStage,true); + }); + RED.popover.tooltip(stageAllButton,RED._("sidebar.project.versionControl.stageAllChange")); + unstagedChangesList = $("<ol>",{style:"position: absolute; top: 30px; bottom: 0; right:0; left:0;"}).appendTo(unstagedContent); + unstagedChangesList.editableList({ + addButton: false, + scrollOnAdd: false, + addItem: function(row,index,entry) { + createChangeEntry(row,entry,entry.treeStatus,'unstaged'); + }, + sort: function(A,B) { + if (A.treeStatus === '?' && B.treeStatus !== '?') { + return 1; + } else if (A.treeStatus !== '?' && B.treeStatus === '?') { + return -1; + } + return A.file.localeCompare(B.file); + } + + }) + + unmergedContent = $('<div class="red-ui-sidebar-vc-change-container"></div>').appendTo(localChanges.content); + + header = $('<div class="red-ui-sidebar-vc-change-header">'+RED._("sidebar.project.versionControl.unmergedChanges")+'</div>').appendTo(unmergedContent); + bg = $('<div style="position: absolute; right: 5px; top: 5px;"></div>').appendTo(header); + var abortMergeButton = $('<button class="red-ui-button red-ui-button-small" style="margin-right: 5px;">'+RED._("sidebar.project.versionControl.abortMerge")+'</button>') + .appendTo(bg) + .on("click", function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + var spinner = utils.addSpinnerOverlay(unmergedContent); + var activeProject = RED.projects.getActiveProject(); + RED.deploy.setDeployInflight(true); + utils.sendRequest({ + url: "projects/"+activeProject.name+"/merge", + type: "DELETE", + responses: { + 0: function(error) { + console.log(error); + }, + 200: function(data) { + spinner.remove(); + refresh(true); + }, + 400: { + 'unexpected_error': function(error) { + console.log(error); + } + }, + } + }).always(function() { + setTimeout(function() { + RED.deploy.setDeployInflight(false); + },500); + }); + }); + unmergedChangesList = $("<ol>",{style:"position: absolute; top: 30px; bottom: 0; right:0; left:0;"}).appendTo(unmergedContent); + unmergedChangesList.editableList({ + addButton: false, + scrollOnAdd: false, + addItem: function(row,index,entry) { + if (entry === emptyMergedItem) { + entry.button = { + label: RED._("sidebar.project.versionControl.commit"), + click: function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + showCommitBox(); + } + } + } + createChangeEntry(row,entry,entry.treeStatus,'unmerged'); + }, + sort: function(A,B) { + if (A.treeStatus === '?' && B.treeStatus !== '?') { + return 1; + } else if (A.treeStatus !== '?' && B.treeStatus === '?') { + return -1; + } + return A.file.localeCompare(B.file); + } + + }) + + + var stagedContent = $('<div class="red-ui-sidebar-vc-change-container"></div>').appendTo(localChanges.content); + + header = $('<div class="red-ui-sidebar-vc-change-header">'+RED._("sidebar.project.versionControl.changeToCommit")+'</div>').appendTo(stagedContent); + + bg = $('<div style="position: absolute; right: 5px; top: 5px;"></div>').appendTo(header); + var showCommitBox = function() { + commitMessage.val(""); + submitCommitButton.prop("disabled",true); + unstagedContent.css("height","30px"); + if (unmergedContent.is(":visible")) { + unmergedContent.css("height","30px"); + stagedContent.css("height","calc(100% - 60px - 175px)"); + } else { + stagedContent.css("height","calc(100% - 30px - 175px)"); + } + commitBox.show(); + setTimeout(function() { + commitBox.css("height","175px"); + },10); + stageAllButton.prop("disabled",true); + unstageAllButton.prop("disabled",true); + commitButton.prop("disabled",true); + abortMergeButton.prop("disabled",true); + commitMessage.trigger("focus"); + } + commitButton = $('<button class="red-ui-button red-ui-button-small" style="margin-right: 5px;">'+RED._("sidebar.project.versionControl.commit")+'</button>') + .appendTo(bg) + .on("click", function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + showCommitBox(); + }); + RED.popover.tooltip(commitButton,RED._("sidebar.project.versionControl.commitChanges")); + unstageAllButton = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-minus"></i> '+RED._("sidebar.project.versionControl.all")+'</button>') + .appendTo(bg) + .on("click", function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + var toUnstage = Object.keys(allChanges).filter(function(fn) { + return allChanges[fn].indexStatus !== ' ' && allChanges[fn].indexStatus !== '?'; + }); + updateBulk(toUnstage,false); + + }); + RED.popover.tooltip(unstageAllButton,RED._("sidebar.project.versionControl.unstageAllChange")); + + + stagedChangesList = $("<ol>",{style:"position: absolute; top: 30px; bottom: 0; right:0; left:0;"}).appendTo(stagedContent); + stagedChangesList.editableList({ + addButton: false, + scrollOnAdd: false, + addItem: function(row,index,entry) { + createChangeEntry(row,entry,entry.indexStatus,'staged'); + }, + sort: function(A,B) { + return A.file.localeCompare(B.file); + } + }) + + commitBox = $('<div class="red-ui-sidebar-vc-slide-box red-ui-sidebar-vc-slide-box-bottom"></div>').hide().appendTo(localChanges.content); + + var commitMessage = $('<textarea></textarea>').attr("placeholder",RED._("sidebar.project.versionControl.commitPlaceholder")) + .appendTo(commitBox) + .on("change keyup paste",function() { + submitCommitButton.prop('disabled',$(this).val().trim()===""); + }); + var commitToolbar = $('<div class="red-ui-sidebar-vc-slide-box-toolbar button-group">').appendTo(commitBox); + + var cancelCommitButton = $('<button class="red-ui-button">'+RED._("sidebar.project.versionControl.cancelCapital")+'</button>') + .appendTo(commitToolbar) + .on("click", function(evt) { + evt.preventDefault(); + commitMessage.val(""); + unstagedContent.css("height",""); + unmergedContent.css("height",""); + stagedContent.css("height",""); + commitBox.css("height",0); + setTimeout(function() { + commitBox.hide(); + },200); + stageAllButton.prop("disabled",false); + unstageAllButton.prop("disabled",false); + commitButton.prop("disabled",false); + abortMergeButton.prop("disabled",false); + + }) + var submitCommitButton = $('<button class="red-ui-button">'+RED._("sidebar.project.versionControl.commitCapital")+'</button>') + .appendTo(commitToolbar) + .on("click", function(evt) { + evt.preventDefault(); + var spinner = utils.addSpinnerOverlay(submitCommitButton).addClass('red-ui-component-spinner-sidebar'); + var activeProject = RED.projects.getActiveProject(); + RED.deploy.setDeployInflight(true); + utils.sendRequest({ + url: "projects/"+activeProject.name+"/commit", + type: "POST", + responses: { + 0: function(error) { + console.log(error); + }, + 200: function(data) { + spinner.remove(); + cancelCommitButton.trigger("click"); + refresh(true); + }, + 400: { + '*': function(error) { + utils.reportUnexpectedError(error); + } + }, + } + },{ + message:commitMessage.val() + }).always(function() { + setTimeout(function() { + RED.deploy.setDeployInflight(false); + },500); + }) + }) + + + var localHistory = sections.add({ + title: RED._("sidebar.project.versionControl.commitHistory"), + collapsible: true + }); + + bg = $('<div style="float: right"></div>').appendTo(localHistory.header); + refreshButton = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-refresh"></i></button>') + .appendTo(bg) + .on("click", function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + refresh(true,true); + }) + RED.popover.tooltip(refreshButton,RED._("sidebar.project.versionControl.refreshCommitHistory")) + + var localBranchToolbar = $('<div class="red-ui-sidebar-vc-change-header" style="text-align: right;"></div>').appendTo(localHistory.content); + + var localBranchButton = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-code-fork"></i> '+RED._("sidebar.project.versionControl.branch")+' <span id="red-ui-sidebar-vc-local-branch"></span></button>') + .appendTo(localBranchToolbar) + .on("click", function(evt) { + evt.preventDefault(); + if ($(this).hasClass('selected')) { + closeBranchBox(); + } else { + closeRemoteBox(); + localCommitListShade.show(); + $(this).addClass('selected'); + var activeProject = RED.projects.getActiveProject(); + localBranchList.refresh("projects/"+activeProject.name+"/branches"); + localBranchBox.show(); + setTimeout(function() { + localBranchBox.css("height","215px"); + localBranchList.focus(); + },100); + } + }) + RED.popover.tooltip(localBranchButton,RED._("sidebar.project.versionControl.changeLocalBranch")) + var repoStatusButton = $('<button class="red-ui-button red-ui-button-small" style="margin-left: 10px;" id="red-ui-sidebar-vc-repo-status-button">'+ + '<span id="red-ui-sidebar-vc-repo-status-stats">'+ + '<i class="fa fa-long-arrow-up"></i> <span id="red-ui-sidebar-vc-commits-ahead"></span> '+ + '<i class="fa fa-long-arrow-down"></i> <span id="red-ui-sidebar-vc-commits-behind"></span>'+ + '</span>'+ + '<span id="red-ui-sidebar-vc-repo-status-auth-issue">'+ + '<i class="fa fa-warning"></i>'+ + '</span>'+ + '</button>') + .appendTo(localBranchToolbar) + .on("click", function(evt) { + evt.preventDefault(); + if ($(this).hasClass('selected')) { + closeRemoteBox(); + } else { + closeBranchBox(); + localCommitListShade.show(); + $(this).addClass('selected'); + var activeProject = RED.projects.getActiveProject(); + $("#red-ui-sidebar-vc-repo-toolbar-set-upstream-row").toggle(!!activeProject.git.branches.remoteAlt); + remoteBox.show(); + + setTimeout(function() { + remoteBox.css("height","265px"); + },100); + + } + }); + RED.popover.tooltip(repoStatusButton,RED._("sidebar.project.versionControl.manageRemoteBranch")) + + localCommitList = $("<ol>",{style:"position: absolute; top: 30px; bottom: 0px; right:0; left:0;"}).appendTo(localHistory.content); + localCommitListShade = $('<div class="red-ui-shade" style="z-Index: 3"></div>').css('top',"30px").hide().appendTo(localHistory.content); + localCommitList.editableList({ + addButton: false, + scrollOnAdd: false, + addItem: function(row,index,entry) { + row.addClass('red-ui-sidebar-vc-commit-entry'); + if (entry.url) { + row.addClass('red-ui-sidebar-vc-commit-more'); + row.text("+ "+(entry.total-entry.totalKnown)+RED._("sidebar.project.versionControl.moreCommits")); + row.on("click", function(e) { + e.preventDefault(); + getCommits(entry.url,localCommitList,row,entry.limit,entry.before); + }) + } else { + row.on("click", function(e) { + var activeProject = RED.projects.getActiveProject(); + if (activeProject) { + $.getJSON("projects/"+activeProject.name+"/commits/"+entry.sha,function(result) { + result.project = activeProject; + result.parents = entry.parents; + result.oldRev = entry.sha+"~1"; + result.newRev = entry.sha; + result.oldRevTitle = RED._("sidebar.project.versionControl.commitCapital")+" "+entry.sha.substring(0,7)+"~1"; + result.newRevTitle = RED._("sidebar.project.versionControl.commitCapital")+" "+entry.sha.substring(0,7); + result.date = humanizeSinceDate(parseInt(entry.date)); + RED.diff.showCommitDiff(result); + }); + } + }); + var container = $('<div>').appendTo(row); + $('<div class="red-ui-sidebar-vc-commit-subject">').text(entry.subject).appendTo(container); + if (entry.refs) { + var refDiv = $('<div class="red-ui-sidebar-vc-commit-refs">').appendTo(container); + entry.refs.forEach(function(ref) { + var label = ref; + if (/HEAD -> /.test(ref)) { + label = ref.substring(8); + } + $('<span class="red-ui-sidebar-vc-commit-ref">').text(label).appendTo(refDiv); + }); + row.addClass('red-ui-sidebar-vc-commit-head'); + } + $('<div class="red-ui-sidebar-vc-commit-sha">').text(entry.sha.substring(0,7)).appendTo(container); + // $('<div class="red-ui-sidebar-vc-commit-user">').text(entry.author).appendTo(container); + $('<div class="red-ui-sidebar-vc-commit-date">').text(humanizeSinceDate(parseInt(entry.date))).appendTo(container); + } + } + }); + + + var closeBranchBox = function(done) { + localBranchButton.removeClass('selected') + localBranchBox.css("height","0"); + localCommitListShade.hide(); + + setTimeout(function() { + localBranchBox.hide(); + if (done) { done() } + },200); + } + var localBranchBox = $('<div class="red-ui-sidebar-vc-slide-box red-ui-sidebar-vc-slide-box-top" style="top:30px;"></div>').hide().appendTo(localHistory.content); + + $('<div class="red-ui-sidebar-vc-slide-box-header"></div>').text(RED._("sidebar.project.versionControl.changeLocalBranch")).appendTo(localBranchBox); + + var localBranchList = utils.createBranchList({ + placeholder: RED._("sidebar.project.versionControl.createBranchPlaceholder"), + container: localBranchBox, + onselect: function(body) { + if (body.current) { + return closeBranchBox(); + } + var spinner = utils.addSpinnerOverlay(localBranchBox); + var activeProject = RED.projects.getActiveProject(); + RED.deploy.setDeployInflight(true); + utils.sendRequest({ + url: "projects/"+activeProject.name+"/branches", + type: "POST", + requireCleanWorkspace: true, + cancel: function() { + spinner.remove(); + }, + responses: { + 0: function(error) { + spinner.remove(); + console.log(error); + // done(error,null); + }, + 200: function(data) { + // Changing branch will trigger a runtime event + // that leads to a project refresh. + closeBranchBox(function() { + spinner.remove(); + }); + }, + 400: { + 'git_local_overwrite': function(error) { + spinner.remove(); + RED.notify(RED._("sidebar.project.versionControl.localOverwrite"),{ + type:'error', + timeout: 8000 + }); + }, + 'unexpected_error': function(error) { + spinner.remove(); + console.log(error); + // done(error,null); + } + }, + } + },body).always(function(){ + setTimeout(function() { + RED.deploy.setDeployInflight(false); + },500); + }); + } + }); + + var remoteBox = $('<div class="red-ui-sidebar-vc-slide-box red-ui-sidebar-vc-slide-box-top" style="top:30px"></div>').hide().appendTo(localHistory.content); + var closeRemoteBox = function() { + $("#red-ui-sidebar-vc-repo-toolbar-set-upstream").prop('checked',false); + repoStatusButton.removeClass('selected') + remoteBox.css("height","0"); + localCommitListShade.hide(); + setTimeout(function() { + remoteBox.hide(); + closeRemoteBranchBox(); + },200); + } + + var closeRemoteBranchBox = function(done) { + if (remoteBranchButton.hasClass('selected')) { + remoteBranchButton.removeClass('selected'); + remoteBranchSubRow.height(0); + remoteBox.css("height","265px"); + setTimeout(function() { + remoteBranchSubRow.hide(); + if (done) { done(); } + },200); + } + } + $('<div class="red-ui-sidebar-vc-slide-box-header"></div>').text(RED._("sidebar.project.versionControl.manageRemoteBranch")).appendTo(remoteBox); + + var remoteBranchRow = $('<div style="margin-bottom: 5px;"></div>').appendTo(remoteBox); + var remoteBranchButton = $('<button id="red-ui-sidebar-vc-repo-branch" class="red-ui-sidebar-vc-repo-action red-ui-button"><i class="fa fa-code-fork"></i> '+RED._("sidebar.project.versionControl.remote")+': <span id="red-ui-sidebar-vc-remote-branch"></span></button>') + .appendTo(remoteBranchRow) + .on("click", function(evt) { + evt.preventDefault(); + if ($(this).hasClass('selected')) { + closeRemoteBranchBox(); + } else { + $(this).addClass('selected'); + var activeProject = RED.projects.getActiveProject(); + remoteBranchList.refresh("projects/"+activeProject.name+"/branches/remote"); + remoteBranchSubRow.show(); + setTimeout(function() { + remoteBranchSubRow.height(180); + remoteBox.css("height","445px"); + remoteBranchList.focus(); + },100); + } + }); + + $('<div id="red-ui-sidebar-vc-repo-toolbar-message" class="red-ui-sidebar-vc-slide-box-header" style="min-height: 100px;"></div>').appendTo(remoteBox); + + + var errorMessage = $('<div id="red-ui-sidebar-vc-repo-toolbar-error-message" class="red-ui-sidebar-vc-slide-box-header" style="min-height: 100px;"></div>').hide().appendTo(remoteBox); + $('<div style="margin-top: 10px;"><i class="fa fa-warning"></i> '+RED._("sidebar.project.versionControl.unableToAccess")+'</div>').appendTo(errorMessage) + var buttonRow = $('<div style="margin: 10px 30px; text-align: center"></div>').appendTo(errorMessage); + $('<button class="red-ui-button" style="width: 80%;"><i class="fa fa-refresh"></i> '+RED._("sidebar.project.versionControl.retry")+'</button>') + .appendTo(buttonRow) + .on("click", function(e) { + e.preventDefault(); + var activeProject = RED.projects.getActiveProject(); + var spinner = utils.addSpinnerOverlay(remoteBox).addClass("red-ui-component-spinner-contain"); + utils.sendRequest({ + url: "projects/"+activeProject.name+"/branches/remote", + type: "GET", + responses: { + 0: function(error) { + console.log(error); + // done(error,null); + }, + 200: function(data) { + refresh(true); + }, + 400: { + 'git_connection_failed': function(error) { + RED.notify(error.message,'error'); + }, + 'git_not_a_repository': function(error) { + RED.notify(error.message,'error'); + }, + 'git_repository_not_found': function(error) { + RED.notify(error.message,'error'); + }, + 'unexpected_error': function(error) { + console.log(error); + // done(error,null); + } + } + } + }).always(function() { + spinner.remove(); + }); + }) + + $('<div class="red-ui-sidebar-vc-slide-box-header" style="height: 20px;"><label id="red-ui-sidebar-vc-repo-toolbar-set-upstream-row" for="red-ui-sidebar-vc-repo-toolbar-set-upstream" class="hide"><input type="checkbox" id="red-ui-sidebar-vc-repo-toolbar-set-upstream"> '+RED._("sidebar.project.versionControl.setUpstreamBranch")+'</label></div>').appendTo(remoteBox); + + var remoteBranchSubRow = $('<div style="height: 0;overflow:hidden; transition: height 0.2s ease-in-out;"></div>').hide().appendTo(remoteBranchRow); + var remoteBranchList = utils.createBranchList({ + placeholder: RED._("sidebar.project.versionControl.createRemoteBranchPlaceholder"), + currentLabel: RED._("sidebar.project.versionControl.upstream"), + remote: function() { + var project = RED.projects.getActiveProject(); + var remotes = Object.keys(project.git.remotes); + return remotes[0]; + }, + container: remoteBranchSubRow, + onselect: function(body) { + $("#red-ui-sidebar-vc-repo-toolbar-set-upstream").prop('checked',false); + $("#red-ui-sidebar-vc-repo-toolbar-set-upstream").prop('disabled',false); + $("#red-ui-sidebar-vc-remote-branch").text(body.name+(body.create?" *":"")); + var activeProject = RED.projects.getActiveProject(); + if (activeProject.git.branches.remote === body.name) { + delete activeProject.git.branches.remoteAlt; + } else { + activeProject.git.branches.remoteAlt = body.name; + } + $("#red-ui-sidebar-vc-repo-toolbar-set-upstream-row").toggle(!!activeProject.git.branches.remoteAlt); + closeRemoteBranchBox(function() { + if (!body.create) { + var start = Date.now(); + var spinner = utils.addSpinnerOverlay($('#red-ui-sidebar-vc-repo-toolbar-message')).addClass("red-ui-component-spinner-contain"); + $.getJSON("projects/"+activeProject.name+"/branches/remote/"+body.name+"/status", function(result) { + setTimeout(function() { + updateRemoteStatus(result.commits.ahead, result.commits.behind); + spinner.remove(); + },Math.max(400-(Date.now() - start),0)); + }) + } else { + if (!activeProject.git.branches.remote) { + $('#red-ui-sidebar-vc-repo-toolbar-message').text(RED._("sidebar.project.versionControl.trackedUpstreamBranch")); + $("#red-ui-sidebar-vc-repo-toolbar-set-upstream").prop('checked',true); + $("#red-ui-sidebar-vc-repo-toolbar-set-upstream").prop('disabled',true); + } else { + $('#red-ui-sidebar-vc-repo-toolbar-message').text(RED._("sidebar.project.versionControl.selectUpstreamBranch")); + } + $("#red-ui-sidebar-vc-repo-pull").prop('disabled',true); + $("#red-ui-sidebar-vc-repo-push").prop('disabled',false); + } + }); + } + }); + + + var row = $('<div style="margin-bottom: 5px;"></div>').appendTo(remoteBox); + + $('<button id="red-ui-sidebar-vc-repo-push" class="red-ui-sidebar-vc-repo-sub-action red-ui-button"><i class="fa fa-long-arrow-up"></i> <span data-i18n="sidebar.project.versionControl.push"></span></button>') + .appendTo(row) + .on("click", function(e) { + e.preventDefault(); + var spinner = utils.addSpinnerOverlay(remoteBox).addClass("red-ui-component-spinner-contain"); + var buttonRow = $('<div style="position: relative; bottom: 60px;"></div>').appendTo(spinner); + $('<button class="red-ui-button"></button>').text(RED._("eventLog.view")).appendTo(buttonRow).on("click", function(evt) { + evt.preventDefault(); + RED.actions.invoke("core:show-event-log"); + }); + var activeProject = RED.projects.getActiveProject(); + RED.eventLog.startEvent("Push changes"+(activeProject.git.branches.remoteAlt?(" : "+activeProject.git.branches.remoteAlt):"")); + var url = "projects/"+activeProject.name+"/push"; + if (activeProject.git.branches.remoteAlt) { + url+="/"+activeProject.git.branches.remoteAlt; + } + var setUpstream = $("#red-ui-sidebar-vc-repo-toolbar-set-upstream").prop('checked'); + if (setUpstream) { + url+="?u=true" + } + utils.sendRequest({ + url: url, + type: "POST", + responses: { + 0: function(error) { + console.log(error); + // done(error,null); + }, + 200: function(data) { + if (setUpstream && activeProject.git.branches.remoteAlt) { + activeProject.git.branches.remote = activeProject.git.branches.remoteAlt; + delete activeProject.git.branches.remoteAlt; + } + refresh(true); + closeRemoteBox(); + }, + 400: { + 'git_push_failed': function(err) { + // TODO: better message + RED.notify(RED._("sidebar.project.versionControl.pushFailed"),"error"); + }, + 'unexpected_error': function(error) { + console.log(error); + // done(error,null); + } + }, + } + },{}).always(function() { + spinner.remove(); + }); + }); + + var pullRemote = function(options) { + options = options || {}; + var spinner = utils.addSpinnerOverlay(remoteBox).addClass("red-ui-component-spinner-contain"); + var buttonRow = $('<div style="position: relative; bottom: 60px;"></div>').appendTo(spinner); + $('<button class="red-ui-button"></button>').text(RED._("eventLog.view")).appendTo(buttonRow).on("click", function(evt) { + evt.preventDefault(); + RED.actions.invoke("core:show-event-log"); + }); + var activeProject = RED.projects.getActiveProject(); + RED.eventLog.startEvent("Pull changes"+(activeProject.git.branches.remoteAlt?(" : "+activeProject.git.branches.remoteAlt):"")); + var url = "projects/"+activeProject.name+"/pull"; + if (activeProject.git.branches.remoteAlt) { + url+="/"+activeProject.git.branches.remoteAlt; + } + if (options.setUpstream || options.allowUnrelatedHistories) { + url+="?"; + } + if (options.setUpstream) { + url += "setUpstream=true" + if (options.allowUnrelatedHistories) { + url += "&"; + } + } + if (options.allowUnrelatedHistories) { + url += "allowUnrelatedHistories=true" + } + utils.sendRequest({ + url: url, + type: "POST", + responses: { + 0: function(error) { + console.log(error); + // done(error,null); + }, + 200: function(data) { + if (options.setUpstream && activeProject.git.branches.remoteAlt) { + activeProject.git.branches.remote = activeProject.git.branches.remoteAlt; + delete activeProject.git.branches.remoteAlt; + } + refresh(true); + closeRemoteBox(); + }, + 400: { + 'git_local_overwrite': function(err) { + RED.notify(RED._("sidebar.project.versionControl.unablePull")+ + '<p><a href="#" onclick="RED.sidebar.versionControl.showLocalChanges(); return false;">'+RED._("sidebar.project.versionControl.showUnstagedChanges")+'</a></p>',"error",false,10000000); + }, + 'git_pull_merge_conflict': function(err) { + refresh(true); + closeRemoteBox(); + }, + 'git_connection_failed': function(err) { + RED.notify(RED._("sidebar.project.versionControl.connectionFailed")+err.toString(),"warning") + }, + 'git_pull_unrelated_history': function(error) { + var notification = RED.notify(RED._("sidebar.project.versionControl.pullUnrelatedHistory"),{ + type: 'error', + modal: true, + fixed: true, + buttons: [ + { + text: RED._("common.label.cancel"), + click: function() { + notification.close(); + } + },{ + text: RED._("sidebar.project.versionControl.pullChanges"), + click: function() { + notification.close(); + options.allowUnrelatedHistories = true; + pullRemote(options) + } + } + ] + }); + }, + '*': function(error) { + utils.reportUnexpectedError(error); + } + }, + } + },{}).always(function() { + spinner.remove(); + }); + } + $('<button id="red-ui-sidebar-vc-repo-pull" class="red-ui-sidebar-vc-repo-sub-action red-ui-button"><i class="fa fa-long-arrow-down"></i> <span data-i18n="sidebar.project.versionControl.pull"></span></button>') + .appendTo(row) + .on("click", function(e) { + e.preventDefault(); + pullRemote({ + setUpstream: $("#red-ui-sidebar-vc-repo-toolbar-set-upstream").prop('checked') + }); + }); + + $('<div class="red-ui-shade red-ui-sidebar-vc-shade">').appendTo(sidebarContent); + + RED.sidebar.addTab({ + id: "version-control", + label: RED._("sidebar.project.versionControl.history"), + name: RED._("sidebar.project.versionControl.projectHistory"), + content: sidebarContent, + enableOnEdit: false, + pinned: true, + iconClass: "fa fa-code-fork", + action: "core:show-version-control-tab", + onchange: function() { + setTimeout(function() { + sections.resize(); + },10); + } + }); + + } + + function humanizeSinceDate(date) { + var delta = (Date.now()/1000) - date; + + var daysDelta = Math.floor(delta / (60*60*24)); + if (daysDelta > 30) { + return (new Date(date*1000)).toLocaleDateString(); + } else if (daysDelta > 0) { + return RED._("sidebar.project.versionControl.daysAgo", {count:daysDelta}) + } + var hoursDelta = Math.floor(delta / (60*60)); + if (hoursDelta > 0) { + return RED._("sidebar.project.versionControl.hoursAgo", {count:hoursDelta}) + } + var minutesDelta = Math.floor(delta / 60); + if (minutesDelta > 0) { + return RED._("sidebar.project.versionControl.minsAgo", {count:minutesDelta}) + } + return RED._("sidebar.project.versionControl.secondsAgo"); + } + + function updateBulk(files,unstaged) { + var activeProject = RED.projects.getActiveProject(); + if (unstaged) { + bulkChangeSpinner = utils.addSpinnerOverlay(unstagedChangesList.parent()); + } else { + bulkChangeSpinner = utils.addSpinnerOverlay(stagedChangesList.parent()); + } + bulkChangeSpinner.addClass('red-ui-component-spinner-sidebar'); + var body = unstaged?{files:files}:undefined; + utils.sendRequest({ + url: "projects/"+activeProject.name+"/stage", + type: unstaged?"POST":"DELETE", + responses: { + 0: function(error) { + console.log(error); + // done(error,null); + }, + 200: function(data) { + refreshFiles(data); + }, + 400: { + 'unexpected_error': function(error) { + console.log(error); + // done(error,null); + } + }, + } + },body); + } + + var refreshInProgress = false; + + function getCommits(url,targetList,spinnerTarget,limit,before) { + var spinner = utils.addSpinnerOverlay(spinnerTarget); + var fullUrl = url+"?limit="+(limit||20); + if (before) { + fullUrl+="&before="+before; + } + utils.sendRequest({ + url: fullUrl, + type: "GET", + responses: { + 0: function(error) { + console.log(error); + // done(error,null); + }, + 200: function(result) { + var lastSha; + result.commits.forEach(function(c) { + targetList.editableList('addItem',c); + lastSha = c.sha; + }) + if (targetList.loadMoreItem) { + targetList.editableList('removeItem',targetList.loadMoreItem); + delete targetList.loadMoreItem; + } + var totalKnown = targetList.editableList('length'); + if (totalKnown < result.total) { + targetList.loadMoreItem = { + totalKnown: totalKnown, + total: result.total, + url: url, + before: lastSha+"~1", + limit: limit, + }; + targetList.editableList('addItem',targetList.loadMoreItem); + } + spinner.remove(); + }, + 400: { + 'unexpected_error': function(error) { + console.log(error); + // done(error,null); + } + } + } + }); + } + function refreshLocalCommits() { + localCommitList.editableList('empty'); + var activeProject = RED.projects.getActiveProject(); + if (activeProject) { + getCommits("projects/"+activeProject.name+"/commits",localCommitList,localCommitList.parent()); + } + } + // function refreshRemoteCommits() { + // remoteCommitList.editableList('empty'); + // var spinner = utils.addSpinnerOverlay(remoteCommitList); + // var activeProject = RED.projects.getActiveProject(); + // if (activeProject) { + // getCommits("projects/"+activeProject.name+"/commits/origin",remoteCommitList,remoteCommitList.parent()); + // } + // } + + function refreshFiles(result) { + var files = result.files; + if (bulkChangeSpinner) { + bulkChangeSpinner.remove(); + bulkChangeSpinner = null; + } + isMerging = !!result.merging; + if (isMerging) { + sidebarContent.addClass("red-ui-sidebar-vc-merging"); + unmergedContent.show(); + } else { + sidebarContent.removeClass("red-ui-sidebar-vc-merging"); + unmergedContent.hide(); + } + unstagedChangesList.editableList('removeItem',emptyStagedItem); + stagedChangesList.editableList('removeItem',emptyStagedItem); + unmergedChangesList.editableList('removeItem',emptyMergedItem); + + var fileNames = Object.keys(files).filter(function(f) { return files[f].type === 'f'}) + fileNames.sort(); + var updateIndex = Date.now()+Math.floor(Math.random()*100); + fileNames.forEach(function(fn) { + var entry = files[fn]; + var addEntry = false; + if (entry.status) { + entry.file = fn; + entry.indexStatus = entry.status[0]; + entry.treeStatus = entry.status[1]; + if ((entry.indexStatus === 'A' && /[AU]/.test(entry.treeStatus)) || + (entry.indexStatus === 'U' && /[DAU]/.test(entry.treeStatus)) || + (entry.indexStatus === 'D' && /[DU]/.test(entry.treeStatus))) { + entry.unmerged = true; + } + if (allChanges[fn]) { + if (allChanges[fn].unmerged && !entry.unmerged) { + unmergedChangesList.editableList('removeItem', allChanges[fn]) + addEntry = true; + } else if (!allChanges[fn].unmerged && entry.unmerged) { + unstagedChangesList.editableList('removeItem', allChanges[fn]) + stagedChangesList.editableList('removeItem', allChanges[fn]) + } + // Known file + if (allChanges[fn].status !== entry.status) { + // Status changed. + if (allChanges[fn].treeStatus !== ' ') { + // Already in the unstaged list + if (entry.treeStatus === ' ') { + unstagedChangesList.editableList('removeItem', allChanges[fn]) + } else if (entry.treeStatus !== allChanges[fn].treeStatus) { + allChanges[fn].updateUnstaged(entry,entry.treeStatus); + } + } else { + addEntry = true; + } + if (allChanges[fn].indexStatus !== ' ' && allChanges[fn].indexStatus !== '?') { + // Already in the staged list + if (entry.indexStatus === ' '||entry.indexStatus === '?') { + stagedChangesList.editableList('removeItem', allChanges[fn]) + } else if (entry.indexStatus !== allChanges[fn].indexStatus) { + allChanges[fn].updateStaged(entry,entry.indexStatus); + } + } else { + addEntry = true; + } + } + allChanges[fn].status = entry.status; + allChanges[fn].indexStatus = entry.indexStatus; + allChanges[fn].treeStatus = entry.treeStatus; + allChanges[fn].oldName = entry.oldName; + allChanges[fn].unmerged = entry.unmerged; + + } else { + addEntry = true; + allChanges[fn] = entry; + } + allChanges[fn].updateIndex = updateIndex; + if (addEntry) { + if (entry.unmerged) { + unmergedChangesList.editableList('addItem', allChanges[fn]); + } else { + if (entry.treeStatus !== ' ') { + unstagedChangesList.editableList('addItem', allChanges[fn]) + } + if (entry.indexStatus !== ' ' && entry.indexStatus !== '?') { + stagedChangesList.editableList('addItem', allChanges[fn]) + } + } + } + } + }); + Object.keys(allChanges).forEach(function(fn) { + if (allChanges[fn].updateIndex !== updateIndex) { + unstagedChangesList.editableList('removeItem', allChanges[fn]); + stagedChangesList.editableList('removeItem', allChanges[fn]); + delete allChanges[fn]; + } + }); + + var stagedCount = stagedChangesList.editableList('length'); + var unstagedCount = unstagedChangesList.editableList('length'); + var unmergedCount = unmergedChangesList.editableList('length'); + + commitButton.prop('disabled',(isMerging && unmergedCount > 0)||(!isMerging && stagedCount === 0)); + stageAllButton.prop('disabled',unstagedCount === 0); + unstageAllButton.prop('disabled',stagedCount === 0); + + if (stagedCount === 0) { + stagedChangesList.editableList('addItem',emptyStagedItem); + } + if (unstagedCount === 0) { + unstagedChangesList.editableList('addItem',emptyStagedItem); + } + if (unmergedCount === 0) { + unmergedChangesList.editableList('addItem',emptyMergedItem); + } + } + + function refresh(full, includeRemote) { + if (refreshInProgress) { + return; + } + if (full) { + allChanges = {}; + unstagedChangesList.editableList('empty'); + stagedChangesList.editableList('empty'); + unmergedChangesList.editableList('empty'); + } + if (!RED.user.hasPermission("projects.write")) { + return; + } + + + refreshInProgress = true; + refreshLocalCommits(); + + var activeProject = RED.projects.getActiveProject(); + if (activeProject) { + var url = "projects/"+activeProject.name+"/status"; + if (includeRemote) { + url += "?remote=true" + } + $.getJSON(url,function(result) { + refreshFiles(result); + + $('#red-ui-sidebar-vc-local-branch').text(result.branches.local); + $('#red-ui-sidebar-vc-remote-branch').text(result.branches.remote||RED._("sidebar.project.versionControl.none")); + + var commitsAhead = result.commits.ahead || 0; + var commitsBehind = result.commits.behind || 0; + + if (activeProject.git.hasOwnProperty('remotes')) { + if (result.branches.hasOwnProperty("remoteError") && result.branches.remoteError.code !== 'git_remote_gone') { + $("#red-ui-sidebar-vc-repo-status-auth-issue").show(); + $("#red-ui-sidebar-vc-repo-status-stats").hide(); + $('#red-ui-sidebar-vc-repo-branch').prop('disabled',true); + $("#red-ui-sidebar-vc-repo-pull").prop('disabled',true); + $("#red-ui-sidebar-vc-repo-push").prop('disabled',true); + $('#red-ui-sidebar-vc-repo-toolbar-message').hide(); + $('#red-ui-sidebar-vc-repo-toolbar-error-message').show(); + } else { + $('#red-ui-sidebar-vc-repo-toolbar-message').show(); + $('#red-ui-sidebar-vc-repo-toolbar-error-message').hide(); + + $("#red-ui-sidebar-vc-repo-status-auth-issue").hide(); + $("#red-ui-sidebar-vc-repo-status-stats").show(); + + $('#red-ui-sidebar-vc-repo-branch').prop('disabled',false); + + $("#red-ui-sidebar-vc-repo-status-button").show(); + if (result.branches.hasOwnProperty('remote')) { + updateRemoteStatus(commitsAhead, commitsBehind); + } else { + $('#red-ui-sidebar-vc-commits-ahead').text(""); + $('#red-ui-sidebar-vc-commits-behind').text(""); + + $('#red-ui-sidebar-vc-repo-toolbar-message').text(RED._("sidebar.project.versionControl.notTracking")); + $("#red-ui-sidebar-vc-repo-pull").prop('disabled',true); + $("#red-ui-sidebar-vc-repo-push").prop('disabled',true); + } + } + } else { + $("#red-ui-sidebar-vc-repo-status-button").hide(); + } + refreshInProgress = false; + $('.red-ui-sidebar-vc-shade').hide(); + }).fail(function() { + refreshInProgress = false; + }); + } else { + $('.red-ui-sidebar-vc-shade').show(); + unstagedChangesList.editableList('empty'); + stagedChangesList.editableList('empty'); + unmergedChangesList.editableList('empty'); + } + } + + + function updateRemoteStatus(commitsAhead, commitsBehind) { + $('#red-ui-sidebar-vc-commits-ahead').text(commitsAhead); + $('#red-ui-sidebar-vc-commits-behind').text(commitsBehind); + if (isMerging) { + $('#red-ui-sidebar-vc-repo-toolbar-message').text(RED._("sidebar.project.versionControl.statusUnmergedChanged")); + $("#red-ui-sidebar-vc-repo-pull").prop('disabled',true); + $("#red-ui-sidebar-vc-repo-push").prop('disabled',true); + } else if (commitsAhead > 0 && commitsBehind === 0) { + $('#red-ui-sidebar-vc-repo-toolbar-message').text(RED._("sidebar.project.versionControl.commitsAhead", {count:commitsAhead})); + $("#red-ui-sidebar-vc-repo-pull").prop('disabled',true); + $("#red-ui-sidebar-vc-repo-push").prop('disabled',false); + } else if (commitsAhead === 0 && commitsBehind > 0) { + $('#red-ui-sidebar-vc-repo-toolbar-message').text(RED._("sidebar.project.versionControl.commitsBehind",{ count: commitsBehind })); + $("#red-ui-sidebar-vc-repo-pull").prop('disabled',false); + $("#red-ui-sidebar-vc-repo-push").prop('disabled',true); + } else if (commitsAhead > 0 && commitsBehind > 0) { + $('#red-ui-sidebar-vc-repo-toolbar-message').text( + RED._("sidebar.project.versionControl.commitsAheadAndBehind1",{ count:commitsBehind })+ + RED._("sidebar.project.versionControl.commitsAheadAndBehind2",{ count:commitsAhead })+ + RED._("sidebar.project.versionControl.commitsAheadAndBehind3",{ count:commitsBehind })); + $("#red-ui-sidebar-vc-repo-pull").prop('disabled',false); + $("#red-ui-sidebar-vc-repo-push").prop('disabled',true); + } else if (commitsAhead === 0 && commitsBehind === 0) { + $('#red-ui-sidebar-vc-repo-toolbar-message').text(RED._("sidebar.project.versionControl.repositoryUpToDate")); + $("#red-ui-sidebar-vc-repo-pull").prop('disabled',true); + $("#red-ui-sidebar-vc-repo-push").prop('disabled',true); + } + } + function show() { + refresh(); + RED.sidebar.show("version-control"); + } + function showLocalChanges() { + RED.sidebar.show("version-control"); + localChanges.expand(); + } + return { + init: init, + show: show, + refresh: refresh, + showLocalChanges: showLocalChanges + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/search.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/search.js new file mode 100644 index 0000000..9bb4cef --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/search.js @@ -0,0 +1,369 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.search = (function() { + + var disabled = false; + var dialog = null; + var searchInput; + var searchResults; + var selected = -1; + var visible = false; + + var index = {}; + var keys = []; + var results = []; + var previousActiveElement; + + + function indexProperty(node,label,property) { + if (typeof property === 'string' || typeof property === 'number') { + property = (""+property).toLowerCase(); + index[property] = index[property] || {}; + index[property][node.id] = {node:node,label:label}; + } else if (Array.isArray(property)) { + property.forEach(function(prop) { + indexProperty(node,label,prop); + }) + } else if (typeof property === 'object') { + for (var prop in property) { + if (property.hasOwnProperty(prop)) { + indexProperty(node,label,property[prop]) + } + } + } + } + function indexNode(n) { + var l = RED.utils.getNodeLabel(n); + if (l) { + l = (""+l).toLowerCase(); + index[l] = index[l] || {}; + index[l][n.id] = {node:n,label:l} + } + l = l||n.label||n.name||n.id||""; + + + var properties = ['id','type','name','label','info']; + if (n._def && n._def.defaults) { + properties = properties.concat(Object.keys(n._def.defaults)); + } + for (var i=0;i<properties.length;i++) { + if (n.hasOwnProperty(properties[i])) { + indexProperty(n, l, n[properties[i]]); + } + } + } + + function indexWorkspace() { + index = {}; + RED.nodes.eachWorkspace(indexNode); + RED.nodes.eachSubflow(indexNode); + RED.nodes.eachConfig(indexNode); + RED.nodes.eachNode(indexNode); + keys = Object.keys(index); + keys.sort(); + keys.forEach(function(key) { + index[key] = Object.keys(index[key]).map(function(id) { + return index[key][id]; + }) + }) + } + + function search(val) { + searchResults.editableList('empty'); + var typeFilter; + var m = /(?:^| )type:([^ ]+)/.exec(val); + if (m) { + val = val.replace(/(?:^| )type:[^ ]+/,""); + typeFilter = m[1]; + } + + val = val.trim(); + + selected = -1; + results = []; + if (val.length > 0 || typeFilter) { + val = val.toLowerCase(); + var i; + var j; + var list = []; + var nodes = {}; + for (i=0;i<keys.length;i++) { + var key = keys[i]; + var kpos = keys[i].indexOf(val); + if (kpos > -1) { + for (j=0;j<index[key].length;j++) { + var node = index[key][j]; + if (!typeFilter || node.node.type === typeFilter) { + nodes[node.node.id] = nodes[node.node.id] = node; + nodes[node.node.id].index = Math.min(nodes[node.node.id].index||Infinity,kpos); + } + } + } + } + list = Object.keys(nodes); + list.sort(function(A,B) { + return nodes[A].index - nodes[B].index; + }); + + for (i=0;i<list.length;i++) { + results.push(nodes[list[i]]); + } + if (results.length > 0) { + for (i=0;i<Math.min(results.length,25);i++) { + searchResults.editableList('addItem',results[i]) + } + if (results.length > 25) { + searchResults.editableList('addItem', { + more: { + results: results, + start: 25 + } + }) + } + } else { + searchResults.editableList('addItem',{}); + } + } + } + + function ensureSelectedIsVisible() { + var selectedEntry = searchResults.find("li.selected"); + if (selectedEntry.length === 1) { + var scrollWindow = searchResults.parent(); + var scrollHeight = scrollWindow.height(); + var scrollOffset = scrollWindow.scrollTop(); + var y = selectedEntry.position().top; + var h = selectedEntry.height(); + if (y+h > scrollHeight) { + scrollWindow.animate({scrollTop: '-='+(scrollHeight-(y+h)-10)},50); + } else if (y<0) { + scrollWindow.animate({scrollTop: '+='+(y-10)},50); + } + } + } + + function createDialog() { + dialog = $("<div>",{id:"red-ui-search",class:"red-ui-search"}).appendTo("#red-ui-main-container"); + var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(dialog); + searchInput = $('<input type="text" data-i18n="[placeholder]menu.label.searchInput">').appendTo(searchDiv).searchBox({ + delay: 200, + change: function() { + search($(this).val()); + } + }); + + searchInput.on('keydown',function(evt) { + var children; + if (results.length > 0) { + if (evt.keyCode === 40) { + // Down + children = searchResults.children(); + if (selected < children.length-1) { + if (selected > -1) { + $(children[selected]).removeClass('selected'); + } + selected++; + } + $(children[selected]).addClass('selected'); + ensureSelectedIsVisible(); + evt.preventDefault(); + } else if (evt.keyCode === 38) { + // Up + children = searchResults.children(); + if (selected > 0) { + if (selected < children.length) { + $(children[selected]).removeClass('selected'); + } + selected--; + } + $(children[selected]).addClass('selected'); + ensureSelectedIsVisible(); + evt.preventDefault(); + } else if (evt.keyCode === 13) { + // Enter + children = searchResults.children(); + if ($(children[selected]).hasClass("red-ui-search-more")) { + var object = $(children[selected]).find(".red-ui-editableList-item-content").data('data'); + if (object) { + searchResults.editableList('removeItem',object); + for (i=object.more.start;i<Math.min(results.length,object.more.start+25);i++) { + searchResults.editableList('addItem',results[i]) + } + if (results.length > object.more.start+25) { + searchResults.editableList('addItem', { + more: { + results: results, + start: object.more.start+25 + } + }) + } + } + } else { + if (results.length > 0) { + reveal(results[Math.max(0,selected)].node); + } + } + } + } + }); + searchInput.i18n(); + + var searchResultsDiv = $("<div>",{class:"red-ui-search-results-container"}).appendTo(dialog); + searchResults = $('<ol>',{style:"position: absolute;top: 5px;bottom: 5px;left: 5px;right: 5px;"}).appendTo(searchResultsDiv).editableList({ + addButton: false, + addItem: function(container,i,object) { + var node = object.node; + var div; + if (object.more) { + container.parent().addClass("red-ui-search-more") + div = $('<a>',{href:'#',class:"red-ui-search-result red-ui-search-empty"}).appendTo(container); + div.text(RED._("palette.editor.more",{count:object.more.results.length-object.more.start})); + div.on("click", function(evt) { + evt.preventDefault(); + searchResults.editableList('removeItem',object); + for (i=object.more.start;i<Math.min(results.length,object.more.start+25);i++) { + searchResults.editableList('addItem',results[i]) + } + if (results.length > object.more.start+25) { + searchResults.editableList('addItem', { + more: { + results: results, + start: object.more.start+25 + } + }) + } + }); + + } else if (node === undefined) { + $('<div>',{class:"red-ui-search-empty"}).text(RED._('search.empty')).appendTo(container); + } else { + var def = node._def; + div = $('<a>',{href:'#',class:"red-ui-search-result"}).appendTo(container); + + var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(div); + var colour = RED.utils.getNodeColor(node.type,def); + var icon_url = RED.utils.getNodeIcon(def,node); + if (node.type === 'tab') { + colour = "#C0DEED"; + } + nodeDiv.css('backgroundColor',colour); + + var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv); + RED.utils.createIconElement(icon_url, iconContainer, true); + + var contentDiv = $('<div>',{class:"red-ui-search-result-node-description"}).appendTo(div); + if (node.z) { + var workspace = RED.nodes.workspace(node.z); + if (!workspace) { + workspace = RED.nodes.subflow(node.z); + workspace = "subflow:"+workspace.name; + } else { + workspace = "flow:"+workspace.label; + } + $('<div>',{class:"red-ui-search-result-node-flow"}).text(workspace).appendTo(contentDiv); + } + + $('<div>',{class:"red-ui-search-result-node-label"}).text(object.label || node.id).appendTo(contentDiv); + $('<div>',{class:"red-ui-search-result-node-type"}).text(node.type).appendTo(contentDiv); + $('<div>',{class:"red-ui-search-result-node-id"}).text(node.id).appendTo(contentDiv); + + div.on("click", function(evt) { + evt.preventDefault(); + reveal(node); + }); + } + }, + scrollOnAdd: false + }); + + } + + function reveal(node) { + hide(); + RED.view.reveal(node.id); + } + + function show(v) { + if (disabled) { + return; + } + if (!visible) { + previousActiveElement = document.activeElement; + RED.keyboard.add("*","escape",function(){hide()}); + $("#red-ui-header-shade").show(); + $("#red-ui-editor-shade").show(); + $("#red-ui-palette-shade").show(); + $("#red-ui-sidebar-shade").show(); + $("#red-ui-sidebar-separator").hide(); + indexWorkspace(); + if (dialog === null) { + createDialog(); + } + dialog.slideDown(300); + searchInput.searchBox('value',v) + RED.events.emit("search:open"); + visible = true; + } + searchInput.trigger("focus"); + } + + function hide() { + if (visible) { + RED.keyboard.remove("escape"); + visible = false; + $("#red-ui-header-shade").hide(); + $("#red-ui-editor-shade").hide(); + $("#red-ui-palette-shade").hide(); + $("#red-ui-sidebar-shade").hide(); + $("#red-ui-sidebar-separator").show(); + if (dialog !== null) { + dialog.slideUp(200,function() { + searchInput.searchBox('value',''); + }); + } + RED.events.emit("search:close"); + if (previousActiveElement) { + $(previousActiveElement).trigger("focus"); + previousActiveElement = null; + } + } + } + + function init() { + RED.actions.add("core:search",show); + + RED.events.on("editor:open",function() { disabled = true; }); + RED.events.on("editor:close",function() { disabled = false; }); + RED.events.on("type-search:open",function() { disabled = true; }); + RED.events.on("type-search:close",function() { disabled = false; }); + RED.events.on("actionList:open",function() { disabled = true; }); + RED.events.on("actionList:close",function() { disabled = false; }); + + + + $("#red-ui-header-shade").on('mousedown',hide); + $("#red-ui-editor-shade").on('mousedown',hide); + $("#red-ui-palette-shade").on('mousedown',hide); + $("#red-ui-sidebar-shade").on('mousedown',hide); + } + + return { + init: init, + show: show, + hide: hide + }; + +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/sidebar.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/sidebar.js new file mode 100644 index 0000000..9e89add --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/sidebar.js @@ -0,0 +1,268 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.sidebar = (function() { + + //$('#sidebar').tabs(); + var sidebar_tabs; + var knownTabs = {}; + + function addTab(title,content,closeable,visible) { + var options; + if (typeof title === "string") { + // TODO: legacy support in case anyone uses this... + options = { + id: content.id, + label: title, + name: title, + content: content, + closeable: closeable, + visible: visible + } + } else if (typeof title === "object") { + options = title; + } + + delete options.closeable; + + options.wrapper = $('<div>',{style:"height:100%"}).appendTo("#red-ui-sidebar-content") + options.wrapper.append(options.content); + options.wrapper.hide(); + + if (!options.enableOnEdit) { + options.shade = $('<div>',{class:"red-ui-sidebar-shade hide"}).appendTo(options.wrapper); + } + + if (options.toolbar) { + $("#red-ui-sidebar-footer").append(options.toolbar); + $(options.toolbar).hide(); + } + var id = options.id; + + RED.menu.addItem("menu-item-view-menu",{ + id:"menu-item-view-menu-"+options.id, + label:options.name, + onselect:function() { + showSidebar(options.id); + }, + group: "sidebar-tabs" + }); + + options.iconClass = options.iconClass || "fa fa-square-o" + + knownTabs[options.id] = options; + + if (options.visible !== false) { + sidebar_tabs.addTab(knownTabs[options.id]); + } + } + + function removeTab(id) { + sidebar_tabs.removeTab(id); + $(knownTabs[id].wrapper).remove(); + if (knownTabs[id].footer) { + knownTabs[id].footer.remove(); + } + delete knownTabs[id]; + RED.menu.removeItem("menu-item-view-menu-"+id); + } + + var sidebarSeparator = {}; + sidebarSeparator.dragging = false; + + function setupSidebarSeparator() { + $("#red-ui-sidebar-separator").draggable({ + axis: "x", + start:function(event,ui) { + sidebarSeparator.closing = false; + sidebarSeparator.opening = false; + var winWidth = $("#red-ui-editor").width(); + sidebarSeparator.start = ui.position.left; + sidebarSeparator.chartWidth = $("#red-ui-workspace").width(); + sidebarSeparator.chartRight = winWidth-$("#red-ui-workspace").width()-$("#red-ui-workspace").offset().left-2; + sidebarSeparator.dragging = true; + + if (!RED.menu.isSelected("menu-item-sidebar")) { + sidebarSeparator.opening = true; + var newChartRight = 7; + $("#red-ui-sidebar").addClass("closing"); + $("#red-ui-workspace").css("right",newChartRight); + $("#red-ui-editor-stack").css("right",newChartRight+1); + $("#red-ui-sidebar").width(0); + RED.menu.setSelected("menu-item-sidebar",true); + RED.events.emit("sidebar:resize"); + } + sidebarSeparator.width = $("#red-ui-sidebar").width(); + }, + drag: function(event,ui) { + var d = ui.position.left-sidebarSeparator.start; + var newSidebarWidth = sidebarSeparator.width-d; + if (sidebarSeparator.opening) { + newSidebarWidth -= 3; + } + + if (newSidebarWidth > 150) { + if (sidebarSeparator.chartWidth+d < 200) { + ui.position.left = 200+sidebarSeparator.start-sidebarSeparator.chartWidth; + d = ui.position.left-sidebarSeparator.start; + newSidebarWidth = sidebarSeparator.width-d; + } + } + + if (newSidebarWidth < 150) { + if (!sidebarSeparator.closing) { + $("#red-ui-sidebar").addClass("closing"); + sidebarSeparator.closing = true; + } + if (!sidebarSeparator.opening) { + newSidebarWidth = 150; + ui.position.left = sidebarSeparator.width-(150 - sidebarSeparator.start); + d = ui.position.left-sidebarSeparator.start; + } + } else if (newSidebarWidth > 150 && (sidebarSeparator.closing || sidebarSeparator.opening)) { + sidebarSeparator.closing = false; + $("#red-ui-sidebar").removeClass("closing"); + } + + var newChartRight = sidebarSeparator.chartRight-d; + $("#red-ui-workspace").css("right",newChartRight); + $("#red-ui-editor-stack").css("right",newChartRight+1); + $("#red-ui-sidebar").width(newSidebarWidth); + + sidebar_tabs.resize(); + RED.events.emit("sidebar:resize"); + }, + stop:function(event,ui) { + sidebarSeparator.dragging = false; + if (sidebarSeparator.closing) { + $("#red-ui-sidebar").removeClass("closing"); + RED.menu.setSelected("menu-item-sidebar",false); + if ($("#red-ui-sidebar").width() < 180) { + $("#red-ui-sidebar").width(180); + $("#red-ui-workspace").css("right",187); + $("#red-ui-editor-stack").css("right",188); + } + } + $("#red-ui-sidebar-separator").css("left","auto"); + $("#red-ui-sidebar-separator").css("right",($("#red-ui-sidebar").width()+2)+"px"); + RED.events.emit("sidebar:resize"); + } + }); + + var sidebarControls = $('<div class="red-ui-sidebar-control-right"><i class="fa fa-chevron-right"</div>').appendTo($("#red-ui-sidebar-separator")); + sidebarControls.on("click", function() { + sidebarControls.hide(); + RED.menu.toggleSelected("menu-item-sidebar"); + }) + $("#red-ui-sidebar-separator").on("mouseenter", function() { + if (!sidebarSeparator.dragging) { + if (RED.menu.isSelected("menu-item-sidebar")) { + sidebarControls.find("i").addClass("fa-chevron-right").removeClass("fa-chevron-left"); + } else { + sidebarControls.find("i").removeClass("fa-chevron-right").addClass("fa-chevron-left"); + } + sidebarControls.toggle("slide", { direction: "right" }, 200); + } + }) + $("#red-ui-sidebar-separator").on("mouseleave", function() { + if (!sidebarSeparator.dragging) { + sidebarControls.stop(false,true); + sidebarControls.hide(); + } + }); + } + + function toggleSidebar(state) { + if (!state) { + $("#red-ui-main-container").addClass("red-ui-sidebar-closed"); + } else { + $("#red-ui-main-container").removeClass("red-ui-sidebar-closed"); + sidebar_tabs.resize(); + } + RED.events.emit("sidebar:resize"); + } + + function showSidebar(id) { + if (id) { + if (!containsTab(id)) { + sidebar_tabs.addTab(knownTabs[id]); + } + sidebar_tabs.activateTab(id); + if (!RED.menu.isSelected("menu-item-sidebar")) { + RED.menu.setSelected("menu-item-sidebar",true); + } + } + } + + function containsTab(id) { + return sidebar_tabs.contains(id); + } + + function init () { + setupSidebarSeparator(); + sidebar_tabs = RED.tabs.create({ + element: $('<ul id="red-ui-sidebar-tabs"></ul>').appendTo("#red-ui-sidebar"), + onchange:function(tab) { + $("#red-ui-sidebar-content").children().hide(); + $("#red-ui-sidebar-footer").children().hide(); + if (tab.onchange) { + tab.onchange.call(tab); + } + $(tab.wrapper).show(); + if (tab.toolbar) { + $(tab.toolbar).show(); + } + }, + onremove: function(tab) { + $(tab.wrapper).hide(); + if (tab.onremove) { + tab.onremove.call(tab); + } + }, + // minimumActiveTabWidth: 70, + collapsible: true + // scrollable: true + }); + + $('<div id="red-ui-sidebar-content"></div>').appendTo("#red-ui-sidebar"); + $('<div id="red-ui-sidebar-footer" class="red-ui-component-footer"></div>').appendTo("#red-ui-sidebar"); + $('<div id="red-ui-sidebar-shade" class="hide"></div>').appendTo("#red-ui-sidebar"); + + RED.actions.add("core:toggle-sidebar",function(state){ + if (state === undefined) { + RED.menu.toggleSelected("menu-item-sidebar"); + } else { + toggleSidebar(state); + } + }); + RED.popover.tooltip($("#red-ui-sidebar-separator").find(".red-ui-sidebar-control-right"),RED._("keyboard.toggleSidebar"),"core:toggle-sidebar"); + showSidebar(); + RED.sidebar.info.init(); + RED.sidebar.config.init(); + RED.sidebar.context.init(); + // hide info bar at start if screen rather narrow... + if ($("#red-ui-editor").width() < 600) { RED.menu.setSelected("menu-item-sidebar",false); } + } + + return { + init: init, + addTab: addTab, + removeTab: removeTab, + show: showSidebar, + containsTab: containsTab, + toggleSidebar: toggleSidebar, + } + +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/state.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/state.js new file mode 100644 index 0000000..1631ba8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/state.js @@ -0,0 +1,29 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.state = { + DEFAULT: 0, + MOVING: 1, + JOINING: 2, + MOVING_ACTIVE: 3, + ADDING: 4, + EDITING: 5, + EXPORT: 6, + IMPORT: 7, + IMPORT_DRAGGING: 8, + QUICK_JOINING: 9, + PANNING: 10, + SELECTING_NODE: 11 +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/statusBar.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/statusBar.js new file mode 100644 index 0000000..4c91562 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/statusBar.js @@ -0,0 +1,50 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + /*! + RED.statusBar.add({ + id: "widget-identifier", + align: "left|right", + element: widgetElement + }) +*/ + +RED.statusBar = (function() { + + var widgets = {}; + var leftBucket; + var rightBucket; + + function addWidget(options) { + widgets[options.id] = options; + var el = $('<span class="red-ui-statusbar-widget"></span>'); + options.element.appendTo(el); + if (options.align === 'left') { + leftBucket.append(el); + } else if (options.align === 'right') { + rightBucket.prepend(el); + } + } + + return { + init: function() { + leftBucket = $('<span class="red-ui-statusbar-bucket red-ui-statusbar-bucket-left">').appendTo("#red-ui-workspace-footer"); + rightBucket = $('<span class="red-ui-statusbar-bucket red-ui-statusbar-bucket-right">').appendTo("#red-ui-workspace-footer"); + }, + add: addWidget + } + +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js new file mode 100644 index 0000000..9f1e7f3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js @@ -0,0 +1,1737 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +RED.subflow = (function() { + + var currentLocale = "en-US"; + + var _subflowEditTemplate = '<script type="text/x-red" data-template-name="subflow">'+ + '<div class="form-row">'+ + '<label for="node-input-name" data-i18n="[append]editor:common.label.name"><i class="fa fa-tag"></i> </label>'+ + '<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">'+ + '</div>'+ + '<div id="subflow-input-ui"></div>'+ + '</script>'; + + var _subflowTemplateEditTemplate = '<script type="text/x-red" data-template-name="subflow-template">'+ + '<div class="form-row">'+ + '<label for="subflow-input-name" data-i18n="[append]common.label.name"><i class="fa fa-tag"></i> </label>'+ + '<input type="text" id="subflow-input-name" data-i18n="[placeholder]common.label.name">'+ + '</div>'+ + '<div class="form-row">'+ + '<ul style="margin-bottom: 20px;" id="subflow-env-tabs"></ul>'+ + '</div>'+ + '<div id="subflow-env-tabs-content">'+ + '<div id="subflow-env-tab-edit">'+ + '<div class="form-row node-input-env-container-row" id="subflow-input-edit-ui">'+ + '<ol class="red-ui-editor-subflow-env-list" id="node-input-env-container"></ol>'+ + '<div class="node-input-env-locales-row"><i class="fa fa-language"></i> <select id="subflow-input-env-locale"></select></div>'+ + '</div>'+ + '</div>'+ + '<div id="subflow-env-tab-preview">'+ + '<div id="subflow-input-ui"/>'+ + '</div>'+ + '</div>'+ + '</script>'; + + function findAvailableSubflowIOPosition(subflow,isInput) { + var pos = {x:50,y:30}; + if (!isInput) { + pos.x += 110; + } + var ports = [].concat(subflow.out).concat(subflow.in); + if (subflow.status) { + ports.push(subflow.status); + } + ports.sort(function(A,B) { + return A.x-B.x; + }); + for (var i=0; i<ports.length; i++) { + var port = ports[i]; + if (port.x == pos.x && port.y == pos.y) { + pos.x += 55; + } + } + return pos; + } + + function addSubflowInput() { + var subflow = RED.nodes.subflow(RED.workspaces.active()); + if (subflow.in.length === 1) { + return; + } + var position = findAvailableSubflowIOPosition(subflow,true); + var newInput = { + type:"subflow", + direction:"in", + z:subflow.id, + i:subflow.in.length, + x:position.x, + y:position.y, + id:RED.nodes.id() + }; + var oldInCount = subflow.in.length; + subflow.in.push(newInput); + subflow.dirty = true; + var wasDirty = RED.nodes.dirty(); + var wasChanged = subflow.changed; + subflow.changed = true; + var result = refresh(true); + var historyEvent = { + t:'edit', + node:subflow, + dirty:wasDirty, + changed:wasChanged, + subflow: { + inputCount: oldInCount, + instances: result.instances + } + }; + RED.history.push(historyEvent); + RED.view.select(); + RED.nodes.dirty(true); + RED.view.redraw(); + $("#red-ui-subflow-input-add").addClass("active"); + $("#red-ui-subflow-input-remove").removeClass("active"); + RED.palette.refresh(); + } + + function removeSubflowInput() { + var activeSubflow = RED.nodes.subflow(RED.workspaces.active()); + if (activeSubflow.in.length === 0) { + return; + } + var removedInput = activeSubflow.in[0]; + var removedInputLinks = []; + RED.nodes.eachLink(function(l) { + if (l.source.type == "subflow" && l.source.z == activeSubflow.id && l.source.i == removedInput.i) { + removedInputLinks.push(l); + } else if (l.target.type == "subflow:"+activeSubflow.id) { + removedInputLinks.push(l); + } + }); + removedInputLinks.forEach(function(l) { RED.nodes.removeLink(l)}); + activeSubflow.in = []; + $("#red-ui-subflow-input-add").removeClass("active"); + $("#red-ui-subflow-input-remove").addClass("active"); + activeSubflow.changed = true; + RED.palette.refresh(); + return {subflowInputs: [ removedInput ], links:removedInputLinks}; + } + + function addSubflowOutput(id) { + var subflow = RED.nodes.subflow(RED.workspaces.active()); + var position = findAvailableSubflowIOPosition(subflow,false); + + var newOutput = { + type:"subflow", + direction:"out", + z:subflow.id, + i:subflow.out.length, + x:position.x, + y:position.y, + id:RED.nodes.id() + }; + var oldOutCount = subflow.out.length; + subflow.out.push(newOutput); + subflow.dirty = true; + var wasDirty = RED.nodes.dirty(); + var wasChanged = subflow.changed; + subflow.changed = true; + + var result = refresh(true); + + var historyEvent = { + t:'edit', + node:subflow, + dirty:wasDirty, + changed:wasChanged, + subflow: { + outputCount: oldOutCount, + instances: result.instances + } + }; + RED.history.push(historyEvent); + RED.view.select(); + RED.nodes.dirty(true); + RED.view.redraw(); + $("#red-ui-subflow-output .spinner-value").text(subflow.out.length); + RED.palette.refresh(); + } + + function removeSubflowOutput(removedSubflowOutputs) { + var activeSubflow = RED.nodes.subflow(RED.workspaces.active()); + if (activeSubflow.out.length === 0) { + return; + } + if (typeof removedSubflowOutputs === "undefined") { + removedSubflowOutputs = [activeSubflow.out[activeSubflow.out.length-1]]; + } + var removedLinks = []; + removedSubflowOutputs.sort(function(a,b) { return b.i-a.i}); + for (i=0;i<removedSubflowOutputs.length;i++) { + var output = removedSubflowOutputs[i]; + activeSubflow.out.splice(output.i,1); + var subflowRemovedLinks = []; + var subflowMovedLinks = []; + RED.nodes.eachLink(function(l) { + if (l.target.type == "subflow" && l.target.z == activeSubflow.id && l.target.i == output.i) { + subflowRemovedLinks.push(l); + } + if (l.source.type == "subflow:"+activeSubflow.id) { + if (l.sourcePort == output.i) { + subflowRemovedLinks.push(l); + } else if (l.sourcePort > output.i) { + subflowMovedLinks.push(l); + } + } + }); + subflowRemovedLinks.forEach(function(l) { RED.nodes.removeLink(l)}); + subflowMovedLinks.forEach(function(l) { l.sourcePort--; }); + + removedLinks = removedLinks.concat(subflowRemovedLinks); + for (var j=output.i;j<activeSubflow.out.length;j++) { + activeSubflow.out[j].i--; + activeSubflow.out[j].dirty = true; + } + } + activeSubflow.changed = true; + RED.palette.refresh(); + return {subflowOutputs: removedSubflowOutputs, links: removedLinks} + } + + function addSubflowStatus() { + var subflow = RED.nodes.subflow(RED.workspaces.active()); + if (subflow.status) { + return; + } + var position = findAvailableSubflowIOPosition(subflow,false); + var statusNode = { + type:"subflow", + direction:"status", + z:subflow.id, + x:position.x, + y:position.y, + id:RED.nodes.id() + }; + subflow.status = statusNode; + subflow.dirty = true; + var wasDirty = RED.nodes.dirty(); + var wasChanged = subflow.changed; + subflow.changed = true; + var result = refresh(true); + var historyEvent = { + t:'edit', + node:subflow, + dirty:wasDirty, + changed:wasChanged, + subflow: { status: true } + }; + RED.history.push(historyEvent); + RED.view.select(); + RED.nodes.dirty(true); + RED.view.redraw(); + $("#red-ui-subflow-status").prop("checked",!!subflow.status); + $("#red-ui-subflow-status").parent().parent().toggleClass("active",!!subflow.status); + } + + function removeSubflowStatus() { + var subflow = RED.nodes.subflow(RED.workspaces.active()); + if (!subflow.status) { + return; + } + var subflowRemovedLinks = []; + RED.nodes.eachLink(function(l) { + if (l.target.type == "subflow" && l.target.z == subflow.id && l.target.direction == "status") { + subflowRemovedLinks.push(l); + } + }); + subflowRemovedLinks.forEach(function(l) { RED.nodes.removeLink(l)}); + delete subflow.status; + + $("#red-ui-subflow-status").prop("checked",!!subflow.status); + $("#red-ui-subflow-status").parent().parent().toggleClass("active",!!subflow.status); + + return { links: subflowRemovedLinks } + } + + function refresh(markChange) { + var activeSubflow = RED.nodes.subflow(RED.workspaces.active()); + refreshToolbar(activeSubflow); + var subflowInstances = []; + if (activeSubflow) { + RED.nodes.filterNodes({type:"subflow:"+activeSubflow.id}).forEach(function(n) { + subflowInstances.push({ + id: n.id, + changed: n.changed + }); + if (markChange) { + n.changed = true; + } + n.inputs = activeSubflow.in.length; + n.outputs = activeSubflow.out.length; + while (n.outputs < n.ports.length) { + n.ports.pop(); + } + n.resize = true; + n.dirty = true; + RED.editor.updateNodeProperties(n); + }); + RED.editor.validateNode(activeSubflow); + return { + instances: subflowInstances + } + } + } + + function refreshToolbar(activeSubflow) { + if (activeSubflow) { + $("#red-ui-subflow-input-add").toggleClass("active", activeSubflow.in.length !== 0); + $("#red-ui-subflow-input-remove").toggleClass("active",activeSubflow.in.length === 0); + + $("#red-ui-subflow-output .spinner-value").text(activeSubflow.out.length); + + $("#red-ui-subflow-status").prop("checked",!!activeSubflow.status); + $("#red-ui-subflow-status").parent().parent().toggleClass("active",!!activeSubflow.status); + + } + } + + function showWorkspaceToolbar(activeSubflow) { + var toolbar = $("#red-ui-workspace-toolbar"); + toolbar.empty(); + + // Edit properties + $('<a class="button" id="red-ui-subflow-edit" href="#" data-i18n="[append]subflow.editSubflowProperties"><i class="fa fa-pencil"></i> </a>').appendTo(toolbar); + + // Inputs + $('<span style="margin-left: 5px;" data-i18n="subflow.input"></span> '+ + '<div style="display: inline-block;" class="button-group">'+ + '<a id="red-ui-subflow-input-remove" class="button active" href="#">0</a>'+ + '<a id="red-ui-subflow-input-add" class="button" href="#">1</a>'+ + '</div>').appendTo(toolbar); + + // Outputs + $('<span style="margin-left: 5px;" data-i18n="subflow.output"></span> <div id="red-ui-subflow-output" style="display: inline-block;" class="button-group spinner-group">'+ + '<a id="red-ui-subflow-output-remove" class="button" href="#"><i class="fa fa-minus"></i></a>'+ + '<div class="spinner-value">3</div>'+ + '<a id="red-ui-subflow-output-add" class="button" href="#"><i class="fa fa-plus"></i></a>'+ + '</div>').appendTo(toolbar); + + // Status + $('<span class="button-group"><span class="button" style="padding:0"><label for="red-ui-subflow-status"><input id="red-ui-subflow-status" type="checkbox"> <span data-i18n="subflow.status"></span></label></span></span>').appendTo(toolbar); + + // $('<a class="button disabled" id="red-ui-subflow-add-input" href="#" data-i18n="[append]subflow.input"><i class="fa fa-plus"></i> </a>').appendTo(toolbar); + // $('<a class="button" id="red-ui-subflow-add-output" href="#" data-i18n="[append]subflow.output"><i class="fa fa-plus"></i> </a>').appendTo(toolbar); + + // Delete + $('<a class="button" id="red-ui-subflow-delete" href="#" data-i18n="[append]subflow.deleteSubflow"><i class="fa fa-trash"></i> </a>').appendTo(toolbar); + + toolbar.i18n(); + + + $("#red-ui-subflow-output-remove").on("click", function(event) { + event.preventDefault(); + var wasDirty = RED.nodes.dirty(); + var wasChanged = activeSubflow.changed; + var result = removeSubflowOutput(); + if (result) { + var inst = refresh(true); + RED.history.push({ + t:'delete', + links:result.links, + subflowOutputs: result.subflowOutputs, + changed: wasChanged, + dirty:wasDirty, + subflow: { + instances: inst.instances + } + }); + + RED.view.select(); + RED.nodes.dirty(true); + RED.view.redraw(true); + } + }); + + $("#red-ui-subflow-output-add").on("click", function(event) { + event.preventDefault(); + addSubflowOutput(); + }); + + $("#red-ui-subflow-input-add").on("click", function(event) { + event.preventDefault(); + addSubflowInput(); + }); + + $("#red-ui-subflow-input-remove").on("click", function(event) { + event.preventDefault(); + var wasDirty = RED.nodes.dirty(); + var wasChanged = activeSubflow.changed; + activeSubflow.changed = true; + var result = removeSubflowInput(); + if (result) { + var inst = refresh(true); + RED.history.push({ + t:'delete', + links:result.links, + changed: wasChanged, + subflowInputs: result.subflowInputs, + dirty:wasDirty, + subflow: { + instances: inst.instances + } + }); + RED.view.select(); + RED.nodes.dirty(true); + RED.view.redraw(true); + } + }); + + $("#red-ui-subflow-status").on("change", function(evt) { + if (this.checked) { + addSubflowStatus(); + } else { + var currentStatus = activeSubflow.status; + var wasChanged = activeSubflow.changed; + var result = removeSubflowStatus(); + if (result) { + activeSubflow.changed = true; + var wasDirty = RED.nodes.dirty(); + RED.history.push({ + t:'delete', + links:result.links, + changed: wasChanged, + dirty:wasDirty, + subflow: { + id: activeSubflow.id, + status: currentStatus + } + }); + RED.view.select(); + RED.nodes.dirty(true); + RED.view.redraw(); + } + } + }) + + $("#red-ui-subflow-edit").on("click", function(event) { + RED.editor.editSubflow(RED.nodes.subflow(RED.workspaces.active())); + event.preventDefault(); + }); + + $("#red-ui-subflow-delete").on("click", function(event) { + event.preventDefault(); + var startDirty = RED.nodes.dirty(); + var historyEvent = removeSubflow(RED.workspaces.active()); + historyEvent.t = 'delete'; + historyEvent.dirty = startDirty; + + RED.history.push(historyEvent); + + }); + + refreshToolbar(activeSubflow); + + $("#red-ui-workspace-chart").css({"margin-top": "40px"}); + $("#red-ui-workspace-toolbar").show(); + } + + function hideWorkspaceToolbar() { + $("#red-ui-workspace-toolbar").hide().empty(); + $("#red-ui-workspace-chart").css({"margin-top": "0"}); + } + + function removeSubflow(id) { + var removedNodes = []; + var removedLinks = []; + + var activeSubflow = RED.nodes.subflow(id); + + RED.nodes.eachNode(function(n) { + if (n.type == "subflow:"+activeSubflow.id) { + removedNodes.push(n); + } + if (n.z == activeSubflow.id) { + removedNodes.push(n); + } + }); + RED.nodes.eachConfig(function(n) { + if (n.z == activeSubflow.id) { + removedNodes.push(n); + } + }); + + var removedConfigNodes = []; + for (var i=0;i<removedNodes.length;i++) { + var removedEntities = RED.nodes.remove(removedNodes[i].id); + removedLinks = removedLinks.concat(removedEntities.links); + removedConfigNodes = removedConfigNodes.concat(removedEntities.nodes); + } + // TODO: this whole delete logic should be in RED.nodes.removeSubflow.. + removedNodes = removedNodes.concat(removedConfigNodes); + + RED.nodes.removeSubflow(activeSubflow); + RED.workspaces.remove(activeSubflow); + RED.nodes.dirty(true); + RED.view.redraw(); + + return { + nodes:removedNodes, + links:removedLinks, + subflows: [activeSubflow] + } + } + + function init() { + RED.events.on("workspace:change",function(event) { + var activeSubflow = RED.nodes.subflow(event.workspace); + if (activeSubflow) { + showWorkspaceToolbar(activeSubflow); + } else { + hideWorkspaceToolbar(); + } + }); + RED.events.on("view:selection-changed",function(selection) { + if (!selection.nodes) { + RED.menu.setDisabled("menu-item-subflow-convert",true); + } else { + RED.menu.setDisabled("menu-item-subflow-convert",false); + } + }); + + RED.actions.add("core:create-subflow",createSubflow); + RED.actions.add("core:convert-to-subflow",convertToSubflow); + + $(_subflowEditTemplate).appendTo("#red-ui-editor-node-configs"); + $(_subflowTemplateEditTemplate).appendTo("#red-ui-editor-node-configs"); + + } + + function createSubflow() { + var lastIndex = 0; + RED.nodes.eachSubflow(function(sf) { + var m = (new RegExp("^Subflow (\\d+)$")).exec(sf.name); + if (m) { + lastIndex = Math.max(lastIndex,m[1]); + } + }); + + var name = "Subflow "+(lastIndex+1); + + var subflowId = RED.nodes.id(); + var subflow = { + type:"subflow", + id:subflowId, + name:name, + info:"", + in: [], + out: [] + }; + RED.nodes.addSubflow(subflow); + RED.history.push({ + t:'createSubflow', + subflow: { + subflow:subflow + }, + dirty:RED.nodes.dirty() + }); + RED.workspaces.show(subflowId); + RED.nodes.dirty(true); + } + + function snapToGrid(x) { + if (RED.settings.get("editor").view['view-snap-grid']) { + x = Math.round(x / RED.view.gridSize()) * RED.view.gridSize(); + } + return x; + } + + function convertToSubflow() { + var selection = RED.view.selection(); + if (!selection.nodes) { + RED.notify(RED._("subflow.errors.noNodesSelected"),"error"); + return; + } + var i,n; + var nodes = {}; + var new_links = []; + var removedLinks = []; + + var candidateInputs = []; + var candidateOutputs = []; + var candidateInputNodes = {}; + + var boundingBox = [selection.nodes[0].x, + selection.nodes[0].y, + selection.nodes[0].x, + selection.nodes[0].y]; + + for (i=0;i<selection.nodes.length;i++) { + n = selection.nodes[i]; + nodes[n.id] = {n:n,outputs:{}}; + boundingBox = [ + Math.min(boundingBox[0],n.x), + Math.min(boundingBox[1],n.y), + Math.max(boundingBox[2],n.x), + Math.max(boundingBox[3],n.y) + ] + } + var offsetX = snapToGrid(boundingBox[0] - 200); + var offsetY = snapToGrid(boundingBox[1] - 80); + + + var center = [ + snapToGrid((boundingBox[2]+boundingBox[0]) / 2), + snapToGrid((boundingBox[3]+boundingBox[1]) / 2) + ]; + + RED.nodes.eachLink(function(link) { + if (nodes[link.source.id] && nodes[link.target.id]) { + // A link wholely within the selection + } + + if (nodes[link.source.id] && !nodes[link.target.id]) { + // An outbound link from the selection + candidateOutputs.push(link); + removedLinks.push(link); + } + if (!nodes[link.source.id] && nodes[link.target.id]) { + // An inbound link + candidateInputs.push(link); + candidateInputNodes[link.target.id] = link.target; + removedLinks.push(link); + } + }); + + var outputs = {}; + candidateOutputs = candidateOutputs.filter(function(v) { + if (outputs[v.source.id+":"+v.sourcePort]) { + outputs[v.source.id+":"+v.sourcePort].targets.push(v.target); + return false; + } + v.targets = []; + v.targets.push(v.target); + outputs[v.source.id+":"+v.sourcePort] = v; + return true; + }); + candidateOutputs.sort(function(a,b) { return a.source.y-b.source.y}); + + if (Object.keys(candidateInputNodes).length > 1) { + RED.notify(RED._("subflow.errors.multipleInputsToSelection"),"error"); + return; + } + + var lastIndex = 0; + RED.nodes.eachSubflow(function(sf) { + var m = (new RegExp("^Subflow (\\d+)$")).exec(sf.name); + if (m) { + lastIndex = Math.max(lastIndex,m[1]); + } + }); + + var name = "Subflow "+(lastIndex+1); + + var subflowId = RED.nodes.id(); + var subflow = { + type:"subflow", + id:subflowId, + name:name, + info:"", + in: Object.keys(candidateInputNodes).map(function(v,i) { var index = i; return { + type:"subflow", + direction:"in", + x:snapToGrid(candidateInputNodes[v].x-(candidateInputNodes[v].w/2)-80 - offsetX), + y:snapToGrid(candidateInputNodes[v].y - offsetY), + z:subflowId, + i:index, + id:RED.nodes.id(), + wires:[{id:candidateInputNodes[v].id}] + }}), + out: candidateOutputs.map(function(v,i) { var index = i; return { + type:"subflow", + direction:"out", + x:snapToGrid(v.source.x+(v.source.w/2)+80 - offsetX), + y:snapToGrid(v.source.y - offsetY), + z:subflowId, + i:index, + id:RED.nodes.id(), + wires:[{id:v.source.id,port:v.sourcePort}] + }}) + }; + + RED.nodes.addSubflow(subflow); + + var subflowInstance = { + id:RED.nodes.id(), + type:"subflow:"+subflow.id, + x: center[0], + y: center[1], + z: RED.workspaces.active(), + inputs: subflow.in.length, + outputs: subflow.out.length, + h: Math.max(30/*node_height*/,(subflow.out.length||0) * 15), + changed:true + } + subflowInstance._def = RED.nodes.getType(subflowInstance.type); + RED.editor.validateNode(subflowInstance); + RED.nodes.add(subflowInstance); + + candidateInputs.forEach(function(l) { + var link = {source:l.source, sourcePort:l.sourcePort, target: subflowInstance}; + new_links.push(link); + RED.nodes.addLink(link); + }); + + candidateOutputs.forEach(function(output,i) { + output.targets.forEach(function(target) { + var link = {source:subflowInstance, sourcePort:i, target: target}; + new_links.push(link); + RED.nodes.addLink(link); + }); + }); + + subflow.in.forEach(function(input) { + input.wires.forEach(function(wire) { + var link = {source: input, sourcePort: 0, target: RED.nodes.node(wire.id) } + new_links.push(link); + RED.nodes.addLink(link); + }); + }); + subflow.out.forEach(function(output,i) { + output.wires.forEach(function(wire) { + var link = {source: RED.nodes.node(wire.id), sourcePort: wire.port , target: output } + new_links.push(link); + RED.nodes.addLink(link); + }); + }); + + for (i=0;i<removedLinks.length;i++) { + RED.nodes.removeLink(removedLinks[i]); + } + + for (i=0;i<selection.nodes.length;i++) { + n = selection.nodes[i]; + if (/^link /.test(n.type)) { + n.links = n.links.filter(function(id) { + var isLocalLink = nodes.hasOwnProperty(id); + if (!isLocalLink) { + var otherNode = RED.nodes.node(id); + if (otherNode && otherNode.links) { + var i = otherNode.links.indexOf(n.id); + if (i > -1) { + otherNode.links.splice(i,1); + } + } + } + return isLocalLink; + }); + } + n.x -= offsetX; + n.y -= offsetY; + RED.nodes.moveNodeToTab(n, subflow.id); + } + + RED.history.push({ + t:'createSubflow', + nodes:[subflowInstance.id], + links:new_links, + subflow: { + subflow: subflow, + offsetX: offsetX, + offsetY: offsetY + }, + + activeWorkspace: RED.workspaces.active(), + removedLinks: removedLinks, + + dirty:RED.nodes.dirty() + }); + RED.view.select(null); + RED.editor.validateNode(subflow); + RED.nodes.dirty(true); + RED.view.redraw(true); + } + + + /** + * Create interface for controlling env var UI definition + */ + function buildEnvControl(envList) { + + var tabs = RED.tabs.create({ + id: "subflow-env-tabs", + onchange: function(tab) { + if (tab.id === "subflow-env-tab-preview") { + var inputContainer = $("#subflow-input-ui"); + var list = envList.editableList("items"); + var exportedEnv = exportEnvList(list, true); + buildEnvUI(inputContainer, exportedEnv); + } + $("#subflow-env-tabs-content").children().hide(); + $("#" + tab.id).show(); + } + }); + tabs.addTab({ + id: "subflow-env-tab-edit", + label: RED._("editor-tab.envProperties") + }); + tabs.addTab({ + id: "subflow-env-tab-preview", + label: RED._("editor-tab.preview") + }); + + var localesList = RED.settings.theme("languages") + .map(function(lc) { var name = RED._("languages."+lc); return {text: (name ? name : lc), val: lc}; }) + .sort(function(a, b) { return a.text.localeCompare(b.text) }); + RED.popover.tooltip($(".node-input-env-locales-row i"),RED._("editor.locale")) + var locales = $("#subflow-input-env-locale") + localesList.forEach(function(item) { + var opt = { + value: item.val + }; + if (item.val === "en-US") { // make en-US default selected + opt.selected = ""; + } + $("<option/>", opt).text(item.text).appendTo(locales); + }); + var locale = RED.i18n.lang(); + locales.val(locale); + + locales.on("change", function() { + currentLocale = $(this).val(); + var items = $("#node-input-env-container").editableList("items"); + items.each(function (i, item) { + var entry = $(this).data('data'); + var labelField = entry.ui.labelField; + labelField.val(lookupLabel(entry.ui.label, "", currentLocale)); + if (labelField.timeout) { + clearTimeout(labelField.timeout); + delete labelField.timeout; + } + labelField.addClass("input-updated"); + labelField.timeout = setTimeout(function() { + delete labelField.timeout + labelField.removeClass("input-updated"); + },3000); + }); + }); + } + + /** + * Create env var edit interface + * @param container - container + * @param node - subflow node + */ + function buildPropertiesList(envContainer, node) { + + var isTemplateNode = (node.type === "subflow"); + + if (isTemplateNode) { + buildEnvControl(envContainer); + } + envContainer + .css({ + 'min-height':'150px', + 'min-width':'450px' + }) + .editableList({ + header: isTemplateNode?$('<div><div><div></div><div data-i18n="common.label.name"></div><div data-i18n="editor-tab.defaultValue"></div><div></div></div></div>'):undefined, + addItem: function(container, i, opt) { + if (isTemplateNode) { + container.addClass("red-ui-editor-subflow-env-editable") + } + + var envRow = $('<div/>').appendTo(container); + var nameField = null; + var valueField = null; + + // if (opt.parent) { + // buildEnvUIRow(envRow,opt,opt.parent.ui||{}) + // } else { + nameField = $('<input/>', { + class: "node-input-env-name", + type: "text", + placeholder: RED._("common.label.name") + }).attr("autocomplete","disable").appendTo(envRow).val(opt.name); + valueField = $('<input/>',{ + style: "width:100%", + class: "node-input-env-value", + type: "text", + }).attr("autocomplete","disable").appendTo(envRow) + valueField.typedInput({default:'str',types:['str','num','bool','json','bin','env']}); + valueField.typedInput('type', opt.parent?(opt.type||opt.parent.type):opt.type); + valueField.typedInput('value', opt.parent?((opt.value !== undefined)?opt.value:opt.parent.value):opt.value); + // } + + + opt.nameField = nameField; + opt.valueField = valueField; + + if (!opt.parent) { + var actionButton = $('<a/>',{href:"#",class:"red-ui-editableList-item-remove red-ui-button red-ui-button-small"}).appendTo(envRow); + $('<i/>',{class:"fa "+(opt.parent?"fa-reply":"fa-remove")}).appendTo(actionButton); + var removeTip = RED.popover.tooltip(actionButton,RED._("subflow.env.remove")); + actionButton.on("click", function(evt) { + evt.preventDefault(); + removeTip.close(); + container.parent().addClass("red-ui-editableList-item-deleting") + container.fadeOut(300, function() { + envContainer.editableList('removeItem',opt); + }); + }); + } + + if (isTemplateNode) { + // Add the UI customisation row + // if `opt.ui` does not exist, then apply defaults. If these + // defaults do not change then they will get stripped off + // before saving. + opt.ui = opt.ui || { + icon: "", + label: {}, + type: "input", + opts: {types:['str','num','bool','json','bin','env']} + } + opt.ui.label = opt.ui.label || {}; + opt.ui.type = opt.ui.type || "input"; + + var uiRow = $('<div/>').appendTo(container).hide(); + // save current info for reverting on cancel + // var copy = $.extend(true, {}, ui); + + $('<a href="#"><i class="fa fa-angle-right"></a>').prependTo(envRow).on("click", function (evt) { + evt.preventDefault(); + if ($(this).hasClass('expanded')) { + uiRow.slideUp(); + $(this).removeClass('expanded'); + } else { + uiRow.slideDown(); + $(this).addClass('expanded'); + } + }); + + buildEnvEditRow(uiRow, opt.ui, nameField, valueField); + nameField.trigger('change'); + } + }, + sortable: ".red-ui-editableList-item-handle", + removable: false + }); + var parentEnv = {}; + var envList = []; + if (/^subflow:/.test(node.type)) { + var subflowDef = RED.nodes.subflow(node.type.substring(8)); + if (subflowDef.env) { + subflowDef.env.forEach(function(env) { + var item = { + name:env.name, + parent: { + type: env.type, + value: env.value, + ui: env.ui + } + } + envList.push(item); + parentEnv[env.name] = item; + }) + } + } + + if (node.env) { + for (var i = 0; i < node.env.length; i++) { + var env = node.env[i]; + if (parentEnv.hasOwnProperty(env.name)) { + parentEnv[env.name].type = env.type; + parentEnv[env.name].value = env.value; + } else { + envList.push({ + name: env.name, + type: env.type, + value: env.value, + ui: env.ui + }); + } + } + } + envList.forEach(function(env) { + if (env.parent && env.parent.ui && env.parent.ui.type === 'hide') { + return; + } + if (!isTemplateNode && env.parent) { + return; + } + envContainer.editableList('addItem', JSON.parse(JSON.stringify(env))); + }); + } + + /** + * Create UI edit interface for environment variable + * @param container - container + * @param env - env var definition + * @param nameField - name field of env var + * @param valueField - value field of env var + */ + function buildEnvEditRow(container, ui, nameField, valueField) { + container.addClass("red-ui-editor-subflow-env-ui-row") + var topRow = $('<div></div>').appendTo(container); + $('<div></div>').appendTo(topRow); + $('<div>').text(RED._("editor.icon")).appendTo(topRow); + $('<div>').text(RED._("editor.label")).appendTo(topRow); + $('<div>').text(RED._("editor.inputType")).appendTo(topRow); + + var row = $('<div></div>').appendTo(container); + $('<div><i class="red-ui-editableList-item-handle fa fa-bars"></i></div>').appendTo(row); + + var typeOptions = { + 'input': {types:['str','num','bool','json','bin','env']}, + 'select': {opts:[]}, + 'spinner': {} + }; + if (ui.opts) { + typeOptions[ui.type] = ui.opts; + } else { + // Pick up the default values if not otherwise provided + ui.opts = typeOptions[ui.type]; + } + var iconCell = $('<div></div>').appendTo(row); + + var iconButton = $('<a href="#"></a>').appendTo(iconCell); + iconButton.on("click", function(evt) { + evt.preventDefault(); + var icon = ui.icon || ""; + var iconPath = (icon ? RED.utils.separateIconPath(icon) : {}); + RED.editor.showIconPicker(iconButton, null, iconPath, true, function (newIcon) { + iconButton.empty(); + var path = newIcon || ""; + var newPath = RED.utils.separateIconPath(path); + if (newPath) { + $('<i class="fa"></i>').addClass(newPath.file).appendTo(iconButton); + } + ui.icon = path; + }); + }) + + if (ui.icon) { + var newPath = RED.utils.separateIconPath(ui.icon); + $('<i class="fa '+newPath.file+'"></i>').appendTo(iconButton); + } + + var labelCell = $('<div></div>').appendTo(row); + + var label = ui.label && ui.label[currentLocale] || ""; + var labelInput = $('<input type="text">').val(label).appendTo(labelCell); + ui.labelField = labelInput; + labelInput.on('change', function(evt) { + ui.label = ui.label || {}; + var val = $(this).val().trim(); + if (val === "") { + delete ui.label[currentLocale]; + } else { + ui.label[currentLocale] = val; + } + }) + var labelIcon = $('<span class="red-ui-editor-subflow-env-lang-icon"><i class="fa fa-language"></i></span>').appendTo(labelCell); + RED.popover.tooltip(labelIcon,function() { + var langs = Object.keys(ui.label); + var content = $("<div>"); + if (langs.indexOf(currentLocale) === -1) { + langs.push(currentLocale); + langs.sort(); + } + langs.forEach(function(l) { + var row = $('<div>').appendTo(content); + $('<span>').css({display:"inline-block",width:"120px"}).text(RED._("languages."+l)+(l===currentLocale?"*":"")).appendTo(row); + $('<span>').text(ui.label[l]||"").appendTo(row); + }); + return content; + }) + + nameField.on('change',function(evt) { + labelInput.attr("placeholder",$(this).val()) + }); + + var inputCell = $('<div></div>').appendTo(row); + var inputCellInput = $('<input type="text">').css("width","100%").appendTo(inputCell); + if (ui.type === "input") { + inputCellInput.val(ui.opts.types.join(",")); + } + var checkbox; + var selectBox; + + inputCellInput.typedInput({ + types: [ + { + value:"input", + label:RED._("editor.inputs.input"), icon:"fa fa-i-cursor",showLabel:false,multiple:true,options:[ + {value:"str",label:RED._("editor.types.str"),icon:"red/images/typedInput/az.svg"}, + {value:"num",label:RED._("editor.types.num"),icon:"red/images/typedInput/09.svg"}, + {value:"bool",label:RED._("editor.types.bool"),icon:"red/images/typedInput/bool.svg"}, + {value:"json",label:RED._("editor.types.json"),icon:"red/images/typedInput/json.svg"}, + {value: "bin",label: RED._("editor.types.bin"),icon: "red/images/typedInput/bin.svg"}, + {value: "env",label: RED._("editor.types.env"),icon: "red/images/typedInput/env.svg"} + ], + default: ['str','num','bool','json','bin','env'], + valueLabel: function(container,value) { + container.css("padding",0); + var innerContainer = $('<div>').css({ + "background":"white", + "height":"100%", + "box-sizing": "border-box" + }).appendTo(container); + + var input = $('<div class="placeholder-input">').appendTo(innerContainer); + $('<span><i class="fa fa-i-cursor"></i></span>').appendTo(input); + if (value.length) { + value.forEach(function(v) { + $('<img>',{src:v.icon,style:"max-width:14px; padding: 0 3px; margin-top:-4px; margin-left: 3px"}).appendTo(input); + }) + } else { + $("<span>").css({ + "color":"#aaa", + "padding-left": "4px" + }).text("select types...").appendTo(input); + } + } + }, + { + value:"select", + label:RED._("editor.inputs.select"), icon:"fa fa-tasks",showLabel:false, + valueLabel: function(container,value) { + container.css("padding","0"); + + selectBox = $('<select></select>').appendTo(container); + if (ui.opts && Array.isArray(ui.opts.opts)) { + ui.opts.opts.forEach(function(o) { + var label = lookupLabel(o.l, o.l["en-US"]||o.v, currentLocale); + // $('<option>').val((o.t||'str')+":"+o.v).text(label).appendTo(selectBox); + $('<option>').val(o.v).text(label).appendTo(selectBox); + }) + } + selectBox.on('change', function(evt) { + var v = selectBox.val(); + // var parts = v.split(":"); + // var t = parts.shift(); + // v = parts.join(":"); + // + // valueField.typedInput("type",'str') + valueField.typedInput("value",v) + }); + selectBox.val(valueField.typedInput("value")); + // selectBox.val(valueField.typedInput('type')+":"+valueField.typedInput("value")); + }, + expand: { + icon: "fa-caret-down", + minWidth: 400, + content: function(container) { + var content = $('<div class="red-ui-editor-subflow-ui-edit-panel">').appendTo(container); + var optList = $('<ol>').appendTo(content).editableList({ + header:$("<div><div>"+RED._("editor.select.label")+"</div><div>"+RED._("editor.select.value")+"</div></div>"), + addItem: function(row,index,itemData) { + var labelDiv = $('<div>').appendTo(row); + var label = lookupLabel(itemData.l, "", currentLocale); + itemData.label = $('<input type="text">').val(label).appendTo(labelDiv); + itemData.label.on('keydown', function(evt) { + if (evt.keyCode === 13) { + itemData.input.focus(); + evt.preventDefault(); + } + }); + var labelIcon = $('<span class="red-ui-editor-subflow-env-lang-icon"><i class="fa fa-language"></i></span>').appendTo(labelDiv); + RED.popover.tooltip(labelIcon,function() { + return currentLocale; + }) + itemData.input = $('<input type="text">').val(itemData.v).appendTo(row); + + // Problem using a TI here: + // - this is in a popout panel + // - clicking the expand button in the TI will close the parent edit tray + // and open the type editor. + // - but it leaves the popout panel over the top. + // - there is no way to get back to the popout panel after closing the type editor + //.typedInput({default:itemData.t||'str', types:['str','num','bool','json','bin','env']}); + itemData.input.on('keydown', function(evt) { + if (evt.keyCode === 13) { + // Enter or Tab + var index = optList.editableList('indexOf',itemData); + var length = optList.editableList('length'); + if (index + 1 === length) { + var newItem = {}; + optList.editableList('addItem',newItem); + setTimeout(function() { + if (newItem.label) { + newItem.label.focus(); + } + },100) + } else { + var nextItem = optList.editableList('getItemAt',index+1); + if (nextItem.label) { + nextItem.label.focus() + } + } + evt.preventDefault(); + } + }); + }, + sortable: true, + removable: true, + height: 160 + }) + if (ui.opts.opts.length > 0) { + ui.opts.opts.forEach(function(o) { + optList.editableList('addItem',$.extend(true,{},o)) + }) + } else { + optList.editableList('addItem',{}) + } + return { + onclose: function() { + var items = optList.editableList('items'); + var vals = []; + items.each(function (i,el) { + var data = el.data('data'); + var l = data.label.val().trim(); + var v = data.input.val(); + // var t = data.input.typedInput('type'); + // var v = data.input.typedInput('value'); + if (l.length > 0) { + data.l = data.l || {}; + data.l[currentLocale] = l; + } + data.v = v; + + if (l.length > 0 || v.length > 0) { + var val = {l:data.l,v:data.v}; + // if (t !== 'str') { + // val.t = t; + // } + vals.push(val); + } + }); + ui.opts.opts = vals; + inputCellInput.typedInput('value',Date.now()) + } + } + } + } + }, + { + value:"checkbox", + label:RED._("editor.inputs.checkbox"), icon:"fa fa-check-square-o",showLabel:false, + valueLabel: function(container,value) { + container.css("padding",0); + checkbox = $('<input type="checkbox">').appendTo(container); + checkbox.on('change', function(evt) { + valueField.typedInput('value',$(this).prop('checked')?"true":"false"); + }) + checkbox.prop('checked',valueField.typedInput('value')==="true"); + } + }, + { + value:"spinner", + label:RED._("editor.inputs.spinner"), icon:"fa fa-sort-numeric-asc", showLabel:false, + valueLabel: function(container,value) { + container.css("padding",0); + var innerContainer = $('<div>').css({ + "background":"white", + "height":"100%", + "box-sizing": "border-box" + }).appendTo(container); + + var input = $('<div class="placeholder-input">').appendTo(innerContainer); + $('<span><i class="fa fa-sort-numeric-asc"></i></span>').appendTo(input); + + var min = ui.opts && ui.opts.min; + var max = ui.opts && ui.opts.max; + var label = ""; + if (min !== undefined && max !== undefined) { + label = Math.min(min,max)+" - "+Math.max(min,max); + } else if (min !== undefined) { + label = "> "+min; + } else if (max !== undefined) { + label = "< "+max; + } + $('<span>').css("margin-left","15px").text(label).appendTo(input); + }, + expand: { + icon: "fa-caret-down", + content: function(container) { + var content = $('<div class="red-ui-editor-subflow-ui-edit-panel">').appendTo(container); + content.css("padding","8px 5px") + var min = ui.opts.min; + var max = ui.opts.max; + var minInput = $('<input type="number" style="margin-bottom:0; width:60px">'); + minInput.val(min); + var maxInput = $('<input type="number" style="margin-bottom:0; width:60px">'); + maxInput.val(max); + $('<div class="form-row" style="margin-bottom:3px"><label>'+RED._("editor.spinner.min")+'</label></div>').append(minInput).appendTo(content); + $('<div class="form-row" style="margin-bottom:0"><label>'+RED._("editor.spinner.max")+'</label></div>').append(maxInput).appendTo(content); + return { + onclose: function() { + var min = minInput.val().trim(); + var max = maxInput.val().trim(); + if (min !== "") { + ui.opts.min = parseInt(min); + } else { + delete ui.opts.min; + } + if (max !== "") { + ui.opts.max = parseInt(max); + } else { + delete ui.opts.max; + } + inputCellInput.typedInput('value',Date.now()) + } + } + } + } + }, + { + value:"none", + label:RED._("editor.inputs.none"), icon:"fa fa-times",hasValue:false + }, + { + value:"hide", + label:RED._("editor.inputs.hidden"), icon:"fa fa-ban",hasValue:false + } + ], + default: 'none' + }).on("typedinputtypechange", function(evt,type) { + ui.type = $(this).typedInput("type"); + ui.opts = typeOptions[ui.type]; + if (ui.type === 'input') { + // In the case of 'input' type, the typedInput uses the multiple-option + // mode. Its value needs to be set to a comma-separately list of the + // selected options. + inputCellInput.typedInput('value',ui.opts.types.join(",")) + } else { + // No other type cares about `value`, but doing this will + // force a refresh of the label now that `ui.opts` has + // been updated. + inputCellInput.typedInput('value',Date.now()) + } + + switch (ui.type) { + case 'input': + valueField.typedInput('types',ui.opts.types); + break; + case 'select': + valueField.typedInput('types',['str']); + break; + case 'checkbox': + valueField.typedInput('types',['bool']); + break; + case 'spinner': + valueField.typedInput('types',['num']) + break; + default: + valueField.typedInput('types',['str','num','bool','json','bin','env']) + } + if (ui.type === 'checkbox') { + valueField.typedInput('type','bool'); + } else if (ui.type === 'spinner') { + valueField.typedInput('type','num'); + } + if (ui.type !== 'checkbox') { + checkbox = null; + } + + }).on("change", function(evt,type) { + if (ui.type === 'input') { + ui.opts.types = inputCellInput.typedInput('value').split(","); + valueField.typedInput('types',ui.opts.types); + } + }); + valueField.on("change", function(evt) { + if (checkbox) { + checkbox.prop('checked',$(this).typedInput('value')==="true") + } + }) + // Set the input to the right type. This will trigger the 'typedinputtypechange' + // event handler (just above ^^) to update the value if needed + inputCellInput.typedInput('type',ui.type) + } + + function buildEnvUIRow(row, tenv, ui) { + ui.label = ui.label||{}; + if (!ui.type) { + ui.type = "input"; + ui.opts = {types:['str','num','bool','json','bin','env']} + } else { + if (!ui.opts) { + ui.opts = (ui.type === "select") ? {opts:[]} : {}; + } + } + + var labels = ui.label || {}; + var locale = RED.i18n.lang(); + var labelText = lookupLabel(labels, labels["en-US"]||tenv.name, locale); + var label = $('<label>').appendTo(row); + var labelContainer = $('<span></span>').appendTo(label); + if (ui.icon) { + var newPath = RED.utils.separateIconPath(ui.icon); + if (newPath) { + $("<i class='fa "+newPath.file +"'/>").appendTo(labelContainer); + } + } + if (ui.type !== "checkbox") { + var css = ui.icon ? {"padding-left":"5px"} : {}; + $('<span>').css(css).text(labelText).appendTo(label); + if (ui.type === 'none') { + label.width('100%'); + } + } + var input; + var val = { + value: "", + type: "str" + }; + if (tenv.parent) { + val.value = tenv.parent.value; + val.type = tenv.parent.type; + } + if (tenv.hasOwnProperty('value')) { + val.value = tenv.value; + } + if (tenv.hasOwnProperty('type')) { + val.type = tenv.type; + } + switch(ui.type) { + case "input": + input = $('<input type="text">').css('width','70%').appendTo(row); + if (ui.opts.types && ui.opts.types.length > 0) { + var inputType = val.type; + if (ui.opts.types.indexOf(inputType) === -1) { + inputType = ui.opts.types[0] + } + input.typedInput({ + types: ui.opts.types, + default: inputType + }) + input.typedInput('value',val.value) + } else { + input.val(val.value) + } + break; + case "select": + input = $('<select>').css('width','70%').appendTo(row); + if (ui.opts.opts) { + ui.opts.opts.forEach(function(o) { + $('<option>').val(o.v).text(lookupLabel(o.l, o.l['en-US']||o.v, locale)).appendTo(input); + }) + } + input.val(val.value); + break; + case "checkbox": + label.css("cursor","default"); + var cblabel = $('<label>').css('width','70%').appendTo(row); + input = $('<input type="checkbox">').css({ + marginTop: 0, + width: 'auto', + height: '34px' + }).appendTo(cblabel); + labelContainer.css({"padding-left":"5px"}).appendTo(cblabel); + $('<span>').css({"padding-left":"5px"}).text(labelText).appendTo(cblabel); + var boolVal = false; + if (val.type === 'bool') { + boolVal = val.value === 'true' + } else if (val.type === 'num') { + boolVal = val.value !== "0" + } else { + boolVal = val.value !== "" + } + input.prop("checked",boolVal); + break; + case "spinner": + input = $('<input>').css('width','70%').appendTo(row); + var spinnerOpts = {}; + if (ui.opts.hasOwnProperty('min')) { + spinnerOpts.min = ui.opts.min; + } + if (ui.opts.hasOwnProperty('max')) { + spinnerOpts.max = ui.opts.max; + } + input.spinner(spinnerOpts).parent().width('70%'); + input.val(val.value); + break; + } + if (input) { + input.attr('id',getSubflowEnvPropertyName(tenv.name)) + } + } + + /** + * Create environment variable input UI + * @param uiContainer - container for UI + * @param envList - env var definitions of template + */ + function buildEnvUI(uiContainer, envList) { + uiContainer.empty(); + var elementID = 0; + for (var i = 0; i < envList.length; i++) { + var tenv = envList[i]; + if (tenv.ui && tenv.ui.type === 'hide') { + continue; + } + var row = $("<div/>", { class: "form-row" }).appendTo(uiContainer); + buildEnvUIRow(row,tenv, tenv.ui || {}); + + // console.log(ui); + } + } + // buildEnvUI + + function exportEnvList(list, all) { + if (list) { + var env = []; + list.each(function(i) { + var entry = $(this); + var item = entry.data('data'); + var name = (item.parent?item.name:item.nameField.val()).trim(); + if ((name !== "") || + (item.ui && (item.ui.type === "none"))) { + var valueInput = item.valueField; + var value = valueInput.typedInput("value"); + var type = valueInput.typedInput("type"); + if (all || !item.parent || (item.parent.value !== value || item.parent.type !== type)) { + var envItem = { + name: name, + type: type, + value: value, + }; + if (item.ui) { + var ui = { + icon: item.ui.icon, + label: $.extend(true,{},item.ui.label), + type: item.ui.type, + opts: $.extend(true,{},item.ui.opts) + } + // Check to see if this is the default ui definition. + // Delete any defaults to keep it compact + // { + // icon: "", + // label: {}, + // type: "input", + // opts: {types:['str','num','bool','json','bin','env']} + // } + if (!ui.icon) { + delete ui.icon; + } + if ($.isEmptyObject(ui.label)) { + delete ui.label; + } + switch (ui.type) { + case "input": + if (JSON.stringify(ui.opts) === JSON.stringify({types:['str','num','bool','json','bin','env']})) { + // This is the default input config. Delete it as it will + // be applied automatically + delete ui.type; + delete ui.opts; + } + break; + case "select": + if (ui.opts && $.isEmptyObject(ui.opts.opts)) { + // This is the default select config. + // Delete it as it will be applied automatically + delete ui.opts; + } + break; + case "spinner": + if ($.isEmptyObject(ui.opts)) { + // This is the default spinner config. + // Delete as it will be applied automatically + delete ui.opts + } + break; + default: + delete ui.opts; + } + if (!$.isEmptyObject(ui)) { + envItem.ui = ui; + } + } + env.push(envItem); + } + } + }); + return env; + } + return null; + } + + function getSubflowInstanceParentEnv(node) { + var parentEnv = {}; + var envList = []; + if (/^subflow:/.test(node.type)) { + var subflowDef = RED.nodes.subflow(node.type.substring(8)); + if (subflowDef.env) { + subflowDef.env.forEach(function(env) { + var item = { + name:env.name, + parent: { + type: env.type, + value: env.value + }, + ui: env.ui + } + envList.push(item); + parentEnv[env.name] = item; + }) + } + } + + if (node.env) { + for (var i = 0; i < node.env.length; i++) { + var env = node.env[i]; + if (parentEnv.hasOwnProperty(env.name)) { + parentEnv[env.name].type = env.type; + parentEnv[env.name].value = env.value; + } else { + // envList.push({ + // name: env.name, + // type: env.type, + // value: env.value, + // }); + } + } + } + return envList; + } + + function exportSubflowInstanceEnv(node) { + var env = []; + + // First, get the values for the SubflowTemplate defined properties + // - these are the ones with custom UI elements + var parentEnv = getSubflowInstanceParentEnv(node); + parentEnv.forEach(function(data) { + var item; + var ui = data.ui || {}; + if (!ui.type) { + ui.type = "input"; + ui.opts = {types:['str','num','bool','json','bin','env']} + } else { + ui.opts = ui.opts || {}; + } + var input = $("#"+getSubflowEnvPropertyName(data.name)); + if (input.length) { + item = { name: data.name }; + switch(ui.type) { + case "input": + if (ui.opts.types && ui.opts.types.length > 0) { + item.value = input.typedInput('value'); + item.type = input.typedInput('type'); + } else { + item.value = input.val(); + item.type = 'str'; + } + break; + case "spinner": + item.value = input.val(); + item.type = 'num'; + break; + case "select": + item.value = input.val(); + item.type = 'str'; + break; + case "checkbox": + item.type = 'bool'; + item.value = ""+input.prop("checked"); + break; + } + if (item.type !== data.parent.type || item.value !== data.parent.value) { + env.push(item); + } + } + }) + // Second, get the values from the Properties table tab + var items = $('#red-ui-editor-subflow-env-list').editableList('items'); + items.each(function (i,el) { + var data = el.data('data'); + var item; + if (data.nameField && data.valueField) { + item = { + name: data.nameField.val(), + value: data.valueField.typedInput("value"), + type: data.valueField.typedInput("type") + } + if (item.name.trim() !== "") { + env.push(item); + } + } + }); + return env; + } + + function getSubflowEnvPropertyName(name) { + return 'node-input-subflow-env-'+name.replace(/[^a-z0-9-_]/ig,"_"); + } + + /** + * Lookup text for specific locale + * @param labels - dict of labels + * @param defaultLabel - fallback label if not found + * @param locale - target locale + * @returns {string} text for specified locale + */ + function lookupLabel(labels, defaultLabel, locale) { + if (labels) { + if (labels[locale]) { + return labels[locale]; + } + if (locale) { + var lang = locale.substring(0, 2); + if (labels[lang]) { + return labels[lang]; + } + } + } + return defaultLabel; + } + + function buildEditForm(container,type,node) { + if (type === "subflow-template") { + buildPropertiesList($('#node-input-env-container'), node); + } else if (type === "subflow") { + buildEnvUI($("#subflow-input-ui"), getSubflowInstanceParentEnv(node)); + } + } + function buildPropertiesForm(container, node) { + var form = $('<form class="dialog-form form-horizontal"></form>').appendTo(container); + var listContainer = $('<div class="form-row node-input-env-container-row"></div>').appendTo(form); + var list = $('<ol id="red-ui-editor-subflow-env-list" class="red-ui-editor-subflow-env-list"></ol>').appendTo(listContainer); + buildPropertiesList(list, node); + } + + return { + init: init, + createSubflow: createSubflow, + convertToSubflow: convertToSubflow, + removeSubflow: removeSubflow, + refresh: refresh, + removeInput: removeSubflowInput, + removeOutput: removeSubflowOutput, + removeStatus: removeSubflowStatus, + + + buildEditForm: buildEditForm, + buildPropertiesForm: buildPropertiesForm, + + exportSubflowTemplateEnv: exportEnvList, + exportSubflowInstanceEnv: exportSubflowInstanceEnv + + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js new file mode 100644 index 0000000..c16be54 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js @@ -0,0 +1,399 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.sidebar.config = (function() { + + + var content = document.createElement("div"); + content.className = "red-ui-sidebar-node-config"; + content.id = "red-ui-sidebar-node-config"; + content.tabIndex = 0; + + $('<div class="red-ui-sidebar-header"><span class="button-group">'+ + '<a class="red-ui-sidebar-header-button-toggle selected" id="red-ui-sidebar-config-filter-all" href="#"><span data-i18n="sidebar.config.filterAll"></span></a>'+ + '<a class="red-ui-sidebar-header-button-toggle" id="red-ui-sidebar-config-filter-unused" href="#"><span data-i18n="sidebar.config.filterUnused"></span></a> '+ + '</span></div>' + ).appendTo(content); + + + var toolbar = $('<div>'+ + '<a class="red-ui-footer-button" id="red-ui-sidebar-config-collapse-all" href="#"><i class="fa fa-angle-double-up"></i></a> '+ + '<a class="red-ui-footer-button" id="red-ui-sidebar-config-expand-all" href="#"><i class="fa fa-angle-double-down"></i></a>'+ + '</div>'); + + var globalCategories = $("<div>").appendTo(content); + var flowCategories = $("<div>").appendTo(content); + var subflowCategories = $("<div>").appendTo(content); + + var showUnusedOnly = false; + + var categories = {}; + + function getOrCreateCategory(name,parent,label) { + name = name.replace(/\./i,"-"); + if (!categories[name]) { + var container = $('<div class="red-ui-palette-category red-ui-sidebar-config-category" id="red-ui-sidebar-config-category-'+name+'"></div>').appendTo(parent); + var header = $('<div class="red-ui-sidebar-config-tray-header red-ui-palette-header"><i class="fa fa-angle-down expanded"></i></div>').appendTo(container); + if (label) { + $('<span class="red-ui-palette-node-config-label"/>').text(label).appendTo(header); + } else { + $('<span class="red-ui-palette-node-config-label" data-i18n="sidebar.config.'+name+'">').appendTo(header); + } + $('<span class="red-ui-sidebar-node-config-filter-info"></span>').appendTo(header); + category = $('<ul class="red-ui-palette-content red-ui-sidebar-node-config-list"></ul>').appendTo(container); + category.on("click", function(e) { + $(content).find(".red-ui-palette-node").removeClass("selected"); + }); + container.i18n(); + var icon = header.find("i"); + var result = { + label: label, + list: category, + size: function() { + return result.list.find("li:not(.red-ui-palette-node-config-none)").length + }, + open: function(snap) { + if (!icon.hasClass("expanded")) { + icon.addClass("expanded"); + if (snap) { + result.list.show(); + } else { + result.list.slideDown(); + } + } + }, + close: function(snap) { + if (icon.hasClass("expanded")) { + icon.removeClass("expanded"); + if (snap) { + result.list.hide(); + } else { + result.list.slideUp(); + } + } + }, + isOpen: function() { + return icon.hasClass("expanded"); + } + }; + + header.on('click', function(e) { + if (result.isOpen()) { + result.close(); + } else { + result.open(); + } + }); + categories[name] = result; + } else { + if (categories[name].label !== label) { + categories[name].list.parent().find('.red-ui-palette-node-config-label').text(label); + categories[name].label = label; + } + } + return categories[name]; + } + + function createConfigNodeList(id,nodes) { + var category = getOrCreateCategory(id.replace(/\./i,"-")) + var list = category.list; + + nodes.sort(function(A,B) { + if (A.type < B.type) { return -1;} + if (A.type > B.type) { return 1;} + return 0; + }); + if (showUnusedOnly) { + var hiddenCount = nodes.length; + nodes = nodes.filter(function(n) { + return n._def.hasUsers!==false && n.users.length === 0; + }) + hiddenCount = hiddenCount - nodes.length; + if (hiddenCount > 0) { + list.parent().find('.red-ui-sidebar-node-config-filter-info').text(RED._('sidebar.config.filtered',{count:hiddenCount})).show(); + } else { + list.parent().find('.red-ui-sidebar-node-config-filter-info').hide(); + } + } else { + list.parent().find('.red-ui-sidebar-node-config-filter-info').hide(); + } + list.empty(); + if (nodes.length === 0) { + $('<li class="red-ui-palette-node-config-none" data-i18n="sidebar.config.none">NONE</li>').i18n().appendTo(list); + category.close(true); + } else { + var currentType = ""; + nodes.forEach(function(node) { + var label = RED.utils.getNodeLabel(node,node.id); + if (node.type != currentType) { + $('<li class="red-ui-palette-node-config-type">'+node.type+'</li>').appendTo(list); + currentType = node.type; + } + + var entry = $('<li class="red-ui-palette-node_id_'+node.id.replace(/\./g,"-")+'"></li>').appendTo(list); + var nodeDiv = $('<div class="red-ui-palette-node-config red-ui-palette-node"></div>').appendTo(entry); + entry.data('node',node.id); + var label = $('<div class="red-ui-palette-label"></div>').text(label).appendTo(nodeDiv); + if (node.d) { + nodeDiv.addClass("red-ui-palette-node-config-disabled"); + $('<i class="fa fa-ban"></i>').prependTo(label); + } + + if (node._def.hasUsers !== false) { + var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container red-ui-palette-icon-container-right"}).appendTo(nodeDiv); + if (node.users.length === 0) { + iconContainer.text(0); + } else { + $('<a href="#"/>').on("click", function(e) { + e.stopPropagation(); + e.preventDefault(); + RED.search.show(node.id); + }).text(node.users.length).appendTo(iconContainer); + } + RED.popover.tooltip(iconContainer,RED._('editor.nodesUse',{count:node.users.length})); + if (node.users.length === 0) { + nodeDiv.addClass("red-ui-palette-node-config-unused"); + } + } + nodeDiv.on('click',function(e) { + e.stopPropagation(); + RED.view.select(false); + if (e.metaKey) { + $(this).toggleClass("selected"); + } else { + $(content).find(".red-ui-palette-node").removeClass("selected"); + $(this).addClass("selected"); + } + RED.sidebar.info.refresh(node); + }); + nodeDiv.on('dblclick',function(e) { + e.stopPropagation(); + RED.editor.editConfig("", node.type, node.id); + }); + var userArray = node.users.map(function(n) { return n.id }); + nodeDiv.on('mouseover',function(e) { + RED.nodes.eachNode(function(node) { + if( userArray.indexOf(node.id) != -1) { + node.highlighted = true; + node.dirty = true; + } + }); + RED.view.redraw(); + }); + nodeDiv.on('mouseout',function(e) { + RED.nodes.eachNode(function(node) { + if(node.highlighted) { + node.highlighted = false; + node.dirty = true; + } + }); + RED.view.redraw(); + }); + }); + category.open(true); + } + } + + function refreshConfigNodeList() { + var validList = {"global":true}; + + getOrCreateCategory("global",globalCategories); + + RED.nodes.eachWorkspace(function(ws) { + validList[ws.id.replace(/\./g,"-")] = true; + getOrCreateCategory(ws.id,flowCategories,ws.label); + }) + RED.nodes.eachSubflow(function(sf) { + validList[sf.id.replace(/\./g,"-")] = true; + getOrCreateCategory(sf.id,subflowCategories,sf.name); + }) + $(".red-ui-sidebar-config-category").each(function() { + var id = $(this).attr('id').substring("red-ui-sidebar-config-category-".length); + if (!validList[id]) { + $(this).remove(); + delete categories[id]; + } + }) + var globalConfigNodes = []; + var configList = {}; + RED.nodes.eachConfig(function(cn) { + if (cn.z) {//} == RED.workspaces.active()) { + configList[cn.z.replace(/\./g,"-")] = configList[cn.z.replace(/\./g,"-")]||[]; + configList[cn.z.replace(/\./g,"-")].push(cn); + } else if (!cn.z) { + globalConfigNodes.push(cn); + } + }); + for (var id in validList) { + if (validList.hasOwnProperty(id)) { + createConfigNodeList(id,configList[id]||[]); + } + } + createConfigNodeList('global',globalConfigNodes); + } + + function init() { + RED.sidebar.addTab({ + id: "config", + label: RED._("sidebar.config.label"), + name: RED._("sidebar.config.name"), + content: content, + toolbar: toolbar, + iconClass: "fa fa-cog", + action: "core:show-config-tab", + onchange: function() { refreshConfigNodeList(); } + }); + RED.actions.add("core:show-config-tab", function() {RED.sidebar.show('config')}); + RED.actions.add("core:select-all-config-nodes", function() { + $(content).find(".red-ui-palette-node").addClass("selected"); + }) + RED.actions.add("core:delete-config-selection", function() { + var selectedNodes = []; + $(content).find(".red-ui-palette-node.selected").each(function() { + selectedNodes.push($(this).parent().data('node')); + }); + if (selectedNodes.length > 0) { + var historyEvent = { + t:'delete', + nodes:[], + changes: {}, + dirty: RED.nodes.dirty() + } + selectedNodes.forEach(function(id) { + var node = RED.nodes.node(id); + try { + if (node._def.oneditdelete) { + node._def.oneditdelete.call(node); + } + } catch(err) { + console.log("oneditdelete",node.id,node.type,err.toString()); + } + historyEvent.nodes.push(node); + for (var i=0;i<node.users.length;i++) { + var user = node.users[i]; + historyEvent.changes[user.id] = { + changed: user.changed, + valid: user.valid + }; + for (var d in user._def.defaults) { + if (user._def.defaults.hasOwnProperty(d) && user[d] == id) { + historyEvent.changes[user.id][d] = id + user[d] = ""; + user.changed = true; + user.dirty = true; + } + } + RED.editor.validateNode(user); + } + RED.nodes.remove(id); + }) + RED.nodes.dirty(true); + RED.view.redraw(true); + RED.history.push(historyEvent); + } + }); + + + RED.events.on("view:selection-changed",function() { + $(content).find(".red-ui-palette-node").removeClass("selected"); + }); + + $("#red-ui-sidebar-config-collapse-all").on("click", function(e) { + e.preventDefault(); + for (var cat in categories) { + if (categories.hasOwnProperty(cat)) { + categories[cat].close(); + } + } + }); + $("#red-ui-sidebar-config-expand-all").on("click", function(e) { + e.preventDefault(); + for (var cat in categories) { + if (categories.hasOwnProperty(cat)) { + if (categories[cat].size() > 0) { + categories[cat].open(); + } + } + } + }); + $('#red-ui-sidebar-config-filter-all').on("click",function(e) { + e.preventDefault(); + if (showUnusedOnly) { + $(this).addClass('selected'); + $('#red-ui-sidebar-config-filter-unused').removeClass('selected'); + showUnusedOnly = !showUnusedOnly; + refreshConfigNodeList(); + } + }); + $('#red-ui-sidebar-config-filter-unused').on("click",function(e) { + e.preventDefault(); + if (!showUnusedOnly) { + $(this).addClass('selected'); + $('#red-ui-sidebar-config-filter-all').removeClass('selected'); + showUnusedOnly = !showUnusedOnly; + refreshConfigNodeList(); + } + }); + RED.popover.tooltip($('#red-ui-sidebar-config-filter-all'), RED._("sidebar.config.showAllUnusedConfigNodes")); + RED.popover.tooltip($('#red-ui-sidebar-config-filter-unused'), RED._("sidebar.config.showAllUnusedConfigNodes")); + + } + function show(id) { + if (typeof id === 'boolean') { + if (id) { + $('#red-ui-sidebar-config-filter-unused').trigger("click"); + } else { + $('#red-ui-sidebar-config-filter-all').trigger("click"); + } + } + refreshConfigNodeList(); + if (typeof id === "string") { + $('#red-ui-sidebar-config-filter-all').trigger("click"); + id = id.replace(/\./g,"-"); + setTimeout(function() { + var node = $(".red-ui-palette-node_id_"+id); + var y = node.position().top; + var h = node.height(); + var scrollWindow = $(".red-ui-sidebar-node-config"); + var scrollHeight = scrollWindow.height(); + + if (y+h > scrollHeight) { + scrollWindow.animate({scrollTop: '-='+(scrollHeight-(y+h)-30)},150); + } else if (y<0) { + scrollWindow.animate({scrollTop: '+='+(y-10)},150); + } + var flash = 21; + var flashFunc = function() { + if ((flash%2)===0) { + node.removeClass('node_highlighted'); + } else { + node.addClass('node_highlighted'); + } + flash--; + if (flash >= 0) { + setTimeout(flashFunc,100); + } + } + flashFunc(); + },100); + } + RED.sidebar.show("config"); + } + return { + init:init, + show:show, + refresh:refreshConfigNodeList + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js new file mode 100644 index 0000000..9994d50 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js @@ -0,0 +1,332 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.sidebar.context = (function() { + + var content; + var sections; + + var localCache = {}; + + var flowAutoRefresh; + var nodeAutoRefresh; + var nodeSection; + // var subflowSection; + var flowSection; + var globalSection; + + var currentNode; + var currentFlow; + + function init() { + + content = $("<div>").css({"position":"relative","height":"100%"}); + content.className = "red-ui-sidebar-context" + + var footerToolbar = $('<div></div>'); + + var stackContainer = $("<div>",{class:"red-ui-sidebar-context-stack"}).appendTo(content); + sections = RED.stack.create({ + container: stackContainer + }); + + nodeSection = sections.add({ + title: RED._("sidebar.context.node"), + collapsible: true + }); + nodeSection.expand(); + nodeSection.content.css({height:"100%"}); + nodeSection.timestamp = $('<div class="red-ui-sidebar-context-updated">&nbsp;</div>').appendTo(nodeSection.content); + var table = $('<table class="red-ui-info-table"></table>').appendTo(nodeSection.content); + nodeSection.table = $('<tbody>').appendTo(table); + var bg = $('<div style="float: right"></div>').appendTo(nodeSection.header); + + var nodeAutoRefreshSetting = RED.settings.get("editor.context.nodeRefresh",false); + nodeAutoRefresh = $('<input type="checkbox">').prop("checked",nodeAutoRefreshSetting).appendTo(bg).toggleButton({ + baseClass: "red-ui-sidebar-header-button red-ui-button-small", + enabledLabel: "", + disabledLabel: "" + }).on("change", function() { + var value = $(this).prop("checked"); + RED.settings.set("editor.context.flowRefresh",value); + }); + RED.popover.tooltip(nodeAutoRefresh.next(),RED._("sidebar.context.autoRefresh")); + + + var manualRefreshNode = $('<button class="red-ui-button red-ui-button-small" style="margin-left: 5px"><i class="fa fa-refresh"></i></button>') + .appendTo(bg) + .on("click", function(evt) { + evt.stopPropagation(); + evt.preventDefault(); + updateNode(currentNode, true); + }) + RED.popover.tooltip(manualRefreshNode,RED._("sidebar.context.refrsh")); + + flowSection = sections.add({ + title: RED._("sidebar.context.flow"), + collapsible: true + }); + flowSection.expand(); + flowSection.content.css({height:"100%"}); + flowSection.timestamp = $('<div class="red-ui-sidebar-context-updated">&nbsp;</div>').appendTo(flowSection.content); + var table = $('<table class="red-ui-info-table"></table>').appendTo(flowSection.content); + flowSection.table = $('<tbody>').appendTo(table); + bg = $('<div style="float: right"></div>').appendTo(flowSection.header); + + var flowAutoRefreshSetting = RED.settings.get("editor.context.flowRefresh",false); + flowAutoRefresh = $('<input type="checkbox">').prop("checked",flowAutoRefreshSetting).appendTo(bg).toggleButton({ + baseClass: "red-ui-sidebar-header-button red-ui-button-small", + enabledLabel: "", + disabledLabel: "" + }).on("change", function() { + var value = $(this).prop("checked"); + RED.settings.set("editor.context.flowRefresh",value); + }); + RED.popover.tooltip(flowAutoRefresh.next(),RED._("sidebar.context.autoRefresh")); + + var manualRefreshFlow = $('<button class="red-ui-button red-ui-button-small" style="margin-left: 5px"><i class="fa fa-refresh"></i></button>') + .appendTo(bg) + .on("click", function(evt) { + evt.stopPropagation(); + evt.preventDefault(); + updateFlow(currentFlow, true); + }) + RED.popover.tooltip(manualRefreshFlow,RED._("sidebar.context.refrsh")); + + globalSection = sections.add({ + title: RED._("sidebar.context.global"), + collapsible: true + }); + globalSection.expand(); + globalSection.content.css({height:"100%"}); + globalSection.timestamp = $('<div class="red-ui-sidebar-context-updated">&nbsp;</div>').appendTo(globalSection.content); + var table = $('<table class="red-ui-info-table"></table>').appendTo(globalSection.content); + globalSection.table = $('<tbody>').appendTo(table); + + bg = $('<div style="float: right"></div>').appendTo(globalSection.header); + $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-refresh"></i></button>') + .appendTo(bg) + .on("click", function(evt) { + evt.stopPropagation(); + evt.preventDefault(); + updateEntry(globalSection,"context/global","global"); + }) + RED.popover.tooltip(bg,RED._("sidebar.context.refrsh")); + + RED.actions.add("core:show-context-tab",show); + + RED.sidebar.addTab({ + id: "context", + label: RED._("sidebar.context.label"), + name: RED._("sidebar.context.name"), + iconClass: "fa fa-database", + content: content, + toolbar: footerToolbar, + // pinned: true, + enableOnEdit: true, + action: "core:show-context-tab" + }); + + RED.events.on("view:selection-changed", function(event) { + var selectedNode = event.nodes && event.nodes.length === 1 && event.nodes[0]; + updateNode(selectedNode); + }) + + RED.events.on("workspace:change", function(event) { + updateFlow(RED.nodes.workspace(event.workspace)); + }) + + $(globalSection.table).empty(); + $('<tr class="red-ui-help-info-row red-ui-search-empty blank" colspan="2"><td data-i18n="sidebar.context.refresh"></td></tr>').appendTo(globalSection.table).i18n(); + globalSection.timestamp.html("&nbsp;"); + } + + function updateNode(node,force) { + currentNode = node; + if (force || nodeAutoRefresh.prop("checked")) { + if (node) { + updateEntry(nodeSection,"context/node/"+node.id,node.id); + } else { + updateEntry(nodeSection) + } + } else { + $(nodeSection.table).empty(); + if (node) { + $('<tr class="red-ui-help-info-row red-ui-search-empty blank" colspan="2"><td data-i18n="sidebar.context.refresh"></td></tr>').appendTo(nodeSection.table).i18n(); + } else { + $('<tr class="red-ui-help-info-row red-ui-search-empty blank" colspan="2"><td data-i18n="sidebar.context.none"></td></tr>').appendTo(nodeSection.table).i18n(); + } + nodeSection.timestamp.html("&nbsp;"); + } + } + function updateFlow(flow, force) { + currentFlow = flow; + if (force || flowAutoRefresh.prop("checked")) { + if (flow) { + updateEntry(flowSection,"context/flow/"+flow.id,flow.id); + } else { + updateEntry(flowSection) + } + } else { + $(flowSection.table).empty(); + $('<tr class="red-ui-help-info-row red-ui-search-empty blank" colspan="2"><td data-i18n="sidebar.context.refresh"></td></tr>').appendTo(flowSection.table).i18n(); + flowSection.timestamp.html("&nbsp;"); + } + } + + function refreshEntry(section,baseUrl,id) { + + var contextStores = RED.settings.context.stores; + var container = section.table; + + $.getJSON(baseUrl, function(data) { + $(container).empty(); + var sortedData = {}; + for (var store in data) { + if (data.hasOwnProperty(store)) { + for (var key in data[store]) { + if (data[store].hasOwnProperty(key)) { + if (!sortedData.hasOwnProperty(key)) { + sortedData[key] = []; + } + data[store][key].store = store; + sortedData[key].push(data[store][key]) + } + } + } + } + var keys = Object.keys(sortedData); + keys.sort(); + var l = keys.length; + for (var i = 0; i < l; i++) { + sortedData[keys[i]].forEach(function(v) { + var k = keys[i]; + var l2 = sortedData[k].length; + var propRow = $('<tr class="red-ui-help-info-row"><td class="red-ui-sidebar-context-property"></td><td></td></tr>').appendTo(container); + var obj = $(propRow.children()[0]); + obj.text(k); + var tools = $('<span class="button-group"></span>'); + + var refreshItem = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-refresh"></i></button>').appendTo(tools).on("click", function(e) { + e.preventDefault(); + e.stopPropagation(); + $.getJSON(baseUrl+"/"+k+"?store="+v.store, function(data) { + if (data.msg !== payload || data.format !== format) { + payload = data.msg; + format = data.format; + tools.detach(); + $(propRow.children()[1]).empty(); + RED.utils.createObjectElement(RED.utils.decodeObject(payload,format), { + typeHint: data.format, + sourceId: id+"."+k, + tools: tools, + path: "" + }).appendTo(propRow.children()[1]); + } + }) + }); + RED.popover.tooltip(refreshItem,RED._("sidebar.context.refrsh")); + var deleteItem = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-trash"></i></button>').appendTo(tools).on("click", function(e) { + e.preventDefault(); + e.stopPropagation(); + var popover = RED.popover.create({ + trigger: 'modal', + target: propRow, + direction: "left", + content: function() { + var content = $('<div>'); + $('<p data-i18n="sidebar.context.deleteConfirm"></p>').appendTo(content); + var row = $('<p>').appendTo(content); + var bg = $('<span class="button-group"></span>').appendTo(row); + $('<button class="red-ui-button" data-i18n="common.label.cancel"></button>').appendTo(bg).on("click", function(e) { + e.preventDefault(); + popover.close(); + }); + bg = $('<span class="button-group"></span>').appendTo(row); + $('<button class="red-ui-button primary" data-i18n="common.label.delete"></button>').appendTo(bg).on("click", function(e) { + e.preventDefault(); + popover.close(); + $.ajax({ + url: baseUrl+"/"+k+"?store="+v.store, + type: "DELETE" + }).done(function(data,textStatus,xhr) { + $.getJSON(baseUrl+"/"+k+"?store="+v.store, function(data) { + if (data.format === 'undefined') { + propRow.remove(); + if (container.children().length === 0) { + $('<tr class="red-ui-help-info-row red-ui-search-empty blank" colspan="2"><td data-i18n="sidebar.context.empty"></td></tr>').appendTo(container).i18n(); + } + } else { + payload = data.msg; + format = data.format; + tools.detach(); + $(propRow.children()[1]).empty(); + RED.utils.createObjectElement(RED.utils.decodeObject(payload,format), { + typeHint: data.format, + sourceId: id+"."+k, + tools: tools, + path: "" + }).appendTo(propRow.children()[1]); + } + }); + }).fail(function(xhr,textStatus,err) { + + }) + }); + return content.i18n(); + } + }); + popover.open(); + + }); + RED.popover.tooltip(deleteItem,RED._("sidebar.context.delete")); + var payload = v.msg; + var format = v.format; + RED.utils.createObjectElement(RED.utils.decodeObject(payload,format), { + typeHint: v.format, + sourceId: id+"."+k, + tools: tools, + path: "" + }).appendTo(propRow.children()[1]); + if (contextStores.length > 1) { + $("<span>",{class:"red-ui-sidebar-context-property-storename"}).text(v.store).appendTo($(propRow.children()[0])) + } + }); + } + if (l === 0) { + $('<tr class="red-ui-help-info-row red-ui-search-empty blank" colspan="2"><td data-i18n="sidebar.context.empty"></td></tr>').appendTo(container).i18n(); + } + $(section.timestamp).text(new Date().toLocaleString()); + }); + } + function updateEntry(section,baseUrl,id) { + var container = section.table; + if (id) { + refreshEntry(section,baseUrl,id); + } else { + $(container).empty(); + $('<tr class="red-ui-help-info-row red-ui-search-empty blank" colspan="2"><td data-i18n="sidebar.context.none"></td></tr>').appendTo(container).i18n(); + } + } + + + + function show() { + RED.sidebar.show("context"); + } + return { + init: init + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js new file mode 100644 index 0000000..bfa4e4b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js @@ -0,0 +1,507 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.sidebar.info = (function() { + + var content; + var sections; + var propertiesSection; + var infoSection; + var helpSection; + var tipBox; + + var expandedSections = { + "property": false + }; + + function init() { + + content = document.createElement("div"); + content.className = "red-ui-sidebar-info" + + RED.actions.add("core:show-info-tab",show); + + var stackContainer = $("<div>",{class:"red-ui-sidebar-info-stack"}).appendTo(content); + + sections = RED.stack.create({ + container: stackContainer + }).hide(); + + propertiesSection = sections.add({ + title: RED._("sidebar.info.info"), + collapsible: true + }); + propertiesSection.expand(); + + infoSection = sections.add({ + title: RED._("sidebar.info.desc"), + collapsible: true + }); + infoSection.expand(); + infoSection.content.css("padding","6px"); + + helpSection = sections.add({ + title: RED._("sidebar.info.nodeHelp"), + collapsible: true + }); + helpSection.expand(); + helpSection.content.css("padding","6px"); + + var tipContainer = $('<div class="red-ui-help-tips"></div>').appendTo(content); + tipBox = $('<div class="red-ui-help-tip"></div>').appendTo(tipContainer); + var tipButtons = $('<div class="red-ui-help-tips-buttons"></div>').appendTo(tipContainer); + + var tipRefresh = $('<a href="#" class="red-ui-footer-button"><i class="fa fa-refresh"></a>').appendTo(tipButtons); + tipRefresh.on("click", function(e) { + e.preventDefault(); + tips.next(); + }) + + var tipClose = $('<a href="#" class="red-ui-footer-button"><i class="fa fa-times"></a>').appendTo(tipButtons); + tipClose.on("click", function(e) { + e.preventDefault(); + RED.actions.invoke("core:toggle-show-tips"); + RED.notify(RED._("sidebar.info.showTips")); + }); + + RED.sidebar.addTab({ + id: "info", + label: RED._("sidebar.info.label"), + name: RED._("sidebar.info.name"), + iconClass: "fa fa-info", + action:"core:show-info-tab", + content: content, + pinned: true, + enableOnEdit: true + }); + if (tips.enabled()) { + tips.start(); + } else { + tips.stop(); + } + + } + + function show() { + RED.sidebar.show("info"); + } + + // TODO: DRY - projects.js + function addTargetToExternalLinks(el) { + $(el).find("a").each(function(el) { + var href = $(this).attr('href'); + if (/^https?:/.test(href)) { + $(this).attr('target','_blank'); + } + }); + return el; + } + function refresh(node) { + if (node === undefined) { + refreshSelection(); + return; + } + sections.show(); + $(propertiesSection.content).empty(); + $(infoSection.content).empty(); + $(helpSection.content).empty(); + infoSection.title.text(RED._("sidebar.info.desc")); + + var propRow; + + var table = $('<table class="red-ui-info-table"></table>').appendTo(propertiesSection.content); + var tableBody = $('<tbody>').appendTo(table); + + var subflowNode; + var subflowUserCount; + + var activeProject = RED.projects.getActiveProject(); + if (activeProject) { + propRow = $('<tr class="red-ui-help-info-row"><td>'+ RED._("sidebar.project.name") + '</td><td></td></tr>').appendTo(tableBody); + $(propRow.children()[1]).text(activeProject.name||""); + $('<tr class="red-ui-help-property-expand blank"><td colspan="2"></td></tr>').appendTo(tableBody); + var editProjectButton = $('<button class="red-ui-button red-ui-button-small" style="position:absolute;right:2px;"><i class="fa fa-ellipsis-h"></i></button>') + .appendTo(propRow.children()[1]) + .on("click", function(evt) { + evt.preventDefault(); + RED.projects.editProject(); + }); + RED.popover.tooltip(editProjectButton,RED._('sidebar.project.showProjectSettings')); + } + propertiesSection.container.show(); + infoSection.container.show(); + helpSection.container.show(); + if (node === null) { + return; + } else if (Array.isArray(node)) { + // Multiple things selected + // - hide help and info sections + + var types = { + nodes:0, + flows:0, + subflows:0 + } + node.forEach(function(n) { + if (n.type === 'tab') { + types.flows++; + types.nodes += RED.nodes.filterNodes({z:n.id}).length; + } else if (n.type === 'subflow') { + types.subflows++; + } else { + types.nodes++; + } + }); + helpSection.container.hide(); + infoSection.container.hide(); + // - show the count of selected nodes + propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info.selection")+"</td><td></td></tr>").appendTo(tableBody); + + var counts = $('<div>').appendTo($(propRow.children()[1])); + if (types.flows > 0) { + $('<div>').text(RED._("clipboard.flow",{count:types.flows})).appendTo(counts); + } + if (types.subflows > 0) { + $('<div>').text(RED._("clipboard.subflow",{count:types.subflows})).appendTo(counts); + } + if (types.nodes > 0) { + $('<div>').text(RED._("clipboard.node",{count:types.nodes})).appendTo(counts); + } + } else { + // A single 'thing' selected. + + // Check to see if this is a subflow or subflow instance + var m = /^subflow(:(.+))?$/.exec(node.type); + if (m) { + if (m[2]) { + subflowNode = RED.nodes.subflow(m[2]); + } else { + subflowNode = node; + } + + subflowUserCount = 0; + var subflowType = "subflow:"+subflowNode.id; + RED.nodes.eachNode(function(n) { + if (n.type === subflowType) { + subflowUserCount++; + } + }); + } + if (node.type === "tab" || node.type === "subflow") { + // If nothing is selected, but we're on a flow or subflow tab. + propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info."+(node.type==='tab'?'flow':'subflow'))+'</td><td></td></tr>').appendTo(tableBody); + RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]); + propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info.tabName")+"</td><td></td></tr>").appendTo(tableBody); + $(propRow.children()[1]).text(node.label||node.name||""); + if (node.type === "tab") { + propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info.status")+'</td><td></td></tr>').appendTo(tableBody); + $(propRow.children()[1]).text((!!!node.disabled)?RED._("sidebar.info.enabled"):RED._("sidebar.info.disabled")) + } + } else { + // An actual node is selected in the editor - build up its properties table + propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info.node")+"</td><td></td></tr>").appendTo(tableBody); + RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]); + if (node.type !== "subflow" && node.type !== "unknown" && node.name) { + propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("common.label.name")+'</td><td></td></tr>').appendTo(tableBody); + $('<span class="red-ui-text-bidi-aware" dir="'+RED.text.bidi.resolveBaseTextDir(node.name)+'"></span>').text(node.name).appendTo(propRow.children()[1]); + } + if (!m) { + propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("sidebar.info.type")+"</td><td></td></tr>").appendTo(tableBody); + $(propRow.children()[1]).text((node.type === "unknown")?node._orig.type:node.type); + if (node.type === "unknown") { + $('<span style="float: right; font-size: 0.8em"><i class="fa fa-warning"></i></span>').prependTo($(propRow.children()[1])) + } + } + var count = 0; + if (!m && node.type != "subflow") { + var defaults; + if (node.type === 'unknown') { + defaults = {}; + Object.keys(node._orig).forEach(function(k) { + if (k !== 'type') { + defaults[k] = {}; + } + }) + } else if (node._def) { + defaults = node._def.defaults; + propRow = $('<tr class="red-ui-help-info-property-row'+(expandedSections.property?"":" hide")+'"><td>'+RED._("sidebar.info.module")+"</td><td></td></tr>").appendTo(tableBody); + $(propRow.children()[1]).text(RED.nodes.getType(node.type).set.module); + count++; + } + $('<tr class="red-ui-help-property-expand red-ui-help-info-property-row blank'+(expandedSections.property?"":" hide")+'"><td colspan="2"></td></tr>').appendTo(tableBody); + + if (defaults) { + for (var n in defaults) { + if (n != "name" && n != "info" && defaults.hasOwnProperty(n)) { + var val = node[n]; + var type = typeof val; + count++; + propRow = $('<tr class="red-ui-help-info-property-row'+(expandedSections.property?"":" hide")+'"><td>'+n+"</td><td></td></tr>").appendTo(tableBody); + if (defaults[n].type) { + var configNode = RED.nodes.node(val); + if (!configNode) { + RED.utils.createObjectElement(undefined).appendTo(propRow.children()[1]); + } else { + var configLabel = RED.utils.getNodeLabel(configNode,val); + var container = propRow.children()[1]; + + var div = $('<span>',{class:""}).appendTo(container); + var nodeDiv = $('<div>',{class:"red-ui-palette-node red-ui-palette-node-small"}).appendTo(div); + var colour = RED.utils.getNodeColor(configNode.type,configNode._def); + var icon_url = RED.utils.getNodeIcon(configNode._def); + nodeDiv.css({'backgroundColor':colour, "cursor":"pointer"}); + var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv); + $('<div/>',{class:"red-ui-palette-icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer); + var nodeContainer = $('<span></span>').css({"verticalAlign":"top","marginLeft":"6px"}).text(configLabel).appendTo(container); + + nodeDiv.on('dblclick',function() { + RED.editor.editConfig("", configNode.type, configNode.id); + }) + + } + } else { + RED.utils.createObjectElement(val).appendTo(propRow.children()[1]); + } + } + } + } + if (count > 0) { + $('<tr class="red-ui-help-property-expand blank"><td colspan="2"><a href="#" class="node-info-property-header'+(expandedSections.property?" expanded":"")+'"><span class="red-ui-help-property-more">'+RED._("sidebar.info.showMore")+'</span><span class="red-ui-help-property-less">'+RED._("sidebar.info.showLess")+'</span> <i class="fa fa-caret-down"></i></a></td></tr>').appendTo(tableBody); + } + } + if (node.type !== 'tab') { + if (m) { + $('<tr class="blank"><th colspan="2">'+RED._("sidebar.info.subflow")+'</th></tr>').appendTo(tableBody); + $('<tr class="node-info-subflow-row"><td>'+RED._("common.label.name")+'</td><td><span class="red-ui-text-bidi-aware" dir=\"'+RED.text.bidi.resolveBaseTextDir(subflowNode.name)+'">'+RED.utils.sanitize(subflowNode.name)+'</span></td></tr>').appendTo(tableBody); + } + } + } + if (m) { + propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("subflow.category")+'</td><td></td></tr>').appendTo(tableBody); + var category = subflowNode.category||"subflows"; + $(propRow.children()[1]).text(RED._("palette.label."+category,{defaultValue:category})) + $('<tr class="node-info-subflow-row"><td>'+RED._("sidebar.info.instances")+"</td><td>"+subflowUserCount+'</td></tr>').appendTo(tableBody); + } + + var helpText = ""; + if (node.type === "tab" || node.type === "subflow") { + $(helpSection.container).hide(); + } else { + $(helpSection.container).show(); + if (subflowNode && node.type !== "subflow") { + // Selected a subflow instance node. + // - The subflow template info goes into help + helpText = (RED.utils.renderMarkdown(subflowNode.info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>')); + } else { + helpText = $("script[data-help-name='"+node.type+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>'); + } + setInfoText(helpText, helpSection.content); + } + + var infoText = ""; + + if (node._def && node._def.info) { + var info = node._def.info; + var textInfo = (typeof info === "function" ? info.call(node) : info); + infoText = infoText + RED.utils.renderMarkdown(textInfo); + } + if (node.info) { + infoText = infoText + RED.utils.renderMarkdown(node.info || "") + } + setInfoText(infoText, infoSection.content); + + $(".red-ui-sidebar-info-stack").scrollTop(0); + $(".node-info-property-header").on("click", function(e) { + e.preventDefault(); + expandedSections["property"] = !expandedSections["property"]; + $(this).toggleClass("expanded",expandedSections["property"]); + $(".red-ui-help-info-property-row").toggle(expandedSections["property"]); + }); + } + + + // $('<tr class="blank"><th colspan="2"></th></tr>').appendTo(tableBody); + // propRow = $('<tr class="red-ui-help-info-row"><td>Actions</td><td></td></tr>').appendTo(tableBody); + // var actionBar = $(propRow.children()[1]); + // + // // var actionBar = $('<div>',{style:"background: #fefefe; padding: 3px;"}).appendTo(propertiesSection.content); + // $('<button type="button" class="red-ui-button"><i class="fa fa-code"></i></button>').appendTo(actionBar); + // $('<button type="button" class="red-ui-button"><i class="fa fa-code"></i></button>').appendTo(actionBar); + // $('<button type="button" class="red-ui-button"><i class="fa fa-code"></i></button>').appendTo(actionBar); + // $('<button type="button" class="red-ui-button"><i class="fa fa-code"></i></button>').appendTo(actionBar); + + + + } + function setInfoText(infoText,target) { + var info = addTargetToExternalLinks($('<div class="red-ui-help"><span class="red-ui-text-bidi-aware" dir=\"'+RED.text.bidi.resolveBaseTextDir(infoText)+'">'+infoText+'</span></div>')).appendTo(target); + info.find(".red-ui-text-bidi-aware").contents().filter(function() { return this.nodeType === 3 && this.textContent.trim() !== "" }).wrap( "<span></span>" ); + var foldingHeader = "H3"; + info.find(foldingHeader).wrapInner('<a class="red-ui-help-info-header expanded" href="#"></a>') + .find("a").prepend('<i class="fa fa-angle-right">').on("click", function(e) { + e.preventDefault(); + var isExpanded = $(this).hasClass('expanded'); + var el = $(this).parent().next(); + while(el.length === 1 && el[0].nodeName !== foldingHeader) { + el.toggle(!isExpanded); + el = el.next(); + } + $(this).toggleClass('expanded',!isExpanded); + }) + } + var tips = (function() { + var enabled = true; + var startDelay = 1000; + var cycleDelay = 15000; + var startTimeout; + var refreshTimeout; + var tipCount = -1; + + RED.actions.add("core:toggle-show-tips",function(state) { + if (state === undefined) { + RED.userSettings.toggle("view-show-tips"); + } else { + enabled = state; + if (enabled) { + startTips(); + } else { + stopTips(); + } + } + }); + + function setTip() { + var r = Math.floor(Math.random() * tipCount); + var tip = RED._("infotips:info.tip"+r); + + var m; + while ((m=/({{(.*?)}})/.exec(tip))) { + var shortcut = RED.keyboard.getShortcut(m[2]); + if (shortcut) { + tip = tip.replace(m[1],RED.keyboard.formatKey(shortcut.key)); + } else { + return; + } + } + while ((m=/(\[(.*?)\])/.exec(tip))) { + tip = tip.replace(m[1],RED.keyboard.formatKey(m[2])); + } + tipBox.html(tip).fadeIn(200); + if (startTimeout) { + startTimeout = null; + refreshTimeout = setInterval(cycleTips,cycleDelay); + } + } + function cycleTips() { + tipBox.fadeOut(300,function() { + setTip(); + }) + } + function startTips() { + $(".red-ui-sidebar-info").addClass('show-tips'); + if (enabled) { + if (!startTimeout && !refreshTimeout) { + if (tipCount === -1) { + do { + tipCount++; + } while(RED._("infotips:info.tip"+tipCount)!=="infotips:info.tip"+tipCount); + } + startTimeout = setTimeout(setTip,startDelay); + } + } + } + function stopTips() { + $(".red-ui-sidebar-info").removeClass('show-tips'); + clearInterval(refreshTimeout); + clearTimeout(startTimeout); + refreshTimeout = null; + startTimeout = null; + } + function nextTip() { + clearInterval(refreshTimeout); + startTimeout = true; + setTip(); + } + return { + start: startTips, + stop: stopTips, + next: nextTip, + enabled: function() { return enabled; } + } + })(); + + function clear() { + // sections.hide(); + refresh(null); + } + + function set(html,title) { + // tips.stop(); + // sections.show(); + refresh(null); + propertiesSection.container.hide(); + helpSection.container.hide(); + infoSection.container.show(); + infoSection.title.text(title||RED._("sidebar.info.desc")); + setInfoText(html,infoSection.content); + $(".red-ui-sidebar-info-stack").scrollTop(0); + } + + function refreshSelection(selection) { + if (selection === undefined) { + selection = RED.view.selection(); + } + if (selection.nodes) { + if (selection.nodes.length == 1) { + var node = selection.nodes[0]; + if (node.type === "subflow" && node.direction) { + refresh(RED.nodes.subflow(node.z)); + } else { + refresh(node); + } + } else { + refresh(selection.nodes); + } + } else if (selection.flows || selection.subflows) { + refresh(selection.flows); + } else { + var activeWS = RED.workspaces.active(); + + var flow = RED.nodes.workspace(activeWS) || RED.nodes.subflow(activeWS); + if (flow) { + refresh(flow); + } else { + var workspace = RED.nodes.workspace(RED.workspaces.active()); + if (workspace && workspace.info) { + refresh(workspace); + } else { + refresh(null) + // clear(); + } + } + } + } + + + RED.events.on("view:selection-changed",refreshSelection); + + return { + init: init, + show: show, + refresh: refresh, + clear: clear, + set: set + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/touch/radialMenu.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/touch/radialMenu.js new file mode 100644 index 0000000..a7c9704 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/touch/radialMenu.js @@ -0,0 +1,151 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +RED.touch = RED.touch||{}; +RED.touch.radialMenu = (function() { + + + var touchMenu = null; + var isActive = false; + var isOutside = false; + var activeOption = null; + + + function createRadial(obj,pos,options) { + isActive = true; + try { + touchMenu = d3.select("body").append("div").classed("red-ui-editor-radial-menu",true) + .on('touchstart',function() { + hide(); + d3.event.preventDefault(); + }); + + var menu = touchMenu.append("div") + .style({ + top: (pos[1]-80)+"px", + left:(pos[0]-80)+"px", + }); + + var menuOpts = []; + var createMenuOpt = function(x,y,opt) { + opt.el = menu.append("div").classed("red-ui-editor-radial-menu-opt",true) + .style({ + top: (y+80-25)+"px", + left:(x+80-25)+"px" + }) + .classed("red-ui-editor-radial-menu-opt-disabled",!!opt.disabled) + + opt.el.html(opt.name); + + opt.x = x; + opt.y = y; + menuOpts.push(opt); + + opt.el.on('touchstart',function() { + opt.el.classed("red-ui-editor-radial-menu-opt-active",true) + d3.event.preventDefault(); + d3.event.stopPropagation(); + }); + opt.el.on('touchend',function() { + hide(); + opt.onselect(); + d3.event.preventDefault(); + d3.event.stopPropagation(); + }); + } + + var n = options.length; + var dang = Math.max(Math.PI/(n-1),Math.PI/4); + var ang = Math.PI; + for (var i=0;i<n;i++) { + var x = Math.floor(Math.cos(ang)*80); + var y = Math.floor(Math.sin(ang)*80); + if (options[i].name) { + createMenuOpt(x,y,options[i]); + } + ang += dang; + } + + + var hide = function() { + isActive = false; + activeOption = null; + touchMenu.remove(); + touchMenu = null; + } + + obj.on('touchend.radial',function() { + obj.on('touchend.radial',null); + obj.on('touchmenu.radial',null); + + if (activeOption) { + try { + activeOption.onselect(); + } catch(err) { + RED._debug(err); + } + hide(); + } else if (isOutside) { + hide(); + } + }); + + obj.on('touchmove.radial',function() { + try { + var touch0 = d3.event.touches.item(0); + var p = [touch0.pageX - pos[0],touch0.pageY-pos[1]]; + for (var i=0;i<menuOpts.length;i++) { + var opt = menuOpts[i]; + if (!opt.disabled) { + if (p[0]>opt.x-30 && p[0]<opt.x+30 && p[1]>opt.y-30 && p[1]<opt.y+30) { + if (opt !== activeOption) { + opt.el.style("background","#999"); + activeOption = opt; + } + } else if (opt === activeOption) { + opt.el.style("background","#fff"); + activeOption = null; + } else { + opt.el.style("background","#fff"); + } + } + } + if (!activeOption) { + var d = Math.abs((p[0]*p[0])+(p[1]*p[1])); + isOutside = (d > 80*80); + } + + } catch(err) { + RED._debug(err); + } + + + }); + + } catch(err) { + RED._debug(err); + } + } + + + return { + show: createRadial, + active: function() { + return isActive; + } + } + +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/tray.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/tray.js new file mode 100644 index 0000000..33a1865 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/tray.js @@ -0,0 +1,312 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.tray = (function() { + + var stack = []; + var editorStack; + var openingTray = false; + var stackHidden = false; + + function resize() { + + } + function showTray(options) { + var el = $('<div class="red-ui-tray"></div>'); + // `editor-tray-header` is deprecated - use red-ui-tray-body instead + var header = $('<div class="red-ui-tray-header editor-tray-header"></div>').appendTo(el); + var bodyWrapper = $('<div class="red-ui-tray-body-wrapper"></div>').appendTo(el); + // `editor-tray-body` is deprecated - use red-ui-tray-body instead + var body = $('<div class="red-ui-tray-body editor-tray-body"></div>').appendTo(bodyWrapper); + // `editor-tray-footer` is deprecated - use red-ui-tray-footer instead + var footer = $('<div class="red-ui-tray-footer"></div>').appendTo(el); + var resizer = $('<div class="red-ui-tray-resize-handle"></div>').appendTo(el); + // var growButton = $('<a class="red-ui-tray-resize-button" style="cursor: w-resize;"><i class="fa fa-angle-left"></i></a>').appendTo(resizer); + // var shrinkButton = $('<a class="red-ui-tray-resize-button" style="cursor: e-resize;"><i style="margin-left: 1px;" class="fa fa-angle-right"></i></a>').appendTo(resizer); + if (options.title) { + var titles = stack.map(function(e) { return e.options.title }); + titles.push(options.title); + var title = '<ul class="red-ui-tray-breadcrumbs"><li>'+titles.join("</li><li>")+'</li></ul>'; + + $('<div class="red-ui-tray-titlebar">'+title+'</div>').appendTo(header); + } + if (options.width === Infinity) { + options.maximized = true; + resizer.addClass('red-ui-tray-resize-maximised'); + } + var buttonBar = $('<div class="red-ui-tray-toolbar"></div>').appendTo(header); + var primaryButton; + if (options.buttons) { + for (var i=0;i<options.buttons.length;i++) { + var button = options.buttons[i]; + var b = $('<button>').button().appendTo(buttonBar); + if (button.id) { + b.attr('id',button.id); + } + if (button.text) { + b.text(button.text); + } + if (button.click) { + b.on("click", (function(action) { + return function(evt) { + if (!$(this).hasClass('disabled')) { + action(evt); + } + }; + })(button.click)); + } + if (button.class) { + b.addClass(button.class); + if (button.class === "primary") { + primaryButton = button; + } + } + } + } + el.appendTo(editorStack); + var tray = { + tray: el, + header: header, + body: body, + footer: footer, + options: options, + primaryButton: primaryButton + }; + stack.push(tray); + + if (!options.maximized) { + el.draggable({ + handle: resizer, + axis: "x", + start:function(event,ui) { + el.width('auto'); + }, + drag: function(event,ui) { + var absolutePosition = editorStack.position().left+ui.position.left + if (absolutePosition < 7) { + ui.position.left += 7-absolutePosition; + } else if (ui.position.left > -tray.preferredWidth-1) { + ui.position.left = -Math.min(editorStack.position().left-7,tray.preferredWidth-1); + } + if (tray.options.resize) { + setTimeout(function() { + tray.options.resize({width: -ui.position.left}); + },0); + } + tray.width = -ui.position.left; + }, + stop:function(event,ui) { + el.width(-ui.position.left); + el.css({left:''}); + if (tray.options.resize) { + tray.options.resize({width: -ui.position.left}); + } + tray.width = -ui.position.left; + } + }); + } + + function finishBuild() { + $("#red-ui-header-shade").show(); + $("#red-ui-editor-shade").show(); + $("#red-ui-palette-shade").show(); + $(".red-ui-sidebar-shade").show(); + tray.preferredWidth = Math.max(el.width(),500); + if (!options.maximized) { + body.css({"minWidth":tray.preferredWidth-40}); + } + if (options.width) { + if (options.width > $("#red-ui-editor-stack").position().left-8) { + options.width = $("#red-ui-editor-stack").position().left-8; + } + el.width(options.width); + } else { + el.width(tray.preferredWidth); + } + + tray.width = el.width(); + if (tray.width > $("#red-ui-editor-stack").position().left-8) { + tray.width = Math.max(0/*tray.preferredWidth*/,$("#red-ui-editor-stack").position().left-8); + el.width(tray.width); + } + + // tray.body.parent().width(Math.min($("#red-ui-editor-stack").position().left-8,tray.width)); + + + $("#red-ui-main-container").scrollLeft(0); + el.css({ + right: -(el.width()+10)+"px", + transition: "right 0.25s ease" + }); + handleWindowResize(); + openingTray = true; + setTimeout(function() { + setTimeout(function() { + if (!options.width) { + el.width(Math.min(tray.preferredWidth,$("#red-ui-editor-stack").position().left-8)); + } + if (options.resize) { + options.resize({width:el.width()}); + } + if (options.show) { + options.show(); + } + setTimeout(function() { + // Delay resetting the flag, so we don't close prematurely + openingTray = false; + },200); + body.find(":focusable:first").trigger("focus"); + + },150); + el.css({right:0}); + },0); + } + if (options.open) { + if (options.open.length === 1) { + options.open(el); + finishBuild(); + } else { + options.open(el,finishBuild); + } + } else { + finishBuild(); + } + } + + function handleWindowResize() { + if (stack.length > 0) { + var tray = stack[stack.length-1]; + if (tray.options.maximized || tray.width > $("#red-ui-editor-stack").position().left-8) { + tray.width = $("#red-ui-editor-stack").position().left-8; + tray.tray.width(tray.width); + // tray.body.parent().width(tray.width); + } else if (tray.width < tray.preferredWidth) { + tray.width = Math.min($("#red-ui-editor-stack").position().left-8,tray.preferredWidth); + tray.tray.width(tray.width); + // tray.body.parent().width(tray.width); + } + var trayHeight = tray.tray.height()-tray.header.outerHeight()-tray.footer.outerHeight(); + tray.body.height(trayHeight); + if (tray.options.resize) { + tray.options.resize({width:tray.width, height:trayHeight}); + } + + } + } + + return { + init: function init() { + editorStack = $("#red-ui-editor-stack"); + $(window).on("resize", handleWindowResize); + RED.events.on("sidebar:resize",handleWindowResize); + $("#red-ui-editor-shade").on("click", function() { + if (!openingTray) { + var tray = stack[stack.length-1]; + if (tray && tray.primaryButton) { + tray.primaryButton.click(); + } + } + }); + }, + show: function show(options) { + if (!options) { + if (stack.length > 0) { + var tray = stack[stack.length-1]; + tray.tray.css({right:0}); + $("#red-ui-header-shade").show(); + $("#red-ui-editor-shade").show(); + $("#red-ui-palette-shade").show(); + $(".red-ui-sidebar-shade").show(); + stackHidden = false; + } + } else if (stackHidden) { + throw new Error("Cannot add to stack whilst hidden"); + } else if (stack.length > 0 && !options.overlay) { + var oldTray = stack[stack.length-1]; + if (options.width === "inherit") { + options.width = oldTray.tray.width(); + } + oldTray.tray.css({ + right: -(oldTray.tray.width()+10)+"px" + }); + setTimeout(function() { + oldTray.tray.detach(); + showTray(options); + },250) + } else { + RED.events.emit("editor:open"); + showTray(options); + } + + }, + hide: function hide() { + if (stack.length > 0) { + var tray = stack[stack.length-1]; + tray.tray.css({ + right: -(tray.tray.width()+10)+"px" + }); + $("#red-ui-header-shade").hide(); + $("#red-ui-editor-shade").hide(); + $("#red-ui-palette-shade").hide(); + $(".red-ui-sidebar-shade").hide(); + stackHidden = true; + } + }, + resize: handleWindowResize, + close: function close(done) { + if (stack.length > 0) { + var tray = stack.pop(); + tray.tray.css({ + right: -(tray.tray.width()+10)+"px" + }); + setTimeout(function() { + if (tray.options.close) { + tray.options.close(); + } + tray.tray.remove(); + if (stack.length > 0) { + var oldTray = stack[stack.length-1]; + if (!oldTray.options.overlay) { + oldTray.tray.appendTo("#red-ui-editor-stack"); + setTimeout(function() { + handleWindowResize(); + oldTray.tray.css({right:0}); + if (oldTray.options.show) { + oldTray.options.show(); + } + },0); + } else { + handleWindowResize(); + if (oldTray.options.show) { + oldTray.options.show(); + } + } + } + if (done) { + done(); + } + if (stack.length === 0) { + $("#red-ui-header-shade").hide(); + $("#red-ui-editor-shade").hide(); + $("#red-ui-palette-shade").hide(); + $(".red-ui-sidebar-shade").hide(); + RED.events.emit("editor:close"); + RED.view.focus(); + } + },250) + } + } + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/typeSearch.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/typeSearch.js new file mode 100644 index 0000000..d41a6a4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/typeSearch.js @@ -0,0 +1,391 @@ +RED.typeSearch = (function() { + + var shade; + + var disabled = false; + var dialog = null; + var searchInput; + var searchResults; + var searchResultsDiv; + var selected = -1; + var visible = false; + + var activeFilter = ""; + var addCallback; + var cancelCallback; + var moveCallback; + + var typesUsed = {}; + + function search(val) { + activeFilter = val.toLowerCase(); + var visible = searchResults.editableList('filter'); + searchResults.editableList('sort'); + setTimeout(function() { + selected = 0; + searchResults.children().removeClass('selected'); + searchResults.children(":visible:first").addClass('selected'); + },100); + + } + + function ensureSelectedIsVisible() { + var selectedEntry = searchResults.find("li.selected"); + if (selectedEntry.length === 1) { + var scrollWindow = searchResults.parent(); + var scrollHeight = scrollWindow.height(); + var scrollOffset = scrollWindow.scrollTop(); + var y = selectedEntry.position().top; + var h = selectedEntry.height(); + if (y+h > scrollHeight) { + scrollWindow.animate({scrollTop: '-='+(scrollHeight-(y+h)-10)},50); + } else if (y<0) { + scrollWindow.animate({scrollTop: '+='+(y-10)},50); + } + } + } + + function moveDialog(dx,dy) { + var pos = dialog.position(); + pos.top = (pos.top + dy)+"px"; + pos.left = (pos.left + dx)+"px"; + dialog.css(pos); + moveCallback(dx,dy); + + } + function createDialog() { + dialog = $("<div>",{id:"red-ui-type-search",class:"red-ui-search red-ui-type-search"}).appendTo("#red-ui-main-container"); + var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(dialog); + searchInput = $('<input type="text" id="red-ui-type-search-input">').attr("placeholder",RED._("search.addNode")).appendTo(searchDiv).searchBox({ + delay: 50, + change: function() { + search($(this).val()); + } + }); + searchInput.on('keydown',function(evt) { + var children = searchResults.children(":visible"); + if (evt.keyCode === 40 && evt.shiftKey) { + evt.preventDefault(); + moveDialog(0,10); + } else if (evt.keyCode === 38 && evt.shiftKey) { + evt.preventDefault(); + moveDialog(0,-10); + } else if (evt.keyCode === 39 && evt.shiftKey) { + evt.preventDefault(); + moveDialog(10,0); + } else if (evt.keyCode === 37 && evt.shiftKey) { + evt.preventDefault(); + moveDialog(-10,0); + } else if (children.length > 0) { + if (evt.keyCode === 40) { + // Down + if (selected < children.length-1) { + if (selected > -1) { + $(children[selected]).removeClass('selected'); + } + selected++; + } + $(children[selected]).addClass('selected'); + ensureSelectedIsVisible(); + evt.preventDefault(); + } else if (evt.keyCode === 38) { + if (selected > 0) { + if (selected < children.length) { + $(children[selected]).removeClass('selected'); + } + selected--; + } + $(children[selected]).addClass('selected'); + ensureSelectedIsVisible(); + evt.preventDefault(); + } else if ((evt.metaKey || evt.ctrlKey) && evt.keyCode === 13 ) { + evt.preventDefault(); + // (ctrl or cmd) and enter + var index = Math.max(0,selected); + if (index < children.length) { + var n = $(children[index]).find(".red-ui-editableList-item-content").data('data'); + typesUsed[n.type] = Date.now(); + if (n.def.outputs === 0) { + confirm(n); + } else { + addCallback(n.type,true); + } + $("#red-ui-type-search-input").val("").trigger("keyup"); + setTimeout(function() { + $("#red-ui-type-search-input").focus(); + },100); + } + } else if (evt.keyCode === 13) { + evt.preventDefault(); + // Enter + var index = Math.max(0,selected); + if (index < children.length) { + // TODO: dips into editableList impl details + confirm($(children[index]).find(".red-ui-editableList-item-content").data('data')); + } + } + } else { + if (evt.keyCode === 13 ) { + // Stop losing focus if [Cmd]-Enter is pressed on an empty list + evt.stopPropagation(); + evt.preventDefault(); + } + } + }); + + searchResultsDiv = $("<div>",{class:"red-ui-search-results-container"}).appendTo(dialog); + searchResults = $('<ol>',{style:"position: absolute;top: 0;bottom: 0;left: 0;right: 0;"}).appendTo(searchResultsDiv).editableList({ + addButton: false, + filter: function(data) { + if (activeFilter === "" ) { + return true; + } + if (data.recent || data.common) { + return false; + } + return (activeFilter==="")||(data.index.indexOf(activeFilter) > -1); + }, + sort: function(A,B) { + if (activeFilter === "") { + return A.i - B.i; + } + var Ai = A.index.indexOf(activeFilter); + var Bi = B.index.indexOf(activeFilter); + if (Ai === -1) { + return 1; + } + if (Bi === -1) { + return -1; + } + if (Ai === Bi) { + return sortTypeLabels(A,B); + } + return Ai-Bi; + }, + addItem: function(container,i,object) { + var def = object.def; + object.index = object.type.toLowerCase(); + if (object.separator) { + container.addClass("red-ui-search-result-separator") + } + var div = $('<div>',{class:"red-ui-search-result"}).appendTo(container); + + var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(div); + var colour = RED.utils.getNodeColor(object.type,def); + var icon_url = RED.utils.getNodeIcon(def); + nodeDiv.css('backgroundColor',colour); + + var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv); + RED.utils.createIconElement(icon_url, iconContainer, false); + + if (def.inputs > 0) { + $('<div/>',{class:"red-ui-search-result-node-port"}).appendTo(nodeDiv); + } + if (def.outputs > 0) { + $('<div/>',{class:"red-ui-search-result-node-port red-ui-search-result-node-output"}).appendTo(nodeDiv); + } + + var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div); + + var label = object.label; + object.index += "|"+label.toLowerCase(); + + $('<div>',{class:"red-ui-search-result-node-label"}).text(label).appendTo(contentDiv); + + div.on("click", function(evt) { + evt.preventDefault(); + confirm(object); + }); + }, + scrollOnAdd: false + }); + + } + function confirm(def) { + hide(); + typesUsed[def.type] = Date.now(); + addCallback(def.type); + } + + function handleMouseActivity(evt) { + if (visible) { + var t = $(evt.target); + while (t.prop('nodeName').toLowerCase() !== 'body') { + if (t.attr('id') === 'red-ui-type-search') { + return; + } + t = t.parent(); + } + hide(true); + if (cancelCallback) { + cancelCallback(); + } + } + } + function show(opts) { + if (!visible) { + RED.keyboard.add("*","escape",function(){ + hide(); + if (cancelCallback) { + cancelCallback(); + } + }); + if (dialog === null) { + createDialog(); + } + visible = true; + } else { + dialog.hide(); + searchResultsDiv.hide(); + } + $(document).off('mousedown.red-ui-type-search'); + $(document).off('mouseup.red-ui-type-search'); + $(document).off('click.red-ui-type-search'); + setTimeout(function() { + $(document).on('mousedown.red-ui-type-search',handleMouseActivity); + $(document).on('mouseup.red-ui-type-search',handleMouseActivity); + $(document).on('click.red-ui-type-search',handleMouseActivity); + },200); + + refreshTypeList(opts); + addCallback = opts.add; + cancelCallback = opts.cancel; + moveCallback = opts.move; + RED.events.emit("type-search:open"); + //shade.show(); + if ($("#red-ui-main-container").height() - opts.y - 150 < 0) { + opts.y = opts.y - 235; + } + dialog.css({left:opts.x+"px",top:opts.y+"px"}).show(); + searchResultsDiv.slideDown(300); + setTimeout(function() { + searchResultsDiv.find(".red-ui-editableList-container").scrollTop(0); + searchInput.trigger("focus"); + },100); + } + function hide(fast) { + if (visible) { + RED.keyboard.remove("escape"); + visible = false; + if (dialog !== null) { + searchResultsDiv.slideUp(fast?50:200,function() { + dialog.hide(); + searchInput.searchBox('value',''); + }); + //shade.hide(); + } + RED.events.emit("type-search:close"); + RED.view.focus(); + $(document).off('mousedown.red-ui-type-search'); + $(document).off('mouseup.red-ui-type-search'); + $(document).off('click.red-ui-type-search'); + } + } + function getTypeLabel(type, def) { + var label = type; + if (typeof def.paletteLabel !== "undefined") { + try { + label = (typeof def.paletteLabel === "function" ? def.paletteLabel.call(def) : def.paletteLabel)||""; + label += " ("+type+")"; + } catch(err) { + console.log("Definition error: "+type+".paletteLabel",err); + } + } + return label; + } + function sortTypeLabels(a,b) { + var al = a.label.toLowerCase(); + var bl = b.label.toLowerCase(); + if (al < bl) { + return -1; + } else if (al === bl) { + return 0; + } else { + return 1; + } + } + function applyFilter(filter,type,def) { + return !filter || + ( + (!filter.type || type === filter.type) && + (!filter.input || def.inputs > 0) && + (!filter.output || def.outputs > 0) + ) + } + function refreshTypeList(opts) { + var i; + searchResults.editableList('empty'); + searchInput.searchBox('value','').focus(); + selected = -1; + var common = [ + 'inject','debug','function','change','switch' + ].filter(function(t) { return applyFilter(opts.filter,t,RED.nodes.getType(t)); }); + + var recentlyUsed = Object.keys(typesUsed); + recentlyUsed.sort(function(a,b) { + return typesUsed[b]-typesUsed[a]; + }); + recentlyUsed = recentlyUsed.filter(function(t) { + return applyFilter(opts.filter,t,RED.nodes.getType(t)) && common.indexOf(t) === -1; + }); + + var items = []; + RED.nodes.registry.getNodeTypes().forEach(function(t) { + var def = RED.nodes.getType(t); + if (def.category !== 'config' && t !== 'unknown' && t !== 'tab') { + items.push({type:t,def: def, label:getTypeLabel(t,def)}); + } + }); + items.sort(sortTypeLabels); + + var commonCount = 0; + var item; + var index = 0; + for(i=0;i<common.length;i++) { + var itemDef = RED.nodes.getType(common[i]); + if (itemDef) { + item = { + type: common[i], + common: true, + def: itemDef, + i: index++ + }; + item.label = getTypeLabel(item.type,item.def); + if (i === common.length-1) { + item.separator = true; + } + searchResults.editableList('addItem', item); + } + } + for(i=0;i<Math.min(5,recentlyUsed.length);i++) { + item = { + type:recentlyUsed[i], + def: RED.nodes.getType(recentlyUsed[i]), + recent: true, + i: index++ + }; + item.label = getTypeLabel(item.type,item.def); + if (i === recentlyUsed.length-1) { + item.separator = true; + } + searchResults.editableList('addItem', item); + } + for (i=0;i<items.length;i++) { + if (applyFilter(opts.filter,items[i].type,items[i].def)) { + items[i].i = index++; + searchResults.editableList('addItem', items[i]); + } + } + setTimeout(function() { + selected = 0; + searchResults.children(":first").addClass('selected'); + },100); + } + + return { + show: show, + refresh: refreshTypeList, + hide: hide + }; + +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/userSettings.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/userSettings.js new file mode 100644 index 0000000..07ab121 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/userSettings.js @@ -0,0 +1,289 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +RED.userSettings = (function() { + + var trayWidth = 700; + var settingsVisible = false; + + var panes = []; + + function addPane(options) { + panes.push(options); + } + + function show(initialTab) { + if (settingsVisible) { + return; + } + if (!RED.user.hasPermission("settings.write")) { + RED.notify(RED._("user.errors.settings"),"error"); + return; + } + settingsVisible = true; + + var trayOptions = { + title: RED._("menu.label.userSettings"), + buttons: [ + { + id: "node-dialog-ok", + text: RED._("common.label.close"), + class: "primary", + click: function() { + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + trayWidth = dimensions.width; + }, + open: function(tray) { + var trayBody = tray.find('.red-ui-tray-body'); + var settingsContent = $('<div></div>').appendTo(trayBody); + var tabContainer = $('<div></div>',{class:"red-ui-settings-tabs-container"}).appendTo(settingsContent); + + $('<ul></ul>',{id:"user-settings-tabs"}).appendTo(tabContainer); + var settingsTabs = RED.tabs.create({ + id: "user-settings-tabs", + vertical: true, + onchange: function(tab) { + setTimeout(function() { + tabContents.children().hide(); + $("#" + tab.id).show(); + if (tab.pane.focus) { + tab.pane.focus(); + } + },50); + } + }); + var tabContents = $('<div></div>',{class:"red-ui-settings-tabs-content"}).appendTo(settingsContent); + + panes.forEach(function(pane) { + settingsTabs.addTab({ + id: "red-ui-settings-tab-"+pane.id, + label: pane.title, + pane: pane + }); + pane.get().hide().appendTo(tabContents); + }); + settingsContent.i18n(); + settingsTabs.activateTab("red-ui-settings-tab-"+(initialTab||'view')) + $("#red-ui-sidebar-shade").show(); + }, + close: function() { + settingsVisible = false; + panes.forEach(function(pane) { + if (pane.close) { + pane.close(); + } + }); + $("#red-ui-sidebar-shade").hide(); + + }, + show: function() {} + } + if (trayWidth !== null) { + trayOptions.width = trayWidth; + } + RED.tray.show(trayOptions); + } + + function localeToName(lc) { + var name = RED._("languages."+lc); + return {text: (name ? name : lc), val: lc}; + } + + function compText(a, b) { + return a.text.localeCompare(b.text); + } + + var viewSettings = [ + { + options: [ + {setting:"editor-language",local: true, label:"menu.label.view.language",options:function(done){ done([{val:'',text:RED._('menu.label.view.browserDefault')}].concat(RED.settings.theme("languages").map(localeToName).sort(compText))) }}, + ] + },{ + title: "menu.label.view.grid", + options: [ + {setting:"view-show-grid",oldSetting:"menu-menu-item-view-show-grid",label:"menu.label.view.showGrid", default: true, toggle:true,onchange:"core:toggle-show-grid"}, + {setting:"view-snap-grid",oldSetting:"menu-menu-item-view-snap-grid",label:"menu.label.view.snapGrid", default: true, toggle:true,onchange:"core:toggle-snap-grid"}, + {setting:"view-grid-size",label:"menu.label.view.gridSize",type:"number",default: 20, onchange:RED.view.gridSize} + ] + }, + { + title: "menu.label.nodes", + options: [ + {setting:"view-node-status",oldSetting:"menu-menu-item-status",label:"menu.label.displayStatus",default: true, toggle:true,onchange:"core:toggle-status"}, + {setting:"view-node-show-label",label:"menu.label.showNodeLabelDefault",default: true, toggle:true} + ] + }, + { + title: "menu.label.other", + options: [ + {setting:"view-show-tips",oldSettings:"menu-menu-item-show-tips",label:"menu.label.showTips",toggle:true,default:true,onchange:"core:toggle-show-tips"} + ] + } + ]; + + var allSettings = {}; + + function createViewPane() { + + var pane = $('<div id="red-ui-settings-tab-view" class="red-ui-help"></div>'); + + var currentEditorSettings = RED.settings.get('editor') || {}; + currentEditorSettings.view = currentEditorSettings.view || {}; + + viewSettings.forEach(function(section) { + if (section.title) { + $('<h3></h3>').text(RED._(section.title)).appendTo(pane); + } + section.options.forEach(function(opt) { + var initialState; + if (opt.local) { + initialState = localStorage.getItem(opt.setting); + } else { + initialState = currentEditorSettings.view[opt.setting]; + } + var row = $('<div class="red-ui-settings-row"></div>').appendTo(pane); + var input; + if (opt.toggle) { + input = $('<label for="user-settings-'+opt.setting+'"><input id="user-settings-'+opt.setting+'" type="checkbox"> '+RED._(opt.label)+'</label>').appendTo(row).find("input"); + input.prop('checked',initialState); + } else if (opt.options) { + $('<label for="user-settings-'+opt.setting+'">'+RED._(opt.label)+'</label>').appendTo(row); + var select = $('<select id="user-settings-'+opt.setting+'"></select>').appendTo(row); + if (typeof opt.options === 'function') { + opt.options(function(options) { + options.forEach(function(opt) { + var val = opt; + var text = opt; + if (typeof opt !== 'string') { + val = opt.val; + text = opt.text; + } + $('<option>').val(val).text(text).appendTo(select); + }) + }) + select.val(initialState) + } else { + // TODO: support other option types + } + } else { + $('<label for="user-settings-'+opt.setting+'">'+RED._(opt.label)+'</label>').appendTo(row); + $('<input id="user-settings-'+opt.setting+'" type="'+(opt.type||"text")+'">').appendTo(row).val(initialState); + } + }); + }) + return pane; + } + + function setSelected(id, value) { + var opt = allSettings[id]; + if (opt.local) { + localStorage.setItem(opt.setting,value); + } else { + var currentEditorSettings = RED.settings.get('editor') || {}; + currentEditorSettings.view = currentEditorSettings.view || {}; + currentEditorSettings.view[opt.setting] = value; + RED.settings.set('editor', currentEditorSettings); + var callback = opt.onchange; + if (typeof callback === 'string') { + callback = RED.actions.get(callback); + } + if (callback) { + callback.call(opt,value); + } + } + } + function toggle(id) { + var opt = allSettings[id]; + var currentEditorSettings = RED.settings.get('editor') || {}; + currentEditorSettings.view = currentEditorSettings.view || {}; + setSelected(id,!currentEditorSettings.view[opt.setting]); + } + + + function init() { + RED.actions.add("core:show-user-settings",show); + RED.actions.add("core:show-help", function() { show('keyboard')}); + + addPane({ + id:'view', + title: RED._("menu.label.view.view"), + get: createViewPane, + close: function() { + viewSettings.forEach(function(section) { + section.options.forEach(function(opt) { + var input = $("#user-settings-"+opt.setting); + if (opt.toggle) { + setSelected(opt.setting,input.prop('checked')); + } else { + setSelected(opt.setting,input.val()); + } + }); + }) + } + }) + + var currentEditorSettings = RED.settings.get('editor') || {}; + currentEditorSettings.view = currentEditorSettings.view || {}; + var editorSettingsChanged = false; + viewSettings.forEach(function(section) { + section.options.forEach(function(opt) { + if (opt.local) { + allSettings[opt.setting] = opt; + return; + } + if (opt.oldSetting) { + var oldValue = RED.settings.get(opt.oldSetting); + if (oldValue !== undefined && oldValue !== null) { + currentEditorSettings.view[opt.setting] = oldValue; + editorSettingsChanged = true; + RED.settings.remove(opt.oldSetting); + } + } + allSettings[opt.setting] = opt; + var value = currentEditorSettings.view[opt.setting]; + if ((value === null || value === undefined) && opt.hasOwnProperty('default')) { + value = opt.default; + currentEditorSettings.view[opt.setting] = value; + editorSettingsChanged = true; + } + + if (opt.onchange) { + var callback = opt.onchange; + if (typeof callback === 'string') { + callback = RED.actions.get(callback); + } + if (callback) { + callback.call(opt,value); + } + } + }); + }); + if (editorSettingsChanged) { + RED.settings.set('editor',currentEditorSettings); + } + + } + return { + init: init, + toggle: toggle, + show: show, + add: addPane + }; +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js new file mode 100644 index 0000000..a9c1c95 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js @@ -0,0 +1,1081 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +RED.utils = (function() { + + window._marked = window.marked; + window.marked = function(txt) { + console.warn("Use of 'marked()' is deprecated. Use RED.utils.renderMarkdown() instead"); + return renderMarkdown(txt); + } + + _marked.setOptions({ + renderer: new _marked.Renderer(), + gfm: true, + tables: true, + breaks: false, + pedantic: false, + smartLists: true, + smartypants: false + }); + + function renderMarkdown(txt) { + var rendered = _marked(txt); + var cleaned = DOMPurify.sanitize(rendered, {SAFE_FOR_JQUERY: true}) + return cleaned; + } + + function formatString(str) { + return str.replace(/\r?\n/g,"&crarr;").replace(/\t/g,"&rarr;"); + } + function sanitize(m) { + return m.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"); + } + + function buildMessageSummaryValue(value) { + var result; + if (Array.isArray(value)) { + result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta"></span>').text('array['+value.length+']'); + } else if (value === null) { + result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-null">null</span>'); + } else if (typeof value === 'object') { + if (value.hasOwnProperty('type') && value.type === 'Buffer' && value.hasOwnProperty('data')) { + result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta"></span>').text('buffer['+value.length+']'); + } else if (value.hasOwnProperty('type') && value.type === 'array' && value.hasOwnProperty('data')) { + result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta"></span>').text('array['+value.length+']'); + } else if (value.hasOwnProperty('type') && value.type === 'function') { + result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta"></span>').text('function'); + } else if (value.hasOwnProperty('type') && value.type === 'number') { + result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-number"></span>').text(value.data); + } else { + result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta">object</span>'); + } + } else if (typeof value === 'string') { + var subvalue; + if (value.length > 30) { + subvalue = sanitize(value.substring(0,30))+"&hellip;"; + } else { + subvalue = sanitize(value); + } + result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-string"></span>').html('"'+formatString(subvalue)+'"'); + } else if (typeof value === 'number') { + result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-number"></span>').text(""+value); + } else { + result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-other"></span>').text(""+value); + } + return result; + } + function makeExpandable(el,onbuild,ontoggle,expand) { + el.addClass("red-ui-debug-msg-expandable"); + el.prop('toggle',function() { + return function(state) { + var parent = el.parent(); + if (parent.hasClass('collapsed')) { + if (state) { + if (onbuild && !parent.hasClass('built')) { + onbuild(); + parent.addClass('built'); + } + parent.removeClass('collapsed'); + return true; + } + } else { + if (!state) { + parent.addClass('collapsed'); + return true; + } + } + return false; + } + }); + el.on("click", function(e) { + var parent = $(this).parent(); + var currentState = !parent.hasClass('collapsed'); + if ($(this).prop('toggle')(!currentState)) { + if (ontoggle) { + ontoggle(!currentState); + } + } + // if (parent.hasClass('collapsed')) { + // if (onbuild && !parent.hasClass('built')) { + // onbuild(); + // parent.addClass('built'); + // } + // if (ontoggle) { + // ontoggle(true); + // } + // parent.removeClass('collapsed'); + // } else { + // parent.addClass('collapsed'); + // if (ontoggle) { + // ontoggle(false); + // } + // } + e.preventDefault(); + }); + if (expand) { + el.trigger("click"); + } + + } + + var pinnedPaths = {}; + var formattedPaths = {}; + + function addMessageControls(obj,sourceId,key,msg,rootPath,strippedKey,extraTools) { + if (!pinnedPaths.hasOwnProperty(sourceId)) { + pinnedPaths[sourceId] = {} + } + var tools = $('<span class="red-ui-debug-msg-tools"></span>').appendTo(obj); + var copyTools = $('<span class="red-ui-debug-msg-tools-copy button-group"></span>').appendTo(tools); + if (!!key) { + var copyPath = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-terminal"></i></button>').appendTo(copyTools).on("click", function(e) { + e.preventDefault(); + e.stopPropagation(); + RED.clipboard.copyText(key,copyPath,"clipboard.copyMessagePath"); + }) + RED.popover.tooltip(copyPath,RED._("node-red:debug.sidebar.copyPath")); + } + var copyPayload = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-clipboard"></i></button>').appendTo(copyTools).on("click", function(e) { + e.preventDefault(); + e.stopPropagation(); + RED.clipboard.copyText(msg,copyPayload,"clipboard.copyMessageValue"); + }) + RED.popover.tooltip(copyPayload,RED._("node-red:debug.sidebar.copyPayload")); + if (strippedKey !== undefined && strippedKey !== '') { + var isPinned = pinnedPaths[sourceId].hasOwnProperty(strippedKey); + + var pinPath = $('<button class="red-ui-button red-ui-button-small red-ui-debug-msg-tools-pin"><i class="fa fa-map-pin"></i></button>').appendTo(tools).on("click", function(e) { + e.preventDefault(); + e.stopPropagation(); + if (pinnedPaths[sourceId].hasOwnProperty(strippedKey)) { + delete pinnedPaths[sourceId][strippedKey]; + $(this).removeClass("selected"); + obj.removeClass("red-ui-debug-msg-row-pinned"); + } else { + var rootedPath = "$"+(strippedKey[0] === '['?"":".")+strippedKey; + pinnedPaths[sourceId][strippedKey] = normalisePropertyExpression(rootedPath); + $(this).addClass("selected"); + obj.addClass("red-ui-debug-msg-row-pinned"); + } + }).toggleClass("selected",isPinned); + obj.toggleClass("red-ui-debug-msg-row-pinned",isPinned); + RED.popover.tooltip(pinPath,RED._("node-red:debug.sidebar.pinPath")); + } + if (extraTools) { + extraTools.addClass("red-ui-debug-msg-tools-other"); + extraTools.appendTo(tools); + } + } + function checkExpanded(strippedKey,expandPaths,minRange,maxRange) { + if (expandPaths && expandPaths.length > 0) { + if (strippedKey === '' && minRange === undefined) { + return true; + } + for (var i=0;i<expandPaths.length;i++) { + var p = expandPaths[i]; + if (p.indexOf(strippedKey) === 0 && (p[strippedKey.length] === "." || p[strippedKey.length] === "[") ) { + + if (minRange !== undefined && p[strippedKey.length] === "[") { + var subkey = p.substring(strippedKey.length); + var m = (/\[(\d+)\]/.exec(subkey)); + if (m) { + var index = parseInt(m[1]); + return minRange<=index && index<=maxRange; + } + } else { + return true; + } + } + } + } + return false; + } + + function formatNumber(element,obj,sourceId,path,cycle,initialFormat) { + var format = (formattedPaths[sourceId] && formattedPaths[sourceId][path] && formattedPaths[sourceId][path]['number']) || initialFormat || "dec"; + if (cycle) { + if (format === 'dec') { + if ((obj.toString().length===13) && (obj<=2147483647000)) { + format = 'dateMS'; + } else if ((obj.toString().length===10) && (obj<=2147483647)) { + format = 'dateS'; + } else { + format = 'hex' + } + } else if (format === 'dateMS' || format == 'dateS') { + if ((obj.toString().length===13) && (obj<=2147483647000)) { + format = 'dateML'; + } else if ((obj.toString().length===10) && (obj<=2147483647)) { + format = 'dateL'; + } else { + format = 'hex' + } + } else if (format === 'dateML' || format == 'dateL') { + format = 'hex'; + } else { + format = 'dec'; + } + formattedPaths[sourceId] = formattedPaths[sourceId]||{}; + formattedPaths[sourceId][path] = formattedPaths[sourceId][path]||{}; + formattedPaths[sourceId][path]['number'] = format; + } else if (initialFormat !== undefined){ + formattedPaths[sourceId] = formattedPaths[sourceId]||{}; + formattedPaths[sourceId][path] = formattedPaths[sourceId][path]||{}; + formattedPaths[sourceId][path]['number'] = format; + } + if (format === 'dec') { + element.text(""+obj); + } else if (format === 'dateMS') { + element.text((new Date(obj)).toISOString()); + } else if (format === 'dateS') { + element.text((new Date(obj*1000)).toISOString()); + } else if (format === 'dateML') { + var dd = new Date(obj); + element.text(dd.toLocaleString() + " [UTC" + ( dd.getTimezoneOffset()/-60 <=0?"":"+" ) + dd.getTimezoneOffset()/-60 +"]"); + } else if (format === 'dateL') { + var ddl = new Date(obj*1000); + element.text(ddl.toLocaleString() + " [UTC" + ( ddl.getTimezoneOffset()/-60 <=0?"":"+" ) + ddl.getTimezoneOffset()/-60 +"]"); + } else if (format === 'hex') { + element.text("0x"+(obj).toString(16)); + } + } + + function formatBuffer(element,button,sourceId,path,cycle) { + var format = (formattedPaths[sourceId] && formattedPaths[sourceId][path] && formattedPaths[sourceId][path]['buffer']) || "raw"; + if (cycle) { + if (format === 'raw') { + format = 'string'; + } else { + format = 'raw'; + } + formattedPaths[sourceId] = formattedPaths[sourceId]||{}; + formattedPaths[sourceId][path] = formattedPaths[sourceId][path]||{}; + formattedPaths[sourceId][path]['buffer'] = format; + } + if (format === 'raw') { + button.text('raw'); + element.removeClass('red-ui-debug-msg-buffer-string').addClass('red-ui-debug-msg-buffer-raw'); + } else if (format === 'string') { + button.text('string'); + element.addClass('red-ui-debug-msg-buffer-string').removeClass('red-ui-debug-msg-buffer-raw'); + } + } + + function buildMessageElement(obj,options) { + options = options || {}; + var key = options.key; + var typeHint = options.typeHint; + var hideKey = options.hideKey; + var path = options.path; + var sourceId = options.sourceId; + var rootPath = options.rootPath; + var expandPaths = options.expandPaths; + var ontoggle = options.ontoggle; + var exposeApi = options.exposeApi; + var tools = options.tools; + + var subElements = {}; + var i; + var e; + var entryObj; + var expandableHeader; + var header; + var headerHead; + var value; + var strippedKey; + if (path !== undefined && rootPath !== undefined) { + strippedKey = path.substring(rootPath.length+(path[rootPath.length]==="."?1:0)); + } + var element = $('<span class="red-ui-debug-msg-element"></span>'); + element.collapse = function() { + element.find(".red-ui-debug-msg-expandable").parent().addClass("collapsed"); + } + header = $('<span class="red-ui-debug-msg-row"></span>').appendTo(element); + if (sourceId) { + addMessageControls(header,sourceId,path,obj,rootPath,strippedKey,tools); + } + if (!key) { + element.addClass("red-ui-debug-msg-top-level"); + if (sourceId) { + var pinned = pinnedPaths[sourceId]; + expandPaths = []; + if (pinned) { + for (var pinnedPath in pinned) { + if (pinned.hasOwnProperty(pinnedPath)) { + try { + var res = getMessageProperty({$:obj},pinned[pinnedPath]); + if (res !== undefined) { + expandPaths.push(pinnedPath); + } + } catch(err) { + } + } + } + expandPaths.sort(); + } + element.clearPinned = function() { + element.find(".red-ui-debug-msg-row-pinned").removeClass("red-ui-debug-msg-row-pinned"); + pinnedPaths[sourceId] = {}; + } + } + } else { + if (!hideKey) { + $('<span class="red-ui-debug-msg-object-key"></span>').text(key).appendTo(header); + $('<span>: </span>').appendTo(header); + } + } + entryObj = $('<span class="red-ui-debug-msg-object-value"></span>').appendTo(header); + + var isArray = Array.isArray(obj); + var isArrayObject = false; + if (obj && typeof obj === 'object' && obj.hasOwnProperty('type') && obj.hasOwnProperty('data') && ((obj.__enc__ && obj.type === 'array') || obj.type === 'Buffer')) { + isArray = true; + isArrayObject = true; + } + if (obj === null || obj === undefined) { + $('<span class="red-ui-debug-msg-type-null">'+obj+'</span>').appendTo(entryObj); + } else if (obj.__enc__ && obj.type === 'number') { + e = $('<span class="red-ui-debug-msg-type-number red-ui-debug-msg-object-header"></span>').text(obj.data).appendTo(entryObj); + } else if (typeHint === "function" || (obj.__enc__ && obj.type === 'function')) { + e = $('<span class="red-ui-debug-msg-type-meta red-ui-debug-msg-object-header"></span>').text("function").appendTo(entryObj); + } else if (typeHint === "internal" || (obj.__enc__ && obj.type === 'internal')) { + e = $('<span class="red-ui-debug-msg-type-meta red-ui-debug-msg-object-header"></span>').text("[internal]").appendTo(entryObj); + } else if (typeof obj === 'string') { + if (/[\t\n\r]/.test(obj)) { + element.addClass('collapsed'); + $('<i class="fa fa-caret-right red-ui-debug-msg-object-handle"></i> ').prependTo(header); + makeExpandable(header, function() { + $('<span class="red-ui-debug-msg-type-meta red-ui-debug-msg-object-type-header"></span>').text(typeHint||'string').appendTo(header); + var row = $('<div class="red-ui-debug-msg-object-entry collapsed"></div>').appendTo(element); + $('<pre class="red-ui-debug-msg-type-string"></pre>').text(obj).appendTo(row); + },function(state) {if (ontoggle) { ontoggle(path,state);}}, checkExpanded(strippedKey,expandPaths)); + } + e = $('<span class="red-ui-debug-msg-type-string red-ui-debug-msg-object-header"></span>').html('"'+formatString(sanitize(obj))+'"').appendTo(entryObj); + if (/^#[0-9a-f]{6}$/i.test(obj)) { + $('<span class="red-ui-debug-msg-type-string-swatch"></span>').css('backgroundColor',obj).appendTo(e); + } + + } else if (typeof obj === 'number') { + e = $('<span class="red-ui-debug-msg-type-number"></span>').appendTo(entryObj); + + if (Number.isInteger(obj) && (obj >= 0)) { // if it's a +ve integer + e.addClass("red-ui-debug-msg-type-number-toggle"); + e.on("click", function(evt) { + evt.preventDefault(); + formatNumber($(this), obj, sourceId, path, true); + }); + } + formatNumber(e,obj,sourceId,path,false,typeHint==='hex'?'hex':undefined); + + } else if (isArray) { + element.addClass('collapsed'); + + var originalLength = obj.length; + if (typeHint) { + var m = /\[(\d+)\]/.exec(typeHint); + if (m) { + originalLength = parseInt(m[1]); + } + } + var data = obj; + var type = 'array'; + if (isArrayObject) { + data = obj.data; + if (originalLength === undefined) { + originalLength = data.length; + } + if (data.__enc__) { + data = data.data; + } + type = obj.type.toLowerCase(); + } else if (/buffer/.test(typeHint)) { + type = 'buffer'; + } + var fullLength = data.length; + + if (originalLength > 0) { + $('<i class="fa fa-caret-right red-ui-debug-msg-object-handle"></i> ').prependTo(header); + var arrayRows = $('<div class="red-ui-debug-msg-array-rows"></div>').appendTo(element); + element.addClass('red-ui-debug-msg-buffer-raw'); + } + if (key) { + headerHead = $('<span class="red-ui-debug-msg-type-meta"></span>').text(typeHint||(type+'['+originalLength+']')).appendTo(entryObj); + } else { + headerHead = $('<span class="red-ui-debug-msg-object-header"></span>').appendTo(entryObj); + $('<span>[ </span>').appendTo(headerHead); + var arrayLength = Math.min(originalLength,10); + for (i=0;i<arrayLength;i++) { + buildMessageSummaryValue(data[i]).appendTo(headerHead); + if (i < arrayLength-1) { + $('<span>, </span>').appendTo(headerHead); + } + } + if (originalLength > arrayLength) { + $('<span> &hellip;</span>').appendTo(headerHead); + } + if (arrayLength === 0) { + $('<span class="red-ui-debug-msg-type-meta">empty</span>').appendTo(headerHead); + } + $('<span> ]</span>').appendTo(headerHead); + } + if (originalLength > 0) { + + makeExpandable(header,function() { + if (!key) { + headerHead = $('<span class="red-ui-debug-msg-type-meta red-ui-debug-msg-object-type-header"></span>').text(typeHint||(type+'['+originalLength+']')).appendTo(header); + } + if (type === 'buffer') { + var stringRow = $('<div class="red-ui-debug-msg-string-rows"></div>').appendTo(element); + var sr = $('<div class="red-ui-debug-msg-object-entry collapsed"></div>').appendTo(stringRow); + var stringEncoding = ""; + try { + stringEncoding = String.fromCharCode.apply(null, new Uint16Array(data)) + } catch(err) { + console.log(err); + } + $('<pre class="red-ui-debug-msg-type-string"></pre>').text(stringEncoding).appendTo(sr); + var bufferOpts = $('<span class="red-ui-debug-msg-buffer-opts"></span>').appendTo(headerHead); + var switchFormat = $('<a class="red-ui-button red-ui-button-small" href="#"></a>').text('raw').appendTo(bufferOpts).on("click", function(e) { + e.preventDefault(); + e.stopPropagation(); + formatBuffer(element,$(this),sourceId,path,true); + }); + formatBuffer(element,switchFormat,sourceId,path,false); + + } + var row; + if (fullLength <= 10) { + for (i=0;i<fullLength;i++) { + row = $('<div class="red-ui-debug-msg-object-entry collapsed"></div>').appendTo(arrayRows); + subElements[path+"["+i+"]"] = buildMessageElement( + data[i], + { + key: ""+i, + typeHint: type==='buffer'?'hex':false, + hideKey: false, + path: path+"["+i+"]", + sourceId: sourceId, + rootPath: rootPath, + expandPaths: expandPaths, + ontoggle: ontoggle, + exposeApi: exposeApi + } + ).appendTo(row); + } + } else { + for (i=0;i<fullLength;i+=10) { + var minRange = i; + row = $('<div class="red-ui-debug-msg-object-entry collapsed"></div>').appendTo(arrayRows); + header = $('<span></span>').appendTo(row); + $('<i class="fa fa-caret-right red-ui-debug-msg-object-handle"></i> ').appendTo(header); + makeExpandable(header, (function() { + var min = minRange; + var max = Math.min(fullLength-1,(minRange+9)); + var parent = row; + return function() { + for (var i=min;i<=max;i++) { + var row = $('<div class="red-ui-debug-msg-object-entry collapsed"></div>').appendTo(parent); + subElements[path+"["+i+"]"] = buildMessageElement( + data[i], + { + key: ""+i, + typeHint: type==='buffer'?'hex':false, + hideKey: false, + path: path+"["+i+"]", + sourceId: sourceId, + rootPath: rootPath, + expandPaths: expandPaths, + ontoggle: ontoggle, + exposeApi: exposeApi + + } + ).appendTo(row); + } + } + })(), + (function() { var path = path+"["+i+"]"; return function(state) {if (ontoggle) { ontoggle(path,state);}}})(), + checkExpanded(strippedKey,expandPaths,minRange,Math.min(fullLength-1,(minRange+9)))); + $('<span class="red-ui-debug-msg-object-key"></span>').html("["+minRange+" &hellip; "+Math.min(fullLength-1,(minRange+9))+"]").appendTo(header); + } + if (fullLength < originalLength) { + $('<div class="red-ui-debug-msg-object-entry collapsed"><span class="red-ui-debug-msg-object-key">['+fullLength+' &hellip; '+originalLength+']</span></div>').appendTo(arrayRows); + } + } + }, + function(state) {if (ontoggle) { ontoggle(path,state);}}, + checkExpanded(strippedKey,expandPaths)); + } + } else if (typeof obj === 'object') { + element.addClass('collapsed'); + var keys = Object.keys(obj); + if (key || keys.length > 0) { + $('<i class="fa fa-caret-right red-ui-debug-msg-object-handle"></i> ').prependTo(header); + makeExpandable(header, function() { + if (!key) { + $('<span class="red-ui-debug-msg-type-meta red-ui-debug-msg-object-type-header"></span>').text('object').appendTo(header); + } + for (i=0;i<keys.length;i++) { + var row = $('<div class="red-ui-debug-msg-object-entry collapsed"></div>').appendTo(element); + var newPath = path; + if (newPath !== undefined) { + if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(keys[i])) { + newPath += (newPath.length > 0?".":"")+keys[i]; + } else { + newPath += "[\""+keys[i].replace(/"/,"\\\"")+"\"]" + } + } + subElements[newPath] = buildMessageElement( + obj[keys[i]], + { + key: keys[i], + typeHint: false, + hideKey: false, + path: newPath, + sourceId: sourceId, + rootPath: rootPath, + expandPaths: expandPaths, + ontoggle: ontoggle, + exposeApi: exposeApi + + } + ).appendTo(row); + } + if (keys.length === 0) { + $('<div class="red-ui-debug-msg-object-entry red-ui-debug-msg-type-meta collapsed"></div>').text("empty").appendTo(element); + } + }, + function(state) {if (ontoggle) { ontoggle(path,state);}}, + checkExpanded(strippedKey,expandPaths)); + } + if (key) { + $('<span class="red-ui-debug-msg-type-meta"></span>').text('object').appendTo(entryObj); + } else { + headerHead = $('<span class="red-ui-debug-msg-object-header"></span>').appendTo(entryObj); + $('<span>{ </span>').appendTo(headerHead); + var keysLength = Math.min(keys.length,5); + for (i=0;i<keysLength;i++) { + $('<span class="red-ui-debug-msg-object-key"></span>').text(keys[i]).appendTo(headerHead); + $('<span>: </span>').appendTo(headerHead); + buildMessageSummaryValue(obj[keys[i]]).appendTo(headerHead); + if (i < keysLength-1) { + $('<span>, </span>').appendTo(headerHead); + } + } + if (keys.length > keysLength) { + $('<span> &hellip;</span>').appendTo(headerHead); + } + if (keysLength === 0) { + $('<span class="red-ui-debug-msg-type-meta">empty</span>').appendTo(headerHead); + } + $('<span> }</span>').appendTo(headerHead); + } + } else { + $('<span class="red-ui-debug-msg-type-other"></span>').text(""+obj).appendTo(entryObj); + } + if (exposeApi) { + element.prop('expand', function() { return function(targetPath, state) { + if (path === targetPath) { + if (header.prop('toggle')) { + header.prop('toggle')(state); + } + } else if (subElements[targetPath] && subElements[targetPath].prop('expand') ) { + subElements[targetPath].prop('expand')(targetPath,state); + } else { + for (var p in subElements) { + if (subElements.hasOwnProperty(p)) { + if (targetPath.indexOf(p) === 0) { + if (subElements[p].prop('expand') ) { + subElements[p].prop('expand')(targetPath,state); + } + break; + } + } + } + } + }}); + } + return element; + } + + function normalisePropertyExpression(str) { + // This must be kept in sync with validatePropertyExpression + // in editor/js/ui/utils.js + + var length = str.length; + if (length === 0) { + throw new Error("Invalid property expression: zero-length"); + } + var parts = []; + var start = 0; + var inString = false; + var inBox = false; + var quoteChar; + var v; + for (var i=0;i<length;i++) { + var c = str[i]; + if (!inString) { + if (c === "'" || c === '"') { + if (i != start) { + throw new Error("Invalid property expression: unexpected "+c+" at position "+i); + } + inString = true; + quoteChar = c; + start = i+1; + } else if (c === '.') { + if (i===0) { + throw new Error("Invalid property expression: unexpected . at position 0"); + } + if (start != i) { + v = str.substring(start,i); + if (/^\d+$/.test(v)) { + parts.push(parseInt(v)); + } else { + parts.push(v); + } + } + if (i===length-1) { + throw new Error("Invalid property expression: unterminated expression"); + } + // Next char is first char of an identifier: a-z 0-9 $ _ + if (!/[a-z0-9\$\_]/i.test(str[i+1])) { + throw new Error("Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1)); + } + start = i+1; + } else if (c === '[') { + if (i === 0) { + throw new Error("Invalid property expression: unexpected "+c+" at position "+i); + } + if (start != i) { + parts.push(str.substring(start,i)); + } + if (i===length-1) { + throw new Error("Invalid property expression: unterminated expression"); + } + // Next char is either a quote or a number + if (!/["'\d]/.test(str[i+1])) { + throw new Error("Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1)); + } + start = i+1; + inBox = true; + } else if (c === ']') { + if (!inBox) { + throw new Error("Invalid property expression: unexpected "+c+" at position "+i); + } + if (start != i) { + v = str.substring(start,i); + if (/^\d+$/.test(v)) { + parts.push(parseInt(v)); + } else { + throw new Error("Invalid property expression: unexpected array expression at position "+start); + } + } + start = i+1; + inBox = false; + } else if (c === ' ') { + throw new Error("Invalid property expression: unexpected ' ' at position "+i); + } + } else { + if (c === quoteChar) { + if (i-start === 0) { + throw new Error("Invalid property expression: zero-length string at position "+start); + } + parts.push(str.substring(start,i)); + // If inBox, next char must be a ]. Otherwise it may be [ or . + if (inBox && !/\]/.test(str[i+1])) { + throw new Error("Invalid property expression: unexpected array expression at position "+start); + } else if (!inBox && i+1!==length && !/[\[\.]/.test(str[i+1])) { + throw new Error("Invalid property expression: unexpected "+str[i+1]+" expression at position "+(i+1)); + } + start = i+1; + inString = false; + } + } + + } + if (inBox || inString) { + throw new Error("Invalid property expression: unterminated expression"); + } + if (start < length) { + parts.push(str.substring(start)); + } + return parts; + } + + function validatePropertyExpression(str) { + try { + var parts = normalisePropertyExpression(str); + return true; + } catch(err) { + return false; + } + } + + function getMessageProperty(msg,expr) { + var result = null; + var msgPropParts; + + if (typeof expr === 'string') { + if (expr.indexOf('msg.')===0) { + expr = expr.substring(4); + } + msgPropParts = normalisePropertyExpression(expr); + } else { + msgPropParts = expr; + } + var m; + msgPropParts.reduce(function(obj, key) { + result = (typeof obj[key] !== "undefined" ? obj[key] : undefined); + if (result === undefined && obj.hasOwnProperty('type') && obj.hasOwnProperty('data')&& obj.hasOwnProperty('length')) { + result = (typeof obj.data[key] !== "undefined" ? obj.data[key] : undefined); + } + return result; + }, msg); + return result; + } + + function setMessageProperty(msg,prop,value,createMissing) { + if (typeof createMissing === 'undefined') { + createMissing = (typeof value !== 'undefined'); + } + if (prop.indexOf('msg.')===0) { + prop = prop.substring(4); + } + var msgPropParts = normalisePropertyExpression(prop); + var depth = 0; + var length = msgPropParts.length; + var obj = msg; + var key; + for (var i=0;i<length-1;i++) { + key = msgPropParts[i]; + if (typeof key === 'string' || (typeof key === 'number' && !Array.isArray(obj))) { + if (obj.hasOwnProperty(key)) { + obj = obj[key]; + } else if (createMissing) { + if (typeof msgPropParts[i+1] === 'string') { + obj[key] = {}; + } else { + obj[key] = []; + } + obj = obj[key]; + } else { + return null; + } + } else if (typeof key === 'number') { + // obj is an array + if (obj[key] === undefined) { + if (createMissing) { + if (typeof msgPropParts[i+1] === 'string') { + obj[key] = {}; + } else { + obj[key] = []; + } + obj = obj[key]; + } else { + return null; + } + } else { + obj = obj[key]; + } + } + } + key = msgPropParts[length-1]; + if (typeof value === "undefined") { + if (typeof key === 'number' && Array.isArray(obj)) { + obj.splice(key,1); + } else { + delete obj[key] + } + } else { + obj[key] = value; + } + } + function separateIconPath(icon) { + var result = {module: "", file: ""}; + if (icon) { + var index = icon.indexOf('icons/'); + if (index !== -1) { + icon = icon.substring(index+6); + } + index = icon.indexOf('/'); + if (index !== -1) { + result.module = icon.slice(0, index); + result.file = icon.slice(index + 1); + } else { + result.file = icon; + } + } + return result; + } + + function getDefaultNodeIcon(def,node) { + var icon_url; + if (node && node.type === "subflow") { + icon_url = "node-red/subflow.svg"; + } else if (typeof def.icon === "function") { + try { + icon_url = def.icon.call(node); + } catch(err) { + console.log("Definition error: "+def.type+".icon",err); + icon_url = "arrow-in.svg"; + } + } else { + icon_url = def.icon; + } + + var iconPath = separateIconPath(icon_url); + if (!iconPath.module) { + if (def.set) { + iconPath.module = def.set.module; + } else { + // Handle subflow instance nodes that don't have def.set + iconPath.module = "node-red"; + } + } + return iconPath; + } + + function isIconExists(iconPath) { + var iconSets = RED.nodes.getIconSets(); + var iconFileList = iconSets[iconPath.module]; + if (iconFileList && iconFileList.indexOf(iconPath.file) !== -1) { + return true; + } else { + return false; + } + } + + function getNodeIcon(def,node) { + if (def.category === 'config') { + return RED.settings.apiRootUrl+"icons/node-red/cog.svg" + } else if (node && node.type === 'tab') { + return RED.settings.apiRootUrl+"icons/node-red/subflow.svg" + } else if (node && node.type === 'unknown') { + return RED.settings.apiRootUrl+"icons/node-red/alert.svg" + } else if (node && node.icon) { + var iconPath = separateIconPath(node.icon); + if (isIconExists(iconPath)) { + if (iconPath.module === "font-awesome") { + return node.icon; + } else { + return RED.settings.apiRootUrl+"icons/" + node.icon; + } + } else if (iconPath.module !== "font-awesome" && /.png$/i.test(iconPath.file)) { + iconPath.file = iconPath.file.replace(/.png$/,".svg"); + if (isIconExists(iconPath)) { + return RED.settings.apiRootUrl+"icons/" + node.icon.replace(/.png$/,".svg"); + } + } + } + + var iconPath = getDefaultNodeIcon(def, node); + if (isIconExists(iconPath)) { + if (iconPath.module === "font-awesome") { + return iconPath.module+"/"+iconPath.file; + } else { + return RED.settings.apiRootUrl+"icons/"+iconPath.module+"/"+iconPath.file; + } + } + + if (/.png$/i.test(iconPath.file)) { + var originalFile = iconPath.file; + iconPath.file = iconPath.file.replace(/.png$/,".svg"); + if (isIconExists(iconPath)) { + return RED.settings.apiRootUrl+"icons/"+iconPath.module+"/"+iconPath.file; + } + iconPath.file = originalFile; + } + + // This could be a non-core node trying to use a core icon. + iconPath.module = 'node-red'; + if (isIconExists(iconPath)) { + return RED.settings.apiRootUrl+"icons/"+iconPath.module+"/"+iconPath.file; + } + if (/.png$/i.test(iconPath.file)) { + iconPath.file = iconPath.file.replace(/.png$/,".svg"); + if (isIconExists(iconPath)) { + return RED.settings.apiRootUrl+"icons/"+iconPath.module+"/"+iconPath.file; + } + } + if (def.category === 'subflows') { + return RED.settings.apiRootUrl+"icons/node-red/subflow.svg"; + } + return RED.settings.apiRootUrl+"icons/node-red/arrow-in.svg"; + } + + function getNodeLabel(node,defaultLabel) { + defaultLabel = defaultLabel||""; + var l; + if (node.type === 'tab') { + l = node.label || defaultLabel + } else { + l = node._def.label; + try { + l = (typeof l === "function" ? l.call(node) : l)||defaultLabel; + } catch(err) { + console.log("Definition error: "+node.type+".label",err); + l = defaultLabel; + } + } + return RED.text.bidi.enforceTextDirectionWithUCC(l); + } + + var nodeColorCache = {}; + function clearNodeColorCache() { + nodeColorCache = {}; + } + + function getNodeColor(type, def) { + var result = def.color; + var paletteTheme = RED.settings.theme('palette.theme') || []; + if (paletteTheme.length > 0) { + if (!nodeColorCache.hasOwnProperty(type)) { + nodeColorCache[type] = def.color; + var l = paletteTheme.length; + for (var i = 0; i < l; i++ ){ + var themeRule = paletteTheme[i]; + if (themeRule.hasOwnProperty('category')) { + if (!themeRule.hasOwnProperty('_category')) { + themeRule._category = new RegExp(themeRule.category); + } + if (!themeRule._category.test(def.category)) { + continue; + } + } + if (themeRule.hasOwnProperty('type')) { + if (!themeRule.hasOwnProperty('_type')) { + themeRule._type = new RegExp(themeRule.type); + } + if (!themeRule._type.test(type)) { + continue; + } + } + nodeColorCache[type] = themeRule.color || def.color; + break; + } + } + result = nodeColorCache[type]; + } + if (result) { + return result; + } else { + return "#ddd"; + } + } + + function addSpinnerOverlay(container,contain) { + var spinner = $('<div class="red-ui-component-spinner "><img src="red/images/spin.svg"/></div>').appendTo(container); + if (contain) { + spinner.addClass('red-ui-component-spinner-contain'); + } + return spinner; + } + + function decodeObject(payload,format) { + if ((format === 'number') && (payload === "NaN")) { + payload = Number.NaN; + } else if ((format === 'number') && (payload === "Infinity")) { + payload = Infinity; + } else if ((format === 'number') && (payload === "-Infinity")) { + payload = -Infinity; + } else if (format === 'Object' || /^array/.test(format) || format === 'boolean' || format === 'number' ) { + payload = JSON.parse(payload); + } else if (/error/i.test(format)) { + payload = JSON.parse(payload); + payload = (payload.name?payload.name+": ":"")+payload.message; + } else if (format === 'null') { + payload = null; + } else if (format === 'undefined') { + payload = undefined; + } else if (/^buffer/.test(format)) { + var buffer = payload; + payload = []; + for (var c = 0; c < buffer.length; c += 2) { + payload.push(parseInt(buffer.substr(c, 2), 16)); + } + } + return payload; + } + + function parseContextKey(key) { + var parts = {}; + var m = /^#:\((\S+?)\)::(.*)$/.exec(key); + if (m) { + parts.store = m[1]; + parts.key = m[2]; + } else { + parts.key = key; + if (RED.settings.context) { + parts.store = RED.settings.context.default; + } + } + return parts; + } + + /** + * Create or update an icon element and append it to iconContainer. + * @param iconUrl - Url of icon. + * @param iconContainer - Icon container element with red-ui-palette-icon-container class. + * @param isLarge - Whether the icon size is large. + */ + function createIconElement(iconUrl, iconContainer, isLarge) { + // Removes the previous icon when icon was changed. + var iconElement = iconContainer.find(".red-ui-palette-icon"); + if (iconElement.length !== 0) { + iconElement.remove(); + } + var faIconElement = iconContainer.find("i"); + if (faIconElement.length !== 0) { + faIconElement.remove(); + } + + // Show either icon image or font-awesome icon + var iconPath = separateIconPath(iconUrl); + if (iconPath.module === "font-awesome") { + var fontAwesomeUnicode = RED.nodes.fontAwesome.getIconUnicode(iconPath.file); + if (fontAwesomeUnicode) { + var faIconElement = $('<i/>').appendTo(iconContainer); + var faLarge = isLarge ? "fa-lg " : ""; + faIconElement.addClass("red-ui-palette-icon-fa fa fa-fw " + faLarge + iconPath.file); + return; + } + // If the specified name is not defined in font-awesome, show arrow-in icon. + iconUrl = RED.settings.apiRootUrl+"icons/node-red/arrow-in.svg" + } + var imageIconElement = $('<div/>',{class:"red-ui-palette-icon"}).appendTo(iconContainer); + imageIconElement.css("backgroundImage", "url("+iconUrl+")"); + } + + return { + createObjectElement: buildMessageElement, + getMessageProperty: getMessageProperty, + setMessageProperty: setMessageProperty, + normalisePropertyExpression: normalisePropertyExpression, + validatePropertyExpression: validatePropertyExpression, + separateIconPath: separateIconPath, + getDefaultNodeIcon: getDefaultNodeIcon, + getNodeIcon: getNodeIcon, + getNodeLabel: getNodeLabel, + getNodeColor: getNodeColor, + clearNodeColorCache: clearNodeColorCache, + addSpinnerOverlay: addSpinnerOverlay, + decodeObject: decodeObject, + parseContextKey: parseContextKey, + createIconElement: createIconElement, + sanitize: sanitize, + renderMarkdown: renderMarkdown + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/view-navigator.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/view-navigator.js new file mode 100644 index 0000000..a3001e4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/view-navigator.js @@ -0,0 +1,158 @@ +/** + * Copyright 2016 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + + RED.view.navigator = (function() { + + var nav_scale = 25; + var nav_width = 5000/nav_scale; + var nav_height = 5000/nav_scale; + + var navContainer; + var navBox; + var navBorder; + var navVis; + var scrollPos; + var scaleFactor; + var chartSize; + var dimensions; + var isDragging; + var isShowing = false; + + function refreshNodes() { + if (!isShowing) { + return; + } + var navNode = navVis.selectAll(".red-ui-navigator-node").data(RED.view.getActiveNodes(),function(d){return d.id}); + navNode.exit().remove(); + navNode.enter().insert("rect") + .attr('class','red-ui-navigator-node') + .attr("pointer-events", "none"); + navNode.each(function(d) { + d3.select(this).attr("x",function(d) { return (d.x-d.w/2)/nav_scale }) + .attr("y",function(d) { return (d.y-d.h/2)/nav_scale }) + .attr("width",function(d) { return Math.max(9,d.w/nav_scale) }) + .attr("height",function(d) { return Math.max(3,d.h/nav_scale) }) + .attr("fill",function(d) { return RED.utils.getNodeColor(d.type,d._def);}) + }); + } + function onScroll() { + if (!isDragging) { + resizeNavBorder(); + } + } + function resizeNavBorder() { + if (navBorder) { + scaleFactor = RED.view.scale(); + chartSize = [ $("#red-ui-workspace-chart").width(), $("#red-ui-workspace-chart").height()]; + scrollPos = [$("#red-ui-workspace-chart").scrollLeft(),$("#red-ui-workspace-chart").scrollTop()]; + navBorder.attr('x',scrollPos[0]/nav_scale) + .attr('y',scrollPos[1]/nav_scale) + .attr('width',chartSize[0]/nav_scale/scaleFactor) + .attr('height',chartSize[1]/nav_scale/scaleFactor) + } + } + function toggle() { + if (!isShowing) { + isShowing = true; + $("#red-ui-view-navigate").addClass("selected"); + resizeNavBorder(); + refreshNodes(); + $("#red-ui-workspace-chart").on("scroll",onScroll); + navContainer.fadeIn(200); + } else { + isShowing = false; + navContainer.fadeOut(100); + $("#red-ui-workspace-chart").off("scroll",onScroll); + $("#red-ui-view-navigate").removeClass("selected"); + } + } + + return { + init: function() { + + $(window).on("resize", resizeNavBorder); + RED.events.on("sidebar:resize",resizeNavBorder); + RED.actions.add("core:toggle-navigator",toggle); + var hideTimeout; + + navContainer = $('<div>').css({ + "position":"absolute", + "bottom":$("#red-ui-workspace-footer").height(), + "right":0, + zIndex: 1 + }).appendTo("#red-ui-workspace").hide(); + + navBox = d3.select(navContainer[0]) + .append("svg:svg") + .attr("width", nav_width) + .attr("height", nav_height) + .attr("pointer-events", "all") + .attr("id","red-ui-navigator-canvas") + + navBox.append("rect").attr("x",0).attr("y",0).attr("width",nav_width).attr("height",nav_height).style({ + fill:"none", + stroke:"none", + pointerEvents:"all" + }).on("mousedown", function() { + // Update these in case they have changed + scaleFactor = RED.view.scale(); + chartSize = [ $("#red-ui-workspace-chart").width(), $("#red-ui-workspace-chart").height()]; + dimensions = [chartSize[0]/nav_scale/scaleFactor, chartSize[1]/nav_scale/scaleFactor]; + var newX = Math.max(0,Math.min(d3.event.offsetX+dimensions[0]/2,nav_width)-dimensions[0]); + var newY = Math.max(0,Math.min(d3.event.offsetY+dimensions[1]/2,nav_height)-dimensions[1]); + navBorder.attr('x',newX).attr('y',newY); + isDragging = true; + $("#red-ui-workspace-chart").scrollLeft(newX*nav_scale*scaleFactor); + $("#red-ui-workspace-chart").scrollTop(newY*nav_scale*scaleFactor); + }).on("mousemove", function() { + if (!isDragging) { return } + if (d3.event.buttons === 0) { + isDragging = false; + return; + } + var newX = Math.max(0,Math.min(d3.event.offsetX+dimensions[0]/2,nav_width)-dimensions[0]); + var newY = Math.max(0,Math.min(d3.event.offsetY+dimensions[1]/2,nav_height)-dimensions[1]); + navBorder.attr('x',newX).attr('y',newY); + $("#red-ui-workspace-chart").scrollLeft(newX*nav_scale*scaleFactor); + $("#red-ui-workspace-chart").scrollTop(newY*nav_scale*scaleFactor); + }).on("mouseup", function() { + isDragging = false; + }) + + navBorder = navBox.append("rect").attr("class","red-ui-navigator-border") + + navVis = navBox.append("svg:g") + + RED.statusBar.add({ + id: "view-navigator", + align: "right", + element: $('<button class="red-ui-footer-button-toggle single" id="red-ui-view-navigate"><i class="fa fa-map-o"></i></button>') + }) + + $("#red-ui-view-navigate").on("click", function(evt) { + evt.preventDefault(); + toggle(); + }) + RED.popover.tooltip($("#red-ui-view-navigate"),RED._('actions.toggle-navigator'),'core:toggle-navigator'); + }, + refresh: refreshNodes, + resize: resizeNavBorder, + toggle: toggle + } + + +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js new file mode 100644 index 0000000..0814892 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js @@ -0,0 +1,137 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +RED.view.tools = (function() { + + + function alignToGrid() { + var selection = RED.view.selection(); + if (selection.nodes) { + var changedNodes = []; + selection.nodes.forEach(function(n) { + var x = n.w/2 + Math.round((n.x-n.w/2)/RED.view.gridSize())*RED.view.gridSize(); + var y = Math.round(n.y/RED.view.gridSize())*RED.view.gridSize(); + if (n.x !== x || n.y !== y) { + changedNodes.push({ + n:n, + ox: n.x, + oy: n.y, + moved: n.moved + }); + n.x = x; + n.y = y; + n.dirty = true; + n.moved = true; + } + }); + if (changedNodes.length > 0) { + RED.history.push({t:"move",nodes:changedNodes,dirty:RED.nodes.dirty()}); + RED.nodes.dirty(true); + RED.view.redraw(true); + } + } + } + + var moving_set = null; + var endMoveSet = false; + function endKeyboardMove() { + endMoveSet = false; + if (moving_set.length > 0) { + var ns = []; + for (var i=0;i<moving_set.length;i++) { + ns.push({n:moving_set[i].n,ox:moving_set[i].ox,oy:moving_set[i].oy,moved:moving_set[i].moved}); + moving_set[i].n.moved = true; + moving_set[i].n.dirty = true; + delete moving_set[i].ox; + delete moving_set[i].oy; + } + RED.view.redraw(); + RED.history.push({t:"move",nodes:ns,dirty:RED.nodes.dirty()}); + RED.nodes.dirty(true); + moving_set = null; + } + } + + function moveSelection(dx,dy) { + if (moving_set === null) { + var selection = RED.view.selection(); + if (selection.nodes) { + moving_set = selection.nodes.map(function(n) { return {n:n}}); + } + } + if (moving_set && moving_set.length > 0) { + if (!endMoveSet) { + $(document).one('keyup',endKeyboardMove); + endMoveSet = true; + } + var minX = 0; + var minY = 0; + var node; + + for (var i=0;i<moving_set.length;i++) { + node = moving_set[i]; + if (node.ox == null && node.oy == null) { + node.ox = node.n.x; + node.oy = node.n.y; + node.moved = node.n.moved; + } + node.n.moved = true; + node.n.dirty = true; + node.n.x += dx; + node.n.y += dy; + node.n.dirty = true; + minX = Math.min(node.n.x-node.n.w/2-5,minX); + minY = Math.min(node.n.y-node.n.h/2-5,minY); + } + + if (minX !== 0 || minY !== 0) { + for (var n = 0; n<moving_set.length; n++) { + node = moving_set[n]; + node.n.x -= minX; + node.n.y -= minY; + } + } + RED.view.redraw(); + } + } + + return { + init: function() { + RED.actions.add("core:align-selection-to-grid", alignToGrid); + + RED.actions.add("core:move-selection-up", function() { moveSelection(0,-1);}); + RED.actions.add("core:move-selection-right", function() { moveSelection(1,0);}); + RED.actions.add("core:move-selection-down", function() { moveSelection(0,1);}); + RED.actions.add("core:move-selection-left", function() { moveSelection(-1,0);}); + + RED.actions.add("core:step-selection-up", function() { moveSelection(0,-RED.view.gridSize());}); + RED.actions.add("core:step-selection-right", function() { moveSelection(RED.view.gridSize(),0);}); + RED.actions.add("core:step-selection-down", function() { moveSelection(0,RED.view.gridSize());}); + RED.actions.add("core:step-selection-left", function() { moveSelection(-RED.view.gridSize(),0);}); + }, + /** + * Aligns all selected nodes to the current grid + */ + alignSelectionToGrid: alignToGrid, + /** + * Moves all of the selected nodes by the specified amount + * @param {Number} dx + * @param {Number} dy + */ + moveSelection: moveSelection + } + +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/view.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/view.js new file mode 100644 index 0000000..7a561d9 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/view.js @@ -0,0 +1,3851 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + + /* <div>#red-ui-workspace-chart + * \- <svg> "outer" + * \- <g> + * \- <g>.red-ui-workspace-chart-event-layer "eventLayer" + * |- <rect>.red-ui-workspace-chart-background + * |- <g>.red-ui-workspace-chart-grid "gridLayer" + * |- <g> "linkLayer" + * |- <g> "dragGroupLayer" + * \- <g> "nodeLayer" + */ + +RED.view = (function() { + var space_width = 5000, + space_height = 5000, + lineCurveScale = 0.75, + scaleFactor = 1, + node_width = 100, + node_height = 30; + + var touchLongPressTimeout = 1000, + startTouchDistance = 0, + startTouchCenter = [], + moveTouchCenter = [], + touchStartTime = 0; + + var workspaceScrollPositions = {}; + + var gridSize = 20; + var snapGrid = false; + + var activeSpliceLink; + var spliceActive = false; + var spliceTimer; + + var activeSubflow = null; + var activeNodes = []; + var activeLinks = []; + var activeFlowLinks = []; + var activeLinkNodes = {}; + + var selected_link = null, + mousedown_link = null, + mousedown_node = null, + mousedown_port_type = null, + mousedown_port_index = 0, + mouseup_node = null, + mouse_offset = [0,0], + mouse_position = null, + mouse_mode = 0, + moving_set = [], + lasso = null, + ghostNode = null, + showStatus = false, + lastClickNode = null, + dblClickPrimed = null, + clickTime = 0, + clickElapsed = 0, + scroll_position = [], + quickAddActive = false, + quickAddLink = null, + showAllLinkPorts = -1; + + var selectNodesOptions; + + var clipboard = ""; + + // Note: these are the permitted status colour aliases. The actual RGB values + // are set in the CSS - flow.scss/colors.scss + var status_colours = { + "red": "#c00", + "green": "#5a8", + "yellow": "#F9DF31", + "blue": "#53A3F3", + "grey": "#d3d3d3" + } + + var PORT_TYPE_INPUT = 1; + var PORT_TYPE_OUTPUT = 0; + + var chart; + var outer; + var eventLayer; + var gridLayer; + var linkLayer; + var dragGroupLayer; + var nodeLayer; + var drag_lines; + + function init() { + + chart = $("#red-ui-workspace-chart"); + + outer = d3.select("#red-ui-workspace-chart") + .append("svg:svg") + .attr("width", space_width) + .attr("height", space_height) + .attr("pointer-events", "all") + .style("cursor","crosshair") + .on("mousedown", function() { + focusView(); + }) + .on("contextmenu", function(){ + d3.event.preventDefault(); + }); + + eventLayer = outer + .append("svg:g") + .on("dblclick.zoom", null) + .append("svg:g") + .attr('class','red-ui-workspace-chart-event-layer') + .on("mousemove", canvasMouseMove) + .on("mousedown", canvasMouseDown) + .on("mouseup", canvasMouseUp) + .on("mouseenter", function() { + if (lasso) { + if (d3.event.buttons !== 1) { + lasso.remove(); + lasso = null; + } + } else if (mouse_mode === RED.state.PANNING && d3.event.buttons !== 4) { + resetMouseVars(); + } + }) + .on("touchend", function() { + clearTimeout(touchStartTime); + touchStartTime = null; + if (RED.touch.radialMenu.active()) { + return; + } + canvasMouseUp.call(this); + }) + .on("touchcancel", canvasMouseUp) + .on("touchstart", function() { + var touch0; + if (d3.event.touches.length>1) { + clearTimeout(touchStartTime); + touchStartTime = null; + d3.event.preventDefault(); + touch0 = d3.event.touches.item(0); + var touch1 = d3.event.touches.item(1); + var a = touch0["pageY"]-touch1["pageY"]; + var b = touch0["pageX"]-touch1["pageX"]; + + var offset = chart.offset(); + var scrollPos = [chart.scrollLeft(),chart.scrollTop()]; + startTouchCenter = [ + (touch1["pageX"]+(b/2)-offset.left+scrollPos[0])/scaleFactor, + (touch1["pageY"]+(a/2)-offset.top+scrollPos[1])/scaleFactor + ]; + moveTouchCenter = [ + touch1["pageX"]+(b/2), + touch1["pageY"]+(a/2) + ] + startTouchDistance = Math.sqrt((a*a)+(b*b)); + } else { + var obj = d3.select(document.body); + touch0 = d3.event.touches.item(0); + var pos = [touch0.pageX,touch0.pageY]; + startTouchCenter = [touch0.pageX,touch0.pageY]; + startTouchDistance = 0; + var point = d3.touches(this)[0]; + touchStartTime = setTimeout(function() { + touchStartTime = null; + showTouchMenu(obj,pos); + //lasso = eventLayer.append("rect") + // .attr("ox",point[0]) + // .attr("oy",point[1]) + // .attr("rx",2) + // .attr("ry",2) + // .attr("x",point[0]) + // .attr("y",point[1]) + // .attr("width",0) + // .attr("height",0) + // .attr("class","nr-ui-view-lasso"); + },touchLongPressTimeout); + } + }) + .on("touchmove", function(){ + if (RED.touch.radialMenu.active()) { + d3.event.preventDefault(); + return; + } + var touch0; + if (d3.event.touches.length<2) { + if (touchStartTime) { + touch0 = d3.event.touches.item(0); + var dx = (touch0.pageX-startTouchCenter[0]); + var dy = (touch0.pageY-startTouchCenter[1]); + var d = Math.abs(dx*dx+dy*dy); + if (d > 64) { + clearTimeout(touchStartTime); + touchStartTime = null; + } + } else if (lasso) { + d3.event.preventDefault(); + } + canvasMouseMove.call(this); + } else { + touch0 = d3.event.touches.item(0); + var touch1 = d3.event.touches.item(1); + var a = touch0["pageY"]-touch1["pageY"]; + var b = touch0["pageX"]-touch1["pageX"]; + var offset = chart.offset(); + var scrollPos = [chart.scrollLeft(),chart.scrollTop()]; + var moveTouchDistance = Math.sqrt((a*a)+(b*b)); + var touchCenter = [ + touch1["pageX"]+(b/2), + touch1["pageY"]+(a/2) + ]; + + if (!isNaN(moveTouchDistance)) { + oldScaleFactor = scaleFactor; + scaleFactor = Math.min(2,Math.max(0.3, scaleFactor + (Math.floor(((moveTouchDistance*100)-(startTouchDistance*100)))/10000))); + + var deltaTouchCenter = [ // Try to pan whilst zooming - not 100% + startTouchCenter[0]*(scaleFactor-oldScaleFactor),//-(touchCenter[0]-moveTouchCenter[0]), + startTouchCenter[1]*(scaleFactor-oldScaleFactor) //-(touchCenter[1]-moveTouchCenter[1]) + ]; + + startTouchDistance = moveTouchDistance; + moveTouchCenter = touchCenter; + + chart.scrollLeft(scrollPos[0]+deltaTouchCenter[0]); + chart.scrollTop(scrollPos[1]+deltaTouchCenter[1]); + redraw(); + } + } + }); + + // Workspace Background + eventLayer.append("svg:rect") + .attr("class","red-ui-workspace-chart-background") + .attr("width", space_width) + .attr("height", space_height); + + gridLayer = eventLayer.append("g").attr("class","red-ui-workspace-chart-grid"); + updateGrid(); + + linkLayer = eventLayer.append("g"); + dragGroupLayer = eventLayer.append("g"); + nodeLayer = eventLayer.append("g"); + drag_lines = []; + + RED.events.on("workspace:change",function(event) { + if (event.old !== 0) { + workspaceScrollPositions[event.old] = { + left:chart.scrollLeft(), + top:chart.scrollTop() + }; + } + var scrollStartLeft = chart.scrollLeft(); + var scrollStartTop = chart.scrollTop(); + + activeSubflow = RED.nodes.subflow(event.workspace); + + RED.menu.setDisabled("menu-item-workspace-edit", activeSubflow); + RED.menu.setDisabled("menu-item-workspace-delete",RED.workspaces.count() == 1 || activeSubflow); + + if (workspaceScrollPositions[event.workspace]) { + chart.scrollLeft(workspaceScrollPositions[event.workspace].left); + chart.scrollTop(workspaceScrollPositions[event.workspace].top); + } else { + chart.scrollLeft(0); + chart.scrollTop(0); + } + var scrollDeltaLeft = chart.scrollLeft() - scrollStartLeft; + var scrollDeltaTop = chart.scrollTop() - scrollStartTop; + if (mouse_position != null) { + mouse_position[0] += scrollDeltaLeft; + mouse_position[1] += scrollDeltaTop; + } + if (RED.workspaces.selection().length === 0) { + clearSelection(); + } + RED.nodes.eachNode(function(n) { + n.dirty = true; + n.dirtyStatus = true; + }); + updateSelection(); + updateActiveNodes(); + redraw(); + }); + + RED.statusBar.add({ + id: "view-zoom-controls", + align: "right", + element: $('<span class="button-group">'+ + '<button class="red-ui-footer-button" id="red-ui-view-zoom-out"><i class="fa fa-minus"></i></button>'+ + '<button class="red-ui-footer-button" id="red-ui-view-zoom-zero"><i class="fa fa-circle-o"></i></button>'+ + '<button class="red-ui-footer-button" id="red-ui-view-zoom-in"><i class="fa fa-plus"></i></button>'+ + '</span>') + }) + + $("#red-ui-view-zoom-out").on("click", zoomOut); + RED.popover.tooltip($("#red-ui-view-zoom-out"),RED._('actions.zoom-out'),'core:zoom-out'); + $("#red-ui-view-zoom-zero").on("click", zoomZero); + RED.popover.tooltip($("#red-ui-view-zoom-zero"),RED._('actions.zoom-reset'),'core:zoom-reset'); + $("#red-ui-view-zoom-in").on("click", zoomIn); + RED.popover.tooltip($("#red-ui-view-zoom-in"),RED._('actions.zoom-in'),'core:zoom-in'); + chart.on("DOMMouseScroll mousewheel", function (evt) { + if ( evt.altKey ) { + evt.preventDefault(); + evt.stopPropagation(); + var move = -(evt.originalEvent.detail) || evt.originalEvent.wheelDelta; + if (move <= 0) { zoomOut(); } + else { zoomIn(); } + } + }); + + // Handle nodes dragged from the palette + chart.droppable({ + accept:".red-ui-palette-node", + drop: function( event, ui ) { + d3.event = event; + var selected_tool = $(ui.draggable[0]).attr("data-palette-type"); + var result = addNode(selected_tool); + if (!result) { + return; + } + var historyEvent = result.historyEvent; + var nn = result.node; + + var showLabel = RED.utils.getMessageProperty(RED.settings.get('editor'),"view.view-node-show-label"); + if (showLabel !== undefined && !/^link (in|out)$/.test(nn._def.type) && !nn._def.defaults.hasOwnProperty("l")) { + nn.l = showLabel; + } + + var helperOffset = d3.touches(ui.helper.get(0))[0]||d3.mouse(ui.helper.get(0)); + var mousePos = d3.touches(this)[0]||d3.mouse(this); + + mousePos[1] += this.scrollTop + ((nn.h/2)-helperOffset[1]); + mousePos[0] += this.scrollLeft + ((nn.w/2)-helperOffset[0]); + mousePos[1] /= scaleFactor; + mousePos[0] /= scaleFactor; + + if (snapGrid) { + mousePos[0] = gridSize*(Math.ceil(mousePos[0]/gridSize)); + mousePos[1] = gridSize*(Math.ceil(mousePos[1]/gridSize)); + } + nn.x = mousePos[0]; + nn.y = mousePos[1]; + + var spliceLink = $(ui.helper).data("splice"); + if (spliceLink) { + // TODO: DRY - droppable/nodeMouseDown/canvasMouseUp/showQuickAddDialog + RED.nodes.removeLink(spliceLink); + var link1 = { + source:spliceLink.source, + sourcePort:spliceLink.sourcePort, + target: nn + }; + var link2 = { + source:nn, + sourcePort:0, + target: spliceLink.target + }; + RED.nodes.addLink(link1); + RED.nodes.addLink(link2); + historyEvent.links = [link1,link2]; + historyEvent.removedLinks = [spliceLink]; + } + + RED.history.push(historyEvent); + RED.nodes.add(nn); + RED.editor.validateNode(nn); + RED.nodes.dirty(true); + // auto select dropped node - so info shows (if visible) + clearSelection(); + nn.selected = true; + moving_set.push({n:nn}); + updateActiveNodes(); + updateSelection(); + redraw(); + + if (nn._def.autoedit) { + RED.editor.edit(nn); + } + } + }); + chart.on("focus", function() { + $("#red-ui-workspace-tabs").addClass("red-ui-workspace-focussed"); + }); + chart.on("blur", function() { + $("#red-ui-workspace-tabs").removeClass("red-ui-workspace-focussed"); + }); + + RED.actions.add("core:copy-selection-to-internal-clipboard",copySelection); + RED.actions.add("core:cut-selection-to-internal-clipboard",function(){copySelection();deleteSelection();}); + RED.actions.add("core:paste-from-internal-clipboard",function(){importNodes(clipboard);}); + RED.actions.add("core:delete-selection",deleteSelection); + RED.actions.add("core:edit-selected-node",editSelection); + RED.actions.add("core:undo",RED.history.pop); + RED.actions.add("core:redo",RED.history.redo); + RED.actions.add("core:select-all-nodes",selectAll); + RED.actions.add("core:zoom-in",zoomIn); + RED.actions.add("core:zoom-out",zoomOut); + RED.actions.add("core:zoom-reset",zoomZero); + RED.actions.add("core:enable-selected-nodes", function() { setSelectedNodeState(false)}); + RED.actions.add("core:disable-selected-nodes", function() { setSelectedNodeState(true)}); + + RED.actions.add("core:toggle-show-grid",function(state) { + if (state === undefined) { + RED.userSettings.toggle("view-show-grid"); + } else { + toggleShowGrid(state); + } + }); + RED.actions.add("core:toggle-snap-grid",function(state) { + if (state === undefined) { + RED.userSettings.toggle("view-snap-grid"); + } else { + toggleSnapGrid(state); + } + }); + RED.actions.add("core:toggle-status",function(state) { + if (state === undefined) { + RED.userSettings.toggle("view-node-status"); + } else { + toggleStatus(state); + } + }); + + RED.view.navigator.init(); + RED.view.tools.init(); + } + + function updateGrid() { + var gridTicks = []; + for (var i=0;i<space_width;i+=+gridSize) { + gridTicks.push(i); + } + gridLayer.selectAll("line.red-ui-workspace-chart-grid-h").remove(); + gridLayer.selectAll("line.red-ui-workspace-chart-grid-h").data(gridTicks).enter() + .append("line") + .attr( + { + "class":"red-ui-workspace-chart-grid-h", + "x1" : 0, + "x2" : space_width, + "y1" : function(d){ return d;}, + "y2" : function(d){ return d;} + }); + gridLayer.selectAll("line.red-ui-workspace-chart-grid-v").remove(); + gridLayer.selectAll("line.red-ui-workspace-chart-grid-v").data(gridTicks).enter() + .append("line") + .attr( + { + "class":"red-ui-workspace-chart-grid-v", + "y1" : 0, + "y2" : space_width, + "x1" : function(d){ return d;}, + "x2" : function(d){ return d;} + }); + } + + function showDragLines(nodes) { + showAllLinkPorts = -1; + for (var i=0;i<nodes.length;i++) { + var node = nodes[i]; + node.el = dragGroupLayer.append("svg:path").attr("class", "red-ui-flow-drag-line"); + if ((node.node.type === "link out" && node.portType === PORT_TYPE_OUTPUT) || + (node.node.type === "link in" && node.portType === PORT_TYPE_INPUT)) { + node.el.attr("class","red-ui-flow-link-link red-ui-flow-drag-line"); + node.virtualLink = true; + showAllLinkPorts = (node.portType === PORT_TYPE_OUTPUT)?PORT_TYPE_INPUT:PORT_TYPE_OUTPUT; + } + drag_lines.push(node); + } + if (showAllLinkPorts !== -1) { + activeNodes.forEach(function(n) { + if (n.type === "link in" || n.type === "link out") { + n.dirty = true; + } + }) + } + } + function hideDragLines() { + if (showAllLinkPorts !== -1) { + activeNodes.forEach(function(n) { + if (n.type === "link in" || n.type === "link out") { + n.dirty = true; + } + }) + } + showAllLinkPorts = -1; + while(drag_lines.length) { + var line = drag_lines.pop(); + if (line.el) { + line.el.remove(); + } + } + } + + function updateActiveNodes() { + var activeWorkspace = RED.workspaces.active(); + + activeNodes = RED.nodes.filterNodes({z:activeWorkspace}); + + activeLinks = RED.nodes.filterLinks({ + source:{z:activeWorkspace}, + target:{z:activeWorkspace} + }); + } + + function generateLinkPath(origX,origY, destX, destY, sc) { + var dy = destY-origY; + var dx = destX-origX; + var delta = Math.sqrt(dy*dy+dx*dx); + var scale = lineCurveScale; + var scaleY = 0; + if (dx*sc > 0) { + if (delta < node_width) { + scale = 0.75-0.75*((node_width-delta)/node_width); + // scale += 2*(Math.min(5*node_width,Math.abs(dx))/(5*node_width)); + // if (Math.abs(dy) < 3*node_height) { + // scaleY = ((dy>0)?0.5:-0.5)*(((3*node_height)-Math.abs(dy))/(3*node_height))*(Math.min(node_width,Math.abs(dx))/(node_width)) ; + // } + } + } else { + scale = 0.4-0.2*(Math.max(0,(node_width-Math.min(Math.abs(dx),Math.abs(dy)))/node_width)); + } + if (dx*sc > 0) { + return "M "+origX+" "+origY+ + " C "+(origX+sc*(node_width*scale))+" "+(origY+scaleY*node_height)+" "+ + (destX-sc*(scale)*node_width)+" "+(destY-scaleY*node_height)+" "+ + destX+" "+destY + } else { + + var midX = Math.floor(destX-dx/2); + var midY = Math.floor(destY-dy/2); + // + if (dy === 0) { + midY = destY + node_height; + } + var cp_height = node_height/2; + var y1 = (destY + midY)/2 + var topX =origX + sc*node_width*scale; + var topY = dy>0?Math.min(y1 - dy/2 , origY+cp_height):Math.max(y1 - dy/2 , origY-cp_height); + var bottomX = destX - sc*node_width*scale; + var bottomY = dy>0?Math.max(y1, destY-cp_height):Math.min(y1, destY+cp_height); + var x1 = (origX+topX)/2; + var scy = dy>0?1:-1; + var cp = [ + // Orig -> Top + [x1,origY], + [topX,dy>0?Math.max(origY, topY-cp_height):Math.min(origY, topY+cp_height)], + // Top -> Mid + // [Mirror previous cp] + [x1,dy>0?Math.min(midY, topY+cp_height):Math.max(midY, topY-cp_height)], + // Mid -> Bottom + // [Mirror previous cp] + [bottomX,dy>0?Math.max(midY, bottomY-cp_height):Math.min(midY, bottomY+cp_height)], + // Bottom -> Dest + // [Mirror previous cp] + [(destX+bottomX)/2,destY] + ]; + if (cp[2][1] === topY+scy*cp_height) { + if (Math.abs(dy) < cp_height*10) { + cp[1][1] = topY-scy*cp_height/2; + cp[3][1] = bottomY-scy*cp_height/2; + } + cp[2][0] = topX; + } + return "M "+origX+" "+origY+ + " C "+ + cp[0][0]+" "+cp[0][1]+" "+ + cp[1][0]+" "+cp[1][1]+" "+ + topX+" "+topY+ + " S "+ + cp[2][0]+" "+cp[2][1]+" "+ + midX+" "+midY+ + " S "+ + cp[3][0]+" "+cp[3][1]+" "+ + bottomX+" "+bottomY+ + " S "+ + cp[4][0]+" "+cp[4][1]+" "+ + destX+" "+destY + } + } + + function addNode(type,x,y) { + var m = /^subflow:(.+)$/.exec(type); + + if (activeSubflow && m) { + var subflowId = m[1]; + if (subflowId === activeSubflow.id) { + RED.notify(RED._("notification.error",{message: RED._("notification.errors.cannotAddSubflowToItself")}),"error"); + return; + } + if (RED.nodes.subflowContains(m[1],activeSubflow.id)) { + RED.notify(RED._("notification.error",{message: RED._("notification.errors.cannotAddCircularReference")}),"error"); + return; + } + } + + var nn = { id:RED.nodes.id(),z:RED.workspaces.active()}; + + nn.type = type; + nn._def = RED.nodes.getType(nn.type); + + if (!m) { + nn.inputs = nn._def.inputs || 0; + nn.outputs = nn._def.outputs; + + for (var d in nn._def.defaults) { + if (nn._def.defaults.hasOwnProperty(d)) { + if (nn._def.defaults[d].value !== undefined) { + nn[d] = JSON.parse(JSON.stringify(nn._def.defaults[d].value)); + } + } + } + + if (nn._def.onadd) { + try { + nn._def.onadd.call(nn); + } catch(err) { + console.log("Definition error: "+nn.type+".onadd:",err); + } + } + } else { + var subflow = RED.nodes.subflow(m[1]); + nn.name = ""; + nn.inputs = subflow.in.length; + nn.outputs = subflow.out.length; + } + + nn.changed = true; + nn.moved = true; + + nn.w = node_width; + nn.h = Math.max(node_height,(nn.outputs||0) * 15); + nn.resize = true; + + var historyEvent = { + t:"add", + nodes:[nn.id], + dirty:RED.nodes.dirty() + } + if (activeSubflow) { + var subflowRefresh = RED.subflow.refresh(true); + if (subflowRefresh) { + historyEvent.subflow = { + id:activeSubflow.id, + changed: activeSubflow.changed, + instances: subflowRefresh.instances + } + } + } + return { + node: nn, + historyEvent: historyEvent + } + + } + + function canvasMouseDown() { + var point; + if (mouse_mode === RED.state.SELECTING_NODE) { + d3.event.stopPropagation(); + return; + } + + if (d3.event.button === 1) { + // Middle Click pan + mouse_mode = RED.state.PANNING; + mouse_position = [d3.event.pageX,d3.event.pageY] + scroll_position = [chart.scrollLeft(),chart.scrollTop()]; + return; + } + if (!mousedown_node && !mousedown_link) { + selected_link = null; + updateSelection(); + } + if (mouse_mode === 0) { + if (lasso) { + lasso.remove(); + lasso = null; + } + } + if (mouse_mode === 0 || mouse_mode === RED.state.QUICK_JOINING) { + if (d3.event.metaKey || d3.event.ctrlKey) { + d3.event.stopPropagation(); + showQuickAddDialog(d3.mouse(this)); + } + } + if (mouse_mode === 0 && !(d3.event.metaKey || d3.event.ctrlKey)) { + if (!touchStartTime) { + point = d3.mouse(this); + lasso = eventLayer.append("rect") + .attr("ox",point[0]) + .attr("oy",point[1]) + .attr("rx",1) + .attr("ry",1) + .attr("x",point[0]) + .attr("y",point[1]) + .attr("width",0) + .attr("height",0) + .attr("class","nr-ui-view-lasso"); + d3.event.preventDefault(); + } + } + } + + function showQuickAddDialog(point,spliceLink) { + var ox = point[0]; + var oy = point[1]; + + if (RED.settings.get("editor").view['view-snap-grid']) { + // eventLayer.append("circle").attr("cx",point[0]).attr("cy",point[1]).attr("r","2").attr('fill','red') + point[0] = Math.round(point[0] / gridSize) * gridSize; + point[1] = Math.round(point[1] / gridSize) * gridSize; + // eventLayer.append("circle").attr("cx",point[0]).attr("cy",point[1]).attr("r","2").attr('fill','blue') + } + + var mainPos = $("#red-ui-main-container").position(); + + if (mouse_mode !== RED.state.QUICK_JOINING) { + mouse_mode = RED.state.QUICK_JOINING; + $(window).on('keyup',disableQuickJoinEventHandler); + } + quickAddActive = true; + + if (ghostNode) { + ghostNode.remove(); + } + ghostNode = eventLayer.append("g").attr('transform','translate('+(point[0] - node_width/2)+','+(point[1] - node_height/2)+')'); + ghostNode.append("rect") + .attr("class","red-ui-flow-node-placeholder") + .attr("rx", 5) + .attr("ry", 5) + .attr("width",node_width) + .attr("height",node_height) + .attr("fill","none") + // var ghostLink = ghostNode.append("svg:path") + // .attr("class","red-ui-flow-link-link") + // .attr("d","M 0 "+(node_height/2)+" H "+(gridSize * -2)) + // .attr("opacity",0); + + var filter; + if (drag_lines.length > 0) { + if (drag_lines[0].virtualLink) { + filter = {type:drag_lines[0].node.type === 'link in'?'link out':'link in'} + } else if (drag_lines[0].portType === PORT_TYPE_OUTPUT) { + filter = {input:true} + } else { + filter = {output:true} + } + + quickAddLink = { + node: drag_lines[0].node, + port: drag_lines[0].port, + portType: drag_lines[0].portType, + } + if (drag_lines[0].virtualLink) { + quickAddLink.virtualLink = true; + } + hideDragLines(); + } + if (spliceLink) { + filter = {input:true, output:true} + } + + var rebuildQuickAddLink = function() { + if (!quickAddLink) { + return; + } + if (!quickAddLink.el) { + quickAddLink.el = dragGroupLayer.append("svg:path").attr("class", "red-ui-flow-drag-line"); + } + var numOutputs = (quickAddLink.portType === PORT_TYPE_OUTPUT)?(quickAddLink.node.outputs || 1):1; + var sourcePort = quickAddLink.port; + var portY = -((numOutputs-1)/2)*13 +13*sourcePort; + var sc = (quickAddLink.portType === PORT_TYPE_OUTPUT)?1:-1; + quickAddLink.el.attr("d",generateLinkPath(quickAddLink.node.x+sc*quickAddLink.node.w/2,quickAddLink.node.y+portY,point[0]-sc*node_width/2,point[1],sc)); + } + if (quickAddLink) { + rebuildQuickAddLink(); + } + + + var lastAddedX; + var lastAddedWidth; + + RED.typeSearch.show({ + x:d3.event.clientX-mainPos.left-node_width/2 - (ox-point[0]), + y:d3.event.clientY-mainPos.top+ node_height/2 + 5 - (oy-point[1]), + filter: filter, + move: function(dx,dy) { + if (ghostNode) { + var pos = d3.transform(ghostNode.attr("transform")).translate; + ghostNode.attr("transform","translate("+(pos[0]+dx)+","+(pos[1]+dy)+")") + point[0] += dx; + point[1] += dy; + rebuildQuickAddLink(); + } + }, + cancel: function() { + if (quickAddLink) { + if (quickAddLink.el) { + quickAddLink.el.remove(); + } + quickAddLink = null; + } + quickAddActive = false; + if (ghostNode) { + ghostNode.remove(); + } + resetMouseVars(); + updateSelection(); + hideDragLines(); + redraw(); + }, + add: function(type,keepAdding) { + var result = addNode(type); + if (!result) { + return; + } + if (keepAdding) { + mouse_mode = RED.state.QUICK_JOINING; + } + + var nn = result.node; + var historyEvent = result.historyEvent; + nn.x = point[0]; + nn.y = point[1]; + var showLabel = RED.utils.getMessageProperty(RED.settings.get('editor'),"view.view-node-show-label"); + if (showLabel !== undefined && !/^link (in|out)$/.test(nn._def.type) && !nn._def.defaults.hasOwnProperty("l")) { + nn.l = showLabel; + } + if (quickAddLink) { + var drag_line = quickAddLink; + var src = null,dst,src_port; + if (drag_line.portType === PORT_TYPE_OUTPUT && (nn.inputs > 0 || drag_line.virtualLink) ) { + src = drag_line.node; + src_port = drag_line.port; + dst = nn; + } else if (drag_line.portType === PORT_TYPE_INPUT && (nn.outputs > 0 || drag_line.virtualLink)) { + src = nn; + dst = drag_line.node; + src_port = 0; + } + + if (src !== null) { + // Joining link nodes via virual wires. Need to update + // the src and dst links property + if (drag_line.virtualLink) { + historyEvent = { + t:'multi', + events: [historyEvent] + } + var oldSrcLinks = $.extend(true,{},{v:src.links}).v + var oldDstLinks = $.extend(true,{},{v:dst.links}).v + src.links.push(dst.id); + dst.links.push(src.id); + src.dirty = true; + dst.dirty = true; + + historyEvent.events.push({ + t:'edit', + node: src, + dirty: RED.nodes.dirty(), + changed: src.changed, + changes: { + links:oldSrcLinks + } + }); + historyEvent.events.push({ + t:'edit', + node: dst, + dirty: RED.nodes.dirty(), + changed: dst.changed, + changes: { + links:oldDstLinks + } + }); + src.changed = true; + dst.changed = true; + } else { + var link = {source: src, sourcePort:src_port, target: dst}; + RED.nodes.addLink(link); + historyEvent.links = [link]; + } + if (!keepAdding) { + quickAddLink.el.remove(); + quickAddLink = null; + if (mouse_mode === RED.state.QUICK_JOINING) { + if (drag_line.portType === PORT_TYPE_OUTPUT && nn.outputs > 0) { + showDragLines([{node:nn,port:0,portType:PORT_TYPE_OUTPUT}]); + } else if (!quickAddLink && drag_line.portType === PORT_TYPE_INPUT && nn.inputs > 0) { + showDragLines([{node:nn,port:0,portType:PORT_TYPE_INPUT}]); + } else { + resetMouseVars(); + } + } + } else { + quickAddLink.node = nn; + quickAddLink.port = 0; + } + } else { + hideDragLines(); + resetMouseVars(); + } + } else { + if (!keepAdding) { + if (mouse_mode === RED.state.QUICK_JOINING) { + if (nn.outputs > 0) { + showDragLines([{node:nn,port:0,portType:PORT_TYPE_OUTPUT}]); + } else if (nn.inputs > 0) { + showDragLines([{node:nn,port:0,portType:PORT_TYPE_INPUT}]); + } else { + resetMouseVars(); + } + } + } else { + if (nn.outputs > 0) { + quickAddLink = { + node: nn, + port: 0, + portType: PORT_TYPE_OUTPUT + } + } else if (nn.inputs > 0) { + quickAddLink = { + node: nn, + port: 0, + portType: PORT_TYPE_INPUT + } + } else { + resetMouseVars(); + } + } + } + if (spliceLink) { + resetMouseVars(); + // TODO: DRY - droppable/nodeMouseDown/canvasMouseUp/showQuickAddDialog + RED.nodes.removeLink(spliceLink); + var link1 = { + source:spliceLink.source, + sourcePort:spliceLink.sourcePort, + target: nn + }; + var link2 = { + source:nn, + sourcePort:0, + target: spliceLink.target + }; + RED.nodes.addLink(link1); + RED.nodes.addLink(link2); + historyEvent.links = (historyEvent.links || []).concat([link1,link2]); + historyEvent.removedLinks = [spliceLink]; + } + RED.history.push(historyEvent); + RED.nodes.add(nn); + RED.editor.validateNode(nn); + RED.nodes.dirty(true); + // auto select dropped node - so info shows (if visible) + clearSelection(); + nn.selected = true; + moving_set.push({n:nn}); + updateActiveNodes(); + updateSelection(); + redraw(); + // At this point the newly added node will have a real width, + // so check if the position needs nudging + if (lastAddedX !== undefined) { + var lastNodeRHEdge = lastAddedX + lastAddedWidth/2; + var thisNodeLHEdge = nn.x - nn.w/2; + var gap = thisNodeLHEdge - lastNodeRHEdge; + if (gap != gridSize *2) { + nn.x = nn.x + gridSize * 2 - gap; + nn.dirty = true; + nn.x = Math.ceil(nn.x / gridSize) * gridSize; + redraw(); + } + } + if (keepAdding) { + if (lastAddedX === undefined) { + // ghostLink.attr("opacity",1); + setTimeout(function() { + RED.typeSearch.refresh({filter:{input:true}}); + },100); + } + + lastAddedX = nn.x; + lastAddedWidth = nn.w; + + point[0] = nn.x + nn.w/2 + node_width/2 + gridSize * 2; + ghostNode.attr('transform','translate('+(point[0] - node_width/2)+','+(point[1] - node_height/2)+')'); + rebuildQuickAddLink(); + } else { + quickAddActive = false; + ghostNode.remove(); + } + } + }); + + updateActiveNodes(); + updateSelection(); + redraw(); + } + + function canvasMouseMove() { + var i; + var node; + // Prevent touch scrolling... + //if (d3.touches(this)[0]) { + // d3.event.preventDefault(); + //} + + // TODO: auto scroll the container + //var point = d3.mouse(this); + //if (point[0]-container.scrollLeft < 30 && container.scrollLeft > 0) { container.scrollLeft -= 15; } + //console.log(d3.mouse(this),container.offsetWidth,container.offsetHeight,container.scrollLeft,container.scrollTop); + + if (mouse_mode === RED.state.PANNING) { + + var pos = [d3.event.pageX,d3.event.pageY]; + var deltaPos = [ + mouse_position[0]-pos[0], + mouse_position[1]-pos[1] + ]; + + chart.scrollLeft(scroll_position[0]+deltaPos[0]) + chart.scrollTop(scroll_position[1]+deltaPos[1]) + return + } + + mouse_position = d3.touches(this)[0]||d3.mouse(this); + + if (lasso) { + var ox = parseInt(lasso.attr("ox")); + var oy = parseInt(lasso.attr("oy")); + var x = parseInt(lasso.attr("x")); + var y = parseInt(lasso.attr("y")); + var w; + var h; + if (mouse_position[0] < ox) { + x = mouse_position[0]; + w = ox-x; + } else { + w = mouse_position[0]-x; + } + if (mouse_position[1] < oy) { + y = mouse_position[1]; + h = oy-y; + } else { + h = mouse_position[1]-y; + } + lasso + .attr("x",x) + .attr("y",y) + .attr("width",w) + .attr("height",h) + ; + return; + } + + if (mouse_mode === RED.state.SELECTING_NODE) { + d3.event.stopPropagation(); + return; + } + + if (mouse_mode != RED.state.QUICK_JOINING && mouse_mode != RED.state.IMPORT_DRAGGING && !mousedown_node && selected_link == null) { + return; + } + + var mousePos; + if (mouse_mode == RED.state.JOINING || mouse_mode === RED.state.QUICK_JOINING) { + // update drag line + if (drag_lines.length === 0 && mousedown_port_type !== null) { + if (d3.event.shiftKey) { + // Get all the wires we need to detach. + var links = []; + var existingLinks = []; + if (selected_link && + ((mousedown_port_type === PORT_TYPE_OUTPUT && + selected_link.source === mousedown_node && + selected_link.sourcePort === mousedown_port_index + ) || + (mousedown_port_type === PORT_TYPE_INPUT && + selected_link.target === mousedown_node + )) + ) { + existingLinks = [selected_link]; + } else { + var filter; + if (mousedown_port_type === PORT_TYPE_OUTPUT) { + filter = { + source:mousedown_node, + sourcePort: mousedown_port_index + } + } else { + filter = { + target: mousedown_node + } + } + existingLinks = RED.nodes.filterLinks(filter); + } + for (i=0;i<existingLinks.length;i++) { + var link = existingLinks[i]; + RED.nodes.removeLink(link); + links.push({ + link:link, + node: (mousedown_port_type===PORT_TYPE_OUTPUT)?link.target:link.source, + port: (mousedown_port_type===PORT_TYPE_OUTPUT)?0:link.sourcePort, + portType: (mousedown_port_type===PORT_TYPE_OUTPUT)?PORT_TYPE_INPUT:PORT_TYPE_OUTPUT + }) + } + if (links.length === 0) { + resetMouseVars(); + redraw(); + } else { + showDragLines(links); + mouse_mode = 0; + updateActiveNodes(); + redraw(); + mouse_mode = RED.state.JOINING; + } + } else if (mousedown_node && !quickAddLink) { + showDragLines([{node:mousedown_node,port:mousedown_port_index,portType:mousedown_port_type}]); + } + selected_link = null; + } + mousePos = mouse_position; + for (i=0;i<drag_lines.length;i++) { + var drag_line = drag_lines[i]; + var numOutputs = (drag_line.portType === PORT_TYPE_OUTPUT)?(drag_line.node.outputs || 1):1; + var sourcePort = drag_line.port; + var portY = -((numOutputs-1)/2)*13 +13*sourcePort; + + var sc = (drag_line.portType === PORT_TYPE_OUTPUT)?1:-1; + drag_line.el.attr("d",generateLinkPath(drag_line.node.x+sc*drag_line.node.w/2,drag_line.node.y+portY,mousePos[0],mousePos[1],sc)); + } + d3.event.preventDefault(); + } else if (mouse_mode == RED.state.MOVING) { + mousePos = d3.mouse(document.body); + if (isNaN(mousePos[0])) { + mousePos = d3.touches(document.body)[0]; + } + var d = (mouse_offset[0]-mousePos[0])*(mouse_offset[0]-mousePos[0]) + (mouse_offset[1]-mousePos[1])*(mouse_offset[1]-mousePos[1]); + if (d > 3) { + mouse_mode = RED.state.MOVING_ACTIVE; + clickElapsed = 0; + spliceActive = false; + if (moving_set.length === 1) { + node = moving_set[0]; + spliceActive = node.n.hasOwnProperty("_def") && + ((node.n.hasOwnProperty("inputs") && node.n.inputs > 0) || (!node.n.hasOwnProperty("inputs") && node.n._def.inputs > 0)) && + ((node.n.hasOwnProperty("outputs") && node.n.outputs > 0) || (!node.n.hasOwnProperty("outputs") && node.n._def.outputs > 0)) && + RED.nodes.filterLinks({ source: node.n }).length === 0 && + RED.nodes.filterLinks({ target: node.n }).length === 0; + } + } + } else if (mouse_mode == RED.state.MOVING_ACTIVE || mouse_mode == RED.state.IMPORT_DRAGGING) { + mousePos = mouse_position; + var minX = 0; + var minY = 0; + var maxX = space_width; + var maxY = space_height; + for (var n = 0; n<moving_set.length; n++) { + node = moving_set[n]; + if (d3.event.shiftKey) { + node.n.ox = node.n.x; + node.n.oy = node.n.y; + } + node.n.x = mousePos[0]+node.dx; + node.n.y = mousePos[1]+node.dy; + node.n.dirty = true; + minX = Math.min(node.n.x-node.n.w/2-5,minX); + minY = Math.min(node.n.y-node.n.h/2-5,minY); + maxX = Math.max(node.n.x+node.n.w/2+5,maxX); + maxY = Math.max(node.n.y+node.n.h/2+5,maxY); + } + if (minX !== 0 || minY !== 0) { + for (i = 0; i<moving_set.length; i++) { + node = moving_set[i]; + node.n.x -= minX; + node.n.y -= minY; + } + } + if (maxX !== space_width || maxY !== space_height) { + for (i = 0; i<moving_set.length; i++) { + node = moving_set[i]; + node.n.x -= (maxX - space_width); + node.n.y -= (maxY - space_height); + } + } + if (snapGrid != d3.event.shiftKey && moving_set.length > 0) { + var gridOffset = [0,0]; + node = moving_set[0]; + gridOffset[0] = node.n.x-(gridSize*Math.floor((node.n.x-node.n.w/2)/gridSize)+node.n.w/2); + gridOffset[1] = node.n.y-(gridSize*Math.floor(node.n.y/gridSize)); + if (gridOffset[0] !== 0 || gridOffset[1] !== 0) { + for (i = 0; i<moving_set.length; i++) { + node = moving_set[i]; + node.n.x -= gridOffset[0]; + node.n.y -= gridOffset[1]; + if (node.n.x == node.n.ox && node.n.y == node.n.oy) { + node.dirty = false; + } + } + } + } + if ((mouse_mode == RED.state.MOVING_ACTIVE || mouse_mode == RED.state.IMPORT_DRAGGING) && moving_set.length === 1) { + node = moving_set[0]; + if (spliceActive) { + if (!spliceTimer) { + spliceTimer = setTimeout(function() { + var nodes = []; + var bestDistance = Infinity; + var bestLink = null; + var mouseX = node.n.x; + var mouseY = node.n.y; + if (outer[0][0].getIntersectionList) { + var svgRect = outer[0][0].createSVGRect(); + svgRect.x = mouseX; + svgRect.y = mouseY; + svgRect.width = 1; + svgRect.height = 1; + nodes = outer[0][0].getIntersectionList(svgRect, outer[0][0]); + } else { + // Firefox doesn"t do getIntersectionList and that + // makes us sad + nodes = RED.view.getLinksAtPoint(mouseX,mouseY); + } + for (var i=0;i<nodes.length;i++) { + if (d3.select(nodes[i]).classed("red-ui-flow-link-background")) { + var length = nodes[i].getTotalLength(); + for (var j=0;j<length;j+=10) { + var p = nodes[i].getPointAtLength(j); + var d2 = ((p.x-mouseX)*(p.x-mouseX))+((p.y-mouseY)*(p.y-mouseY)); + if (d2 < 200 && d2 < bestDistance) { + bestDistance = d2; + bestLink = nodes[i]; + } + } + } + } + if (activeSpliceLink && activeSpliceLink !== bestLink) { + d3.select(activeSpliceLink.parentNode).classed("red-ui-flow-link-splice",false); + } + if (bestLink) { + d3.select(bestLink.parentNode).classed("red-ui-flow-link-splice",true) + } else { + d3.select(".red-ui-flow-link-splice").classed("red-ui-flow-link-splice",false); + } + activeSpliceLink = bestLink; + spliceTimer = null; + },100); + } + } + } + + + } + if (mouse_mode !== 0) { + redraw(); + } + } + + function canvasMouseUp() { + var i; + var historyEvent; + if (mouse_mode === RED.state.PANNING) { + resetMouseVars(); + return + } + if (mouse_mode === RED.state.SELECTING_NODE) { + d3.event.stopPropagation(); + return; + } + if (mouse_mode === RED.state.QUICK_JOINING) { + return; + } + if (mousedown_node && mouse_mode == RED.state.JOINING) { + var removedLinks = []; + for (i=0;i<drag_lines.length;i++) { + if (drag_lines[i].link) { + removedLinks.push(drag_lines[i].link) + } + } + if (removedLinks.length > 0) { + historyEvent = { + t:"delete", + links: removedLinks, + dirty:RED.nodes.dirty() + }; + RED.history.push(historyEvent); + RED.nodes.dirty(true); + } + hideDragLines(); + } + if (lasso) { + var x = parseInt(lasso.attr("x")); + var y = parseInt(lasso.attr("y")); + var x2 = x+parseInt(lasso.attr("width")); + var y2 = y+parseInt(lasso.attr("height")); + if (!d3.event.ctrlKey) { + clearSelection(); + } + RED.nodes.eachNode(function(n) { + if (n.z == RED.workspaces.active() && !n.selected) { + n.selected = (n.x > x && n.x < x2 && n.y > y && n.y < y2); + if (n.selected) { + n.dirty = true; + moving_set.push({n:n}); + } + } + }); + if (activeSubflow) { + activeSubflow.in.forEach(function(n) { + n.selected = (n.x > x && n.x < x2 && n.y > y && n.y < y2); + if (n.selected) { + n.dirty = true; + moving_set.push({n:n}); + } + }); + activeSubflow.out.forEach(function(n) { + n.selected = (n.x > x && n.x < x2 && n.y > y && n.y < y2); + if (n.selected) { + n.dirty = true; + moving_set.push({n:n}); + } + }); + if (activeSubflow.status) { + activeSubflow.status.selected = (activeSubflow.status.x > x && activeSubflow.status.x < x2 && activeSubflow.status.y > y && activeSubflow.status.y < y2); + if (activeSubflow.status.selected) { + activeSubflow.status.dirty = true; + moving_set.push({n:activeSubflow.status}); + } + } + } + updateSelection(); + lasso.remove(); + lasso = null; + } else if (mouse_mode == RED.state.DEFAULT && mousedown_link == null && !d3.event.ctrlKey && !d3.event.metaKey ) { + clearSelection(); + updateSelection(); + } + if (mouse_mode == RED.state.MOVING_ACTIVE) { + if (moving_set.length > 0) { + var ns = []; + for (var j=0;j<moving_set.length;j++) { + var n = moving_set[j]; + if (n.ox !== n.n.x || n.oy !== n.n.y) { + ns.push({n:n.n,ox:n.ox,oy:n.oy,moved:n.n.moved}); + n.n.dirty = true; + n.n.moved = true; + } + } + if (ns.length > 0) { + historyEvent = {t:"move",nodes:ns,dirty:RED.nodes.dirty()}; + if (activeSpliceLink) { + // TODO: DRY - droppable/nodeMouseDown/canvasMouseUp + var spliceLink = d3.select(activeSpliceLink).data()[0]; + RED.nodes.removeLink(spliceLink); + var link1 = { + source:spliceLink.source, + sourcePort:spliceLink.sourcePort, + target: moving_set[0].n + }; + var link2 = { + source:moving_set[0].n, + sourcePort:0, + target: spliceLink.target + }; + RED.nodes.addLink(link1); + RED.nodes.addLink(link2); + historyEvent.links = [link1,link2]; + historyEvent.removedLinks = [spliceLink]; + updateActiveNodes(); + } + RED.nodes.dirty(true); + RED.history.push(historyEvent); + } + } + } + if (mouse_mode == RED.state.MOVING || mouse_mode == RED.state.MOVING_ACTIVE) { + for (i=0;i<moving_set.length;i++) { + delete moving_set[i].ox; + delete moving_set[i].oy; + } + } + if (mouse_mode == RED.state.IMPORT_DRAGGING) { + RED.keyboard.remove("escape"); + updateActiveNodes(); + RED.nodes.dirty(true); + } + resetMouseVars(); + redraw(); + } + + function zoomIn() { + if (scaleFactor < 2) { + zoomView(scaleFactor+0.1); + } + } + function zoomOut() { + if (scaleFactor > 0.3) { + zoomView(scaleFactor-0.1); + } + } + function zoomZero() { zoomView(1); } + + function zoomView(factor) { + var screenSize = [chart.width(),chart.height()]; + var scrollPos = [chart.scrollLeft(),chart.scrollTop()]; + var center = [(scrollPos[0] + screenSize[0]/2)/scaleFactor,(scrollPos[1] + screenSize[1]/2)/scaleFactor]; + scaleFactor = factor; + var newCenter = [(scrollPos[0] + screenSize[0]/2)/scaleFactor,(scrollPos[1] + screenSize[1]/2)/scaleFactor]; + var delta = [(newCenter[0]-center[0])*scaleFactor,(newCenter[1]-center[1])*scaleFactor] + chart.scrollLeft(scrollPos[0]-delta[0]); + chart.scrollTop(scrollPos[1]-delta[1]); + + RED.view.navigator.resize(); + redraw(); + } + + + function selectAll() { + if (mouse_mode === RED.state.SELECTING_NODE && selectNodesOptions.single) { + return; + } + RED.nodes.eachNode(function(n) { + if (n.z == RED.workspaces.active()) { + if (mouse_mode === RED.state.SELECTING_NODE) { + if (selectNodesOptions.filter && !selectNodesOptions.filter(n)) { + return; + } + } + if (!n.selected) { + n.selected = true; + n.dirty = true; + moving_set.push({n:n}); + } + } + }); + if (mouse_mode !== RED.state.SELECTING_NODE && activeSubflow) { + activeSubflow.in.forEach(function(n) { + if (!n.selected) { + n.selected = true; + n.dirty = true; + moving_set.push({n:n}); + } + }); + activeSubflow.out.forEach(function(n) { + if (!n.selected) { + n.selected = true; + n.dirty = true; + moving_set.push({n:n}); + } + }); + if (activeSubflow.status) { + if (!activeSubflow.status.selected) { + activeSubflow.status.selected = true; + activeSubflow.status.dirty = true; + moving_set.push({n:activeSubflow.status}); + } + } + } + + selected_link = null; + if (mouse_mode !== RED.state.SELECTING_NODE) { + updateSelection(); + } + redraw(); + } + + function clearSelection() { + for (var i=0;i<moving_set.length;i++) { + var n = moving_set[i]; + n.n.dirty = true; + n.n.selected = false; + } + moving_set = []; + selected_link = null; + } + + var lastSelection = null; + function updateSelection() { + var selection = {}; + var activeWorkspace = RED.workspaces.active(); + + var workspaceSelection = RED.workspaces.selection(); + if (workspaceSelection.length === 0) { + if (moving_set.length > 0) { + selection.nodes = moving_set.map(function(n) { return n.n;}); + } + if (selected_link != null) { + selection.link = selected_link; + } + activeLinks = RED.nodes.filterLinks({ + source:{z:activeWorkspace}, + target:{z:activeWorkspace} + }); + var tabOrder = RED.nodes.getWorkspaceOrder(); + var currentLinks = activeLinks; + var addedLinkLinks = {}; + activeFlowLinks = []; + var activeLinkNodeIds = Object.keys(activeLinkNodes); + activeLinkNodeIds.forEach(function(n) { + activeLinkNodes[n].dirty = true; + }) + activeLinkNodes = {}; + for (var i=0;i<moving_set.length;i++) { + if (moving_set[i].n.type === "link out" || moving_set[i].n.type === "link in") { + var linkNode = moving_set[i].n; + activeLinkNodes[linkNode.id] = linkNode; + var offFlowLinks = {}; + linkNode.links.forEach(function(id) { + var target = RED.nodes.node(id); + if (target) { + if (linkNode.type === "link out") { + if (target.z === linkNode.z) { + if (!addedLinkLinks[linkNode.id+":"+target.id]) { + activeLinks.push({ + source:linkNode, + sourcePort:0, + target: target, + link: true + }); + addedLinkLinks[linkNode.id+":"+target.id] = true; + activeLinkNodes[target.id] = target; + target.dirty = true; + + } + } else { + offFlowLinks[target.z] = offFlowLinks[target.z]||[]; + offFlowLinks[target.z].push(target); + } + } else { + if (target.z === linkNode.z) { + if (!addedLinkLinks[target.id+":"+linkNode.id]) { + activeLinks.push({ + source:target, + sourcePort:0, + target: linkNode, + link: true + }); + addedLinkLinks[target.id+":"+linkNode.id] = true; + activeLinkNodes[target.id] = target; + target.dirty = true; + } + } else { + offFlowLinks[target.z] = offFlowLinks[target.z]||[]; + offFlowLinks[target.z].push(target); + } + } + } + }); + var offFlows = Object.keys(offFlowLinks); + // offFlows.sort(function(A,B) { + // return tabOrder.indexOf(A) - tabOrder.indexOf(B); + // }); + if (offFlows.length > 0) { + activeFlowLinks.push({ + refresh: Math.floor(Math.random()*10000), + node: linkNode, + links: offFlowLinks//offFlows.map(function(i) { return {id:i,links:offFlowLinks[i]};}) + }); + } + } + } + if (activeFlowLinks.length === 0 && selected_link !== null && selected_link.link) { + activeLinks.push(selected_link); + activeLinkNodes[selected_link.source.id] = selected_link.source; + selected_link.source.dirty = true; + activeLinkNodes[selected_link.target.id] = selected_link.target; + selected_link.target.dirty = true; + } + } else { + selection.flows = workspaceSelection; + } + var selectionJSON = activeWorkspace+":"+JSON.stringify(selection,function(key,value) { + if (key === 'nodes' || key === 'flows') { + return value.map(function(n) { return n.id }) + } else if (key === 'link') { + return value.source.id+":"+value.sourcePort+":"+value.target.id; + } + return value; + }); + if (selectionJSON !== lastSelection) { + lastSelection = selectionJSON; + RED.events.emit("view:selection-changed",selection); + } + } + + function editSelection() { + if (moving_set.length > 0) { + var node = moving_set[0].n; + if (node.type === "subflow") { + RED.editor.editSubflow(activeSubflow); + } else { + RED.editor.edit(node); + } + } + } + function deleteSelection() { + if (mouse_mode === RED.state.SELECTING_NODE) { + return; + } + if (portLabelHover) { + portLabelHover.remove(); + portLabelHover = null; + } + var workspaceSelection = RED.workspaces.selection(); + if (workspaceSelection.length > 0) { + var workspaceCount = 0; + workspaceSelection.forEach(function(ws) { if (ws.type === 'tab') { workspaceCount++ } }); + if (workspaceCount === RED.workspaces.count()) { + // Cannot delete all workspaces + return; + } + var historyEvent = { + t: 'delete', + dirty: RED.nodes.dirty(), + nodes: [], + links: [], + workspaces: [], + subflows: [] + } + var workspaceOrder = RED.nodes.getWorkspaceOrder().slice(0); + + for (var i=0;i<workspaceSelection.length;i++) { + var ws = workspaceSelection[i]; + ws._index = workspaceOrder.indexOf(ws.id); + RED.workspaces.remove(ws); + var subEvent; + if (ws.type === 'tab') { + historyEvent.workspaces.push(ws); + subEvent = RED.nodes.removeWorkspace(ws.id); + } else { + subEvent = RED.subflow.removeSubflow(ws.id); + historyEvent.subflows = historyEvent.subflows.concat(subEvent.subflows); + } + historyEvent.nodes = historyEvent.nodes.concat(subEvent.nodes); + historyEvent.links = historyEvent.links.concat(subEvent.links); + } + RED.history.push(historyEvent); + RED.nodes.dirty(true); + updateActiveNodes(); + updateSelection(); + redraw(); + } else if (moving_set.length > 0 || selected_link != null) { + var result; + var removedNodes = []; + var removedLinks = []; + var removedSubflowOutputs = []; + var removedSubflowInputs = []; + var removedSubflowStatus; + var subflowInstances = []; + + var startDirty = RED.nodes.dirty(); + var startChanged = false; + if (moving_set.length > 0) { + for (var i=0;i<moving_set.length;i++) { + var node = moving_set[i].n; + node.selected = false; + if (node.type != "subflow") { + if (node.x < 0) { + node.x = 25 + } + var removedEntities = RED.nodes.remove(node.id); + removedNodes.push(node); + removedNodes = removedNodes.concat(removedEntities.nodes); + removedLinks = removedLinks.concat(removedEntities.links); + } else { + if (node.direction === "out") { + removedSubflowOutputs.push(node); + } else if (node.direction === "in") { + removedSubflowInputs.push(node); + } else if (node.direction === "status") { + removedSubflowStatus = node; + } + node.dirty = true; + } + } + if (removedSubflowOutputs.length > 0) { + result = RED.subflow.removeOutput(removedSubflowOutputs); + if (result) { + removedLinks = removedLinks.concat(result.links); + } + } + // Assume 0/1 inputs + if (removedSubflowInputs.length == 1) { + result = RED.subflow.removeInput(); + if (result) { + removedLinks = removedLinks.concat(result.links); + } + } + if (removedSubflowStatus) { + result = RED.subflow.removeStatus(); + if (result) { + removedLinks = removedLinks.concat(result.links); + } + } + + var instances = RED.subflow.refresh(true); + if (instances) { + subflowInstances = instances.instances; + } + moving_set = []; + if (removedNodes.length > 0 || removedSubflowOutputs.length > 0 || removedSubflowInputs.length > 0 || removedSubflowStatus) { + RED.nodes.dirty(true); + } + } + var historyEvent; + + if (selected_link && selected_link.link) { + var sourceId = selected_link.source.id; + var targetId = selected_link.target.id; + var sourceIdIndex = selected_link.target.links.indexOf(sourceId); + var targetIdIndex = selected_link.source.links.indexOf(targetId); + + historyEvent = { + t:"multi", + events: [ + { + t: "edit", + node: selected_link.source, + changed: selected_link.source.changed, + changes: { + links: $.extend(true,{},{v:selected_link.source.links}).v + } + }, + { + t: "edit", + node: selected_link.target, + changed: selected_link.target.changed, + changes: { + links: $.extend(true,{},{v:selected_link.target.links}).v + } + } + + ], + dirty:RED.nodes.dirty() + } + RED.nodes.dirty(true); + selected_link.source.changed = true; + selected_link.target.changed = true; + selected_link.target.links.splice(sourceIdIndex,1); + selected_link.source.links.splice(targetIdIndex,1); + selected_link.source.dirty = true; + selected_link.target.dirty = true; + + } else { + if (selected_link) { + RED.nodes.removeLink(selected_link); + removedLinks.push(selected_link); + } + RED.nodes.dirty(true); + historyEvent = { + t:"delete", + nodes:removedNodes, + links:removedLinks, + subflowOutputs:removedSubflowOutputs, + subflowInputs:removedSubflowInputs, + subflow: { + id: activeSubflow?activeSubflow.id:undefined, + instances: subflowInstances + }, + dirty:startDirty + }; + if (removedSubflowStatus) { + historyEvent.subflow.status = removedSubflowStatus; + } + } + RED.history.push(historyEvent); + + selected_link = null; + updateActiveNodes(); + updateSelection(); + redraw(); + } + } + + function copySelection() { + if (mouse_mode === RED.state.SELECTING_NODE) { + return; + } + var nodes = []; + var selection = RED.workspaces.selection(); + if (selection.length > 0) { + nodes = []; + selection.forEach(function(n) { + if (n.type === 'tab') { + nodes.push(n); + nodes = nodes.concat(RED.nodes.filterNodes({z:n.id})); + } + }); + } else if (moving_set.length > 0) { + nodes = moving_set.map(function(n) { return n.n }); + } + + if (nodes.length > 0) { + var nns = []; + for (var n=0;n<nodes.length;n++) { + var node = nodes[n]; + // The only time a node.type == subflow can be selected is the + // input/output "proxy" nodes. They cannot be copied. + if (node.type != "subflow") { + for (var d in node._def.defaults) { + if (node._def.defaults.hasOwnProperty(d)) { + if (node._def.defaults[d].type) { + var configNode = RED.nodes.node(node[d]); + if (configNode && configNode._def.exclusive) { + nns.push(RED.nodes.convertNode(configNode)); + } + } + } + } + nns.push(RED.nodes.convertNode(node)); + //TODO: if the node has an exclusive config node, it should also be copied, to ensure it remains exclusive... + } + } + clipboard = JSON.stringify(nns); + RED.notify(RED._("clipboard.nodeCopied",{count:nns.length}),{id:"clipboard"}); + } + } + + function calculateTextWidth(str, className, offset) { + return calculateTextDimensions(str,className,offset,0)[0]; + } + + var textDimensionPlaceholder = {}; + function calculateTextDimensions(str,className,offsetW,offsetH) { + if (!textDimensionPlaceholder[className]) { + textDimensionPlaceholder[className] = document.createElement("span"); + textDimensionPlaceholder[className].className = className; + textDimensionPlaceholder[className].style.position = "absolute"; + textDimensionPlaceholder[className].style.top = "-1000px"; + document.getElementById("red-ui-editor").appendChild(textDimensionPlaceholder[className]); + } + textDimensionPlaceholder[className].textContent = (str||""); + var w = textDimensionPlaceholder[className].offsetWidth; + var h = textDimensionPlaceholder[className].offsetHeight; + return [offsetW+w,offsetH+h]; + } + + function resetMouseVars() { + mousedown_node = null; + mouseup_node = null; + mousedown_link = null; + mouse_mode = 0; + mousedown_port_type = null; + activeSpliceLink = null; + spliceActive = false; + d3.select(".red-ui-flow-link-splice").classed("red-ui-flow-link-splice",false); + if (spliceTimer) { + clearTimeout(spliceTimer); + spliceTimer = null; + } + } + + function disableQuickJoinEventHandler(evt) { + // Check for ctrl (all browsers), "Meta" (Chrome/FF), keyCode 91 (Safari) + if (evt.keyCode === 17 || evt.key === "Meta" || evt.keyCode === 91) { + resetMouseVars(); + hideDragLines(); + redraw(); + $(window).off('keyup',disableQuickJoinEventHandler); + } + } + + function portMouseDown(d,portType,portIndex) { + //console.log(d,portType,portIndex); + // disable zoom + //eventLayer.call(d3.behavior.zoom().on("zoom"), null); + if (d3.event.button === 1) { + return; + } + if (mouse_mode === RED.state.SELECTING_NODE) { + d3.event.stopPropagation(); + return; + } + mousedown_node = d; + mousedown_port_type = portType; + mousedown_port_index = portIndex || 0; + if (mouse_mode !== RED.state.QUICK_JOINING) { + mouse_mode = RED.state.JOINING; + document.body.style.cursor = "crosshair"; + if (d3.event.ctrlKey || d3.event.metaKey) { + mouse_mode = RED.state.QUICK_JOINING; + showDragLines([{node:mousedown_node,port:mousedown_port_index,portType:mousedown_port_type}]); + $(window).on('keyup',disableQuickJoinEventHandler); + } + } + d3.event.stopPropagation(); + d3.event.preventDefault(); + } + + function portMouseUp(d,portType,portIndex) { + if (mouse_mode === RED.state.SELECTING_NODE) { + d3.event.stopPropagation(); + return; + } + var i; + if (mouse_mode === RED.state.QUICK_JOINING && drag_lines.length > 0) { + if (drag_lines[0].node === d) { + // Cannot quick-join to self + return + } + if (drag_lines[0].virtualLink && + ( + (drag_lines[0].node.type === 'link in' && d.type !== 'link out') || + (drag_lines[0].node.type === 'link out' && d.type !== 'link in') + ) + ) { + return + } + } + document.body.style.cursor = ""; + if (mouse_mode == RED.state.JOINING || mouse_mode == RED.state.QUICK_JOINING) { + if (typeof TouchEvent != "undefined" && d3.event instanceof TouchEvent) { + RED.nodes.eachNode(function(n) { + if (n.z == RED.workspaces.active()) { + var hw = n.w/2; + var hh = n.h/2; + if (n.x-hw<mouse_position[0] && n.x+hw> mouse_position[0] && + n.y-hh<mouse_position[1] && n.y+hh>mouse_position[1]) { + mouseup_node = n; + portType = mouseup_node.inputs>0?PORT_TYPE_INPUT:PORT_TYPE_OUTPUT; + portIndex = 0; + } + } + }); + } else { + mouseup_node = d; + } + var addedLinks = []; + var removedLinks = []; + var modifiedNodes = []; // joining link nodes + + var select_link = null; + + for (i=0;i<drag_lines.length;i++) { + if (drag_lines[i].link) { + removedLinks.push(drag_lines[i].link) + } + } + var linkEditEvents = []; + + for (i=0;i<drag_lines.length;i++) { + if (portType != drag_lines[i].portType && mouseup_node !== drag_lines[i].node) { + var drag_line = drag_lines[i]; + var src,dst,src_port; + if (drag_line.portType === PORT_TYPE_OUTPUT) { + src = drag_line.node; + src_port = drag_line.port; + dst = mouseup_node; + } else if (drag_line.portType === PORT_TYPE_INPUT) { + src = mouseup_node; + dst = drag_line.node; + src_port = portIndex; + } + var link = {source: src, sourcePort:src_port, target: dst}; + if (drag_line.virtualLink) { + if (/^link (in|out)$/.test(src.type) && /^link (in|out)$/.test(dst.type) && src.type !== dst.type) { + if (src.links.indexOf(dst.id) === -1 && dst.links.indexOf(src.id) === -1) { + var oldSrcLinks = $.extend(true,{},{v:src.links}).v + var oldDstLinks = $.extend(true,{},{v:dst.links}).v + src.links.push(dst.id); + dst.links.push(src.id); + src.dirty = true; + dst.dirty = true; + modifiedNodes.push(src); + modifiedNodes.push(dst); + + link.link = true; + activeLinks.push(link); + activeLinkNodes[src.id] = src; + activeLinkNodes[dst.id] = dst; + select_link = link; + + linkEditEvents.push({ + t:'edit', + node: src, + dirty: RED.nodes.dirty(), + changed: src.changed, + changes: { + links:oldSrcLinks + } + }); + linkEditEvents.push({ + t:'edit', + node: dst, + dirty: RED.nodes.dirty(), + changed: dst.changed, + changes: { + links:oldDstLinks + } + }); + src.changed = true; + dst.changed = true; + } + } + } else { + // This is not a virtualLink - which means it started + // on a regular node port. Need to ensure the this isn't + // connecting to a link node virual port. + if (!( + (d.type === "link out" && portType === PORT_TYPE_OUTPUT) || + (d.type === "link in" && portType === PORT_TYPE_INPUT) + )) { + var existingLink = RED.nodes.filterLinks({source:src,target:dst,sourcePort: src_port}).length !== 0; + if (!existingLink) { + RED.nodes.addLink(link); + addedLinks.push(link); + } + } + } + } + } + if (addedLinks.length > 0 || removedLinks.length > 0 || modifiedNodes.length > 0) { + // console.log(addedLinks); + // console.log(removedLinks); + // console.log(modifiedNodes); + var historyEvent; + if (modifiedNodes.length > 0) { + historyEvent = { + t:"multi", + events: linkEditEvents, + dirty:RED.nodes.dirty() + }; + } else { + historyEvent = { + t:"add", + links:addedLinks, + removedLinks: removedLinks, + dirty:RED.nodes.dirty() + }; + } + if (activeSubflow) { + var subflowRefresh = RED.subflow.refresh(true); + if (subflowRefresh) { + historyEvent.subflow = { + id:activeSubflow.id, + changed: activeSubflow.changed, + instances: subflowRefresh.instances + } + } + } + RED.history.push(historyEvent); + updateActiveNodes(); + RED.nodes.dirty(true); + } + if (mouse_mode === RED.state.QUICK_JOINING) { + if (addedLinks.length > 0 || modifiedNodes.length > 0) { + hideDragLines(); + if (portType === PORT_TYPE_INPUT && d.outputs > 0) { + showDragLines([{node:d,port:0,portType:PORT_TYPE_OUTPUT}]); + } else if (portType === PORT_TYPE_OUTPUT && d.inputs > 0) { + showDragLines([{node:d,port:0,portType:PORT_TYPE_INPUT}]); + } else { + resetMouseVars(); + } + selected_link = select_link; + mousedown_link = select_link; + if (select_link) { + updateSelection(); + } + } + redraw(); + return; + } + + resetMouseVars(); + hideDragLines(); + selected_link = select_link; + mousedown_link = select_link; + if (select_link) { + updateSelection(); + } + redraw(); + } + } + + var portLabelHoverTimeout = null; + var portLabelHover = null; + + + function getElementPosition(node) { + var d3Node = d3.select(node); + if (d3Node.attr('class') === 'red-ui-workspace-chart-event-layer') { + return [0,0]; + } + var result = []; + var localPos = [0,0]; + if (node.nodeName.toLowerCase() === 'g') { + var transform = d3Node.attr("transform"); + if (transform) { + localPos = d3.transform(transform).translate; + } + } else { + localPos = [d3Node.attr("x")||0,d3Node.attr("y")||0]; + } + var parentPos = getElementPosition(node.parentNode); + return [localPos[0]+parentPos[0],localPos[1]+parentPos[1]] + + } + + function getPortLabel(node,portType,portIndex) { + var result; + var nodePortLabels = (portType === PORT_TYPE_INPUT)?node.inputLabels:node.outputLabels; + if (nodePortLabels && nodePortLabels[portIndex]) { + return nodePortLabels[portIndex]; + } + var portLabels = (portType === PORT_TYPE_INPUT)?node._def.inputLabels:node._def.outputLabels; + if (typeof portLabels === 'string') { + result = portLabels; + } else if (typeof portLabels === 'function') { + try { + result = portLabels.call(node,portIndex); + } catch(err) { + console.log("Definition error: "+node.type+"."+((portType === PORT_TYPE_INPUT)?"inputLabels":"outputLabels"),err); + result = null; + } + } else if ($.isArray(portLabels)) { + result = portLabels[portIndex]; + } + return result; + } + function showTooltip(x,y,content,direction) { + var tooltip = eventLayer.append("g") + .attr("transform","translate("+x+","+y+")") + .attr("class","red-ui-flow-port-tooltip"); + + var lines = content.split("\n"); + var labelWidth = 6; + var labelHeight = 12; + var labelHeights = []; + var lineHeight = 0; + lines.forEach(function(l,i) { + var labelDimensions = calculateTextDimensions(l||"&nbsp;", "red-ui-flow-port-tooltip-label", 8,0); + labelWidth = Math.max(labelWidth,labelDimensions[0] + 6); + labelHeights.push(labelDimensions[1]); + if (i === 0) { + lineHeight = labelDimensions[1]; + } + labelHeight += labelDimensions[1]; + }); + var labelWidth1 = (labelWidth/2)-5-2; + var labelWidth2 = labelWidth - 4; + + var labelHeight1 = (labelHeight/2)-5-2; + var labelHeight2 = labelHeight - 4; + var path; + var lx; + var ly = -labelHeight/2; + var anchor; + if (direction === "left") { + path = "M0 0 l -5 -5 v -"+(labelHeight1)+" q 0 -2 -2 -2 h -"+labelWidth+" q -2 0 -2 2 v "+(labelHeight2)+" q 0 2 2 2 h "+labelWidth+" q 2 0 2 -2 v -"+(labelHeight1)+" l 5 -5"; + lx = -14; + anchor = "end"; + } else if (direction === "right") { + path = "M0 0 l 5 -5 v -"+(labelHeight1)+" q 0 -2 2 -2 h "+labelWidth+" q 2 0 2 2 v "+(labelHeight2)+" q 0 2 -2 2 h -"+labelWidth+" q -2 0 -2 -2 v -"+(labelHeight1)+" l -5 -5" + lx = 14; + anchor = "start"; + } else if (direction === "top") { + path = "M0 0 l 5 -5 h "+(labelWidth1)+" q 2 0 2 -2 v -"+labelHeight+" q 0 -2 -2 -2 h -"+(labelWidth2)+" q -2 0 -2 2 v "+labelHeight+" q 0 2 2 2 h "+(labelWidth1)+" l 5 5" + lx = -labelWidth/2 + 6; + ly = -labelHeight-lineHeight+12; + anchor = "start"; + } + tooltip.append("path").attr("d",path); + lines.forEach(function(l,i) { + ly += labelHeights[i]; + // tooltip.append("path").attr("d","M "+(lx-10)+" "+ly+" l 20 0 m -10 -5 l 0 10 ").attr('r',2).attr("stroke","#f00").attr("stroke-width","1").attr("fill","none") + tooltip.append("svg:text").attr("class","red-ui-flow-port-tooltip-label") + .attr("x", lx) + .attr("y", ly) + .attr("text-anchor",anchor) + .text(l||" ") + }); + return tooltip; + } + + function portMouseOver(port,d,portType,portIndex) { + if (mouse_mode === RED.state.SELECTING_NODE) { + d3.event.stopPropagation(); + return; + } + clearTimeout(portLabelHoverTimeout); + var active = (mouse_mode!=RED.state.JOINING && mouse_mode != RED.state.QUICK_JOINING) || // Not currently joining - all ports active + ( + drag_lines.length > 0 && // Currently joining + drag_lines[0].portType !== portType && // INPUT->OUTPUT OUTPUT->INPUT + ( + !drag_lines[0].virtualLink || // Not a link wire + (drag_lines[0].node.type === 'link in' && d.type === 'link out') || + (drag_lines[0].node.type === 'link out' && d.type === 'link in') + ) + ) + + if (active && ((portType === PORT_TYPE_INPUT && ((d._def && d._def.inputLabels)||d.inputLabels)) || (portType === PORT_TYPE_OUTPUT && ((d._def && d._def.outputLabels)||d.outputLabels)))) { + portLabelHoverTimeout = setTimeout(function() { + var tooltip = getPortLabel(d,portType,portIndex); + if (!tooltip) { + return; + } + var pos = getElementPosition(port.node()); + portLabelHoverTimeout = null; + portLabelHover = showTooltip( + (pos[0]+(portType===PORT_TYPE_INPUT?-2:12)), + (pos[1]+5), + tooltip, + portType===PORT_TYPE_INPUT?"left":"right" + ); + },500); + } + port.classed("red-ui-flow-port-hovered",active); + } + function portMouseOut(port,d,portType,portIndex) { + if (mouse_mode === RED.state.SELECTING_NODE) { + d3.event.stopPropagation(); + return; + } + clearTimeout(portLabelHoverTimeout); + if (portLabelHover) { + portLabelHover.remove(); + portLabelHover = null; + } + port.classed("red-ui-flow-port-hovered",false); + } + + function nodeMouseUp(d) { + if (mouse_mode === RED.state.SELECTING_NODE) { + d3.event.stopPropagation(); + return; + } + if (dblClickPrimed && mousedown_node == d && clickElapsed > 0 && clickElapsed < 750) { + mouse_mode = RED.state.DEFAULT; + if (d.type != "subflow") { + RED.editor.edit(d); + } else { + RED.editor.editSubflow(activeSubflow); + } + clickElapsed = 0; + d3.event.stopPropagation(); + return; + } + var direction = d._def? (d.inputs > 0 ? 1: 0) : (d.direction == "in" ? 0: 1) + var wasJoining = false; + if (mouse_mode === RED.state.JOINING || mouse_mode === RED.state.QUICK_JOINING) { + wasJoining = true; + if (drag_lines.length > 0) { + if (drag_lines[0].virtualLink) { + if (d.type === 'link in') { + direction = 1; + } else if (d.type === 'link out') { + direction = 0; + } + } + } + } + + portMouseUp(d, direction, 0); + if (wasJoining) { + d3.selectAll(".red-ui-flow-port-hovered").classed("red-ui-flow-port-hovered",false); + } + } + + function nodeMouseDown(d) { + focusView(); + if (d3.event.button === 1) { + return; + } + //var touch0 = d3.event; + //var pos = [touch0.pageX,touch0.pageY]; + //RED.touch.radialMenu.show(d3.select(this),pos); + if (mouse_mode == RED.state.IMPORT_DRAGGING) { + RED.keyboard.remove("escape"); + + if (activeSpliceLink) { + // TODO: DRY - droppable/nodeMouseDown/canvasMouseUp + var spliceLink = d3.select(activeSpliceLink).data()[0]; + RED.nodes.removeLink(spliceLink); + var link1 = { + source:spliceLink.source, + sourcePort:spliceLink.sourcePort, + target: moving_set[0].n + }; + var link2 = { + source:moving_set[0].n, + sourcePort:0, + target: spliceLink.target + }; + RED.nodes.addLink(link1); + RED.nodes.addLink(link2); + var historyEvent = RED.history.peek(); + historyEvent.links = [link1,link2]; + historyEvent.removedLinks = [spliceLink]; + updateActiveNodes(); + } + + updateSelection(); + RED.nodes.dirty(true); + redraw(); + resetMouseVars(); + d3.event.stopPropagation(); + return; + } else if (mouse_mode == RED.state.QUICK_JOINING) { + d3.event.stopPropagation(); + return; + } else if (mouse_mode === RED.state.SELECTING_NODE) { + d3.event.stopPropagation(); + if (selectNodesOptions.single) { + selectNodesOptions.done(d); + return; + } + if (d.selected) { + d.selected = false; + for (i=0;i<moving_set.length;i+=1) { + if (moving_set[i].n === d) { + moving_set.splice(i,1); + break; + } + } + } else { + if (!selectNodesOptions.filter || selectNodesOptions.filter(d)) { + d.selected = true; + moving_set.push({n:d}); + } + } + d.dirty = true; + redraw(); + // if (selectNodesOptions && selectNodesOptions.onselect) { + // selectNodesOptions.onselect(moving_set.map(function(n) { return n.n;})) + // } + return; + } + mousedown_node = d; + var now = Date.now(); + clickElapsed = now-clickTime; + clickTime = now; + + dblClickPrimed = (lastClickNode == mousedown_node && + d3.event.button === 0 && + !d3.event.shiftKey && !d3.event.metaKey && !d3.event.altKey && !d3.event.ctrlKey); + lastClickNode = mousedown_node; + + var i; + + if (d.selected && (d3.event.ctrlKey||d3.event.metaKey)) { + mousedown_node.selected = false; + for (i=0;i<moving_set.length;i+=1) { + if (moving_set[i].n === mousedown_node) { + moving_set.splice(i,1); + break; + } + } + } else { + if (d3.event.shiftKey) { + clearSelection(); + var cnodes = RED.nodes.getAllFlowNodes(mousedown_node); + for (var n=0;n<cnodes.length;n++) { + cnodes[n].selected = true; + cnodes[n].dirty = true; + moving_set.push({n:cnodes[n]}); + } + } else if (!d.selected) { + if (!d3.event.ctrlKey && !d3.event.metaKey) { + clearSelection(); + } + mousedown_node.selected = true; + moving_set.push({n:mousedown_node}); + } + selected_link = null; + if (d3.event.button != 2) { + mouse_mode = RED.state.MOVING; + var mouse = d3.touches(this)[0]||d3.mouse(this); + mouse[0] += d.x-d.w/2; + mouse[1] += d.y-d.h/2; + for (i=0;i<moving_set.length;i++) { + moving_set[i].ox = moving_set[i].n.x; + moving_set[i].oy = moving_set[i].n.y; + moving_set[i].dx = moving_set[i].n.x-mouse[0]; + moving_set[i].dy = moving_set[i].n.y-mouse[1]; + } + mouse_offset = d3.mouse(document.body); + if (isNaN(mouse_offset[0])) { + mouse_offset = d3.touches(document.body)[0]; + } + } + } + d.dirty = true; + updateSelection(); + redraw(); + d3.event.stopPropagation(); + } + + function isButtonEnabled(d) { + var buttonEnabled = true; + var ws = RED.nodes.workspace(RED.workspaces.active()); + if (ws && !ws.disabled && !d.d) { + if (d._def.button.hasOwnProperty('enabled')) { + if (typeof d._def.button.enabled === "function") { + buttonEnabled = d._def.button.enabled.call(d); + } else { + buttonEnabled = d._def.button.enabled; + } + } + } else { + buttonEnabled = false; + } + return buttonEnabled; + } + + function nodeButtonClicked(d) { + if (mouse_mode === RED.state.SELECTING_NODE) { + d3.event.stopPropagation(); + return; + } + var activeWorkspace = RED.workspaces.active(); + var ws = RED.nodes.workspace(activeWorkspace); + if (ws && !ws.disabled && !d.d) { + if (d._def.button.toggle) { + d[d._def.button.toggle] = !d[d._def.button.toggle]; + d.dirty = true; + } + if (d._def.button.onclick) { + try { + d._def.button.onclick.call(d); + } catch(err) { + console.log("Definition error: "+d.type+".onclick",err); + } + } + if (d.dirty) { + redraw(); + } + } else { + if (activeSubflow) { + RED.notify(RED._("notification.warning", {message:RED._("notification.warnings.nodeActionDisabledSubflow")}),"warning"); + } else { + RED.notify(RED._("notification.warning", {message:RED._("notification.warnings.nodeActionDisabled")}),"warning"); + } + } + d3.event.preventDefault(); + } + + function showTouchMenu(obj,pos) { + var mdn = mousedown_node; + var options = []; + options.push({name:"delete",disabled:(moving_set.length===0 && selected_link === null),onselect:function() {deleteSelection();}}); + options.push({name:"cut",disabled:(moving_set.length===0),onselect:function() {copySelection();deleteSelection();}}); + options.push({name:"copy",disabled:(moving_set.length===0),onselect:function() {copySelection();}}); + options.push({name:"paste",disabled:(clipboard.length===0),onselect:function() {importNodes(clipboard,false,true);}}); + options.push({name:"edit",disabled:(moving_set.length != 1),onselect:function() { RED.editor.edit(mdn);}}); + options.push({name:"select",onselect:function() {selectAll();}}); + options.push({name:"undo",disabled:(RED.history.depth() === 0),onselect:function() {RED.history.pop();}}); + + RED.touch.radialMenu.show(obj,pos,options); + resetMouseVars(); + } + + function createIconAttributes(iconUrl, icon_group, d) { + var fontAwesomeUnicode = null; + if (iconUrl.indexOf("font-awesome/") === 0) { + var iconName = iconUrl.substr(13); + var fontAwesomeUnicode = RED.nodes.fontAwesome.getIconUnicode(iconName); + if (!fontAwesomeUnicode) { + var iconPath = RED.utils.getDefaultNodeIcon(d._def, d); + iconUrl = RED.settings.apiRootUrl+"icons/"+iconPath.module+"/"+iconPath.file; + } + } + if (fontAwesomeUnicode) { + // Since Node-RED workspace uses SVG, i tag cannot be used for font-awesome icon. + // On SVG, use text tag as an alternative. + icon_group.append("text") + .attr("xlink:href",iconUrl) + .attr("class","fa-lg") + .attr("x",15) + .text(fontAwesomeUnicode); + } else { + var icon = icon_group.append("image") + .attr("xlink:href",iconUrl) + .attr("class","red-ui-flow-node-icon") + .attr("x",0) + .attr("width","30") + .attr("height","30") + .style("display","none"); + + var img = new Image(); + img.src = iconUrl; + img.onload = function() { + if (!iconUrl.match(/\.svg$/)) { + var largestEdge = Math.max(img.width,img.height); + var scaleFactor = 1; + if (largestEdge > 30) { + scaleFactor = 30/largestEdge; + } + var width = img.width * scaleFactor; + var height = img.height * scaleFactor; + icon.attr("width",width); + icon.attr("height",height); + icon.attr("x",15-width/2); + } + icon.attr("xlink:href",iconUrl); + icon.style("display",null); + //if ("right" == d._def.align) { + // icon.attr("x",function(d){return d.w-img.width-1-(d.outputs>0?5:0);}); + // icon_shade.attr("x",function(d){return d.w-30}); + // icon_shade_border.attr("d",function(d){return "M "+(d.w-30)+" 1 l 0 "+(d.h-2);}); + //} + } + } + } + + function redraw() { + eventLayer.attr("transform","scale("+scaleFactor+")"); + outer.attr("width", space_width*scaleFactor).attr("height", space_height*scaleFactor); + + // Don't bother redrawing nodes if we're drawing links + if (showAllLinkPorts !== -1 || mouse_mode != RED.state.JOINING) { + + var dirtyNodes = {}; + + if (activeSubflow) { + var subflowOutputs = nodeLayer.selectAll(".red-ui-flow-subflow-port-output").data(activeSubflow.out,function(d,i){ return d.id;}); + subflowOutputs.exit().remove(); + var outGroup = subflowOutputs.enter().insert("svg:g").attr("class","red-ui-flow-node red-ui-flow-subflow-port-output").attr("transform",function(d) { return "translate("+(d.x-20)+","+(d.y-20)+")"}); + outGroup.each(function(d,i) { + d.w=40; + d.h=40; + }); + outGroup.append("rect").attr("class","red-ui-flow-subflow-port").attr("rx",8).attr("ry",8).attr("width",40).attr("height",40) + // TODO: This is exactly the same set of handlers used for regular nodes - DRY + .on("mouseup",nodeMouseUp) + .on("mousedown",nodeMouseDown) + .on("touchstart",function(d) { + var obj = d3.select(this); + var touch0 = d3.event.touches.item(0); + var pos = [touch0.pageX,touch0.pageY]; + startTouchCenter = [touch0.pageX,touch0.pageY]; + startTouchDistance = 0; + touchStartTime = setTimeout(function() { + showTouchMenu(obj,pos); + },touchLongPressTimeout); + nodeMouseDown.call(this,d) + }) + .on("touchend", function(d) { + clearTimeout(touchStartTime); + touchStartTime = null; + if (RED.touch.radialMenu.active()) { + d3.event.stopPropagation(); + return; + } + nodeMouseUp.call(this,d); + }); + + outGroup.append("g").attr('transform','translate(-5,15)').append("rect").attr("class","red-ui-flow-port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10) + .on("mousedown", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);} ) + .on("touchstart", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);} ) + .on("mouseup", function(d,i){portMouseUp(d,PORT_TYPE_INPUT,0);}) + .on("touchend",function(d,i){portMouseUp(d,PORT_TYPE_INPUT,0);} ) + .on("mouseover",function(d){portMouseOver(d3.select(this),d,PORT_TYPE_INPUT,0);}) + .on("mouseout",function(d){portMouseOut(d3.select(this),d,PORT_TYPE_INPUT,0);}); + + outGroup.append("svg:text").attr("class","red-ui-flow-port-label").attr("x",20).attr("y",12).style("font-size","10px").text("output"); + outGroup.append("svg:text").attr("class","red-ui-flow-port-label red-ui-flow-port-index").attr("x",20).attr("y",28).text(function(d,i){ return i+1}); + + var subflowInputs = nodeLayer.selectAll(".red-ui-flow-subflow-port-input").data(activeSubflow.in,function(d,i){ return d.id;}); + subflowInputs.exit().remove(); + var inGroup = subflowInputs.enter().insert("svg:g").attr("class","red-ui-flow-node red-ui-flow-subflow-port-input").attr("transform",function(d) { return "translate("+(d.x-20)+","+(d.y-20)+")"}); + inGroup.each(function(d,i) { + d.w=40; + d.h=40; + }); + inGroup.append("rect").attr("class","red-ui-flow-subflow-port").attr("rx",8).attr("ry",8).attr("width",40).attr("height",40) + // TODO: This is exactly the same set of handlers used for regular nodes - DRY + .on("mouseup",nodeMouseUp) + .on("mousedown",nodeMouseDown) + .on("touchstart",function(d) { + var obj = d3.select(this); + var touch0 = d3.event.touches.item(0); + var pos = [touch0.pageX,touch0.pageY]; + startTouchCenter = [touch0.pageX,touch0.pageY]; + startTouchDistance = 0; + touchStartTime = setTimeout(function() { + showTouchMenu(obj,pos); + },touchLongPressTimeout); + nodeMouseDown.call(this,d) + }) + .on("touchend", function(d) { + clearTimeout(touchStartTime); + touchStartTime = null; + if (RED.touch.radialMenu.active()) { + d3.event.stopPropagation(); + return; + } + nodeMouseUp.call(this,d); + }); + + inGroup.append("g").attr('transform','translate(35,15)').append("rect").attr("class","red-ui-flow-port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10) + .on("mousedown", function(d,i){portMouseDown(d,PORT_TYPE_OUTPUT,i);} ) + .on("touchstart", function(d,i){portMouseDown(d,PORT_TYPE_OUTPUT,i);} ) + .on("mouseup", function(d,i){portMouseUp(d,PORT_TYPE_OUTPUT,i);}) + .on("touchend",function(d,i){portMouseUp(d,PORT_TYPE_OUTPUT,i);} ) + .on("mouseover",function(d){portMouseOver(d3.select(this),d,PORT_TYPE_OUTPUT,0);}) + .on("mouseout",function(d) {portMouseOut(d3.select(this),d,PORT_TYPE_OUTPUT,0);}); + + inGroup.append("svg:text").attr("class","red-ui-flow-port-label").attr("x",18).attr("y",20).style("font-size","10px").text("input"); + + var subflowStatus = nodeLayer.selectAll(".red-ui-flow-subflow-port-status").data(activeSubflow.status?[activeSubflow.status]:[],function(d,i){ return d.id;}); + subflowStatus.exit().remove(); + + var statusGroup = subflowStatus.enter().insert("svg:g").attr("class","red-ui-flow-node red-ui-flow-subflow-port-status").attr("transform",function(d) { return "translate("+(d.x-20)+","+(d.y-20)+")"}); + statusGroup.each(function(d,i) { + d.w=40; + d.h=40; + }); + statusGroup.append("rect").attr("class","red-ui-flow-subflow-port").attr("rx",8).attr("ry",8).attr("width",40).attr("height",40) + // TODO: This is exactly the same set of handlers used for regular nodes - DRY + .on("mouseup",nodeMouseUp) + .on("mousedown",nodeMouseDown) + .on("touchstart",function(d) { + var obj = d3.select(this); + var touch0 = d3.event.touches.item(0); + var pos = [touch0.pageX,touch0.pageY]; + startTouchCenter = [touch0.pageX,touch0.pageY]; + startTouchDistance = 0; + touchStartTime = setTimeout(function() { + showTouchMenu(obj,pos); + },touchLongPressTimeout); + nodeMouseDown.call(this,d) + }) + .on("touchend", function(d) { + clearTimeout(touchStartTime); + touchStartTime = null; + if (RED.touch.radialMenu.active()) { + d3.event.stopPropagation(); + return; + } + nodeMouseUp.call(this,d); + }); + + statusGroup.append("g").attr('transform','translate(-5,15)').append("rect").attr("class","red-ui-flow-port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10) + .on("mousedown", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);} ) + .on("touchstart", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);} ) + .on("mouseup", function(d,i){portMouseUp(d,PORT_TYPE_INPUT,0);}) + .on("touchend",function(d,i){portMouseUp(d,PORT_TYPE_INPUT,0);} ) + .on("mouseover",function(d){portMouseOver(d3.select(this),d,PORT_TYPE_INPUT,0);}) + .on("mouseout",function(d){portMouseOut(d3.select(this),d,PORT_TYPE_INPUT,0);}); + + statusGroup.append("svg:text").attr("class","red-ui-flow-port-label").attr("x",22).attr("y",20).style("font-size","10px").text("status"); + + subflowOutputs.each(function(d,i) { + if (d.dirty) { + var output = d3.select(this); + output.classed("red-ui-flow-node-selected",function(d) { return d.selected; }) + output.selectAll(".red-ui-flow-port-index").text(function(d){ return d.i+1}); + output.attr("transform", function(d) { return "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")"; }); + dirtyNodes[d.id] = d; + d.dirty = false; + } + }); + subflowInputs.each(function(d,i) { + if (d.dirty) { + var input = d3.select(this); + input.classed("red-ui-flow-node-selected",function(d) { return d.selected; }) + input.attr("transform", function(d) { return "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")"; }); + dirtyNodes[d.id] = d; + d.dirty = false; + } + }); + subflowStatus.each(function(d,i) { + if (d.dirty) { + var output = d3.select(this); + output.classed("red-ui-flow-node-selected",function(d) { return d.selected; }) + output.selectAll(".red-ui-flow-port-index").text(function(d){ return d.i+1}); + output.attr("transform", function(d) { return "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")"; }); + dirtyNodes[d.id] = d; + d.dirty = false; + } + }); + + + } else { + nodeLayer.selectAll(".red-ui-flow-subflow-port-output").remove(); + nodeLayer.selectAll(".red-ui-flow-subflow-port-input").remove(); + nodeLayer.selectAll(".red-ui-flow-subflow-port-status").remove(); + } + + var node = nodeLayer.selectAll(".red-ui-flow-node-group").data(activeNodes,function(d){return d.id}); + node.exit().remove(); + + var nodeEnter = node.enter().insert("svg:g") + .attr("class", "red-ui-flow-node red-ui-flow-node-group") + .classed("red-ui-flow-subflow",function(d) { return activeSubflow != null; }); + + nodeEnter.each(function(d,i) { + var node = d3.select(this); + var isLink = (d.type === "link in" || d.type === "link out") + var hideLabel = d.hasOwnProperty('l')?!d.l : isLink; + node.attr("id",d.id); + var l = RED.utils.getNodeLabel(d); + if (d.resize || d.w === undefined) { + if (hideLabel) { + d.w = node_height; + } else { + d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "red-ui-flow-node-label", 50)+(d._def.inputs>0?7:0))/20)) ); + } + } + d.h = Math.max(node_height,(d.outputs||0) * 15); + + // if (d._def.badge) { + // var badge = node.append("svg:g").attr("class","node_badge_group"); + // var badgeRect = badge.append("rect").attr("class","node_badge").attr("rx",5).attr("ry",5).attr("width",40).attr("height",15); + // badge.append("svg:text").attr("class","node_badge_label").attr("x",35).attr("y",11).attr("text-anchor","end").text(d._def.badge()); + // if (d._def.onbadgeclick) { + // badgeRect.attr("cursor","pointer") + // .on("click",function(d) { d._def.onbadgeclick.call(d);d3.event.preventDefault();}); + // } + // } + + if (d._def.button) { + var nodeButtonGroup = node.append("svg:g") + .attr("transform",function(d) { return "translate("+((d._def.align == "right") ? 94 : -25)+",2)"; }) + .attr("class","red-ui-flow-node-button"); + nodeButtonGroup.append("rect") + .attr("class","red-ui-flow-node-button-background") + .attr("rx",5) + .attr("ry",5) + .attr("width",32) + .attr("height",node_height-4); + nodeButtonGroup.append("rect") + .attr("class","red-ui-flow-node-button-button") + .attr("x",function(d) { return d._def.align == "right"? 11:5}) + .attr("y",4) + .attr("rx",4) + .attr("ry",4) + .attr("width",16) + .attr("height",node_height-12) + .attr("fill",function(d) { return RED.utils.getNodeColor(d.type,d._def); /*d._def.color;*/}) + .attr("cursor","pointer") + .on("mousedown",function(d) {if (!lasso && isButtonEnabled(d)) {focusView();d3.select(this).attr("fill-opacity",0.2);d3.event.preventDefault(); d3.event.stopPropagation();}}) + .on("mouseup",function(d) {if (!lasso && isButtonEnabled(d)) { d3.select(this).attr("fill-opacity",0.4);d3.event.preventDefault();d3.event.stopPropagation();}}) + .on("mouseover",function(d) {if (!lasso && isButtonEnabled(d)) { d3.select(this).attr("fill-opacity",0.4);}}) + .on("mouseout",function(d) {if (!lasso && isButtonEnabled(d)) { + var op = 1; + if (d._def.button.toggle) { + op = d[d._def.button.toggle]?1:0.2; + } + d3.select(this).attr("fill-opacity",op); + }}) + .on("click",nodeButtonClicked) + .on("touchstart",nodeButtonClicked) + } + + var mainRect = node.append("rect") + .attr("class", "red-ui-flow-node") + .classed("red-ui-flow-node-unknown",function(d) { return d.type == "unknown"; }) + .attr("rx", 5) + .attr("ry", 5) + .attr("fill",function(d) { return RED.utils.getNodeColor(d.type,d._def); /*d._def.color;*/}) + .on("mouseup",nodeMouseUp) + .on("mousedown",nodeMouseDown) + .on("touchstart",function(d) { + var obj = d3.select(this); + var touch0 = d3.event.touches.item(0); + var pos = [touch0.pageX,touch0.pageY]; + startTouchCenter = [touch0.pageX,touch0.pageY]; + startTouchDistance = 0; + touchStartTime = setTimeout(function() { + showTouchMenu(obj,pos); + },touchLongPressTimeout); + nodeMouseDown.call(this,d) + }) + .on("touchend", function(d) { + clearTimeout(touchStartTime); + touchStartTime = null; + if (RED.touch.radialMenu.active()) { + d3.event.stopPropagation(); + return; + } + nodeMouseUp.call(this,d); + }) + .on("mouseover",function(d) { + if (mouse_mode === 0 || mouse_mode === RED.state.SELECTING_NODE) { + if (mouse_mode === RED.state.SELECTING_NODE && selectNodesOptions && selectNodesOptions.filter) { + if (selectNodesOptions.filter(d)) { + node.classed("red-ui-flow-node-hovered",true); + } + } else { + node.classed("red-ui-flow-node-hovered",true); + } + clearTimeout(portLabelHoverTimeout); + if (d.hasOwnProperty('l')?!d.l : (d.type === "link in" || d.type === "link out")) { + portLabelHoverTimeout = setTimeout(function() { + var tooltip; + if (d._def.label) { + tooltip = d._def.label; + try { + tooltip = (typeof tooltip === "function" ? tooltip.call(d) : tooltip)||""; + } catch(err) { + console.log("Definition error: "+d.type+".label",err); + tooltip = d.type; + } + } + if (tooltip !== "") { + var pos = getElementPosition(node.node()); + portLabelHoverTimeout = null; + portLabelHover = showTooltip( + (pos[0] + d.w/2), + (pos[1]-1), + tooltip, + "top" + ); + } + },500); + } + } else if (mouse_mode === RED.state.JOINING || mouse_mode === RED.state.QUICK_JOINING) { + if (drag_lines.length > 0) { + var selectClass; + var portType; + if ((drag_lines[0].virtualLink && drag_lines[0].portType === PORT_TYPE_INPUT) || drag_lines[0].portType === PORT_TYPE_OUTPUT) { + selectClass = ".red-ui-flow-port-input .red-ui-flow-port"; + portType = PORT_TYPE_INPUT; + } else { + selectClass = ".red-ui-flow-port-output .red-ui-flow-port"; + portType = PORT_TYPE_OUTPUT; + } + portMouseOver(d3.select(this.parentNode).selectAll(selectClass),d,portType,0); + } + } + }) + .on("mouseout",function(d) { + node.classed("red-ui-flow-node-hovered",false); + clearTimeout(portLabelHoverTimeout); + if (portLabelHover) { + portLabelHover.remove(); + portLabelHover = null; + } + if (mouse_mode === RED.state.JOINING || mouse_mode === RED.state.QUICK_JOINING) { + if (drag_lines.length > 0) { + var selectClass; + var portType; + if ((drag_lines[0].virtualLink && drag_lines[0].portType === PORT_TYPE_INPUT) || drag_lines[0].portType === PORT_TYPE_OUTPUT) { + selectClass = ".red-ui-flow-port-input .red-ui-flow-port"; + portType = PORT_TYPE_INPUT; + } else { + selectClass = ".red-ui-flow-port-output .red-ui-flow-port"; + portType = PORT_TYPE_OUTPUT; + } + portMouseOut(d3.select(this.parentNode).selectAll(selectClass),d,portType,0); + } + } + }); + + //node.append("rect").attr("class", "node-gradient-top").attr("rx", 6).attr("ry", 6).attr("height",30).attr("stroke","none").attr("fill","url(#gradient-top)").style("pointer-events","none"); + //node.append("rect").attr("class", "node-gradient-bottom").attr("rx", 6).attr("ry", 6).attr("height",30).attr("stroke","none").attr("fill","url(#gradient-bottom)").style("pointer-events","none"); + + if (d._def.icon) { + var icon_url = RED.utils.getNodeIcon(d._def,d); + var icon_group = node.append("g") + .attr("class","red-ui-flow-node-icon-group") + .attr("x",0).attr("y",0); + + var icon_shade = icon_group.append("rect") + .attr("x",0).attr("y",0) + .attr("class","red-ui-flow-node-icon-shade") + .attr("width","30") + .attr("height",function(d){return Math.min(50,d.h-4);}); + + createIconAttributes(icon_url, icon_group, d); + + var icon_shade_border = icon_group.append("path") + .attr("d",function(d) { return "M 30 1 l 0 "+(d.h-2)}) + .attr("class","red-ui-flow-node-icon-shade-border"); + + if ("right" == d._def.align) { + icon_group.attr("class","red-ui-flow-node-icon-group red-ui-flow-node-icon-group-"+d._def.align); + icon_shade_border.attr("d",function(d) { return "M 0 1 l 0 "+(d.h-2)}) + //icon.attr("class","red-ui-flow-node-icon red-ui-flow-node-icon-"+d._def.align); + //icon.attr("class","red-ui-flow-node-icon-shade red-ui-flow-node-icon-shade-"+d._def.align); + //icon.attr("class","red-ui-flow-node-icon-shade-border red-ui-flow-node-icon-shade-border-"+d._def.align); + } + + //if (d.inputs > 0 && d._def.align == null) { + // icon_shade.attr("width",35); + // icon.attr("transform","translate(5,0)"); + // icon_shade_border.attr("transform","translate(5,0)"); + //} + //if (d._def.outputs > 0 && "right" == d._def.align) { + // icon_shade.attr("width",35); //icon.attr("x",5); + //} + + //icon.style("pointer-events","none"); + icon_group.style("pointer-events","none"); + } + var text = node.append("svg:text") + .attr("class","red-ui-flow-node-label") + .attr("x", 38) + .attr("dy", ".35em") + .attr("text-anchor","start") + .classed("hide",hideLabel); + + if (d._def.align) { + text.attr("class","red-ui-flow-node-label red-ui-flow-node-label-"+d._def.align); + if (d._def.align === "right") { + text.attr("text-anchor","end"); + } + } + + var status = node.append("svg:g").attr("class","red-ui-flow-node-status-group").style("display","none"); + var statusRect = status.append("rect").attr("class","red-ui-flow-node-status") + .attr("x",6).attr("y",1).attr("width",9).attr("height",9) + .attr("rx",2).attr("ry",2).attr("stroke-width","3"); + var statusLabel = status.append("svg:text") + .attr("class","red-ui-flow-node-status-label") + .attr("x",20).attr("y",10); + + node.append("g").attr("class","red-ui-flow-node-changed hide").attr("transform","translate(20, -2)").append("circle").attr("r",5); + var nodeErrorButton = node.append("g").attr("class","red-ui-flow-node-error hide").attr("transform","translate(0, -2)").append("path").attr("d","M -5,4 l 10,0 -5,-8 z"); + nodeErrorButton.on("mouseenter", function() { + if (d.validationErrors && d.validationErrors.length > 0) { + clearTimeout(portLabelHoverTimeout); + portLabelHoverTimeout = setTimeout(function() { + var pos = getElementPosition(nodeErrorButton.node()); + portLabelHoverTimeout = null; + portLabelHover = showTooltip( + (pos[0]), + (pos[1]), + RED._("editor.errors.invalidProperties")+"\n - "+d.validationErrors.join("\n - "), + "top" + ); + },500); + } + }).on("mouseleave", function() { + clearTimeout(portLabelHoverTimeout); + if (portLabelHover) { + portLabelHover.remove(); + portLabelHover = null; + } + }); + }); + + node.each(function(d,i) { + if (d.dirty) { + var isLink = (d.type === "link in" || d.type === "link out") + var hideLabel = d.hasOwnProperty('l')?!d.l : isLink; + dirtyNodes[d.id] = d; + //if (d.x < -50) deleteSelection(); // Delete nodes if dragged back to palette + if (d.resize) { + var l = RED.utils.getNodeLabel(d); + var ow = d.w; + if (hideLabel) { + d.w = node_height; + } else { + d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "red-ui-flow-node-label", 50)+(d._def.inputs>0?7:0))/20)) ); + } + // d.w = Math.max(node_width,20*(Math.ceil((calculateTextWidth(l, "red-ui-flow-node-label", 50)+(d._def.inputs>0?7:0))/20)) ); + d.h = Math.max(node_height,(d.outputs||0) * 15); + d.x += (d.w-ow)/2; + d.resize = false; + } + var thisNode = d3.select(this); + thisNode.classed("red-ui-flow-node-disabled", function(d) { return d.d === true}); + thisNode.classed("red-ui-flow-subflow",function(d) { return activeSubflow != null; }) + + //thisNode.selectAll(".centerDot").attr({"cx":function(d) { return d.w/2;},"cy":function(d){return d.h/2}}); + thisNode.attr("transform", function(d) { return "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")"; }); + if (mouse_mode != RED.state.MOVING_ACTIVE) { + thisNode.classed("red-ui-flow-node-selected",function(d) { return d.selected }) + thisNode.selectAll(".red-ui-flow-node") + .attr("width",function(d){return d.w}) + .attr("height",function(d){return d.h}) + .classed("red-ui-flow-node-highlighted",function(d) { return d.highlighted; }) + ; + if ((!d._def.align && d.inputs !== 0 && d.outputs === 0) || "right" === d._def.align) { + thisNode.selectAll(".red-ui-flow-node-icon-group").classed("red-ui-flow-node-icon-group-right", true); + thisNode.selectAll(".red-ui-flow-node-label").classed("red-ui-flow-node-label-right", true).attr("text-anchor", "end"); + } else { + thisNode.selectAll(".red-ui-flow-node-icon-group").classed("red-ui-flow-node-icon-group-right", false); + thisNode.selectAll(".red-ui-flow-node-label").classed("red-ui-flow-node-label-right", false).attr("text-anchor", "start"); + } + thisNode.selectAll(".red-ui-flow-node-icon-group").attr("transform", function (d) { return "translate(0, 0)"; }); + thisNode.selectAll(".red-ui-flow-node-label").attr("x", function (d) { return 38; }); + thisNode.selectAll(".red-ui-flow-node-icon-group-right").attr("transform", function(d){return "translate("+(d.w-30)+",0)"}); + thisNode.selectAll(".red-ui-flow-node-label-right").attr("x", function(d){return d.w-38}); + //thisNode.selectAll(".red-ui-flow-node-icon-right").attr("x",function(d){return d.w-d3.select(this).attr("width")-1-(d.outputs>0?5:0);}); + //thisNode.selectAll(".red-ui-flow-node-icon-shade-right").attr("x",function(d){return d.w-30;}); + //thisNode.selectAll(".red-ui-flow-node-icon-shade-border-right").attr("d",function(d){return "M "+(d.w-30)+" 1 l 0 "+(d.h-2)}); + + var inputPorts = thisNode.selectAll(".red-ui-flow-port-input"); + if ((!isLink || (showAllLinkPorts === -1 && !activeLinkNodes[d.id])) && d.inputs === 0 && !inputPorts.empty()) { + inputPorts.remove(); + } else if (((isLink && (showAllLinkPorts===PORT_TYPE_INPUT||activeLinkNodes[d.id]))|| d.inputs === 1) && inputPorts.empty()) { + var inputGroup = thisNode.append("g").attr("class","red-ui-flow-port-input"); + var inputGroupPorts; + + if (d.type === "link in") { + inputGroupPorts = inputGroup.append("circle") + .attr("cx",-1).attr("cy",5) + .attr("r",5) + .attr("class","red-ui-flow-port red-ui-flow-link-port") + } else { + inputGroupPorts = inputGroup.append("rect").attr("class","red-ui-flow-port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10) + } + inputGroupPorts.on("mousedown",function(d){portMouseDown(d,PORT_TYPE_INPUT,0);}) + .on("touchstart",function(d){portMouseDown(d,PORT_TYPE_INPUT,0);}) + .on("mouseup",function(d){portMouseUp(d,PORT_TYPE_INPUT,0);} ) + .on("touchend",function(d){portMouseUp(d,PORT_TYPE_INPUT,0);} ) + .on("mouseover",function(d){portMouseOver(d3.select(this),d,PORT_TYPE_INPUT,0);}) + .on("mouseout",function(d) {portMouseOut(d3.select(this),d,PORT_TYPE_INPUT,0);}); + } + + var numOutputs = d.outputs; + if (isLink && d.type === "link out") { + if (showAllLinkPorts===PORT_TYPE_OUTPUT || activeLinkNodes[d.id]) { + d.ports = [0]; + numOutputs = 1; + } else { + d.ports = []; + numOutputs = 0; + } + } + var y = (d.h/2)-((numOutputs-1)/2)*13; + d.ports = d.ports || d3.range(numOutputs); + d._ports = thisNode.selectAll(".red-ui-flow-port-output").data(d.ports); + var output_group = d._ports.enter().append("g").attr("class","red-ui-flow-port-output"); + var output_group_ports; + + if (d.type === "link out") { + output_group_ports = output_group.append("circle") + .attr("cx",11).attr("cy",5) + .attr("r",5) + .attr("class","red-ui-flow-port red-ui-flow-link-port") + } else { + output_group_ports = output_group.append("rect") + .attr("class","red-ui-flow-port") + .attr("rx",3).attr("ry",3) + .attr("width",10) + .attr("height",10) + } + + output_group_ports.on("mousedown",(function(){var node = d; return function(d,i){portMouseDown(node,PORT_TYPE_OUTPUT,i);}})() ) + .on("touchstart",(function(){var node = d; return function(d,i){portMouseDown(node,PORT_TYPE_OUTPUT,i);}})() ) + .on("mouseup",(function(){var node = d; return function(d,i){portMouseUp(node,PORT_TYPE_OUTPUT,i);}})() ) + .on("touchend",(function(){var node = d; return function(d,i){portMouseUp(node,PORT_TYPE_OUTPUT,i);}})() ) + .on("mouseover",(function(){var node = d; return function(d,i){portMouseOver(d3.select(this),node,PORT_TYPE_OUTPUT,i);}})()) + .on("mouseout",(function(){var node = d; return function(d,i) {portMouseOut(d3.select(this),node,PORT_TYPE_OUTPUT,i);}})()); + + d._ports.exit().remove(); + if (d._ports) { + numOutputs = d.outputs || 1; + y = (d.h/2)-((numOutputs-1)/2)*13; + var x = d.w - 5; + d._ports.each(function(d,i) { + var port = d3.select(this); + port.attr("transform", function(d) { return "translate("+x+","+((y+13*i)-5)+")";}); + }); + } + thisNode.selectAll("text.red-ui-flow-node-label").text(function(d,i){ + var l = ""; + if (d._def.label) { + l = d._def.label; + try { + l = (typeof l === "function" ? l.call(d) : l)||""; + l = RED.text.bidi.enforceTextDirectionWithUCC(l); + } catch(err) { + console.log("Definition error: "+d.type+".label",err); + l = d.type; + } + } + return l; + }) + .attr("y", function(d){return (d.h/2)-1;}) + .attr("class",function(d){ + var s = ""; + if (d._def.labelStyle) { + s = d._def.labelStyle; + try { + s = (typeof s === "function" ? s.call(d) : s)||""; + } catch(err) { + console.log("Definition error: "+d.type+".labelStyle",err); + s = ""; + } + s = " "+s; + } + return "red-ui-flow-node-label"+(d._def.align?" red-ui-flow-node-label-"+d._def.align:"")+s; + }).classed("hide",hideLabel); + if (d._def.icon) { + var icon = thisNode.select(".red-ui-flow-node-icon"); + var faIcon = thisNode.select(".fa-lg"); + var current_url; + if (!icon.empty()) { + current_url = icon.attr("xlink:href"); + } else { + current_url = faIcon.attr("xlink:href"); + } + var new_url = RED.utils.getNodeIcon(d._def,d); + if (new_url !== current_url) { + if (!icon.empty()) { + icon.remove(); + } else { + faIcon.remove(); + } + var iconGroup = thisNode.select(".red-ui-flow-node-icon-group"); + createIconAttributes(new_url, iconGroup, d); + } + } + + thisNode.selectAll(".red-ui-flow-node-changed") + .attr("transform",function(d){return "translate("+(d.w-10)+", -2)"}) + .classed("hide",function(d) { return !(d.changed||d.moved); }); + + thisNode.selectAll(".red-ui-flow-node-error") + .attr("transform",function(d){ return "translate("+(d.w-10-((d.changed||d.moved)?14:0))+", -2)"}) + .classed("hide",function(d) { return d.valid; }); + + thisNode.selectAll(".red-ui-flow-port-input").each(function(d,i) { + var port = d3.select(this); + port.attr("transform",function(d){return "translate(-5,"+((d.h/2)-5)+")";}) + }); + + thisNode.selectAll(".red-ui-flow-node-icon").attr("y",function(d){return (d.h-d3.select(this).attr("height"))/2;}); + thisNode.selectAll(".red-ui-flow-node-icon-shade").attr("height",function(d){return d.h;}); + thisNode.selectAll(".red-ui-flow-node-icon-shade-border").attr("d", function (d) { + return "M " + (((!d._def.align && d.inputs !== 0 && d.outputs === 0) || "right" === d._def.align) ? 0 : 30) + " 1 l 0 " + (d.h - 2); + }); + thisNode.selectAll(".fa-lg").attr("y",function(d){return (d.h+13)/2;}); + + thisNode.selectAll(".red-ui-flow-node-button").attr("opacity",function(d) { + return (!isButtonEnabled(d))?0.4:1 + }); + thisNode.selectAll(".red-ui-flow-node-button-button").attr("cursor",function(d) { + return (!isButtonEnabled(d))?"":"pointer"; + }); + thisNode.selectAll(".red-ui-flow-node-button").attr("transform",function(d){ + var x = d._def.align == "right"?d.w-6:-25; + if (d._def.button.toggle && !d[d._def.button.toggle]) { + x = x - (d._def.align == "right"?8:-8); + } + return "translate("+x+",2)"; + }); + thisNode.selectAll(".red-ui-flow-node-button rect").attr("fill-opacity",function(d){ + if (d._def.button.toggle) { + return d[d._def.button.toggle]?1:0.2; + } + return 1; + }); + + if (d._def.button && (typeof d._def.button.visible === "function")) { // is defined and a function... + if (d._def.button.visible.call(d) === false) { + thisNode.selectAll(".red-ui-flow-node-button").style("display","none"); + } + else { + thisNode.selectAll(".red-ui-flow-node-button").style("display","inherit"); + } + } + + // thisNode.selectAll(".node_badge_group").attr("transform",function(d){return "translate("+(d.w-40)+","+(d.h+3)+")";}); + // thisNode.selectAll("text.node_badge_label").text(function(d,i) { + // if (d._def.badge) { + // if (typeof d._def.badge == "function") { + // try { + // return d._def.badge.call(d); + // } catch(err) { + // console.log("Definition error: "+d.type+".badge",err); + // return ""; + // } + // } else { + // return d._def.badge; + // } + // } + // return ""; + // }); + } + + if (d.dirtyStatus) { + if (!showStatus || !d.status) { + thisNode.selectAll(".red-ui-flow-node-status-group").style("display","none"); + } else { + thisNode.selectAll(".red-ui-flow-node-status-group").style("display","inline"); + var fill = status_colours[d.status.fill]; // Only allow our colours for now + if (d.status.shape == null && fill == null) { + thisNode.selectAll(".red-ui-flow-node-status").style("display","none"); + thisNode.selectAll(".red-ui-flow-node-status-group").attr("transform","translate(-14,"+(d.h+3)+")"); + } else { + thisNode.selectAll(".red-ui-flow-node-status-group").attr("transform","translate(3,"+(d.h+3)+")"); + var statusClass = "red-ui-flow-node-status-"+(d.status.shape||"dot")+"-"+d.status.fill; + thisNode.selectAll(".red-ui-flow-node-status").style("display","inline").attr("class","red-ui-flow-node-status "+statusClass); + } + if (d.status.hasOwnProperty('text')) { + thisNode.selectAll(".red-ui-flow-node-status-label").text(d.status.text); + } else { + thisNode.selectAll(".red-ui-flow-node-status-label").text(""); + } + } + delete d.dirtyStatus; + } + + d.dirty = false; + } + }); + + var link = linkLayer.selectAll(".red-ui-flow-link").data( + activeLinks, + function(d) { + return d.source.id+":"+d.sourcePort+":"+d.target.id+":"+d.target.i; + } + ); + var linkEnter = link.enter().insert("g",".red-ui-flow-node").attr("class","red-ui-flow-link"); + + linkEnter.each(function(d,i) { + var l = d3.select(this); + d.added = true; + l.append("svg:path").attr("class","red-ui-flow-link-background red-ui-flow-link-path") + .classed("red-ui-flow-link-link", function(d) { return d.link }) + .on("mousedown",function(d) { + if (mouse_mode === RED.state.SELECTING_NODE) { + d3.event.stopPropagation(); + return; + } + mousedown_link = d; + clearSelection(); + selected_link = mousedown_link; + updateSelection(); + redraw(); + focusView(); + d3.event.stopPropagation(); + if (d3.event.metaKey || d3.event.ctrlKey) { + l.classed("red-ui-flow-link-splice",true); + showQuickAddDialog(d3.mouse(this), selected_link); + } + }) + .on("touchstart",function(d) { + if (mouse_mode === RED.state.SELECTING_NODE) { + d3.event.stopPropagation(); + return; + } + mousedown_link = d; + clearSelection(); + selected_link = mousedown_link; + updateSelection(); + redraw(); + focusView(); + d3.event.stopPropagation(); + + var obj = d3.select(document.body); + var touch0 = d3.event.touches.item(0); + var pos = [touch0.pageX,touch0.pageY]; + touchStartTime = setTimeout(function() { + touchStartTime = null; + showTouchMenu(obj,pos); + },touchLongPressTimeout); + }) + l.append("svg:path").attr("class","red-ui-flow-link-outline red-ui-flow-link-path"); + l.append("svg:path").attr("class","red-ui-flow-link-line red-ui-flow-link-path") + .classed("red-ui-flow-link-link", function(d) { return d.link }) + .classed("red-ui-flow-subflow-link", function(d) { return !d.link && activeSubflow }); + }); + + link.exit().remove(); + var links = linkLayer.selectAll(".red-ui-flow-link-path"); + links.each(function(d) { + var link = d3.select(this); + if (d.added || d===selected_link || d.selected || dirtyNodes[d.source.id] || dirtyNodes[d.target.id]) { + if (/red-ui-flow-link-line/.test(link.attr('class'))) { + link.classed("red-ui-flow-subflow-link", function(d) { return !d.link && activeSubflow }); + } + link.attr("d",function(d){ + var numOutputs = d.source.outputs || 1; + var sourcePort = d.sourcePort || 0; + var y = -((numOutputs-1)/2)*13 +13*sourcePort; + d.x1 = d.source.x+d.source.w/2; + d.y1 = d.source.y+y; + d.x2 = d.target.x-d.target.w/2; + d.y2 = d.target.y; + + // return "M "+d.x1+" "+d.y1+ + // " C "+(d.x1+scale*node_width)+" "+(d.y1+scaleY*node_height)+" "+ + // (d.x2-scale*node_width)+" "+(d.y2-scaleY*node_height)+" "+ + // d.x2+" "+d.y2; + var path = generateLinkPath(d.x1,d.y1,d.x2,d.y2,1); + if (/NaN/.test(path)) { + return "" + } + return path; + }); + link.classed("red-ui-flow-node-disabled", function(d) { return d.source.d || d.target.d; }); + } + }) + + link.classed("red-ui-flow-link-selected", function(d) { return d === selected_link || d.selected; }); + link.classed("red-ui-flow-link-unknown",function(d) { + delete d.added; + return d.target.type == "unknown" || d.source.type == "unknown" + }); + var offLinks = linkLayer.selectAll(".red-ui-flow-link-off-flow").data( + activeFlowLinks, + function(d) { + return d.node.id+":"+d.refresh + } + ); + + var offLinksEnter = offLinks.enter().insert("g",".red-ui-flow-node").attr("class","red-ui-flow-link-off-flow"); + offLinksEnter.each(function(d,i) { + var g = d3.select(this); + var s = 1; + var labelAnchor = "start"; + if (d.node.type === "link in") { + s = -1; + labelAnchor = "end"; + } + var stemLength = s*30; + var branchLength = s*20; + var l = g.append("svg:path").attr("class","red-ui-flow-link-link").attr("d","M 0 0 h "+stemLength); + var links = d.links; + var flows = Object.keys(links); + var tabOrder = RED.nodes.getWorkspaceOrder(); + flows.sort(function(A,B) { + return tabOrder.indexOf(A) - tabOrder.indexOf(B); + }); + var linkWidth = 10; + var h = node_height; + var y = -(flows.length-1)*h/2; + var linkGroups = g.selectAll(".red-ui-flow-link-group").data(flows); + var enterLinkGroups = linkGroups.enter().append("g").attr("class","red-ui-flow-link-group") + .on('mouseover', function() { if (mouse_mode !== 0) { return } d3.select(this).classed('red-ui-flow-link-group-active',true)}) + .on('mouseout', function() {if (mouse_mode !== 0) { return } d3.select(this).classed('red-ui-flow-link-group-active',false)}) + .on('mousedown', function() { d3.event.preventDefault(); d3.event.stopPropagation(); }) + .on('mouseup', function(f) { + if (mouse_mode !== 0) { + return + } + d3.event.stopPropagation(); + var targets = d.links[f]; + RED.workspaces.show(f); + targets.forEach(function(n) { + n.selected = true; + n.dirty = true; + moving_set.push({n:n}); + }); + updateSelection(); + redraw(); + }); + enterLinkGroups.each(function(f) { + var linkG = d3.select(this); + linkG.append("svg:path") + .attr("class","red-ui-flow-link-link") + .attr("d", + "M "+stemLength+" 0 "+ + "C "+(stemLength+(1.7*branchLength))+" "+0+ + " "+(stemLength+(0.1*branchLength))+" "+y+" "+ + (stemLength+branchLength*1.5)+" "+y+" " + ); + linkG.append("svg:path") + .attr("class","red-ui-flow-link-port") + .attr("d", + "M "+(stemLength+branchLength*1.5+s*(linkWidth+7))+" "+(y-12)+" "+ + "h "+(-s*linkWidth)+" "+ + "a 3 3 45 0 "+(s===1?"0":"1")+" "+(s*-3)+" 3 "+ + "v 18 "+ + "a 3 3 45 0 "+(s===1?"0":"1")+" "+(s*3)+" 3 "+ + "h "+(s*linkWidth) + ); + linkG.append("svg:path") + .attr("class","red-ui-flow-link-port") + .attr("d", + "M "+(stemLength+branchLength*1.5+s*(linkWidth+10))+" "+(y-12)+" "+ + "h "+(s*(linkWidth*3))+" "+ + "M "+(stemLength+branchLength*1.5+s*(linkWidth+10))+" "+(y+12)+" "+ + "h "+(s*(linkWidth*3)) + ).style("stroke-dasharray","12 3 8 4 3"); + linkG.append("rect").attr("class","red-ui-flow-port red-ui-flow-link-port") + .attr("x",stemLength+branchLength*1.5-4+(s*4)) + .attr("y",y-4) + .attr("rx",2) + .attr("ry",2) + .attr("width",8) + .attr("height",8); + linkG.append("rect") + .attr("x",stemLength+branchLength*1.5-(s===-1?node_width:0)) + .attr("y",y-12) + .attr("width",node_width) + .attr("height",24) + .style("stroke","none") + .style("fill","transparent") + var tab = RED.nodes.workspace(f); + var label; + if (tab) { + label = tab.label || tab.id; + } + linkG.append("svg:text") + .attr("class","red-ui-flow-port-label") + .attr("x",stemLength+branchLength*1.5+(s*15)) + .attr("y",y+1) + .style("font-size","10px") + .style("text-anchor",labelAnchor) + .text(label); + + y += h; + }); + linkGroups.exit().remove(); + }); + offLinks.exit().remove(); + offLinks = linkLayer.selectAll(".red-ui-flow-link-off-flow"); + offLinks.each(function(d) { + var s = 1; + if (d.node.type === "link in") { + s = -1; + } + var link = d3.select(this); + link.attr("transform", function(d) { return "translate(" + (d.node.x+(s*d.node.w/2)) + "," + (d.node.y) + ")"; }); + + }) + + } else { + // JOINING - unselect any selected links + linkLayer.selectAll(".red-ui-flow-link-selected").data( + activeLinks, + function(d) { + return d.source.id+":"+d.sourcePort+":"+d.target.id+":"+d.target.i; + } + ).classed("red-ui-flow-link-selected", false); + } + RED.view.navigator.refresh(); + if (d3.event) { + d3.event.preventDefault(); + } + + } + + function focusView() { + try { + // Workaround for browser unexpectedly scrolling iframe into full + // view - record the parent scroll position and restore it after + // setting the focus + var scrollX = window.parent.window.scrollX; + var scrollY = window.parent.window.scrollY; + chart.trigger("focus"); + window.parent.window.scrollTo(scrollX,scrollY); + } catch(err) { + // In case we're iframed into a page of a different origin, just focus + // the view following the inevitable DOMException + chart.trigger("focus"); + } + } + + /** + * Imports a new collection of nodes from a JSON String. + * - all get new IDs assigned + * - all "selected" + * - attached to mouse for placing - "IMPORT_DRAGGING" + */ + function importNodes(newNodesStr,addNewFlow,touchImport) { + if (mouse_mode === RED.state.SELECTING_NODE) { + return; + } + try { + var activeSubflowChanged; + if (activeSubflow) { + activeSubflowChanged = activeSubflow.changed; + } + var result = RED.nodes.import(newNodesStr,true,addNewFlow); + if (result) { + var new_nodes = result[0]; + var new_links = result[1]; + var new_workspaces = result[2]; + var new_subflows = result[3]; + var new_default_workspace = result[4]; + if (addNewFlow && new_default_workspace) { + RED.workspaces.show(new_default_workspace.id); + } + var new_ms = new_nodes.filter(function(n) { return n.hasOwnProperty("x") && n.hasOwnProperty("y") && n.z == RED.workspaces.active() }).map(function(n) { return {n:n};}); + var new_node_ids = new_nodes.map(function(n){ n.changed = true; return n.id; }); + + // TODO: pick a more sensible root node + if (new_ms.length > 0) { + var root_node = new_ms[0].n; + var dx = root_node.x; + var dy = root_node.y; + + if (mouse_position == null) { + mouse_position = [0,0]; + } + + var minX = 0; + var minY = 0; + var i; + var node; + + for (i=0;i<new_ms.length;i++) { + node = new_ms[i]; + node.n.selected = true; + node.n.changed = true; + node.n.moved = true; + node.n.x -= dx - mouse_position[0]; + node.n.y -= dy - mouse_position[1]; + node.dx = node.n.x - mouse_position[0]; + node.dy = node.n.y - mouse_position[1]; + minX = Math.min(node.n.x-node_width/2-5,minX); + minY = Math.min(node.n.y-node_height/2-5,minY); + } + for (i=0;i<new_ms.length;i++) { + node = new_ms[i]; + node.n.x -= minX; + node.n.y -= minY; + node.dx -= minX; + node.dy -= minY; + if (node.n._def.onadd) { + try { + node.n._def.onadd.call(node.n); + } catch(err) { + console.log("Definition error: "+node.n.type+".onadd:",err); + } + } + + } + if (!touchImport) { + mouse_mode = RED.state.IMPORT_DRAGGING; + spliceActive = false; + if (new_ms.length === 1) { + node = new_ms[0]; + spliceActive = node.n.hasOwnProperty("_def") && + node.n._def.inputs > 0 && + node.n._def.outputs > 0; + } + } + RED.keyboard.add("*","escape",function(){ + RED.keyboard.remove("escape"); + clearSelection(); + RED.history.pop(); + mouse_mode = 0; + }); + clearSelection(); + moving_set = new_ms; + } + + var historyEvent = { + t:"add", + nodes:new_node_ids, + links:new_links, + workspaces:new_workspaces, + subflows:new_subflows, + dirty:RED.nodes.dirty() + }; + if (new_ms.length === 0) { + RED.nodes.dirty(true); + } + if (activeSubflow) { + var subflowRefresh = RED.subflow.refresh(true); + if (subflowRefresh) { + historyEvent.subflow = { + id:activeSubflow.id, + changed: activeSubflowChanged, + instances: subflowRefresh.instances + } + } + } + RED.history.push(historyEvent); + + updateActiveNodes(); + redraw(); + + var counts = []; + var newNodeCount = 0; + var newConfigNodeCount = 0; + new_nodes.forEach(function(n) { + if (n.hasOwnProperty("x") && n.hasOwnProperty("y")) { + newNodeCount++; + } else { + newConfigNodeCount++; + } + }) + if (new_workspaces.length > 0) { + counts.push(RED._("clipboard.flow",{count:new_workspaces.length})); + } + if (newNodeCount > 0) { + counts.push(RED._("clipboard.node",{count:newNodeCount})); + } + if (newConfigNodeCount > 0) { + counts.push(RED._("clipboard.configNode",{count:newNodeCount})); + } + if (new_subflows.length > 0) { + counts.push(RED._("clipboard.subflow",{count:new_subflows.length})); + } + if (counts.length > 0) { + var countList = "<ul><li>"+counts.join("</li><li>")+"</li></ul>"; + RED.notify("<p>"+RED._("clipboard.nodesImported")+"</p>"+countList,{id:"clipboard"}); + } + + } + } catch(error) { + if (error.code != "NODE_RED") { + console.log(error.stack); + RED.notify(RED._("notification.error",{message:error.toString()}),"error"); + } else { + RED.notify(RED._("notification.error",{message:error.message}),"error"); + } + } + } + + function toggleShowGrid(state) { + if (state) { + gridLayer.style("visibility","visible"); + } else { + gridLayer.style("visibility","hidden"); + } + } + function toggleSnapGrid(state) { + snapGrid = state; + redraw(); + } + function toggleStatus(s) { + showStatus = s; + RED.nodes.eachNode(function(n) { n.dirtyStatus = true; n.dirty = true;}); + //TODO: subscribe/unsubscribe here + redraw(); + } + function setSelectedNodeState(isDisabled) { + if (mouse_mode === RED.state.SELECTING_NODE) { + return; + } + var workspaceSelection = RED.workspaces.selection(); + var changed = false; + if (workspaceSelection.length > 0) { + // TODO: toggle workspace state + } else if (moving_set.length > 0) { + var historyEvents = []; + for (var i=0;i<moving_set.length;i++) { + var node = moving_set[i].n; + if (isDisabled != node.d) { + historyEvents.push({ + t: "edit", + node: node, + changed: node.changed, + changes: { + d: node.d + } + }); + if (isDisabled) { + node.d = true; + } else { + delete node.d; + } + node.dirty = true; + node.changed = true; + } + } + if (historyEvents.length > 0) { + RED.history.push({ + t:"multi", + events: historyEvents, + dirty:RED.nodes.dirty() + }) + RED.nodes.dirty(true) + } + } + RED.view.redraw(); + + } + + return { + init: init, + state:function(state) { + if (state == null) { + return mouse_mode + } else { + mouse_mode = state; + } + }, + + redraw: function(updateActive) { + if (updateActive) { + updateActiveNodes(); + updateSelection(); + } + redraw(); + }, + focus: focusView, + importNodes: importNodes, + calculateTextWidth: calculateTextWidth, + select: function(selection) { + if (typeof selection !== "undefined") { + clearSelection(); + if (typeof selection == "string") { + var selectedNode = RED.nodes.node(selection); + if (selectedNode) { + selectedNode.selected = true; + selectedNode.dirty = true; + moving_set = [{n:selectedNode}]; + } + } + } + updateSelection(); + redraw(); + }, + selection: function() { + var selection = {}; + if (moving_set.length > 0) { + selection.nodes = moving_set.map(function(n) { return n.n;}); + } + if (selected_link != null) { + selection.link = selected_link; + } + return selection; + }, + scale: function() { + return scaleFactor; + }, + getLinksAtPoint: function(x,y) { + var result = []; + var links = outer.selectAll(".red-ui-flow-link-background")[0]; + for (var i=0;i<links.length;i++) { + var bb = links[i].getBBox(); + if (x >= bb.x && y >= bb.y && x <= bb.x+bb.width && y <= bb.y+bb.height) { + result.push(links[i]) + } + } + return result; + }, + reveal: function(id) { + if (RED.nodes.workspace(id) || RED.nodes.subflow(id)) { + RED.workspaces.show(id); + } else { + var node = RED.nodes.node(id); + if (node._def.category !== 'config' && node.z) { + node.highlighted = true; + node.dirty = true; + RED.workspaces.show(node.z); + + var screenSize = [chart.width()/scaleFactor,chart.height()/scaleFactor]; + var scrollPos = [chart.scrollLeft()/scaleFactor,chart.scrollTop()/scaleFactor]; + + if (node.x < scrollPos[0] || node.y < scrollPos[1] || node.x > screenSize[0]+scrollPos[0] || node.y > screenSize[1]+scrollPos[1]) { + var deltaX = '-='+(((scrollPos[0] - node.x) + screenSize[0]/2)*scaleFactor); + var deltaY = '-='+(((scrollPos[1] - node.y) + screenSize[1]/2)*scaleFactor); + chart.animate({ + scrollLeft: deltaX, + scrollTop: deltaY + },200); + } + + if (!node._flashing) { + node._flashing = true; + var flash = 22; + var flashFunc = function() { + flash--; + node.dirty = true; + if (flash >= 0) { + node.highlighted = !node.highlighted; + setTimeout(flashFunc,100); + } else { + node.highlighted = false; + delete node._flashing; + } + RED.view.redraw(); + } + flashFunc(); + } + } else if (node._def.category === 'config') { + RED.sidebar.config.show(id); + } + } + }, + gridSize: function(v) { + if (v === undefined) { + return gridSize; + } else { + gridSize = Math.max(5,v); + updateGrid(); + } + }, + getActiveNodes: function() { + return activeNodes; + }, + selectNodes: function(options) { + $("#red-ui-workspace-tabs-shade").show(); + $("#red-ui-palette-shade").show(); + $("#red-ui-sidebar-shade").show(); + $("#red-ui-header-shade").show(); + $("#red-ui-workspace").addClass("red-ui-workspace-select-mode"); + + mouse_mode = RED.state.SELECTING_NODE; + clearSelection(); + if (options.selected) { + console.log(options.selected); + options.selected.forEach(function(id) { + var n = RED.nodes.node(id); + if (n) { + n.selected = true; + n.dirty = true; + moving_set.push({n:n}); + } + }) + } + redraw(); + selectNodesOptions = options||{}; + var closeNotification = function() { + clearSelection(); + $("#red-ui-workspace-tabs-shade").hide(); + $("#red-ui-palette-shade").hide(); + $("#red-ui-sidebar-shade").hide(); + $("#red-ui-header-shade").hide(); + $("#red-ui-workspace").removeClass("red-ui-workspace-select-mode"); + resetMouseVars(); + notification.close(); + } + selectNodesOptions.done = function(selection) { + closeNotification(); + if (selectNodesOptions.onselect) { + selectNodesOptions.onselect(selection); + } + } + var buttons = [{ + text: RED._("common.label.cancel"), + click: function(e) { + closeNotification(); + if (selectNodesOptions.oncancel) { + selectNodesOptions.oncancel(); + } + } + }]; + if (!selectNodesOptions.single) { + buttons.push({ + text: RED._("common.label.done"), + class: "primary", + click: function(e) { + var selection = moving_set.map(function(n) { return n.n;}); + selectNodesOptions.done(selection); + } + }); + } + var notification = RED.notify(selectNodesOptions.prompt || RED._("workspace.selectNodes"),{ + modal: false, + fixed: true, + type: "compact", + buttons: buttons + }) + } + }; +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js new file mode 100644 index 0000000..1f361d0 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js @@ -0,0 +1,468 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +RED.workspaces = (function() { + + var activeWorkspace = 0; + var workspaceIndex = 0; + + function addWorkspace(ws,skipHistoryEntry,targetIndex) { + if (ws) { + workspace_tabs.addTab(ws,targetIndex); + workspace_tabs.resize(); + } else { + var tabId = RED.nodes.id(); + do { + workspaceIndex += 1; + } while ($("#red-ui-workspace-tabs a[title='"+RED._('workspace.defaultName',{number:workspaceIndex})+"']").size() !== 0); + + ws = {type:"tab",id:tabId,disabled: false,info:"",label:RED._('workspace.defaultName',{number:workspaceIndex})}; + RED.nodes.addWorkspace(ws,targetIndex); + workspace_tabs.addTab(ws,targetIndex); + workspace_tabs.activateTab(tabId); + if (!skipHistoryEntry) { + RED.history.push({t:'add',workspaces:[ws],dirty:RED.nodes.dirty()}); + RED.nodes.dirty(true); + } + } + RED.view.focus(); + return ws; + } + function deleteWorkspace(ws) { + if (workspaceTabCount === 1) { + return; + } + var workspaceOrder = RED.nodes.getWorkspaceOrder(); + ws._index = workspaceOrder.indexOf(ws.id); + removeWorkspace(ws); + var historyEvent = RED.nodes.removeWorkspace(ws.id); + historyEvent.t = 'delete'; + historyEvent.dirty = RED.nodes.dirty(); + historyEvent.workspaces = [ws]; + RED.history.push(historyEvent); + RED.nodes.dirty(true); + RED.sidebar.config.refresh(); + } + + function showEditWorkspaceDialog(id) { + var workspace = RED.nodes.workspace(id); + if (!workspace) { + var subflow = RED.nodes.subflow(id); + if (subflow) { + RED.editor.editSubflow(subflow); + } + return; + } + RED.view.state(RED.state.EDITING); + var tabflowEditor; + var trayOptions = { + title: RED._("workspace.editFlow",{name:RED.utils.sanitize(workspace.label)}), + buttons: [ + { + id: "node-dialog-delete", + class: 'leftButton'+((workspaceTabCount === 1)?" disabled":""), + text: RED._("common.label.delete"), //'<i class="fa fa-trash"></i>', + click: function() { + deleteWorkspace(workspace); + RED.tray.close(); + } + }, + { + id: "node-dialog-cancel", + text: RED._("common.label.cancel"), + click: function() { + RED.tray.close(); + } + }, + { + id: "node-dialog-ok", + class: "primary", + text: RED._("common.label.done"), + click: function() { + var label = $( "#node-input-name" ).val(); + var changed = false; + var changes = {}; + if (workspace.label != label) { + changes.label = workspace.label; + changed = true; + workspace.label = label; + workspace_tabs.renameTab(workspace.id,label); + } + var disabled = $("#node-input-disabled").prop("checked"); + if (workspace.disabled !== disabled) { + changes.disabled = workspace.disabled; + changed = true; + workspace.disabled = disabled; + } + var info = tabflowEditor.getValue(); + if (workspace.info !== info) { + changes.info = workspace.info; + changed = true; + workspace.info = info; + } + $("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled); + $("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled); + + if (changed) { + var historyEvent = { + t: "edit", + changes:changes, + node: workspace, + dirty: RED.nodes.dirty() + } + workspace.changed = true; + RED.history.push(historyEvent); + RED.nodes.dirty(true); + RED.sidebar.config.refresh(); + var selection = RED.view.selection(); + if (!selection.nodes && !selection.links) { + RED.sidebar.info.refresh(workspace); + } + if (changes.hasOwnProperty('disabled')) { + RED.nodes.eachNode(function(n) { + if (n.z === workspace.id) { + n.dirty = true; + } + }); + RED.view.redraw(); + } + } + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + var rows = $("#dialog-form>div:not(.node-text-editor-row)"); + var editorRow = $("#dialog-form>div.node-text-editor-row"); + var height = $("#dialog-form").height(); + for (var i=0; i<rows.size(); i++) { + height -= $(rows[i]).outerHeight(true); + } + height -= (parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom"))); + $(".node-text-editor").css("height",height+"px"); + tabflowEditor.resize(); + }, + open: function(tray) { + var trayFooter = tray.find(".red-ui-tray-footer"); + var trayBody = tray.find('.red-ui-tray-body'); + var trayFooterLeft = $('<div class="red-ui-tray-footer-left"></div>').appendTo(trayFooter) + + var dialogForm = $('<form id="dialog-form" class="form-horizontal"></form>').appendTo(trayBody); + $('<div class="form-row">'+ + '<label for="node-input-name" data-i18n="[append]editor:common.label.name"><i class="fa fa-tag"></i> </label>'+ + '<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">'+ + '</div>').appendTo(dialogForm); + + + if (!workspace.hasOwnProperty("disabled")) { + workspace.disabled = false; + } + + $('<input id="node-input-disabled" type="checkbox">').prop("checked",workspace.disabled).appendTo(trayFooterLeft).toggleButton({ + enabledIcon: "fa-circle-thin", + disabledIcon: "fa-ban", + invertState: true + }) + + + var row = $('<div class="form-row node-text-editor-row">'+ + '<label for="node-input-info" data-i18n="editor:workspace.info" style="width:300px;"></label>'+ + '<div style="min-height:250px;" class="node-text-editor" id="node-input-info"></div>'+ + '</div>').appendTo(dialogForm); + tabflowEditor = RED.editor.createEditor({ + id: 'node-input-info', + mode: 'ace/mode/markdown', + value: "" + }); + + $('#node-info-input-info-expand').on("click", function(e) { + e.preventDefault(); + var value = tabflowEditor.getValue(); + RED.editor.editMarkdown({ + value: value, + width: "Infinity", + cursor: tabflowEditor.getCursorPosition(), + complete: function(v,cursor) { + tabflowEditor.setValue(v, -1); + tabflowEditor.gotoLine(cursor.row+1,cursor.column,false); + setTimeout(function() { + tabflowEditor.focus(); + },300); + } + }) + }); + + + + $('<input type="text" style="display: none;" />').prependTo(dialogForm); + dialogForm.on("submit", function(e) { e.preventDefault();}); + $("#node-input-name").val(workspace.label); + RED.text.bidi.prepareInput($("#node-input-name")); + tabflowEditor.getSession().setValue(workspace.info || "", -1); + dialogForm.i18n(); + }, + close: function() { + if (RED.view.state() != RED.state.IMPORT_DRAGGING) { + RED.view.state(RED.state.DEFAULT); + } + RED.sidebar.info.refresh(workspace); + tabflowEditor.destroy(); + } + } + RED.tray.show(trayOptions); + } + + + var workspace_tabs; + var workspaceTabCount = 0; + function createWorkspaceTabs() { + workspace_tabs = RED.tabs.create({ + id: "red-ui-workspace-tabs", + onchange: function(tab) { + var event = { + old: activeWorkspace + } + activeWorkspace = tab.id; + event.workspace = activeWorkspace; + RED.events.emit("workspace:change",event); + window.location.hash = 'flow/'+tab.id; + $("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!tab.disabled); + RED.sidebar.config.refresh(); + RED.view.focus(); + }, + onclick: function(tab) { + RED.view.focus(); + }, + ondblclick: function(tab) { + if (tab.type != "subflow") { + showEditWorkspaceDialog(tab.id); + } else { + RED.editor.editSubflow(RED.nodes.subflow(tab.id)); + } + }, + onadd: function(tab) { + if (tab.type === "tab") { + workspaceTabCount++; + } + $('<span class="red-ui-workspace-disabled-icon"><i class="fa fa-ban"></i> </span>').prependTo("#red-ui-tab-"+(tab.id.replace(".","-"))+" .red-ui-tab-label"); + if (tab.disabled) { + $("#red-ui-tab-"+(tab.id.replace(".","-"))).addClass('red-ui-workspace-disabled'); + } + RED.menu.setDisabled("menu-item-workspace-delete",workspaceTabCount <= 1); + if (workspaceTabCount === 1) { + showWorkspace(); + } + }, + onremove: function(tab) { + if (tab.type === "tab") { + workspaceTabCount--; + } + RED.menu.setDisabled("menu-item-workspace-delete",workspaceTabCount <= 1); + if (workspaceTabCount === 0) { + hideWorkspace(); + } + }, + onreorder: function(oldOrder, newOrder) { + RED.history.push({t:'reorder',order:oldOrder,dirty:RED.nodes.dirty()}); + RED.nodes.dirty(true); + setWorkspaceOrder(newOrder); + }, + onselect: function(selectedTabs) { + RED.view.select(false) + if (selectedTabs.length === 0) { + $("#red-ui-workspace-chart svg").css({"pointer-events":"auto",filter:"none"}) + $("#red-ui-workspace-toolbar").css({"pointer-events":"auto",filter:"none"}) + $("#red-ui-palette-container").css({"pointer-events":"auto",filter:"none"}) + $(".red-ui-sidebar-shade").hide(); + } else { + RED.view.select(false) + $("#red-ui-workspace-chart svg").css({"pointer-events":"none",filter:"opacity(60%)"}) + $("#red-ui-workspace-toolbar").css({"pointer-events":"none",filter:"opacity(60%)"}) + $("#red-ui-palette-container").css({"pointer-events":"none",filter:"opacity(60%)"}) + $(".red-ui-sidebar-shade").show(); + } + }, + minimumActiveTabWidth: 150, + scrollable: true, + addButton: "core:add-flow", + addButtonCaption: RED._("workspace.addFlow"), + searchButton: "core:list-flows", + searchButtonCaption: RED._("workspace.listFlows") + }); + workspaceTabCount = 0; + } + function showWorkspace() { + $("#red-ui-workspace .red-ui-tabs").show() + $("#red-ui-workspace-chart").show() + $("#red-ui-workspace-footer").children().show() + } + function hideWorkspace() { + $("#red-ui-workspace .red-ui-tabs").hide() + $("#red-ui-workspace-chart").hide() + $("#red-ui-workspace-footer").children().hide() + } + + function init() { + $('<ul id="red-ui-workspace-tabs"></ul>').appendTo("#red-ui-workspace"); + $('<div id="red-ui-workspace-tabs-shade" class="hide"></div>').appendTo("#red-ui-workspace"); + $('<div id="red-ui-workspace-chart" tabindex="1"></div>').appendTo("#red-ui-workspace"); + $('<div id="red-ui-workspace-toolbar"></div>').appendTo("#red-ui-workspace"); + $('<div id="red-ui-workspace-footer" class="red-ui-component-footer"></div>').appendTo("#red-ui-workspace"); + $('<div id="red-ui-editor-shade" class="hide"></div>').appendTo("#red-ui-workspace"); + + + createWorkspaceTabs(); + RED.events.on("sidebar:resize",workspace_tabs.resize); + + RED.actions.add("core:show-next-tab",workspace_tabs.nextTab); + RED.actions.add("core:show-previous-tab",workspace_tabs.previousTab); + + RED.menu.setAction('menu-item-workspace-delete',function() { + deleteWorkspace(RED.nodes.workspace(activeWorkspace)); + }); + + $(window).on("resize", function() { + workspace_tabs.resize(); + }); + + RED.actions.add("core:add-flow",function(opts) { addWorkspace(undefined,undefined,opts?opts.index:undefined)}); + RED.actions.add("core:edit-flow",editWorkspace); + RED.actions.add("core:remove-flow",removeWorkspace); + RED.actions.add("core:enable-flow",enableWorkspace); + RED.actions.add("core:disable-flow",disableWorkspace); + + RED.actions.add("core:list-flows",function() { + RED.actions.invoke("core:search","type:tab "); + }) + + hideWorkspace(); + } + + function editWorkspace(id) { + showEditWorkspaceDialog(id||activeWorkspace); + } + + function enableWorkspace(id) { + setWorkspaceState(id,false); + } + function disableWorkspace(id) { + setWorkspaceState(id,true); + } + function setWorkspaceState(id,disabled) { + var workspace = RED.nodes.workspace(id||activeWorkspace); + if (!workspace) { + return; + } + if (workspace.disabled !== disabled) { + var changes = { disabled: workspace.disabled }; + workspace.disabled = disabled; + $("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled); + $("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled); + var historyEvent = { + t: "edit", + changes:changes, + node: workspace, + dirty: RED.nodes.dirty() + } + workspace.changed = true; + RED.history.push(historyEvent); + RED.nodes.dirty(true); + RED.sidebar.config.refresh(); + var selection = RED.view.selection(); + if (!selection.nodes && !selection.links) { + RED.sidebar.info.refresh(workspace); + } + if (changes.hasOwnProperty('disabled')) { + RED.nodes.eachNode(function(n) { + if (n.z === workspace.id) { + n.dirty = true; + } + }); + RED.view.redraw(); + } + } + } + + + function removeWorkspace(ws) { + if (!ws) { + deleteWorkspace(RED.nodes.workspace(activeWorkspace)); + } else { + if (workspace_tabs.contains(ws.id)) { + workspace_tabs.removeTab(ws.id); + } + if (ws.id === activeWorkspace) { + activeWorkspace = 0; + } + } + } + + function setWorkspaceOrder(order) { + RED.nodes.setWorkspaceOrder(order.filter(function(id) { + return RED.nodes.workspace(id) !== undefined; + })); + workspace_tabs.order(order); + } + + return { + init: init, + add: addWorkspace, + remove: removeWorkspace, + order: setWorkspaceOrder, + edit: editWorkspace, + contains: function(id) { + return workspace_tabs.contains(id); + }, + count: function() { + return workspaceTabCount; + }, + active: function() { + return activeWorkspace + }, + selection: function() { + return workspace_tabs.selection(); + }, + show: function(id) { + if (!workspace_tabs.contains(id)) { + var sf = RED.nodes.subflow(id); + if (sf) { + addWorkspace({type:"subflow",id:id,icon:"red/images/subflow_tab.svg",label:sf.name, closeable: true}); + } else { + return; + } + } + workspace_tabs.activateTab(id); + }, + refresh: function() { + RED.nodes.eachWorkspace(function(ws) { + workspace_tabs.renameTab(ws.id,ws.label); + + }) + RED.nodes.eachSubflow(function(sf) { + if (workspace_tabs.contains(sf.id)) { + workspace_tabs.renameTab(sf.id,sf.name); + } + }); + RED.sidebar.config.refresh(); + }, + resize: function() { + workspace_tabs.resize(); + }, + enable: enableWorkspace, + disable: disableWorkspace + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/user.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/user.js new file mode 100644 index 0000000..485670e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/user.js @@ -0,0 +1,300 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.user = (function() { + + function login(opts,done) { + if (typeof opts == 'function') { + done = opts; + opts = {}; + } + + var dialog = $('<div id="node-dialog-login" class="hide">'+ + '<div style="display: inline-block;width: 250px; vertical-align: top; margin-right: 10px; margin-bottom: 20px;"><img id="node-dialog-login-image" src=""/></div>'+ + '<div style="display: inline-block; width: 250px; vertical-align: bottom; margin-left: 10px; margin-bottom: 20px;">'+ + '<form id="node-dialog-login-fields" class="form-horizontal" style="margin-bottom: 0px;"></form>'+ + '</div>'+ + '</div>'); + + dialog.dialog({ + autoOpen: false, + classes: { + "ui-dialog": "red-ui-editor-dialog", + "ui-dialog-titlebar-close": "hide", + "ui-widget-overlay": "red-ui-editor-dialog" + }, + modal: true, + closeOnEscape: !!opts.cancelable, + width: 600, + resizable: false, + draggable: false + }); + + $("#node-dialog-login-fields").empty(); + $.ajax({ + dataType: "json", + url: "auth/login", + success: function(data) { + var i=0; + + if (data.type == "credentials") { + + for (;i<data.prompts.length;i++) { + var field = data.prompts[i]; + var row = $("<div/>",{class:"form-row"}); + $('<label for="node-dialog-login-'+field.id+'">'+RED._(field.label)+':</label><br/>').appendTo(row); + var input = $('<input style="width: 100%" id="node-dialog-login-'+field.id+'" type="'+field.type+'" tabIndex="'+(i+1)+'"/>').appendTo(row); + + if (i<data.prompts.length-1) { + input.keypress( + (function() { + var r = row; + return function(event) { + if (event.keyCode == 13) { + r.next("div").find("input").trigger("focus"); + event.preventDefault(); + } + } + })() + ); + } + row.appendTo("#node-dialog-login-fields"); + } + $('<div class="form-row" style="text-align: right; margin-top: 10px;"><span id="node-dialog-login-failed" style="line-height: 2em;float:left;" class="hide">'+RED._("user.loginFailed")+'</span><img src="red/images/spin.svg" style="height: 30px; margin-right: 10px; " class="login-spinner hide"/>'+ + (opts.cancelable?'<a href="#" id="node-dialog-login-cancel" class="red-ui-button" style="margin-right: 20px;" tabIndex="'+(i+1)+'">'+RED._("common.label.cancel")+'</a>':'')+ + '<input type="submit" id="node-dialog-login-submit" class="red-ui-button" style="width: auto;" tabIndex="'+(i+2)+'" value="'+RED._("user.login")+'"></div>').appendTo("#node-dialog-login-fields"); + + + $("#node-dialog-login-submit").button(); + $("#node-dialog-login-fields").on("submit", function(event) { + $("#node-dialog-login-submit").button("option","disabled",true); + $("#node-dialog-login-failed").hide(); + $(".login-spinner").show(); + + var body = { + client_id: "node-red-editor", + grant_type: "password", + scope:"" + } + for (var i=0;i<data.prompts.length;i++) { + var field = data.prompts[i]; + body[field.id] = $("#node-dialog-login-"+field.id).val(); + } + $.ajax({ + url:"auth/token", + type: "POST", + data: body + }).done(function(data,textStatus,xhr) { + RED.settings.set("auth-tokens",data); + $("#node-dialog-login").dialog('destroy').remove(); + if (opts.updateMenu) { + updateUserMenu(); + } + done(); + }).fail(function(jqXHR,textStatus,errorThrown) { + RED.settings.remove("auth-tokens"); + $("#node-dialog-login-failed").show(); + }).always(function() { + $("#node-dialog-login-submit").button("option","disabled",false); + $(".login-spinner").hide(); + }); + event.preventDefault(); + }); + + } else if (data.type == "strategy") { + i = 0; + for (;i<data.prompts.length;i++) { + var field = data.prompts[i]; + var row = $("<div/>",{class:"form-row",style:"text-align: center"}).appendTo("#node-dialog-login-fields"); + + var loginButton = $('<a href="#" class="red-ui-button"></a>',{style: "padding: 10px"}).appendTo(row).on("click", function() { + document.location = field.url; + }); + if (field.image) { + $("<img>",{src:field.image}).appendTo(loginButton); + } else if (field.label) { + var label = $('<span></span>').text(field.label); + if (field.icon) { + $('<i></i>',{class: "fa fa-2x "+field.icon, style:"vertical-align: middle"}).appendTo(loginButton); + label.css({ + "verticalAlign":"middle", + "marginLeft":"8px" + }); + + } + label.appendTo(loginButton); + } + loginButton.button(); + } + + + } + if (opts.cancelable) { + $("#node-dialog-login-cancel").button().on("click", function( event ) { + $("#node-dialog-login").dialog('destroy').remove(); + }); + } + + var loginImageSrc = data.image || "red/images/node-red-256.png"; + + $("#node-dialog-login-image").load(function() { + dialog.dialog("open"); + }).attr("src",loginImageSrc); + + + } + }); + } + + function logout() { + var tokens = RED.settings.get("auth-tokens"); + var token = tokens?tokens.access_token:""; + $.ajax({ + url: "auth/revoke", + type: "POST", + data: {token:token} + }).done(function(data,textStatus,xhr) { + RED.settings.remove("auth-tokens"); + if (data && data.redirect) { + document.location.href = data.redirect; + } else { + document.location.reload(true); + } + }).fail(function(jqXHR,textStatus,errorThrown) { + if (jqXHR.status === 401) { + document.location.reload(true); + } else { + console.log(textStatus); + } + }) + } + + function updateUserMenu() { + $("#red-ui-header-button-user-submenu li").remove(); + if (RED.settings.user.anonymous) { + RED.menu.addItem("red-ui-header-button-user",{ + id:"usermenu-item-login", + label:RED._("menu.label.login"), + onselect: function() { + RED.user.login({cancelable:true},function() { + RED.settings.load(function() { + RED.notify(RED._("user.loggedInAs",{name:RED.settings.user.username}),"success"); + updateUserMenu(); + RED.events.emit("login",RED.settings.user.username); + }); + }); + } + }); + } else { + RED.menu.addItem("red-ui-header-button-user",{ + id:"usermenu-item-username", + label:"<b>"+RED.settings.user.username+"</b>" + }); + RED.menu.addItem("red-ui-header-button-user",{ + id:"usermenu-item-logout", + label:RED._("menu.label.logout"), + onselect: function() { + RED.user.logout(); + } + }); + } + + } + + function init() { + if (RED.settings.user) { + if (!RED.settings.editorTheme || !RED.settings.editorTheme.hasOwnProperty("userMenu")) { + + var userMenu = $('<li><a id="red-ui-header-button-user" class="button hide" href="#"></a></li>') + .prependTo(".red-ui-header-toolbar"); + if (RED.settings.user.image) { + $('<span class="user-profile"></span>').css({ + backgroundImage: "url("+RED.settings.user.image+")", + }).appendTo(userMenu.find("a")); + } else { + $('<i class="fa fa-user"></i>').appendTo(userMenu.find("a")); + } + + RED.menu.init({id:"red-ui-header-button-user", + options: [] + }); + updateUserMenu(); + } + } + + } + + var readRE = /^((.+)\.)?read$/ + var writeRE = /^((.+)\.)?write$/ + + function hasPermission(permission) { + if (permission === "") { + return true; + } + if (!RED.settings.user) { + return true; + } + return checkPermission(RED.settings.user.permissions||"",permission); + } + function checkPermission(userScope,permission) { + if (permission === "") { + return true; + } + var i; + + if (Array.isArray(permission)) { + // Multiple permissions requested - check each one + for (i=0;i<permission.length;i++) { + if (!checkPermission(userScope,permission[i])) { + return false; + } + } + // All permissions check out + return true; + } + + if (Array.isArray(userScope)) { + if (userScope.length === 0) { + return false; + } + for (i=0;i<userScope.length;i++) { + if (checkPermission(userScope[i],permission)) { + return true; + } + } + return false; + } + + if (userScope === "*" || userScope === permission) { + return true; + } + + if (userScope === "read" || userScope === "*.read") { + return readRE.test(permission); + } else if (userScope === "write" || userScope === "*.write") { + return writeRE.test(permission); + } + return false; + } + + + return { + init: init, + login: login, + logout: logout, + hasPermission: hasPermission + } + +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/js/validators.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/validators.js new file mode 100644 index 0000000..833472b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/js/validators.js @@ -0,0 +1,35 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +RED.validators = { + number: function(blankAllowed){return function(v) { return (blankAllowed&&(v===''||v===undefined)) || (v!=='' && !isNaN(v));}}, + regex: function(re){return function(v) { return re.test(v);}}, + typedInput: function(ptypeName,isConfig) { return function(v) { + var ptype = $("#node-"+(isConfig?"config-":"")+"input-"+ptypeName).val() || this[ptypeName]; + if (ptype === 'json') { + try { + JSON.parse(v); + return true; + } catch(err) { + return false; + } + } else if (ptype === 'msg' || ptype === 'flow' || ptype === 'global' ) { + return RED.utils.validatePropertyExpression(v); + } else if (ptype === 'num') { + return /^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$/.test(v); + } + return true; + }} +}; diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ace.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ace.scss new file mode 100644 index 0000000..fb6eaf8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ace.scss @@ -0,0 +1,72 @@ +.red-ui-editor, .red-ui-editor-dialog { + + .ace_read-only { + .ace_scroller { + background: $text-editor-background-disabled; + color: $text-editor-color-disabled; + } + .ace_cursor { + color: transparent !important; + } + } + + + .ace_gutter { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + } + .ace_scroller { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + } + + .ace_scroller { + background: $text-editor-background; + color: $text-editor-color; + } + .ace_marker-layer .ace_active-line { + background: $text-editor-active-line-background; + } + .ace_marker-layer .ace_selection { + background: $text-editor-selection-background; + border-radius: 1px; + } + .ace_gutter-cell { + color: $text-editor-color; + } + .ace_gutter-active-line { + background: $text-editor-gutter-active-line-background; + } + .ace_gutter { + background: $text-editor-gutter-background; + } + .ace_tooltip { + font-family: $primary-font; + line-height: 1.4em; + max-width: 400px; + white-space: normal; + background-image: none; + background: $popover-background; + color: $popover-color; + border-radius: 4px; + @include component-shadow; + border-color: $popover-background; + } + textarea.ace_text-input { + overflow: hidden; + padding: 0px 1px !important; + } + + #red-ui-event-log-editor { + .ace_scroller { + background: $event-log-background; + color: $event-log-color; + } + .ace_marker-layer .ace_active-line { + background: $event-log-active-line-background; + } + .ace_marker-layer .ace_selection { + background: $event-log-selection-background; + } + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/base.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/base.scss new file mode 100644 index 0000000..2aca0b8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/base.scss @@ -0,0 +1,263 @@ +/** +* Copyright JS Foundation and other contributors, http://js.foundation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + + + +.red-ui-editor { + font-size: $primary-font-size; + font-family: $primary-font; + padding: 0; + margin: 0; + background: $primary-background; + color: $primary-text-color; + line-height: 20px; +} + +#red-ui-editor { + position: absolute; + top: 0; left: 0; bottom: 0; right: 0; +} +#red-ui-editor-node-configs { + display: none; +} +#red-ui-main-container { + position: absolute; + top:40px; left:0; bottom: 0; right:0; + overflow:hidden; +} + +#red-ui-palette-shade, #red-ui-editor-shade, #red-ui-header-shade, #red-ui-sidebar-shade { + @include shade; + z-index: 2; +} +#red-ui-sidebar-shade { + left: -8px; + top: -1px; + bottom: -1px; +} +#red-ui-full-shade { + @include shade; + z-index: 15; +} +.red-ui-editor, +.red-ui-editor-dialog, +.red-ui-menu, +.red-ui-popover, +.red-ui-typedInput-options, +.red-ui-icon-picker { + a { + text-decoration: none; + color: $primary-text-color; + } + a:hover, + a:focus { + text-decoration: none; + color: $primary-text-color; + } + + p { + margin: 0 0 10px; + } + + small { + font-size: 85%; + } + + strong { + font-weight: bold; + } + + em { + font-style: italic; + } + + cite { + font-style: normal; + } + + ul, + ol { + padding: 0; + margin: 0 0 10px 25px; + } + + ul ul, + ul ol, + ol ol, + ol ul { + margin-bottom: 0; + } + + li { + line-height: 20px; + } + dl { + margin-bottom: 20px; + } + + dt, + dd { + line-height: 20px; + } + + dt { + font-weight: bold; + } + + dd { + margin-left: 10px; + } + + hr { + margin: 20px 0; + border: 0; + border-top: 1px solid $tertiary-border-color; + } + + + + i.spinner { + display: inline-block; + width: 14px; + height: 14px; + line-height: 14px; + vertical-align: text-top; + margin-top: 0px; + background: url(images/spin.svg) no-repeat 50% 50%; + background-size: contain + } + + code { + font-family: $monospace-font; + font-size: $primary-font-size; + padding: 0px; + margin: 1px; + color: $info-text-code-color; + white-space: nowrap; + } + + pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + line-height: 20px; + word-break: break-all; + word-wrap: break-word; + white-space: pre-wrap; + background-color:$tertiary-background; + border: 1px solid $tertiary-border-color; + border-radius: 2px; + } + + pre code { + padding: 0; + color: inherit; + white-space: pre; + white-space: pre-wrap; + background-color: transparent; + border: 0; + } + + .pull-right { + float: right; + } + + .pull-left { + float: left; + } + .hide { + display: none; + } + .show { + display: block; + } + + img { + width: auto\9; + height: auto; + max-width: 100%; + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; + } + + blockquote { + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 4px solid $secondary-border-color; + color: $secondary-text-color; + + p { + font-size: 14px; + font-weight: inherit; + line-height: 1.25; + margin-bottom: 0; + } + } + + table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; + } +} + +.red-ui-component-spinner { + position: absolute; + top: 1px; + bottom: 1px; + left: 1px; + right: 1px; + text-align: center; + padding: 40px; + background: $secondary-background; + &:before { + content: ''; + display: inline-block; + height: 100%; + vertical-align: middle; + margin-right: -0.25em; + } + img { + display: inline-block; + vertical-align: middle; + width: 80px; + } + &.red-ui-component-spinner-sidebar { + background: $secondary-background; + padding:0; + img { + width: 40px; + } + } + &.projects-version-control-spinner-sidebar { + background: $secondary-background; + padding:0; + img { + width: 20px; + } + } + + &.red-ui-component-spinner-contain { + padding: 0; + img { + width: auto; + height: 100%; + max-height: 50px; + } + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/colors.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/colors.scss new file mode 100644 index 0000000..8411343 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/colors.scss @@ -0,0 +1,286 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +$primary-font: 'Helvetica Neue', Arial, Helvetica, sans-serif; +$primary-font-size: 14px; +$monospace-font: Menlo, Consolas, 'DejaVu Sans Mono', Courier, monospace; + +$primary-background: #f3f3f3;//#0ff; + +$secondary-background: #fff;//#ff0; +$secondary-background-selected: #efefef;//#e9e900; +$secondary-background-inactive: #f0f0f0;//#f0f000; +$secondary-background-hover: #ddd;//#dd0; +$secondary-background-disabled: #f9f9f9;//#fafa0; + +$tertiary-background: #f7f7f7;//#f0f; + +$shadow: rgba(0, 0, 0, 0.2); + +// Main body text +$primary-text-color: #555;//#0f0; +// UI control label text +$secondary-text-color: #888;//#00f; +$secondary-text-color-focus: #666;//#009; +$secondary-text-color-hover: #666;//#006; +$secondary-text-color-active: #666;//#006; +$secondary-text-color-selected: #666;//#00A; +$secondary-text-color-inactive: #666;//#006; +$secondary-text-color-disabled: #bbb;//#00C; +$secondary-text-color-disabled-active: #999;//#009; +$secondary-text-color-disabled-inactive: #aaa;//#00A; + +// Sub label text +$tertiary-text-color: #aaa;//#90f; +// Heading text +$header-text-color: #444;//#f00; + +$text-color-warning: #AD1625; +$text-color-green: #3a3; + +$primary-border-color: #bbbbbb;//#f00; +$secondary-border-color: #dddddd;//#0f0; +$tertiary-border-color: #ccc;//#00f; + +$form-background: $secondary-background; + +$form-placeholder-color: $tertiary-text-color; +$form-text-color: $primary-text-color; +$form-text-color-disabled: $secondary-text-color-disabled; +$form-input-focus-color: rgba(85,150,230,0.8); +$form-input-border-color: $tertiary-border-color; +$form-input-border-selected-color: #aaa;//#f0f; +$form-input-border-error-color: rgb(214, 97, 95); +$form-input-background: $secondary-background; +$form-input-background-disabled: $secondary-background-disabled; +$form-button-background: $secondary-background-selected; + +$form-tips-background: #ffe; + + +$text-editor-color: #4D4D4C;//#00f; +$text-editor-background: $secondary-background; +$text-editor-color-disabled: $secondary-text-color-inactive; +$text-editor-background-disabled: $secondary-background-disabled; +$text-editor-gutter-background: #f6f6f6;//#ee0; +$text-editor-gutter-color: #777;//#00e; +$text-editor-gutter-active-line-background: #dcdcdc;//#dd0; +$text-editor-active-line-background: #efefef;//#ee0; +$text-editor-selection-background: #D6D6D6;//#e0e; + +$event-log-background: #444; +$event-log-color: #dd9; +$event-log-active-line-background: #333; +$event-log-selection-background: #999; + + + + +$list-item-color: $primary-text-color; +$list-item-secondary-color: $secondary-text-color; +$list-item-background: $secondary-background; +$list-item-background-disabled: $secondary-background-inactive; +$list-item-background-hover: $secondary-background-hover; +$list-item-background-selected: $secondary-background-selected; +$list-item-border-selected: $secondary-text-color-selected; + +$tab-text-color-active: $header-text-color; +$tab-text-color-inactive: $secondary-text-color-inactive; +$tab-text-color-disabled-active: $secondary-text-color-disabled-active; +$tab-text-color-disabled-inactive: $secondary-text-color-disabled-inactive; + +$tab-badge-color: $tertiary-text-color; +$tab-background: $secondary-background; +$tab-background-active: $secondary-background; +$tab-background-selected: $secondary-background-selected; +$tab-background-inactive: $secondary-background-inactive; +$tab-background-hover: $secondary-background-hover; + +$palette-header-background: $primary-background; +$palette-header-color: $header-text-color; +$palette-content-background: $secondary-background; + + +$workspace-button-background: $secondary-background; +$workspace-button-background-hover: $secondary-background-hover; +$workspace-button-background-active: $secondary-background-selected; + +$workspace-button-color: $secondary-text-color; +$workspace-button-color-disabled: $secondary-text-color-disabled; +$workspace-button-color-focus: $secondary-text-color-focus; +$workspace-button-color-hover: $secondary-text-color-hover; +$workspace-button-color-active: $secondary-text-color-active; +$workspace-button-color-selected: $secondary-text-color-selected; + +$workspace-button-color-primary: #eee; +$workspace-button-background-primary: #AD1625; +$workspace-button-background-primary-hover: #6E0A1E; + +$workspace-button-color-focus-outline: $form-input-border-color; + +$shade-color: rgba(160,160,160,0.5); + + +$popover-background: #333; +$popover-color: #eee; +$popover-button-border-color: #bbb; +$popover-button-border-color-hover: #666; + + + +$diff-text-header-color: $secondary-text-color; +$diff-text-header-background: #ffd; +$diff-text-header-background-hover: #ffc; +$diff-state-added: #009900; +$diff-state-deleted: #f80000; +$diff-state-changed: #f89406; +$diff-state-changed-background: #fff2e1; +$diff-state-unchanged: #bbb; +$diff-state-unchanged-background: #fff; + +$diff-state-conflicted: purple; +$diff-state-moved: #3f81b3; +$diff-state-conflict: #9b45ce; +$diff-state-conflict-background: #ffdad4; + +$diff-state-added-background: #e7ffe3; +$diff-state-added-border: #b8daad; +$diff-state-added-header-background: #c0f6c0; +$diff-state-added-header-border: #aaeeaa; + +$diff-state-deleted-background: #ffe1e1; +$diff-state-deleted-border: #e4bcbc; +$diff-state-deleted-header-background: #ffcccc; +$diff-state-deleted-header-border: #eebbbb; + +$diff-merge-header-color: #800080; +$diff-merge-header-background: #e5f9ff; +$diff-merge-header-border-color: #b2edff; + +$menuBackground: $primary-background; +$menuDivider: $secondary-border-color; +$menuColor: $primary-text-color; +$menuActiveColor: $secondary-text-color-active; +$menuActiveBackground: $secondary-background-hover; +$menuDisabledColor: $secondary-text-color-disabled; +$menuHoverColor: $secondary-text-color-hover; +$menuHoverBackground: $secondary-background-hover; +$menuCaret: $tertiary-text-color; + +$view-navigator-background: rgba(245,245,245,0.8); + +$view-lasso-stroke: #ff7f0e; +$view-lasso-fill: rgba(20,125,255,0.1); + +$view-background: $secondary-background; +$view-select-mode-background: $secondary-background-selected; +$view-grid-color: #eee; + +$node-label-color: #333; +$node-border: #999; +$node-border-unknown: #f33; +$node-border-placeholder: #aaa; +$node-background-placeholder: #eee; + +$node-port-background: #d9d9d9; +$node-port-background-hover: #eee; +$node-icon-color: #fff; +$node-icon-background-color: rgba(0,0,0,0.05); +$node-icon-background-color-fill: #000; +$node-icon-background-color-opacity: 0.05; +$node-icon-border-color: #000; +$node-icon-border-color-opacity: 0.1; + + +$node-link-port-background: #eee; + +$node-status-error-border: rgb(145, 16, 2); +$node-status-error-background: rgb(255, 102, 0); +$node-status-changed-border: rgb(28, 102, 140); +$node-status-changed-background: rgb(0, 188, 255); + +$node-status-colors: ( + red: #c00, + green: #5a8, + yellow: #F9DF31, + blue: #53A3F3, + grey: #d3d3d3 +); + + +$node-selected-color: #ff7f0e; +$port-selected-color: #ff7f0e; + +$link-color: #999; +$link-link-color: #aaa; +$link-disabled-color: #ccc; +$link-link-active-color: #ff7f0e; +$link-unknown-color: #f00; + +$clipboard-textarea-background: #F3E7E7; + + +$deploy-button-color: #eee; +$deploy-button-color-active: #ccc; +$deploy-button-color-disabled: #999; +$deploy-button-background: #8C101C; +$deploy-button-background-hover: #6E0A1E; +$deploy-button-background-active: #4C0A17; +$deploy-button-background-disabled: #444; +$deploy-button-background-disabled-hover: #555; + + +$header-background: #000; +$header-button-background-active: #121212; +$header-menu-color: #C7C7C7; +$header-menu-color-disabled: #666; +$header-menu-heading-color: #fff; +$header-menu-sublabel-color: #aeaeae; +$header-menu-background: #121212; +$header-menu-item-hover: #323232; +$header-menu-item-border-active: #777677; +$headerMenuItemDivider: #464646; +$headerMenuCaret: #C7C7C7; + +$vcCommitShaColor: #c38888; + +$info-text-code-color: #AD1625; +$info-text-link-color: #0088cc; + +$dnd-background: rgba(0,0,0,0.3); +$dnd-color: #fff; + +$notification-border-default: #325C80; +$notification-border-success: #4B8400; +$notification-border-warning: #D74108; +$notification-border-error: $text-color-warning; + +$debug-message-background: $secondary-background; +$debug-message-background-hover: $secondary-background-selected; + +$debug-message-text-color: #333; +$debug-message-text-color-meta: #a66; +$debug-message-text-color-object-key: #792e90; +$debug-message-text-color-msg-type-other: #2033d6; +$debug-message-text-color-msg-type-string: #b72828; +$debug-message-text-color-msg-type-null: #666; +$debug-message-text-color-msg-type-meta: #666; +$debug-message-text-color-msg-type-number: #2033d6; + +$debug-message-border: #eee; +$debug-message-border-hover: #999; +$debug-message-border-warning: #ffdf9d; +$debug-message-border-error: #f99; diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/debug.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/debug.scss new file mode 100644 index 0000000..c92c433 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/debug.scss @@ -0,0 +1,252 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +.red-ui-debug-window { + padding:0; + margin:0; + background: $secondary-background; + line-height: 20px; + .red-ui-debug-msg-payload { + font-size: 14px; + } +} + +.red-ui-debug-content { + position: absolute; + top: 43px; + bottom: 0px; + left:0px; + right: 0px; + overflow-y: scroll; +} +.red-ui-debug-filter-box { + position:absolute; + top: 42px; + left: 0px; + right: 0px; + z-index: 20; + background: $tertiary-background; + padding: 10px; + border-bottom: 1px solid $secondary-border-color; + box-shadow: 0 2px 6px $shadow; +} +.red-ui-debug-filter-row { + .red-ui-nodeList { + margin: 10px 0; + } +} + +.red-ui-debug-msg { + position: relative; + border-bottom: 1px solid $debug-message-border; + border-left: 8px solid $debug-message-border; + border-right: 8px solid $debug-message-border; + padding: 2px; + &>.red-ui-debug-msg-meta .red-ui-debug-msg-tools { + display: none; + } + + &.red-ui-debug-msg-hover { + border-right-color: $debug-message-border-hover; + &>.red-ui-debug-msg-meta .red-ui-debug-msg-tools { + display: inline-block; + } + } +} +.red-ui-debug-msg-row { + .red-ui-debug-msg-tools-pin { + display: none; + } + &.red-ui-debug-msg-row-pinned .red-ui-debug-msg-tools-pin { + display: inline-block; + } + &:hover { + background: $debug-message-background-hover; + &>.red-ui-debug-msg-tools { + .red-ui-debug-msg-tools-copy { + display: inline-block; + } + .red-ui-debug-msg-tools-pin { + display: inline-block; + } + .red-ui-debug-msg-tools-other { + display: inline-block; + } + } + } +} +.red-ui-debug-msg-meta .red-ui-debug-msg-tools { + .red-ui-button-small { + font-size: 11px; + } +} +.red-ui-debug-msg-tools { + .button-group:not(:last-child) { + margin-right: 3px; + } + .red-ui-button-small { + height: 16px; + line-height: 14px; + font-size: 8px; + border-radius: 1px; + padding: 0 3px; + min-width: 18px; + } +} + +.red-ui-debug-msg-meta { + background: $debug-message-background; + font-size: 11px; + color: $secondary-text-color-inactive; +} +.red-ui-debug-msg-date { + padding: 1px 5px 1px 1px; +} +.red-ui-debug-msg-topic { + display: block; + color: $debug-message-text-color-meta; +} +.red-ui-debug-msg-name { + padding: 1px 5px; + color: $secondary-text-color-inactive; +} +.red-ui-debug-msg-tools { + position: absolute; + top: 3px; + right: 1px; + .red-ui-debug-msg-tools-copy { + display: none; + } + .red-ui-debug-msg-tools-other { + display: none; + } +} +.red-ui-debug-msg-payload { + display: block; + padding: 2px; + background: $debug-message-background; + font-family: $monospace-font; + font-size: 13px !important; +} +.red-ui-debug-msg-level-log { + border-left-color: $debug-message-border; + border-right-color: $debug-message-border; +} +.red-ui-debug-msg-level-30 { + border-left-color: $debug-message-border-warning; + border-right-color: $debug-message-border-warning; +} +.red-ui-debug-msg-level-20 { + border-left-color: $debug-message-border-error; + border-right-color: $debug-message-border-error; +} +.red-ui-debug-msg-object-entry { + position: relative; + padding-left: 15px; +} +.red-ui-debug-msg-element { + color: $debug-message-text-color; + line-height: 1.3em; + overflow-wrap: break-word; +} +.red-ui-debug-msg-object-key { + color: $debug-message-text-color-object-key; +} +.red-ui-debug-msg-object-value { + +} +.red-ui-debug-msg-object-handle { + color: $secondary-text-color; + font-size: 1em; + width: 1em; + text-align: center; + transition: transform 0.1s ease-in-out; + transform: rotate(90deg); +} +.red-ui-debug-msg-element:not(.red-ui-debug-msg-top-level)>.red-ui-debug-msg-expandable>.red-ui-debug-msg-object-handle { + margin-left: -1em; +} +.red-ui-debug-msg-object-entry>.red-ui-debug-msg-expandable>.red-ui-debug-msg-object-handle { + margin-left: -1em; +} +.red-ui-debug-msg-object-entry.collapsed>span>.red-ui-debug-msg-object-handle { + transform: rotate(0deg); +} +.red-ui-debug-msg-element.collapsed>span>.red-ui-debug-msg-object-handle { + transform: rotate(0deg); +} +.red-ui-debug-msg-object-entry.collapsed > .red-ui-debug-msg-object-entry { + display:none; +} +.red-ui-debug-msg-element.collapsed .red-ui-debug-msg-object-entry { + display:none; +} +.red-ui-debug-msg-element:not(.collapsed)>.red-ui-debug-msg-expandable>.red-ui-debug-msg-object-value>.red-ui-debug-msg-object-header { + display:none; +} +.red-ui-debug-msg-element.collapsed .red-ui-debug-msg-buffer-opts { + display: none; +} +.red-ui-debug-msg-element.collapsed .red-ui-debug-msg-object-type-header { + display:none; +} +.red-ui-debug-msg-object-entry pre { + font-family: $monospace-font; + font-size: 13px; + line-height: 1.2em; + margin: 0 0 0 -1em; +} + +.red-ui-debug-msg-type-other { color: $debug-message-text-color-msg-type-other; } +.red-ui-debug-msg-type-string { color: $debug-message-text-color-msg-type-string; } +.red-ui-debug-msg-type-null { color: $debug-message-text-color-msg-type-null; font-style: italic;} +.red-ui-debug-msg-type-meta { color: $debug-message-text-color-msg-type-meta; font-style: italic;} +.red-ui-debug-msg-type-number { color: $debug-message-text-color-msg-type-number; }; +.red-ui-debug-msg-type-number-toggle { cursor: pointer;} + +.red-ui-debug-msg-row { + display: block; + padding: 4px 2px 2px; + position: relative; + &.red-ui-debug-msg-row-pinned { + background: $secondary-background-selected; + } +} +.red-ui-debug-msg-expandable { + cursor: pointer; +} +.red-ui-debug-msg-expandable:hover .red-ui-debug-msg-object-handle { + color:$secondary-text-color-hover; +} + +.red-ui-debug-msg-buffer-opts { + margin-left: 5px; +} + +.red-ui-debug-msg-buffer-raw > .red-ui-debug-msg-string-rows { + display: none; +} +.red-ui-debug-msg-buffer-string > .red-ui-debug-msg-array-rows { + display: none; +} +.red-ui-debug-msg-type-string-swatch { + display: inline-block; + width: 1.1em; + height: 0.9em; + vertical-align: middle; + border-radius: 3px; + margin: 0 4px; +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/diff.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/diff.scss new file mode 100644 index 0000000..a8b16ca --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/diff.scss @@ -0,0 +1,669 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +.red-ui-diff-panel { + padding: 5px; + padding-top: 30px; + position: relative; + + .red-ui-editableList-container { + border-radius:1px; + padding:0; + background: $tertiary-background; + } + .red-ui-diff-list { + li { + background: $tertiary-background; + padding: 0px; + border: none; + min-height: 0; + } + } + .red-ui-editableList-item-content { + padding: 5px; + // padding-bottom: 5px; + } +} +.red-ui-diff-container { + position: absolute; + top: 40px; + right:0; + bottom: 0; + left: 0; + overflow-y: scroll; +} + +.red-ui-diff-panel-headers { + position: absolute; + left:232px; + right:12px; + top: 5px; + height: 25px; + div { + height: 25px; + display: inline-block; + box-sizing: border-box; + padding-top: 2px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + width: 50%; + background: $tertiary-background; + text-align: center; + border-top: 1px solid $secondary-border-color; + border-color:$secondary-border-color; + border-left: 1px solid $secondary-border-color; + } + div:last-child { + border-right: 1px solid $secondary-border-color; + } +} + +.red-ui-diff-dialog-toolbar { + box-sizing: border-box; + color: $secondary-text-color; + text-align: right; + padding: 8px 10px; + background: $primary-background; + border-bottom: 1px solid $secondary-border-color; + white-space: nowrap; +} +.red-ui-diff-list-flow { + background: $secondary-background; + border: 1px solid $secondary-border-color; + border-radius: 1px; + overflow: hidden; + + &.collapsed { + .red-ui-diff-list-flow-title .red-ui-diff-list-chevron { + transform: rotate(-90deg); + } + .red-ui-diff-list-node { + display: none; + } + } +} +.red-ui-diff-list-flow-stats { + font-size: 0.9em; +} + +.red-ui-diff-list-chevron { + display: inline-block; + width: 15px; + text-align: center; + margin-left: 3px; + transition: transform 0.1s ease-in-out; + +} +.red-ui-diff-list-node { + margin-left: 20px; + font-size: 0.9em; + + &:first-child { + border-top: 1px solid $tertiary-border-color; + } + &:not(:last-child) { + border-bottom: 1px solid $tertiary-border-color; + } + + &.collapsed { + .red-ui-diff-list-chevron { + transform: rotate(-90deg); + } + .red-ui-diff-list-node-properties { + display: none; + } + } + &:not(.collapsed) { + .red-ui-diff-list-node-cell:not(:first-child) { + //display: none; + } + .red-ui-diff-list-node-cell:first-child { + //width: 100% + } + } + + table { + border-collapse: collapse; + table-layout:fixed; + width: calc(100% - 20px); + margin-left: 20px; + } + col:first-child { + width: 180px; + } + col:not(:first-child) { + width: 100%; + } + td, th { + border-top: 1px solid $secondary-border-color; + border-left: 1px solid $secondary-border-color; + &:first-child { + border-left: none; + } + padding: 0 0 0 3px; + text-align: left; + overflow-x: auto; + } + tr { + vertical-align: top; + &:first-child td { + white-space:nowrap; + overflow:hidden; + } + &:hover { + background: $secondary-background-selected; + } + + } + + td { + .red-ui-diff-status { + margin-left: 0; + } + } + tr:not(.red-ui-diff-list-header) { + .red-ui-diff-status { + width: 12px; + margin-left: 0; + margin-top: 0; + margin-bottom: 0; + margin-right: 5px; + } + } +} +.red-ui-diff-three-way { + .red-ui-diff-list-node-cell { + width: calc((100% - 220px) / 2); + &:first-child { + width: 220px; + } + } + col:not(:first-child) { + width:50%; + } + + .red-ui-diff-list-node { + .red-ui-diff-list-node-cell { + width: calc((100% + 20px - 220px) / 2); + &:first-child { + width: 200px; + } + + } + } +} + +.red-ui-diff-list-flow-title { + cursor: pointer; + padding: 0; + &:hover { + background: $secondary-background-selected; + } +} +.red-ui-diff-list-flow-title-meta { + vertical-align: middle; + display: inline-block; + padding-top: 2px; +} +.red-ui-diff-list-node-header { + cursor: pointer; + &:hover { + background: $secondary-background-selected; + } +} +.red-ui-diff-list-node-icon { + vertical-align: middle; + display: inline-block; + margin: 5px; + width: 18px; + height: 15px; + background: $form-input-background; + border-radius: 2px; + border: 1px solid $node-border; + background-position: 5% 50%; + background-repeat: no-repeat; + background-size: contain; + position: relative; + + .red-ui-palette-icon { + background-position: 49% 50%; + width: 15px; + } + .red-ui-palette-icon-fa { + position: relative; + top: -2.5px; + left: 0px; + } + .red-ui-palette-icon-container { + width: 18px; + } +} +.red-ui-diff-list-flow-empty { + .red-ui-diff-list-chevron i { + display: none; + } + .red-ui-diff-list-flow-title { + cursor: default; + &:hover { + background: none; + } + } +} +.red-ui-diff-status-deleted { + cursor: default !important; + .red-ui-diff-status { + color: $diff-state-deleted; + } + .red-ui-diff-list-node-node { + opacity: 0.5; + } + .red-ui-diff-list-node-description { + opacity: 0.5; + text-decoration: line-through; + } +} +.red-ui-diff-status-added { + cursor: default !important; + .red-ui-diff-status { + color: $diff-state-added; + } +} +.red-ui-diff-status-moved { + .red-ui-diff-status { + color: $diff-state-moved; + } +} + +.red-ui-diff-status-changed { + .red-ui-diff-status { + color: $diff-state-changed; + } +} +.red-ui-diff-status-unchanged { + .red-ui-diff-status { + color: $diff-state-unchanged; + } +} +.red-ui-diff-status-conflict { + .red-ui-diff-status { + color: $diff-state-conflict; + } +} +.red-ui-diff-list-node-title { + display: inline-block; + .red-ui-diff-status { + margin-left: 15px; + } +} +.red-ui-diff-list-node-properties { + margin: 0; + color: $primary-text-color; +} +.red-ui-diff-status { + display: inline-block; + height: 20px; + margin-left: 5px; + vertical-align: top; + margin-top: 6px; + margin-bottom: 6px; + text-align: center; +} +.red-ui-diff-list-element { + display: inline-block; + width: calc(100% - 20px); +} + +.red-ui-diff-list-node-description { + color: $form-text-color; + margin-right: 5px; + padding-top: 5px; + display: inline-block; + &:after { + content: ""; + display: table; + clear: both; + } +} + +.red-ui-diff-state-added { color: $diff-state-added; } +.red-ui-diff-state-deleted { color: $diff-state-deleted; } +.red-ui-diff-state-changed { color: $diff-state-changed; } +.red-ui-diff-state-unchanged { color: $diff-state-unchanged; } +.red-ui-diff-state-conflicted { color: $diff-state-conflicted; } + + +.red-ui-diff-list-node-cell { + display: inline-block; + vertical-align: top; + box-sizing: border-box; + width: calc( (100% - 20px) / 2); + height: 32px; + border-left: 1px solid $secondary-border-color; + padding-top: 2px; + white-space: nowrap; + overflow: hidden; + position: relative; +} +.red-ui-diff-empty { + background: $secondary-background-disabled; + background: repeating-linear-gradient( + 20deg, + $secondary-background, $secondary-background 5px, + $secondary-background-disabled 5px, + $secondary-background-disabled 10px + ); +} +.red-ui-diff-list-node-cell:first-child { + border-left: none; +} +.red-ui-diff-list-cell-label { + margin-left: 20px; + vertical-align: top; + box-sizing: border-box; + padding-left: 8px; + width: 120px; +} +.red-ui-diff-list-wires { + display: inline-block; + .red-ui-diff-list-node-node { + width: 18px; + height: 15px; + } + .red-ui-palette-icon-container { + width: 18px; + } + .red-ui-palette-icon { + width: 15px; + } + ul,li,ol { + background: none !important; + } + ul { + vertical-align: middle; + display: inline-block; + margin-left: 5px; + } + li { + list-style-type: none !important; + } + ol { + font-size: 0.9em; + margin: 0; + & > span { + vertical-align: middle; + display: inline-block; + width: 30px; + text-align: center; + } + } + +} +.red-ui-diff-list-node-props .red-ui-diff-list-node-cell:first-child { + padding: 6px 0px; + span:not(.red-ui-diff-list-chevron) { + margin-left: 5px; + } + +} +.red-ui-diff-list-cell { + .red-ui-debug-msg-row:hover { + background: none; + } + &.red-ui-diff-status-changed { + background: $diff-state-changed-background; + } + &.red-ui-diff-status-conflict { + background: $diff-state-conflict-background; + } +} + +label.red-ui-diff-selectbox { + position: absolute; + top:0; + right:0; + bottom:0; + width: 35px; + text-align: center; + border-left: 1px solid $secondary-border-color; + margin:0; + input[type="radio"] { + margin-top: 8px; + } + + &:hover { + background: $secondary-background-hover; + } +} + +.red-ui-diff-list-node-conflict.red-ui-diff-select-remote { + .red-ui-diff-list-node-remote { + background: $diff-state-added-background; + label { + border-left-color: $diff-state-added-border; + } + } + .red-ui-diff-list-node-local { + background: $diff-state-deleted-background; + label { + border-left-color: $diff-state-deleted-border; + } + } +} +.red-ui-diff-list-node-conflict.red-ui-diff-select-local { + .red-ui-diff-list-node-local { + background: $diff-state-added-background; + label { + border-left-color: $diff-state-added-border; + } + } + .red-ui-diff-list-node-remote { + background: $diff-state-deleted-background; + label { + border-left-color: $diff-state-deleted-border; + } + } +} + + +ul.red-ui-deploy-dialog-confirm-list { + font-size: 0.9em; + width: 400px; + margin: 10px auto; + text-align: left; +} + +.red-ui-deploy-dialog-confirm-conflict-row { + img { + vertical-align:middle; + height: 30px; + margin-right: 10px; + } + i { + vertical-align:middle; + text-align: center; + font-size: 30px; + width: 30px; + margin-right: 10px; + &.fa-check { + color: $text-color-green; + } + &.fa-exclamation { + color: $secondary-text-color; + } + } + div { + vertical-align: middle; + width: calc(100% - 60px); + display:inline-block; + } +} + +#red-ui-diff-dialog-toolbar-resolved-conflicts .red-ui-diff-status { + margin:0; +} +.red-ui-diff-text-diff-button { + float: right; + margin: 2px 3px; + line-height: 14px; + height: 16px; + +} +.red-ui-diff-text { + height: 100%; + overflow-y:auto; + + table.red-ui-diff-text-content { + margin: 10px; + border: 1px solid $secondary-border-color; + border-radius: 3px; + table-layout: fixed; + width: calc(100% - 20px); + td { + vertical-align: top; + word-wrap: break-word; + } + td.lineno { + font-family: $monospace-font; + text-align: right; + color: $tertiary-text-color; + background: $tertiary-background; + padding: 1px 5px; + &.added { + background: $diff-state-added-header-background; + } + &.removed { + background: $diff-state-deleted-header-background; + } + } + td.lineno:nth-child(3) { + border-left: 1px solid $secondary-border-color; + } + td.linetext { + font-family: $monospace-font; + white-space: pre-wrap; + padding: 1px 5px; + border-left: 1px solid $tertiary-border-color; + span.prefix { + width: 30px; + display: inline-block; + text-align: center; + color: $secondary-text-color; + } + + &.added { + border-left-color: $diff-state-added-header-border; + } + &.removed { + border-left-color: $diff-state-deleted-header-border; + } + } + td.blank { + background: $tertiary-background; + } + td.added { + background: $diff-state-added-background; + } + td.removed { + background: $diff-state-deleted-background; + } + tr.mergeHeader td { + color: $diff-merge-header-color; + background: $diff-merge-header-background; + height: 26px; + vertical-align: middle; + } + tr.mergeHeader-separator td { + color: $diff-merge-header-color; + background: $diff-merge-header-border-color; + height: 0px; + } + tr.mergeHeader-ours td { + border-top: 2px solid $diff-merge-header-border-color; + } + tr.mergeHeader-theirs td { + border-bottom: 2px solid $diff-merge-header-border-color; + } + td.unchanged { + background: $diff-state-unchanged-background; + color: $diff-state-unchanged; + } + tr.unchanged { + background: $diff-state-unchanged-background; + } + tr.start-block { + border-top: 1px solid $secondary-border-color; + } + tr.end-block { + border-bottom: 1px solid $secondary-border-color; + } + tr.red-ui-diff-text-file-header td { + .filename { + font-family: $monospace-font; + } + background: $primary-background; + padding: 5px 10px 5px 0; + color: $primary-text-color; + cursor: pointer; + i.red-ui-diff-list-chevron { + width: 30px; + } + } + tr.red-ui-diff-text-file-header.collapsed { + td i.red-ui-diff-list-chevron { + transform: rotate(-90deg); + } + } + tr.red-ui-diff-text-commit-header td { + background: $primary-background; + padding: 5px 10px; + color: $primary-text-color; + h3 { + font-size: 1.4em; + margin: 0; + } + .commit-summary { + border-top: 1px solid $secondary-border-color; + padding-top: 5px; + color: $secondary-text-color; + } + .commit-body { + margin-bottom:15px; + white-space: pre; + line-height: 1.2em; + } + } + + tr.red-ui-diff-text-header > td:not(.red-ui-diff-flow-diff) { + font-family: $monospace-font; + padding: 5px 10px; + text-align: left; + color: $secondary-text-color; + background: $diff-text-header-background; + height: 30px; + vertical-align: middle; + border-top: 1px solid $secondary-border-color; + border-bottom: 1px solid $secondary-border-color; + } + tr.red-ui-diff-text-expand td { + cursor: pointer; + &:hover { + background: $diff-text-header-background; + } + } + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/dragdrop.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/dragdrop.scss new file mode 100644 index 0000000..1476cf8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/dragdrop.scss @@ -0,0 +1,39 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#red-ui-drop-target { + position: absolute; + top: 0; bottom: 0; + left: 0; right: 0; + background: $dnd-background; + display:table; + width: 100%; + height: 100%; + display: none; + z-index:100; + div { + pointer-events: none; + display: table-cell; + vertical-align: middle; + text-align: center; + font-size: 40px; + color: $dnd-color; + i { + pointer-events: none; + font-size: 80px; + } + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/dropdownMenu.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/dropdownMenu.scss new file mode 100644 index 0000000..6580945 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/dropdownMenu.scss @@ -0,0 +1,177 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +.red-ui-menu-dropdown { + font-family: $primary-font; + font-size: $primary-font-size; + position: absolute; + top: 100%; + width: 200px; + left: 0; + z-index: 1000; + display: none; + float: left; + margin: 2px 0 0; + margin-left: 0px !important; + padding: 5px 0; + list-style: none; + background: $menuBackground; + border: 1px solid $secondary-border-color; + box-shadow: 0 5px 10px $shadow; + + &.pull-right { + right: 0; + left: auto; + } + + .red-ui-menu-divider { + height: 1px; + margin: 9px 1px; + overflow: hidden; + background-color: $menuDivider; + } + & > li > a, + & > li > a:focus { + display: block; + padding: 4px 0 4px 32px; + clear: both; + font-weight: normal; + line-height: 20px; + color: $menuColor; + white-space: normal !important; + outline: none; + } + + & > .active > a, + & > .active > a:hover, + & > .active > a:focus { + color: $menuActiveColor; + text-decoration: none; + background-color: $menuActiveBackground; + outline: 0; + } + + & > .disabled > a, + & > .disabled > a:hover, + & > .disabled > a:focus { + color: $menuDisabledColor; + } + + & > .disabled > a:hover, + & > .disabled > a:focus { + text-decoration: none; + cursor: default; + background-color: transparent; + background-image: none; + } + + a { + img { + max-width: 14px; + } + .fa { + width: 20px; + margin-left: -25px; + margin-top: 3px; + text-align: center; + } + .fa-check-square { + display: none; + } + .fa-square { + display: inline-block; + } + &.active { + .fa-check-square { + display: inline-block; + } + .fa-square { + display: none; + } + } + } + +} + +.pull-right > .red-ui-menu-dropdown { + right: 0; + left: auto; +} + + +.red-ui-menu-dropdown > li > a:hover, +.red-ui-menu-dropdown > li > a:focus, +.red-ui-menu-dropdown-submenu:hover > a, +.red-ui-menu-dropdown-submenu:focus > a { + color: $menuHoverColor; + text-decoration: none; + background-color: $menuHoverBackground; +} + +.red-ui-menu-dropdown-submenu { + position: relative; + & > .red-ui-menu-dropdown { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + } + &:hover > .red-ui-menu-dropdown { + display: block; + } + & > a:after { + display: block; + float: right; + width: 0; + height: 0; + margin-top: 5px; + margin-right: -10px; + border-color: transparent; + border-left-color: $menuCaret; + border-style: solid; + border-width: 5px 0 5px 5px; + content: " "; + } + &.pull-left { + float: none; + & > .red-ui-menu-dropdown { + left: -100%; + margin-left: 10px; + } + } +} + +.red-ui-menu-dropdown-submenu>a:after { + display: none; +} +.red-ui-menu-dropdown-submenu>a:before { + display: block; + float: left; + width: 0; + height: 0; + margin-top: 5px; + margin-left: -30px; + /* Caret Arrow */ + border-color: transparent; + border-right-color: $menuCaret; + border-style: solid; + border-width: 5px 5px 5px 0; + content: " "; +} + +.red-ui-menu-dropdown-submenu.disabled > a:before { + border-right-color: $menuCaret; +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/editor.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/editor.scss new file mode 100644 index 0000000..b13941f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/editor.scss @@ -0,0 +1,998 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +#red-ui-editor-stack { + position: absolute; + margin: 0; + top: 0; + bottom: 0px; + right: 323px; + width: 0; + z-index: 5; +} +.red-ui-tray { + position:absolute; + margin: 0; + top: 0; + //min-width: 500px; + width: auto; + right: -1000px; + bottom: 0; + background: $secondary-background; + border-left: 1px solid $secondary-border-color; + border-bottom: 1px solid $primary-border-color; + box-sizing: content-box; +} +.red-ui-tray.open { + right: 0; +} +.red-ui-tray-body-wrapper { + width: 100%; + box-sizing: border-box; + overflow: auto; +} +.red-ui-tray-body { + position: relative; + box-sizing: border-box; + padding: 0.1px; // prevent margin collapsing + // .dialog-form,#dialog-form, #node-config-dialog-edit-form { + // margin: 20px; + // height: calc(100% - 40px); + // } +} +.red-ui-tray-content { + overflow: auto; + position: relative; + .red-ui-palette-icon-fa { + top: 6px; + left: 4px; + } +} +.red-ui-tray-header { + @include disable-selection; + position: relative; + box-sizing: border-box; + font-weight: bold; + border-bottom: 1px solid $secondary-border-color; + background: $palette-header-background; + &:after { + content: ""; + display: table; + clear: both; + } +} + +.red-ui-tray-footer { + @include component-footer; + height: 35px; + font-size: 14px !important; + line-height: 35px; + vertical-align: middle; + + button.red-ui-button { + padding: 0px 8px; + height: 26px; + line-height: 26px; + &.toggle:not(.selected) { + color: $workspace-button-color-selected !important; + background: $workspace-button-background-active; + } + } + + .red-ui-tray-footer-left { + display:inline-block; + margin-right: 20px; + float:left; + } + .red-ui-tray-footer-right { + float: right; + } +} + +.red-ui-tray-toolbar { + text-align: right; + padding: 6px; + + button { + @include editor-button; + &.toggle { + @include workspace-button-toggle; + } + } +} + +.red-ui-tray-titlebar { + color: $header-text-color; + border-bottom: 1px solid $secondary-border-color; + padding: 8px; +} +.red-ui-editor ul.red-ui-tray-breadcrumbs { + list-style-type: none; + margin: 0; + padding:0; + + li { + display: inline-block; + padding:0; + margin:0; + + &:not(:last-child) { + color: $workspace-button-color; + font-weight: normal; + + &:after { + display: inline-block; + content: '>'; + margin: 0 5px; + } + + } + } +} +.red-ui-tray-resize-handle { + position: absolute; + top: 0px; + bottom: 0px; + width: 7px; + left: -9px; + background: $primary-background url(images/grip.png) no-repeat 50% 50%; + cursor: col-resize; + border-left: 1px solid $primary-border-color; + box-shadow: -1px 0 6px $shadow; + + &.red-ui-tray-resize-maximised { + background: $primary-background; + cursor: default; + } +} +a.red-ui-tray-resize-button, +button.red-ui-tray-resize-button { + @include workspace-button; + display: block; + height: 37px; + line-height: 35px; + border: none; + border-bottom: 1px solid $secondary-border-color; + margin: 0; + background: $primary-background; + color: $workspace-button-color; +} + +.red-ui-editor .red-ui-tray { + .dialog-form, #dialog-form, #node-config-dialog-edit-form { + margin: 20px; + height: calc(100% - 40px); + } +} + +.red-ui-editor,.red-ui-editor-dialog { + + .dialog-form, #dialog-form, #node-config-dialog-edit-form { + margin: 0; + height:100%; + } + + .input-error { + border-color: $form-input-border-error-color !important; + } + + .input-updated { + border-color: $node-selected-color !important; + } + + .form-row { + clear: both; + color: $form-text-color; + margin-bottom:12px; + } + .form-row label { + display: inline-block; + width: 100px; + } + .form-row input, .form-row div[contenteditable="true"] { + width:70%; + } + .form-tips { + background: $form-tips-background; + padding: 8px; + border-radius: 2px; + border: 1px solid $secondary-border-color; + max-width: 450px; + } + .form-tips code { + border: none; + padding: auto; + } + .form-tips a { + text-decoration: underline; + } + + .form-warning { + border-color: $text-color-warning; + } +} + +.node-text-editor { + position: relative; + .red-ui-editor-text-help { + position: absolute; + bottom: 0px; + right: 1px; + border-bottom-right-radius: 5px; + z-Index: 8; + border-bottom: none; + border-right: none; + } +} +.red-ui-editor-text-container { + border:1px solid $tertiary-border-color; + border-radius:5px; + overflow: hidden; + font-size: $primary-font-size !important; + font-family: $monospace-font !important; + height: 100%; + + &.red-ui-editor-text-container-toolbar { + height: calc(100% - 40px); + } +} + +a.editor-button, // Deprecated: use .red-ui-button +button.editor-button, // Deprecated: use .red-ui-button +a.red-ui-button, +button.red-ui-button + { + @include workspace-button; + height: 34px; + line-height: 32px; + font-size: 13px; + border-radius: 2px; + padding: 0 10px; + white-space: nowrap; + text-overflow: ellipsis; + &.toggle { + @include workspace-button-toggle; + } +} + + +a.editor-button-small, // Deprecated: use .red-ui-button-small +button.editor-button-small, // Deprecated: use .red-ui-button-small +a.red-ui-button-small, +button.red-ui-button-small +{ + height: 20px; + min-width: 20px; + line-height: 18px; + font-size: 10px; + border-radius: 2px; + padding: 0 5px; +} + +#red-ui-editor-config-scope-warning { + display: inline-block; + margin-right: 5px; + color: $text-color-warning; + vertical-align: middle; +} +#red-ui-editor-config-scope { + margin: 1px 0 0 0; + padding: 0; + height: 22px; + width: 200px; + +} + +.red-ui-editor .red-ui-tray .red-ui-editor-type-expression #dialog-form { + margin: 0; + height: 100%; + .red-ui-panel { + &:first-child { + padding: 20px 20px 0; + } + &:last-child { + padding-bottom: 20px; + } + } +} +.red-ui-editor-type-expression-tab-content { + position: relative; + padding: 0 20px; +} + +#red-ui-editor-type-expression-help { + position: absolute; + top: 35px; + left:0; + right: 0; + bottom:0; + padding: 0 20px; + overflow: auto; + box-sizing: border-box; +} +#red-ui-editor-type-expression-panel-info { + & > .form-row { + margin: 0; + & > div:first-child { + margin-top: 10px; + } + } +} +.red-ui-editor-type-expression-legacy { + float: left; +} +.red-ui-editor-type-buffer-type { + text-align: right; +} +.red-ui-editor .red-ui-tray .red-ui-editor-type-markdown-editor #dialog-form { + margin: 0; + height: 100%; + .red-ui-panel { + padding: 20px 20px 10px; + &:last-child { + padding-top: 60px; + background: $primary-background; + + } + } +} +.red-ui-editor-type-markdown-panel-preview { + padding: 10px; + border:1px solid $secondary-border-color; + border-radius:5px; + height: calc(100% - 21px); + overflow-y: scroll; + background: $secondary-background; +} + +#red-ui-clipboard-hidden { + position: absolute; + top: -3000px; +} +.form-row .red-ui-editor-node-label-form-row { + margin: 5px 0 0 50px; + label { + margin-right: 20px; + text-align: right; + width: 30px; + } + button { + margin-left: 10px; + } + input { + width: calc(100% - 100px); + } + #red-ui-editor-node-icon-module { + width: calc(55% - 50px); + } + #red-ui-editor-node-icon-file { + width: calc(45% - 55px); + margin-left: 5px; + } +} +.red-ui-editor-node-label-form-none { + span { + padding-left: 50px; + width: 100px; + color: $secondary-text-color; + } +} + +button.red-ui-button.red-ui-editor-node-appearance-button { + position: relative; + height: 35px !important; + text-align: left; + padding: 0 6px 0 3px; + >i { + width: 15px; + vertical-align: middle; + padding-left: 2px; + } + .red-ui-search-result-node { + vertical-align: middle; + float: none; + position: relative; + top: -1px; + + } +} + +.red-ui-icon-picker { + select { + box-sizing: border-box; + margin: 3px; + width: calc(100% - 6px); + } +} +.red-ui-icon-list { + width: 308px; + height: 200px; + overflow-y: scroll; + line-height: 0px; + position: relative; + &.red-ui-icon-list-dark { + .red-ui-palette-icon-fa { + color: $secondary-text-color; + } + .red-ui-palette-icon-container { + background: $secondary-background; + border-radius: 4px; + } + } +} +.red-ui-icon-list-icon { + display: inline-block; + margin: 2px; + padding: 4px; + cursor: pointer; + border-radius: 4px; + + &:hover { + background: $list-item-background-hover; + } + &.selected { + background: $list-item-background-selected; + .red-ui-search-result-node { + // border-color: white; + } + } + .red-ui-palette-icon-fa { + top: 6px; + left: 3px; + } +} +.red-ui-icon-list-module { + background: $palette-header-background; + font-size: 0.9em; + padding: 3px; + color: $secondary-text-color; + clear: both; + i { + margin-right: 5px; + } +} +.red-ui-icon-meta { + border-top: 1px solid $secondary-border-color; + background: $tertiary-background; + height: 24px; + span { + padding: 4px; + color: $secondary-text-color; + font-size: 0.9em; + } + button { + float: right; + margin: 2px; + } +} + + +.red-ui-editor input.red-ui-editor-type-json-editor-key { + width: 150px; +} + +.red-ui-editor-type-json-editor { + height: calc(100% - 10px); + .red-ui-treeList-container { + background: $secondary-background; + } + .red-ui-treeList-label { + padding-top: 0; + padding-bottom: 0; + white-space: nowrap; + min-height: 35px; + .red-ui-treeList-icon:before { + content:''; + display: inline-block; + height: 35px; + vertical-align: middle; + } + > span, > span > span { + vertical-align: middle; + } + &:hover, &:hover .red-ui-treeList-sublabel-text { + background: $secondary-background-disabled; + .red-ui-editor-type-json-editor-item-gutter { + > span, > button { + display: inline-block; + } + } + } + &.selected { + .red-ui-editor-type-json-editor-item-gutter { + background: $secondary-background-hover; + } + &:hover { + .red-ui-editor-type-json-editor-item-gutter { + background: $secondary-background-selected; + } + } + } + &.red-ui-editor-type-json-root-node { + .red-ui-editor-type-json-editor-item-gutter { + > span, > button { + display: inline-block; + } + } + } + } +} +.red-ui-editor-type-json-editor-controls { + height: 34px; + line-height: 34px; + display: none; +} +.red-ui-editor-type-json-editor-key { + width: 100px; +} +.red-ui-editor-type-json-editor-label { + display: inline-block; + white-space: pre-wrap; +} +.red-ui-editor-type-json-editor-label-value { + min-width: 200px; +} +.red-ui-editor-type-json-editor-label-value, +.red-ui-editor-type-json-editor-label-key { + display: inline-block; + box-sizing: border-box; + min-height: 34px; + line-height: 30px; + padding: 0 2px; + border: 2px solid rgba(0,0,0,0); + border-radius: 3px; + &:not(.red-ui-editor-type-json-editor-label-array-key):hover { + border-color: $list-item-background-hover; + border-style: dashed; + } +} +.red-ui-editor-type-json-editor-item-gutter { + width: 48px; + padding-left: 4px; + + height: 100%; + line-height: 35px; + color: $tertiary-text-color; + background: $secondary-background-disabled; + > span { + display: inline-block; + height: 35px; + line-height: 35px; + width: 20px; + text-align:center; + } + > span, > button { + display: none; + } +} + + +.red-ui-editor-type-json-editor-item-handle { + cursor: move; +} +.red-ui-editor-type-json-tab-content { + position: relative; + height: calc(100% - 40px); +} + +button.red-ui-toggleButton.toggle { + text-align: left; +} + + +.red-ui-editor-subflow-env-ui-row { + margin-right: 3px; + >div { + display: grid; + grid-template-columns: 16px 40px 35% auto; + } + >div:first-child { + font-size: 0.9em; + color: $tertiary-text-color; + margin: 3px 0 -4px; + >div { + padding-left: 3px; + } + } + >div:last-child { + >div { + height: 40px; + line-height: 30px; + display: inline-block; + box-sizing: border-box; + // border-left: 2px dashed $secondary-border-color; + // border-bottom: 2px dashed $secondary-border-color; + // border: 1px dashed $secondary-border-color; + border-right: none; + &:not(:first-child) { + padding: 3px; + } + // &:last-child { + // border-right: 1px dashed $secondary-border-color; + // } + .placeholder-input { + position: relative; + padding: 0 3px; + line-height: 24px; + opacity: 0.8 + } + .red-ui-typedInput-value-label,.red-ui-typedInput-option-label { + select,.placeholder-input { + margin: 3px; + height: 26px; + width: calc(100% - 10px); + padding-left: 3px; + } + .placeholder-input { + span:first-child { + display:inline-block; + height: 100%; + width: 20px; + text-align:center; + border-right: 1px solid $secondary-border-color; + background: $tertiary-background; + } + } + input[type="checkbox"] { + margin-left: 8px; + margin-top: 0; + height: 100%; + } + } + } + >div:nth-child(1) { + border: none; + padding: 2px; + .red-ui-editableList-item-handle { + position:relative; + top: 0px; + color: $tertiary-text-color; + } + } + >div:nth-child(2) { + margin: 4px; + height: 32px; + border: 1px dashed $secondary-border-color; + text-align: center; + a { + display: block; + width: 100%; + height: 100%; + line-height: 32px; + &:hover { + background: $secondary-background-hover; + } + i { + height: 100%; + vertical-align: middle; + } + } + } + >div:nth-child(3) { + position: relative; + input { + width: 100%; + } + } + } +} + +span.red-ui-editor-subflow-env-lang-icon { + position: absolute; + display: inline-block; + background: $secondary-background; + opacity: 0.8; + width: 20px; + line-height: 32px; + height: 32px; + text-align: center; + top: 4px; + right: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + +} +// .red-ui-editor-subflow-ui-grid { +// width: 100%; +// .red-ui-editableList-container { +// border: none; +// border-radius: 0; +// } +// .red-ui-editableList-container li { +// border: none; +// padding: 0; +// &:not(:first-child) .red-ui-editableList-item-content >div:first-child >div { +// border-top: none; +// } +// &.ui-sortable-helper { +// border: 2px dashed $secondary-border-color; +// .red-ui-editableList-item-content { +// >div { +// border: none; +// opacity: 0.7 +// } +// +// } +// } +// } +// +// .red-ui-editableList-item-content { +// >div>div { +// display: inline-block; +// box-sizing: border-box; +// border-left: 1px dashed $secondary-border-color; +// border-bottom: 1px dashed $secondary-border-color; +// } +// >div:first-child { +// font-size: 0.9em; +// display: grid; +// grid-template-columns: 25px auto 20px; +// >div { +// border-top: 1px dashed $secondary-border-color; +// padding: 1px; +// } +// >div:nth-child(3) { +// border-top: none; +// border-bottom: none; +// // width: 20px; +// } +// } +// >div:last-child { +// display: grid; +// grid-template-columns: 25px 140px auto 20px; +// >div { +// height: 48px; +// line-height: 30px; +// // display: inline-block; +// // height: 48px; +// // line-height: 30px; +// // box-sizing: border-box; +// // +// // border-left: 2px dashed $secondary-border-color; +// border-top: none; +// // border-bottom: 2px dashed $secondary-border-color; +// &:not(:first-child) { +// padding: 6px 3px; +// } +// .placeholder-input { +// position: relative; +// padding: 0 3px; +// line-height: 24px; +// opacity: 0.8 +// } +// .red-ui-typedInput-value-label,.red-ui-typedInput-option-label { +// select,.placeholder-input { +// margin: 3px; +// height: 26px; +// width: calc(100% - 10px); +// padding-left: 3px; +// } +// input[type="checkbox"] { +// margin-left: 8px; +// margin-top: 0; +// height: 100%; +// } +// } +// } +// >div:nth-child(1) { +// text-align: center; +// a { +// display: block; +// width: 100%; +// height: 100%; +// line-height: 45px; +// &:hover { +// background: $secondary-background-hover; +// } +// } +// } +// >div:nth-child(2) { +// input { +// width: 100%; +// } +// // width: 140px; +// } +// >div:nth-child(3) { +// position: relative; +// .options-button { +// position: absolute; +// top: calc(50% - 10px); +// margin-right: 2px; +// right: 2px; +// } +// } +// >div:nth-child(4) { +// border-top: none; +// border-bottom: none; +// // width: 20px; +// } +// +// } +// } +// } +.red-ui-editor-subflow-ui-edit-panel { + padding-bottom: 3px; + background: $primary-background; + .red-ui-editableList-border { + border: none; + border-radius: 0; + border-bottom: 1px solid $secondary-border-color; + } + .red-ui-editableList-container { + } + .red-ui-editableList-addButton { + margin-left: 2px; + } + .red-ui-editableList-header { + background: $primary-background; + display: grid; + grid-template-columns: 50% 50%; + color: $secondary-text-color; + div:first-child { + padding-left: 23px; + } + div:last-child { + padding-left: 3px; + } + } + .red-ui-editableList-container { + padding: 0 1px; + li { + background: $secondary-background; + // border-bottom: none; + padding: 0; + .red-ui-editableList-item-content { + display: grid; + grid-template-columns: 50% 50%; + >div { + position:relative; + + } + } + input { + margin-bottom: 0; + border:none; + width: 100%; + border-right: 1px solid $secondary-border-color; + + border-radius: 0; + &:focus { + box-shadow: 0 0 0 1px inset $form-input-focus-color; + } + &:first-child { + border-left: 1px solid $secondary-border-color; + } + } + button.red-ui-typedInput-type-select, button.red-ui-typedInput-option-expand, button.red-ui-typedInput-option-trigger { + border-radius: 0; + height: 34px; + } + .red-ui-typedInput-container { + border-radius: 0; + border: none; + input.red-ui-typedInput-input { + height: 34px; + border-right: none; + } + } + + .red-ui-editor-subflow-env-lang-icon { + top: 1px; + right: 1px; + border-top-right-radius:0; + border-bottom-right-radius:0; + } + .red-ui-editableList-item-remove { + right: 3px; + } + } + } +} + +.node-input-env-locales-row { + position: relative; + top: -20px; + float: right; + select { + padding: 2px; + width: 160px; + height: auto; + min-width: 20px; + line-height: 18px; + font-size: 10px; + } +} +.node-input-env-container-row { + min-width: 470px; + position: relative; + .red-ui-editableList-item-content { + label { + margin-bottom: 0; + line-height: 32px; + span { + display: inline-block; + width: 20px; + text-align: center; + } + } + >div:first-child { + display: grid; + padding-left: 5px; + grid-template-columns: 40% auto 37px; + > :first-child { + width: calc(100% - 5px); + } + input { + width: calc(100% - 5px); + } + } + &.red-ui-editor-subflow-env-editable { + >div:first-child { + padding-left: 0; + grid-template-columns: 24px 40% auto 37px; + > a:first-child { + text-align: center; + line-height: 32px; + i.fa-angle-right { + transition: all 0.2s linear; + } + &.expanded { + i.fa-angle-right { + transform: rotate(90deg); + } + } + } + + } + } + } + .red-ui-editableList-border .red-ui-editableList-header { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + + background: $tertiary-background; + padding: 0; + >div { + display: grid; + grid-template-columns: 24px 40% auto 37px; + >div { + display: inline-block; + } + } + } + .red-ui-editableList-container { + padding: 0; + .red-ui-editableList-item-handle { + top: 25px; + } + .red-ui-editableList-item-remove { + top: 25px; + right: 5px; + } + } +} +#subflow-input-ui { + // .form-row { + // display: grid; + // grid-template-columns: 120px auto; + // label span { + // display: inline-block; + // width: 20px; + // text-align: center; + // } + // } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/flow.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/flow.scss new file mode 100644 index 0000000..d92d1e9 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/flow.scss @@ -0,0 +1,298 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +.nr-ui-view-lasso { + stroke-width: 1px; + stroke: $view-lasso-stroke; + fill: $view-lasso-fill; + stroke-dasharray: 10 5; +} + +.node_label_italic, // deprecated: use red-ui-flow-node-label-italic +.red-ui-flow-node-label-italic { + font-style: italic; +} +.red-ui-flow-node-label-white { + fill: $view-background !important; +} +.red-ui-flow-node-label { + stroke-width: 0; + fill: $node-label-color; + font-size: 14px; + pointer-events: none; + -webkit-touch-callout: none; + @include disable-selection; +} + +.red-ui-flow-port-label { + stroke-width: 0; + fill: $secondary-text-color; + font-size: 16px; + alignment-baseline: middle; + text-anchor: middle; + pointer-events: none; + -webkit-touch-callout: none; + @include disable-selection; +} + + +.red-ui-flow-node { + stroke: $node-border; + cursor: move; + stroke-width: 1; +} +.red-ui-workspace-select-mode { + g.red-ui-flow-node.red-ui-flow-node-hovered * { + cursor: pointer !important + } + g.red-ui-flow-node, g.red-ui-flow-link { + opacity: 0.5; + } + g.red-ui-flow-node.red-ui-flow-node-hovered:not(.red-ui-flow-node-selected) { + opacity: 0.9; + .red-ui-flow-node { + stroke-width: 2; + stroke: $node-selected-color !important; + stroke-dasharray: 10, 4; + } + } +} + +.red-ui-flow-node-unknown { + stroke-dasharray:10,4; + stroke: $node-border-unknown; +} +.red-ui-flow-node-placeholder { + stroke-dasharray:10,4; + stroke: $node-border-placeholder; + fill: $node-background-placeholder; + opacity: 0.5; + stroke-width: 2; +} +.red-ui-flow-node-icon-group { + .fa-lg { + stroke: none; + fill: $node-icon-color; + text-anchor: middle; + font-family: FontAwesome; + } +} +.red-ui-flow-node-icon-shade { + stroke: none; + fill: $node-icon-background-color-fill; + fill-opacity: $node-icon-background-color-opacity; +} +.red-ui-flow-node-icon-shade-border { + stroke-opacity: $node-icon-border-color-opacity; + stroke: $node-icon-border-color; + stroke-width: 1; +} + +.red-ui-flow-node-button { + fill: inherit; +} +.red-ui-flow-node-button-background { + fill: $node-background-placeholder; +} + +.red-ui-flow-port { + stroke: $node-border; + stroke-width: 1; + fill: $node-port-background; + cursor: crosshair; +} + +.red-ui-flow-node-error { + fill: $node-status-error-background; + stroke: $node-status-error-border; + stroke-width:1px; + cursor: default; + stroke-linejoin: round; + stroke-linecap: round; +} +.red-ui-flow-node-changed { + fill: $node-status-changed-background; + stroke: $node-status-changed-border; + cursor: default; + stroke-width:1px; + stroke-linejoin: round; + stroke-linecap: round; +} + +g.red-ui-flow-node-selected { + .red-ui-workspace-select-mode & { + opacity: 1; + } + .red-ui-flow-node,.red-ui-flow-subflow-port { + stroke-width: 2; + stroke: $node-selected-color !important; + } +} +.red-ui-flow-node-highlighted { + border-color: $node-selected-color !important; + border-style: dashed !important; + stroke: $node-selected-color; + stroke-width: 3; + stroke-dasharray: 8, 4; +} + +.red-ui-flow-subflow .red-ui-flow-node { +} + +.red-ui-workspace-disabled { + .red-ui-flow-node { + stroke-dasharray: 8, 3; + fill-opacity: 0.5; + } + .red-ui-flow-link-line { + stroke-dasharray: 10,8 !important; + stroke-width: 2 !important; + stroke: $link-disabled-color; + } + .red-ui-flow-port { + fill-opacity: 1; + stroke-dasharray: none; + } +} +.red-ui-flow-node-disabled { + &.red-ui-flow-node, .red-ui-flow-node { + stroke-dasharray: 8, 3; + fill-opacity: 0.5; + } + &.red-ui-flow-link-line { + stroke-dasharray: 10,8 !important; + stroke-width: 2 !important; + stroke: $link-disabled-color; + } + .red-ui-flow-port { + fill-opacity: 1; + stroke-dasharray: none; + } +} +@each $current-color in red green yellow blue grey { + .red-ui-flow-node-status-dot-#{$current-color} { + fill: map-get($node-status-colors,$current-color); + stroke: map-get($node-status-colors,$current-color); + } + .red-ui-flow-node-status-ring-#{$current-color} { + fill: $view-background; + stroke: map-get($node-status-colors,$current-color); + } +} + +.red-ui-flow-node-status-label { + @include disable-selection; + stroke-width: 0; + fill: $secondary-text-color; + font-size:9pt; + text-anchor:start; +} + +.red-ui-flow-port-hovered { + stroke: $port-selected-color; + fill: $port-selected-color; +} + +.red-ui-flow-subflow-port { + fill: $node-background-placeholder; + stroke: $node-border; +} + +.red-ui-flow-drag-line { + stroke: $node-selected-color !important; + stroke-width: 3; + fill: none; + pointer-events: none; +} + +.red-ui-flow-link-line { + stroke: $link-color; + stroke-width: 3; + fill: none; + pointer-events: none; +} +.red-ui-flow-link-link { + stroke-width: 2; + stroke: $link-link-color; + fill: none; + stroke-dasharray: 25,4; +} +.red-ui-flow-link-off-flow { + stroke-width: 2; +} + +.red-ui-flow-link-port { + fill: $node-link-port-background; + stroke: $link-link-color; + stroke-width: 1; +} +.red-ui-flow-link-group-active .red-ui-flow-link-port { + stroke: $link-link-active-color; +} +.red-ui-flow-link-group:hover { + cursor: pointer; +} + +.red-ui-flow-link-outline { + stroke: $view-background; + stroke-width: 5; + cursor: crosshair; + fill: none; + pointer-events: none; +} +.red-ui-flow-link-background { + stroke: $view-background; + opacity: 0; + stroke-width: 20; + cursor: crosshair; + fill: none; +} +.red-ui-flow-link-splice > .red-ui-flow-link-line { + stroke-dasharray: 15,8; +} + +g.red-ui-flow-link-selected path.red-ui-flow-link-line { + stroke: $node-selected-color; +} +g.red-ui-flow-link-unknown path.red-ui-flow-link-line { + stroke: $link-unknown-color; + stroke-width: 2; + stroke-dasharray: 10, 4; +} + +@keyframes red-ui-flow-port-tooltip-fadeIn { from { opacity:0; } to { opacity:1; } } + +.red-ui-flow-port-tooltip { + opacity:0; + animation: 0.1s ease-in 0s 1 normal forwards red-ui-flow-port-tooltip-fadeIn; + pointer-events: none; + + path:first-child { + fill: $popover-background; + stroke: $popover-background; + stroke-width: 1; + } +} +.red-ui-flow-port-tooltip-label { + stroke-width: 0; + fill: $popover-color; + font-family: $primary-font; + font-size: 12px; + pointer-events: none; + -webkit-touch-callout: none; + white-space: pre; + @include disable-selection; +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/forms.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/forms.scss new file mode 100644 index 0000000..8b08d89 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/forms.scss @@ -0,0 +1,735 @@ +/** +* Copyright JS Foundation and other contributors, http://js.foundation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ +/*! +* Extracted from Bootstrap v2.3.2 +* +* Copyright 2013 Twitter, Inc +* Licensed under the Apache License v2.0 +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Designed and built with all the love in the world by @mdo and @fat. +*/ + +.red-ui-editor, .red-ui-editor-dialog { + + button, + input, + select, + div[contenteditable="true"], + textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; + } + + button, + div[contenteditable="true"], + input { + *overflow: visible; + line-height: normal; + } + + button::-moz-focus-inner, + div[contenteditable="true"]::-moz-focus-inner, + input::-moz-focus-inner { + padding: 0; + border: 0; + } + + button, + html input[type="button"], + input[type="reset"], + input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; + } + + label, + select, + button, + input[type="button"], + input[type="reset"], + input[type="submit"], + input[type="radio"], + input[type="checkbox"] { + cursor: pointer; + } + + input[type="search"] { + box-sizing: content-box; + } + + input[type="search"]::-webkit-search-decoration, + input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; + } + + textarea { + overflow: auto; + vertical-align: top; + } + + form { + margin: 0 0 20px; + } + + fieldset { + padding: 0; + margin: 0; + border: 0; + } + + legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: 40px; + color: $tertiary-text-color; + border: 0; + border-bottom: 1px solid $secondary-border-color; + } + + legend small { + color: $tertiary-text-color; + } + + + label, + input, + div[contenteditable="true"], + button, + select, + textarea { + font-size: 14px; + font-weight: normal; + line-height: 20px; + } + + input, + div[contenteditable="true"], + button, + select, + textarea { + font-family: $primary-font; + } + + label { + display: block; + margin-bottom: 5px; + } + + select, + textarea, + input[type="text"], + input[type="password"], + input[type="datetime"], + input[type="datetime-local"], + input[type="date"], + input[type="month"], + input[type="time"], + input[type="week"], + input[type="number"], + input[type="email"], + input[type="url"], + input[type="search"], + input[type="tel"], + input[type="color"], + div[contenteditable="true"], + .uneditable-input, + .placeholder-input { + box-sizing: border-box; + display: inline-block; + height: 34px; + padding: 6px 6px; + margin-bottom: 10px; + font-size: 14px; + line-height: 20px; + color: $form-text-color; + vertical-align: middle; + border-radius: 4px; + } + + input, + textarea, + div[contenteditable="true"], + .uneditable-input { + width: 206px; + } + + textarea { + height: auto; + } + + textarea, + input[type="text"], + input[type="password"], + input[type="datetime"], + input[type="datetime-local"], + input[type="date"], + input[type="month"], + input[type="time"], + input[type="week"], + input[type="number"], + input[type="email"], + input[type="url"], + input[type="search"], + input[type="tel"], + input[type="color"], + div[contenteditable="true"], + .uneditable-input, + .placeholder-input { + background-color: $form-input-background; + border: 1px solid $form-input-border-color; + } + + textarea:focus, + input[type="text"]:focus, + input[type="password"]:focus, + input[type="datetime"]:focus, + input[type="datetime-local"]:focus, + input[type="date"]:focus, + input[type="month"]:focus, + input[type="time"]:focus, + input[type="week"]:focus, + input[type="number"]:focus, + input[type="email"]:focus, + input[type="url"]:focus, + input[type="search"]:focus, + input[type="tel"]:focus, + input[type="color"]:focus, + div[contenteditable="true"]:focus, + .uneditable-input:focus { + border-color: $form-input-focus-color; + outline: 0; + outline: thin dotted \9; + } + + input[type="radio"], + input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + *margin-top: 0; + line-height: normal; + } + + input[type="file"], + input[type="image"], + input[type="submit"], + input[type="reset"], + input[type="button"], + input[type="radio"], + input[type="checkbox"] { + width: auto; + } + + select, + input[type="file"] { + height: 34px; + line-height: 34px; + } + + select { + width: 220px; + background-color: $form-input-background; + border: 1px solid $form-input-border-color; + } + + select[multiple], + select[size] { + height: auto; + } + + select:focus, + input[type="file"]:focus, + input[type="radio"]:focus, + input[type="checkbox"]:focus { + outline: 2px auto $form-input-focus-color; + outline-offset: -3px; + } + + .uneditable-input, + .uneditable-textarea { + color: $form-text-color-disabled; + cursor: not-allowed; + background-color: $form-input-background-disabled; + border-color: $form-input-border-color; + } + + .uneditable-input { + overflow: hidden; + white-space: nowrap; + } + + .uneditable-textarea { + width: auto; + height: auto; + } + + input:-moz-placeholder, + textarea:-moz-placeholder { + color: $form-placeholder-color; + } + + input:-ms-input-placeholder, + div[contenteditable="true"]:-ms-input-placeholder, + textarea:-ms-input-placeholder { + color: $form-placeholder-color; + } + + input::-webkit-input-placeholder, + div[contenteditable="true"]::-webkit-input-placeholder, + textarea::-webkit-input-placeholder { + color: $form-placeholder-color; + } + + .radio, + .checkbox { + min-height: 20px; + padding-left: 20px; + } + + .radio input[type="radio"], + .checkbox input[type="checkbox"] { + float: left; + margin-left: -20px; + } + + .controls > .radio:first-child, + .controls > .checkbox:first-child { + padding-top: 5px; + } + + .radio.inline, + .checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; + } + + .radio.inline + .radio.inline, + .checkbox.inline + .checkbox.inline { + margin-left: 10px; + } + + .input-mini { + width: 60px; + } + + .input-small { + width: 90px; + } + + .input-medium { + width: 150px; + } + + .input-large { + width: 210px; + } + + .input-xlarge { + width: 270px; + } + + .input-xxlarge { + width: 530px; + } + + input[class*="span"], + select[class*="span"], + textarea[class*="span"], + .uneditable-input[class*="span"], + .row-fluid input[class*="span"], + .row-fluid select[class*="span"], + .row-fluid textarea[class*="span"], + .row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; + } + + .input-append input[class*="span"], + .input-append .uneditable-input[class*="span"], + .input-prepend input[class*="span"], + .input-prepend .uneditable-input[class*="span"], + .row-fluid input[class*="span"], + .row-fluid select[class*="span"], + .row-fluid textarea[class*="span"], + .row-fluid .uneditable-input[class*="span"], + .row-fluid .input-prepend [class*="span"], + .row-fluid .input-append [class*="span"] { + display: inline-block; + } + + input, + textarea, + div[contenteditable="true"], + .uneditable-input { + margin-left: 0; + } + + label.disabled { + color: $form-text-color-disabled; + cursor: default; + } + + input[disabled], + select[disabled], + textarea[disabled], + input[readonly], + select[readonly], + textarea[readonly] { + cursor: not-allowed; + background-color: $form-input-background-disabled; + } + + input[type="radio"][disabled], + input[type="checkbox"][disabled], + input[type="radio"][readonly], + input[type="checkbox"][readonly] { + background-color: transparent; + } + + input:invalid, + div[contenteditable="true"]:invalid, + textarea:invalid, + select:invalid { + border-color: $form-input-border-error-color; + } + + input:focus:invalid, + div[contenteditable="true"]:focus:invalid, + textarea:focus:invalid, + select:focus:invalid { + border-color: $form-input-border-error-color; + } + + input:focus:invalid:focus, + div[contenteditable="true"]:focus:invalid:focus, + textarea:focus:invalid:focus, + select:focus:invalid:focus { + border-color: $form-input-border-error-color; + } + + .input-append, + .input-prepend { + display: inline-block; + margin-bottom: 10px; + font-size: 0; + white-space: nowrap; + vertical-align: middle; + } + + .input-append input, + .input-prepend input, + .input-append div[contenteditable="true"], + .input-prepend div[contenteditable="true"], + .input-append select, + .input-prepend select, + .input-append .uneditable-input, + .input-prepend .uneditable-input, + .input-append .red-ui-menu-dropdown, + .input-prepend .red-ui-menu-dropdown, + .input-append .popover, + .input-prepend .popover { + font-size: 14px; + } + + .input-append input, + .input-prepend input, + .input-append div[contenteditable="true"], + .input-prepend div[contenteditable="true"], + .input-append select, + .input-prepend select, + .input-append .uneditable-input, + .input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: top; + border-radius: 0 4px 4px 0; + } + + .input-append input:focus, + .input-prepend input:focus, + .input-append div[contenteditable="true"]:focus, + .input-prepend div[contenteditable="true"]:focus, + .input-append select:focus, + .input-prepend select:focus, + .input-append .uneditable-input:focus, + .input-prepend .uneditable-input:focus { + z-index: 2; + } + + .input-append .add-on, + .input-prepend .add-on { + display: inline-block; + width: auto; + height: 20px; + min-width: 16px; + padding: 4px 5px; + font-size: 14px; + font-weight: normal; + line-height: 20px; + text-align: center; + background-color: $form-button-background; + border: 1px solid $form-input-border-color; + } + + .input-append .add-on, + .input-prepend .add-on, + .input-append .btn, + .input-prepend .btn, + .input-append .btn-group > .dropdown-toggle, + .input-prepend .btn-group > .dropdown-toggle { + vertical-align: top; + border-radius: 0; + } + + .input-prepend .add-on, + .input-prepend .btn { + margin-right: -1px; + } + + .input-prepend .add-on:first-child, + .input-prepend .btn:first-child { + border-radius: 4px 0 0 4px; + } + + .input-append input, + .input-append div[contenteditable="true"], + .input-append select, + .input-append .uneditable-input { + border-radius: 4px 0 0 4px; + } + + .input-append input + .btn-group .btn:last-child, + .input-append select + .btn-group .btn:last-child, + .input-append .uneditable-input + .btn-group .btn:last-child { + border-radius: 0 4px 4px 0; + } + + .input-append .add-on, + .input-append .btn, + .input-append .btn-group { + margin-left: -1px; + } + + .input-append .add-on:last-child, + .input-append .btn:last-child, + .input-append .btn-group:last-child > .dropdown-toggle { + border-radius: 0 4px 4px 0; + } + + .input-prepend.input-append input, + .input-prepend.input-append div[contenteditable="true"], + .input-prepend.input-append select, + .input-prepend.input-append .uneditable-input { + border-radius: 0; + } + + .input-prepend.input-append input + .btn-group .btn, + .input-prepend.input-append select + .btn-group .btn, + .input-prepend.input-append .uneditable-input + .btn-group .btn { + border-radius: 0 4px 4px 0; + } + + .input-prepend.input-append .add-on:first-child, + .input-prepend.input-append .btn:first-child { + margin-right: -1px; + border-radius: 4px 0 0 4px; + } + + .input-prepend.input-append .add-on:last-child, + .input-prepend.input-append .btn:last-child { + margin-left: -1px; + border-radius: 0 4px 4px 0; + } + + .input-prepend.input-append .btn-group:first-child { + margin-left: 0; + } + + input.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + + margin-bottom: 0; + border-radius: 15px; + } + + /* Allow for input prepend/append in search forms */ + + .form-search .input-append .search-query, + .form-search .input-prepend .search-query { + border-radius: 0; + } + + .form-search .input-append .search-query { + border-radius: 14px 0 0 14px; + } + + .form-search .input-append .btn { + border-radius: 0 14px 14px 0; + } + + .form-search .input-prepend .search-query { + border-radius: 0 14px 14px 0; + } + + .form-search .input-prepend .btn { + border-radius: 14px 0 0 14px; + } + + .form-search input, + .form-inline input, + .form-horizontal input, + .form-search div[contenteditable="true"], + .form-inline div[contenteditable="true"], + .form-horizontal div[contenteditable="true"], + .form-search textarea, + .form-inline textarea, + .form-horizontal textarea, + .form-search select, + .form-inline select, + .form-horizontal select, + .form-search .help-inline, + .form-inline .help-inline, + .form-horizontal .help-inline, + .form-search .uneditable-input, + .form-inline .uneditable-input, + .form-horizontal .uneditable-input, + .form-search .input-prepend, + .form-inline .input-prepend, + .form-horizontal .input-prepend, + .form-search .input-append, + .form-inline .input-append, + .form-horizontal .input-append { + display: inline-block; + *display: inline; + margin-bottom: 0; + vertical-align: middle; + *zoom: 1; + } + + .form-search .hide, + .form-inline .hide, + .form-horizontal .hide { + display: none; + } + + .form-search label, + .form-inline label, + .form-search .btn-group, + .form-inline .btn-group { + display: inline-block; + } + + .form-search .input-append, + .form-inline .input-append, + .form-search .input-prepend, + .form-inline .input-prepend { + margin-bottom: 0; + } + + .form-search .radio, + .form-search .checkbox, + .form-inline .radio, + .form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; + } + + .form-search .radio input[type="radio"], + .form-search .checkbox input[type="checkbox"], + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; + } + + .control-group { + margin-bottom: 10px; + } + + legend + .control-group { + margin-top: 20px; + -webkit-margin-top-collapse: separate; + } + + .form-horizontal .control-group { + margin-bottom: 20px; + *zoom: 1; + } + + .form-horizontal .control-group:before, + .form-horizontal .control-group:after { + display: table; + line-height: 0; + content: ""; + } + + .form-horizontal .control-group:after { + clear: both; + } + + .form-horizontal .control-label { + float: left; + width: 160px; + padding-top: 5px; + text-align: right; + } + + .form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 180px; + *margin-left: 0; + } + + .form-horizontal .controls:first-child { + *padding-left: 180px; + } + + .form-horizontal .help-block { + margin-bottom: 0; + } + + .form-horizontal input + .help-block, + .form-horizontal select + .help-block, + .form-horizontal textarea + .help-block, + .form-horizontal .uneditable-input + .help-block, + .form-horizontal .input-prepend + .help-block, + .form-horizontal .input-append + .help-block { + margin-top: 10px; + } + + .form-horizontal .form-actions { + padding-left: 180px; + } + + .form-row div[contenteditable="true"] { + white-space: nowrap; + overflow: hidden; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/header.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/header.scss new file mode 100644 index 0000000..4093e9b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/header.scss @@ -0,0 +1,281 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +.button { + @include disable-selection; +} + +#red-ui-header { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 40px; + background: $header-background; + box-sizing: border-box; + padding: 0px 0px 0px 20px; + color: $header-menu-color; + font-size: 14px; + + span.red-ui-header-logo { + float: left; + margin-top: 5px; + font-size: 30px; + line-height: 30px; + text-decoration: none; + white-space: nowrap; + + span { + vertical-align: middle; + font-size: 16px !important; + &:not(:first-child) { + margin-left: 5px; + } + } + img { + height: 18px; + } + + a { + color: inherit; + &:hover { + text-decoration: none; + } + } + + } + + .red-ui-header-toolbar { + padding: 0; + margin: 0; + list-style: none; + float: right; + + > li { + display: inline-block; + padding: 0; + margin: 0; + position: relative; + + } + } + + .button { + min-width: 20px; + text-align: center; + line-height: 40px; + display: inline-block; + font-size: 20px; + padding: 0px 12px; + text-decoration: none; + color: $header-menu-color; + margin: auto 5px; + vertical-align: middle; + border-left: 2px solid $header-background; + border-right: 2px solid $header-background; + + &:hover { + border-color: $header-menu-item-hover; + } + &:active, &.active { + background: $header-button-background-active; + } + &:focus { + outline: none; + } + } + + .button-group { + display: inline-block; + margin: auto 15px; + vertical-align: middle; + clear: both; + & > a { + display: inline-block; + position: relative; + float: left; + line-height: 22px; + font-size: 14px; + text-decoration: none; + padding: 4px 8px; + margin: 0; + } + } + + .red-ui-deploy-button { + background: $deploy-button-background; + color: $deploy-button-color; + + &:hover { + background: $deploy-button-background-hover; + } + &:focus { + outline: none; + } + &:active { + background: $deploy-button-background-active; + color: $deploy-button-color-active; + } + } + + .red-ui-deploy-button-spinner { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + text-align: center; + + img { + opacity: 0.8; + height: 100%; + } + } + + #red-ui-header-button-deploy { + padding: 4px 12px; + &.disabled { + cursor: default; + background: $deploy-button-background-disabled; + color: $deploy-button-color-disabled; + + .red-ui-deploy-button-content>img { + opacity: 0.3; + } + &+ #red-ui-header-button-deploy-options { + background: $deploy-button-background-disabled; + color: $deploy-button-color-active; + } + &+ #red-ui-header-button-deploy-options:hover { + background: $deploy-button-background-disabled-hover; + } + &+ #red-ui-header-button-deploy-options:active { + background: $deploy-button-background-disabled; + } + } + + .red-ui-deploy-button-content>img { + margin-right: 8px; + } + } + + .red-ui-deploy-button-group.open { + #red-ui-header-button-deploy-options { + background: $header-button-background-active !important; + } + } + + li.open .button { + background: $header-button-background-active; + border-color: $header-button-background-active; + } + + + ul.red-ui-menu-dropdown { + background: $header-menu-background; + border: 1px solid $header-menu-background; + width: 250px !important; + margin-top: 0; + li a { + color: $header-menu-color; + padding: 3px 40px; + img { + max-width: 100%; + margin-right: 10px; + padding: 4px; + border: 3px solid transparent; + } + + &.active img { + border: 3px solid $header-menu-item-border-active; + } + + span.red-ui-menu-label-container { + width: 180px; + vertical-align: top; + display: inline-block; + text-indent: 0px; + } + span.red-ui-menu-label { + font-size: 14px; + display: inline-block; + text-indent: 0px; + } + span.red-ui-menu-sublabel { + color: $header-menu-sublabel-color; + font-size: 13px; + display: inline-block; + text-indent: 0px; + } + } + > li > a:hover, + > li > a:focus, + > li:hover > a, + > li:focus > a { + background: $header-menu-item-hover !important; + } + li.red-ui-menu-divider { + background: $headerMenuItemDivider; + } + li.disabled a { + color: $header-menu-color-disabled; + } + > li.disabled > a:hover, + > li.disabled > a:focus { + background: none !important; + } + } + .red-ui-menu-dropdown-submenu>a:before { + border-right-color: $headerMenuCaret; + } + + /* Deploy menu customisations */ + ul#red-ui-header-button-deploy-options-submenu { + width: 300px !important; + li a { + padding: 10px 30px; + color: $header-menu-heading-color; + span.red-ui-menu-label { + font-size: 16px; + display: inline-block; + text-indent: 0px; + } + > i.fa { + display: none; + } + } + } + /* User menu customisations */ + #usermenu-item-username > .red-ui-menu-label { + color: $header-menu-heading-color; + } + + #red-ui-header-button-user .user-profile { + background-position: center center; + background-repeat: no-repeat; + background-size: contain; + display: inline-block; + width: 40px; + height: 35px; + vertical-align: middle; + } +} + +@media only screen and (max-width: 450px) { + span.red-ui-header-logo > span { + display: none; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/jquery.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/jquery.scss new file mode 100644 index 0000000..b5b9616 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/jquery.scss @@ -0,0 +1,195 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +.ui-widget { + font-size: 14px !important; + font-family: $primary-font; +} +.ui-widget input, .ui-widget div[contenteditable="true"], .ui-widget select, .ui-widget textarea, .ui-widget button { + font-size: 14px !important; + font-family: $primary-font; +} +.ui-widget input, .ui-widget div[contenteditable="true"] { + box-shadow: none; +} + +.ui-widget-header { + color: $header-text-color; +} + +/* jQuery Theme overrides */ +.ui-tabs .ui-tabs-panel { + padding: 0px; +} + +.ui-autocomplete { + max-height: 250px; + overflow-x: hidden; + overflow-y: scroll; +} + +.ui-dialog { + border-radius: 1px; + background: $secondary-background; + padding: 0; + @include component-shadow; +} +.ui-dialog .ui-dialog-content { + padding: 25px 25px 10px 25px; +} +.ui-dialog .ui-dialog-title { + width: auto; +} +.ui-dialog .ui-dialog-titlebar { + padding: 10px; + background: $primary-background; + border: none; + border-bottom: 1px solid $primary-border-color; + border-radius: 0; +} +.ui-dialog .ui-dialog-buttonpane.ui-widget-content { + background: $tertiary-background; + +} +.ui-corner-all { + border-radius: 1px; +} +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { + background: $primary-background; +} +.ui-dialog-no-close .ui-dialog-titlebar-close { + display: none; +} + +.ui-dialog-buttonset { + text-align: right; +} + +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { + float: none; +} + +.ui-dialog-buttonset button { + @include workspace-button; + font-size: 14px; + padding: 6px 14px; + margin-right: 8px; + border-radius: 2px; + color: $workspace-button-color; + background: $workspace-button-background; + + &.leftButton { + float: left; + margin-top: 7px; + } + &:not(.leftButton):not(:last-child) { + margin-right: 16px; + } + + &.primary { + border-color: $workspace-button-background-primary; + color: $workspace-button-color-primary !important; + background: $workspace-button-background-primary; + &:not(.disabled):hover { + border-color: $workspace-button-background-primary-hover; + background: $workspace-button-background-primary-hover; + color: $workspace-button-color-primary !important; + } + &.disabled { + border-color: $form-input-border-color; + color: $workspace-button-color-disabled !important; + background: $workspace-button-background; + } + } + &.disabled { + background: none; + } + &.disabled { + background: none; + } + &.disabled:focus { + outline: none; + } + .ui-button-text { + padding: 0; + } +} + +.ui-dialog .ui-dialog-buttonpane { + padding: .3em 1em .5em 1em; +} + +.ui-spinner { + border-radius: 4px; + padding: 0; + border: 1px solid $form-input-border-color; +} +.ui-spinner input { + background: $form-input-background; + margin: 0 17px 0 0; + padding: 6px; + border: none; + border-top-right-radius: 0px; + border-bottom-right-radius: 0px; + &:focus { + outline: none; + } +} + + +.ui-widget-overlay { + @include shade; + z-index: 100; + opacity: 1; +} + +.ui-state-default, +.ui-widget-content .ui-state-default, +.ui-widget-header .ui-state-default, +.ui-button, +html .ui-button.ui-state-disabled:hover, +html .ui-button.ui-state-disabled:active { + border: 1px solid $secondary-border-color; + background: $form-button-background; +} + +.ui-state-hover, +.ui-widget-content .ui-state-hover, +.ui-widget-header .ui-state-hover, +.ui-state-focus, +.ui-widget-content .ui-state-focus, +.ui-widget-header .ui-state-focus, +.ui-button:hover, .ui-button:focus { + border: 1px solid $secondary-border-color; + background: $workspace-button-background-hover; + color: $workspace-button-color-hover; +} + +.ui-state-active, +.ui-widget-content .ui-state-active, +.ui-widget-header .ui-state-active, +a.ui-button:active, +.ui-button:active, +.ui-button.ui-state-active:hover { + border: 1px solid $secondary-border-color; + background: $workspace-button-background-active; + font-weight: normal; + color: $workspace-button-color-active; +} + +.ui-state-active .ui-icon, .ui-button:active .ui-icon { + background-image: url(../vendor/jquery/css/base/images/ui-icons_777777_256x240.png); +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/keyboard.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/keyboard.scss new file mode 100644 index 0000000..8c4e5a3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/keyboard.scss @@ -0,0 +1,127 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +#red-ui-settings-tab-keyboard { + .red-ui-editableList-container { + border-radius: 0; + border: none; + padding: 0; + } + .keyboard-shortcut-list-header { + padding:0 5px 0 5px; + border-bottom: 1px solid $primary-border-color; + div { + color: $header-text-color !important; + } + .red-ui-searchBox-container { + width: calc(100% - 20px); + } + .keyboard-shortcut-entry-scope { + text-align: center; + } + + } + .keyboard-shortcut-list { + position: absolute; + top:30px; + left:10px; + right:10px; + bottom:10px; + li { + padding: 0; + .red-ui-editableList-item-content { + padding: 8px; + cursor: pointer; + } + } + li:hover { + background: $list-item-background-hover; + } + } + .keyboard-shortcut-entry { + div { + display: inline-block; + } + // white-space: nowrap; + + select { + margin: 0; + width: calc(100% - 30px); + font-size: 0.9em; + margin-right: 5px; + } + } + .keyboard-shortcut-entry-key { + width:160px; + vertical-align: middle; + input { + margin:0; + width: calc(100% - 5px); + } + } + .keyboard-shortcut-entry-text { + vertical-align: middle; + width: calc(100% - 160px - 100px - 10px); + overflow: hidden; + i { + color: $tertiary-text-color; + margin-right: 5px; + } + } + .keyboard-shortcut-entry-scope { + width:100px; + color: $tertiary-text-color; + vertical-align: middle; + text-align: right; + } + .keyboard-shortcut-entry:not(.keyboard-shortcut-list-header) { + .keyboard-shortcut-entry-scope { + font-size: 0.8em; + } + } + .keyboard-shortcut-entry-unassigned { + color: $tertiary-text-color; + .keyboard-shortcut-entry-key { + font-style: italic; + } + } + .keyboard-shortcut-entry-expanded { + background: $list-item-background-selected; + .keyboard-shortcut-entry-key { + width: 150px; + } + .keyboard-shortcut-entry-text { + } + .keyboard-shortcut-entry-scope { + width: 110px; + } + span { + display: none; + } + } +} +.help-key { + border: 1px solid $tertiary-border-color; + padding: 4px; + border-radius: 3px; + background: $tertiary-background; + font-family: $monospace-font; + box-shadow: $shade-color 1px 1px 1px; +} +.help-key-block { + white-space: nowrap; +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/library.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/library.scss new file mode 100644 index 0000000..60014b2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/library.scss @@ -0,0 +1,154 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +.red-ui-clipboard-import-error { + pre { + margin: 10px 0; + border: none; + color: $primary-text-color; + span { + padding: 5px 0; + } + span.error { + padding: 5px; + border: 1px solid $form-input-border-error-color; + margin: 0 1px; + } + } +} +.red-ui-clipboard-dialog-tab-clipboard { + padding: 10px; + textarea { + resize: none; + width: 100%; + border-radius: 4px; + font-family: $monospace-font !important; + font-size: 13px !important; + height: 300px; + line-height: 1.3em; + padding: 6px 10px; + background: $clipboard-textarea-background; + } +} + +.red-ui-clipboard-dialog-tabs { + position: absolute; + top:0; + left:0; + bottom:0; + width:120px; +} + +.red-ui-clipboard-dialog-tabs-content { + position: absolute; + top: 0; + left: 120px; + right: 0; + bottom: 0; + padding: 0; + background: $form-input-background; + &>div { + height: 100%; + } +} +.red-ui-clipboard-dialog-box { + height: 400px; + position:relative; + border:1px solid $primary-border-color; +} + +.red-ui-clipboard-dialog-tab-library { + .form-row { + margin-left: 10px; + } +} + +#red-ui-clipboard-dialog { + form { + margin-bottom: 0; + } + .form-row:last-child { + margin-bottom: 0; + } +} +#red-ui-clipboard-dialog-tab-library-name { + width: calc(100% - 120px); +} +#red-ui-clipboard-dialog-export-tab-library-browser { + height: calc(100% - 60px); + margin-bottom: 13px; + border-bottom: 1px solid $primary-border-color; + box-sizing: border-box; +} +#red-ui-clipboard-dialog-import-tab-library-browser { + height: 100%; + box-sizing: border-box; +} + + +.red-ui-library-browser { + position: relative; + height: 100%; + .red-ui-treeList-container { + background: $secondary-background; + border: none; + border-radius: 0; + li { + background: none; + } + label { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } + .red-ui-editableList-border { + border-radius: 0; + } + + .red-ui-treeList-label input.red-ui-treeList-input { + border-radius: 2px; + margin-top: -6px; + margin-bottom: -6px; + } +} + +#red-ui-library-dialog-save-browser { + height: calc(100% - 60px); + border: 1px solid $primary-border-color; + margin-bottom: 10px; +} +#red-ui-library-dialog-load-browser { + // border: 1px solid $primary-border-color; +} +#red-ui-library-dialog-load-panes { + border: 1px solid $primary-border-color; +} + + +#red-ui-library-dialog-load-preview { + height: 100%; +} + +#red-ui-library-dialog-load-preview-text { + box-sizing: border-box; +} +#red-ui-library-dialog-load-preview-details { + box-sizing: border-box; + .red-ui-help-info-row:first-child { + border-top: none; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/mixins.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/mixins.scss new file mode 100644 index 0000000..dda9ef3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/mixins.scss @@ -0,0 +1,245 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +@mixin disable-selection { + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +@mixin enable-selection { + -webkit-user-select: auto; + -khtml-user-select: auto; + -moz-user-select: auto; + -ms-user-select: auto; + user-select: auto; +} + +@mixin component-border { + border: 1px solid $primary-border-color; + box-sizing: border-box; + +} + +@mixin reset-a-style { + color: $workspace-button-color !important; + background: $workspace-button-background; + text-decoration: none; + + &.disabled, &:disabled { + cursor: default; + color: $workspace-button-color-disabled !important; + } + &:hover, &:focus { + text-decoration: none; + } + &:not(.disabled):not(:disabled):hover, { + color: $workspace-button-color-hover !important; + background: $workspace-button-background-hover; + } + &:not(.disabled):not(:disabled):focus { + color: $workspace-button-color-focus !important; + } + &:not(.disabled):not(:disabled):active { + color: $workspace-button-color-active !important; + background: $workspace-button-background-active; + text-decoration: none; + } +} + +@mixin workspace-button { + @include disable-selection; + @include reset-a-style; + + box-sizing: border-box; + display: inline-block; + border: 1px solid $form-input-border-color; + text-align: center; + margin:0; + cursor:pointer; + + &.selected:not(.disabled):not(:disabled) { + color: $workspace-button-color-selected !important; + background: $workspace-button-background-active; + } + .button-group &:not(:first-child) { + border-left: none; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .button-group &:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .button-group-vertical & { + display: block; + min-width: 22px; + } + .button-group-vertical &:not(:first-child) { + border-top: none; + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .button-group-vertical &:not(:last-child) { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + + .button-row &:not(:first-child) { + margin-left: 15px; + } + + &:focus { + outline: 1px solid $workspace-button-color-focus-outline; + } + + &.primary { + border-color: $workspace-button-background-primary; + color: $workspace-button-color-primary !important; + background: $workspace-button-background-primary; + &.disabled, &.ui-state-disabled { + background: none; + color: $workspace-button-color !important; + border-color: $form-input-border-color; + } + &:not(.disabled):not(.ui-button-disabled):hover { + border-color: $workspace-button-background-primary-hover; + background: $workspace-button-background-primary-hover; + color: $workspace-button-color-primary !important; + } + } + &.secondary { + background: none; + &:not(:hover) { + border-color: transparent; + } + + } + +} +.button-group-vertical { + display: inline-block; + vertical-align: middle; +} +.button-group:not(:last-child) { + margin-right: 10px; +} + + +@mixin workspace-button-toggle { + @include workspace-button; + &:not(.single) { + margin-bottom: 1px; + &.selected:not(.disabled):not(:disabled) { + border-bottom-width: 2px; + border-bottom-color: $form-input-border-selected-color; + margin-bottom: 0; + cursor: default; + } + &:not(.selected) { + margin-top: 1px; + } + } +} +@mixin editor-button { + @include workspace-button; + font-size: 14px; + padding: 6px 14px; + margin-right: 8px; + &:not(.disabled):hover { + //color: $workspace-button-color; + } + &.disabled { + background: none; + } + &.disabled:focus { + outline: none; + } + &.leftButton { + float: left; + margin-top: 1px; + } + &:not(.leftButton):not(:last-child) { + margin-right: 16px; + } + &.ui-state-disabled { + opacity: 1; + } +} + +@mixin component-footer { + border-top: 1px solid $primary-border-color; + background: $primary-background; + text-align: right; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 25px; + line-height: 25px; + padding: 0 6px; + user-select: none; + + .button-group:not(:last-child) { + margin-right: 5px; + } + +} + +@mixin component-footer-button { + @include workspace-button; + font-size: 12px; + line-height: 18px; + width: 19px; + height: 19px; + padding: 0; + &.text-button { + width: auto; + padding: 0 5px; + } +} +@mixin component-footer-button-toggle { + @include workspace-button-toggle; + font-size: 12px; + line-height: 18px; + height: 19px; + width: 19px; + padding: 0; + &.text-button { + width: auto; + padding: 0 5px; + } +} + +@mixin component-shadow { + box-shadow: 1px 1px 4px $shadow; + +} + +@mixin shade { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + background: $shade-color; + z-index: 5; +} +.red-ui-shade { + @include shade +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/notifications.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/notifications.scss new file mode 100644 index 0000000..f7c6463 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/notifications.scss @@ -0,0 +1,133 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#red-ui-notifications { + z-index: 100; + width: 500px; + margin-left: -250px; + left: 50%; + position: absolute; + top: 1px; +} +.red-ui-notification { + box-sizing: border-box; + position: relative; + padding: 14px 18px; + margin-bottom: 4px; + box-shadow: 0 1px 1px 1px $shadow; + background-color: $secondary-background; + color: $primary-text-color; + border: 1px solid $notification-border-default; + border-left-width: 16px; + overflow: hidden; + .ui-dialog-buttonset { + margin-top: 20px; + } +} +.red-ui-notification p:first-child { + font-size: 1.1em; + font-weight: 400; +} +.red-ui-notification a { + text-decoration: none; + &:hover { + text-decoration: underline; + } +} + +.red-ui-notification-success { + border-color: $notification-border-success; +} +.red-ui-notification-warning { + border-color: $notification-border-warning; +} +.red-ui-notification-error { + border-color: $notification-border-error; +} + +.red-ui-notification-compact { + p { + margin: 0; + } + .ui-dialog-buttonset { + margin-top: 0; + position: absolute; + top: 8px; + right: 10px; + } +} + +.red-ui-notification-shake-horizontal { + -webkit-animation: red-ui-notification-shake-horizontal 0.3s steps(2, end) both; + animation: red-ui-notification-shake-horizontal 0.3s steps(2, end) both; +} + +@-webkit-keyframes red-ui-notification-shake-horizontal { + 0%, + 100% { + -webkit-transform: translateX(0); + transform: translateX(0); + } + 10%, + 30%, + 50%, + 70% { + -webkit-transform: translateX(-1px); + transform: translateX(-1px); + } + 20%, + 40%, + 60% { + -webkit-transform: translateX(1px); + transform: translateX(1px); + } + // 80% { + // -webkit-transform: translateX(1px); + // transform: translateX(1px); + // } + // 90% { + // -webkit-transform: translateX(-1px); + // transform: translateX(-1px); + // } +} +@keyframes red-ui-notification-shake-horizontal { + 0%, + 100% { + -webkit-transform: translateX(0); + transform: translateX(0); + } + 10%, + 30%, + 50%, + 70% { + -webkit-transform: translateX(-1px); + transform: translateX(-1px); + } + 20%, + 40%, + 60% { + -webkit-transform: translateX(1px); + transform: translateX(1px); + } + // 80% { + // -webkit-transform: translateX(1px); + // transform: translateX(1px); + // } + // 90% { + // -webkit-transform: translateX(-1px); + // transform: translateX(-1px); + // } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/palette-editor.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/palette-editor.scss new file mode 100644 index 0000000..7e167e4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/palette-editor.scss @@ -0,0 +1,239 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#red-ui-settings-tab-palette { + height: 100%; +} + +#red-ui-palette-editor { + text-align: left; + position: absolute; + top: 0px; + right: 0; + bottom: 0; + left:0; + padding: 0; + box-sizing:border-box; + background: $secondary-background; + + .red-ui-editableList-container { + border: none; + border-radius: 0; + padding: 0px; + + + li { + // border: none; + // border-top: 1px solid $primary-border-color; + padding: 0px; + .red-ui-button { + min-width: 60px; + } + + .disabled { + // background: $secondary-background-inactive;//f3f3f3; + + .red-ui-palette-module-name { + font-style: italic; + color: $tertiary-text-color; + } + .red-ui-palette-module-version { + color: $tertiary-text-color; + } + .red-ui-palette-module-errors .fa-warning { + opacity: 0.5; + } + ul.red-ui-palette-module-error-list li { + color: $tertiary-text-color; + } + + + } + .red-ui-editableList-item-content { + padding: 12px 16px; + } + &:last-child { + // border-bottom: 1px solid $primary-border-color; + } + } + + } + .red-ui-palette-editor-tab { + position:absolute; + top:35px; + left:0; + right:0; + bottom:0 + } + .red-ui-palette-editor-toolbar { + background: $primary-background; + box-sizing: border-box; + padding: 8px 10px; + border-bottom: 1px solid $primary-border-color; + text-align: right; + } + .red-ui-palette-module-shade-status { + color: $secondary-text-color; + } + .red-ui-palette-module-updated { + margin-left: 10px; + } + .red-ui-palette-module-link { + margin-left: 5px; + } + + .red-ui-palette-module-description { + margin-left: 20px; + font-size: 0.9em; + color: $secondary-text-color; + } + .red-ui-palette-module-link { + } + .red-ui-palette-module-set-button-group { + } + .red-ui-palette-module-content { + display: none; + padding: 10px 3px; + } + i.fa.red-ui-palette-module-node-chevron { + width: 8px; + margin-right: 0; + transform: rotate(0deg); + transition: transform 0.2s ease-in-out; + } + .expanded { + i.fa.red-ui-palette-module-node-chevron { + transform: rotate(90deg); + } + } + .red-ui-palette-module-set { + border:1px solid $secondary-border-color; + border-radius: 0; + padding: 5px; + position: relative; + &:not(:last-child) { + border-bottom: none; + } + &:first-child { + border-top-right-radius: 2px; + border-top-left-radius: 2px; + } + &:last-child { + border-bottom-right-radius: 2px; + border-bottom-left-radius: 2px; + } + } + + .red-ui-palette-module-type { + color: $secondary-text-color; + padding-left: 5px; + font-size: 0.9em; + @include enable-selection; + } + .red-ui-palette-module-type-swatch { + display: inline-block; + width: 12px; + height: 12px; + border-radius: 3px; + vertical-align: middle; + margin-right: 5px; + background: $primary-background; + border: 1px dashed $secondary-border-color; + } + .red-ui-palette-module-set-button-group { + position: absolute; + right: 4px; + top: 4px; + } + + .red-ui-palette-module-set-disabled { + background: $list-item-background-disabled; + .red-ui-palette-module-type { + color: $secondary-text-color-disabled-active; + } + } + .red-ui-palette-module-more { + padding: 0 !important; + margin-top: 10px; + margin-bottom: 10px; + background: $tab-background-inactive; + a { + display: block; + text-align: center; + padding: 12px 8px; + color: $text-color-warning; + + &:hover { + text-decoration: none; + background: $tab-background-hover; + } + } + } + +} +.red-ui-palette-module-meta { + color: $secondary-text-color; + position: relative; + &.disabled { + color: $secondary-text-color-disabled; + } + + .fa { + width: 15px; + text-align: center; + margin-right: 5px; + } +} +.red-ui-palette-module-name { + color: $primary-text-color; + white-space: nowrap; + @include enable-selection; +} +.red-ui-palette-module-version, .red-ui-palette-module-updated, .red-ui-palette-module-link { + font-style:italic; + font-size: 0.8em; + @include enable-selection; +} +.red-ui-palette-module-button-group { + position: absolute; + right: 0; + bottom: 0; + a { + margin-left: 5px; + } +} +.red-ui-palette-module-meta .fa-warning { + color: $text-color-warning; +} +ul.red-ui-palette-module-error-list { + display: inline-block; + list-style-type: none; + margin: 0; + font-size: 0.9em; + li { + border: none; + background: none; + } +} + +.red-ui-palette-module-shade { + @include shade; + text-align: center; + padding-top: 20px; +} +#red-ui-palette-module-install-shade { + padding-top: 80px; +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/palette.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/palette.scss new file mode 100644 index 0000000..ea4b06c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/palette.scss @@ -0,0 +1,216 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +#red-ui-palette{ + position: absolute; + top: 0px; + bottom: 0px; + left:0px; + background: $primary-background; + width: 180px; + text-align: center; + @include disable-selection; + @include component-border; + transition: width 0.2s ease-in-out; +} + +.red-ui-palette-closed { + #red-ui-palette { + width: 8px; + .red-ui-component-footer { + display: none; + } + } + #red-ui-palette-search { display: none; } + #red-ui-palette-container { display: none; } +} + +.red-ui-palette-scroll { + position: absolute; + top: 35px; + right: 0; + bottom: 25px; + left:0; + padding: 0; + overflow-y: auto; + box-sizing:border-box; +} +#red-ui-palette> .red-ui-palette-spinner { + padding-top: 80px; +} +.red-ui-palette-search { + position: relative; + overflow: hidden; + background: $secondary-background; + text-align: center; + height: 35px; + padding: 3px; + border-bottom: 1px solid $primary-border-color; + box-sizing:border-box; +} + +.red-ui-palette-category { + border-bottom: 1px solid $secondary-border-color; +} +.red-ui-palette-content { + background: $palette-content-background; + padding: 3px; +} + +.red-ui-palette-header { + position: relative; + background: $palette-header-background; + color: $palette-header-color; + cursor: pointer; + text-align: left; + padding: 9px; + font-weight: bold; + padding-left: 30px; + overflow: hidden; + user-select: none; + &:hover { + background: $palette-header-background !important; + } +} +.red-ui-palette-header > i { + position: absolute; + left: 11px; + top: 12px; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + -webkit-transform: rotate(-90deg); + -moz-transform: rotate(-90deg); + -o-transform: rotate(-90deg); +} +.red-ui-palette-header i.expanded { + -webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); +} +.red-ui-palette-header span { + clear: both; +} +.red-ui-palette-label { + color: $node-label-color; + font-size: 13px; + margin: 4px 0 4px 32px; + line-height: 20px; + overflow: hidden; + text-align: center; + @include disable-selection; +} +.red-ui-palette-label-right { + margin: 4px 32px 4px 0; +} + +.red-ui-palette-node { + // display: inline-block; + cursor: move; + background: $secondary-background; + margin: 10px auto; + height: 25px; + border-radius: 5px; + border: 1px solid $node-border; + background-position: 5% 50%; + background-repeat: no-repeat; + width: 120px; + background-size: contain; + position: relative; + &:not(.red-ui-palette-node-config):first-child { + margin-top: 15px; + } + &:not(.red-ui-palette-node-config):last-child { + margin-bottom: 15px; + } +} +.red-ui-palette-node:hover { + border-color: transparent; + box-shadow: 0 0 0 2px $node-selected-color; +} +.red-ui-palette-port { + position: absolute; + top:8px; + left: -5px; + box-sizing: border-box; + -moz-box-sizing: border-box; + background: $node-port-background; + border-radius: 3px; + width: 10px; + height: 10px; + border: 1px solid $node-border; +} +.red-ui-palette-port-output { + left:auto; + right: -6px; +} + +.red-ui-palette-node:hover .red-ui-palette-port { + background-color: $node-port-background-hover; +} +.red-ui-palette-icon-container { + position: absolute; + text-align: center; + top:0; + bottom:0; + left:0; + width: 30px; + border-right: 1px solid $node-icon-background-color; + background-color: $node-icon-background-color; +} +.red-ui-palette-icon-container-right { + left: auto; + right: 0; + border-right: none; + border-left: 1px solid $node-icon-background-color; +} +.red-ui-palette-icon { + display: inline-block; + width: 20px; + height: 100%; + background-position: 50% 50%; + background-size: contain; + background-repeat: no-repeat; +} +.red-ui-palette-icon-fa { + color: white; + position: absolute; + top: 7px; + left: 3px; +} +.red-ui-palette-node-small { + display: inline-block; + position: relative; + width: 18px; + height: 15px; + margin: 3px 0px; + vertical-align: middle; + cursor: default; + + .red-ui-palette-icon-container { + width: 18px; + border-right: none; + } + .red-ui-palette-icon { + margin-left: -1px; + width: 15px; + } + .red-ui-palette-icon-fa { + top: 2px; + left: 1px; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/panels.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/panels.scss new file mode 100644 index 0000000..9f99db5 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/panels.scss @@ -0,0 +1,61 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +.red-ui-panels { + position: relative; + overflow: hidden; + & > div { + // border: 1px solid red; + box-sizing: border-box; + } +} + +.red-ui-panels-separator { + border-top: 1px solid $secondary-border-color; + border-bottom: 1px solid $secondary-border-color; + height: 7px; + box-sizing: border-box; + cursor: ns-resize; + background: $primary-background url(images/grip.png) no-repeat 50% 50%; +} + + +.red-ui-panel { + overflow: auto; + height: calc(50% - 4px); +} + +.red-ui-panels.red-ui-panels-horizontal { + height: 100%; + &>.red-ui-panel { + vertical-align: top; + display: inline-block; + height: 100%; + width: calc(50% - 4px); + } + &>.red-ui-panels-separator { + vertical-align: top; + border-top: none; + border-bottom: none; + border-left: 1px solid $secondary-border-color; + border-right: 1px solid $secondary-border-color; + height: 100%; + width: 7px; + display: inline-block; + cursor: ew-resize; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/popover.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/popover.scss new file mode 100644 index 0000000..95097a3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/popover.scss @@ -0,0 +1,176 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +.red-ui-popover { + display: none; + position: absolute; + width: auto; + padding: 10px; + height: auto; + background: $popover-background; + color: $popover-color; + border-radius: 4px; + z-index: 1000; + font-family: $primary-font; + font-size: 14px; + line-height: 1.4em; + @include component-shadow; + border-color: $popover-background; +} + +.red-ui-popover:after, .red-ui-popover:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; +} +.red-ui-popover.red-ui-popover-right:after, .red-ui-popover.red-ui-popover-right:before { + top: 50%; + right: 100%; +} +.red-ui-popover.red-ui-popover-left:after, .red-ui-popover.red-ui-popover-left:before { + top: 50%; + left: 100%; +} + +.red-ui-popover.red-ui-popover-bottom:after, .red-ui-popover.red-ui-popover-bottom:before { + bottom: 100%; + left: 50%; +} + +.red-ui-popover.red-ui-popover-top:after, .red-ui-popover.red-ui-popover-top:before { + top: 100%; + left: 50%; +} + +.red-ui-popover.red-ui-popover-right:after { + border-color: transparent; + border-right-color: $popover-background; + border-width: 10px; + margin-top: -10px; +} +.red-ui-popover.red-ui-popover-right:before { + border-color: transparent; + border-right-color: $popover-background; + border-width: 11px; + margin-top: -11px; +} + +.red-ui-popover.red-ui-popover-left:after { + border-color: transparent; + border-left-color: $popover-background; + border-width: 10px; + margin-top: -10px; +} +.red-ui-popover.red-ui-popover-left:before { + border-color: transparent; + border-left-color: $popover-background; + border-width: 11px; + margin-top: -11px; +} + + +.red-ui-popover.red-ui-popover-bottom:after { + border-color: transparent; + border-bottom-color: $popover-background; + border-width: 10px; + margin-left: -10px; +} +.red-ui-popover.red-ui-popover-bottom:before { + border-color: transparent; + border-bottom-color: $popover-background; + border-width: 11px; + margin-left: -11px; +} + +.red-ui-popover.red-ui-popover-top:after { + border-color: transparent; + border-top-color: $popover-background; + border-width: 10px; + margin-left: -10px; +} +.red-ui-popover.red-ui-popover-top:before { + border-color: transparent; + border-top-color: $popover-background; + border-width: 11px; + margin-left: -11px; +} + + + +.red-ui-popover-size-small { + font-size: 12px; + padding: 5px 7px; + line-height: 1.8em; + + &.red-ui-popover-right:after, &.red-ui-popover-left:after { + border-width: 7px; + margin-top: -7px; + } + &.red-ui-popover-right:before, &.red-ui-popover-left:before { + border-width: 8px; + margin-top: -8px; + } + + &.red-ui-popover-bottom:after, &.red-ui-popover-top:after { + border-width: 7px; + margin-left: -7px; + } + &.red-ui-popover-bottom:before, &.red-ui-popover-top:before { + border-width: 8px; + margin-left: -8px; + } + +} + +.red-ui-popover-key { + font-size: 11px; + font-family: $monospace-font; + margin-left: 3px; + border: 1px solid $popover-color; + border-radius:3px; + padding: 1px 2px; +} + +.red-ui-popover a.red-ui-button, +.red-ui-popover button.red-ui-button { + &.primary { + border-color: $popover-button-border-color; + } + &.primary:not(.disabled):not(.ui-button-disabled):hover { + border-color: $popover-button-border-color-hover; + } +} +.red-ui-popover code { + border: none; + background: none; + color: $tertiary-text-color; +} + + +.red-ui-popover-panel { + @include component-shadow; + font-family: $primary-font; + font-size: $primary-font-size; + position: absolute; + box-sizing: border-box; + border: 1px solid $primary-border-color; + background: $secondary-background; + z-index: 2000; +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/projects.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/projects.scss new file mode 100644 index 0000000..9b1005f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/projects.scss @@ -0,0 +1,799 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#red-ui-projects-dialog { + .red-ui-editableList-container { + padding: 0px; + } + +} +#red-ui-project-settings-tab-settings { + overflow-y: scroll; +} +.red-ui-sidebar-vc-shade { + background: $primary-background; +} + +.red-ui-projects-edit-form form { + margin: 0; + .form-row { + margin-bottom: 15px; + label { + color: $primary-text-color; + width: 100%; + display: block; + &.red-ui-projects-edit-form-inline-label { + font-weight: normal; + color: inherit; + width: auto; + } + } + input[type=text], input[type=password],textarea { + width: 100%; + } + input[type=checkbox], input[type=radio] { + width: auto; + vertical-align: middle; + } + } + +} +.red-ui-projects-edit-form-sublabel { + color: $tertiary-text-color; + text-align: right; + margin-bottom: -15px; + font-weight: normal; +} +.red-ui-project-settings-tab-pane { + & * .red-ui-projects-edit-form-sublabel { + margin-right: 50px; + margin-top: -10px !important; + margin-bottom: 5px; + } +} + +.red-ui-projects-dialog-screen-start { + .red-ui-projects-dialog-screen-start-hero { + text-align: center; + font-size: 2em; + padding: 10px; + min-height: 60px; + color: $primary-text-color; + } + .red-ui-projects-dialog-screen-start-body { + min-height: 400px; + line-height: 1.6em; + p { + font-size: 1.1em; + margin-bottom: 20px; + } + p:first-child { + font-weight: 500; + font-size: 1.2em; + } + } + button.red-ui-button { + width: calc(50% - 80px); + margin: 20px; + height: auto; + line-height: 2em; + padding: 10px; + } + .button-group { + text-align: center; + } +} +.red-ui-projects-dialog-screen-create { + min-height: 500px; + button.red-ui-projects-dialog-screen-create-type { + height: auto; + padding: 10px; + } + .button-group { + text-align: center; + } +} + +.red-ui-projects-dialog-screen-secret { + min-height: auto; +} + +.red-ui-projects-dialog-credentials-box { + width: 550px; + > div { + vertical-align: top; + display: inline-block; + } +} +.red-ui-projects-dialog-credentials-box-right { + min-height:150px; + box-sizing: border-box; + float: right; + width: 331px; + margin-left: -1px; + padding: 15px; + margin-top: -15px; + border: 1px solid $secondary-border-color; + border-radius: 3px; +} +.red-ui-projects-dialog-credentials-box-left { + width: 220px; + > div { + padding: 7px 8px 3px 8px; + border: 1px solid $secondary-border-color; + border-radius: 4px; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-right-color: $form-background; + &.disabled { + border-color: $form-background; + border-right-color:$secondary-border-color; + } + i { + font-size: 1.4em; + margin-right: 8px; + vertical-align: middle; + } + label.red-ui-projects-edit-form-inline-label { + margin-left: 5px; + span { + vertical-align: middle; + } + } + input[type="radio"] { + vertical-align: middle; + margin-top:0; + margin-right: 10px; + } + + } +} +.red-ui-projects-dialog-credentials-box-enabled { +} +.red-ui-projects-dialog-credentials-box-disabled { +} + +.red-ui-projects-dialog-project-list-container { + border: 1px solid $secondary-border-color; + border-radius: 2px; +} +.red-ui-projects-dialog-project-list-inner-container { + height: 300px; + overflow-y: scroll; + position:relative; + .red-ui-editableList-border { + border: none; + } +} +.red-ui-projects-dialog-project-list { + li { + padding: 0 !important; + } +} +.red-ui-projects-dialog-project-list-entry { + padding: 12px 0; + + color: $list-item-color; + background: $list-item-background; + border-left: 3px solid $list-item-background; + border-right: 3px solid $list-item-background; + + &.projects-list-entry-current { + &:not(.selectable) { + color: $form-text-color; + background: $list-item-background-selected; + border-left-color:$list-item-border-selected; + border-right-color:$list-item-border-selected; + } + i { + color: $secondary-text-color; + } + } + &.selectable { + cursor: pointer; + &:hover:not(.selected) { + color: $form-text-color; + background: $list-item-background-hover; + border-left-color:$list-item-background-hover; + border-right-color:$list-item-background-hover; + } + } + .red-ui-projects-dialog-project-list-entry-icon { + i { + color: $tertiary-text-color; + font-size: 2em; + + } + } + &.selected { + color: $form-text-color; + background: $list-item-background-selected; + border-left-color:$list-item-border-selected; + border-right-color:$list-item-border-selected; + } + span { + display: inline-block; + vertical-align:middle; + } + .red-ui-projects-dialog-project-list-entry-icon { + margin: 0 10px 0 5px; + } + .red-ui-projects-dialog-project-list-entry-name { + font-size: 1.2em; + } + .red-ui-projects-dialog-project-list-entry-current { + float: right; + margin-right: 20px; + font-size: 0.9em; + color: $secondary-text-color; + padding-top: 4px; + } + .red-ui-projects-dialog-project-list-entry-tools { + position: absolute; + top: 16px; + right: 30px; + display: none; + color: $secondary-text-color; + } + &:hover { + .red-ui-projects-dialog-project-list-entry-tools { + display: block; + } + } +} +.red-ui-projects-dialog-screen-create-type.red-ui-button.toggle.selected:not(.disabled):not(:disabled) { + color: $secondary-text-color-active !important; +} +.red-ui-projects-dialog-screen-input-status { + text-align: right; + position: absolute; + top: 2px; + right: 8px; + width: 70px; + height: 30px; + color: $secondary-text-color; +} + +.red-ui-sidebar-vc { + height: 100%; +} + +.red-ui-sidebar-vc-stack { + position: absolute; + top: 0px; + bottom: 0; + left: 0; + right: 0; + overflow: hidden; + + .red-ui-palette-category { + &:not(.expanded) button { + display: none; + } + } +} + +#red-ui-project-settings-tab-deps { + .red-ui-editableList-container { + padding: 0; + } + .red-ui-editableList-border { + border-radius: 0; + } + .red-ui-editableList-item-content { + padding: 0px 6px; + } + .red-ui-palette-module-header { + padding: 6px 4px; + } + .red-ui-palette-module-button { + float: right; + } + .red-ui-palette-module-unused { + & > * { + color: $secondary-text-color; + } + } + .red-ui-palette-module-unknown { + border: 1px dashed $secondary-border-color; + background: $secondary-background-inactive; + } + .red-ui-palette-module-not-installed { + border: 1px dashed $text-color-warning; + i.fa-warning { + color: $text-color-warning; + } + } +} + + +.red-ui-project-settings-tab-pane { + position: absolute; + top:0; + left:0; + right:0; + bottom:0; + overflow-y: auto; + padding: 8px 20px 20px; +} +.red-ui-sidebar-vc { + .red-ui-editableList-container { + background: $tertiary-background; + padding: 0; + li { + padding:0; + background: $secondary-background; + } + } + .red-ui-editableList-border { + border: none; + border-radius: 0; + } +} + +.red-ui-sidebar-vc-change-container { + position: relative; + height: 50%; + box-sizing: border-box; + transition: height 0.2s ease-in-out; + &:first-child { + // border-bottom: 1px solid $primary-border-color; + } +} +.red-ui-sidebar-vc-merging { + .red-ui-sidebar-vc-change-container { + height: 33%; + } +} +.red-ui-sidebar-vc-slide-box { + position:absolute; + bottom: 0; + left:0; + right:0; + height:0; + transition: height 0.2s ease-in-out; + background: $tertiary-background; + box-sizing: border-box; + overflow: hidden; + &.red-ui-sidebar-vc-slide-box-top { + z-index: 4; + top: 0px; + left: auto; + width: 100%; + max-width: 280px; + border-left: 1px solid $primary-border-color; + border-right: 1px solid $primary-border-color; + border-bottom: 1px solid $primary-border-color; + box-shadow: 1px 1px 4px $shadow; + + color: $primary-text-color; + background: $tertiary-background; + padding: 10px; + box-sizing: border-box; + + } + &.red-ui-sidebar-vc-slide-box-bottom { + bottom: 0px; + border-top: 1px solid $secondary-border-color; + } + + textarea { + height: 110px; + margin: 10px; + width: calc(100% - 20px); + box-sizing: border-box; + border-radius: 1px; + resize: none; + } + +} +.red-ui-projects-branch-list { + position: relative; + .red-ui-searchBox-container { + border-top: 1px solid $secondary-border-color; + border-left: 1px solid $secondary-border-color; + border-right: 1px solid $secondary-border-color; + border-top-left-radius: 2px; + border-top-right-radius: 2px; + overflow: hidden; + } + .red-ui-editableList { + border: 1px solid $secondary-border-color; + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; + & > .red-ui-editableList-border { + border-radius: 0; + border: none; + } + .red-ui-editableList-container { + padding: 0; + li { + padding: 0; + background: $secondary-background; + } + } + } +} +.uneditable-input .red-ui-projects-branch-list { + .red-ui-editableList { + border-left: none; + border-bottom: none; + border-right: none; + } + .red-ui-searchBox-container { + border-left: none; + border-right: none; + } +} +.red-ui-sidebar-vc-slide-box-header { + margin-bottom: 10px; +} + +.red-ui-sidebar-vc-slide-box-toolbar { + padding: 0 20px; + text-align: right; +} +.red-ui-sidebar-vc-branch-list-entry { + padding: 5px 8px; + margin: 0 1px; + color: $list-item-color; + background: $list-item-background; + border-left: 2px solid $list-item-background; + border-right: 2px solid $list-item-background; + cursor: pointer; + &.selected { + border-left-color:$list-item-border-selected; + border-right-color:$list-item-border-selected; + } + i { width: 16px; text-align: center} + &.input-error { + cursor: default; + } + &:not(.input-error):hover { + background: $list-item-background-hover; + border-left-color:$list-item-border-selected; + border-right-color:$list-item-border-selected; + } + span { + margin-left: 5px; + } + span.current { + float: right; + font-size: 0.8em; + color: $tertiary-text-color; + } +} + +.red-ui-sidebar-vc-change-entry { + height: 20px; + padding: 5px 10px; + position: relative; + white-space: nowrap; + span { + margin: 0 6px; + } + a { + color: currentColor; + &.disabled { + pointer-events: none; + } + } + .red-ui-sidebar-vc-change-entry-tools { + position: absolute; + top: 4px; + right: 4px; + display: none; + button { + width: 24px; + } + } + + &:hover { + .red-ui-sidebar-vc-change-entry-tools { + display: block; + } + } + &.red-ui-help-info-node { + text-align: center; + background: $list-item-background; + white-space: normal; + height: auto; + } +} + +.red-ui-sidebar-vc-commit-entry { + min-height: 20px; + padding: 5px 10px; + position: relative; + white-space: nowrap; + overflow: hidden; + cursor: pointer; + &:hover { + background: $secondary-background-hover; + } +} +.red-ui-sidebar-vc-commit-more { + color: $secondary-text-color; + text-align: center; + padding: 10px; + font-style: italic; +} +.red-ui-sidebar-vc-commit-sha { + float: right; + font-family: $monospace-font; + color: $vcCommitShaColor; + display: inline-block; + font-size: 0.85em; + margin-left: 5px; +} +.red-ui-sidebar-vc-commit-subject { + color: $primary-text-color; +} +.red-ui-sidebar-vc-commit-refs { + min-height: 22px; +} +.red-ui-sidebar-vc-commit-ref { + color: $tertiary-text-color; + font-size: 0.7em; + border: 1px solid $tertiary-border-color; + border-radius: 10px; + padding: 2px 5px; + margin-right: 5px; +} +.red-ui-sidebar-vc-commit-date { + color: $secondary-text-color; + font-size: 0.85em; +} +.red-ui-sidebar-vc-commit-user { + float: right; + color: $secondary-text-color; + font-size: 0.85em; +} +.red-ui-sidebar-vc-commit-head { +} +.red-ui-sidebar-vc-change-header { + color: $primary-text-color; + background: $tertiary-background; + padding: 4px 10px; + height: 30px; + box-sizing: border-box; + border-top: 1px solid $secondary-border-color; + border-bottom: 1px solid $secondary-border-color; + i { + transition: all 0.2s ease-in-out; + } +} +.red-ui-sidebar-vc-repo-toolbar { + color: $primary-text-color; + background: $tertiary-background; + padding: 10px; + box-sizing: border-box; +} + +.red-ui-sidebar-vc-repo-count { + margin-right: 8px; + display: none; +} +.red-ui-sidebar-vc-repo-action { + text-align: left; + width: 100%; +} +.red-ui-sidebar-vc-repo-sub-action { + width: calc(50% - 5px); + margin-right: 5px; + &:not(:first-child) { + margin-right: 0; + margin-left: 5px; + } +} + +.red-ui-projects-file-listing-container > .red-ui-editableList > .red-ui-editableList-border { + border-radius: 0; + border: none; + border-top: 1px solid $secondary-border-color; + +} +.red-ui-editableList-container .red-ui-projects-dialog-file-list { + .red-ui-editableList-border { + border: none; + } + li { + padding: 0 !important; + border: none; + } + .red-ui-editableList-container { + padding: 0; + } +} +.red-ui-projects-dialog-file-list-entry { + padding: 3px 0; + border-left: 2px solid $list-item-background; + border-right: 2px solid $list-item-background; + background: $list-item-background; + + &.projects-list-entry-current { + &:not(.selectable) { + background: $list-item-background-selected; + } + i { + color: $secondary-text-color-selected; + } + } + &.selectable { + cursor: pointer; + &:hover { + background: $list-item-background-hover; + border-left-color:$list-item-border-selected; + border-right-color:$list-item-border-selected; + } + } + &.unselectable { + color: $secondary-text-color-disabled; + } + + i { + color: $secondary-text-color; + width: 16px; + text-align: center; + } + &.selected { + background: $list-item-background-selected; + border-left-color:$list-item-border-selected; + border-right-color:$list-item-border-selected; + } + span { + display: inline-block; + vertical-align:middle; + } + .red-ui-projects-dialog-file-list-entry-folder { + margin: 0 10px 0 0px; + + .fa-angle-right { + color: $primary-text-color; + transition: all 0.2s ease-in-out; + + } + } + .red-ui-projects-dialog-file-list-entry-file { + margin: 0 10px 0 20px; + } + .red-ui-projects-dialog-file-list-entry-name { + font-size: 1em; + } + &.expanded .fa-angle-right { + transform: rotate(90deg); + } +} +.red-ui-projects-dialog-file-list-entry-file-type-git { color: $tertiary-text-color } + +.red-ui-projects-dialog-remote-list { + .red-ui-editableList-container { + padding: 0; + li { + padding: 0; + border: none; + border-radius: 4px; + overflow: hidden; + } + } +} + +div.red-ui-projects-dialog-ssh-public-key { + position: relative; + padding: 15px 20px 0; + pre { + position: relative; + word-break: break-all; + } + &:after { + content: ""; + display: table; + clear: both; + } +} + +.red-ui-projects-dialog-ssh-key-list { + li { + padding: 0 !important; + } + .red-ui-projects-dialog-ssh-key-header { + padding: 10px 5px; + cursor: pointer; + &:hover { + background: $list-item-background-hover; + } + } +} + +.red-ui-projects-dialog-list { + position: relative; + .red-ui-editableList-container { + padding: 1px; + background: $tertiary-background; + li:last-child { + border-bottom: none; + } + } +} + +.red-ui-projects-dialog-list-entry { + &.red-ui-search-empty { + padding: 0; + } + + span { + display: inline-block; + } + .entry-icon { + text-align: center; + min-width: 30px; + vertical-align: top; + color: $secondary-text-color; + } + .entry-name { + min-width: 250px; + } + &.current .entry-name { + font-weight: bold; + } + .entry-detail { + color: $tertiary-text-color; + font-size: 0.9em; + } + + .entry-remote-name { + min-width: 250px; + } + + + .entry-tools { + float: right; + margin-right: 10px; + } +} +.red-ui-projects-dialog-list-dialog { + position: relative; + margin-top: 10px; + margin-bottom: 20px; + background: $secondary-background; + border-radius: 4px; + border: 1px solid $secondary-border-color; + .red-ui-projects-edit-form-sublabel { + margin-top: -8px !important; + display: block !important; + width: auto !important; + } + &:after { + content: ""; + display: table; + clear: both; + } + + .red-ui-projects-dialog-list-dialog-header { + font-weight: bold; + background: $primary-background; + margin-top: 0 !important; + padding: 5px 10px; + margin-bottom: 10px; + } +} + +#red-ui-settings-tab-gitconfig { + padding: 8px 20px 20px; +} +.red-ui-settings-section-description { + color: $secondary-text-color; +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/radialMenu.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/radialMenu.scss new file mode 100644 index 0000000..1149194 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/radialMenu.scss @@ -0,0 +1,54 @@ +/** +* Copyright JS Foundation and other contributors, http://js.foundation +* +* Licensed under the Apache License, Version 2.0 (the License); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + +.red-ui-editor-radial-menu { + font-size: $primary-font-size; + font-family: $primary-font; + position: absolute; + top: 0; + left:0; + bottom:0; + right:0; + z-index: 1000; + + & > div { + position: absolute; + border-radius: 80px; + width: 160px; + height: 160px; + background: $shadow; + border: 1px solid $primary-border-color; + } +} + +.red-ui-editor-radial-menu-opt { + position: absolute; + border-radius: 20px; + width: 50px; + height: 50px; + background: $secondary-background; + border: 2px solid $primary-border-color; + text-align: center; + line-height:50px +} + +.red-ui-editor-radial-menu-opt-disabled { + border-color: $tertiary-border-color; + color: $tertiary-border-color; +} +.red-ui-editor-radial-menu-opt-active { + background: $secondary-background-hover; +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/search.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/search.scss new file mode 100644 index 0000000..0ec8b65 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/search.scss @@ -0,0 +1,206 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +.red-ui-search { + z-index:1000; + display: none; + position: absolute; + width: 500px; + left: 50%; + margin-left: -250px; + top: 0px; + border: 1px solid $primary-border-color; + box-shadow: 0 0 10px $shadow; +} + +.red-ui-type-search { + box-shadow: 0 1px 6px -3px black; + background: none; + width: 300px; + margin-left: 0px; + //height: 75px; + border: none; + .red-ui-search-container { + border-top-left-radius: 5px; + border-top-right-radius: 5px; + border: 1px dashed $primary-border-color; + border-bottom: none; + padding: 0; + } + .red-ui-search-results-container { + display: none; + height: 150px; + .red-ui-editableList-container { + border: 1px dashed $primary-border-color; + border-top: 1px solid $secondary-border-color; + } + } + .red-ui-search-result { + padding: 2px 2px 2px 5px; + font-size: 13px; + border-left-width: 3px; + border-right-width: 3px; + .red-ui-palette-icon-fa { + position: relative; + top: -2.5px; + left: 0px; + } + } + .red-ui-search-result-separator { + border-bottom: 3px solid $secondary-border-color; + } + .red-ui-search-result-node { + position: relative; + width: 18px; + height: 15px; + margin-top: 1px; + } + .red-ui-search-result-node-port { + position: absolute; + border-radius: 2px; + border: 1px solid $node-border;; + width: 6px; + height: 7px; + top:4px; + left:-4px; + background: $node-port-background; + box-sizing: border-box; + } + .red-ui-search-result-node-output{ + left: 16px; + } + .red-ui-palette-icon-container { + width: 18px; + } + .red-ui-palette-icon { + width: 15px; + } + .red-ui-search-result-description { + margin-left:28px; + } + .red-ui-search-result-node-label { + color: $secondary-text-color; + } +} + +.red-ui-search-container { + padding: 3px; + background: $form-input-background; + border-bottom: 1px solid $secondary-border-color; +} +.red-ui-search-results-container { + position:relative; + height: 300px; + padding: 5px; + background: $primary-background; + .red-ui-search-results-list { + + } + .red-ui-editableList-container { + padding: 0; + background: $primary-background; + li { + padding: 0; + } + } +} +.red-ui-search-result { + padding: 8px 2px 8px 5px; + display: block; + cursor: pointer; + color: $list-item-color; + background: $list-item-background; + border-left: 3px solid $list-item-background; + border-right: 3px solid $list-item-background; + li.selected & { + background: $list-item-background-selected; + border-left-color: $list-item-border-selected; + border-right-color: $list-item-border-selected; + } + &:hover { + text-decoration: none; + color: $form-text-color; + background: $list-item-background-hover; + border-left-color:$list-item-background-hover; + border-right-color:$list-item-background-hover; + } + &:after { + content: ""; + display: table; + clear: both; + } + .red-ui-palette-icon-fa { + top: 6px; + left: 3px; + } +} + +.red-ui-search-result-node { + display: inline-block; + width: 30px; + float:left; + height: 25px; + border-radius: 5px; + border: 1px solid $node-border; + background-position: 5% 50%; + background-repeat: no-repeat; + background-size: contain; + position: relative; + + .red-ui-palette-icon-container { + border-right: none; + } + +} +.red-ui-search-result-node-description { + margin-left: 40px; + margin-right: 5px; +} +.red-ui-search-result-node-label { + color: $primary-text-color; +} +.red-ui-search-result-node-type { + font-style: italic; + font-size: 0.9em; + color: $tertiary-text-color; +} +.red-ui-search-result-node-flow { + float:right; + font-size: 0.8em; + color: $tertiary-text-color; +} +.red-ui-search-result-node-id { + display:none; + font-size: 0.8em; + color: $tertiary-text-color; +} +.red-ui-search-empty { + padding: 10px; + text-align: center; + font-style: italic; + color: $form-placeholder-color; +} + +.red-ui-search-result-action { + color: $primary-text-color; +} +.red-ui-search-result-action-key { + position: absolute; + top: 9px; + right: 0; + margin-right: 10px; + color: $tertiary-text-color; +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/sidebar.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/sidebar.scss new file mode 100644 index 0000000..d855271 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/sidebar.scss @@ -0,0 +1,143 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#red-ui-sidebar { + position: absolute; + top: 0px; + right: 0px; + bottom: 0px; + width: 315px; + background: $primary-background; + box-sizing: border-box; + z-index: 10; + @include component-border; +} + +#red-ui-sidebar.closing { + border-style: dashed; +} + +#red-ui-sidebar-content { + position: absolute; + background: $secondary-background; + top: 35px; + right: 0; + bottom: 25px; + left: 0px; + overflow-y: auto; +} + +#red-ui-sidebar-separator { + position: absolute; + top: 5px; + right: 315px; + bottom:10px; + width: 7px; + z-index: 11; + background: $primary-background url(images/grip.png) no-repeat 50% 50%; + cursor: col-resize; +} + +.red-ui-sidebar-closed > #red-ui-sidebar { display: none; } +.red-ui-sidebar-closed > #red-ui-sidebar-separator { right: 0px !important; } +.red-ui-sidebar-closed > #red-ui-workspace { right: 7px !important; } +.red-ui-sidebar-closed > #red-ui-editor-stack { right: 8px !important; } + +#red-ui-sidebar .button { + @include workspace-button; + line-height: 18px; + font-size: 12px; + margin-right: 5px; + padding: 2px 8px; +} + +.sidebar-header, /* Deprecated -> red-ui-sidebar-header */ +.red-ui-sidebar-header { + color: $primary-text-color; + text-align: right; + padding: 8px 10px; + background: $primary-background; + border-bottom: 1px solid $secondary-border-color; + white-space: nowrap; +} + +/* Deprecated -> red-ui-footer-button */ +.sidebar-footer-button { + @include component-footer-button; +} +/* Deprecated -> red-ui-footer-button-toggle */ +.sidebar-footer-button-toggle { + @include component-footer-button-toggle; +} + +a.sidebar-header-button, +button.sidebar-header-button, /* Deprecated -> red-ui-sidebar-header-button */ +a.red-ui-sidebar-header-button, +button.red-ui-sidebar-header-button { + @include workspace-button; + font-size: 13px; + line-height: 13px; + padding: 5px 8px; + &.toggle { + @include workspace-button-toggle; + } +} + +a.sidebar-header-button-toggle, /* Deprecated -> red-ui-sidebar-header-button-toggle */ +button.sidebar-header-button-toggle, /* Deprecated -> red-ui-sidebar-header-button-toggle */ +a.red-ui-sidebar-header-button-toggle, +button.red-ui-sidebar-header-button-toggle { + @include workspace-button-toggle; + font-size: 13px; + line-height: 13px; + padding: 5px 8px; +} + +.sidebar-header-button:not(:first-child), /* Deprecated -> red-ui-sidebar-header-button */ +.red-ui-sidebar-header-button:not(:first-child) { + border-left: none; +} + +.red-ui-sidebar-shade { + @include shade; +} + + +@mixin red-ui-sidebar-control { + display: none; + position: absolute; + top: calc(50% - 26px); + + padding:15px 8px; + border:1px solid $primary-border-color; + background:$primary-background; + color: $secondary-text-color; + text-align: center; + cursor: pointer; +} + +.red-ui-sidebar-control-right { + @include red-ui-sidebar-control; + right: calc(100%); + border-top-left-radius: 5px; + border-bottom-left-radius: 5px; +} +.red-ui-sidebar-control-left { + @include red-ui-sidebar-control; + left: calc(100%); + border-top-right-radius: 5px; + border-bottom-right-radius: 5px; +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/style.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/style.scss new file mode 100644 index 0000000..088e5c1 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/style.scss @@ -0,0 +1,69 @@ +/** +* Copyright JS Foundation and other contributors, http://js.foundation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + +@import "colors"; +@import "mixins"; + +@import "base"; +@import "forms"; + +@import "jquery"; +@import "ace"; + +@import "dropdownMenu"; + +@import "header"; +@import "palette"; +@import "sidebar"; +@import "workspace"; +@import "workspaceToolbar"; + +@import "notifications"; + +@import "editor"; +@import "library"; +@import "search"; + +@import "panels"; +@import "tabs"; +@import "tab-config"; +@import "tab-context"; +@import "tab-info"; +@import "popover"; +@import "flow"; +@import "palette-editor"; +@import "diff"; + +@import "userSettings"; + +@import "projects"; + + +@import "ui/common/editableList"; +@import "ui/common/searchBox"; +@import "ui/common/typedInput"; +@import "ui/common/nodeList"; +@import "ui/common/checkboxSet"; +@import "ui/common/stack"; +@import "ui/common/treeList"; + +@import "dragdrop"; + +@import "keyboard"; + +@import "debug"; + +@import "radialMenu"; diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss new file mode 100644 index 0000000..f88cbfd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss @@ -0,0 +1,115 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +.red-ui-sidebar-node-config { + position: relative; + background: $secondary-background; + height: 100%; + overflow-y:auto; + @include disable-selection; +} + +ul.red-ui-sidebar-node-config-list { + margin: 0; + padding: 0; + list-style-type: none; + li { + padding: 0; + margin: 0; + text-align: center; + } + .red-ui-palette-node { + overflow: hidden; + + &.selected { + border-color: transparent; + box-shadow: 0 0 0 2px $node-selected-color; + } + } + .red-ui-palette-label { + margin-left: 8px; + line-height: 24px; + text-align: left; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + .red-ui-palette-icon-container { + font-size: 12px; + line-height: 30px; + background-color: $secondary-background-selected; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + a { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + color: $secondary-text-color; + &:hover { + text-decoration: none; + background: $secondary-background-hover; + } + } + } +} +.red-ui-palette-node-config { + width: 160px; + height: 30px; + background: $primary-background; + color: $primary-text-color; + cursor: pointer; +} +ul.red-ui-sidebar-node-config-list li.red-ui-palette-node-config-type { + color: $secondary-text-color; + text-align: right; + padding-right: 3px; + &:not(:first-child) { + margin-top: 20px; + } +} +.red-ui-palette-node-config-none { + color: $tertiary-text-color; + text-align:right; + padding-right: 3px; +} +.red-ui-palette-node-config-unused,.red-ui-palette-node-config-disabled { + border-color: $primary-border-color; + background: $secondary-background-inactive; + border-style: dashed; + color: $tertiary-text-color; +} +.red-ui-palette-node-config-disabled { + opacity: 0.6; + font-style: italic; + i { + color: $secondary-text-color; + margin-right: 5px; + } +} +.red-ui-sidebar-node-config-filter-info { + position: absolute; + top: 0; + right:0; + height: 38px; + line-height: 38px; + padding: 0 8px; + background: $palette-header-background; + font-size: 0.8em; + color: $secondary-text-color; + font-weight: normal; +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/tab-context.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/tab-context.scss new file mode 100644 index 0000000..4be9761 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/tab-context.scss @@ -0,0 +1,67 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +.red-ui-sidebar-context-stack { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + overflow-y: scroll; + + .red-ui-palette-category { + &:not(.expanded) button { + display: none; + } + } + + .red-ui-info-table { + table-layout: fixed; + } + + table.red-ui-info-table tr:not(.blank) td:first-child { + width: 30%; + } + table.red-ui-info-table tr:not(.blank) td:last-child { + vertical-align: top; + } + +} + +.red-ui-sidebar-context-property { + overflow-wrap: break-word; + position: relative; + .red-ui-debug-msg-tools { + right: 0px; + margin-right: 5px; + display: none; + } + &:hover .red-ui-debug-msg-tools { + display: inline-block; + } +} +.red-ui-sidebar-context-updated { + text-align: right; + font-size: 11px; + color: $tertiary-text-color; + padding: 1px 3px; +} +.red-ui-sidebar-context-property-storename { + display: block; + font-size: 0.8em; + font-style: italic; + color: $tertiary-text-color; +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss new file mode 100644 index 0000000..bc72f75 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss @@ -0,0 +1,281 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +.red-ui-sidebar-info hr { + margin: 10px 0; +} +table.red-ui-info-table { + font-size: 14px; + margin: 0 0 10px; + width: 100%; +} +table.red-ui-info-table tr:not(.blank) { + border-top: 1px solid $secondary-border-color; + border-bottom: 1px solid $secondary-border-color; +} +.red-ui-help-property-expand { + font-size: 0.8em; + text-align: right; + line-height: 0.9em; + a { + padding-bottom: 5px; + } + +} +table.red-ui-info-table tr.blank { + border: none; + th { + text-align: left; + font-weight: 500; + color: $primary-text-color; + padding: 6px 3px 3px; + } + >* { + padding-top: 8px; + border: none; + padding-left: 0px; + } + + + a { + display: block; + color: $primary-text-color; + &:hover,&:focus { + color: $primary-text-color; + text-decoration: none; + } + &:not(.expanded) { + .red-ui-help-property-more { + display: inline; + } + .red-ui-help-property-less { + display: none; + } + } + i { + width: 10px; + text-align: center; + transition: transform 0.2s ease-in-out; + } + + &.expanded { + .red-ui-help-property-more { + display: none; + } + .red-ui-help-property-less { + display: inline; + } + i { + transform: rotate(180deg); + } + } + } +} +.red-ui-help-info-none { + font-style: italic; + color: $tertiary-text-color; +} +table.red-ui-info-table tr:not(.blank) td:first-child{ + color: $header-text-color; + vertical-align: top; + width: 90px; + padding: 3px 3px 3px 6px; + background:$tertiary-background; + border-right: 1px solid $secondary-border-color; +} +table.red-ui-info-table tr:not(.blank) td:last-child{ + padding: 3px 3px 3px 6px; + color: $primary-text-color; + overflow-y: hidden; +} +div.red-ui-info-table { + margin: 5px; +} +.red-ui-help { + font-size: $primary-font-size; + line-height: 1.5em; + + a { + color: $info-text-link-color; + text-decoration: none; + } + + a:hover, + a:focus { + color: $info-text-link-color; + text-decoration: underline; + } + + + h1 { + font-weight: 500; + font-size: 1.296em; + line-height: 1.3em; + margin: 8px auto; + } + h2 { + font-weight: 500; + font-size: 1.215em; + margin: 8px auto; + line-height: 1.3em; + } + h3 { + font-weight: 500; + font-size: 1.138em; + margin: 7px auto 5px; + line-height: 1.3em; + } + h4, + h5 { + font-weight: 500; + font-size: 1.067em; + line-height: 1.3em; + margin: 8px auto 5px; + } + & > span > p:first-child { + } + dl.message-properties { + border: 1px solid $secondary-border-color; + border-radius: 2px; + + margin: 5px auto 10px; + &>dt { + padding: 0px 3px 2px 3px; + font-family: $monospace-font; + font-weight: normal; + margin: 5px 3px 1px; + color: $text-color-warning; + white-space: nowrap; + &.optional { + font-style: italic; + + } + .property-type { + font-family: $primary-font; + color: $primary-text-color; + font-style: italic; + font-size: 11px; + float: right; + } + &:after { + content: ""; + display: table; + clear: both; + } + } + &>dd { + margin: 0px 8px 2px 13px; + vertical-align: top; + } + } + ol.node-ports { + margin: 0; + li { + border: 1px solid $secondary-border-color; + border-radius: 2px; + list-style-position: inside; + padding: 3px; + margin-bottom: 5px; + dl.message-properties { + border: none; + } + } + } + .red-ui-help-info-header { + i { + width: 10px; + text-align: center; + transition: transform 0.2s ease-in-out; + margin-right: 4px; + } + color: $header-text-color; + &:hover, &:focus { + text-decoration: none; + } + &.expanded { + i { + transform: rotate(90deg); + } + } + } + +} +.red-ui-sidebar-info-stack { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + overflow-y: scroll; +} +.red-ui-help-tips { + display: none; + position: absolute; + left:0; + right:0; + bottom: 0; + height: 150px; + box-sizing: border-box; + border-top: 1px solid $secondary-border-color; + background-color: $secondary-background; + padding: 20px; + box-shadow: 0 5px 20px 0px $shadow; + overflow-y: auto; +} +.red-ui-sidebar-info.show-tips { + .red-ui-sidebar-info-stack { + bottom: 150px; + } + .red-ui-help-tips { + display: block; + } +} + +.red-ui-help-tips:before { + content: ''; + display: inline-block; + height: 100%; + vertical-align: middle; + margin-right: -0.25em; /* Adjusts for spacing */ +} + +.red-ui-help-tip { + display: inline-block; + vertical-align: middle; + width: 100%; + font-size: 16px; + text-align: center; + line-height: 1.9em; + color : $tertiary-text-color; + @include disable-selection; + cursor: default; +} +.red-ui-help-tips-buttons { + position: absolute; + top: 4px; + right: 6px; + a { + color: $secondary-text-color; + border-color: $secondary-border-color !important; + margin-left: 4px; + } +} + +.node-info-property-config-node { + border: 1px solid $secondary-border-color; + border-radius: 4px; + padding: 2px 4px 2px; +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/tabs.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/tabs.scss new file mode 100644 index 0000000..53358ac --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/tabs.scss @@ -0,0 +1,362 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +.red-ui-tabs { + position: relative; + background: $tab-background; + overflow: hidden; + height: 35px; + box-sizing: border-box; + + .red-ui-tabs-scroll-container { + height: 60px; + overflow-x: scroll; + overflow-y: hidden; + &::-webkit-scrollbar { + display: none; + } + } + & ul { + list-style-type: none; + padding:0; + margin: 0; + display: block; + height: 35px; + box-sizing:border-box; + border-bottom: 1px solid $primary-border-color; + white-space: nowrap; + @include disable-selection; + + li { + box-sizing: border-box; + display: inline-block; + border-left: 1px solid $primary-border-color; + border-top: 1px solid $primary-border-color; + border-right: 1px solid $primary-border-color; + border-bottom: 1px solid $primary-border-color; + background: $tab-background-inactive; + margin: 3px 3px 0 3px; + height: 32px; + line-height: 29px; + max-width: 200px; + width: 14%; + overflow: hidden; + white-space: nowrap; + position: relative; + &.red-ui-tabs-closeable:hover { + .red-ui-tabs-badges { + display: none; + } + .red-ui-tab-close { + display: block; + } + } + a.red-ui-tab-label { + display: block; + font-size: 14px; + padding-left: 12px; + width: 100%; + height: 100%; + color: $tab-text-color-inactive; + } + a:hover { + text-decoration: none; + } + a:focus { + text-decoration: none; + } + + &:not(.active) a:hover+a.red-ui-tab-close { + background: $tab-background-hover; + } + &.active { + background: $tab-background-active; + font-weight: bold; + border-bottom: 1px solid $tab-background-active; + z-index: 2; + + a { + color: $tab-text-color-active; + } + a.red-ui-tab-close { + color: $workspace-button-color; + background: $tab-background-active; + &:hover { + background: $workspace-button-background-hover !important; + color: $workspace-button-color-hover; + } + } + img.red-ui-tab-icon { + opacity: 0.2; + } + } + &.selected { + &:not(.active) { + background: $tab-background-selected; + } + font-weight: bold; + .red-ui-tabs-badge-selected { + display: inline; + background: $tab-background; + } + .red-ui-tabs-badge-changed { + display: none; + } + + } + &:not(.active) a:hover { + color: $workspace-button-color-hover; + background: $tab-background-hover; + } + } + } + &.red-ui-tabs-scrollable { + padding-left: 21px; + padding-right: 21px; + } + &.red-ui-tabs-add { + padding-right: 35px; + } + &.red-ui-tabs-add.red-ui-tabs-scrollable { + padding-right: 59px; + } + &.red-ui-tabs-add.red-ui-tabs-search.red-ui-tabs-scrollable { + padding-right: 95px; + } + + &.red-ui-tabs-collapsible { + li:not(.active) { + display: none; + &.red-ui-tab-pinned { + a { + padding-left: 0; + text-align: center; + } + span { + display: none; + } + width: 32px; + } + } + } + + &.red-ui-tabs-vertical { + box-sizing: border-box; + height: 100%; + border-right: 1px solid $primary-border-color; + margin: 0; + background: $tertiary-background; + overflow: visible; + + .red-ui-tabs-scroll-container { + height: auto; + overflow-x:visible; + overflow-y: scroll; + } + + & ul { + padding: 0; + height: auto; + border: none; + width: calc(100% + 1px); + li { + width: 100%; + display: block; + margin: 0; + border: none; + border-right: 1px solid $primary-border-color; + height: auto; + &:not(:first-child) { + border-top: 1px solid $secondary-border-color; + } + &:last-child { + border-bottom: 1px solid $secondary-border-color; + } + + a.red-ui-tab-label { + padding: 9px; + } + + &.active { + border-right: 1px solid $tab-background-active; + } + } + } + } + .red-ui-tabs-select { + position: absolute; + top:0; + bottom: 0; + left: 0; + right: 0; + opacity: 0.4; + background: red; + } +} +.red-ui-tab-button { + position: absolute; + box-sizing: border-box; + top: 0; + right: 0; + height: 35px; + background: $tab-background; + border-bottom: 1px solid $primary-border-color; + z-index: 2; + + a { + @include workspace-button; + line-height: 32px; + height: 32px; + width: 32px; + margin-top: 3px; + margin-right:3px; + margin-left:3px; + border: 1px solid $primary-border-color; + z-index: 2; + } +} +.red-ui-tab-link-buttons { + position: absolute; + box-sizing: border-box; + top: 0; + right: 0; + height: 35px; + background: $tab-background; + border-bottom: 1px solid $primary-border-color; + z-index: 2; + a { + @include workspace-button-toggle; + line-height: 26px; + height: 28px; + width: 28px; + margin: 4px 3px 3px; + z-index: 2; + &.red-ui-tab-link-button-menu { + border-color: $tab-background; + } + &:not(.single):not(.selected) { + margin-top: 4px; + } + } +} +.red-ui-tab-scroll { + width: 21px; + top: 0; + a { + height: 35px; + width: 21px; + display: block; + color: $workspace-button-color; + font-size: 22px; + text-align: center; + margin:0; + border-left: none; + border-right: none; + border-top: none; + } +} +.red-ui-tab-scroll-left { + left:0; + a { + border-right: 1px solid $primary-border-color; + } +} +.red-ui-tab-scroll-right { + right: 0px; + a { + border-left: 1px solid $primary-border-color; + } + +} +.red-ui-tabs.red-ui-tabs-add .red-ui-tab-scroll-right { + right: 38px; +} + +.red-ui-tabs.red-ui-tabs-add.red-ui-tabs-search .red-ui-tab-scroll-right { + right: 76px; +} +.red-ui-tabs.red-ui-tabs-add.red-ui-tabs-search .red-ui-tabs-add { + right: 38px; +} + + +img.red-ui-tab-icon { + margin-left: -8px; + margin-right: 3px; + margin-top: -2px; + opacity: 0.1; + width: 20px; + height: 20px; + vertical-align: middle; +} +i.red-ui-tab-icon { + opacity: 0.7; + width: 18px; + height: 20px; +} + +.red-ui-tabs-badges { + position: absolute; + top:0px; + right:0px; + width: 20px; + pointer-events: none; + display: block; + height: 30px; + line-height: 28px; + text-align: center; + padding:0px; + color: $tab-badge-color; +} + +.red-ui-tabs-badges i { + display: none; +} + +.red-ui-tab.node_changed img.node_changed { + display: inline-block; +} +.red-ui-tab.node_error img.node_error { + display: inline-block; +} + +.red-ui-tabs-badges img { + width: 10px; + height: 10px; + margin-right: 2px; + vertical-align: top; + +} + +.red-ui-tab-close { + display: none; + background: $tab-background-inactive; + opacity: 0.8; + position: absolute; + right: 0px; + top: 0px; + width: 20px; + height: 30px; + line-height: 28px; + text-align: center; + padding: 0px; + color: $workspace-button-color; + &:hover { + background: $workspace-button-background-hover !important; + color: $workspace-button-color-hover; + opacity: 1; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/checkboxSet.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/checkboxSet.scss new file mode 100644 index 0000000..8858e47 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/checkboxSet.scss @@ -0,0 +1,29 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +.red-ui-checkboxSet { + width: 15px; + display: inline-block; + color: $secondary-text-color; + cursor: pointer; + input { + display:none; + } + + &.disabled { + pointer-events: none; + color: $secondary-text-color-disabled; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/editableList.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/editableList.scss new file mode 100644 index 0000000..a5873f6 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/editableList.scss @@ -0,0 +1,75 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +.red-ui-editableList-border { + border: 1px solid $form-input-border-color; + border-radius: 4px; + .red-ui-editableList-header { + border-bottom: 1px solid $form-input-border-color; + padding: 2px 16px 2px 4px; + font-size: 0.9em; + } +} +.red-ui-editableList-container { + padding: 5px; + margin: 0; + vertical-align: middle; + box-sizing: border-box; + .red-ui-editableList-list { + list-style-type:none; + margin: 0; + } + .red-ui-editabelList-item-placeholder { + border: 2px dashed $secondary-border-color !important; + } + li { + box-sizing: border-box; + position: relative; + background: $secondary-background; + margin:0; + padding:8px 0px; + border-bottom: 1px solid $secondary-border-color; + min-height: 20px; + .red-ui-editableList-item-handle { + position: absolute; + top: 50%; + left: 2px; + margin-top: -7px; + color: $tertiary-text-color; + cursor: move; + } + .red-ui-editableList-item-remove { + position: absolute; + top: 50%; + right: 0px; + margin-top: -9px; + } + &.ui-sortable-helper { + border-top: 1px solid $secondary-border-color; + } + //.red-ui-editableList-item-content { outline: 1px solid red} + + &.red-ui-editableList-item-sortable .red-ui-editableList-item-content { + margin-left: 22px; + } + &.red-ui-editableList-item-removable .red-ui-editableList-item-content { + margin-right: 28px; + } + &.red-ui-editableList-item-deleting { + background: $secondary-background-inactive; + } + } + +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/nodeList.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/nodeList.scss new file mode 100644 index 0000000..01a7a48 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/nodeList.scss @@ -0,0 +1,65 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +.red-ui-nodeList { + .red-ui-editableList-container { + padding: 0; + li { + padding: 2px 5px; + margin: 0; + white-space: nowrap; + border: none; + background: $secondary-background; + &:hover { + background: $secondary-background-hover; + } + + i.fa-angle-right { + text-align: center; + width: 15px; + transition: transform 0.1s ease-in-out; + } + .expandable { + cursor: pointer; + } + .expanded i.fa-angle-right { + transform: rotate(90deg); + } + .meta { + float: right; + input[type="checkbox"].red-ui-treeList-checkbox { + margin: 0; + } + } + .red-ui-editableList-item-content.disabled { + color: $secondary-text-color-disabled; + } + &.red-ui-editableList-section-header { + background: $primary-background; + .red-ui-editableList-item-content.disabled { + color: $secondary-text-color-disabled; + } + } + + } + } + .red-ui-editableList-header { + text-align: left; + &>span:last-child { + float: right; + font-size: 14px; + } + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/searchBox.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/searchBox.scss new file mode 100644 index 0000000..d0cd631 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/searchBox.scss @@ -0,0 +1,73 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +.red-ui-searchBox-container { + position: relative; + i { + font-size: 10px; + color: $secondary-text-color; + } + i.fa-search { + position: absolute; + pointer-events: none; + left: 8px; + top: 9px; + } + i.fa-times { + position: absolute; + right: 5px; + top: 9px; + } + form.red-ui-searchBox-form { + margin: 0; + } + input.red-ui-searchBox-input { + border-radius: 0; + border: none; + width: 100%; + box-shadow: none; + -webkit-box-shadow: none; + padding: 3px 17px 3px 22px; + margin: 0px; + height: 30px; + box-sizing:border-box; + + &:focus { + border: none; + box-shadow: none; + -webkit-box-shadow: none; + } + } + a { + position: absolute; + right: 0; + top: 0; + bottom: 0; + width: 20px; + display: none; + } + .red-ui-searchBox-resultCount { + position: absolute; + right: 18px; + top: 4px; + background: $primary-background; + color: $secondary-text-color; + padding: 1px 8px; + font-size: 9px; + border-radius: 4px; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/stack.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/stack.scss new file mode 100644 index 0000000..a32bfad --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/stack.scss @@ -0,0 +1,26 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +.red-ui-stack { + background: $secondary-background; + .red-ui-palette-category { + background: $secondary-background; + + &:last-child { + border-bottom: none; + } + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/treeList.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/treeList.scss new file mode 100644 index 0000000..8911b11 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/treeList.scss @@ -0,0 +1,126 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +.red-ui-treeList { + &:focus { + outline: none !important; + } +} + +.red-ui-treeList-container { + width: 100%; + height: 100%; + position: relative; + background: $tertiary-background; + + border: 1px solid $form-input-border-color; + border-radius: 4px; + + box-sizing: border-box; + + .red-ui-editableList-border { + border: none; + } + + .red-ui-editableList-container { + padding: 0px; + } + + .red-ui-editableList-container li { + padding: 0; + border-bottom: none; + .red-ui-editableList-container { + // margin-left: 15px; + } + } + .red-ui-editableList-item-content { + & > .red-ui-treeList-label .fa-angle-right { + transition: transform 0.1s ease-in-out; + } + .red-ui-editableList { + // display: none; + } + &.expanded { + & > .red-ui-treeList-label .fa-angle-right { + transform: rotate(90deg) + } + // & > .red-ui-editableList { + // display: block + // } + // & > .red-ui-treeList-spinner { + // display: block; + // } + } + } +} +.red-ui-treeList-label { + @include disable-selection; + padding: 6px 0; + display: block; + color: $list-item-color; + text-decoration: none; + cursor: pointer; + vertical-align: middle; + margin: 0; + position: relative; + + &:hover, &:hover .red-ui-treeList-sublabel-text { + background: $list-item-background-hover; + color: $list-item-color; + text-decoration: none; + } + &:focus, &:focus .red-ui-treeList-sublabel-text { + background: $list-item-background-hover; + outline: none; + color: $list-item-color; + text-decoration: none; + } + &.selected, &.selected .red-ui-treeList-sublabel-text { + background: $list-item-background-selected; + outline: none; + color: $list-item-color; + } + + input.red-ui-treeList-checkbox { + margin: 0; + } +} +.red-ui-treeList-label-text { + margin-left: 4px; +} +.red-ui-treeList-sublabel-text { + top: 0; + bottom: 0; + right: 0; + padding: 0 10px 0 5px; + line-height: 32px; + font-size: 0.9em; + color: $list-item-secondary-color; + position: absolute; + background: $list-item-background; +} + + +.red-ui-treeList-icon { + display: inline-block; + width: 20px; + text-align: center; +} +.red-ui-treeList-spinner { + height: 32px; + background: url(images/spin.svg) 50% 50% no-repeat; + background-size: auto 20px; +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/typedInput.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/typedInput.scss new file mode 100644 index 0000000..be2d506 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/ui/common/typedInput.scss @@ -0,0 +1,213 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +.red-ui-typedInput-container { + border: 1px solid $form-input-border-color; + border-radius: 4px; + height: 34px; + display: inline-block; + padding: 0; + margin: 0; + vertical-align: middle; + box-sizing: border-box; + overflow:visible; + position: relative; + .red-ui-typedInput-input-wrap { + position: absolute; + left:0; + right:0; + top:0; + bottom:0; + outline: red; + } + input.red-ui-typedInput-input { + width: 100%; + padding: 0 0 0 3px; + margin:0; + height: 32px; + border:none; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + box-shadow: none; + vertical-align: middle; + } + + &.red-ui-typedInput-focus:not(.input-error) { + border-color: $form-input-focus-color !important; + } + .red-ui-typedInput-value-label { + position: absolute; + display: inline-block; + height: 32px; + box-sizing: border-box; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + + } +} +.red-ui-typedInput-options { + @include component-shadow; + font-family: $primary-font; + font-size: $primary-font-size; + + position: absolute; + max-height: 350px; + overflow-y: auto; + border: 1px solid $primary-border-color; + box-sizing: border-box; + background: $secondary-background; + white-space: nowrap; + z-index: 2000; + a { + padding: 6px 18px 6px 6px; + display: block; + border-bottom: 1px solid $secondary-border-color; + color: $form-text-color; + &:hover { + text-decoration: none; + background: $workspace-button-background-hover; + } + &:focus { + text-decoration: none; + background: $workspace-button-background-active; + outline: none; + } + &:active { + text-decoration: none; + background: $workspace-button-background-active; + } + input[type="checkbox"] { + margin-right: 6px; + } + } + .red-ui-typedInput-icon { + margin-right: 6px; + } +} +button.red-ui-typedInput-type-select, +button.red-ui-typedInput-option-expand, +button.red-ui-typedInput-option-trigger + { + text-align: left; + border: none; + position: absolute; + box-sizing: border-box; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + padding: 0 1px 0 5px; + display:inline-block; + background: $form-button-background; + height: 32px; + line-height: 30px; + min-width: 23px; + vertical-align: middle; + color: $form-text-color; + i.red-ui-typedInput-icon { + margin-left: 1px; + margin-right: 2px; + vertical-align: middle; + } + &.disabled { + cursor: default; + i.red-ui-typedInput-icon { + color: $secondary-text-color-disabled; + } + } + .red-ui-typedInput-type-label,.red-ui-typedInput-option-label { + display: inline-block; + vertical-align: middle; + height: 100%; + padding: 0 1px 0 5px; + img { + max-width: none; + } + } + + &:not(.disabled):hover { + text-decoration: none; + background: $workspace-button-background-hover; + } + &:focus { + text-decoration: none; + outline: none; + box-shadow: inset 0 0 0 1px $form-input-focus-color; + } + &:not(.disabled):active { + background: $workspace-button-background-active; + text-decoration: none; + } + &.red-ui-typedInput-full-width { + width: 100%; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + } + &:before { + content:''; + display: inline-block; + height: 100%; + vertical-align: middle; + } +} +button.red-ui-typedInput-option-expand { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + right: 0; +} + +button.red-ui-typedInput-option-trigger { + border-top-left-radius: 0px; + border-bottom-left-radius: 0px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + padding: 0 0 0 0; + position:absolute; + right: 0; + .red-ui-typedInput-option-label { + background:$form-button-background; + color: $form-text-color; + position:absolute; + left:0; + right:23px; + top: 0; + padding: 0 5px 0 8px; + i.red-ui-typedInput-icon { + margin-right: 4px; + } + } + .red-ui-typedInput-option-caret { + top: 0; + position: absolute; + right: 0; + bottom: 0; + width: 17px; + padding-left: 5px; + &:before { + content:''; + display: inline-block; + height: 100%; + vertical-align: middle; + } + } + &:focus { + box-shadow: none; + } + &:focus .red-ui-typedInput-option-caret { + box-shadow: inset 0 0 0 1px $form-input-focus-color; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/userSettings.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/userSettings.scss new file mode 100644 index 0000000..60afeeb --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/userSettings.scss @@ -0,0 +1,89 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +.red-ui-settings-tabs-container { + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 120px; + background: $tertiary-background; +} +.red-ui-settings-tabs-content { + position: absolute; + top: 0; + left: 120px; + right: 0; + bottom: 0; + padding: 0; + h3:not(:first-child) { + border-top: 1px solid $secondary-border-color; + margin-top: 15px; + margin-bottom: 10px; + padding-top: 20px; + } + label { + display: inline-block; + min-width: 100px; + vertical-align: top; + margin-top: 5px; + input { + vertical-align: top; + padding-bottom: 0; + } + } + input, div.uneditable-input { + //margin-bottom: 0; + } + div.uneditable-input { + position: relative; + } + input[type='number'] { + width: 60px; + } + h4 { + margin-top: 20px; + margin-bottom: 10px; + } +} + +#red-ui-settings-tab-view { + position: absolute; + top:0; + right: 0; + left: 0; + bottom: 0; + padding: 8px 20px 20px; + overflow-y: scroll; +} +.red-ui-settings-row { + padding: 5px 10px 2px; +} +.red-ui-settings-section { + position: relative; + &:after { + content: ""; + display: table; + clear: both; + } + .uneditable-input, input, textarea { + width: calc(100% - 150px); + } + textarea { + resize: none; + height: 10em; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/widgetStyle.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/widgetStyle.scss new file mode 100644 index 0000000..1f45b51 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/widgetStyle.scss @@ -0,0 +1,23 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +@import "colors"; +@import "mixins"; + +@import "forms"; +@import "jquery"; +@import "typedInput"; +@import "editableList"; diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/workspace.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/workspace.scss new file mode 100644 index 0000000..f6255ea --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/workspace.scss @@ -0,0 +1,174 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#red-ui-workspace { + position: absolute; + margin: 0; + top:0px; + left:179px; + bottom: 0px; + right: 322px; + overflow: hidden; + @include component-border; + transition: left 0.1s ease-in-out; +} + +#red-ui-workspace-chart { + overflow: auto; + position: absolute; + bottom:25px; + top: 35px; + left:0px; + right:0px; + box-sizing:border-box; + transition: right 0.2s ease; + &:focus { + outline: none; + } +} +#red-ui-workspace-tabs-shade { + @include shade; + z-index: 2; + bottom: auto; + height: 35px; +} + +.red-ui-workspace-chart-background { + fill: $view-background; +} +.red-ui-workspace-chart-grid line { + fill: none; + shape-rendering: crispEdges; + stroke: $view-grid-color; + stroke-width: 1px; +} +.red-ui-workspace-select-mode { + .red-ui-workspace-chart-background { + opacity: 0.7; + // fill: $view-select-mode-background; + } + .red-ui-workspace-chart-grid line { + opacity: 0.8; + } +} + +.red-ui-palette-closed #red-ui-workspace { + left: 7px; +} + +// .workspace-footer-button { +// @include component-footer-button; +// margin-left: 2px; +// margin-right: 2px; +// } +// +// .workspace-footer-button-toggle { +// @include component-footer-button-toggle; +// margin-left: 2px; +// margin-right: 2px; +// } + +#red-ui-workspace-tabs:not(.red-ui-workspace-focussed) { + opacity:0.8; +} +.red-ui-workspace-disabled-icon { + display: none; +} +.red-ui-workspace-disabled { + &.red-ui-tab { + border-top-style: dashed; + border-left-style: dashed; + border-right-style: dashed; + + a { + font-style: italic; + color: $tab-text-color-disabled-inactive !important; + } + &.active a { + font-weight: normal; + color: $tab-text-color-disabled-active !important; + } + .red-ui-workspace-disabled-icon { + display: inline; + } + } +} + + +#red-ui-navigator-canvas { + position: absolute; + bottom: 0; + right:0; + zIndex: 101; + border-left: 1px solid $primary-border-color; + border-top: 1px solid $primary-border-color; + background: $view-navigator-background; + box-shadow: -1px 0 3px $shadow; +} +.red-ui-navigator-border { + stroke-dasharray: 5,5; + pointer-events: none; + stroke: $secondary-border-color; + strokeWidth: 1; + fill: $view-background; +} + +.red-ui-component-footer { + @include component-footer; + + > .button-group { + display: inline-block; + > .red-ui-footer-button { + margin-top: -1px; + } + } +} + +a.red-ui-footer-button, +button.red-ui-footer-button { + @include component-footer-button; +} + +a.red-ui-footer-button-toggle, +button.red-ui-footer-button-toggle { + @include component-footer-button-toggle; +} + +.red-ui-statusbar-widget { + margin: 0 2px; + display: inline-block; + vertical-align: middle; + height: 100%; + line-height: 20px; +} + +.red-ui-statusbar-bucket { + position: absolute; + top: 0; + bottom: 0; +} +.red-ui-statusbar-bucket-left { + left: 10px; + .red-ui-statusbar-widget:first-child { + margin-left: 0; + } +} +.red-ui-statusbar-bucket-right { + right: 10px; + .red-ui-statusbar-widget:last-child { + margin-right: 0; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/workspaceToolbar.scss b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/workspaceToolbar.scss new file mode 100644 index 0000000..fbc0dbd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/sass/workspaceToolbar.scss @@ -0,0 +1,85 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +#red-ui-workspace-toolbar { + display: none; + color: $workspace-button-color; + font-size: 12px; + line-height: 18px; + position: absolute; + top: 35px; + left:0; + right: 0; + padding: 7px; + height: 40px; + box-sizing: border-box; + background: $secondary-background; + border-bottom: 1px solid $secondary-border-color; + white-space: nowrap; + transition: right 0.2s ease; + overflow: hidden; + + label { + padding: 1px 8px; + margin: 0; + font-size: 12px; + } + input[type="checkbox"] { + margin: 0 3px 0 0 ; + padding: 0; + } + .button { + @include workspace-button; + margin-right: 10px; + padding: 2px 8px; + } + + .button-group { + @include disable-selection; + + .button:first-child { + margin-right: 0; + } + + &:not(.spinner-group) { + .button:not(:first-child) { + border-left: none; + } + } + .button.active { + background: $workspace-button-background-active; + cursor: default; + } + } + + .spinner-value { + width: 25px; + color: $workspace-button-color; + padding: 0 5px; + display: inline-block; + text-align: center; + border-top: 1px solid $secondary-border-color; + border-bottom: 1px solid $secondary-border-color; + margin: 0; + height: 24px; + font-size: 12px; + background: $form-input-background; + line-height: 22px; + box-sizing: border-box; + } + +} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/LICENSE b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/LICENSE new file mode 100644 index 0000000..4760be2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2010, Ajax.org B.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Ajax.org B.V. nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/ace.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/ace.js new file mode 100644 index 0000000..0808ecd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/ace.js @@ -0,0 +1,17 @@ +(function(){function o(n){var i=e;n&&(e[n]||(e[n]={}),i=e[n]);if(!i.define||!i.define.packaged)t.original=i.define,i.define=t,i.define.packaged=!0;if(!i.require||!i.require.packaged)r.original=i.require,i.require=r,i.require.packaged=!0}var ACE_NAMESPACE = "ace",e=function(){return this}();!e&&typeof window!="undefined"&&(e=window);if(!ACE_NAMESPACE&&typeof requirejs!="undefined")return;var t=function(e,n,r){if(typeof e!="string"){t.original?t.original.apply(this,arguments):(console.error("dropping module because define wasn't a string."),console.trace());return}arguments.length==2&&(r=n),t.modules[e]||(t.payloads[e]=r,t.modules[e]=null)};t.modules={},t.payloads={};var n=function(e,t,n){if(typeof t=="string"){var i=s(e,t);if(i!=undefined)return n&&n(),i}else if(Object.prototype.toString.call(t)==="[object Array]"){var o=[];for(var u=0,a=t.length;u<a;++u){var f=s(e,t[u]);if(f==undefined&&r.original)return;o.push(f)}return n&&n.apply(null,o)||!0}},r=function(e,t){var i=n("",e,t);return i==undefined&&r.original?r.original.apply(this,arguments):i},i=function(e,t){if(t.indexOf("!")!==-1){var n=t.split("!");return i(e,n[0])+"!"+i(e,n[1])}if(t.charAt(0)=="."){var r=e.split("/").slice(0,-1).join("/");t=r+"/"+t;while(t.indexOf(".")!==-1&&s!=t){var s=t;t=t.replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return t},s=function(e,r){r=i(e,r);var s=t.modules[r];if(!s){s=t.payloads[r];if(typeof s=="function"){var o={},u={id:r,uri:"",exports:o,packaged:!0},a=function(e,t){return n(r,e,t)},f=s(a,o,u);o=f||u.exports,t.modules[r]=o,delete t.payloads[r]}s=t.modules[r]=o||s}return s};o(ACE_NAMESPACE)})(),ace.define("ace/lib/regexp",["require","exports","module"],function(e,t,n){"use strict";function o(e){return(e.global?"g":"")+(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.extended?"x":"")+(e.sticky?"y":"")}function u(e,t,n){if(Array.prototype.indexOf)return e.indexOf(t,n);for(var r=n||0;r<e.length;r++)if(e[r]===t)return r;return-1}var r={exec:RegExp.prototype.exec,test:RegExp.prototype.test,match:String.prototype.match,replace:String.prototype.replace,split:String.prototype.split},i=r.exec.call(/()??/,"")[1]===undefined,s=function(){var e=/^/g;return r.test.call(e,""),!e.lastIndex}();if(s&&i)return;RegExp.prototype.exec=function(e){var t=r.exec.apply(this,arguments),n,a;if(typeof e=="string"&&t){!i&&t.length>1&&u(t,"")>-1&&(a=RegExp(this.source,r.replace.call(o(this),"g","")),r.replace.call(e.slice(t.index),a,function(){for(var e=1;e<arguments.length-2;e++)arguments[e]===undefined&&(t[e]=undefined)}));if(this._xregexp&&this._xregexp.captureNames)for(var f=1;f<t.length;f++)n=this._xregexp.captureNames[f-1],n&&(t[n]=t[f]);!s&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--}return t},s||(RegExp.prototype.test=function(e){var t=r.exec.call(this,e);return t&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--,!!t})}),ace.define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)=="[object Array]"});var m=Object("a"),g=m[0]!="a"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _=" \n\x0b\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";if(!String.prototype.trim||_.trim()){_="["+_+"]";var D=new RegExp("^"+_+_+"*"),P=new RegExp(_+_+"*$");String.prototype.trim=function(){return String(this).replace(D,"").replace(P,"")}}var F=function(e){if(e==null)throw new TypeError("can't convert "+e+" to object");return Object(e)}}),ace.define("ace/lib/fixoldbrowsers",["require","exports","module","ace/lib/regexp","ace/lib/es5-shim"],function(e,t,n){"use strict";e("./regexp"),e("./es5-shim"),typeof Element!="undefined"&&!Element.prototype.remove&&Object.defineProperty(Element.prototype,"remove",{enumerable:!1,writable:!0,configurable:!0,value:function(){this.parentNode&&this.parentNode.removeChild(this)}})}),ace.define("ace/lib/useragent",["require","exports","module"],function(e,t,n){"use strict";t.OS={LINUX:"LINUX",MAC:"MAC",WINDOWS:"WINDOWS"},t.getOS=function(){return t.isMac?t.OS.MAC:t.isLinux?t.OS.LINUX:t.OS.WINDOWS};if(typeof navigator!="object")return;var r=(navigator.platform.match(/mac|win|linux/i)||["other"])[0].toLowerCase(),i=navigator.userAgent;t.isWin=r=="win",t.isMac=r=="mac",t.isLinux=r=="linux",t.isIE=navigator.appName=="Microsoft Internet Explorer"||navigator.appName.indexOf("MSAppHost")>=0?parseFloat((i.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]):parseFloat((i.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]),t.isOldIE=t.isIE&&t.isIE<9,t.isGecko=t.isMozilla=i.match(/ Gecko\/\d+/),t.isOpera=window.opera&&Object.prototype.toString.call(window.opera)=="[object Opera]",t.isWebKit=parseFloat(i.split("WebKit/")[1])||undefined,t.isChrome=parseFloat(i.split(" Chrome/")[1])||undefined,t.isEdge=parseFloat(i.split(" Edge/")[1])||undefined,t.isAIR=i.indexOf("AdobeAIR")>=0,t.isIPad=i.indexOf("iPad")>=0,t.isAndroid=i.indexOf("Android")>=0,t.isChromeOS=i.indexOf(" CrOS ")>=0,t.isIOS=/iPad|iPhone|iPod/.test(i)&&!window.MSStream,t.isIOS&&(t.isMac=!0),t.isMobile=t.isIPad||t.isAndroid}),ace.define("ace/lib/dom",["require","exports","module","ace/lib/useragent"],function(e,t,n){"use strict";var r=e("./useragent"),i="http://www.w3.org/1999/xhtml";t.buildDom=function o(e,t,n){if(typeof e=="string"&&e){var r=document.createTextNode(e);return t&&t.appendChild(r),r}if(!Array.isArray(e))return e;if(typeof e[0]!="string"||!e[0]){var i=[];for(var s=0;s<e.length;s++){var u=o(e[s],t,n);u&&i.push(u)}return i}var a=document.createElement(e[0]),f=e[1],l=1;f&&typeof f=="object"&&!Array.isArray(f)&&(l=2);for(var s=l;s<e.length;s++)o(e[s],a,n);return l==2&&Object.keys(f).forEach(function(e){var t=f[e];e==="class"?a.className=Array.isArray(t)?t.join(" "):t:typeof t=="function"||e=="value"?a[e]=t:e==="ref"?n&&(n[t]=a):t!=null&&a.setAttribute(e,t)}),t&&t.appendChild(a),a},t.getDocumentHead=function(e){return e||(e=document),e.head||e.getElementsByTagName("head")[0]||e.documentElement},t.createElement=function(e,t){return document.createElementNS?document.createElementNS(t||i,e):document.createElement(e)},t.removeChildren=function(e){e.innerHTML=""},t.createTextNode=function(e,t){var n=t?t.ownerDocument:document;return n.createTextNode(e)},t.createFragment=function(e){var t=e?e.ownerDocument:document;return t.createDocumentFragment()},t.hasCssClass=function(e,t){var n=(e.className+"").split(/\s+/g);return n.indexOf(t)!==-1},t.addCssClass=function(e,n){t.hasCssClass(e,n)||(e.className+=" "+n)},t.removeCssClass=function(e,t){var n=e.className.split(/\s+/g);for(;;){var r=n.indexOf(t);if(r==-1)break;n.splice(r,1)}e.className=n.join(" ")},t.toggleCssClass=function(e,t){var n=e.className.split(/\s+/g),r=!0;for(;;){var i=n.indexOf(t);if(i==-1)break;r=!1,n.splice(i,1)}return r&&n.push(t),e.className=n.join(" "),r},t.setCssClass=function(e,n,r){r?t.addCssClass(e,n):t.removeCssClass(e,n)},t.hasCssString=function(e,t){var n=0,r;t=t||document;if(r=t.querySelectorAll("style"))while(n<r.length)if(r[n++].id===e)return!0},t.importCssString=function(n,r,i){var s=i;if(!i||!i.getRootNode)s=document;else{s=i.getRootNode();if(!s||s==i)s=document}var o=s.ownerDocument||s;if(r&&t.hasCssString(r,s))return null;r&&(n+="\n/*# sourceURL=ace/css/"+r+" */");var u=t.createElement("style");u.appendChild(o.createTextNode(n)),r&&(u.id=r),s==o&&(s=t.getDocumentHead(o)),s.insertBefore(u,s.firstChild)},t.importCssStylsheet=function(e,n){t.buildDom(["link",{rel:"stylesheet",href:e}],t.getDocumentHead(n))},t.scrollbarWidth=function(e){var n=t.createElement("ace_inner");n.style.width="100%",n.style.minWidth="0px",n.style.height="200px",n.style.display="block";var r=t.createElement("ace_outer"),i=r.style;i.position="absolute",i.left="-10000px",i.overflow="hidden",i.width="200px",i.minWidth="0px",i.height="150px",i.display="block",r.appendChild(n);var s=e.documentElement;s.appendChild(r);var o=n.offsetWidth;i.overflow="scroll";var u=n.offsetWidth;return o==u&&(u=r.clientWidth),s.removeChild(r),o-u},typeof document=="undefined"&&(t.importCssString=function(){}),t.computedStyle=function(e,t){return window.getComputedStyle(e,"")||{}},t.setStyle=function(e,t,n){e[t]!==n&&(e[t]=n)},t.HAS_CSS_ANIMATION=!1,t.HAS_CSS_TRANSFORMS=!1,t.HI_DPI=r.isWin?typeof window!="undefined"&&window.devicePixelRatio>=1.5:!0;if(typeof document!="undefined"){var s=document.createElement("div");t.HI_DPI&&s.style.transform!==undefined&&(t.HAS_CSS_TRANSFORMS=!0),!r.isEdge&&typeof s.style.animationName!="undefined"&&(t.HAS_CSS_ANIMATION=!0),s=null}t.HAS_CSS_TRANSFORMS?t.translate=function(e,t,n){e.style.transform="translate("+Math.round(t)+"px, "+Math.round(n)+"px)"}:t.translate=function(e,t,n){e.style.top=Math.round(n)+"px",e.style.left=Math.round(t)+"px"}}),ace.define("ace/lib/oop",["require","exports","module"],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/lib/keys",["require","exports","module","ace/lib/oop"],function(e,t,n){"use strict";var r=e("./oop"),i=function(){var e={MODIFIER_KEYS:{16:"Shift",17:"Ctrl",18:"Alt",224:"Meta"},KEY_MODS:{ctrl:1,alt:2,option:2,shift:4,"super":8,meta:8,command:8,cmd:8},FUNCTION_KEYS:{8:"Backspace",9:"Tab",13:"Return",19:"Pause",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"Print",45:"Insert",46:"Delete",96:"Numpad0",97:"Numpad1",98:"Numpad2",99:"Numpad3",100:"Numpad4",101:"Numpad5",102:"Numpad6",103:"Numpad7",104:"Numpad8",105:"Numpad9","-13":"NumpadEnter",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"Numlock",145:"Scrolllock"},PRINTABLE_KEYS:{32:" ",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",61:"=",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",107:"+",109:"-",110:".",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",111:"/",106:"*"}},t,n;for(n in e.FUNCTION_KEYS)t=e.FUNCTION_KEYS[n].toLowerCase(),e[t]=parseInt(n,10);for(n in e.PRINTABLE_KEYS)t=e.PRINTABLE_KEYS[n].toLowerCase(),e[t]=parseInt(n,10);return r.mixin(e,e.MODIFIER_KEYS),r.mixin(e,e.PRINTABLE_KEYS),r.mixin(e,e.FUNCTION_KEYS),e.enter=e["return"],e.escape=e.esc,e.del=e["delete"],e[173]="-",function(){var t=["cmd","ctrl","alt","shift"];for(var n=Math.pow(2,t.length);n--;)e.KEY_MODS[n]=t.filter(function(t){return n&e.KEY_MODS[t]}).join("-")+"-"}(),e.KEY_MODS[0]="",e.KEY_MODS[-1]="input-",e}();r.mixin(t,i),t.keyCodeToString=function(e){var t=i[e];return typeof t!="string"&&(t=String.fromCharCode(e)),t.toLowerCase()}}),ace.define("ace/lib/event",["require","exports","module","ace/lib/keys","ace/lib/useragent"],function(e,t,n){"use strict";function a(e,t,n){var a=u(t);if(!i.isMac&&s){t.getModifierState&&(t.getModifierState("OS")||t.getModifierState("Win"))&&(a|=8);if(s.altGr){if((3&a)==3)return;s.altGr=0}if(n===18||n===17){var f="location"in t?t.location:t.keyLocation;if(n===17&&f===1)s[n]==1&&(o=t.timeStamp);else if(n===18&&a===3&&f===2){var l=t.timeStamp-o;l<50&&(s.altGr=!0)}}}n in r.MODIFIER_KEYS&&(n=-1),a&8&&n>=91&&n<=93&&(n=-1);if(!a&&n===13){var f="location"in t?t.location:t.keyLocation;if(f===3){e(t,a,-n);if(t.defaultPrevented)return}}if(i.isChromeOS&&a&8){e(t,a,n);if(t.defaultPrevented)return;a&=-9}return!!a||n in r.FUNCTION_KEYS||n in r.PRINTABLE_KEYS?e(t,a,n):!1}function f(){s=Object.create(null)}var r=e("./keys"),i=e("./useragent"),s=null,o=0;t.addListener=function(e,t,n){if(e.addEventListener)return e.addEventListener(t,n,!1);if(e.attachEvent){var r=function(){n.call(e,window.event)};n._wrapper=r,e.attachEvent("on"+t,r)}},t.removeListener=function(e,t,n){if(e.removeEventListener)return e.removeEventListener(t,n,!1);e.detachEvent&&e.detachEvent("on"+t,n._wrapper||n)},t.stopEvent=function(e){return t.stopPropagation(e),t.preventDefault(e),!1},t.stopPropagation=function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0},t.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},t.getButton=function(e){return e.type=="dblclick"?0:e.type=="contextmenu"||i.isMac&&e.ctrlKey&&!e.altKey&&!e.shiftKey?2:e.preventDefault?e.button:{1:0,2:2,4:1}[e.button]},t.capture=function(e,n,r){function i(e){n&&n(e),r&&r(e),t.removeListener(document,"mousemove",n,!0),t.removeListener(document,"mouseup",i,!0),t.removeListener(document,"dragstart",i,!0)}return t.addListener(document,"mousemove",n,!0),t.addListener(document,"mouseup",i,!0),t.addListener(document,"dragstart",i,!0),i},t.addTouchMoveListener=function(e,n){var r,i;t.addListener(e,"touchstart",function(e){var t=e.touches,n=t[0];r=n.clientX,i=n.clientY}),t.addListener(e,"touchmove",function(e){var t=e.touches;if(t.length>1)return;var s=t[0];e.wheelX=r-s.clientX,e.wheelY=i-s.clientY,r=s.clientX,i=s.clientY,n(e)})},t.addMouseWheelListener=function(e,n){"onmousewheel"in e?t.addListener(e,"mousewheel",function(e){var t=8;e.wheelDeltaX!==undefined?(e.wheelX=-e.wheelDeltaX/t,e.wheelY=-e.wheelDeltaY/t):(e.wheelX=0,e.wheelY=-e.wheelDelta/t),n(e)}):"onwheel"in e?t.addListener(e,"wheel",function(e){var t=.35;switch(e.deltaMode){case e.DOM_DELTA_PIXEL:e.wheelX=e.deltaX*t||0,e.wheelY=e.deltaY*t||0;break;case e.DOM_DELTA_LINE:case e.DOM_DELTA_PAGE:e.wheelX=(e.deltaX||0)*5,e.wheelY=(e.deltaY||0)*5}n(e)}):t.addListener(e,"DOMMouseScroll",function(e){e.axis&&e.axis==e.HORIZONTAL_AXIS?(e.wheelX=(e.detail||0)*5,e.wheelY=0):(e.wheelX=0,e.wheelY=(e.detail||0)*5),n(e)})},t.addMultiMouseDownListener=function(e,n,r,s){function c(e){t.getButton(e)!==0?o=0:e.detail>1?(o++,o>4&&(o=1)):o=1;if(i.isIE){var c=Math.abs(e.clientX-u)>5||Math.abs(e.clientY-a)>5;if(!f||c)o=1;f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),o==1&&(u=e.clientX,a=e.clientY)}e._clicks=o,r[s]("mousedown",e);if(o>4)o=0;else if(o>1)return r[s](l[o],e)}function h(e){o=2,f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),r[s]("mousedown",e),r[s](l[o],e)}var o=0,u,a,f,l={2:"dblclick",3:"tripleclick",4:"quadclick"};Array.isArray(e)||(e=[e]),e.forEach(function(e){t.addListener(e,"mousedown",c),i.isOldIE&&t.addListener(e,"dblclick",h)})};var u=!i.isMac||!i.isOpera||"KeyboardEvent"in window?function(e){return 0|(e.ctrlKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.metaKey?8:0)}:function(e){return 0|(e.metaKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.ctrlKey?8:0)};t.getModifierString=function(e){return r.KEY_MODS[u(e)]},t.addCommandKeyListener=function(e,n){var r=t.addListener;if(i.isOldGecko||i.isOpera&&!("KeyboardEvent"in window)){var o=null;r(e,"keydown",function(e){o=e.keyCode}),r(e,"keypress",function(e){return a(n,e,o)})}else{var u=null;r(e,"keydown",function(e){s[e.keyCode]=(s[e.keyCode]||0)+1;var t=a(n,e,e.keyCode);return u=e.defaultPrevented,t}),r(e,"keypress",function(e){u&&(e.ctrlKey||e.altKey||e.shiftKey||e.metaKey)&&(t.stopEvent(e),u=null)}),r(e,"keyup",function(e){s[e.keyCode]=null}),s||(f(),r(window,"focus",f))}};if(typeof window=="object"&&window.postMessage&&!i.isOldIE){var l=1;t.nextTick=function(e,n){n=n||window;var r="zero-timeout-message-"+l++,i=function(s){s.data==r&&(t.stopPropagation(s),t.removeListener(n,"message",i),e())};t.addListener(n,"message",i),n.postMessage(r,"*")}}t.$idleBlocked=!1,t.onIdle=function(e,n){return setTimeout(function r(){t.$idleBlocked?setTimeout(r,100):e()},n)},t.$idleBlockId=null,t.blockIdle=function(e){t.$idleBlockId&&clearTimeout(t.$idleBlockId),t.$idleBlocked=!0,t.$idleBlockId=setTimeout(function(){t.$idleBlocked=!1},e||100)},t.nextFrame=typeof window=="object"&&(window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame),t.nextFrame?t.nextFrame=t.nextFrame.bind(window):t.nextFrame=function(e){setTimeout(e,17)}}),ace.define("ace/range",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define("ace/lib/lang",["require","exports","module"],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function s(e){if(typeof e!="object"||!e)return e;var t;if(Array.isArray(e)){t=[];for(var n=0;n<e.length;n++)t[n]=s(e[n]);return t}if(Object.prototype.toString.call(e)!=="[object Object]")return e;t={};for(var n in e)t[n]=s(e[n]);return t},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return(""+e).replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define("ace/keyboard/textinput",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/dom","ace/lib/lang","ace/lib/keys"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=e("../lib/dom"),o=e("../lib/lang"),u=i.isChrome<18,a=i.isIE,f=i.isChrome>63,l=400,c=e("../lib/keys"),h=c.KEY_MODS,p=i.isIOS,d=p?/\s/:/\n/,v=function(e,t){function W(){x=!0,n.blur(),n.focus(),x=!1}function V(e){e.keyCode==27&&n.value.length<n.selectionStart&&(g||(T=n.value),N=C=-1,A()),X()}function J(){clearTimeout($),$=setTimeout(function(){b&&(n.style.cssText=b,b=""),t.renderer.$keepTextAreaAtCursor==null&&(t.renderer.$keepTextAreaAtCursor=!0,t.renderer.$moveTextAreaToCursor())},0)}function Q(e,t,n){var r=null,i=!1;n.addEventListener("keydown",function(e){r&&clearTimeout(r),i=!0},!0),n.addEventListener("keyup",function(e){r=setTimeout(function(){i=!1},100)},!0);var s=function(e){if(document.activeElement!==n)return;if(i||g)return;if(v)return;var r=n.selectionStart,s=n.selectionEnd,o=null,u=0;console.log(r,s);if(r==0)o=c.up;else if(r==1)o=c.home;else if(s>C&&T[s]=="\n")o=c.end;else if(r<N&&T[r-1]==" ")o=c.left,u=h.option;else if(r<N||r==N&&C!=N&&r==s)o=c.left;else if(s>C&&T.slice(0,s).split("\n").length>2)o=c.down;else if(s>C&&T[s-1]==" ")o=c.right,u=h.option;else if(s>C||s==C&&C!=N&&r==s)o=c.right;r!==s&&(u|=h.shift),o&&(t.onCommandKey(null,u,o),N=r,C=s,A(""))};document.addEventListener("selectionchange",s),t.on("destroy",function(){document.removeEventListener("selectionchange",s)})}var n=s.createElement("textarea");n.className="ace_text-input",n.setAttribute("wrap","off"),n.setAttribute("autocorrect","off"),n.setAttribute("autocapitalize","off"),n.setAttribute("spellcheck",!1),n.style.opacity="0",e.insertBefore(n,e.firstChild);var v=!1,m=!1,g=!1,y=!1,b="",w=!0,E=!1;i.isMobile||(n.style.fontSize="1px");var S=!1,x=!1,T="",N=0,C=0;try{var k=document.activeElement===n}catch(L){}r.addListener(n,"blur",function(e){if(x)return;t.onBlur(e),k=!1}),r.addListener(n,"focus",function(e){if(x)return;k=!0;if(i.isEdge)try{if(!document.hasFocus())return}catch(e){}t.onFocus(e),i.isEdge?setTimeout(A):A()}),this.$focusScroll=!1,this.focus=function(){if(b||f||this.$focusScroll=="browser")return n.focus({preventScroll:!0});var e=n.style.top;n.style.position="fixed",n.style.top="0px";try{var t=n.getBoundingClientRect().top!=0}catch(r){return}var i=[];if(t){var s=n.parentElement;while(s&&s.nodeType==1)i.push(s),s.setAttribute("ace_nocontext",!0),!s.parentElement&&s.getRootNode?s=s.getRootNode().host:s=s.parentElement}n.focus({preventScroll:!0}),t&&i.forEach(function(e){e.removeAttribute("ace_nocontext")}),setTimeout(function(){n.style.position="",n.style.top=="0px"&&(n.style.top=e)},0)},this.blur=function(){n.blur()},this.isFocused=function(){return k},t.on("beforeEndOperation",function(){if(t.curOp&&t.curOp.command.name=="insertstring")return;g&&(T=n.value="",z()),A()});var A=p?function(e){if(!k||v&&!e)return;e||(e="");var r="\n ab"+e+"cde fg\n";r!=n.value&&(n.value=T=r);var i=4,s=4+(e.length||(t.selection.isEmpty()?0:1));(N!=i||C!=s)&&n.setSelectionRange(i,s),N=i,C=s}:function(){if(g||y)return;if(!k&&!D)return;g=!0;var e=t.selection,r=e.getRange(),i=e.cursor.row,s=r.start.column,o=r.end.column,u=t.session.getLine(i);if(r.start.row!=i){var a=t.session.getLine(i-1);s=r.start.row<i-1?0:s,o+=a.length+1,u=a+"\n"+u}else if(r.end.row!=i){var f=t.session.getLine(i+1);o=r.end.row>i+1?f.length:o,o+=u.length+1,u=u+"\n"+f}u.length>l&&(s<l&&o<l?u=u.slice(0,l):(u="\n",s=0,o=1));var c=u+"\n\n";c!=T&&(n.value=T=c,N=C=c.length),D&&(N=n.selectionStart,C=n.selectionEnd);if(C!=o||N!=s||n.selectionEnd!=C)try{n.setSelectionRange(s,o),N=s,C=o}catch(h){}g=!1};k&&t.onFocus();var O=function(e){return e.selectionStart===0&&e.selectionEnd>=T.length&&e.value===T&&T&&e.selectionEnd!==C},M=function(e){if(g)return;v?v=!1:O(n)&&(t.selectAll(),A())},_=null;this.setInputHandler=function(e){_=e},this.getInputHandler=function(){return _};var D=!1,P=function(e,r){D&&(D=!1);if(m)return A(),e&&t.onPaste(e),m=!1,"";var i=n.selectionStart,s=n.selectionEnd,o=N,u=T.length-C,a=e,f=e.length-i,l=e.length-s,c=0;while(o>0&&T[c]==e[c])c++,o--;a=a.slice(c),c=1;while(u>0&&T.length-c>N-1&&T[T.length-c]==e[e.length-c])c++,u--;return f-=c-1,l-=c-1,a=a.slice(0,a.length-c+1),!r&&f==a.length&&!o&&!u&&!l?"":(y=!0,a&&!o&&!u&&!f&&!l||S?t.onTextInput(a):t.onTextInput(a,{extendLeft:o,extendRight:u,restoreStart:f,restoreEnd:l}),y=!1,T=e,N=i,C=s,a)},H=function(e){if(g)return U();var t=n.value,r=P(t,!0);(t.length>l+100||d.test(r))&&A()},B=function(e,t,n){var r=e.clipboardData||window.clipboardData;if(!r||u)return;var i=a||n?"Text":"text/plain";try{return t?r.setData(i,t)!==!1:r.getData(i)}catch(e){if(!n)return B(e,t,!0)}},j=function(e,i){var s=t.getCopyText();if(!s)return r.preventDefault(e);B(e,s)?(p&&(A(s),v=s,setTimeout(function(){v=!1},10)),i?t.onCut():t.onCopy(),r.preventDefault(e)):(v=!0,n.value=s,n.select(),setTimeout(function(){v=!1,A(),i?t.onCut():t.onCopy()}))},F=function(e){j(e,!0)},I=function(e){j(e,!1)},q=function(e){var s=B(e);typeof s=="string"?(s&&t.onPaste(s,e),i.isIE&&setTimeout(A),r.preventDefault(e)):(n.value="",m=!0)};r.addCommandKeyListener(n,t.onCommandKey.bind(t)),r.addListener(n,"select",M),r.addListener(n,"input",H),r.addListener(n,"cut",F),r.addListener(n,"copy",I),r.addListener(n,"paste",q),(!("oncut"in n)||!("oncopy"in n)||!("onpaste"in n))&&r.addListener(e,"keydown",function(e){if(i.isMac&&!e.metaKey||!e.ctrlKey)return;switch(e.keyCode){case 67:I(e);break;case 86:q(e);break;case 88:F(e)}});var R=function(e){if(g||!t.onCompositionStart||t.$readOnly)return;g={};if(S)return;setTimeout(U,0),t.on("mousedown",W);var r=t.getSelectionRange();r.end.row=r.start.row,r.end.column=r.start.column,g.markerRange=r,g.selectionStart=N,t.onCompositionStart(g),g.useTextareaForIME?(n.value="",T="",N=0,C=0):(n.msGetInputContext&&(g.context=n.msGetInputContext()),n.getInputContext&&(g.context=n.getInputContext()))},U=function(){if(!g||!t.onCompositionUpdate||t.$readOnly)return;if(S)return W();if(g.useTextareaForIME)t.onCompositionUpdate(n.value);else{var e=n.value;P(e),g.markerRange&&(g.context&&(g.markerRange.start.column=g.selectionStart=g.context.compositionStartOffset),g.markerRange.end.column=g.markerRange.start.column+C-g.selectionStart)}},z=function(e){if(!t.onCompositionEnd||t.$readOnly)return;g=!1,t.onCompositionEnd(),t.off("mousedown",W),e&&H()},X=o.delayedCall(U,50).schedule.bind(null,null);r.addListener(n,"compositionstart",R),r.addListener(n,"compositionupdate",U),r.addListener(n,"keyup",V),r.addListener(n,"keydown",X),r.addListener(n,"compositionend",z),this.getElement=function(){return n},this.setCommandMode=function(e){S=e,n.readOnly=!1},this.setReadOnly=function(e){S||(n.readOnly=e)},this.setCopyWithEmptySelection=function(e){E=e},this.onContextMenu=function(e){D=!0,A(),t._emit("nativecontextmenu",{target:t,domEvent:e}),this.moveToMouse(e,!0)},this.moveToMouse=function(e,o){b||(b=n.style.cssText),n.style.cssText=(o?"z-index:100000;":"")+(i.isIE?"opacity:0.1;":"")+"text-indent: -"+(N+C)*t.renderer.characterWidth*.5+"px;";var u=t.container.getBoundingClientRect(),a=s.computedStyle(t.container),f=u.top+(parseInt(a.borderTopWidth)||0),l=u.left+(parseInt(u.borderLeftWidth)||0),c=u.bottom-f-n.clientHeight-2,h=function(e){n.style.left=e.clientX-l-2+"px",n.style.top=Math.min(e.clientY-f-2,c)+"px"};h(e);if(e.type!="mousedown")return;t.renderer.$keepTextAreaAtCursor&&(t.renderer.$keepTextAreaAtCursor=null),clearTimeout($),i.isWin&&r.capture(t.container,h,J)},this.onContextMenuClose=J;var $,K=function(e){t.textInput.onContextMenu(e),J()};r.addListener(n,"mouseup",K),r.addListener(n,"mousedown",function(e){e.preventDefault(),J()}),r.addListener(t.renderer.scroller,"contextmenu",K),r.addListener(n,"contextmenu",K),p&&Q(e,t,n)};t.TextInput=v}),ace.define("ace/mouse/default_handlers",["require","exports","module","ace/lib/useragent"],function(e,t,n){"use strict";function o(e){e.$clickSelection=null;var t=e.editor;t.setDefaultHandler("mousedown",this.onMouseDown.bind(e)),t.setDefaultHandler("dblclick",this.onDoubleClick.bind(e)),t.setDefaultHandler("tripleclick",this.onTripleClick.bind(e)),t.setDefaultHandler("quadclick",this.onQuadClick.bind(e)),t.setDefaultHandler("mousewheel",this.onMouseWheel.bind(e)),t.setDefaultHandler("touchmove",this.onTouchMove.bind(e));var n=["select","startSelect","selectEnd","selectAllEnd","selectByWordsEnd","selectByLinesEnd","dragWait","dragWaitEnd","focusWait"];n.forEach(function(t){e[t]=this[t]},this),e.selectByLines=this.extendSelectionBy.bind(e,"getLineRange"),e.selectByWords=this.extendSelectionBy.bind(e,"getWordRange")}function u(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}function a(e,t){if(e.start.row==e.end.row)var n=2*t.column-e.start.column-e.end.column;else if(e.start.row==e.end.row-1&&!e.start.column&&!e.end.column)var n=t.column-4;else var n=2*t.row-e.start.row-e.end.row;return n<0?{cursor:e.start,anchor:e.end}:{cursor:e.end,anchor:e.start}}var r=e("../lib/useragent"),i=0,s=550;(function(){this.onMouseDown=function(e){var t=e.inSelection(),n=e.getDocumentPosition();this.mousedownEvent=e;var i=this.editor,s=e.getButton();if(s!==0){var o=i.getSelectionRange(),u=o.isEmpty();(u||s==1)&&i.selection.moveToPosition(n),s==2&&(i.textInput.onContextMenu(e.domEvent),r.isMozilla||e.preventDefault());return}this.mousedownEvent.time=Date.now();if(t&&!i.isFocused()){i.focus();if(this.$focusTimeout&&!this.$clickSelection&&!i.inMultiSelectMode){this.setState("focusWait"),this.captureMouse(e);return}}return this.captureMouse(e),this.startSelect(n,e.domEvent._clicks>1),e.preventDefault()},this.startSelect=function(e,t){e=e||this.editor.renderer.screenToTextCoordinates(this.x,this.y);var n=this.editor;if(!this.mousedownEvent)return;this.mousedownEvent.getShiftKey()?n.selection.selectToPosition(e):t||n.selection.moveToPosition(e),t||this.select(),n.renderer.scroller.setCapture&&n.renderer.scroller.setCapture(),n.setStyle("ace_selecting"),this.setState("select")},this.select=function(){var e,t=this.editor,n=t.renderer.screenToTextCoordinates(this.x,this.y);if(this.$clickSelection){var r=this.$clickSelection.comparePoint(n);if(r==-1)e=this.$clickSelection.end;else if(r==1)e=this.$clickSelection.start;else{var i=a(this.$clickSelection,n);n=i.cursor,e=i.anchor}t.selection.setSelectionAnchor(e.row,e.column)}t.selection.selectToPosition(n),t.renderer.scrollCursorIntoView()},this.extendSelectionBy=function(e){var t,n=this.editor,r=n.renderer.screenToTextCoordinates(this.x,this.y),i=n.selection[e](r.row,r.column);if(this.$clickSelection){var s=this.$clickSelection.comparePoint(i.start),o=this.$clickSelection.comparePoint(i.end);if(s==-1&&o<=0){t=this.$clickSelection.end;if(i.end.row!=r.row||i.end.column!=r.column)r=i.start}else if(o==1&&s>=0){t=this.$clickSelection.start;if(i.start.row!=r.row||i.start.column!=r.column)r=i.end}else if(s==-1&&o==1)r=i.end,t=i.start;else{var u=a(this.$clickSelection,r);r=u.cursor,t=u.anchor}n.selection.setSelectionAnchor(t.row,t.column)}n.selection.selectToPosition(r),n.renderer.scrollCursorIntoView()},this.selectEnd=this.selectAllEnd=this.selectByWordsEnd=this.selectByLinesEnd=function(){this.$clickSelection=null,this.editor.unsetStyle("ace_selecting"),this.editor.renderer.scroller.releaseCapture&&this.editor.renderer.scroller.releaseCapture()},this.focusWait=function(){var e=u(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y),t=Date.now();(e>i||t-this.mousedownEvent.time>this.$focusTimeout)&&this.startSelect(this.mousedownEvent.getDocumentPosition())},this.onDoubleClick=function(e){var t=e.getDocumentPosition(),n=this.editor,r=n.session,i=r.getBracketRange(t);i?(i.isEmpty()&&(i.start.column--,i.end.column++),this.setState("select")):(i=n.selection.getWordRange(t.row,t.column),this.setState("selectByWords")),this.$clickSelection=i,this.select()},this.onTripleClick=function(e){var t=e.getDocumentPosition(),n=this.editor;this.setState("selectByLines");var r=n.getSelectionRange();r.isMultiLine()&&r.contains(t.row,t.column)?(this.$clickSelection=n.selection.getLineRange(r.start.row),this.$clickSelection.end=n.selection.getLineRange(r.end.row).end):this.$clickSelection=n.selection.getLineRange(t.row),this.select()},this.onQuadClick=function(e){var t=this.editor;t.selectAll(),this.$clickSelection=t.getSelectionRange(),this.setState("selectAll")},this.onMouseWheel=function(e){if(e.getAccelKey())return;e.getShiftKey()&&e.wheelY&&!e.wheelX&&(e.wheelX=e.wheelY,e.wheelY=0);var t=this.editor;this.$lastScroll||(this.$lastScroll={t:0,vx:0,vy:0,allowed:0});var n=this.$lastScroll,r=e.domEvent.timeStamp,i=r-n.t,o=i?e.wheelX/i:n.vx,u=i?e.wheelY/i:n.vy;i<s&&(o=(o+n.vx)/2,u=(u+n.vy)/2);var a=Math.abs(o/u),f=!1;a>=1&&t.renderer.isScrollableBy(e.wheelX*e.speed,0)&&(f=!0),a<=1&&t.renderer.isScrollableBy(0,e.wheelY*e.speed)&&(f=!0);if(f)n.allowed=r;else if(r-n.allowed<s){var l=Math.abs(o)<=1.5*Math.abs(n.vx)&&Math.abs(u)<=1.5*Math.abs(n.vy);l?(f=!0,n.allowed=r):n.allowed=0}n.t=r,n.vx=o,n.vy=u;if(f)return t.renderer.scrollBy(e.wheelX*e.speed,e.wheelY*e.speed),e.stop()},this.onTouchMove=function(e){this.editor._emit("mousewheel",e)}}).call(o.prototype),t.DefaultHandlers=o}),ace.define("ace/tooltip",["require","exports","module","ace/lib/oop","ace/lib/dom"],function(e,t,n){"use strict";function s(e){this.isOpen=!1,this.$element=null,this.$parentNode=e}var r=e("./lib/oop"),i=e("./lib/dom");(function(){this.$init=function(){return this.$element=i.createElement("div"),this.$element.className="ace_tooltip",this.$element.style.display="none",this.$parentNode.appendChild(this.$element),this.$element},this.getElement=function(){return this.$element||this.$init()},this.setText=function(e){this.getElement().textContent=e},this.setHtml=function(e){this.getElement().innerHTML=e},this.setPosition=function(e,t){this.getElement().style.left=e+"px",this.getElement().style.top=t+"px"},this.setClassName=function(e){i.addCssClass(this.getElement(),e)},this.show=function(e,t,n){e!=null&&this.setText(e),t!=null&&n!=null&&this.setPosition(t,n),this.isOpen||(this.getElement().style.display="block",this.isOpen=!0)},this.hide=function(){this.isOpen&&(this.getElement().style.display="none",this.isOpen=!1)},this.getHeight=function(){return this.getElement().offsetHeight},this.getWidth=function(){return this.getElement().offsetWidth},this.destroy=function(){this.isOpen=!1,this.$element&&this.$element.parentNode&&this.$element.parentNode.removeChild(this.$element)}}).call(s.prototype),t.Tooltip=s}),ace.define("ace/mouse/default_gutter_handler",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event","ace/tooltip"],function(e,t,n){"use strict";function u(e){function l(){var r=u.getDocumentPosition().row,s=n.$annotations[r];if(!s)return c();var o=t.session.getLength();if(r==o){var a=t.renderer.pixelToScreenCoordinates(0,u.y).row,l=u.$pos;if(a>t.session.documentToScreenRow(l.row,l.column))return c()}if(f==s)return;f=s.text.join("<br/>"),i.setHtml(f),i.show(),t._signal("showGutterTooltip",i),t.on("mousewheel",c);if(e.$tooltipFollowsMouse)h(u);else{var p=u.domEvent.target,d=p.getBoundingClientRect(),v=i.getElement().style;v.left=d.right+"px",v.top=d.bottom+"px"}}function c(){o&&(o=clearTimeout(o)),f&&(i.hide(),f=null,t._signal("hideGutterTooltip",i),t.removeEventListener("mousewheel",c))}function h(e){i.setPosition(e.x,e.y)}var t=e.editor,n=t.renderer.$gutterLayer,i=new a(t.container);e.editor.setDefaultHandler("guttermousedown",function(r){if(!t.isFocused()||r.getButton()!=0)return;var i=n.getRegion(r);if(i=="foldWidgets")return;var s=r.getDocumentPosition().row,o=t.session.selection;if(r.getShiftKey())o.selectTo(s,0);else{if(r.domEvent.detail==2)return t.selectAll(),r.preventDefault();e.$clickSelection=t.selection.getLineRange(s)}return e.setState("selectByLines"),e.captureMouse(r),r.preventDefault()});var o,u,f;e.editor.setDefaultHandler("guttermousemove",function(t){var n=t.domEvent.target||t.domEvent.srcElement;if(r.hasCssClass(n,"ace_fold-widget"))return c();f&&e.$tooltipFollowsMouse&&h(t),u=t;if(o)return;o=setTimeout(function(){o=null,u&&!e.isMousePressed?l():c()},50)}),s.addListener(t.renderer.$gutter,"mouseout",function(e){u=null;if(!f||o)return;o=setTimeout(function(){o=null,c()},50)}),t.on("changeSession",c)}function a(e){o.call(this,e)}var r=e("../lib/dom"),i=e("../lib/oop"),s=e("../lib/event"),o=e("../tooltip").Tooltip;i.inherits(a,o),function(){this.setPosition=function(e,t){var n=window.innerWidth||document.documentElement.clientWidth,r=window.innerHeight||document.documentElement.clientHeight,i=this.getWidth(),s=this.getHeight();e+=15,t+=15,e+i>n&&(e-=e+i-n),t+s>r&&(t-=20+s),o.prototype.setPosition.call(this,e,t)}}.call(a.prototype),t.GutterHandler=u}),ace.define("ace/mouse/mouse_event",["require","exports","module","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=t.MouseEvent=function(e,t){this.domEvent=e,this.editor=t,this.x=this.clientX=e.clientX,this.y=this.clientY=e.clientY,this.$pos=null,this.$inSelection=null,this.propagationStopped=!1,this.defaultPrevented=!1};(function(){this.stopPropagation=function(){r.stopPropagation(this.domEvent),this.propagationStopped=!0},this.preventDefault=function(){r.preventDefault(this.domEvent),this.defaultPrevented=!0},this.stop=function(){this.stopPropagation(),this.preventDefault()},this.getDocumentPosition=function(){return this.$pos?this.$pos:(this.$pos=this.editor.renderer.screenToTextCoordinates(this.clientX,this.clientY),this.$pos)},this.inSelection=function(){if(this.$inSelection!==null)return this.$inSelection;var e=this.editor,t=e.getSelectionRange();if(t.isEmpty())this.$inSelection=!1;else{var n=this.getDocumentPosition();this.$inSelection=t.contains(n.row,n.column)}return this.$inSelection},this.getButton=function(){return r.getButton(this.domEvent)},this.getShiftKey=function(){return this.domEvent.shiftKey},this.getAccelKey=i.isMac?function(){return this.domEvent.metaKey}:function(){return this.domEvent.ctrlKey}}).call(s.prototype)}),ace.define("ace/mouse/dragdrop_handler",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";function f(e){function T(e,n){var r=Date.now(),i=!n||e.row!=n.row,s=!n||e.column!=n.column;if(!S||i||s)t.moveCursorToPosition(e),S=r,x={x:p,y:d};else{var o=l(x.x,x.y,p,d);o>a?S=null:r-S>=u&&(t.renderer.scrollCursorIntoView(),S=null)}}function N(e,n){var r=Date.now(),i=t.renderer.layerConfig.lineHeight,s=t.renderer.layerConfig.characterWidth,u=t.renderer.scroller.getBoundingClientRect(),a={x:{left:p-u.left,right:u.right-p},y:{top:d-u.top,bottom:u.bottom-d}},f=Math.min(a.x.left,a.x.right),l=Math.min(a.y.top,a.y.bottom),c={row:e.row,column:e.column};f/s<=2&&(c.column+=a.x.left<a.x.right?-3:2),l/i<=1&&(c.row+=a.y.top<a.y.bottom?-1:1);var h=e.row!=c.row,v=e.column!=c.column,m=!n||e.row!=n.row;h||v&&!m?E?r-E>=o&&t.renderer.scrollCursorIntoView(c):E=r:E=null}function C(){var e=g;g=t.renderer.screenToTextCoordinates(p,d),T(g,e),N(g,e)}function k(){m=t.selection.toOrientedRange(),h=t.session.addMarker(m,"ace_selection",t.getSelectionStyle()),t.clearSelection(),t.isFocused()&&t.renderer.$cursorLayer.setBlinking(!1),clearInterval(v),C(),v=setInterval(C,20),y=0,i.addListener(document,"mousemove",O)}function L(){clearInterval(v),t.session.removeMarker(h),h=null,t.selection.fromOrientedRange(m),t.isFocused()&&!w&&t.renderer.$cursorLayer.setBlinking(!t.getReadOnly()),m=null,g=null,y=0,E=null,S=null,i.removeListener(document,"mousemove",O)}function O(){A==null&&(A=setTimeout(function(){A!=null&&h&&L()},20))}function M(e){var t=e.types;return!t||Array.prototype.some.call(t,function(e){return e=="text/plain"||e=="Text"})}function _(e){var t=["copy","copymove","all","uninitialized"],n=["move","copymove","linkmove","all","uninitialized"],r=s.isMac?e.altKey:e.ctrlKey,i="uninitialized";try{i=e.dataTransfer.effectAllowed.toLowerCase()}catch(e){}var o="none";return r&&t.indexOf(i)>=0?o="copy":n.indexOf(i)>=0?o="move":t.indexOf(i)>=0&&(o="copy"),o}var t=e.editor,n=r.createElement("img");n.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",s.isOpera&&(n.style.cssText="width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;");var f=["dragWait","dragWaitEnd","startDrag","dragReadyEnd","onMouseDrag"];f.forEach(function(t){e[t]=this[t]},this),t.addEventListener("mousedown",this.onMouseDown.bind(e));var c=t.container,h,p,d,v,m,g,y=0,b,w,E,S,x;this.onDragStart=function(e){if(this.cancelDrag||!c.draggable){var r=this;return setTimeout(function(){r.startSelect(),r.captureMouse(e)},0),e.preventDefault()}m=t.getSelectionRange();var i=e.dataTransfer;i.effectAllowed=t.getReadOnly()?"copy":"copyMove",s.isOpera&&(t.container.appendChild(n),n.scrollTop=0),i.setDragImage&&i.setDragImage(n,0,0),s.isOpera&&t.container.removeChild(n),i.clearData(),i.setData("Text",t.session.getTextRange()),w=!0,this.setState("drag")},this.onDragEnd=function(e){c.draggable=!1,w=!1,this.setState(null);if(!t.getReadOnly()){var n=e.dataTransfer.dropEffect;!b&&n=="move"&&t.session.remove(t.getSelectionRange()),t.renderer.$cursorLayer.setBlinking(!0)}this.editor.unsetStyle("ace_dragging"),this.editor.renderer.setCursorStyle("")},this.onDragEnter=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||k(),y++,e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragOver=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||(k(),y++),A!==null&&(A=null),e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragLeave=function(e){y--;if(y<=0&&h)return L(),b=null,i.preventDefault(e)},this.onDrop=function(e){if(!g)return;var n=e.dataTransfer;if(w)switch(b){case"move":m.contains(g.row,g.column)?m={start:g,end:g}:m=t.moveText(m,g);break;case"copy":m=t.moveText(m,g,!0)}else{var r=n.getData("Text");m={start:g,end:t.session.insert(g,r)},t.focus(),b=null}return L(),i.preventDefault(e)},i.addListener(c,"dragstart",this.onDragStart.bind(e)),i.addListener(c,"dragend",this.onDragEnd.bind(e)),i.addListener(c,"dragenter",this.onDragEnter.bind(e)),i.addListener(c,"dragover",this.onDragOver.bind(e)),i.addListener(c,"dragleave",this.onDragLeave.bind(e)),i.addListener(c,"drop",this.onDrop.bind(e));var A=null}function l(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}var r=e("../lib/dom"),i=e("../lib/event"),s=e("../lib/useragent"),o=200,u=200,a=5;(function(){this.dragWait=function(){var e=Date.now()-this.mousedownEvent.time;e>this.editor.getDragDelay()&&this.startDrag()},this.dragWaitEnd=function(){var e=this.editor.container;e.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()),this.selectEnd()},this.dragReadyEnd=function(e){this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly()),this.editor.unsetStyle("ace_dragging"),this.editor.renderer.setCursorStyle(""),this.dragWaitEnd()},this.startDrag=function(){this.cancelDrag=!1;var e=this.editor,t=e.container;t.draggable=!0,e.renderer.$cursorLayer.setBlinking(!1),e.setStyle("ace_dragging");var n=s.isWin?"default":"move";e.renderer.setCursorStyle(n),this.setState("dragReady")},this.onMouseDrag=function(e){var t=this.editor.container;if(s.isIE&&this.state=="dragReady"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>3&&t.dragDrop()}if(this.state==="dragWait"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>0&&(t.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()))}},this.onMouseDown=function(e){if(!this.$dragEnabled)return;this.mousedownEvent=e;var t=this.editor,n=e.inSelection(),r=e.getButton(),i=e.domEvent.detail||1;if(i===1&&r===0&&n){if(e.editor.inMultiSelectMode&&(e.getAccelKey()||e.getShiftKey()))return;this.mousedownEvent.time=Date.now();var o=e.domEvent.target||e.domEvent.srcElement;"unselectable"in o&&(o.unselectable="on");if(t.getDragDelay()){if(s.isWebKit){this.cancelDrag=!0;var u=t.container;u.draggable=!0}this.setState("dragWait")}else this.startDrag();this.captureMouse(e,this.onMouseDrag.bind(this)),e.defaultPrevented=!0}}}).call(f.prototype),t.DragdropHandler=f}),ace.define("ace/lib/net",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("./dom");t.get=function(e,t){var n=new XMLHttpRequest;n.open("GET",e,!0),n.onreadystatechange=function(){n.readyState===4&&t(n.responseText)},n.send(null)},t.loadScript=function(e,t){var n=r.getDocumentHead(),i=document.createElement("script");i.src=e,n.appendChild(i),i.onload=i.onreadystatechange=function(e,n){if(n||!i.readyState||i.readyState=="loaded"||i.readyState=="complete")i=i.onload=i.onreadystatechange=null,n||t()}},t.qualifyURL=function(e){var t=document.createElement("a");return t.href=e,t.href}}),ace.define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)});if(!t)return new Promise(function(e){t=e})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t)r&&this.setDefaultHandler(e,r.pop());else if(r){var i=r.indexOf(t);i!=-1&&r.splice(i,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?"unshift":"push"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define("ace/lib/app_config",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"no use strict";function o(e){typeof console!="undefined"&&console.warn&&console.warn.apply(console,arguments)}function u(e,t){var n=new Error(e);n.data=t,typeof console=="object"&&console.error&&console.error(n),setTimeout(function(){throw n})}var r=e("./oop"),i=e("./event_emitter").EventEmitter,s={setOptions:function(e){Object.keys(e).forEach(function(t){this.setOption(t,e[t])},this)},getOptions:function(e){var t={};if(!e){var n=this.$options;e=Object.keys(n).filter(function(e){return!n[e].hidden})}else Array.isArray(e)||(t=e,e=Object.keys(t));return e.forEach(function(e){t[e]=this.getOption(e)},this),t},setOption:function(e,t){if(this["$"+e]===t)return;var n=this.$options[e];if(!n)return o('misspelled option "'+e+'"');if(n.forwardTo)return this[n.forwardTo]&&this[n.forwardTo].setOption(e,t);n.handlesSet||(this["$"+e]=t),n&&n.set&&n.set.call(this,t)},getOption:function(e){var t=this.$options[e];return t?t.forwardTo?this[t.forwardTo]&&this[t.forwardTo].getOption(e):t&&t.get?t.get.call(this):this["$"+e]:o('misspelled option "'+e+'"')}},a=function(){this.$defaultOptions={}};(function(){r.implement(this,i),this.defineOptions=function(e,t,n){return e.$options||(this.$defaultOptions[t]=e.$options={}),Object.keys(n).forEach(function(t){var r=n[t];typeof r=="string"&&(r={forwardTo:r}),r.name||(r.name=t),e.$options[r.name]=r,"initialValue"in r&&(e["$"+r.name]=r.initialValue)}),r.implement(e,s),this},this.resetOptions=function(e){Object.keys(e.$options).forEach(function(t){var n=e.$options[t];"value"in n&&e.setOption(t,n.value)})},this.setDefaultValue=function(e,t,n){var r=this.$defaultOptions[e]||(this.$defaultOptions[e]={});r[t]&&(r.forwardTo?this.setDefaultValue(r.forwardTo,t,n):r[t].value=n)},this.setDefaultValues=function(e,t){Object.keys(t).forEach(function(n){this.setDefaultValue(e,n,t[n])},this)},this.warn=o,this.reportError=u}).call(a.prototype),t.AppConfig=a}),ace.define("ace/config",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/lib/net","ace/lib/app_config"],function(e,t,n){"no use strict";function l(r){if(!u||!u.document)return;a.packaged=r||e.packaged||n.packaged||u.define&&define.packaged;var i={},s="",o=document.currentScript||document._currentScript,f=o&&o.ownerDocument||document,l=f.getElementsByTagName("script");for(var h=0;h<l.length;h++){var p=l[h],d=p.src||p.getAttribute("src");if(!d)continue;var v=p.attributes;for(var m=0,g=v.length;m<g;m++){var y=v[m];y.name.indexOf("data-ace-")===0&&(i[c(y.name.replace(/^data-ace-/,""))]=y.value)}var b=d.match(/^(.*)\/ace(\-\w+)?\.js(\?|$)/);b&&(s=b[1])}s&&(i.base=i.base||s,i.packaged=!0),i.basePath=i.base,i.workerPath=i.workerPath||i.base,i.modePath=i.modePath||i.base,i.themePath=i.themePath||i.base,delete i.base;for(var w in i)typeof i[w]!="undefined"&&t.set(w,i[w])}function c(e){return e.replace(/-(.)/g,function(e,t){return t.toUpperCase()})}var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./lib/net"),o=e("./lib/app_config").AppConfig;n.exports=t=new o;var u=function(){return this||typeof window!="undefined"&&window}(),a={packaged:!1,workerPath:null,modePath:null,themePath:null,basePath:"",suffix:".js",$moduleUrls:{},loadWorkerFromBlob:!0};t.get=function(e){if(!a.hasOwnProperty(e))throw new Error("Unknown config key: "+e);return a[e]},t.set=function(e,t){if(!a.hasOwnProperty(e))throw new Error("Unknown config key: "+e);a[e]=t},t.all=function(){return r.copyObject(a)},t.$modes={},t.moduleUrl=function(e,t){if(a.$moduleUrls[e])return a.$moduleUrls[e];var n=e.split("/");t=t||n[n.length-2]||"";var r=t=="snippets"?"/":"-",i=n[n.length-1];if(t=="worker"&&r=="-"){var s=new RegExp("^"+t+"[\\-_]|[\\-_]"+t+"$","g");i=i.replace(s,"")}(!i||i==t)&&n.length>1&&(i=n[n.length-2]);var o=a[t+"Path"];return o==null?o=a.basePath:r=="/"&&(t=r=""),o&&o.slice(-1)!="/"&&(o+="/"),o+t+r+i+this.get("suffix")},t.setModuleUrl=function(e,t){return a.$moduleUrls[e]=t},t.$loading={},t.loadModule=function(n,r){var i,o;Array.isArray(n)&&(o=n[0],n=n[1]);try{i=e(n)}catch(u){}if(i&&!t.$loading[n])return r&&r(i);t.$loading[n]||(t.$loading[n]=[]),t.$loading[n].push(r);if(t.$loading[n].length>1)return;var a=function(){e([n],function(e){t._emit("load.module",{name:n,module:e});var r=t.$loading[n];t.$loading[n]=null,r.forEach(function(t){t&&t(e)})})};if(!t.get("packaged"))return a();s.loadScript(t.moduleUrl(n,o),a),f()};var f=function(){!a.basePath&&!a.workerPath&&!a.modePath&&!a.themePath&&!Object.keys(a.$moduleUrls).length&&(console.error("Unable to infer path to ace from script src,","use ace.config.set('basePath', 'path') to enable dynamic loading of modes and themes","or with webpack use ace/webpack-resolver"),f=function(){})};t.init=l}),ace.define("ace/mouse/mouse_handler",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/mouse/default_handlers","ace/mouse/default_gutter_handler","ace/mouse/mouse_event","ace/mouse/dragdrop_handler","ace/config"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=e("./default_handlers").DefaultHandlers,o=e("./default_gutter_handler").GutterHandler,u=e("./mouse_event").MouseEvent,a=e("./dragdrop_handler").DragdropHandler,f=e("../config"),l=function(e){var t=this;this.editor=e,new s(this),new o(this),new a(this);var n=function(t){var n=!document.hasFocus||!document.hasFocus()||!e.isFocused()&&document.activeElement==(e.textInput&&e.textInput.getElement());n&&window.focus(),e.focus()},u=e.renderer.getMouseEventTarget();r.addListener(u,"click",this.onMouseEvent.bind(this,"click")),r.addListener(u,"mousemove",this.onMouseMove.bind(this,"mousemove")),r.addMultiMouseDownListener([u,e.renderer.scrollBarV&&e.renderer.scrollBarV.inner,e.renderer.scrollBarH&&e.renderer.scrollBarH.inner,e.textInput&&e.textInput.getElement()].filter(Boolean),[400,300,250],this,"onMouseEvent"),r.addMouseWheelListener(e.container,this.onMouseWheel.bind(this,"mousewheel")),r.addTouchMoveListener(e.container,this.onTouchMove.bind(this,"touchmove"));var f=e.renderer.$gutter;r.addListener(f,"mousedown",this.onMouseEvent.bind(this,"guttermousedown")),r.addListener(f,"click",this.onMouseEvent.bind(this,"gutterclick")),r.addListener(f,"dblclick",this.onMouseEvent.bind(this,"gutterdblclick")),r.addListener(f,"mousemove",this.onMouseEvent.bind(this,"guttermousemove")),r.addListener(u,"mousedown",n),r.addListener(f,"mousedown",n),i.isIE&&e.renderer.scrollBarV&&(r.addListener(e.renderer.scrollBarV.element,"mousedown",n),r.addListener(e.renderer.scrollBarH.element,"mousedown",n)),e.on("mousemove",function(n){if(t.state||t.$dragDelay||!t.$dragEnabled)return;var r=e.renderer.screenToTextCoordinates(n.x,n.y),i=e.session.selection.getRange(),s=e.renderer;!i.isEmpty()&&i.insideStart(r.row,r.column)?s.setCursorStyle("default"):s.setCursorStyle("")})};(function(){this.onMouseEvent=function(e,t){this.editor._emit(e,new u(t,this.editor))},this.onMouseMove=function(e,t){var n=this.editor._eventRegistry&&this.editor._eventRegistry.mousemove;if(!n||!n.length)return;this.editor._emit(e,new u(t,this.editor))},this.onMouseWheel=function(e,t){var n=new u(t,this.editor);n.speed=this.$scrollSpeed*2,n.wheelX=t.wheelX,n.wheelY=t.wheelY,this.editor._emit(e,n)},this.onTouchMove=function(e,t){var n=new u(t,this.editor);n.speed=1,n.wheelX=t.wheelX,n.wheelY=t.wheelY,this.editor._emit(e,n)},this.setState=function(e){this.state=e},this.captureMouse=function(e,t){this.x=e.x,this.y=e.y,this.isMousePressed=!0;var n=this.editor,s=this.editor.renderer;s.$keepTextAreaAtCursor&&(s.$keepTextAreaAtCursor=null);var o=this,a=function(e){if(!e)return;if(i.isWebKit&&!e.which&&o.releaseMouse)return o.releaseMouse();o.x=e.clientX,o.y=e.clientY,t&&t(e),o.mouseEvent=new u(e,o.editor),o.$mouseMoved=!0},f=function(e){n.off("beforeEndOperation",c),clearInterval(h),l(),o[o.state+"End"]&&o[o.state+"End"](e),o.state="",s.$keepTextAreaAtCursor==null&&(s.$keepTextAreaAtCursor=!0,s.$moveTextAreaToCursor()),o.isMousePressed=!1,o.$onCaptureMouseMove=o.releaseMouse=null,e&&o.onMouseEvent("mouseup",e),n.endOperation()},l=function(){o[o.state]&&o[o.state](),o.$mouseMoved=!1};if(i.isOldIE&&e.domEvent.type=="dblclick")return setTimeout(function(){f(e)});var c=function(e){if(!o.releaseMouse)return;n.curOp.command.name&&n.curOp.selectionChanged&&(o[o.state+"End"]&&o[o.state+"End"](),o.state="",o.releaseMouse())};n.on("beforeEndOperation",c),n.startOperation({command:{name:"mouse"}}),o.$onCaptureMouseMove=a,o.releaseMouse=r.capture(this.editor.container,a,f);var h=setInterval(l,20)},this.releaseMouse=null,this.cancelContextMenu=function(){var e=function(t){if(t&&t.domEvent&&t.domEvent.type!="contextmenu")return;this.editor.off("nativecontextmenu",e),t&&t.domEvent&&r.stopEvent(t.domEvent)}.bind(this);setTimeout(e,10),this.editor.on("nativecontextmenu",e)}}).call(l.prototype),f.defineOptions(l.prototype,"mouseHandler",{scrollSpeed:{initialValue:2},dragDelay:{initialValue:i.isMac?150:0},dragEnabled:{initialValue:!0},focusTimeout:{initialValue:0},tooltipFollowsMouse:{initialValue:!0}}),t.MouseHandler=l}),ace.define("ace/mouse/fold_handler",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";function i(e){e.on("click",function(t){var n=t.getDocumentPosition(),i=e.session,s=i.getFoldAt(n.row,n.column,1);s&&(t.getAccelKey()?i.removeFold(s):i.expandFold(s),t.stop());var o=t.domEvent&&t.domEvent.target;o&&r.hasCssClass(o,"ace_inline_button")&&r.hasCssClass(o,"ace_toggle_wrap")&&(i.setOption("wrap",!0),e.renderer.scrollCursorIntoView())}),e.on("gutterclick",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n=="foldWidgets"){var r=t.getDocumentPosition().row,i=e.session;i.foldWidgets&&i.foldWidgets[r]&&e.session.onFoldWidgetClick(r,t),e.isFocused()||e.focus(),t.stop()}}),e.on("gutterdblclick",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n=="foldWidgets"){var r=t.getDocumentPosition().row,i=e.session,s=i.getParentFoldRangeData(r,!0),o=s.range||s.firstRange;if(o){r=o.start.row;var u=i.getFoldAt(r,i.getLine(r).length,1);u?i.removeFold(u):(i.addFold("...",o),e.renderer.scrollCursorIntoView({row:o.start.row,column:0}))}t.stop()}})}var r=e("../lib/dom");t.FoldHandler=i}),ace.define("ace/keyboard/keybinding",["require","exports","module","ace/lib/keys","ace/lib/event"],function(e,t,n){"use strict";var r=e("../lib/keys"),i=e("../lib/event"),s=function(e){this.$editor=e,this.$data={editor:e},this.$handlers=[],this.setDefaultHandler(e.commands)};(function(){this.setDefaultHandler=function(e){this.removeKeyboardHandler(this.$defaultHandler),this.$defaultHandler=e,this.addKeyboardHandler(e,0)},this.setKeyboardHandler=function(e){var t=this.$handlers;if(t[t.length-1]==e)return;while(t[t.length-1]&&t[t.length-1]!=this.$defaultHandler)this.removeKeyboardHandler(t[t.length-1]);this.addKeyboardHandler(e,1)},this.addKeyboardHandler=function(e,t){if(!e)return;typeof e=="function"&&!e.handleKeyboard&&(e.handleKeyboard=e);var n=this.$handlers.indexOf(e);n!=-1&&this.$handlers.splice(n,1),t==undefined?this.$handlers.push(e):this.$handlers.splice(t,0,e),n==-1&&e.attach&&e.attach(this.$editor)},this.removeKeyboardHandler=function(e){var t=this.$handlers.indexOf(e);return t==-1?!1:(this.$handlers.splice(t,1),e.detach&&e.detach(this.$editor),!0)},this.getKeyboardHandler=function(){return this.$handlers[this.$handlers.length-1]},this.getStatusText=function(){var e=this.$data,t=e.editor;return this.$handlers.map(function(n){return n.getStatusText&&n.getStatusText(t,e)||""}).filter(Boolean).join(" ")},this.$callKeyboardHandlers=function(e,t,n,r){var s,o=!1,u=this.$editor.commands;for(var a=this.$handlers.length;a--;){s=this.$handlers[a].handleKeyboard(this.$data,e,t,n,r);if(!s||!s.command)continue;s.command=="null"?o=!0:o=u.exec(s.command,this.$editor,s.args,r),o&&r&&e!=-1&&s.passEvent!=1&&s.command.passEvent!=1&&i.stopEvent(r);if(o)break}return!o&&e==-1&&(s={command:"insertstring"},o=u.exec("insertstring",this.$editor,t)),o&&this.$editor._signal&&this.$editor._signal("keyboardActivity",s),o},this.onCommandKey=function(e,t,n){var i=r.keyCodeToString(n);this.$callKeyboardHandlers(t,i,n,e)},this.onTextInput=function(e){this.$callKeyboardHandlers(-1,e)}}).call(s.prototype),t.KeyBinding=s}),ace.define("ace/lib/bidiutil",["require","exports","module"],function(e,t,n){"use strict";function F(e,t,n,r){var i=s?d:p,c=null,h=null,v=null,m=0,g=null,y=null,b=-1,w=null,E=null,T=[];if(!r)for(w=0,r=[];w<n;w++)r[w]=R(e[w]);o=s,u=!1,a=!1,f=!1,l=!1;for(E=0;E<n;E++){c=m,T[E]=h=q(e,r,T,E),m=i[c][h],g=m&240,m&=15,t[E]=v=i[m][5];if(g>0)if(g==16){for(w=b;w<E;w++)t[w]=1;b=-1}else b=-1;y=i[m][6];if(y)b==-1&&(b=E);else if(b>-1){for(w=b;w<E;w++)t[w]=v;b=-1}r[E]==S&&(t[E]=0),o|=v}if(l)for(w=0;w<n;w++)if(r[w]==x){t[w]=s;for(var C=w-1;C>=0;C--){if(r[C]!=N)break;t[C]=s}}}function I(e,t,n){if(o<e)return;if(e==1&&s==m&&!f){n.reverse();return}var r=n.length,i=0,u,a,l,c;while(i<r){if(t[i]>=e){u=i+1;while(u<r&&t[u]>=e)u++;for(a=i,l=u-1;a<l;a++,l--)c=n[a],n[a]=n[l],n[l]=c;i=u}i++}}function q(e,t,n,r){var i=t[r],o,c,h,p;switch(i){case g:case y:u=!1;case E:case w:return i;case b:return u?w:b;case T:return u=!0,a=!0,y;case N:return E;case C:if(r<1||r+1>=t.length||(o=n[r-1])!=b&&o!=w||(c=t[r+1])!=b&&c!=w)return E;return u&&(c=w),c==o?c:E;case k:o=r>0?n[r-1]:S;if(o==b&&r+1<t.length&&t[r+1]==b)return b;return E;case L:if(r>0&&n[r-1]==b)return b;if(u)return E;p=r+1,h=t.length;while(p<h&&t[p]==L)p++;if(p<h&&t[p]==b)return b;return E;case A:h=t.length,p=r+1;while(p<h&&t[p]==A)p++;if(p<h){var d=e[r],v=d>=1425&&d<=2303||d==64286;o=t[p];if(v&&(o==y||o==T))return y}if(r<1||(o=t[r-1])==S)return E;return n[r-1];case S:return u=!1,f=!0,s;case x:return l=!0,E;case O:case M:case D:case P:case _:u=!1;case H:return E}}function R(e){var t=e.charCodeAt(0),n=t>>8;return n==0?t>191?g:B[t]:n==5?/[\u0591-\u05f4]/.test(e)?y:g:n==6?/[\u0610-\u061a\u064b-\u065f\u06d6-\u06e4\u06e7-\u06ed]/.test(e)?A:/[\u0660-\u0669\u066b-\u066c]/.test(e)?w:t==1642?L:/[\u06f0-\u06f9]/.test(e)?b:T:n==32&&t<=8287?j[t&255]:n==254?t>=65136?T:E:E}function U(e){return e>="\u064b"&&e<="\u0655"}var r=["\u0621","\u0641"],i=["\u063a","\u064a"],s=0,o=0,u=!1,a=!1,f=!1,l=!1,c=!1,h=!1,p=[[0,3,0,1,0,0,0],[0,3,0,1,2,2,0],[0,3,0,17,2,0,1],[0,3,5,5,4,1,0],[0,3,21,21,4,0,1],[0,3,5,5,4,2,0]],d=[[2,0,1,1,0,1,0],[2,0,1,1,0,2,0],[2,0,2,1,3,2,0],[2,0,2,33,3,1,1]],v=0,m=1,g=0,y=1,b=2,w=3,E=4,S=5,x=6,T=7,N=8,C=9,k=10,L=11,A=12,O=13,M=14,_=15,D=16,P=17,H=18,B=[H,H,H,H,H,H,H,H,H,x,S,x,N,S,H,H,H,H,H,H,H,H,H,H,H,H,H,H,S,S,S,x,N,E,E,L,L,L,E,E,E,E,E,k,C,k,C,C,b,b,b,b,b,b,b,b,b,b,C,E,E,E,E,E,E,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,E,E,E,E,E,E,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,E,E,E,E,H,H,H,H,H,H,S,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,C,E,L,L,L,L,E,E,E,E,g,E,E,H,E,E,L,L,b,b,E,g,E,E,E,b,g,E,E,E,E,E],j=[N,N,N,N,N,N,N,N,N,N,N,H,H,H,g,y,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,N,S,O,M,_,D,P,C,L,L,L,L,L,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,C,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,N];t.L=g,t.R=y,t.EN=b,t.ON_R=3,t.AN=4,t.R_H=5,t.B=6,t.RLE=7,t.DOT="\u00b7",t.doBidiReorder=function(e,n,r){if(e.length<2)return{};var i=e.split(""),o=new Array(i.length),u=new Array(i.length),a=[];s=r?m:v,F(i,a,i.length,n);for(var f=0;f<o.length;o[f]=f,f++);I(2,a,o),I(1,a,o);for(var f=0;f<o.length-1;f++)n[f]===w?a[f]=t.AN:a[f]===y&&(n[f]>T&&n[f]<O||n[f]===E||n[f]===H)?a[f]=t.ON_R:f>0&&i[f-1]==="\u0644"&&/\u0622|\u0623|\u0625|\u0627/.test(i[f])&&(a[f-1]=a[f]=t.R_H,f++);i[i.length-1]===t.DOT&&(a[i.length-1]=t.B),i[0]==="\u202b"&&(a[0]=t.RLE);for(var f=0;f<o.length;f++)u[f]=a[o[f]];return{logicalFromVisual:o,bidiLevels:u}},t.hasBidiCharacters=function(e,t){var n=!1;for(var r=0;r<e.length;r++)t[r]=R(e.charAt(r)),!n&&(t[r]==y||t[r]==T||t[r]==w)&&(n=!0);return n},t.getVisualFromLogicalIdx=function(e,t){for(var n=0;n<t.logicalFromVisual.length;n++)if(t.logicalFromVisual[n]==e)return n;return 0}}),ace.define("ace/bidihandler",["require","exports","module","ace/lib/bidiutil","ace/lib/lang"],function(e,t,n){"use strict";var r=e("./lib/bidiutil"),i=e("./lib/lang"),s=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac\u202B]/,o=function(e){this.session=e,this.bidiMap={},this.currentRow=null,this.bidiUtil=r,this.charWidths=[],this.EOL="\u00ac",this.showInvisibles=!0,this.isRtlDir=!1,this.$isRtl=!1,this.line="",this.wrapIndent=0,this.EOF="\u00b6",this.RLE="\u202b",this.contentWidth=0,this.fontMetrics=null,this.rtlLineOffset=0,this.wrapOffset=0,this.isMoveLeftOperation=!1,this.seenBidi=s.test(e.getValue())};(function(){this.isBidiRow=function(e,t,n){return this.seenBidi?(e!==this.currentRow&&(this.currentRow=e,this.updateRowLine(t,n),this.updateBidiMap()),this.bidiMap.bidiLevels):!1},this.onChange=function(e){this.seenBidi?this.currentRow=null:e.action=="insert"&&s.test(e.lines.join("\n"))&&(this.seenBidi=!0,this.currentRow=null)},this.getDocumentRow=function(){var e=0,t=this.session.$screenRowCache;if(t.length){var n=this.session.$getRowCacheIndex(t,this.currentRow);n>=0&&(e=this.session.$docRowCache[n])}return e},this.getSplitIndex=function(){var e=0,t=this.session.$screenRowCache;if(t.length){var n,r=this.session.$getRowCacheIndex(t,this.currentRow);while(this.currentRow-e>0){n=this.session.$getRowCacheIndex(t,this.currentRow-e-1);if(n!==r)break;r=n,e++}}else e=this.currentRow;return e},this.updateRowLine=function(e,t){e===undefined&&(e=this.getDocumentRow());var n=e===this.session.getLength()-1,s=n?this.EOF:this.EOL;this.wrapIndent=0,this.line=this.session.getLine(e),this.isRtlDir=this.$isRtl||this.line.charAt(0)===this.RLE;if(this.session.$useWrapMode){var o=this.session.$wrapData[e];o&&(t===undefined&&(t=this.getSplitIndex()),t>0&&o.length?(this.wrapIndent=o.indent,this.wrapOffset=this.wrapIndent*this.charWidths[r.L],this.line=t<o.length?this.line.substring(o[t-1],o[t]):this.line.substring(o[o.length-1])):this.line=this.line.substring(0,o[t])),t==o.length&&(this.line+=this.showInvisibles?s:r.DOT)}else this.line+=this.showInvisibles?s:r.DOT;var u=this.session,a=0,f;this.line=this.line.replace(/\t|[\u1100-\u2029, \u202F-\uFFE6]/g,function(e,t){return e===" "||u.isFullWidth(e.charCodeAt(0))?(f=e===" "?u.getScreenTabSize(t+a):2,a+=f-1,i.stringRepeat(r.DOT,f)):e}),this.isRtlDir&&(this.fontMetrics.$main.textContent=this.line.charAt(this.line.length-1)==r.DOT?this.line.substr(0,this.line.length-1):this.line,this.rtlLineOffset=this.contentWidth-this.fontMetrics.$main.getBoundingClientRect().width)},this.updateBidiMap=function(){var e=[];r.hasBidiCharacters(this.line,e)||this.isRtlDir?this.bidiMap=r.doBidiReorder(this.line,e,this.isRtlDir):this.bidiMap={}},this.markAsDirty=function(){this.currentRow=null},this.updateCharacterWidths=function(e){if(this.characterWidth===e.$characterSize.width)return;this.fontMetrics=e;var t=this.characterWidth=e.$characterSize.width,n=e.$measureCharWidth("\u05d4");this.charWidths[r.L]=this.charWidths[r.EN]=this.charWidths[r.ON_R]=t,this.charWidths[r.R]=this.charWidths[r.AN]=n,this.charWidths[r.R_H]=n*.45,this.charWidths[r.B]=this.charWidths[r.RLE]=0,this.currentRow=null},this.setShowInvisibles=function(e){this.showInvisibles=e,this.currentRow=null},this.setEolChar=function(e){this.EOL=e},this.setContentWidth=function(e){this.contentWidth=e},this.isRtlLine=function(e){return this.$isRtl?!0:e!=undefined?this.session.getLine(e).charAt(0)==this.RLE:this.isRtlDir},this.setRtlDirection=function(e,t){var n=e.getCursorPosition();for(var r=e.selection.getSelectionAnchor().row;r<=n.row;r++)!t&&e.session.getLine(r).charAt(0)===e.session.$bidiHandler.RLE?e.session.doc.removeInLine(r,0,1):t&&e.session.getLine(r).charAt(0)!==e.session.$bidiHandler.RLE&&e.session.doc.insert({column:0,row:r},e.session.$bidiHandler.RLE)},this.getPosLeft=function(e){e-=this.wrapIndent;var t=this.line.charAt(0)===this.RLE?1:0,n=e>t?this.session.getOverwrite()?e:e-1:t,i=r.getVisualFromLogicalIdx(n,this.bidiMap),s=this.bidiMap.bidiLevels,o=0;!this.session.getOverwrite()&&e<=t&&s[i]%2!==0&&i++;for(var u=0;u<i;u++)o+=this.charWidths[s[u]];return!this.session.getOverwrite()&&e>t&&s[i]%2===0&&(o+=this.charWidths[s[i]]),this.wrapIndent&&(o+=this.isRtlDir?-1*this.wrapOffset:this.wrapOffset),this.isRtlDir&&(o+=this.rtlLineOffset),o},this.getSelections=function(e,t){var n=this.bidiMap,r=n.bidiLevels,i,s=[],o=0,u=Math.min(e,t)-this.wrapIndent,a=Math.max(e,t)-this.wrapIndent,f=!1,l=!1,c=0;this.wrapIndent&&(o+=this.isRtlDir?-1*this.wrapOffset:this.wrapOffset);for(var h,p=0;p<r.length;p++)h=n.logicalFromVisual[p],i=r[p],f=h>=u&&h<a,f&&!l?c=o:!f&&l&&s.push({left:c,width:o-c}),o+=this.charWidths[i],l=f;f&&p===r.length&&s.push({left:c,width:o-c});if(this.isRtlDir)for(var d=0;d<s.length;d++)s[d].left+=this.rtlLineOffset;return s},this.offsetToCol=function(e){this.isRtlDir&&(e-=this.rtlLineOffset);var t=0,e=Math.max(e,0),n=0,r=0,i=this.bidiMap.bidiLevels,s=this.charWidths[i[r]];this.wrapIndent&&(e-=this.isRtlDir?-1*this.wrapOffset:this.wrapOffset);while(e>n+s/2){n+=s;if(r===i.length-1){s=0;break}s=this.charWidths[i[++r]]}return r>0&&i[r-1]%2!==0&&i[r]%2===0?(e<n&&r--,t=this.bidiMap.logicalFromVisual[r]):r>0&&i[r-1]%2===0&&i[r]%2!==0?t=1+(e>n?this.bidiMap.logicalFromVisual[r]:this.bidiMap.logicalFromVisual[r-1]):this.isRtlDir&&r===i.length-1&&s===0&&i[r-1]%2===0||!this.isRtlDir&&r===0&&i[r]%2!==0?t=1+this.bidiMap.logicalFromVisual[r]:(r>0&&i[r-1]%2!==0&&s!==0&&r--,t=this.bidiMap.logicalFromVisual[r]),t===0&&this.isRtlDir&&t++,t+this.wrapIndent}}).call(o.prototype),t.BidiHandler=o}),ace.define("ace/selection",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter","ace/range"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/lang"),s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=function(e){this.session=e,this.doc=e.getDocument(),this.clearSelection(),this.cursor=this.lead=this.doc.createAnchor(0,0),this.anchor=this.doc.createAnchor(0,0),this.$silent=!1;var t=this;this.cursor.on("change",function(e){t.$cursorChanged=!0,t.$silent||t._emit("changeCursor"),!t.$isEmpty&&!t.$silent&&t._emit("changeSelection"),!t.$keepDesiredColumnOnChange&&e.old.column!=e.value.column&&(t.$desiredColumn=null)}),this.anchor.on("change",function(){t.$anchorChanged=!0,!t.$isEmpty&&!t.$silent&&t._emit("changeSelection")})};(function(){r.implement(this,s),this.isEmpty=function(){return this.$isEmpty||this.anchor.row==this.lead.row&&this.anchor.column==this.lead.column},this.isMultiLine=function(){return!this.$isEmpty&&this.anchor.row!=this.cursor.row},this.getCursor=function(){return this.lead.getPosition()},this.setSelectionAnchor=function(e,t){this.$isEmpty=!1,this.anchor.setPosition(e,t)},this.getAnchor=this.getSelectionAnchor=function(){return this.$isEmpty?this.getSelectionLead():this.anchor.getPosition()},this.getSelectionLead=function(){return this.lead.getPosition()},this.isBackwards=function(){var e=this.anchor,t=this.lead;return e.row>t.row||e.row==t.row&&e.column>t.column},this.getRange=function(){var e=this.anchor,t=this.lead;return this.$isEmpty?o.fromPoints(t,t):this.isBackwards()?o.fromPoints(t,e):o.fromPoints(e,t)},this.clearSelection=function(){this.$isEmpty||(this.$isEmpty=!0,this._emit("changeSelection"))},this.selectAll=function(){this.$setSelection(0,0,Number.MAX_VALUE,Number.MAX_VALUE)},this.setRange=this.setSelectionRange=function(e,t){var n=t?e.end:e.start,r=t?e.start:e.end;this.$setSelection(n.row,n.column,r.row,r.column)},this.$setSelection=function(e,t,n,r){var i=this.$isEmpty,s=this.inMultiSelectMode;this.$silent=!0,this.$cursorChanged=this.$anchorChanged=!1,this.anchor.setPosition(e,t),this.cursor.setPosition(n,r),this.$isEmpty=!o.comparePoints(this.anchor,this.cursor),this.$silent=!1,this.$cursorChanged&&this._emit("changeCursor"),(this.$cursorChanged||this.$anchorChanged||i!=this.$isEmpty||s)&&this._emit("changeSelection")},this.$moveSelection=function(e){var t=this.lead;this.$isEmpty&&this.setSelectionAnchor(t.row,t.column),e.call(this)},this.selectTo=function(e,t){this.$moveSelection(function(){this.moveCursorTo(e,t)})},this.selectToPosition=function(e){this.$moveSelection(function(){this.moveCursorToPosition(e)})},this.moveTo=function(e,t){this.clearSelection(),this.moveCursorTo(e,t)},this.moveToPosition=function(e){this.clearSelection(),this.moveCursorToPosition(e)},this.selectUp=function(){this.$moveSelection(this.moveCursorUp)},this.selectDown=function(){this.$moveSelection(this.moveCursorDown)},this.selectRight=function(){this.$moveSelection(this.moveCursorRight)},this.selectLeft=function(){this.$moveSelection(this.moveCursorLeft)},this.selectLineStart=function(){this.$moveSelection(this.moveCursorLineStart)},this.selectLineEnd=function(){this.$moveSelection(this.moveCursorLineEnd)},this.selectFileEnd=function(){this.$moveSelection(this.moveCursorFileEnd)},this.selectFileStart=function(){this.$moveSelection(this.moveCursorFileStart)},this.selectWordRight=function(){this.$moveSelection(this.moveCursorWordRight)},this.selectWordLeft=function(){this.$moveSelection(this.moveCursorWordLeft)},this.getWordRange=function(e,t){if(typeof t=="undefined"){var n=e||this.lead;e=n.row,t=n.column}return this.session.getWordRange(e,t)},this.selectWord=function(){this.setSelectionRange(this.getWordRange())},this.selectAWord=function(){var e=this.getCursor(),t=this.session.getAWordRange(e.row,e.column);this.setSelectionRange(t)},this.getLineRange=function(e,t){var n=typeof e=="number"?e:this.lead.row,r,i=this.session.getFoldLine(n);return i?(n=i.start.row,r=i.end.row):r=n,t===!0?new o(n,0,r,this.session.getLine(r).length):new o(n,0,r+1,0)},this.selectLine=function(){this.setSelectionRange(this.getLineRange())},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.wouldMoveIntoSoftTab=function(e,t,n){var r=e.column,i=e.column+t;return n<0&&(r=e.column-t,i=e.column),this.session.isTabStop(e)&&this.doc.getLine(e.row).slice(r,i).split(" ").length-1==t},this.moveCursorLeft=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,-1))this.moveCursorTo(t.start.row,t.start.column);else if(e.column===0)e.row>0&&this.moveCursorTo(e.row-1,this.doc.getLine(e.row-1).length);else{var n=this.session.getTabSize();this.wouldMoveIntoSoftTab(e,n,-1)&&!this.session.getNavigateWithinSoftTabs()?this.moveCursorBy(0,-n):this.moveCursorBy(0,-1)}},this.moveCursorRight=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,1))this.moveCursorTo(t.end.row,t.end.column);else if(this.lead.column==this.doc.getLine(this.lead.row).length)this.lead.row<this.doc.getLength()-1&&this.moveCursorTo(this.lead.row+1,0);else{var n=this.session.getTabSize(),e=this.lead;this.wouldMoveIntoSoftTab(e,n,1)&&!this.session.getNavigateWithinSoftTabs()?this.moveCursorBy(0,n):this.moveCursorBy(0,1)}},this.moveCursorLineStart=function(){var e=this.lead.row,t=this.lead.column,n=this.session.documentToScreenRow(e,t),r=this.session.screenToDocumentPosition(n,0),i=this.session.getDisplayLine(e,null,r.row,r.column),s=i.match(/^\s*/);s[0].length!=t&&!this.session.$useEmacsStyleLineStart&&(r.column+=s[0].length),this.moveCursorToPosition(r)},this.moveCursorLineEnd=function(){var e=this.lead,t=this.session.getDocumentLastRowColumnPosition(e.row,e.column);if(this.lead.column==t.column){var n=this.session.getLine(t.row);if(t.column==n.length){var r=n.search(/\s+$/);r>0&&(t.column=r)}}this.moveCursorTo(t.row,t.column)},this.moveCursorFileEnd=function(){var e=this.doc.getLength()-1,t=this.doc.getLine(e).length;this.moveCursorTo(e,t)},this.moveCursorFileStart=function(){this.moveCursorTo(0,0)},this.moveCursorLongWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t);this.session.nonTokenRe.lastIndex=0,this.session.tokenRe.lastIndex=0;var i=this.session.getFoldAt(e,t,1);if(i){this.moveCursorTo(i.end.row,i.end.column);return}this.session.nonTokenRe.exec(r)&&(t+=this.session.nonTokenRe.lastIndex,this.session.nonTokenRe.lastIndex=0,r=n.substring(t));if(t>=n.length){this.moveCursorTo(e,n.length),this.moveCursorRight(),e<this.doc.getLength()-1&&this.moveCursorWordRight();return}this.session.tokenRe.exec(r)&&(t+=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0),this.moveCursorTo(e,t)},this.moveCursorLongWordLeft=function(){var e=this.lead.row,t=this.lead.column,n;if(n=this.session.getFoldAt(e,t,-1)){this.moveCursorTo(n.start.row,n.start.column);return}var r=this.session.getFoldStringAt(e,t,-1);r==null&&(r=this.doc.getLine(e).substring(0,t));var s=i.stringReverse(r);this.session.nonTokenRe.lastIndex=0,this.session.tokenRe.lastIndex=0,this.session.nonTokenRe.exec(s)&&(t-=this.session.nonTokenRe.lastIndex,s=s.slice(this.session.nonTokenRe.lastIndex),this.session.nonTokenRe.lastIndex=0);if(t<=0){this.moveCursorTo(e,0),this.moveCursorLeft(),e>0&&this.moveCursorWordLeft();return}this.session.tokenRe.exec(s)&&(t-=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0),this.moveCursorTo(e,t)},this.$shortWordEndIndex=function(e){var t=0,n,r=/\s/,i=this.session.tokenRe;i.lastIndex=0;if(this.session.tokenRe.exec(e))t=this.session.tokenRe.lastIndex;else{while((n=e[t])&&r.test(n))t++;if(t<1){i.lastIndex=0;while((n=e[t])&&!i.test(n)){i.lastIndex=0,t++;if(r.test(n)){if(t>2){t--;break}while((n=e[t])&&r.test(n))t++;if(t>2)break}}}}return i.lastIndex=0,t},this.moveCursorShortWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i=this.session.getFoldAt(e,t,1);if(i)return this.moveCursorTo(i.end.row,i.end.column);if(t==n.length){var s=this.doc.getLength();do e++,r=this.doc.getLine(e);while(e<s&&/^\s*$/.test(r));/^\s+/.test(r)||(r=""),t=0}var o=this.$shortWordEndIndex(r);this.moveCursorTo(e,t+o)},this.moveCursorShortWordLeft=function(){var e=this.lead.row,t=this.lead.column,n;if(n=this.session.getFoldAt(e,t,-1))return this.moveCursorTo(n.start.row,n.start.column);var r=this.session.getLine(e).substring(0,t);if(t===0){do e--,r=this.doc.getLine(e);while(e>0&&/^\s*$/.test(r));t=r.length,/\s+$/.test(r)||(r="")}var s=i.stringReverse(r),o=this.$shortWordEndIndex(s);return this.moveCursorTo(e,t-o)},this.moveCursorWordRight=function(){this.session.$selectLongWords?this.moveCursorLongWordRight():this.moveCursorShortWordRight()},this.moveCursorWordLeft=function(){this.session.$selectLongWords?this.moveCursorLongWordLeft():this.moveCursorShortWordLeft()},this.moveCursorBy=function(e,t){var n=this.session.documentToScreenPosition(this.lead.row,this.lead.column),r;t===0&&(e!==0&&(this.session.$bidiHandler.isBidiRow(n.row,this.lead.row)?(r=this.session.$bidiHandler.getPosLeft(n.column),n.column=Math.round(r/this.session.$bidiHandler.charWidths[0])):r=n.column*this.session.$bidiHandler.charWidths[0]),this.$desiredColumn?n.column=this.$desiredColumn:this.$desiredColumn=n.column);var i=this.session.screenToDocumentPosition(n.row+e,n.column,r);e!==0&&t===0&&i.row===this.lead.row&&i.column===this.lead.column&&this.session.lineWidgets&&this.session.lineWidgets[i.row]&&(i.row>0||e>0)&&i.row++,this.moveCursorTo(i.row,i.column+t,t===0)},this.moveCursorToPosition=function(e){this.moveCursorTo(e.row,e.column)},this.moveCursorTo=function(e,t,n){var r=this.session.getFoldAt(e,t,1);r&&(e=r.start.row,t=r.start.column),this.$keepDesiredColumnOnChange=!0;var i=this.session.getLine(e);/[\uDC00-\uDFFF]/.test(i.charAt(t))&&i.charAt(t-1)&&(this.lead.row==e&&this.lead.column==t+1?t-=1:t+=1),this.lead.setPosition(e,t),this.$keepDesiredColumnOnChange=!1,n||(this.$desiredColumn=null)},this.moveCursorToScreen=function(e,t,n){var r=this.session.screenToDocumentPosition(e,t);this.moveCursorTo(r.row,r.column,n)},this.detach=function(){this.lead.detach(),this.anchor.detach(),this.session=this.doc=null},this.fromOrientedRange=function(e){this.setSelectionRange(e,e.cursor==e.start),this.$desiredColumn=e.desiredColumn||this.$desiredColumn},this.toOrientedRange=function(e){var t=this.getRange();return e?(e.start.column=t.start.column,e.start.row=t.start.row,e.end.column=t.end.column,e.end.row=t.end.row):e=t,e.cursor=this.isBackwards()?e.start:e.end,e.desiredColumn=this.$desiredColumn,e},this.getRangeOfMovements=function(e){var t=this.getCursor();try{e(this);var n=this.getCursor();return o.fromPoints(t,n)}catch(r){return o.fromPoints(t,t)}finally{this.moveCursorToPosition(t)}},this.toJSON=function(){if(this.rangeCount)var e=this.ranges.map(function(e){var t=e.clone();return t.isBackwards=e.cursor==e.start,t});else{var e=this.getRange();e.isBackwards=this.isBackwards()}return e},this.fromJSON=function(e){if(e.start==undefined){if(this.rangeList){this.toSingleRange(e[0]);for(var t=e.length;t--;){var n=o.fromPoints(e[t].start,e[t].end);e[t].isBackwards&&(n.cursor=n.start),this.addRange(n,!0)}return}e=e[0]}this.rangeList&&this.toSingleRange(e),this.setSelectionRange(e,e.isBackwards)},this.isEqual=function(e){if((e.length||this.rangeCount)&&e.length!=this.rangeCount)return!1;if(!e.length||!this.ranges)return this.getRange().isEqual(e);for(var t=this.ranges.length;t--;)if(!this.ranges[t].isEqual(e[t]))return!1;return!0}}).call(u.prototype),t.Selection=u}),ace.define("ace/tokenizer",["require","exports","module","ace/config"],function(e,t,n){"use strict";var r=e("./config"),i=2e3,s=function(e){this.states=e,this.regExps={},this.matchMappings={};for(var t in this.states){var n=this.states[t],r=[],i=0,s=this.matchMappings[t]={defaultToken:"text"},o="g",u=[];for(var a=0;a<n.length;a++){var f=n[a];f.defaultToken&&(s.defaultToken=f.defaultToken),f.caseInsensitive&&(o="gi");if(f.regex==null)continue;f.regex instanceof RegExp&&(f.regex=f.regex.toString().slice(1,-1));var l=f.regex,c=(new RegExp("(?:("+l+")|(.))")).exec("a").length-2;Array.isArray(f.token)?f.token.length==1||c==1?f.token=f.token[0]:c-1!=f.token.length?(this.reportError("number of classes and regexp groups doesn't match",{rule:f,groupCount:c-1}),f.token=f.token[0]):(f.tokenArray=f.token,f.token=null,f.onMatch=this.$arrayTokens):typeof f.token=="function"&&!f.onMatch&&(c>1?f.onMatch=this.$applyToken:f.onMatch=f.token),c>1&&(/\\\d/.test(f.regex)?l=f.regex.replace(/\\([0-9]+)/g,function(e,t){return"\\"+(parseInt(t,10)+i+1)}):(c=1,l=this.removeCapturingGroups(f.regex)),!f.splitRegex&&typeof f.token!="string"&&u.push(f)),s[i]=a,i+=c,r.push(l),f.onMatch||(f.onMatch=null)}r.length||(s[0]=0,r.push("$")),u.forEach(function(e){e.splitRegex=this.createSplitterRegexp(e.regex,o)},this),this.regExps[t]=new RegExp("("+r.join(")|(")+")|($)",o)}};(function(){this.$setMaxTokenCount=function(e){i=e|0},this.$applyToken=function(e){var t=this.splitRegex.exec(e).slice(1),n=this.token.apply(this,t);if(typeof n=="string")return[{type:n,value:e}];var r=[];for(var i=0,s=n.length;i<s;i++)t[i]&&(r[r.length]={type:n[i],value:t[i]});return r},this.$arrayTokens=function(e){if(!e)return[];var t=this.splitRegex.exec(e);if(!t)return"text";var n=[],r=this.tokenArray;for(var i=0,s=r.length;i<s;i++)t[i+1]&&(n[n.length]={type:r[i],value:t[i+1]});return n},this.removeCapturingGroups=function(e){var t=e.replace(/\\.|\[(?:\\.|[^\\\]])*|\(\?[:=!]|(\()/g,function(e,t){return t?"(?:":e});return t},this.createSplitterRegexp=function(e,t){if(e.indexOf("(?=")!=-1){var n=0,r=!1,i={};e.replace(/(\\.)|(\((?:\?[=!])?)|(\))|([\[\]])/g,function(e,t,s,o,u,a){return r?r=u!="]":u?r=!0:o?(n==i.stack&&(i.end=a+1,i.stack=-1),n--):s&&(n++,s.length!=1&&(i.stack=n,i.start=a)),e}),i.end!=null&&/^\)*$/.test(e.substr(i.end))&&(e=e.substring(0,i.start)+e.substr(i.end))}return e.charAt(0)!="^"&&(e="^"+e),e.charAt(e.length-1)!="$"&&(e+="$"),new RegExp(e,(t||"").replace("g",""))},this.getLineTokens=function(e,t){if(t&&typeof t!="string"){var n=t.slice(0);t=n[0],t==="#tmp"&&(n.shift(),t=n.shift())}else var n=[];var r=t||"start",s=this.states[r];s||(r="start",s=this.states[r]);var o=this.matchMappings[r],u=this.regExps[r];u.lastIndex=0;var a,f=[],l=0,c=0,h={type:null,value:""};while(a=u.exec(e)){var p=o.defaultToken,d=null,v=a[0],m=u.lastIndex;if(m-v.length>l){var g=e.substring(l,m-v.length);h.type==p?h.value+=g:(h.type&&f.push(h),h={type:p,value:g})}for(var y=0;y<a.length-2;y++){if(a[y+1]===undefined)continue;d=s[o[y]],d.onMatch?p=d.onMatch(v,r,n,e):p=d.token,d.next&&(typeof d.next=="string"?r=d.next:r=d.next(r,n),s=this.states[r],s||(this.reportError("state doesn't exist",r),r="start",s=this.states[r]),o=this.matchMappings[r],l=m,u=this.regExps[r],u.lastIndex=m),d.consumeLineEnd&&(l=m);break}if(v)if(typeof p=="string")!!d&&d.merge===!1||h.type!==p?(h.type&&f.push(h),h={type:p,value:v}):h.value+=v;else if(p){h.type&&f.push(h),h={type:null,value:""};for(var y=0;y<p.length;y++)f.push(p[y])}if(l==e.length)break;l=m;if(c++>i){c>2*e.length&&this.reportError("infinite loop with in ace tokenizer",{startState:t,line:e});while(l<e.length)h.type&&f.push(h),h={value:e.substring(l,l+=2e3),type:"overflow"};r="start",n=[];break}}return h.type&&f.push(h),n.length>1&&n[0]!==r&&n.unshift("#tmp",r),{tokens:f,state:n.length?n:r}},this.reportError=r.reportError}).call(s.prototype),t.Tokenizer=s}),ace.define("ace/mode/text_highlight_rules",["require","exports","module","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../lib/lang"),i=function(){this.$rules={start:[{token:"empty_line",regex:"^$"},{defaultToken:"text"}]}};(function(){this.addRules=function(e,t){if(!t){for(var n in e)this.$rules[n]=e[n];return}for(var n in e){var r=e[n];for(var i=0;i<r.length;i++){var s=r[i];if(s.next||s.onMatch)typeof s.next=="string"&&s.next.indexOf(t)!==0&&(s.next=t+s.next),s.nextState&&s.nextState.indexOf(t)!==0&&(s.nextState=t+s.nextState)}this.$rules[t+n]=r}},this.getRules=function(){return this.$rules},this.embedRules=function(e,t,n,i,s){var o=typeof e=="function"?(new e).getRules():e;if(i)for(var u=0;u<i.length;u++)i[u]=t+i[u];else{i=[];for(var a in o)i.push(t+a)}this.addRules(o,t);if(n){var f=Array.prototype[s?"push":"unshift"];for(var u=0;u<i.length;u++)f.apply(this.$rules[i[u]],r.deepCopy(n))}this.$embeds||(this.$embeds=[]),this.$embeds.push(t)},this.getEmbeds=function(){return this.$embeds};var e=function(e,t){return(e!="start"||t.length)&&t.unshift(this.nextState,e),this.nextState},t=function(e,t){return t.shift(),t.shift()||"start"};this.normalizeRules=function(){function i(s){var o=r[s];o.processed=!0;for(var u=0;u<o.length;u++){var a=o[u],f=null;Array.isArray(a)&&(f=a,a={}),!a.regex&&a.start&&(a.regex=a.start,a.next||(a.next=[]),a.next.push({defaultToken:a.token},{token:a.token+".end",regex:a.end||a.start,next:"pop"}),a.token=a.token+".start",a.push=!0);var l=a.next||a.push;if(l&&Array.isArray(l)){var c=a.stateName;c||(c=a.token,typeof c!="string"&&(c=c[0]||""),r[c]&&(c+=n++)),r[c]=l,a.next=c,i(c)}else l=="pop"&&(a.next=t);a.push&&(a.nextState=a.next||a.push,a.next=e,delete a.push);if(a.rules)for(var h in a.rules)r[h]?r[h].push&&r[h].push.apply(r[h],a.rules[h]):r[h]=a.rules[h];var p=typeof a=="string"?a:a.include;p&&(Array.isArray(p)?f=p.map(function(e){return r[e]}):f=r[p]);if(f){var d=[u,1].concat(f);a.noEscape&&(d=d.filter(function(e){return!e.next})),o.splice.apply(o,d),u--}a.keywordMap&&(a.token=this.createKeywordMapper(a.keywordMap,a.defaultToken||"text",a.caseInsensitive),delete a.defaultToken)}}var n=0,r=this.$rules;Object.keys(r).forEach(i,this)},this.createKeywordMapper=function(e,t,n,r){var i=Object.create(null);return Object.keys(e).forEach(function(t){var s=e[t];n&&(s=s.toLowerCase());var o=s.split(r||"|");for(var u=o.length;u--;)i[o[u]]=t}),Object.getPrototypeOf(i)&&(i.__proto__=null),this.$keywordList=Object.keys(i),e=null,n?function(e){return i[e.toLowerCase()]||t}:function(e){return i[e]||t}},this.getKeywords=function(){return this.$keywords}}).call(i.prototype),t.TextHighlightRules=i}),ace.define("ace/mode/behaviour",["require","exports","module"],function(e,t,n){"use strict";var r=function(){this.$behaviours={}};(function(){this.add=function(e,t,n){switch(undefined){case this.$behaviours:this.$behaviours={};case this.$behaviours[e]:this.$behaviours[e]={}}this.$behaviours[e][t]=n},this.addBehaviours=function(e){for(var t in e)for(var n in e[t])this.add(t,n,e[t][n])},this.remove=function(e){this.$behaviours&&this.$behaviours[e]&&delete this.$behaviours[e]},this.inherit=function(e,t){if(typeof e=="function")var n=(new e).getBehaviours(t);else var n=e.getBehaviours(t);this.addBehaviours(n)},this.getBehaviours=function(e){if(!e)return this.$behaviours;var t={};for(var n=0;n<e.length;n++)this.$behaviours[e[n]]&&(t[e[n]]=this.$behaviours[e[n]]);return t}}).call(r.prototype),t.Behaviour=r}),ace.define("ace/token_iterator",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("./range").Range,i=function(e,t,n){this.$session=e,this.$row=t,this.$rowTokens=e.getTokens(t);var r=e.getTokenAt(t,n);this.$tokenIndex=r?r.index:-1};(function(){this.stepBackward=function(){this.$tokenIndex-=1;while(this.$tokenIndex<0){this.$row-=1;if(this.$row<0)return this.$row=0,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=this.$rowTokens.length-1}return this.$rowTokens[this.$tokenIndex]},this.stepForward=function(){this.$tokenIndex+=1;var e;while(this.$tokenIndex>=this.$rowTokens.length){this.$row+=1,e||(e=this.$session.getLength());if(this.$row>=e)return this.$row=e-1,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=0}return this.$rowTokens[this.$tokenIndex]},this.getCurrentToken=function(){return this.$rowTokens[this.$tokenIndex]},this.getCurrentTokenRow=function(){return this.$row},this.getCurrentTokenColumn=function(){var e=this.$rowTokens,t=this.$tokenIndex,n=e[t].start;if(n!==undefined)return n;n=0;while(t>0)t-=1,n+=e[t].value.length;return n},this.getCurrentTokenPosition=function(){return{row:this.$row,column:this.getCurrentTokenColumn()}},this.getCurrentTokenRange=function(){var e=this.$rowTokens[this.$tokenIndex],t=this.getCurrentTokenColumn();return new r(this.$row,t,this.$row,t+e.value.length)}}).call(i.prototype),t.TokenIterator=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c={'"':'"',"'":"'"},h=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},p=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},d=function(e){this.add("braces","insertion",function(t,n,r,i,s){var u=r.getCursorPosition(),a=i.doc.getLine(u.row);if(s=="{"){h(r);var l=r.getSelectionRange(),c=i.doc.getTextRange(l);if(c!==""&&c!=="{"&&r.getWrapBehavioursEnabled())return p(l,c,"{","}");if(d.isSaneInsertion(r,i))return/[\]\}\)]/.test(a[u.column])||r.inMultiSelectMode||e&&e.braces?(d.recordAutoInsert(r,i,"}"),{text:"{}",selection:[1,1]}):(d.recordMaybeInsert(r,i,"{"),{text:"{",selection:[1,1]})}else if(s=="}"){h(r);var v=a.substring(u.column,u.column+1);if(v=="}"){var m=i.$findOpeningBracket("}",{column:u.column+1,row:u.row});if(m!==null&&d.isAutoInsertedClosing(u,a,s))return d.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(s=="\n"||s=="\r\n"){h(r);var g="";d.isMaybeInsertedClosing(u,a)&&(g=o.stringRepeat("}",f.maybeInsertedBrackets),d.clearMaybeInsertedClosing());var v=a.substring(u.column,u.column+1);if(v==="}"){var y=i.findMatchingBracket({row:u.row,column:u.column+1},"}");if(!y)return null;var b=this.$getIndent(i.getLine(y.row))}else{if(!g){d.clearMaybeInsertedClosing();return}var b=this.$getIndent(a)}var w=b+i.getTabString();return{text:"\n"+w+"\n"+b+g,selection:[1,w.length,1,w.length]}}d.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){h(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){h(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return p(s,o,"(",")");if(d.isSaneInsertion(n,r))return d.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){h(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&d.isAutoInsertedClosing(u,a,i))return d.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){h(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){h(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return p(s,o,"[","]");if(d.isSaneInsertion(n,r))return d.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){h(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&d.isAutoInsertedClosing(u,a,i))return d.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){h(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){var s=r.$mode.$quotes||c;if(i.length==1&&s[i]){if(this.lineCommentStart&&this.lineCommentStart.indexOf(i)!=-1)return;h(n);var o=i,u=n.getSelectionRange(),a=r.doc.getTextRange(u);if(a!==""&&(a.length!=1||!s[a])&&n.getWrapBehavioursEnabled())return p(u,a,o,o);if(!a){var f=n.getCursorPosition(),l=r.doc.getLine(f.row),d=l.substring(f.column-1,f.column),v=l.substring(f.column,f.column+1),m=r.getTokenAt(f.row,f.column),g=r.getTokenAt(f.row,f.column+1);if(d=="\\"&&m&&/escape/.test(m.type))return null;var y=m&&/string|escape/.test(m.type),b=!g||/string|escape/.test(g.type),w;if(v==o)w=y!==b,w&&/string\.end/.test(g.type)&&(w=!1);else{if(y&&!b)return null;if(y&&b)return null;var E=r.$mode.tokenRe;E.lastIndex=0;var S=E.test(d);E.lastIndex=0;var x=E.test(d);if(S||x)return null;if(v&&!/[\s;,.})\]\\]/.test(v))return null;w=!0}return{text:w?o+o:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.$mode.$quotes||c,o=r.doc.getTextRange(i);if(!i.isMultiLine()&&s.hasOwnProperty(o)){h(n);var u=r.doc.getLine(i.start.row),a=u.substring(i.start.column+1,i.start.column+2);if(a==o)return i.end.column++,i}})};d.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},d.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},d.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},d.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},d.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},d.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},d.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},d.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(d,i),t.CstyleBehaviour=d}),ace.define("ace/unicode",["require","exports","module"],function(e,t,n){"use strict";var r=[48,9,8,25,5,0,2,25,48,0,11,0,5,0,6,22,2,30,2,457,5,11,15,4,8,0,2,0,18,116,2,1,3,3,9,0,2,2,2,0,2,19,2,82,2,138,2,4,3,155,12,37,3,0,8,38,10,44,2,0,2,1,2,1,2,0,9,26,6,2,30,10,7,61,2,9,5,101,2,7,3,9,2,18,3,0,17,58,3,100,15,53,5,0,6,45,211,57,3,18,2,5,3,11,3,9,2,1,7,6,2,2,2,7,3,1,3,21,2,6,2,0,4,3,3,8,3,1,3,3,9,0,5,1,2,4,3,11,16,2,2,5,5,1,3,21,2,6,2,1,2,1,2,1,3,0,2,4,5,1,3,2,4,0,8,3,2,0,8,15,12,2,2,8,2,2,2,21,2,6,2,1,2,4,3,9,2,2,2,2,3,0,16,3,3,9,18,2,2,7,3,1,3,21,2,6,2,1,2,4,3,8,3,1,3,2,9,1,5,1,2,4,3,9,2,0,17,1,2,5,4,2,2,3,4,1,2,0,2,1,4,1,4,2,4,11,5,4,4,2,2,3,3,0,7,0,15,9,18,2,2,7,2,2,2,22,2,9,2,4,4,7,2,2,2,3,8,1,2,1,7,3,3,9,19,1,2,7,2,2,2,22,2,9,2,4,3,8,2,2,2,3,8,1,8,0,2,3,3,9,19,1,2,7,2,2,2,22,2,15,4,7,2,2,2,3,10,0,9,3,3,9,11,5,3,1,2,17,4,23,2,8,2,0,3,6,4,0,5,5,2,0,2,7,19,1,14,57,6,14,2,9,40,1,2,0,3,1,2,0,3,0,7,3,2,6,2,2,2,0,2,0,3,1,2,12,2,2,3,4,2,0,2,5,3,9,3,1,35,0,24,1,7,9,12,0,2,0,2,0,5,9,2,35,5,19,2,5,5,7,2,35,10,0,58,73,7,77,3,37,11,42,2,0,4,328,2,3,3,6,2,0,2,3,3,40,2,3,3,32,2,3,3,6,2,0,2,3,3,14,2,56,2,3,3,66,5,0,33,15,17,84,13,619,3,16,2,25,6,74,22,12,2,6,12,20,12,19,13,12,2,2,2,1,13,51,3,29,4,0,5,1,3,9,34,2,3,9,7,87,9,42,6,69,11,28,4,11,5,11,11,39,3,4,12,43,5,25,7,10,38,27,5,62,2,28,3,10,7,9,14,0,89,75,5,9,18,8,13,42,4,11,71,55,9,9,4,48,83,2,2,30,14,230,23,280,3,5,3,37,3,5,3,7,2,0,2,0,2,0,2,30,3,52,2,6,2,0,4,2,2,6,4,3,3,5,5,12,6,2,2,6,67,1,20,0,29,0,14,0,17,4,60,12,5,0,4,11,18,0,5,0,3,9,2,0,4,4,7,0,2,0,2,0,2,3,2,10,3,3,6,4,5,0,53,1,2684,46,2,46,2,132,7,6,15,37,11,53,10,0,17,22,10,6,2,6,2,6,2,6,2,6,2,6,2,6,2,6,2,31,48,0,470,1,36,5,2,4,6,1,5,85,3,1,3,2,2,89,2,3,6,40,4,93,18,23,57,15,513,6581,75,20939,53,1164,68,45,3,268,4,27,21,31,3,13,13,1,2,24,9,69,11,1,38,8,3,102,3,1,111,44,25,51,13,68,12,9,7,23,4,0,5,45,3,35,13,28,4,64,15,10,39,54,10,13,3,9,7,22,4,1,5,66,25,2,227,42,2,1,3,9,7,11171,13,22,5,48,8453,301,3,61,3,105,39,6,13,4,6,11,2,12,2,4,2,0,2,1,2,1,2,107,34,362,19,63,3,53,41,11,5,15,17,6,13,1,25,2,33,4,2,134,20,9,8,25,5,0,2,25,12,88,4,5,3,5,3,5,3,2],i=0,s=[];for(var o=0;o<r.length;o+=2)s.push(i+=r[o]),r[o+1]&&s.push(45,i+=r[o+1]);t.wordChars=String.fromCharCode.apply(null,s)}),ace.define("ace/mode/text",["require","exports","module","ace/config","ace/tokenizer","ace/mode/text_highlight_rules","ace/mode/behaviour/cstyle","ace/unicode","ace/lib/lang","ace/token_iterator","ace/range"],function(e,t,n){"use strict";var r=e("../config"),i=e("../tokenizer").Tokenizer,s=e("./text_highlight_rules").TextHighlightRules,o=e("./behaviour/cstyle").CstyleBehaviour,u=e("../unicode"),a=e("../lib/lang"),f=e("../token_iterator").TokenIterator,l=e("../range").Range,c=function(){this.HighlightRules=s};(function(){this.$defaultBehaviour=new o,this.tokenRe=new RegExp("^["+u.wordChars+"\\$_]+","g"),this.nonTokenRe=new RegExp("^(?:[^"+u.wordChars+"\\$_]|\\s])+","g"),this.getTokenizer=function(){return this.$tokenizer||(this.$highlightRules=this.$highlightRules||new this.HighlightRules(this.$highlightRuleConfig),this.$tokenizer=new i(this.$highlightRules.getRules())),this.$tokenizer},this.lineCommentStart="",this.blockComment="",this.toggleCommentLines=function(e,t,n,r){function w(e){for(var t=n;t<=r;t++)e(i.getLine(t),t)}var i=t.doc,s=!0,o=!0,u=Infinity,f=t.getTabSize(),l=!1;if(!this.lineCommentStart){if(!this.blockComment)return!1;var c=this.blockComment.start,h=this.blockComment.end,p=new RegExp("^(\\s*)(?:"+a.escapeRegExp(c)+")"),d=new RegExp("(?:"+a.escapeRegExp(h)+")\\s*$"),v=function(e,t){if(g(e,t))return;if(!s||/\S/.test(e))i.insertInLine({row:t,column:e.length},h),i.insertInLine({row:t,column:u},c)},m=function(e,t){var n;(n=e.match(d))&&i.removeInLine(t,e.length-n[0].length,e.length),(n=e.match(p))&&i.removeInLine(t,n[1].length,n[0].length)},g=function(e,n){if(p.test(e))return!0;var r=t.getTokens(n);for(var i=0;i<r.length;i++)if(r[i].type==="comment")return!0}}else{if(Array.isArray(this.lineCommentStart))var p=this.lineCommentStart.map(a.escapeRegExp).join("|"),c=this.lineCommentStart[0];else var p=a.escapeRegExp(this.lineCommentStart),c=this.lineCommentStart;p=new RegExp("^(\\s*)(?:"+p+") ?"),l=t.getUseSoftTabs();var m=function(e,t){var n=e.match(p);if(!n)return;var r=n[1].length,s=n[0].length;!b(e,r,s)&&n[0][s-1]==" "&&s--,i.removeInLine(t,r,s)},y=c+" ",v=function(e,t){if(!s||/\S/.test(e))b(e,u,u)?i.insertInLine({row:t,column:u},y):i.insertInLine({row:t,column:u},c)},g=function(e,t){return p.test(e)},b=function(e,t,n){var r=0;while(t--&&e.charAt(t)==" ")r++;if(r%f!=0)return!1;var r=0;while(e.charAt(n++)==" ")r++;return f>2?r%f!=f-1:r%f==0}}var E=Infinity;w(function(e,t){var n=e.search(/\S/);n!==-1?(n<u&&(u=n),o&&!g(e,t)&&(o=!1)):E>e.length&&(E=e.length)}),u==Infinity&&(u=E,s=!1,o=!1),l&&u%f!=0&&(u=Math.floor(u/f)*f),w(o?m:v)},this.toggleBlockComment=function(e,t,n,r){var i=this.blockComment;if(!i)return;!i.start&&i[0]&&(i=i[0]);var s=new f(t,r.row,r.column),o=s.getCurrentToken(),u=t.selection,a=t.selection.toOrientedRange(),c,h;if(o&&/comment/.test(o.type)){var p,d;while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.start);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;p=new l(m,g,m,g+i.start.length);break}o=s.stepBackward()}var s=new f(t,r.row,r.column),o=s.getCurrentToken();while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.end);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;d=new l(m,g,m,g+i.end.length);break}o=s.stepForward()}d&&t.remove(d),p&&(t.remove(p),c=p.start.row,h=-i.start.length)}else h=i.start.length,c=n.start.row,t.insert(n.end,i.end),t.insert(n.start,i.start);a.start.row==c&&(a.start.column+=h),a.end.row==c&&(a.end.column+=h),t.selection.fromOrientedRange(a)},this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.autoOutdent=function(e,t,n){},this.$getIndent=function(e){return e.match(/^\s*/)[0]},this.createWorker=function(e){return null},this.createModeDelegates=function(e){this.$embeds=[],this.$modes={};for(var t in e)if(e[t]){var n=e[t],i=n.prototype.$id,s=r.$modes[i];s||(r.$modes[i]=s=new n),r.$modes[t]||(r.$modes[t]=s),this.$embeds.push(t),this.$modes[t]=s}var o=["toggleBlockComment","toggleCommentLines","getNextLineIndent","checkOutdent","autoOutdent","transformAction","getCompletions"];for(var t=0;t<o.length;t++)(function(e){var n=o[t],r=e[n];e[o[t]]=function(){return this.$delegator(n,arguments,r)}})(this)},this.$delegator=function(e,t,n){var r=t[0]||"start";if(typeof r!="string"){if(Array.isArray(r[2])){var i=r[2][r[2].length-1],s=this.$modes[i];if(s)return s[e].apply(s,[r[1]].concat([].slice.call(t,1)))}r=r[0]||"start"}for(var o=0;o<this.$embeds.length;o++){if(!this.$modes[this.$embeds[o]])continue;var u=r.split(this.$embeds[o]);if(!u[0]&&u[1]){t[0]=u[1];var s=this.$modes[this.$embeds[o]];return s[e].apply(s,t)}}var a=n.apply(this,t);return n?a:undefined},this.transformAction=function(e,t,n,r,i){if(this.$behaviour){var s=this.$behaviour.getBehaviours();for(var o in s)if(s[o][t]){var u=s[o][t].apply(this,arguments);if(u)return u}}},this.getKeywords=function(e){if(!this.completionKeywords){var t=this.$tokenizer.rules,n=[];for(var r in t){var i=t[r];for(var s=0,o=i.length;s<o;s++)if(typeof i[s].token=="string")/keyword|support|storage/.test(i[s].token)&&n.push(i[s].regex);else if(typeof i[s].token=="object")for(var u=0,a=i[s].token.length;u<a;u++)if(/keyword|support|storage/.test(i[s].token[u])){var r=i[s].regex.match(/\(.+?\)/g)[u];n.push(r.substr(1,r.length-2))}}this.completionKeywords=n}return e?n.concat(this.$keywordList||[]):this.$keywordList},this.$createKeywordList=function(){return this.$highlightRules||this.getTokenizer(),this.$keywordList=this.$highlightRules.$keywordList||[]},this.getCompletions=function(e,t,n,r){var i=this.$keywordList||this.$createKeywordList();return i.map(function(e){return{name:e,value:e,score:0,meta:"keyword"}})},this.$id="ace/mode/text"}).call(c.prototype),t.Mode=c}),ace.define("ace/apply_delta",["require","exports","module"],function(e,t,n){"use strict";function r(e,t){throw console.log("Invalid Delta:",e),"Invalid Delta: "+t}function i(e,t){return t.row>=0&&t.row<e.length&&t.column>=0&&t.column<=e[t.row].length}function s(e,t){t.action!="insert"&&t.action!="remove"&&r(t,"delta.action must be 'insert' or 'remove'"),t.lines instanceof Array||r(t,"delta.lines must be an Array"),(!t.start||!t.end)&&r(t,"delta.start/end must be an present");var n=t.start;i(e,t.start)||r(t,"delta.start must be contained in document");var s=t.end;t.action=="remove"&&!i(e,s)&&r(t,"delta.end must contained in document for 'remove' actions");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,"delta.range must match delta lines")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||"";switch(t.action){case"insert":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case"remove":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){function e(e,t,n){var r=n?e.column<=t.column:e.column<t.column;return e.row<t.row||e.row==t.row&&r}function t(t,n,r){var i=t.action=="insert",s=(i?1:-1)*(t.end.row-t.start.row),o=(i?1:-1)*(t.end.column-t.start.column),u=t.start,a=i?u:t.end;return e(n,u,r)?{row:n.row,column:n.column}:e(a,n,!r)?{row:n.row+s,column:n.column+(n.row==a.row?o:0)}:{row:u.row,column:u.column}}r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){if(e.start.row==e.end.row&&e.start.row!=this.row)return;if(e.start.row>this.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/apply_delta","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./apply_delta").applyDelta,s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=e("./anchor").Anchor,a=function(e){this.$lines=[""],e.length===0?this.$lines=[""]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."),this.insertMergedLines(e,["",""])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:"insert",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e<this.getLength()?(t=t.concat([""]),n=0):(t=[""].concat(t),e--,n=this.$lines[e].length),this.insertMergedLines({row:e,column:n},t)},this.insertMergedLines=function(e,t){var n=this.clippedPos(e.row,e.column),r={row:n.row+t.length-1,column:(t.length==1?n.column:0)+t[t.length-1].length};return this.applyDelta({start:n,end:r,action:"insert",lines:t}),this.clonePos(r)},this.remove=function(e){var t=this.clippedPos(e.start.row,e.start.column),n=this.clippedPos(e.end.row,e.end.column);return this.applyDelta({start:t,end:n,action:"remove",lines:this.getLinesForRange({start:t,end:n})}),this.clonePos(t)},this.removeInLine=function(e,t,n){var r=this.clippedPos(e,t),i=this.clippedPos(e,n);return this.applyDelta({start:r,end:i,action:"remove",lines:this.getLinesForRange({start:r,end:i})},!0),this.clonePos(r)},this.removeFullLines=function(e,t){e=Math.min(Math.max(0,e),this.getLength()-1),t=Math.min(Math.max(0,t),this.getLength()-1);var n=t==this.getLength()-1&&e>0,r=t<this.getLength()-1,i=n?e-1:e,s=n?this.getLine(i).length:0,u=r?t+1:t,a=r?0:this.getLine(u).length,f=new o(i,s,u,a),l=this.$lines.slice(e,t+1);return this.applyDelta({start:f.start,end:f.end,action:"remove",lines:this.getLinesForRange(f)}),l},this.removeNewLine=function(e){e<this.getLength()-1&&e>=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++)this.applyDelta(e[t])},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action=="insert";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4?this.$splitAndapplyLargeDelta(e,2e4):(i(this.$lines,e,t),this._signal("change",e))},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length-t+1,i=e.start.row,s=e.start.column;for(var o=0,u=0;o<r;o=u){u+=t-1;var a=n.slice(o,u);a.push(""),this.applyDelta({start:this.pos(i+o,s),end:this.pos(i+u,s=0),action:e.action,lines:a},!0)}e.lines=n.slice(o),e.start.row=i+o,e.start.column=s,this.applyDelta(e,!0)},this.revertDelta=function(e){this.applyDelta({start:this.clonePos(e.start),end:this.clonePos(e.end),action:e.action=="insert"?"remove":"insert",lines:e.lines.slice()})},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:e+n[s-1].length+r}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(a.prototype),t.Document=a}),ace.define("ace/background_tokenizer",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=function(e,t){this.running=!1,this.lines=[],this.states=[],this.currentLine=0,this.tokenizer=e;var n=this;this.$worker=function(){if(!n.running)return;var e=new Date,t=n.currentLine,r=-1,i=n.doc,s=t;while(n.lines[t])t++;var o=i.getLength(),u=0;n.running=!1;while(t<o){n.$tokenizeRow(t),r=t;do t++;while(n.lines[t]);u++;if(u%5===0&&new Date-e>20){n.running=setTimeout(n.$worker,20);break}}n.currentLine=t,r==-1&&(r=t),s<=r&&n.fireUpdateEvent(s,r)}};(function(){r.implement(this,i),this.setTokenizer=function(e){this.tokenizer=e,this.lines=[],this.states=[],this.start(0)},this.setDocument=function(e){this.doc=e,this.lines=[],this.states=[],this.stop()},this.fireUpdateEvent=function(e,t){var n={first:e,last:t};this._signal("update",{data:n})},this.start=function(e){this.currentLine=Math.min(e||0,this.currentLine,this.doc.getLength()),this.lines.splice(this.currentLine,this.lines.length),this.states.splice(this.currentLine,this.states.length),this.stop(),this.running=setTimeout(this.$worker,700)},this.scheduleStart=function(){this.running||(this.running=setTimeout(this.$worker,700))},this.$updateOnChange=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.lines[t]=null;else if(e.action=="remove")this.lines.splice(t,n+1,null),this.states.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.lines.splice.apply(this.lines,r),this.states.splice.apply(this.states,r)}this.currentLine=Math.min(t,this.currentLine,this.doc.getLength()),this.stop()},this.stop=function(){this.running&&clearTimeout(this.running),this.running=!1},this.getTokens=function(e){return this.lines[e]||this.$tokenizeRow(e)},this.getState=function(e){return this.currentLine==e&&this.$tokenizeRow(e),this.states[e]||"start"},this.$tokenizeRow=function(e){var t=this.doc.getLine(e),n=this.states[e-1],r=this.tokenizer.getLineTokens(t,n,e);return this.states[e]+""!=r.state+""?(this.states[e]=r.state,this.lines[e+1]=null,this.currentLine>e+1&&(this.currentLine=e+1)):this.currentLine==e&&(this.currentLine=e+1),this.lines[e]=r.tokens}}).call(s.prototype),t.BackgroundTokenizer=s}),ace.define("ace/search_highlight",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"],function(e,t,n){"use strict";var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./range").Range,o=function(e,t,n){this.setRegexp(e),this.clazz=t,this.type=n||"text"};(function(){this.MAX_RANGES=500,this.setRegexp=function(e){if(this.regExp+""==e+"")return;this.regExp=e,this.cache=[]},this.update=function(e,t,n,i){if(!this.regExp)return;var o=i.firstRow,u=i.lastRow;for(var a=o;a<=u;a++){var f=this.cache[a];f==null&&(f=r.getMatchOffsets(n.getLine(a),this.regExp),f.length>this.MAX_RANGES&&(f=f.slice(0,this.MAX_RANGES)),f=f.map(function(e){return new s(a,e.offset,a,e.offset+e.length)}),this.cache[a]=f.length?f:"");for(var l=f.length;l--;)t.drawSingleLineMarker(e,f[l].toScreenRange(n),this.clazz,i)}}}).call(o.prototype),t.SearchHighlight=o}),ace.define("ace/edit_session/fold_line",["require","exports","module","ace/range"],function(e,t,n){"use strict";function i(e,t){this.foldData=e,Array.isArray(t)?this.folds=t:t=this.folds=[t];var n=t[t.length-1];this.range=new r(t[0].start.row,t[0].start.column,n.end.row,n.end.column),this.start=this.range.start,this.end=this.range.end,this.folds.forEach(function(e){e.setFoldLine(this)},this)}var r=e("../range").Range;(function(){this.shiftRow=function(e){this.start.row+=e,this.end.row+=e,this.folds.forEach(function(t){t.start.row+=e,t.end.row+=e})},this.addFold=function(e){if(e.sameRow){if(e.start.row<this.startRow||e.endRow>this.endRow)throw new Error("Can't add a fold to this FoldLine as it has no connection");this.folds.push(e),this.folds.sort(function(e,t){return-e.range.compareEnd(t.start.row,t.start.column)}),this.range.compareEnd(e.start.row,e.start.column)>0?(this.end.row=e.end.row,this.end.column=e.end.column):this.range.compareStart(e.end.row,e.end.column)<0&&(this.start.row=e.start.row,this.start.column=e.start.column)}else if(e.start.row==this.end.row)this.folds.push(e),this.end.row=e.end.row,this.end.column=e.end.column;else{if(e.end.row!=this.start.row)throw new Error("Trying to add fold to FoldRow that doesn't have a matching row");this.folds.unshift(e),this.start.row=e.start.row,this.start.column=e.start.column}e.foldLine=this},this.containsRow=function(e){return e>=this.start.row&&e<=this.end.row},this.walk=function(e,t,n){var r=0,i=this.folds,s,o,u,a=!0;t==null&&(t=this.end.row,n=this.end.column);for(var f=0;f<i.length;f++){s=i[f],o=s.range.compareStart(t,n);if(o==-1){e(null,t,n,r,a);return}u=e(null,s.start.row,s.start.column,r,a),u=!u&&e(s.placeholder,s.start.row,s.start.column,r);if(u||o===0)return;a=!s.sameRow,r=s.end.column}e(null,t,n,r,a)},this.getNextFoldTo=function(e,t){var n,r;for(var i=0;i<this.folds.length;i++){n=this.folds[i],r=n.range.compareEnd(e,t);if(r==-1)return{fold:n,kind:"after"};if(r===0)return{fold:n,kind:"inside"}}return null},this.addRemoveChars=function(e,t,n){var r=this.getNextFoldTo(e,t),i,s;if(r){i=r.fold;if(r.kind=="inside"&&i.start.column!=t&&i.start.row!=e)window.console&&window.console.log(e,t,i);else if(i.start.row==e){s=this.folds;var o=s.indexOf(i);o===0&&(this.start.column+=n);for(o;o<s.length;o++){i=s[o],i.start.column+=n;if(!i.sameRow)return;i.end.column+=n}this.end.column+=n}}},this.split=function(e,t){var n=this.getNextFoldTo(e,t);if(!n||n.kind=="inside")return null;var r=n.fold,s=this.folds,o=this.foldData,u=s.indexOf(r),a=s[u-1];this.end.row=a.end.row,this.end.column=a.end.column,s=s.splice(u,s.length-u);var f=new i(o,s);return o.splice(o.indexOf(this)+1,0,f),f},this.merge=function(e){var t=e.folds;for(var n=0;n<t.length;n++)this.addFold(t[n]);var r=this.foldData;r.splice(r.indexOf(e),1)},this.toString=function(){var e=[this.range.toString()+": ["];return this.folds.forEach(function(t){e.push(" "+t.toString())}),e.push("]"),e.join("\n")},this.idxToPosition=function(e){var t=0;for(var n=0;n<this.folds.length;n++){var r=this.folds[n];e-=r.start.column-t;if(e<0)return{row:r.start.row,column:r.start.column+e};e-=r.placeholder.length;if(e<0)return r.start;t=r.end.column}return{row:this.end.row,column:this.end.column+e}}}).call(i.prototype),t.FoldLine=i}),ace.define("ace/range_list",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("./range").Range,i=r.comparePoints,s=function(){this.ranges=[]};(function(){this.comparePoints=i,this.pointIndex=function(e,t,n){var r=this.ranges;for(var s=n||0;s<r.length;s++){var o=r[s],u=i(e,o.end);if(u>0)continue;var a=i(e,o.start);return u===0?t&&a!==0?-s-2:s:a>0||a===0&&!t?s:-s-1}return-s-1},this.add=function(e){var t=!e.isEmpty(),n=this.pointIndex(e.start,t);n<0&&(n=-n-1);var r=this.pointIndex(e.end,t,n);return r<0?r=-r-1:r++,this.ranges.splice(n,r-n,e)},this.addList=function(e){var t=[];for(var n=e.length;n--;)t.push.apply(t,this.add(e[n]));return t},this.substractPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges.splice(t,1)},this.merge=function(){var e=[],t=this.ranges;t=t.sort(function(e,t){return i(e.start,t.start)});var n=t[0],r;for(var s=1;s<t.length;s++){r=n,n=t[s];var o=i(r.end,n.start);if(o<0)continue;if(o==0&&!r.isEmpty()&&!n.isEmpty())continue;i(r.end,n.end)<0&&(r.end.row=n.end.row,r.end.column=n.end.column),t.splice(s,1),e.push(n),n=r,s--}return this.ranges=t,e},this.contains=function(e,t){return this.pointIndex({row:e,column:t})>=0},this.containsPoint=function(e){return this.pointIndex(e)>=0},this.rangeAtPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges[t]},this.clipRows=function(e,t){var n=this.ranges;if(n[0].start.row>t||n[n.length-1].start.row<e)return[];var r=this.pointIndex({row:e,column:0});r<0&&(r=-r-1);var i=this.pointIndex({row:t,column:0},r);i<0&&(i=-i-1);var s=[];for(var o=r;o<i;o++)s.push(n[o]);return s},this.removeAll=function(){return this.ranges.splice(0,this.ranges.length)},this.attach=function(e){this.session&&this.detach(),this.session=e,this.onChange=this.$onChange.bind(this),this.session.on("change",this.onChange)},this.detach=function(){if(!this.session)return;this.session.removeListener("change",this.onChange),this.session=null},this.$onChange=function(e){var t=e.start,n=e.end,r=t.row,i=n.row,s=this.ranges;for(var o=0,u=s.length;o<u;o++){var a=s[o];if(a.end.row>=r)break}if(e.action=="insert"){var f=i-r,l=-t.column+n.column;for(;o<u;o++){var a=s[o];if(a.start.row>r)break;a.start.row==r&&a.start.column>=t.column&&(a.start.column!=t.column||!this.$insertRight)&&(a.start.column+=l,a.start.row+=f);if(a.end.row==r&&a.end.column>=t.column){if(a.end.column==t.column&&this.$insertRight)continue;a.end.column==t.column&&l>0&&o<u-1&&a.end.column>a.start.column&&a.end.column==s[o+1].start.column&&(a.end.column-=l),a.end.column+=l,a.end.row+=f}}}else{var f=r-i,l=t.column-n.column;for(;o<u;o++){var a=s[o];if(a.start.row>i)break;if(a.end.row<i&&(r<a.end.row||r==a.end.row&&t.column<a.end.column))a.end.row=r,a.end.column=t.column;else if(a.end.row==i)if(a.end.column<=n.column){if(f||a.end.column>t.column)a.end.column=t.column,a.end.row=t.row}else a.end.column+=l,a.end.row+=f;else a.end.row>i&&(a.end.row+=f);if(a.start.row<i&&(r<a.start.row||r==a.start.row&&t.column<a.start.column))a.start.row=r,a.start.column=t.column;else if(a.start.row==i)if(a.start.column<=n.column){if(f||a.start.column>t.column)a.start.column=t.column,a.start.row=t.row}else a.start.column+=l,a.start.row+=f;else a.start.row>i&&(a.start.row+=f)}}if(f!=0&&o<u)for(;o<u;o++){var a=s[o];a.start.row+=f,a.end.row+=f}}}).call(s.prototype),t.RangeList=s}),ace.define("ace/edit_session/fold",["require","exports","module","ace/range","ace/range_list","ace/lib/oop"],function(e,t,n){"use strict";function u(e,t){e.row-=t.row,e.row==0&&(e.column-=t.column)}function a(e,t){u(e.start,t),u(e.end,t)}function f(e,t){e.row==0&&(e.column+=t.column),e.row+=t.row}function l(e,t){f(e.start,t),f(e.end,t)}var r=e("../range").Range,i=e("../range_list").RangeList,s=e("../lib/oop"),o=t.Fold=function(e,t){this.foldLine=null,this.placeholder=t,this.range=e,this.start=e.start,this.end=e.end,this.sameRow=e.start.row==e.end.row,this.subFolds=this.ranges=[]};s.inherits(o,i),function(){this.toString=function(){return'"'+this.placeholder+'" '+this.range.toString()},this.setFoldLine=function(e){this.foldLine=e,this.subFolds.forEach(function(t){t.setFoldLine(e)})},this.clone=function(){var e=this.range.clone(),t=new o(e,this.placeholder);return this.subFolds.forEach(function(e){t.subFolds.push(e.clone())}),t.collapseChildren=this.collapseChildren,t},this.addSubFold=function(e){if(this.range.isEqual(e))return;if(!this.range.containsRange(e))throw new Error("A fold can't intersect already existing fold"+e.range+this.range);a(e,this.start);var t=e.start.row,n=e.start.column;for(var r=0,i=-1;r<this.subFolds.length;r++){i=this.subFolds[r].range.compare(t,n);if(i!=1)break}var s=this.subFolds[r];if(i==0)return s.addSubFold(e);var t=e.range.end.row,n=e.range.end.column;for(var o=r,i=-1;o<this.subFolds.length;o++){i=this.subFolds[o].range.compare(t,n);if(i!=1)break}var u=this.subFolds[o];if(i==0)throw new Error("A fold can't intersect already existing fold"+e.range+this.range);var f=this.subFolds.splice(r,o-r,e);return e.setFoldLine(this.foldLine),e},this.restoreRange=function(e){return l(e,this.start)}}.call(o.prototype)}),ace.define("ace/edit_session/folding",["require","exports","module","ace/range","ace/edit_session/fold_line","ace/edit_session/fold","ace/token_iterator"],function(e,t,n){"use strict";function u(){this.getFoldAt=function(e,t,n){var r=this.getFoldLine(e);if(!r)return null;var i=r.folds;for(var s=0;s<i.length;s++){var o=i[s];if(o.range.contains(e,t)){if(n==1&&o.range.isEnd(e,t))continue;if(n==-1&&o.range.isStart(e,t))continue;return o}}},this.getFoldsInRange=function(e){var t=e.start,n=e.end,r=this.$foldData,i=[];t.column+=1,n.column-=1;for(var s=0;s<r.length;s++){var o=r[s].range.compareRange(e);if(o==2)continue;if(o==-2)break;var u=r[s].folds;for(var a=0;a<u.length;a++){var f=u[a];o=f.range.compareRange(e);if(o==-2)break;if(o==2)continue;if(o==42)break;i.push(f)}}return t.column-=1,n.column+=1,i},this.getFoldsInRangeList=function(e){if(Array.isArray(e)){var t=[];e.forEach(function(e){t=t.concat(this.getFoldsInRange(e))},this)}else var t=this.getFoldsInRange(e);return t},this.getAllFolds=function(){var e=[],t=this.$foldData;for(var n=0;n<t.length;n++)for(var r=0;r<t[n].folds.length;r++)e.push(t[n].folds[r]);return e},this.getFoldStringAt=function(e,t,n,r){r=r||this.getFoldLine(e);if(!r)return null;var i={end:{column:0}},s,o;for(var u=0;u<r.folds.length;u++){o=r.folds[u];var a=o.range.compareEnd(e,t);if(a==-1){s=this.getLine(o.start.row).substring(i.end.column,o.start.column);break}if(a===0)return null;i=o}return s||(s=this.getLine(o.start.row).substring(i.end.column)),n==-1?s.substring(0,t-i.end.column):n==1?s.substring(t-i.end.column):s},this.getFoldLine=function(e,t){var n=this.$foldData,r=0;t&&(r=n.indexOf(t)),r==-1&&(r=0);for(r;r<n.length;r++){var i=n[r];if(i.start.row<=e&&i.end.row>=e)return i;if(i.end.row>e)return null}return null},this.getNextFoldLine=function(e,t){var n=this.$foldData,r=0;t&&(r=n.indexOf(t)),r==-1&&(r=0);for(r;r<n.length;r++){var i=n[r];if(i.end.row>=e)return i}return null},this.getFoldedRowCount=function(e,t){var n=this.$foldData,r=t-e+1;for(var i=0;i<n.length;i++){var s=n[i],o=s.end.row,u=s.start.row;if(o>=t){u<t&&(u>=e?r-=t-u:r=0);break}o>=e&&(u>=e?r-=o-u:r-=o-e+1)}return r},this.$addFoldLine=function(e){return this.$foldData.push(e),this.$foldData.sort(function(e,t){return e.start.row-t.start.row}),e},this.addFold=function(e,t){var n=this.$foldData,r=!1,o;e instanceof s?o=e:(o=new s(t,e),o.collapseChildren=t.collapseChildren),this.$clipRangeToDocument(o.range);var u=o.start.row,a=o.start.column,f=o.end.row,l=o.end.column;if(u<f||u==f&&a<=l-2){var c=this.getFoldAt(u,a,1),h=this.getFoldAt(f,l,-1);if(c&&h==c)return c.addSubFold(o);c&&!c.range.isStart(u,a)&&this.removeFold(c),h&&!h.range.isEnd(f,l)&&this.removeFold(h);var p=this.getFoldsInRange(o.range);p.length>0&&(this.removeFolds(p),p.forEach(function(e){o.addSubFold(e)}));for(var d=0;d<n.length;d++){var v=n[d];if(f==v.start.row){v.addFold(o),r=!0;break}if(u==v.end.row){v.addFold(o),r=!0;if(!o.sameRow){var m=n[d+1];if(m&&m.start.row==f){v.merge(m);break}}break}if(f<=v.start.row)break}return r||(v=this.$addFoldLine(new i(this.$foldData,o))),this.$useWrapMode?this.$updateWrapData(v.start.row,v.start.row):this.$updateRowLengthCache(v.start.row,v.start.row),this.$modified=!0,this._signal("changeFold",{data:o,action:"add"}),o}throw new Error("The range has to be at least 2 characters width")},this.addFolds=function(e){e.forEach(function(e){this.addFold(e)},this)},this.removeFold=function(e){var t=e.foldLine,n=t.start.row,r=t.end.row,i=this.$foldData,s=t.folds;if(s.length==1)i.splice(i.indexOf(t),1);else if(t.range.isEnd(e.end.row,e.end.column))s.pop(),t.end.row=s[s.length-1].end.row,t.end.column=s[s.length-1].end.column;else if(t.range.isStart(e.start.row,e.start.column))s.shift(),t.start.row=s[0].start.row,t.start.column=s[0].start.column;else if(e.sameRow)s.splice(s.indexOf(e),1);else{var o=t.split(e.start.row,e.start.column);s=o.folds,s.shift(),o.start.row=s[0].start.row,o.start.column=s[0].start.column}this.$updating||(this.$useWrapMode?this.$updateWrapData(n,r):this.$updateRowLengthCache(n,r)),this.$modified=!0,this._signal("changeFold",{data:e,action:"remove"})},this.removeFolds=function(e){var t=[];for(var n=0;n<e.length;n++)t.push(e[n]);t.forEach(function(e){this.removeFold(e)},this),this.$modified=!0},this.expandFold=function(e){this.removeFold(e),e.subFolds.forEach(function(t){e.restoreRange(t),this.addFold(t)},this),e.collapseChildren>0&&this.foldAll(e.start.row+1,e.end.row,e.collapseChildren-1),e.subFolds=[]},this.expandFolds=function(e){e.forEach(function(e){this.expandFold(e)},this)},this.unfold=function(e,t){var n,i;e==null?(n=new r(0,0,this.getLength(),0),t=!0):typeof e=="number"?n=new r(e,0,e,this.getLine(e).length):"row"in e?n=r.fromPoints(e,e):n=e,i=this.getFoldsInRangeList(n);if(t)this.removeFolds(i);else{var s=i;while(s.length)this.expandFolds(s),s=this.getFoldsInRangeList(n)}if(i.length)return i},this.isRowFolded=function(e,t){return!!this.getFoldLine(e,t)},this.getRowFoldEnd=function(e,t){var n=this.getFoldLine(e,t);return n?n.end.row:e},this.getRowFoldStart=function(e,t){var n=this.getFoldLine(e,t);return n?n.start.row:e},this.getFoldDisplayLine=function(e,t,n,r,i){r==null&&(r=e.start.row),i==null&&(i=0),t==null&&(t=e.end.row),n==null&&(n=this.getLine(t).length);var s=this.doc,o="";return e.walk(function(e,t,n,u){if(t<r)return;if(t==r){if(n<i)return;u=Math.max(i,u)}e!=null?o+=e:o+=s.getLine(t).substring(u,n)},t,n),o},this.getDisplayLine=function(e,t,n,r){var i=this.getFoldLine(e);if(!i){var s;return s=this.doc.getLine(e),s.substring(r||0,t||s.length)}return this.getFoldDisplayLine(i,e,t,n,r)},this.$cloneFoldData=function(){var e=[];return e=this.$foldData.map(function(t){var n=t.folds.map(function(e){return e.clone()});return new i(e,n)}),e},this.toggleFold=function(e){var t=this.selection,n=t.getRange(),r,i;if(n.isEmpty()){var s=n.start;r=this.getFoldAt(s.row,s.column);if(r){this.expandFold(r);return}(i=this.findMatchingBracket(s))?n.comparePoint(i)==1?n.end=i:(n.start=i,n.start.column++,n.end.column--):(i=this.findMatchingBracket({row:s.row,column:s.column+1}))?(n.comparePoint(i)==1?n.end=i:n.start=i,n.start.column++):n=this.getCommentFoldRange(s.row,s.column)||n}else{var o=this.getFoldsInRange(n);if(e&&o.length){this.expandFolds(o);return}o.length==1&&(r=o[0])}r||(r=this.getFoldAt(n.start.row,n.start.column));if(r&&r.range.toString()==n.toString()){this.expandFold(r);return}var u="...";if(!n.isMultiLine()){u=this.getTextRange(n);if(u.length<4)return;u=u.trim().substring(0,2)+".."}this.addFold(u,n)},this.getCommentFoldRange=function(e,t,n){var i=new o(this,e,t),s=i.getCurrentToken(),u=s.type;if(s&&/^comment|string/.test(u)){u=u.match(/comment|string/)[0],u=="comment"&&(u+="|doc-start");var a=new RegExp(u),f=new r;if(n!=1){do s=i.stepBackward();while(s&&a.test(s.type));i.stepForward()}f.start.row=i.getCurrentTokenRow(),f.start.column=i.getCurrentTokenColumn()+2,i=new o(this,e,t);if(n!=-1){var l=-1;do{s=i.stepForward();if(l==-1){var c=this.getState(i.$row);a.test(c)||(l=i.$row)}else if(i.$row>l)break}while(s&&a.test(s.type));s=i.stepBackward()}else s=i.getCurrentToken();return f.end.row=i.getCurrentTokenRow(),f.end.column=i.getCurrentTokenColumn()+s.value.length-2,f}},this.foldAll=function(e,t,n){n==undefined&&(n=1e5);var r=this.foldWidgets;if(!r)return;t=t||this.getLength(),e=e||0;for(var i=e;i<t;i++){r[i]==null&&(r[i]=this.getFoldWidget(i));if(r[i]!="start")continue;var s=this.getFoldWidgetRange(i);if(s&&s.isMultiLine()&&s.end.row<=t&&s.start.row>=e){i=s.end.row;try{var o=this.addFold("...",s);o&&(o.collapseChildren=n)}catch(u){}}}},this.$foldStyles={manual:1,markbegin:1,markbeginend:1},this.$foldStyle="markbegin",this.setFoldStyle=function(e){if(!this.$foldStyles[e])throw new Error("invalid fold style: "+e+"["+Object.keys(this.$foldStyles).join(", ")+"]");if(this.$foldStyle==e)return;this.$foldStyle=e,e=="manual"&&this.unfold();var t=this.$foldMode;this.$setFolding(null),this.$setFolding(t)},this.$setFolding=function(e){if(this.$foldMode==e)return;this.$foldMode=e,this.off("change",this.$updateFoldWidgets),this.off("tokenizerUpdate",this.$tokenizerUpdateFoldWidgets),this._signal("changeAnnotation");if(!e||this.$foldStyle=="manual"){this.foldWidgets=null;return}this.foldWidgets=[],this.getFoldWidget=e.getFoldWidget.bind(e,this,this.$foldStyle),this.getFoldWidgetRange=e.getFoldWidgetRange.bind(e,this,this.$foldStyle),this.$updateFoldWidgets=this.updateFoldWidgets.bind(this),this.$tokenizerUpdateFoldWidgets=this.tokenizerUpdateFoldWidgets.bind(this),this.on("change",this.$updateFoldWidgets),this.on("tokenizerUpdate",this.$tokenizerUpdateFoldWidgets)},this.getParentFoldRangeData=function(e,t){var n=this.foldWidgets;if(!n||t&&n[e])return{};var r=e-1,i;while(r>=0){var s=n[r];s==null&&(s=n[r]=this.getFoldWidget(r));if(s=="start"){var o=this.getFoldWidgetRange(r);i||(i=o);if(o&&o.end.row>=e)break}r--}return{range:r!==-1&&o,firstRange:i}},this.onFoldWidgetClick=function(e,t){t=t.domEvent;var n={children:t.shiftKey,all:t.ctrlKey||t.metaKey,siblings:t.altKey},r=this.$toggleFoldWidget(e,n);if(!r){var i=t.target||t.srcElement;i&&/ace_fold-widget/.test(i.className)&&(i.className+=" ace_invalid")}},this.$toggleFoldWidget=function(e,t){if(!this.getFoldWidget)return;var n=this.getFoldWidget(e),r=this.getLine(e),i=n==="end"?-1:1,s=this.getFoldAt(e,i===-1?0:r.length,i);if(s)return t.children||t.all?this.removeFold(s):this.expandFold(s),s;var o=this.getFoldWidgetRange(e,!0);if(o&&!o.isMultiLine()){s=this.getFoldAt(o.start.row,o.start.column,1);if(s&&o.isEqual(s.range))return this.removeFold(s),s}if(t.siblings){var u=this.getParentFoldRangeData(e);if(u.range)var a=u.range.start.row+1,f=u.range.end.row;this.foldAll(a,f,t.all?1e4:0)}else t.children?(f=o?o.end.row:this.getLength(),this.foldAll(e+1,f,t.all?1e4:0)):o&&(t.all&&(o.collapseChildren=1e4),this.addFold("...",o));return o},this.toggleFoldWidget=function(e){var t=this.selection.getCursor().row;t=this.getRowFoldStart(t);var n=this.$toggleFoldWidget(t,{});if(n)return;var r=this.getParentFoldRangeData(t,!0);n=r.range||r.firstRange;if(n){t=n.start.row;var i=this.getFoldAt(t,this.getLine(t).length,1);i?this.removeFold(i):this.addFold("...",n)}},this.updateFoldWidgets=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.foldWidgets[t]=null;else if(e.action=="remove")this.foldWidgets.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.foldWidgets.splice.apply(this.foldWidgets,r)}},this.tokenizerUpdateFoldWidgets=function(e){var t=e.data;t.first!=t.last&&this.foldWidgets.length>t.first&&this.foldWidgets.splice(t.first,this.foldWidgets.length)}}var r=e("../range").Range,i=e("./fold_line").FoldLine,s=e("./fold").Fold,o=e("../token_iterator").TokenIterator;t.Folding=u}),ace.define("ace/edit_session/bracket_match",["require","exports","module","ace/token_iterator","ace/range"],function(e,t,n){"use strict";function s(){this.findMatchingBracket=function(e,t){if(e.column==0)return null;var n=t||this.getLine(e.row).charAt(e.column-1);if(n=="")return null;var r=n.match(/([\(\[\{])|([\)\]\}])/);return r?r[1]?this.$findClosingBracket(r[1],e):this.$findOpeningBracket(r[2],e):null},this.getBracketRange=function(e){var t=this.getLine(e.row),n=!0,r,s=t.charAt(e.column-1),o=s&&s.match(/([\(\[\{])|([\)\]\}])/);o||(s=t.charAt(e.column),e={row:e.row,column:e.column+1},o=s&&s.match(/([\(\[\{])|([\)\]\}])/),n=!1);if(!o)return null;if(o[1]){var u=this.$findClosingBracket(o[1],e);if(!u)return null;r=i.fromPoints(e,u),n||(r.end.column++,r.start.column--),r.cursor=r.end}else{var u=this.$findOpeningBracket(o[2],e);if(!u)return null;r=i.fromPoints(u,e),n||(r.start.column++,r.end.column--),r.cursor=r.start}return r},this.$brackets={")":"(","(":")","]":"[","[":"]","{":"}","}":"{","<":">",">":"<"},this.$findOpeningBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp("(\\.?"+u.type.replace(".","\\.").replace("rparen",".paren").replace(/\b(?:end)\b/,"(?:start|begin|end)")+")+"));var a=t.column-o.getCurrentTokenColumn()-2,f=u.value;for(;;){while(a>=0){var l=f.charAt(a);if(l==i){s-=1;if(s==0)return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else l==e&&(s+=1);a-=1}do u=o.stepBackward();while(u&&!n.test(u.type));if(u==null)break;f=u.value,a=f.length-1}return null},this.$findClosingBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp("(\\.?"+u.type.replace(".","\\.").replace("lparen",".paren").replace(/\b(?:start|begin)\b/,"(?:start|begin|end)")+")+"));var a=t.column-o.getCurrentTokenColumn();for(;;){var f=u.value,l=f.length;while(a<l){var c=f.charAt(a);if(c==i){s-=1;if(s==0)return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else c==e&&(s+=1);a+=1}do u=o.stepForward();while(u&&!n.test(u.type));if(u==null)break;a=0}return null}}var r=e("../token_iterator").TokenIterator,i=e("../range").Range;t.BracketMatch=s}),ace.define("ace/edit_session",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/bidihandler","ace/config","ace/lib/event_emitter","ace/selection","ace/mode/text","ace/range","ace/document","ace/background_tokenizer","ace/search_highlight","ace/edit_session/folding","ace/edit_session/bracket_match"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/lang"),s=e("./bidihandler").BidiHandler,o=e("./config"),u=e("./lib/event_emitter").EventEmitter,a=e("./selection").Selection,f=e("./mode/text").Mode,l=e("./range").Range,c=e("./document").Document,h=e("./background_tokenizer").BackgroundTokenizer,p=e("./search_highlight").SearchHighlight,d=function(e,t){this.$breakpoints=[],this.$decorations=[],this.$frontMarkers={},this.$backMarkers={},this.$markerId=1,this.$undoSelect=!0,this.$foldData=[],this.id="session"+ ++d.$uid,this.$foldData.toString=function(){return this.join("\n")},this.on("changeFold",this.onChangeFold.bind(this)),this.$onChange=this.onChange.bind(this);if(typeof e!="object"||!e.getLine)e=new c(e);this.setDocument(e),this.selection=new a(this),this.$bidiHandler=new s(this),o.resetOptions(this),this.setMode(t),o._signal("session",this)};d.$uid=0,function(){function m(e){return e<4352?!1:e>=4352&&e<=4447||e>=4515&&e<=4519||e>=4602&&e<=4607||e>=9001&&e<=9002||e>=11904&&e<=11929||e>=11931&&e<=12019||e>=12032&&e<=12245||e>=12272&&e<=12283||e>=12288&&e<=12350||e>=12353&&e<=12438||e>=12441&&e<=12543||e>=12549&&e<=12589||e>=12593&&e<=12686||e>=12688&&e<=12730||e>=12736&&e<=12771||e>=12784&&e<=12830||e>=12832&&e<=12871||e>=12880&&e<=13054||e>=13056&&e<=19903||e>=19968&&e<=42124||e>=42128&&e<=42182||e>=43360&&e<=43388||e>=44032&&e<=55203||e>=55216&&e<=55238||e>=55243&&e<=55291||e>=63744&&e<=64255||e>=65040&&e<=65049||e>=65072&&e<=65106||e>=65108&&e<=65126||e>=65128&&e<=65131||e>=65281&&e<=65376||e>=65504&&e<=65510}r.implement(this,u),this.setDocument=function(e){this.doc&&this.doc.removeListener("change",this.$onChange),this.doc=e,e.on("change",this.$onChange),this.bgTokenizer&&this.bgTokenizer.setDocument(this.getDocument()),this.resetCaches()},this.getDocument=function(){return this.doc},this.$resetRowCache=function(e){if(!e){this.$docRowCache=[],this.$screenRowCache=[];return}var t=this.$docRowCache.length,n=this.$getRowCacheIndex(this.$docRowCache,e)+1;t>n&&(this.$docRowCache.splice(n,t),this.$screenRowCache.splice(n,t))},this.$getRowCacheIndex=function(e,t){var n=0,r=e.length-1;while(n<=r){var i=n+r>>1,s=e[i];if(t>s)n=i+1;else{if(!(t<s))return i;r=i-1}}return n-1},this.resetCaches=function(){this.$modified=!0,this.$wrapData=[],this.$rowLengthCache=[],this.$resetRowCache(0),this.bgTokenizer&&this.bgTokenizer.start(0)},this.onChangeFold=function(e){var t=e.data;this.$resetRowCache(t.start.row)},this.onChange=function(e){this.$modified=!0,this.$bidiHandler.onChange(e),this.$resetRowCache(e.start.row);var t=this.$updateInternalDataOnChange(e);!this.$fromUndo&&this.$undoManager&&(t&&t.length&&(this.$undoManager.add({action:"removeFolds",folds:t},this.mergeUndoDeltas),this.mergeUndoDeltas=!0),this.$undoManager.add(e,this.mergeUndoDeltas),this.mergeUndoDeltas=!0,this.$informUndoManager.schedule()),this.bgTokenizer&&this.bgTokenizer.$updateOnChange(e),this._signal("change",e)},this.setValue=function(e){this.doc.setValue(e),this.selection.moveTo(0,0),this.$resetRowCache(0),this.setUndoManager(this.$undoManager),this.getUndoManager().reset()},this.getValue=this.toString=function(){return this.doc.getValue()},this.getSelection=function(){return this.selection},this.getState=function(e){return this.bgTokenizer.getState(e)},this.getTokens=function(e){return this.bgTokenizer.getTokens(e)},this.getTokenAt=function(e,t){var n=this.bgTokenizer.getTokens(e),r,i=0;if(t==null){var s=n.length-1;i=this.getLine(e).length}else for(var s=0;s<n.length;s++){i+=n[s].value.length;if(i>=t)break}return r=n[s],r?(r.index=s,r.start=i-r.value.length,r):null},this.setUndoManager=function(e){this.$undoManager=e,this.$informUndoManager&&this.$informUndoManager.cancel();if(e){var t=this;e.addSession(this),this.$syncInformUndoManager=function(){t.$informUndoManager.cancel(),t.mergeUndoDeltas=!1},this.$informUndoManager=i.delayedCall(this.$syncInformUndoManager)}else this.$syncInformUndoManager=function(){}},this.markUndoGroup=function(){this.$syncInformUndoManager&&this.$syncInformUndoManager()},this.$defaultUndoManager={undo:function(){},redo:function(){},reset:function(){},add:function(){},addSelection:function(){},startNewGroup:function(){},addSession:function(){}},this.getUndoManager=function(){return this.$undoManager||this.$defaultUndoManager},this.getTabString=function(){return this.getUseSoftTabs()?i.stringRepeat(" ",this.getTabSize()):" "},this.setUseSoftTabs=function(e){this.setOption("useSoftTabs",e)},this.getUseSoftTabs=function(){return this.$useSoftTabs&&!this.$mode.$indentWithTabs},this.setTabSize=function(e){this.setOption("tabSize",e)},this.getTabSize=function(){return this.$tabSize},this.isTabStop=function(e){return this.$useSoftTabs&&e.column%this.$tabSize===0},this.setNavigateWithinSoftTabs=function(e){this.setOption("navigateWithinSoftTabs",e)},this.getNavigateWithinSoftTabs=function(){return this.$navigateWithinSoftTabs},this.$overwrite=!1,this.setOverwrite=function(e){this.setOption("overwrite",e)},this.getOverwrite=function(){return this.$overwrite},this.toggleOverwrite=function(){this.setOverwrite(!this.$overwrite)},this.addGutterDecoration=function(e,t){this.$decorations[e]||(this.$decorations[e]=""),this.$decorations[e]+=" "+t,this._signal("changeBreakpoint",{})},this.removeGutterDecoration=function(e,t){this.$decorations[e]=(this.$decorations[e]||"").replace(" "+t,""),this._signal("changeBreakpoint",{})},this.getBreakpoints=function(){return this.$breakpoints},this.setBreakpoints=function(e){this.$breakpoints=[];for(var t=0;t<e.length;t++)this.$breakpoints[e[t]]="ace_breakpoint";this._signal("changeBreakpoint",{})},this.clearBreakpoints=function(){this.$breakpoints=[],this._signal("changeBreakpoint",{})},this.setBreakpoint=function(e,t){t===undefined&&(t="ace_breakpoint"),t?this.$breakpoints[e]=t:delete this.$breakpoints[e],this._signal("changeBreakpoint",{})},this.clearBreakpoint=function(e){delete this.$breakpoints[e],this._signal("changeBreakpoint",{})},this.addMarker=function(e,t,n,r){var i=this.$markerId++,s={range:e,type:n||"line",renderer:typeof n=="function"?n:null,clazz:t,inFront:!!r,id:i};return r?(this.$frontMarkers[i]=s,this._signal("changeFrontMarker")):(this.$backMarkers[i]=s,this._signal("changeBackMarker")),i},this.addDynamicMarker=function(e,t){if(!e.update)return;var n=this.$markerId++;return e.id=n,e.inFront=!!t,t?(this.$frontMarkers[n]=e,this._signal("changeFrontMarker")):(this.$backMarkers[n]=e,this._signal("changeBackMarker")),e},this.removeMarker=function(e){var t=this.$frontMarkers[e]||this.$backMarkers[e];if(!t)return;var n=t.inFront?this.$frontMarkers:this.$backMarkers;delete n[e],this._signal(t.inFront?"changeFrontMarker":"changeBackMarker")},this.getMarkers=function(e){return e?this.$frontMarkers:this.$backMarkers},this.highlight=function(e){if(!this.$searchHighlight){var t=new p(null,"ace_selected-word","text");this.$searchHighlight=this.addDynamicMarker(t)}this.$searchHighlight.setRegexp(e)},this.highlightLines=function(e,t,n,r){typeof t!="number"&&(n=t,t=e),n||(n="ace_step");var i=new l(e,0,t,Infinity);return i.id=this.addMarker(i,n,"fullLine",r),i},this.setAnnotations=function(e){this.$annotations=e,this._signal("changeAnnotation",{})},this.getAnnotations=function(){return this.$annotations||[]},this.clearAnnotations=function(){this.setAnnotations([])},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r?\n)/m);t?this.$autoNewLine=t[1]:this.$autoNewLine="\n"},this.getWordRange=function(e,t){var n=this.getLine(e),r=!1;t>0&&(r=!!n.charAt(t-1).match(this.tokenRe)),r||(r=!!n.charAt(t).match(this.tokenRe));if(r)var i=this.tokenRe;else if(/^\s+$/.test(n.slice(t-1,t+1)))var i=/\s/;else var i=this.nonTokenRe;var s=t;if(s>0){do s--;while(s>=0&&n.charAt(s).match(i));s++}var o=t;while(o<n.length&&n.charAt(o).match(i))o++;return new l(e,s,e,o)},this.getAWordRange=function(e,t){var n=this.getWordRange(e,t),r=this.getLine(n.end.row);while(r.charAt(n.end.column).match(/[ \t]/))n.end.column+=1;return n},this.setNewLineMode=function(e){this.doc.setNewLineMode(e)},this.getNewLineMode=function(){return this.doc.getNewLineMode()},this.setUseWorker=function(e){this.setOption("useWorker",e)},this.getUseWorker=function(){return this.$useWorker},this.onReloadTokenizer=function(e){var t=e.data;this.bgTokenizer.start(t.first),this._signal("tokenizerUpdate",e)},this.$modes=o.$modes,this.$mode=null,this.$modeId=null,this.setMode=function(e,t){if(e&&typeof e=="object"){if(e.getTokenizer)return this.$onChangeMode(e);var n=e,r=n.path}else r=e||"ace/mode/text";this.$modes["ace/mode/text"]||(this.$modes["ace/mode/text"]=new f);if(this.$modes[r]&&!n){this.$onChangeMode(this.$modes[r]),t&&t();return}this.$modeId=r,o.loadModule(["mode",r],function(e){if(this.$modeId!==r)return t&&t();this.$modes[r]&&!n?this.$onChangeMode(this.$modes[r]):e&&e.Mode&&(e=new e.Mode(n),n||(this.$modes[r]=e,e.$id=r),this.$onChangeMode(e)),t&&t()}.bind(this)),this.$mode||this.$onChangeMode(this.$modes["ace/mode/text"],!0)},this.$onChangeMode=function(e,t){t||(this.$modeId=e.$id);if(this.$mode===e)return;this.$mode=e,this.$stopWorker(),this.$useWorker&&this.$startWorker();var n=e.getTokenizer();if(n.addEventListener!==undefined){var r=this.onReloadTokenizer.bind(this);n.addEventListener("update",r)}if(!this.bgTokenizer){this.bgTokenizer=new h(n);var i=this;this.bgTokenizer.addEventListener("update",function(e){i._signal("tokenizerUpdate",e)})}else this.bgTokenizer.setTokenizer(n);this.bgTokenizer.setDocument(this.getDocument()),this.tokenRe=e.tokenRe,this.nonTokenRe=e.nonTokenRe,t||(e.attachToSession&&e.attachToSession(this),this.$options.wrapMethod.set.call(this,this.$wrapMethod),this.$setFolding(e.foldingRules),this.bgTokenizer.start(0),this._emit("changeMode"))},this.$stopWorker=function(){this.$worker&&(this.$worker.terminate(),this.$worker=null)},this.$startWorker=function(){try{this.$worker=this.$mode.createWorker(this)}catch(e){o.warn("Could not load worker",e),this.$worker=null}},this.getMode=function(){return this.$mode},this.$scrollTop=0,this.setScrollTop=function(e){if(this.$scrollTop===e||isNaN(e))return;this.$scrollTop=e,this._signal("changeScrollTop",e)},this.getScrollTop=function(){return this.$scrollTop},this.$scrollLeft=0,this.setScrollLeft=function(e){if(this.$scrollLeft===e||isNaN(e))return;this.$scrollLeft=e,this._signal("changeScrollLeft",e)},this.getScrollLeft=function(){return this.$scrollLeft},this.getScreenWidth=function(){return this.$computeWidth(),this.lineWidgets?Math.max(this.getLineWidgetMaxWidth(),this.screenWidth):this.screenWidth},this.getLineWidgetMaxWidth=function(){if(this.lineWidgetsWidth!=null)return this.lineWidgetsWidth;var e=0;return this.lineWidgets.forEach(function(t){t&&t.screenWidth>e&&(e=t.screenWidth)}),this.lineWidgetWidth=e},this.$computeWidth=function(e){if(this.$modified||e){this.$modified=!1;if(this.$useWrapMode)return this.screenWidth=this.$wrapLimit;var t=this.doc.getAllLines(),n=this.$rowLengthCache,r=0,i=0,s=this.$foldData[i],o=s?s.start.row:Infinity,u=t.length;for(var a=0;a<u;a++){if(a>o){a=s.end.row+1;if(a>=u)break;s=this.$foldData[i++],o=s?s.start.row:Infinity}n[a]==null&&(n[a]=this.$getStringScreenWidth(t[a])[0]),n[a]>r&&(r=n[a])}this.screenWidth=r}},this.getLine=function(e){return this.doc.getLine(e)},this.getLines=function(e,t){return this.doc.getLines(e,t)},this.getLength=function(){return this.doc.getLength()},this.getTextRange=function(e){return this.doc.getTextRange(e||this.selection.getRange())},this.insert=function(e,t){return this.doc.insert(e,t)},this.remove=function(e){return this.doc.remove(e)},this.removeFullLines=function(e,t){return this.doc.removeFullLines(e,t)},this.undoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;for(var n=e.length-1;n!=-1;n--){var r=e[n];r.action=="insert"||r.action=="remove"?this.doc.revertDelta(r):r.folds&&this.addFolds(r.folds)}!t&&this.$undoSelect&&(e.selectionBefore?this.selection.fromJSON(e.selectionBefore):this.selection.setRange(this.$getUndoSelection(e,!0))),this.$fromUndo=!1},this.redoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;for(var n=0;n<e.length;n++){var r=e[n];(r.action=="insert"||r.action=="remove")&&this.doc.applyDelta(r)}!t&&this.$undoSelect&&(e.selectionAfter?this.selection.fromJSON(e.selectionAfter):this.selection.setRange(this.$getUndoSelection(e,!1))),this.$fromUndo=!1},this.setUndoSelect=function(e){this.$undoSelect=e},this.$getUndoSelection=function(e,t){function n(e){return t?e.action!=="insert":e.action==="insert"}var r,i,s;for(var o=0;o<e.length;o++){var u=e[o];if(!u.start)continue;if(!r){n(u)?(r=l.fromPoints(u.start,u.end),s=!0):(r=l.fromPoints(u.start,u.start),s=!1);continue}n(u)?(i=u.start,r.compare(i.row,i.column)==-1&&r.setStart(i),i=u.end,r.compare(i.row,i.column)==1&&r.setEnd(i),s=!0):(i=u.start,r.compare(i.row,i.column)==-1&&(r=l.fromPoints(u.start,u.start)),s=!1)}return r},this.replace=function(e,t){return this.doc.replace(e,t)},this.moveText=function(e,t,n){var r=this.getTextRange(e),i=this.getFoldsInRange(e),s=l.fromPoints(t,t);if(!n){this.remove(e);var o=e.start.row-e.end.row,u=o?-e.end.column:e.start.column-e.end.column;u&&(s.start.row==e.end.row&&s.start.column>e.end.column&&(s.start.column+=u),s.end.row==e.end.row&&s.end.column>e.end.column&&(s.end.column+=u)),o&&s.start.row>=e.end.row&&(s.start.row+=o,s.end.row+=o)}s.end=this.insert(s.start,r);if(i.length){var a=e.start,f=s.start,o=f.row-a.row,u=f.column-a.column;this.addFolds(i.map(function(e){return e=e.clone(),e.start.row==a.row&&(e.start.column+=u),e.end.row==a.row&&(e.end.column+=u),e.start.row+=o,e.end.row+=o,e}))}return s},this.indentRows=function(e,t,n){n=n.replace(/\t/g,this.getTabString());for(var r=e;r<=t;r++)this.doc.insertInLine({row:r,column:0},n)},this.outdentRows=function(e){var t=e.collapseRows(),n=new l(0,0,0,0),r=this.getTabSize();for(var i=t.start.row;i<=t.end.row;++i){var s=this.getLine(i);n.start.row=i,n.end.row=i;for(var o=0;o<r;++o)if(s.charAt(o)!=" ")break;o<r&&s.charAt(o)==" "?(n.start.column=o,n.end.column=o+1):(n.start.column=0,n.end.column=o),this.remove(n)}},this.$moveLines=function(e,t,n){e=this.getRowFoldStart(e),t=this.getRowFoldEnd(t);if(n<0){var r=this.getRowFoldStart(e+n);if(r<0)return 0;var i=r-e}else if(n>0){var r=this.getRowFoldEnd(t+n);if(r>this.doc.getLength()-1)return 0;var i=r-t}else{e=this.$clipRowToDocument(e),t=this.$clipRowToDocument(t);var i=t-e+1}var s=new l(e,0,t,Number.MAX_VALUE),o=this.getFoldsInRange(s).map(function(e){return e=e.clone(),e.start.row+=i,e.end.row+=i,e}),u=n==0?this.doc.getLines(e,t):this.doc.removeFullLines(e,t);return this.doc.insertFullLines(e+i,u),o.length&&this.addFolds(o),i},this.moveLinesUp=function(e,t){return this.$moveLines(e,t,-1)},this.moveLinesDown=function(e,t){return this.$moveLines(e,t,1)},this.duplicateLines=function(e,t){return this.$moveLines(e,t,0)},this.$clipRowToDocument=function(e){return Math.max(0,Math.min(e,this.doc.getLength()-1))},this.$clipColumnToRow=function(e,t){return t<0?0:Math.min(this.doc.getLine(e).length,t)},this.$clipPositionToDocument=function(e,t){t=Math.max(0,t);if(e<0)e=0,t=0;else{var n=this.doc.getLength();e>=n?(e=n-1,t=this.doc.getLine(n-1).length):t=Math.min(this.doc.getLine(e).length,t)}return{row:e,column:t}},this.$clipRangeToDocument=function(e){e.start.row<0?(e.start.row=0,e.start.column=0):e.start.column=this.$clipColumnToRow(e.start.row,e.start.column);var t=this.doc.getLength()-1;return e.end.row>t?(e.end.row=t,e.end.column=this.doc.getLine(t).length):e.end.column=this.$clipColumnToRow(e.end.row,e.end.column),e},this.$wrapLimit=80,this.$useWrapMode=!1,this.$wrapLimitRange={min:null,max:null},this.setUseWrapMode=function(e){if(e!=this.$useWrapMode){this.$useWrapMode=e,this.$modified=!0,this.$resetRowCache(0);if(e){var t=this.getLength();this.$wrapData=Array(t),this.$updateWrapData(0,t-1)}this._signal("changeWrapMode")}},this.getUseWrapMode=function(){return this.$useWrapMode},this.setWrapLimitRange=function(e,t){if(this.$wrapLimitRange.min!==e||this.$wrapLimitRange.max!==t)this.$wrapLimitRange={min:e,max:t},this.$modified=!0,this.$bidiHandler.markAsDirty(),this.$useWrapMode&&this._signal("changeWrapMode")},this.adjustWrapLimit=function(e,t){var n=this.$wrapLimitRange;n.max<0&&(n={min:t,max:t});var r=this.$constrainWrapLimit(e,n.min,n.max);return r!=this.$wrapLimit&&r>1?(this.$wrapLimit=r,this.$modified=!0,this.$useWrapMode&&(this.$updateWrapData(0,this.getLength()-1),this.$resetRowCache(0),this._signal("changeWrapLimit")),!0):!1},this.$constrainWrapLimit=function(e,t,n){return t&&(e=Math.max(t,e)),n&&(e=Math.min(n,e)),e},this.getWrapLimit=function(){return this.$wrapLimit},this.setWrapLimit=function(e){this.setWrapLimitRange(e,e)},this.getWrapLimitRange=function(){return{min:this.$wrapLimitRange.min,max:this.$wrapLimitRange.max}},this.$updateInternalDataOnChange=function(e){var t=this.$useWrapMode,n=e.action,r=e.start,i=e.end,s=r.row,o=i.row,u=o-s,a=null;this.$updating=!0;if(u!=0)if(n==="remove"){this[t?"$wrapData":"$rowLengthCache"].splice(s,u);var f=this.$foldData;a=this.getFoldsInRange(e),this.removeFolds(a);var l=this.getFoldLine(i.row),c=0;if(l){l.addRemoveChars(i.row,i.column,r.column-i.column),l.shiftRow(-u);var h=this.getFoldLine(s);h&&h!==l&&(h.merge(l),l=h),c=f.indexOf(l)+1}for(c;c<f.length;c++){var l=f[c];l.start.row>=i.row&&l.shiftRow(-u)}o=s}else{var p=Array(u);p.unshift(s,0);var d=t?this.$wrapData:this.$rowLengthCache;d.splice.apply(d,p);var f=this.$foldData,l=this.getFoldLine(s),c=0;if(l){var v=l.range.compareInside(r.row,r.column);v==0?(l=l.split(r.row,r.column),l&&(l.shiftRow(u),l.addRemoveChars(o,0,i.column-r.column))):v==-1&&(l.addRemoveChars(s,0,i.column-r.column),l.shiftRow(u)),c=f.indexOf(l)+1}for(c;c<f.length;c++){var l=f[c];l.start.row>=s&&l.shiftRow(u)}}else{u=Math.abs(e.start.column-e.end.column),n==="remove"&&(a=this.getFoldsInRange(e),this.removeFolds(a),u=-u);var l=this.getFoldLine(s);l&&l.addRemoveChars(s,r.column,u)}return t&&this.$wrapData.length!=this.doc.getLength()&&console.error("doc.getLength() and $wrapData.length have to be the same!"),this.$updating=!1,t?this.$updateWrapData(s,o):this.$updateRowLengthCache(s,o),a},this.$updateRowLengthCache=function(e,t,n){this.$rowLengthCache[e]=null,this.$rowLengthCache[t]=null},this.$updateWrapData=function(e,t){var r=this.doc.getAllLines(),i=this.getTabSize(),o=this.$wrapData,u=this.$wrapLimit,a,f,l=e;t=Math.min(t,r.length-1);while(l<=t)f=this.getFoldLine(l,f),f?(a=[],f.walk(function(e,t,i,o){var u;if(e!=null){u=this.$getDisplayTokens(e,a.length),u[0]=n;for(var f=1;f<u.length;f++)u[f]=s}else u=this.$getDisplayTokens(r[t].substring(o,i),a.length);a=a.concat(u)}.bind(this),f.end.row,r[f.end.row].length+1),o[f.start.row]=this.$computeWrapSplits(a,u,i),l=f.end.row+1):(a=this.$getDisplayTokens(r[l]),o[l]=this.$computeWrapSplits(a,u,i),l++)};var e=1,t=2,n=3,s=4,a=9,c=10,d=11,v=12;this.$computeWrapSplits=function(e,r,i){function g(){var t=0;if(m===0)return t;if(p)for(var n=0;n<e.length;n++){var r=e[n];if(r==c)t+=1;else{if(r!=d){if(r==v)continue;break}t+=i}}return h&&p!==!1&&(t+=i),Math.min(t,m)}function y(t){var n=t-f;for(var r=f;r<t;r++){var i=e[r];if(i===12||i===2)n-=1}o.length||(b=g(),o.indent=b),l+=n,o.push(l),f=t}if(e.length==0)return[];var o=[],u=e.length,f=0,l=0,h=this.$wrapAsCode,p=this.$indentedSoftWrap,m=r<=Math.max(2*i,8)||p===!1?0:Math.floor(r/2),b=0;while(u-f>r-b){var w=f+r-b;if(e[w-1]>=c&&e[w]>=c){y(w);continue}if(e[w]==n||e[w]==s){for(w;w!=f-1;w--)if(e[w]==n)break;if(w>f){y(w);continue}w=f+r;for(w;w<e.length;w++)if(e[w]!=s)break;if(w==e.length)break;y(w);continue}var E=Math.max(w-(r-(r>>2)),f-1);while(w>E&&e[w]<n)w--;if(h){while(w>E&&e[w]<n)w--;while(w>E&&e[w]==a)w--}else while(w>E&&e[w]<c)w--;if(w>E){y(++w);continue}w=f+r,e[w]==t&&w--,y(w-b)}return o},this.$getDisplayTokens=function(n,r){var i=[],s;r=r||0;for(var o=0;o<n.length;o++){var u=n.charCodeAt(o);if(u==9){s=this.getScreenTabSize(i.length+r),i.push(d);for(var f=1;f<s;f++)i.push(v)}else u==32?i.push(c):u>39&&u<48||u>57&&u<64?i.push(a):u>=4352&&m(u)?i.push(e,t):i.push(e)}return i},this.$getStringScreenWidth=function(e,t,n){if(t==0)return[0,0];t==null&&(t=Infinity),n=n||0;var r,i;for(i=0;i<e.length;i++){r=e.charCodeAt(i),r==9?n+=this.getScreenTabSize(n):r>=4352&&m(r)?n+=2:n+=1;if(n>t)break}return[n,i]},this.lineWidgets=null,this.getRowLength=function(e){if(this.lineWidgets)var t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0;else t=0;return!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.getRowLineCount=function(e){return!this.$useWrapMode||!this.$wrapData[e]?1:this.$wrapData[e].length+1},this.getRowWrapIndent=function(e){if(this.$useWrapMode){var t=this.screenToDocumentPosition(e,Number.MAX_VALUE),n=this.$wrapData[t.row];return n.length&&n[0]<t.column?n.indent:0}return 0},this.getScreenLastRowColumn=function(e){var t=this.screenToDocumentPosition(e,Number.MAX_VALUE);return this.documentToScreenColumn(t.row,t.column)},this.getDocumentLastRowColumn=function(e,t){var n=this.documentToScreenRow(e,t);return this.getScreenLastRowColumn(n)},this.getDocumentLastRowColumnPosition=function(e,t){var n=this.documentToScreenRow(e,t);return this.screenToDocumentPosition(n,Number.MAX_VALUE/10)},this.getRowSplitData=function(e){return this.$useWrapMode?this.$wrapData[e]:undefined},this.getScreenTabSize=function(e){return this.$tabSize-e%this.$tabSize},this.screenToDocumentRow=function(e,t){return this.screenToDocumentPosition(e,t).row},this.screenToDocumentColumn=function(e,t){return this.screenToDocumentPosition(e,t).column},this.screenToDocumentPosition=function(e,t,n){if(e<0)return{row:0,column:0};var r,i=0,s=0,o,u=0,a=0,f=this.$screenRowCache,l=this.$getRowCacheIndex(f,e),c=f.length;if(c&&l>=0)var u=f[l],i=this.$docRowCache[l],h=e>f[c-1];else var h=!c;var p=this.getLength()-1,d=this.getNextFoldLine(i),v=d?d.start.row:Infinity;while(u<=e){a=this.getRowLength(i);if(u+a>e||i>=p)break;u+=a,i++,i>v&&(i=d.end.row+1,d=this.getNextFoldLine(i,d),v=d?d.start.row:Infinity),h&&(this.$docRowCache.push(i),this.$screenRowCache.push(u))}if(d&&d.start.row<=i)r=this.getFoldDisplayLine(d),i=d.start.row;else{if(u+a<=e||i>p)return{row:p,column:this.getLine(p).length};r=this.getLine(i),d=null}var m=0,g=Math.floor(e-u);if(this.$useWrapMode){var y=this.$wrapData[i];y&&(o=y[g],g>0&&y.length&&(m=y.indent,s=y[g-1]||y[y.length-1],r=r.substring(s)))}return n!==undefined&&this.$bidiHandler.isBidiRow(u+g,i,g)&&(t=this.$bidiHandler.offsetToCol(n)),s+=this.$getStringScreenWidth(r,t-m)[1],this.$useWrapMode&&s>=o&&(s=o-1),d?d.idxToPosition(s):{row:i,column:s}},this.documentToScreenPosition=function(e,t){if(typeof t=="undefined")var n=this.$clipPositionToDocument(e.row,e.column);else n=this.$clipPositionToDocument(e,t);e=n.row,t=n.column;var r=0,i=null,s=null;s=this.getFoldAt(e,t,1),s&&(e=s.start.row,t=s.start.column);var o,u=0,a=this.$docRowCache,f=this.$getRowCacheIndex(a,e),l=a.length;if(l&&f>=0)var u=a[f],r=this.$screenRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getNextFoldLine(u),p=h?h.start.row:Infinity;while(u<e){if(u>=p){o=h.end.row+1;if(o>e)break;h=this.getNextFoldLine(o,h),p=h?h.start.row:Infinity}else o=u+1;r+=this.getRowLength(u),u=o,c&&(this.$docRowCache.push(u),this.$screenRowCache.push(r))}var d="";h&&u>=p?(d=this.getFoldDisplayLine(h,e,t),i=h.start.row):(d=this.getLine(e).substring(0,t),i=e);var v=0;if(this.$useWrapMode){var m=this.$wrapData[i];if(m){var g=0;while(d.length>=m[g])r++,g++;d=d.substring(m[g-1]||0,d.length),v=g>0?m.indent:0}}return{row:r,column:v+this.$getStringScreenWidth(d)[0]}},this.documentToScreenColumn=function(e,t){return this.documentToScreenPosition(e,t).column},this.documentToScreenRow=function(e,t){return this.documentToScreenPosition(e,t).row},this.getScreenLength=function(){var e=0,t=null;if(!this.$useWrapMode){e=this.getLength();var n=this.$foldData;for(var r=0;r<n.length;r++)t=n[r],e-=t.end.row-t.start.row}else{var i=this.$wrapData.length,s=0,r=0,t=this.$foldData[r++],o=t?t.start.row:Infinity;while(s<i){var u=this.$wrapData[s];e+=u?u.length+1:1,s++,s>o&&(s=t.end.row+1,t=this.$foldData[r++],o=t?t.start.row:Infinity)}}return this.lineWidgets&&(e+=this.$getWidgetScreenLength()),e},this.$setFontMetrics=function(e){if(!this.$enableVarChar)return;this.$getStringScreenWidth=function(t,n,r){if(n===0)return[0,0];n||(n=Infinity),r=r||0;var i,s;for(s=0;s<t.length;s++){i=t.charAt(s),i===" "?r+=this.getScreenTabSize(r):r+=e.getCharacterWidth(i);if(r>n)break}return[r,s]}},this.destroy=function(){this.bgTokenizer&&(this.bgTokenizer.setDocument(null),this.bgTokenizer=null),this.$stopWorker()},this.isFullWidth=m}.call(d.prototype),e("./edit_session/folding").Folding.call(d.prototype),e("./edit_session/bracket_match").BracketMatch.call(d.prototype),o.defineOptions(d.prototype,"session",{wrap:{set:function(e){!e||e=="off"?e=!1:e=="free"?e=!0:e=="printMargin"?e=-1:typeof e=="string"&&(e=parseInt(e,10)||!1);if(this.$wrap==e)return;this.$wrap=e;if(!e)this.setUseWrapMode(!1);else{var t=typeof e=="number"?e:null;this.setWrapLimitRange(t,t),this.setUseWrapMode(!0)}},get:function(){return this.getUseWrapMode()?this.$wrap==-1?"printMargin":this.getWrapLimitRange().min?this.$wrap:"free":"off"},handlesSet:!0},wrapMethod:{set:function(e){e=e=="auto"?this.$mode.type!="text":e!="text",e!=this.$wrapAsCode&&(this.$wrapAsCode=e,this.$useWrapMode&&(this.$useWrapMode=!1,this.setUseWrapMode(!0)))},initialValue:"auto"},indentedSoftWrap:{set:function(){this.$useWrapMode&&(this.$useWrapMode=!1,this.setUseWrapMode(!0))},initialValue:!0},firstLineNumber:{set:function(){this._signal("changeBreakpoint")},initialValue:1},useWorker:{set:function(e){this.$useWorker=e,this.$stopWorker(),e&&this.$startWorker()},initialValue:!0},useSoftTabs:{initialValue:!0},tabSize:{set:function(e){e=parseInt(e);if(isNaN(e)||this.$tabSize===e)return;this.$modified=!0,this.$rowLengthCache=[],this.$tabSize=e,this._signal("changeTabSize")},initialValue:4,handlesSet:!0},navigateWithinSoftTabs:{initialValue:!1},foldStyle:{set:function(e){this.setFoldStyle(e)},handlesSet:!0},overwrite:{set:function(e){this._signal("changeOverwrite")},initialValue:!1},newLineMode:{set:function(e){this.doc.setNewLineMode(e)},get:function(){return this.doc.getNewLineMode()},handlesSet:!0},mode:{set:function(e){this.setMode(e)},get:function(){return this.$modeId},handlesSet:!0}}),t.EditSession=d}),ace.define("ace/search",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"],function(e,t,n){"use strict";function u(e,t){function n(e){return/\w/.test(e)||t.regExp?"\\b":""}return n(e[0])+e+n(e[e.length-1])}var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./range").Range,o=function(){this.$options={}};(function(){this.set=function(e){return i.mixin(this.$options,e),this},this.getOptions=function(){return r.copyObject(this.$options)},this.setOptions=function(e){this.$options=e},this.find=function(e){var t=this.$options,n=this.$matchIterator(e,t);if(!n)return!1;var r=null;return n.forEach(function(e,n,i,o){return r=new s(e,n,i,o),n==o&&t.start&&t.start.start&&t.skipCurrent!=0&&r.isEqual(t.start)?(r=null,!1):!0}),r},this.findAll=function(e){var t=this.$options;if(!t.needle)return[];this.$assembleRegExp(t);var n=t.range,i=n?e.getLines(n.start.row,n.end.row):e.doc.getAllLines(),o=[],u=t.re;if(t.$isMultiLine){var a=u.length,f=i.length-a,l;e:for(var c=u.offset||0;c<=f;c++){for(var h=0;h<a;h++)if(i[c+h].search(u[h])==-1)continue e;var p=i[c],d=i[c+a-1],v=p.length-p.match(u[0])[0].length,m=d.match(u[a-1])[0].length;if(l&&l.end.row===c&&l.end.column>v)continue;o.push(l=new s(c,v,c+a-1,m)),a>2&&(c=c+a-2)}}else for(var g=0;g<i.length;g++){var y=r.getMatchOffsets(i[g],u);for(var h=0;h<y.length;h++){var b=y[h];o.push(new s(g,b.offset,g,b.offset+b.length))}}if(n){var w=n.start.column,E=n.start.column,g=0,h=o.length-1;while(g<h&&o[g].start.column<w&&o[g].start.row==n.start.row)g++;while(g<h&&o[h].end.column>E&&o[h].end.row==n.end.row)h--;o=o.slice(g,h+1);for(g=0,h=o.length;g<h;g++)o[g].start.row+=n.start.row,o[g].end.row+=n.start.row}return o},this.replace=function(e,t){var n=this.$options,r=this.$assembleRegExp(n);if(n.$isMultiLine)return t;if(!r)return;var i=r.exec(e);if(!i||i[0].length!=e.length)return null;t=e.replace(r,t);if(n.preserveCase){t=t.split("");for(var s=Math.min(e.length,e.length);s--;){var o=e[s];o&&o.toLowerCase()!=o?t[s]=t[s].toUpperCase():t[s]=t[s].toLowerCase()}t=t.join("")}return t},this.$assembleRegExp=function(e,t){if(e.needle instanceof RegExp)return e.re=e.needle;var n=e.needle;if(!e.needle)return e.re=!1;e.regExp||(n=r.escapeRegExp(n)),e.wholeWord&&(n=u(n,e));var i=e.caseSensitive?"gm":"gmi";e.$isMultiLine=!t&&/[\n\r]/.test(n);if(e.$isMultiLine)return e.re=this.$assembleMultilineRegExp(n,i);try{var s=new RegExp(n,i)}catch(o){s=!1}return e.re=s},this.$assembleMultilineRegExp=function(e,t){var n=e.replace(/\r\n|\r|\n/g,"$\n^").split("\n"),r=[];for(var i=0;i<n.length;i++)try{r.push(new RegExp(n[i],t))}catch(s){return!1}return r},this.$matchIterator=function(e,t){var n=this.$assembleRegExp(t);if(!n)return!1;var r=t.backwards==1,i=t.skipCurrent!=0,s=t.range,o=t.start;o||(o=s?s[r?"end":"start"]:e.selection.getRange()),o.start&&(o=o[i!=r?"end":"start"]);var u=s?s.start.row:0,a=s?s.end.row:e.getLength()-1;if(r)var f=function(e){var n=o.row;if(c(n,o.column,e))return;for(n--;n>=u;n--)if(c(n,Number.MAX_VALUE,e))return;if(t.wrap==0)return;for(n=a,u=o.row;n>=u;n--)if(c(n,Number.MAX_VALUE,e))return};else var f=function(e){var n=o.row;if(c(n,o.column,e))return;for(n+=1;n<=a;n++)if(c(n,0,e))return;if(t.wrap==0)return;for(n=u,a=o.row;n<=a;n++)if(c(n,0,e))return};if(t.$isMultiLine)var l=n.length,c=function(t,i,s){var o=r?t-l+1:t;if(o<0)return;var u=e.getLine(o),a=u.search(n[0]);if(!r&&a<i||a===-1)return;for(var f=1;f<l;f++){u=e.getLine(o+f);if(u.search(n[f])==-1)return}var c=u.match(n[l-1])[0].length;if(r&&c>i)return;if(s(o,a,o+l-1,c))return!0};else if(r)var c=function(t,r,i){var s=e.getLine(t),o=[],u,a=0;n.lastIndex=0;while(u=n.exec(s)){var f=u[0].length;a=u.index;if(!f){if(a>=s.length)break;n.lastIndex=a+=1}if(u.index+f>r)break;o.push(u.index,f)}for(var l=o.length-1;l>=0;l-=2){var c=o[l-1],f=o[l];if(i(t,c,t,c+f))return!0}};else var c=function(t,r,i){var s=e.getLine(t),o,u;n.lastIndex=r;while(u=n.exec(s)){var a=u[0].length;o=u.index;if(i(t,o,t,o+a))return!0;if(!a){n.lastIndex=o+=1;if(o>=s.length)return!1}}};return{forEach:f}}}).call(o.prototype),t.Search=o}),ace.define("ace/keyboard/hash_handler",["require","exports","module","ace/lib/keys","ace/lib/useragent"],function(e,t,n){"use strict";function o(e,t){this.platform=t||(i.isMac?"mac":"win"),this.commands={},this.commandKeyBinding={},this.addCommands(e),this.$singleCommand=!0}function u(e,t){o.call(this,e,t),this.$singleCommand=!1}var r=e("../lib/keys"),i=e("../lib/useragent"),s=r.KEY_MODS;u.prototype=o.prototype,function(){function e(e){return typeof e=="object"&&e.bindKey&&e.bindKey.position||(e.isDefault?-100:0)}this.addCommand=function(e){this.commands[e.name]&&this.removeCommand(e),this.commands[e.name]=e,e.bindKey&&this._buildKeyHash(e)},this.removeCommand=function(e,t){var n=e&&(typeof e=="string"?e:e.name);e=this.commands[n],t||delete this.commands[n];var r=this.commandKeyBinding;for(var i in r){var s=r[i];if(s==e)delete r[i];else if(Array.isArray(s)){var o=s.indexOf(e);o!=-1&&(s.splice(o,1),s.length==1&&(r[i]=s[0]))}}},this.bindKey=function(e,t,n){typeof e=="object"&&e&&(n==undefined&&(n=e.position),e=e[this.platform]);if(!e)return;if(typeof t=="function")return this.addCommand({exec:t,bindKey:e,name:t.name||e});e.split("|").forEach(function(e){var r="";if(e.indexOf(" ")!=-1){var i=e.split(/\s+/);e=i.pop(),i.forEach(function(e){var t=this.parseKeys(e),n=s[t.hashId]+t.key;r+=(r?" ":"")+n,this._addCommandToBinding(r,"chainKeys")},this),r+=" "}var o=this.parseKeys(e),u=s[o.hashId]+o.key;this._addCommandToBinding(r+u,t,n)},this)},this._addCommandToBinding=function(t,n,r){var i=this.commandKeyBinding,s;if(!n)delete i[t];else if(!i[t]||this.$singleCommand)i[t]=n;else{Array.isArray(i[t])?(s=i[t].indexOf(n))!=-1&&i[t].splice(s,1):i[t]=[i[t]],typeof r!="number"&&(r=e(n));var o=i[t];for(s=0;s<o.length;s++){var u=o[s],a=e(u);if(a>r)break}o.splice(s,0,n)}},this.addCommands=function(e){e&&Object.keys(e).forEach(function(t){var n=e[t];if(!n)return;if(typeof n=="string")return this.bindKey(n,t);typeof n=="function"&&(n={exec:n});if(typeof n!="object")return;n.name||(n.name=t),this.addCommand(n)},this)},this.removeCommands=function(e){Object.keys(e).forEach(function(t){this.removeCommand(e[t])},this)},this.bindKeys=function(e){Object.keys(e).forEach(function(t){this.bindKey(t,e[t])},this)},this._buildKeyHash=function(e){this.bindKey(e.bindKey,e)},this.parseKeys=function(e){var t=e.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(e){return e}),n=t.pop(),i=r[n];if(r.FUNCTION_KEYS[i])n=r.FUNCTION_KEYS[i].toLowerCase();else{if(!t.length)return{key:n,hashId:-1};if(t.length==1&&t[0]=="shift")return{key:n.toUpperCase(),hashId:-1}}var s=0;for(var o=t.length;o--;){var u=r.KEY_MODS[t[o]];if(u==null)return typeof console!="undefined"&&console.error("invalid modifier "+t[o]+" in "+e),!1;s|=u}return{key:n,hashId:s}},this.findKeyCommand=function(t,n){var r=s[t]+n;return this.commandKeyBinding[r]},this.handleKeyboard=function(e,t,n,r){if(r<0)return;var i=s[t]+n,o=this.commandKeyBinding[i];e.$keyChain&&(e.$keyChain+=" "+i,o=this.commandKeyBinding[e.$keyChain]||o);if(o)if(o=="chainKeys"||o[o.length-1]=="chainKeys")return e.$keyChain=e.$keyChain||i,{command:"null"};if(e.$keyChain)if(!!t&&t!=4||n.length!=1){if(t==-1||r>0)e.$keyChain=""}else e.$keyChain=e.$keyChain.slice(0,-i.length-1);return{command:o}},this.getStatusText=function(e,t){return t.$keyChain||""}}.call(o.prototype),t.HashHandler=o,t.MultiHashHandler=u}),ace.define("ace/commands/command_manager",["require","exports","module","ace/lib/oop","ace/keyboard/hash_handler","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../keyboard/hash_handler").MultiHashHandler,s=e("../lib/event_emitter").EventEmitter,o=function(e,t){i.call(this,t,e),this.byName=this.commands,this.setDefaultHandler("exec",function(e){return e.command.exec(e.editor,e.args||{})})};r.inherits(o,i),function(){r.implement(this,s),this.exec=function(e,t,n){if(Array.isArray(e)){for(var r=e.length;r--;)if(this.exec(e[r],t,n))return!0;return!1}typeof e=="string"&&(e=this.commands[e]);if(!e)return!1;if(t&&t.$readOnly&&!e.readOnly)return!1;if(this.$checkCommandState!=0&&e.isAvailable&&!e.isAvailable(t))return!1;var i={editor:t,command:e,args:n};return i.returnValue=this._emit("exec",i),this._signal("afterExec",i),i.returnValue===!1?!1:!0},this.toggleRecording=function(e){if(this.$inReplay)return;return e&&e._emit("changeStatus"),this.recording?(this.macro.pop(),this.removeEventListener("exec",this.$addCommandToMacro),this.macro.length||(this.macro=this.oldMacro),this.recording=!1):(this.$addCommandToMacro||(this.$addCommandToMacro=function(e){this.macro.push([e.command,e.args])}.bind(this)),this.oldMacro=this.macro,this.macro=[],this.on("exec",this.$addCommandToMacro),this.recording=!0)},this.replay=function(e){if(this.$inReplay||!this.macro)return;if(this.recording)return this.toggleRecording(e);try{this.$inReplay=!0,this.macro.forEach(function(t){typeof t=="string"?this.exec(t,e):this.exec(t[0],e,t[1])},this)}finally{this.$inReplay=!1}},this.trimMacro=function(e){return e.map(function(e){return typeof e[0]!="string"&&(e[0]=e[0].name),e[1]||(e=e[0]),e})}}.call(o.prototype),t.CommandManager=o}),ace.define("ace/commands/default_commands",["require","exports","module","ace/lib/lang","ace/config","ace/range"],function(e,t,n){"use strict";function o(e,t){return{win:e,mac:t}}var r=e("../lib/lang"),i=e("../config"),s=e("../range").Range;t.commands=[{name:"showSettingsMenu",bindKey:o("Ctrl-,","Command-,"),exec:function(e){i.loadModule("ace/ext/settings_menu",function(t){t.init(e),e.showSettingsMenu()})},readOnly:!0},{name:"goToNextError",bindKey:o("Alt-E","F4"),exec:function(e){i.loadModule("./ext/error_marker",function(t){t.showErrorMarker(e,1)})},scrollIntoView:"animate",readOnly:!0},{name:"goToPreviousError",bindKey:o("Alt-Shift-E","Shift-F4"),exec:function(e){i.loadModule("./ext/error_marker",function(t){t.showErrorMarker(e,-1)})},scrollIntoView:"animate",readOnly:!0},{name:"selectall",bindKey:o("Ctrl-A","Command-A"),exec:function(e){e.selectAll()},readOnly:!0},{name:"centerselection",bindKey:o(null,"Ctrl-L"),exec:function(e){e.centerSelection()},readOnly:!0},{name:"gotoline",bindKey:o("Ctrl-L","Command-L"),exec:function(e,t){typeof t!="number"&&(t=parseInt(prompt("Enter line number:"),10)),isNaN(t)||e.gotoLine(t)},readOnly:!0},{name:"fold",bindKey:o("Alt-L|Ctrl-F1","Command-Alt-L|Command-F1"),exec:function(e){e.session.toggleFold(!1)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"unfold",bindKey:o("Alt-Shift-L|Ctrl-Shift-F1","Command-Alt-Shift-L|Command-Shift-F1"),exec:function(e){e.session.toggleFold(!0)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"toggleFoldWidget",bindKey:o("F2","F2"),exec:function(e){e.session.toggleFoldWidget()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"toggleParentFoldWidget",bindKey:o("Alt-F2","Alt-F2"),exec:function(e){e.session.toggleFoldWidget(!0)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"foldall",bindKey:o(null,"Ctrl-Command-Option-0"),exec:function(e){e.session.foldAll()},scrollIntoView:"center",readOnly:!0},{name:"foldOther",bindKey:o("Alt-0","Command-Option-0"),exec:function(e){e.session.foldAll(),e.session.unfold(e.selection.getAllRanges())},scrollIntoView:"center",readOnly:!0},{name:"unfoldall",bindKey:o("Alt-Shift-0","Command-Option-Shift-0"),exec:function(e){e.session.unfold()},scrollIntoView:"center",readOnly:!0},{name:"findnext",bindKey:o("Ctrl-K","Command-G"),exec:function(e){e.findNext()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"findprevious",bindKey:o("Ctrl-Shift-K","Command-Shift-G"),exec:function(e){e.findPrevious()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"selectOrFindNext",bindKey:o("Alt-K","Ctrl-G"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findNext()},readOnly:!0},{name:"selectOrFindPrevious",bindKey:o("Alt-Shift-K","Ctrl-Shift-G"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findPrevious()},readOnly:!0},{name:"find",bindKey:o("Ctrl-F","Command-F"),exec:function(e){i.loadModule("ace/ext/searchbox",function(t){t.Search(e)})},readOnly:!0},{name:"overwrite",bindKey:"Insert",exec:function(e){e.toggleOverwrite()},readOnly:!0},{name:"selecttostart",bindKey:o("Ctrl-Shift-Home","Command-Shift-Home|Command-Shift-Up"),exec:function(e){e.getSelection().selectFileStart()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"gotostart",bindKey:o("Ctrl-Home","Command-Home|Command-Up"),exec:function(e){e.navigateFileStart()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"selectup",bindKey:o("Shift-Up","Shift-Up|Ctrl-Shift-P"),exec:function(e){e.getSelection().selectUp()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"golineup",bindKey:o("Up","Up|Ctrl-P"),exec:function(e,t){e.navigateUp(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttoend",bindKey:o("Ctrl-Shift-End","Command-Shift-End|Command-Shift-Down"),exec:function(e){e.getSelection().selectFileEnd()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"gotoend",bindKey:o("Ctrl-End","Command-End|Command-Down"),exec:function(e){e.navigateFileEnd()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"selectdown",bindKey:o("Shift-Down","Shift-Down|Ctrl-Shift-N"),exec:function(e){e.getSelection().selectDown()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"golinedown",bindKey:o("Down","Down|Ctrl-N"),exec:function(e,t){e.navigateDown(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectwordleft",bindKey:o("Ctrl-Shift-Left","Option-Shift-Left"),exec:function(e){e.getSelection().selectWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotowordleft",bindKey:o("Ctrl-Left","Option-Left"),exec:function(e){e.navigateWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttolinestart",bindKey:o("Alt-Shift-Left","Command-Shift-Left|Ctrl-Shift-A"),exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotolinestart",bindKey:o("Alt-Left|Home","Command-Left|Home|Ctrl-A"),exec:function(e){e.navigateLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectleft",bindKey:o("Shift-Left","Shift-Left|Ctrl-Shift-B"),exec:function(e){e.getSelection().selectLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotoleft",bindKey:o("Left","Left|Ctrl-B"),exec:function(e,t){e.navigateLeft(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectwordright",bindKey:o("Ctrl-Shift-Right","Option-Shift-Right"),exec:function(e){e.getSelection().selectWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotowordright",bindKey:o("Ctrl-Right","Option-Right"),exec:function(e){e.navigateWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttolineend",bindKey:o("Alt-Shift-Right","Command-Shift-Right|Shift-End|Ctrl-Shift-E"),exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotolineend",bindKey:o("Alt-Right|End","Command-Right|End|Ctrl-E"),exec:function(e){e.navigateLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectright",bindKey:o("Shift-Right","Shift-Right"),exec:function(e){e.getSelection().selectRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotoright",bindKey:o("Right","Right|Ctrl-F"),exec:function(e,t){e.navigateRight(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectpagedown",bindKey:"Shift-PageDown",exec:function(e){e.selectPageDown()},readOnly:!0},{name:"pagedown",bindKey:o(null,"Option-PageDown"),exec:function(e){e.scrollPageDown()},readOnly:!0},{name:"gotopagedown",bindKey:o("PageDown","PageDown|Ctrl-V"),exec:function(e){e.gotoPageDown()},readOnly:!0},{name:"selectpageup",bindKey:"Shift-PageUp",exec:function(e){e.selectPageUp()},readOnly:!0},{name:"pageup",bindKey:o(null,"Option-PageUp"),exec:function(e){e.scrollPageUp()},readOnly:!0},{name:"gotopageup",bindKey:"PageUp",exec:function(e){e.gotoPageUp()},readOnly:!0},{name:"scrollup",bindKey:o("Ctrl-Up",null),exec:function(e){e.renderer.scrollBy(0,-2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:"scrolldown",bindKey:o("Ctrl-Down",null),exec:function(e){e.renderer.scrollBy(0,2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:"selectlinestart",bindKey:"Shift-Home",exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectlineend",bindKey:"Shift-End",exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"togglerecording",bindKey:o("Ctrl-Alt-E","Command-Option-E"),exec:function(e){e.commands.toggleRecording(e)},readOnly:!0},{name:"replaymacro",bindKey:o("Ctrl-Shift-E","Command-Shift-E"),exec:function(e){e.commands.replay(e)},readOnly:!0},{name:"jumptomatching",bindKey:o("Ctrl-P","Ctrl-P"),exec:function(e){e.jumpToMatching()},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"selecttomatching",bindKey:o("Ctrl-Shift-P","Ctrl-Shift-P"),exec:function(e){e.jumpToMatching(!0)},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"expandToMatching",bindKey:o("Ctrl-Shift-M","Ctrl-Shift-M"),exec:function(e){e.jumpToMatching(!0,!0)},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"passKeysToBrowser",bindKey:o(null,null),exec:function(){},passEvent:!0,readOnly:!0},{name:"copy",exec:function(e){},readOnly:!0},{name:"cut",exec:function(e){var t=e.$copyWithEmptySelection&&e.selection.isEmpty(),n=t?e.selection.getLineRange():e.selection.getRange();e._emit("cut",n),n.isEmpty()||e.session.remove(n),e.clearSelection()},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"paste",exec:function(e,t){e.$handlePaste(t)},scrollIntoView:"cursor"},{name:"removeline",bindKey:o("Ctrl-D","Command-D"),exec:function(e){e.removeLines()},scrollIntoView:"cursor",multiSelectAction:"forEachLine"},{name:"duplicateSelection",bindKey:o("Ctrl-Shift-D","Command-Shift-D"),exec:function(e){e.duplicateSelection()},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"sortlines",bindKey:o("Ctrl-Alt-S","Command-Alt-S"),exec:function(e){e.sortLines()},scrollIntoView:"selection",multiSelectAction:"forEachLine"},{name:"togglecomment",bindKey:o("Ctrl-/","Command-/"),exec:function(e){e.toggleCommentLines()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"toggleBlockComment",bindKey:o("Ctrl-Shift-/","Command-Shift-/"),exec:function(e){e.toggleBlockComment()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"modifyNumberUp",bindKey:o("Ctrl-Shift-Up","Alt-Shift-Up"),exec:function(e){e.modifyNumber(1)},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"modifyNumberDown",bindKey:o("Ctrl-Shift-Down","Alt-Shift-Down"),exec:function(e){e.modifyNumber(-1)},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"replace",bindKey:o("Ctrl-H","Command-Option-F"),exec:function(e){i.loadModule("ace/ext/searchbox",function(t){t.Search(e,!0)})}},{name:"undo",bindKey:o("Ctrl-Z","Command-Z"),exec:function(e){e.undo()}},{name:"redo",bindKey:o("Ctrl-Shift-Z|Ctrl-Y","Command-Shift-Z|Command-Y"),exec:function(e){e.redo()}},{name:"copylinesup",bindKey:o("Alt-Shift-Up","Command-Option-Up"),exec:function(e){e.copyLinesUp()},scrollIntoView:"cursor"},{name:"movelinesup",bindKey:o("Alt-Up","Option-Up"),exec:function(e){e.moveLinesUp()},scrollIntoView:"cursor"},{name:"copylinesdown",bindKey:o("Alt-Shift-Down","Command-Option-Down"),exec:function(e){e.copyLinesDown()},scrollIntoView:"cursor"},{name:"movelinesdown",bindKey:o("Alt-Down","Option-Down"),exec:function(e){e.moveLinesDown()},scrollIntoView:"cursor"},{name:"del",bindKey:o("Delete","Delete|Ctrl-D|Shift-Delete"),exec:function(e){e.remove("right")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"backspace",bindKey:o("Shift-Backspace|Backspace","Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H"),exec:function(e){e.remove("left")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"cut_or_delete",bindKey:o("Shift-Delete",null),exec:function(e){if(!e.selection.isEmpty())return!1;e.remove("left")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolinestart",bindKey:o("Alt-Backspace","Command-Backspace"),exec:function(e){e.removeToLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolineend",bindKey:o("Alt-Delete","Ctrl-K|Command-Delete"),exec:function(e){e.removeToLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolinestarthard",bindKey:o("Ctrl-Shift-Backspace",null),exec:function(e){var t=e.selection.getRange();t.start.column=0,e.session.remove(t)},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolineendhard",bindKey:o("Ctrl-Shift-Delete",null),exec:function(e){var t=e.selection.getRange();t.end.column=Number.MAX_VALUE,e.session.remove(t)},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removewordleft",bindKey:o("Ctrl-Backspace","Alt-Backspace|Ctrl-Alt-Backspace"),exec:function(e){e.removeWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removewordright",bindKey:o("Ctrl-Delete","Alt-Delete"),exec:function(e){e.removeWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"outdent",bindKey:o("Shift-Tab","Shift-Tab"),exec:function(e){e.blockOutdent()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"indent",bindKey:o("Tab","Tab"),exec:function(e){e.indent()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"blockoutdent",bindKey:o("Ctrl-[","Ctrl-["),exec:function(e){e.blockOutdent()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"blockindent",bindKey:o("Ctrl-]","Ctrl-]"),exec:function(e){e.blockIndent()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"insertstring",exec:function(e,t){e.insert(t)},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"inserttext",exec:function(e,t){e.insert(r.stringRepeat(t.text||"",t.times||1))},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"splitline",bindKey:o(null,"Ctrl-O"),exec:function(e){e.splitLine()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"transposeletters",bindKey:o("Alt-Shift-X","Ctrl-T"),exec:function(e){e.transposeLetters()},multiSelectAction:function(e){e.transposeSelections(1)},scrollIntoView:"cursor"},{name:"touppercase",bindKey:o("Ctrl-U","Ctrl-U"),exec:function(e){e.toUpperCase()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"tolowercase",bindKey:o("Ctrl-Shift-U","Ctrl-Shift-U"),exec:function(e){e.toLowerCase()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"expandtoline",bindKey:o("Ctrl-Shift-L","Command-Shift-L"),exec:function(e){var t=e.selection.getRange();t.start.column=t.end.column=0,t.end.row++,e.selection.setRange(t,!1)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"joinlines",bindKey:o(null,null),exec:function(e){var t=e.selection.isBackwards(),n=t?e.selection.getSelectionLead():e.selection.getSelectionAnchor(),i=t?e.selection.getSelectionAnchor():e.selection.getSelectionLead(),o=e.session.doc.getLine(n.row).length,u=e.session.doc.getTextRange(e.selection.getRange()),a=u.replace(/\n\s*/," ").length,f=e.session.doc.getLine(n.row);for(var l=n.row+1;l<=i.row+1;l++){var c=r.stringTrimLeft(r.stringTrimRight(e.session.doc.getLine(l)));c.length!==0&&(c=" "+c),f+=c}i.row+1<e.session.doc.getLength()-1&&(f+=e.session.doc.getNewLineCharacter()),e.clearSelection(),e.session.doc.replace(new s(n.row,0,i.row+2,0),f),a>0?(e.selection.moveCursorTo(n.row,n.column),e.selection.selectTo(n.row,n.column+a)):(o=e.session.doc.getLine(n.row).length>o?o+1:o,e.selection.moveCursorTo(n.row,o))},multiSelectAction:"forEach",readOnly:!0},{name:"invertSelection",bindKey:o(null,null),exec:function(e){var t=e.session.doc.getLength()-1,n=e.session.doc.getLine(t).length,r=e.selection.rangeList.ranges,i=[];r.length<1&&(r=[e.selection.getRange()]);for(var o=0;o<r.length;o++)o==r.length-1&&(r[o].end.row!==t||r[o].end.column!==n)&&i.push(new s(r[o].end.row,r[o].end.column,t,n)),o===0?(r[o].start.row!==0||r[o].start.column!==0)&&i.push(new s(0,0,r[o].start.row,r[o].start.column)):i.push(new s(r[o-1].end.row,r[o-1].end.column,r[o].start.row,r[o].start.column));e.exitMultiSelectMode(),e.clearSelection();for(var o=0;o<i.length;o++)e.selection.addRange(i[o],!1)},readOnly:!0,scrollIntoView:"none"}]}),ace.define("ace/clipboard",["require","exports","module"],function(e,t,n){"use strict";n.exports={lineMode:!1}}),ace.define("ace/editor",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/keyboard/textinput","ace/mouse/mouse_handler","ace/mouse/fold_handler","ace/keyboard/keybinding","ace/edit_session","ace/search","ace/range","ace/lib/event_emitter","ace/commands/command_manager","ace/commands/default_commands","ace/config","ace/token_iterator","ace/clipboard"],function(e,t,n){"use strict";e("./lib/fixoldbrowsers");var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./lib/lang"),o=e("./lib/useragent"),u=e("./keyboard/textinput").TextInput,a=e("./mouse/mouse_handler").MouseHandler,f=e("./mouse/fold_handler").FoldHandler,l=e("./keyboard/keybinding").KeyBinding,c=e("./edit_session").EditSession,h=e("./search").Search,p=e("./range").Range,d=e("./lib/event_emitter").EventEmitter,v=e("./commands/command_manager").CommandManager,m=e("./commands/default_commands").commands,g=e("./config"),y=e("./token_iterator").TokenIterator,b=e("./clipboard"),w=function(e,t,n){var r=e.getContainerElement();this.container=r,this.renderer=e,this.id="editor"+ ++w.$uid,this.commands=new v(o.isMac?"mac":"win",m),typeof document=="object"&&(this.textInput=new u(e.getTextAreaContainer(),this),this.renderer.textarea=this.textInput.getElement(),this.$mouseHandler=new a(this),new f(this)),this.keyBinding=new l(this),this.$search=(new h).set({wrap:!0}),this.$historyTracker=this.$historyTracker.bind(this),this.commands.on("exec",this.$historyTracker),this.$initOperationListeners(),this._$emitInputEvent=s.delayedCall(function(){this._signal("input",{}),this.session&&this.session.bgTokenizer&&this.session.bgTokenizer.scheduleStart()}.bind(this)),this.on("change",function(e,t){t._$emitInputEvent.schedule(31)}),this.setSession(t||n&&n.session||new c("")),g.resetOptions(this),n&&this.setOptions(n),g._signal("editor",this)};w.$uid=0,function(){r.implement(this,d),this.$initOperationListeners=function(){this.commands.on("exec",this.startOperation.bind(this),!0),this.commands.on("afterExec",this.endOperation.bind(this),!0),this.$opResetTimer=s.delayedCall(this.endOperation.bind(this,!0)),this.on("change",function(){this.curOp||(this.startOperation(),this.curOp.selectionBefore=this.$lastSel),this.curOp.docChanged=!0}.bind(this),!0),this.on("changeSelection",function(){this.curOp||(this.startOperation(),this.curOp.selectionBefore=this.$lastSel),this.curOp.selectionChanged=!0}.bind(this),!0)},this.curOp=null,this.prevOp={},this.startOperation=function(e){if(this.curOp){if(!e||this.curOp.command)return;this.prevOp=this.curOp}e||(this.previousCommand=null,e={}),this.$opResetTimer.schedule(),this.curOp=this.session.curOp={command:e.command||{},args:e.args,scrollTop:this.renderer.scrollTop},this.curOp.selectionBefore=this.selection.toJSON()},this.endOperation=function(e){if(this.curOp){if(e&&e.returnValue===!1)return this.curOp=null;if(e==1&&this.curOp.command&&this.curOp.command.name=="mouse")return;this._signal("beforeEndOperation");if(!this.curOp)return;var t=this.curOp.command,n=t&&t.scrollIntoView;if(n){switch(n){case"center-animate":n="animate";case"center":this.renderer.scrollCursorIntoView(null,.5);break;case"animate":case"cursor":this.renderer.scrollCursorIntoView();break;case"selectionPart":var r=this.selection.getRange(),i=this.renderer.layerConfig;(r.start.row>=i.lastRow||r.end.row<=i.firstRow)&&this.renderer.scrollSelectionIntoView(this.selection.anchor,this.selection.lead);break;default:}n=="animate"&&this.renderer.animateScrolling(this.curOp.scrollTop)}var s=this.selection.toJSON();this.curOp.selectionAfter=s,this.$lastSel=this.selection.toJSON(),this.session.getUndoManager().addSelection(s),this.prevOp=this.curOp,this.curOp=null}},this.$mergeableCommands=["backspace","del","insertstring"],this.$historyTracker=function(e){if(!this.$mergeUndoDeltas)return;var t=this.prevOp,n=this.$mergeableCommands,r=t.command&&e.command.name==t.command.name;if(e.command.name=="insertstring"){var i=e.args;this.mergeNextCommand===undefined&&(this.mergeNextCommand=!0),r=r&&this.mergeNextCommand&&(!/\s/.test(i)||/\s/.test(t.args)),this.mergeNextCommand=!0}else r=r&&n.indexOf(e.command.name)!==-1;this.$mergeUndoDeltas!="always"&&Date.now()-this.sequenceStartTime>2e3&&(r=!1),r?this.session.mergeUndoDeltas=!0:n.indexOf(e.command.name)!==-1&&(this.sequenceStartTime=Date.now())},this.setKeyboardHandler=function(e,t){if(e&&typeof e=="string"&&e!="ace"){this.$keybindingId=e;var n=this;g.loadModule(["keybinding",e],function(r){n.$keybindingId==e&&n.keyBinding.setKeyboardHandler(r&&r.handler),t&&t()})}else this.$keybindingId=null,this.keyBinding.setKeyboardHandler(e),t&&t()},this.getKeyboardHandler=function(){return this.keyBinding.getKeyboardHandler()},this.setSession=function(e){if(this.session==e)return;this.curOp&&this.endOperation(),this.curOp={};var t=this.session;if(t){this.session.off("change",this.$onDocumentChange),this.session.off("changeMode",this.$onChangeMode),this.session.off("tokenizerUpdate",this.$onTokenizerUpdate),this.session.off("changeTabSize",this.$onChangeTabSize),this.session.off("changeWrapLimit",this.$onChangeWrapLimit),this.session.off("changeWrapMode",this.$onChangeWrapMode),this.session.off("changeFold",this.$onChangeFold),this.session.off("changeFrontMarker",this.$onChangeFrontMarker),this.session.off("changeBackMarker",this.$onChangeBackMarker),this.session.off("changeBreakpoint",this.$onChangeBreakpoint),this.session.off("changeAnnotation",this.$onChangeAnnotation),this.session.off("changeOverwrite",this.$onCursorChange),this.session.off("changeScrollTop",this.$onScrollTopChange),this.session.off("changeScrollLeft",this.$onScrollLeftChange);var n=this.session.getSelection();n.off("changeCursor",this.$onCursorChange),n.off("changeSelection",this.$onSelectionChange)}this.session=e,e?(this.$onDocumentChange=this.onDocumentChange.bind(this),e.on("change",this.$onDocumentChange),this.renderer.setSession(e),this.$onChangeMode=this.onChangeMode.bind(this),e.on("changeMode",this.$onChangeMode),this.$onTokenizerUpdate=this.onTokenizerUpdate.bind(this),e.on("tokenizerUpdate",this.$onTokenizerUpdate),this.$onChangeTabSize=this.renderer.onChangeTabSize.bind(this.renderer),e.on("changeTabSize",this.$onChangeTabSize),this.$onChangeWrapLimit=this.onChangeWrapLimit.bind(this),e.on("changeWrapLimit",this.$onChangeWrapLimit),this.$onChangeWrapMode=this.onChangeWrapMode.bind(this),e.on("changeWrapMode",this.$onChangeWrapMode),this.$onChangeFold=this.onChangeFold.bind(this),e.on("changeFold",this.$onChangeFold),this.$onChangeFrontMarker=this.onChangeFrontMarker.bind(this),this.session.on("changeFrontMarker",this.$onChangeFrontMarker),this.$onChangeBackMarker=this.onChangeBackMarker.bind(this),this.session.on("changeBackMarker",this.$onChangeBackMarker),this.$onChangeBreakpoint=this.onChangeBreakpoint.bind(this),this.session.on("changeBreakpoint",this.$onChangeBreakpoint),this.$onChangeAnnotation=this.onChangeAnnotation.bind(this),this.session.on("changeAnnotation",this.$onChangeAnnotation),this.$onCursorChange=this.onCursorChange.bind(this),this.session.on("changeOverwrite",this.$onCursorChange),this.$onScrollTopChange=this.onScrollTopChange.bind(this),this.session.on("changeScrollTop",this.$onScrollTopChange),this.$onScrollLeftChange=this.onScrollLeftChange.bind(this),this.session.on("changeScrollLeft",this.$onScrollLeftChange),this.selection=e.getSelection(),this.selection.on("changeCursor",this.$onCursorChange),this.$onSelectionChange=this.onSelectionChange.bind(this),this.selection.on("changeSelection",this.$onSelectionChange),this.onChangeMode(),this.onCursorChange(),this.onScrollTopChange(),this.onScrollLeftChange(),this.onSelectionChange(),this.onChangeFrontMarker(),this.onChangeBackMarker(),this.onChangeBreakpoint(),this.onChangeAnnotation(),this.session.getUseWrapMode()&&this.renderer.adjustWrapLimit(),this.renderer.updateFull()):(this.selection=null,this.renderer.setSession(e)),this._signal("changeSession",{session:e,oldSession:t}),this.curOp=null,t&&t._signal("changeEditor",{oldEditor:this}),e&&e._signal("changeEditor",{editor:this}),e&&e.bgTokenizer&&e.bgTokenizer.scheduleStart()},this.getSession=function(){return this.session},this.setValue=function(e,t){return this.session.doc.setValue(e),t?t==1?this.navigateFileEnd():t==-1&&this.navigateFileStart():this.selectAll(),e},this.getValue=function(){return this.session.getValue()},this.getSelection=function(){return this.selection},this.resize=function(e){this.renderer.onResize(e)},this.setTheme=function(e,t){this.renderer.setTheme(e,t)},this.getTheme=function(){return this.renderer.getTheme()},this.setStyle=function(e){this.renderer.setStyle(e)},this.unsetStyle=function(e){this.renderer.unsetStyle(e)},this.getFontSize=function(){return this.getOption("fontSize")||i.computedStyle(this.container).fontSize},this.setFontSize=function(e){this.setOption("fontSize",e)},this.$highlightBrackets=function(){this.session.$bracketHighlight&&(this.session.removeMarker(this.session.$bracketHighlight),this.session.$bracketHighlight=null);if(this.$highlightPending)return;var e=this;this.$highlightPending=!0,setTimeout(function(){e.$highlightPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=t.findMatchingBracket(e.getCursorPosition());if(n)var r=new p(n.row,n.column,n.row,n.column+1);else if(t.$mode.getMatching)var r=t.$mode.getMatching(e.session);r&&(t.$bracketHighlight=t.addMarker(r,"ace_bracket","text"))},50)},this.$highlightTags=function(){if(this.$highlightTagPending)return;var e=this;this.$highlightTagPending=!0,setTimeout(function(){e.$highlightTagPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=e.getCursorPosition(),r=new y(e.session,n.row,n.column),i=r.getCurrentToken();if(!i||!/\b(?:tag-open|tag-name)/.test(i.type)){t.removeMarker(t.$tagHighlight),t.$tagHighlight=null;return}if(i.type.indexOf("tag-open")!=-1){i=r.stepForward();if(!i)return}var s=i.value,o=0,u=r.stepBackward();if(u.value=="<"){do u=i,i=r.stepForward(),i&&i.value===s&&i.type.indexOf("tag-name")!==-1&&(u.value==="<"?o++:u.value==="</"&&o--);while(i&&o>=0)}else{do i=u,u=r.stepBackward(),i&&i.value===s&&i.type.indexOf("tag-name")!==-1&&(u.value==="<"?o++:u.value==="</"&&o--);while(u&&o<=0);r.stepForward()}if(!i){t.removeMarker(t.$tagHighlight),t.$tagHighlight=null;return}var a=r.getCurrentTokenRow(),f=r.getCurrentTokenColumn(),l=new p(a,f,a,f+i.value.length),c=t.$backMarkers[t.$tagHighlight];t.$tagHighlight&&c!=undefined&&l.compareRange(c.range)!==0&&(t.removeMarker(t.$tagHighlight),t.$tagHighlight=null),t.$tagHighlight||(t.$tagHighlight=t.addMarker(l,"ace_bracket","text"))},50)},this.focus=function(){var e=this;setTimeout(function(){e.isFocused()||e.textInput.focus()}),this.textInput.focus()},this.isFocused=function(){return this.textInput.isFocused()},this.blur=function(){this.textInput.blur()},this.onFocus=function(e){if(this.$isFocused)return;this.$isFocused=!0,this.renderer.showCursor(),this.renderer.visualizeFocus(),this._emit("focus",e)},this.onBlur=function(e){if(!this.$isFocused)return;this.$isFocused=!1,this.renderer.hideCursor(),this.renderer.visualizeBlur(),this._emit("blur",e)},this.$cursorChange=function(){this.renderer.updateCursor()},this.onDocumentChange=function(e){var t=this.session.$useWrapMode,n=e.start.row==e.end.row?e.end.row:Infinity;this.renderer.updateLines(e.start.row,n,t),this._signal("change",e),this.$cursorChange(),this.$updateHighlightActiveLine()},this.onTokenizerUpdate=function(e){var t=e.data;this.renderer.updateLines(t.first,t.last)},this.onScrollTopChange=function(){this.renderer.scrollToY(this.session.getScrollTop())},this.onScrollLeftChange=function(){this.renderer.scrollToX(this.session.getScrollLeft())},this.onCursorChange=function(){this.$cursorChange(),this.$highlightBrackets(),this.$highlightTags(),this.$updateHighlightActiveLine(),this._signal("changeSelection")},this.$updateHighlightActiveLine=function(){var e=this.getSession(),t;if(this.$highlightActiveLine){if(this.$selectionStyle!="line"||!this.selection.isMultiLine())t=this.getCursorPosition();this.renderer.theme&&this.renderer.theme.$selectionColorConflict&&!this.selection.isEmpty()&&(t=!1),this.renderer.$maxLines&&this.session.getLength()===1&&!(this.renderer.$minLines>1)&&(t=!1)}if(e.$highlightLineMarker&&!t)e.removeMarker(e.$highlightLineMarker.id),e.$highlightLineMarker=null;else if(!e.$highlightLineMarker&&t){var n=new p(t.row,t.column,t.row,Infinity);n.id=e.addMarker(n,"ace_active-line","screenLine"),e.$highlightLineMarker=n}else t&&(e.$highlightLineMarker.start.row=t.row,e.$highlightLineMarker.end.row=t.row,e.$highlightLineMarker.start.column=t.column,e._signal("changeBackMarker"))},this.onSelectionChange=function(e){var t=this.session;t.$selectionMarker&&t.removeMarker(t.$selectionMarker),t.$selectionMarker=null;if(!this.selection.isEmpty()){var n=this.selection.getRange(),r=this.getSelectionStyle();t.$selectionMarker=t.addMarker(n,"ace_selection",r)}else this.$updateHighlightActiveLine();var i=this.$highlightSelectedWord&&this.$getSelectionHighLightRegexp();this.session.highlight(i),this._signal("changeSelection")},this.$getSelectionHighLightRegexp=function(){var e=this.session,t=this.getSelectionRange();if(t.isEmpty()||t.isMultiLine())return;var n=t.start.column,r=t.end.column,i=e.getLine(t.start.row),s=i.substring(n,r);if(s.length>5e3||!/[\w\d]/.test(s))return;var o=this.$search.$assembleRegExp({wholeWord:!0,caseSensitive:!0,needle:s}),u=i.substring(n-1,r+1);if(!o.test(u))return;return o},this.onChangeFrontMarker=function(){this.renderer.updateFrontMarkers()},this.onChangeBackMarker=function(){this.renderer.updateBackMarkers()},this.onChangeBreakpoint=function(){this.renderer.updateBreakpoints()},this.onChangeAnnotation=function(){this.renderer.setAnnotations(this.session.getAnnotations())},this.onChangeMode=function(e){this.renderer.updateText(),this._emit("changeMode",e)},this.onChangeWrapLimit=function(){this.renderer.updateFull()},this.onChangeWrapMode=function(){this.renderer.onResize(!0)},this.onChangeFold=function(){this.$updateHighlightActiveLine(),this.renderer.updateFull()},this.getSelectedText=function(){return this.session.getTextRange(this.getSelectionRange())},this.getCopyText=function(){var e=this.getSelectedText(),t=this.session.doc.getNewLineCharacter(),n=!1;if(!e&&this.$copyWithEmptySelection){n=!0;var r=this.selection.getAllRanges();for(var i=0;i<r.length;i++){var s=r[i];if(i&&r[i-1].start.row==s.start.row)continue;e+=this.session.getLine(s.start.row)+t}}var o={text:e};return this._signal("copy",o),b.lineMode=n?o.text:"",o.text},this.onCopy=function(){this.commands.exec("copy",this)},this.onCut=function(){this.commands.exec("cut",this)},this.onPaste=function(e,t){var n={text:e,event:t};this.commands.exec("paste",this,n)},this.$handlePaste=function(e){typeof e=="string"&&(e={text:e}),this._signal("paste",e);var t=e.text,n=t==b.lineMode,r=this.session;if(!this.inMultiSelectMode||this.inVirtualSelectionMode)n?r.insert({row:this.selection.lead.row,column:0},t):this.insert(t);else if(n)this.selection.rangeList.ranges.forEach(function(e){r.insert({row:e.start.row,column:0},t)});else{var i=t.split(/\r\n|\r|\n/),s=this.selection.rangeList.ranges;if(i.length>s.length||i.length<2||!i[1])return this.commands.exec("insertstring",this,t);for(var o=s.length;o--;){var u=s[o];u.isEmpty()||r.remove(u),r.insert(u.start,i[o])}}},this.execCommand=function(e,t){return this.commands.exec(e,this,t)},this.insert=function(e,t){var n=this.session,r=n.getMode(),i=this.getCursorPosition();if(this.getBehavioursEnabled()&&!t){var s=r.transformAction(n.getState(i.row),"insertion",this,n,e);s&&(e!==s.text&&(this.inVirtualSelectionMode||(this.session.mergeUndoDeltas=!1,this.mergeNextCommand=!1)),e=s.text)}e==" "&&(e=this.session.getTabString());if(!this.selection.isEmpty()){var o=this.getSelectionRange();i=this.session.remove(o),this.clearSelection()}else if(this.session.getOverwrite()&&e.indexOf("\n")==-1){var o=new p.fromPoints(i,i);o.end.column+=e.length,this.session.remove(o)}if(e=="\n"||e=="\r\n"){var u=n.getLine(i.row);if(i.column>u.search(/\S|$/)){var a=u.substr(i.column).search(/\S|$/);n.doc.removeInLine(i.row,i.column,i.column+a)}}this.clearSelection();var f=i.column,l=n.getState(i.row),u=n.getLine(i.row),c=r.checkOutdent(l,u,e),h=n.insert(i,e);s&&s.selection&&(s.selection.length==2?this.selection.setSelectionRange(new p(i.row,f+s.selection[0],i.row,f+s.selection[1])):this.selection.setSelectionRange(new p(i.row+s.selection[0],s.selection[1],i.row+s.selection[2],s.selection[3])));if(n.getDocument().isNewLine(e)){var d=r.getNextLineIndent(l,u.slice(0,i.column),n.getTabString());n.insert({row:i.row+1,column:0},d)}c&&r.autoOutdent(l,n,i.row)},this.onTextInput=function(e,t){if(!t)return this.keyBinding.onTextInput(e);this.startOperation({command:{name:"insertstring"}});var n=this.applyComposition.bind(this,e,t);this.selection.rangeCount?this.forEachSelection(n):n(),this.endOperation()},this.applyComposition=function(e,t){if(t.extendLeft||t.extendRight){var n=this.selection.getRange();n.start.column-=t.extendLeft,n.end.column+=t.extendRight,this.selection.setRange(n),!e&&!n.isEmpty()&&this.remove()}(e||!this.selection.isEmpty())&&this.insert(e,!0);if(t.restoreStart||t.restoreEnd){var n=this.selection.getRange();n.start.column-=t.restoreStart,n.end.column-=t.restoreEnd,this.selection.setRange(n)}},this.onCommandKey=function(e,t,n){this.keyBinding.onCommandKey(e,t,n)},this.setOverwrite=function(e){this.session.setOverwrite(e)},this.getOverwrite=function(){return this.session.getOverwrite()},this.toggleOverwrite=function(){this.session.toggleOverwrite()},this.setScrollSpeed=function(e){this.setOption("scrollSpeed",e)},this.getScrollSpeed=function(){return this.getOption("scrollSpeed")},this.setDragDelay=function(e){this.setOption("dragDelay",e)},this.getDragDelay=function(){return this.getOption("dragDelay")},this.setSelectionStyle=function(e){this.setOption("selectionStyle",e)},this.getSelectionStyle=function(){return this.getOption("selectionStyle")},this.setHighlightActiveLine=function(e){this.setOption("highlightActiveLine",e)},this.getHighlightActiveLine=function(){return this.getOption("highlightActiveLine")},this.setHighlightGutterLine=function(e){this.setOption("highlightGutterLine",e)},this.getHighlightGutterLine=function(){return this.getOption("highlightGutterLine")},this.setHighlightSelectedWord=function(e){this.setOption("highlightSelectedWord",e)},this.getHighlightSelectedWord=function(){return this.$highlightSelectedWord},this.setAnimatedScroll=function(e){this.renderer.setAnimatedScroll(e)},this.getAnimatedScroll=function(){return this.renderer.getAnimatedScroll()},this.setShowInvisibles=function(e){this.renderer.setShowInvisibles(e)},this.getShowInvisibles=function(){return this.renderer.getShowInvisibles()},this.setDisplayIndentGuides=function(e){this.renderer.setDisplayIndentGuides(e)},this.getDisplayIndentGuides=function(){return this.renderer.getDisplayIndentGuides()},this.setShowPrintMargin=function(e){this.renderer.setShowPrintMargin(e)},this.getShowPrintMargin=function(){return this.renderer.getShowPrintMargin()},this.setPrintMarginColumn=function(e){this.renderer.setPrintMarginColumn(e)},this.getPrintMarginColumn=function(){return this.renderer.getPrintMarginColumn()},this.setReadOnly=function(e){this.setOption("readOnly",e)},this.getReadOnly=function(){return this.getOption("readOnly")},this.setBehavioursEnabled=function(e){this.setOption("behavioursEnabled",e)},this.getBehavioursEnabled=function(){return this.getOption("behavioursEnabled")},this.setWrapBehavioursEnabled=function(e){this.setOption("wrapBehavioursEnabled",e)},this.getWrapBehavioursEnabled=function(){return this.getOption("wrapBehavioursEnabled")},this.setShowFoldWidgets=function(e){this.setOption("showFoldWidgets",e)},this.getShowFoldWidgets=function(){return this.getOption("showFoldWidgets")},this.setFadeFoldWidgets=function(e){this.setOption("fadeFoldWidgets",e)},this.getFadeFoldWidgets=function(){return this.getOption("fadeFoldWidgets")},this.remove=function(e){this.selection.isEmpty()&&(e=="left"?this.selection.selectLeft():this.selection.selectRight());var t=this.getSelectionRange();if(this.getBehavioursEnabled()){var n=this.session,r=n.getState(t.start.row),i=n.getMode().transformAction(r,"deletion",this,n,t);if(t.end.column===0){var s=n.getTextRange(t);if(s[s.length-1]=="\n"){var o=n.getLine(t.end.row);/^\s+$/.test(o)&&(t.end.column=o.length)}}i&&(t=i)}this.session.remove(t),this.clearSelection()},this.removeWordRight=function(){this.selection.isEmpty()&&this.selection.selectWordRight(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeWordLeft=function(){this.selection.isEmpty()&&this.selection.selectWordLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineStart=function(){this.selection.isEmpty()&&this.selection.selectLineStart(),this.selection.isEmpty()&&this.selection.selectLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineEnd=function(){this.selection.isEmpty()&&this.selection.selectLineEnd();var e=this.getSelectionRange();e.start.column==e.end.column&&e.start.row==e.end.row&&(e.end.column=0,e.end.row++),this.session.remove(e),this.clearSelection()},this.splitLine=function(){this.selection.isEmpty()||(this.session.remove(this.getSelectionRange()),this.clearSelection());var e=this.getCursorPosition();this.insert("\n"),this.moveCursorToPosition(e)},this.transposeLetters=function(){if(!this.selection.isEmpty())return;var e=this.getCursorPosition(),t=e.column;if(t===0)return;var n=this.session.getLine(e.row),r,i;t<n.length?(r=n.charAt(t)+n.charAt(t-1),i=new p(e.row,t-1,e.row,t+1)):(r=n.charAt(t-1)+n.charAt(t-2),i=new p(e.row,t-2,e.row,t)),this.session.replace(i,r),this.session.selection.moveToPosition(i.end)},this.toLowerCase=function(){var e=this.getSelectionRange();this.selection.isEmpty()&&this.selection.selectWord();var t=this.getSelectionRange(),n=this.session.getTextRange(t);this.session.replace(t,n.toLowerCase()),this.selection.setSelectionRange(e)},this.toUpperCase=function(){var e=this.getSelectionRange();this.selection.isEmpty()&&this.selection.selectWord();var t=this.getSelectionRange(),n=this.session.getTextRange(t);this.session.replace(t,n.toUpperCase()),this.selection.setSelectionRange(e)},this.indent=function(){var e=this.session,t=this.getSelectionRange();if(t.start.row<t.end.row){var n=this.$getSelectedRows();e.indentRows(n.first,n.last," ");return}if(t.start.column<t.end.column){var r=e.getTextRange(t);if(!/^\s+$/.test(r)){var n=this.$getSelectedRows();e.indentRows(n.first,n.last," ");return}}var i=e.getLine(t.start.row),o=t.start,u=e.getTabSize(),a=e.documentToScreenColumn(o.row,o.column);if(this.session.getUseSoftTabs())var f=u-a%u,l=s.stringRepeat(" ",f);else{var f=a%u;while(i[t.start.column-1]==" "&&f)t.start.column--,f--;this.selection.setSelectionRange(t),l=" "}return this.insert(l)},this.blockIndent=function(){var e=this.$getSelectedRows();this.session.indentRows(e.first,e.last," ")},this.blockOutdent=function(){var e=this.session.getSelection();this.session.outdentRows(e.getRange())},this.sortLines=function(){var e=this.$getSelectedRows(),t=this.session,n=[];for(var r=e.first;r<=e.last;r++)n.push(t.getLine(r));n.sort(function(e,t){return e.toLowerCase()<t.toLowerCase()?-1:e.toLowerCase()>t.toLowerCase()?1:0});var i=new p(0,0,0,0);for(var r=e.first;r<=e.last;r++){var s=t.getLine(r);i.start.row=r,i.end.row=r,i.end.column=s.length,t.replace(i,n[r-e.first])}},this.toggleCommentLines=function(){var e=this.session.getState(this.getCursorPosition().row),t=this.$getSelectedRows();this.session.getMode().toggleCommentLines(e,this.session,t.first,t.last)},this.toggleBlockComment=function(){var e=this.getCursorPosition(),t=this.session.getState(e.row),n=this.getSelectionRange();this.session.getMode().toggleBlockComment(t,this.session,n,e)},this.getNumberAt=function(e,t){var n=/[\-]?[0-9]+(?:\.[0-9]+)?/g;n.lastIndex=0;var r=this.session.getLine(e);while(n.lastIndex<t){var i=n.exec(r);if(i.index<=t&&i.index+i[0].length>=t){var s={value:i[0],start:i.index,end:i.index+i[0].length};return s}}return null},this.modifyNumber=function(e){var t=this.selection.getCursor().row,n=this.selection.getCursor().column,r=new p(t,n-1,t,n),i=this.session.getTextRange(r);if(!isNaN(parseFloat(i))&&isFinite(i)){var s=this.getNumberAt(t,n);if(s){var o=s.value.indexOf(".")>=0?s.start+s.value.indexOf(".")+1:s.end,u=s.start+s.value.length-o,a=parseFloat(s.value);a*=Math.pow(10,u),o!==s.end&&n<o?e*=Math.pow(10,s.end-n-1):e*=Math.pow(10,s.end-n),a+=e,a/=Math.pow(10,u);var f=a.toFixed(u),l=new p(t,s.start,t,s.end);this.session.replace(l,f),this.moveCursorTo(t,Math.max(s.start+1,n+f.length-s.value.length))}}else this.toggleWord()},this.$toggleWordPairs=[["first","last"],["true","false"],["yes","no"],["width","height"],["top","bottom"],["right","left"],["on","off"],["x","y"],["get","set"],["max","min"],["horizontal","vertical"],["show","hide"],["add","remove"],["up","down"],["before","after"],["even","odd"],["inside","outside"],["next","previous"],["increase","decrease"],["attach","detach"],["&&","||"],["==","!="]],this.toggleWord=function(){var e=this.selection.getCursor().row,t=this.selection.getCursor().column;this.selection.selectWord();var n=this.getSelectedText(),r=this.selection.getWordRange().start.column,i=n.replace(/([a-z]+|[A-Z]+)(?=[A-Z_]|$)/g,"$1 ").split(/\s/),o=t-r-1;o<0&&(o=0);var u=0,a=0,f=this;n.match(/[A-Za-z0-9_]+/)&&i.forEach(function(t,i){a=u+t.length,o>=u&&o<=a&&(n=t,f.selection.clearSelection(),f.moveCursorTo(e,u+r),f.selection.selectTo(e,a+r)),u=a});var l=this.$toggleWordPairs,c;for(var h=0;h<l.length;h++){var p=l[h];for(var d=0;d<=1;d++){var v=+!d,m=n.match(new RegExp("^\\s?_?("+s.escapeRegExp(p[d])+")\\s?$","i"));if(m){var g=n.match(new RegExp("([_]|^|\\s)("+s.escapeRegExp(m[1])+")($|\\s)","g"));g&&(c=n.replace(new RegExp(s.escapeRegExp(p[d]),"i"),function(e){var t=p[v];return e.toUpperCase()==e?t=t.toUpperCase():e.charAt(0).toUpperCase()==e.charAt(0)&&(t=t.substr(0,0)+p[v].charAt(0).toUpperCase()+t.substr(1)),t}),this.insert(c),c="")}}}},this.removeLines=function(){var e=this.$getSelectedRows();this.session.removeFullLines(e.first,e.last),this.clearSelection()},this.duplicateSelection=function(){var e=this.selection,t=this.session,n=e.getRange(),r=e.isBackwards();if(n.isEmpty()){var i=n.start.row;t.duplicateLines(i,i)}else{var s=r?n.start:n.end,o=t.insert(s,t.getTextRange(n),!1);n.start=s,n.end=o,e.setSelectionRange(n,r)}},this.moveLinesDown=function(){this.$moveLines(1,!1)},this.moveLinesUp=function(){this.$moveLines(-1,!1)},this.moveText=function(e,t,n){return this.session.moveText(e,t,n)},this.copyLinesUp=function(){this.$moveLines(-1,!0)},this.copyLinesDown=function(){this.$moveLines(1,!0)},this.$moveLines=function(e,t){var n,r,i=this.selection;if(!i.inMultiSelectMode||this.inVirtualSelectionMode){var s=i.toOrientedRange();n=this.$getSelectedRows(s),r=this.session.$moveLines(n.first,n.last,t?0:e),t&&e==-1&&(r=0),s.moveBy(r,0),i.fromOrientedRange(s)}else{var o=i.rangeList.ranges;i.rangeList.detach(this.session),this.inVirtualSelectionMode=!0;var u=0,a=0,f=o.length;for(var l=0;l<f;l++){var c=l;o[l].moveBy(u,0),n=this.$getSelectedRows(o[l]);var h=n.first,p=n.last;while(++l<f){a&&o[l].moveBy(a,0);var d=this.$getSelectedRows(o[l]);if(t&&d.first!=p)break;if(!t&&d.first>p+1)break;p=d.last}l--,u=this.session.$moveLines(h,p,t?0:e),t&&e==-1&&(c=l+1);while(c<=l)o[c].moveBy(u,0),c++;t||(u=0),a+=u}i.fromOrientedRange(i.ranges[0]),i.rangeList.attach(this.session),this.inVirtualSelectionMode=!1}},this.$getSelectedRows=function(e){return e=(e||this.getSelectionRange()).collapseRows(),{first:this.session.getRowFoldStart(e.start.row),last:this.session.getRowFoldEnd(e.end.row)}},this.onCompositionStart=function(e){this.renderer.showComposition(e)},this.onCompositionUpdate=function(e){this.renderer.setCompositionText(e)},this.onCompositionEnd=function(){this.renderer.hideComposition()},this.getFirstVisibleRow=function(){return this.renderer.getFirstVisibleRow()},this.getLastVisibleRow=function(){return this.renderer.getLastVisibleRow()},this.isRowVisible=function(e){return e>=this.getFirstVisibleRow()&&e<=this.getLastVisibleRow()},this.isRowFullyVisible=function(e){return e>=this.renderer.getFirstFullyVisibleRow()&&e<=this.renderer.getLastFullyVisibleRow()},this.$getVisibleRowCount=function(){return this.renderer.getScrollBottomRow()-this.renderer.getScrollTopRow()+1},this.$moveByPage=function(e,t){var n=this.renderer,r=this.renderer.layerConfig,i=e*Math.floor(r.height/r.lineHeight);t===!0?this.selection.$moveSelection(function(){this.moveCursorBy(i,0)}):t===!1&&(this.selection.moveCursorBy(i,0),this.selection.clearSelection());var s=n.scrollTop;n.scrollBy(0,i*r.lineHeight),t!=null&&n.scrollCursorIntoView(null,.5),n.animateScrolling(s)},this.selectPageDown=function(){this.$moveByPage(1,!0)},this.selectPageUp=function(){this.$moveByPage(-1,!0)},this.gotoPageDown=function(){this.$moveByPage(1,!1)},this.gotoPageUp=function(){this.$moveByPage(-1,!1)},this.scrollPageDown=function(){this.$moveByPage(1)},this.scrollPageUp=function(){this.$moveByPage(-1)},this.scrollToRow=function(e){this.renderer.scrollToRow(e)},this.scrollToLine=function(e,t,n,r){this.renderer.scrollToLine(e,t,n,r)},this.centerSelection=function(){var e=this.getSelectionRange(),t={row:Math.floor(e.start.row+(e.end.row-e.start.row)/2),column:Math.floor(e.start.column+(e.end.column-e.start.column)/2)};this.renderer.alignCursor(t,.5)},this.getCursorPosition=function(){return this.selection.getCursor()},this.getCursorPositionScreen=function(){return this.session.documentToScreenPosition(this.getCursorPosition())},this.getSelectionRange=function(){return this.selection.getRange()},this.selectAll=function(){this.selection.selectAll()},this.clearSelection=function(){this.selection.clearSelection()},this.moveCursorTo=function(e,t){this.selection.moveCursorTo(e,t)},this.moveCursorToPosition=function(e){this.selection.moveCursorToPosition(e)},this.jumpToMatching=function(e,t){var n=this.getCursorPosition(),r=new y(this.session,n.row,n.column),i=r.getCurrentToken(),s=i||r.stepForward();if(!s)return;var o,u=!1,a={},f=n.column-s.start,l,c={")":"(","(":"(","]":"[","[":"[","{":"{","}":"{"};do{if(s.value.match(/[{}()\[\]]/g))for(;f<s.value.length&&!u;f++){if(!c[s.value[f]])continue;l=c[s.value[f]]+"."+s.type.replace("rparen","lparen"),isNaN(a[l])&&(a[l]=0);switch(s.value[f]){case"(":case"[":case"{":a[l]++;break;case")":case"]":case"}":a[l]--,a[l]===-1&&(o="bracket",u=!0)}}else s.type.indexOf("tag-name")!==-1&&(isNaN(a[s.value])&&(a[s.value]=0),i.value==="<"?a[s.value]++:i.value==="</"&&a[s.value]--,a[s.value]===-1&&(o="tag",u=!0));u||(i=s,s=r.stepForward(),f=0)}while(s&&!u);if(!o)return;var h,d;if(o==="bracket"){h=this.session.getBracketRange(n);if(!h){h=new p(r.getCurrentTokenRow(),r.getCurrentTokenColumn()+f-1,r.getCurrentTokenRow(),r.getCurrentTokenColumn()+f-1),d=h.start;if(t||d.row===n.row&&Math.abs(d.column-n.column)<2)h=this.session.getBracketRange(d)}}else if(o==="tag"){if(!s||s.type.indexOf("tag-name")===-1)return;var v=s.value;h=new p(r.getCurrentTokenRow(),r.getCurrentTokenColumn()-2,r.getCurrentTokenRow(),r.getCurrentTokenColumn()-2);if(h.compare(n.row,n.column)===0){u=!1;do s=i,i=r.stepBackward(),i&&(i.type.indexOf("tag-close")!==-1&&h.setEnd(r.getCurrentTokenRow(),r.getCurrentTokenColumn()+1),s.value===v&&s.type.indexOf("tag-name")!==-1&&(i.value==="<"?a[v]++:i.value==="</"&&a[v]--,a[v]===0&&(u=!0)));while(i&&!u)}s&&s.type.indexOf("tag-name")&&(d=h.start,d.row==n.row&&Math.abs(d.column-n.column)<2&&(d=h.end))}d=h&&h.cursor||d,d&&(e?h&&t?this.selection.setRange(h):h&&h.isEqual(this.getSelectionRange())?this.clearSelection():this.selection.selectTo(d.row,d.column):this.selection.moveTo(d.row,d.column))},this.gotoLine=function(e,t,n){this.selection.clearSelection(),this.session.unfold({row:e-1,column:t||0}),this.exitMultiSelectMode&&this.exitMultiSelectMode(),this.moveCursorTo(e-1,t||0),this.isRowFullyVisible(e-1)||this.scrollToLine(e-1,!0,n)},this.navigateTo=function(e,t){this.selection.moveTo(e,t)},this.navigateUp=function(e){if(this.selection.isMultiLine()&&!this.selection.isBackwards()){var t=this.selection.anchor.getPosition();return this.moveCursorToPosition(t)}this.selection.clearSelection(),this.selection.moveCursorBy(-e||-1,0)},this.navigateDown=function(e){if(this.selection.isMultiLine()&&this.selection.isBackwards()){var t=this.selection.anchor.getPosition();return this.moveCursorToPosition(t)}this.selection.clearSelection(),this.selection.moveCursorBy(e||1,0)},this.navigateLeft=function(e){if(!this.selection.isEmpty()){var t=this.getSelectionRange().start;this.moveCursorToPosition(t)}else{e=e||1;while(e--)this.selection.moveCursorLeft()}this.clearSelection()},this.navigateRight=function(e){if(!this.selection.isEmpty()){var t=this.getSelectionRange().end;this.moveCursorToPosition(t)}else{e=e||1;while(e--)this.selection.moveCursorRight()}this.clearSelection()},this.navigateLineStart=function(){this.selection.moveCursorLineStart(),this.clearSelection()},this.navigateLineEnd=function(){this.selection.moveCursorLineEnd(),this.clearSelection()},this.navigateFileEnd=function(){this.selection.moveCursorFileEnd(),this.clearSelection()},this.navigateFileStart=function(){this.selection.moveCursorFileStart(),this.clearSelection()},this.navigateWordRight=function(){this.selection.moveCursorWordRight(),this.clearSelection()},this.navigateWordLeft=function(){this.selection.moveCursorWordLeft(),this.clearSelection()},this.replace=function(e,t){t&&this.$search.set(t);var n=this.$search.find(this.session),r=0;return n?(this.$tryReplace(n,e)&&(r=1),this.selection.setSelectionRange(n),this.renderer.scrollSelectionIntoView(n.start,n.end),r):r},this.replaceAll=function(e,t){t&&this.$search.set(t);var n=this.$search.findAll(this.session),r=0;if(!n.length)return r;var i=this.getSelectionRange();this.selection.moveTo(0,0);for(var s=n.length-1;s>=0;--s)this.$tryReplace(n[s],e)&&r++;return this.selection.setSelectionRange(i),r},this.$tryReplace=function(e,t){var n=this.session.getTextRange(e);return t=this.$search.replace(n,t),t!==null?(e.end=this.session.replace(e,t),e):null},this.getLastSearchOptions=function(){return this.$search.getOptions()},this.find=function(e,t,n){t||(t={}),typeof e=="string"||e instanceof RegExp?t.needle=e:typeof e=="object"&&r.mixin(t,e);var i=this.selection.getRange();t.needle==null&&(e=this.session.getTextRange(i)||this.$search.$options.needle,e||(i=this.session.getWordRange(i.start.row,i.start.column),e=this.session.getTextRange(i)),this.$search.set({needle:e})),this.$search.set(t),t.start||this.$search.set({start:i});var s=this.$search.find(this.session);if(t.preventScroll)return s;if(s)return this.revealRange(s,n),s;t.backwards?i.start=i.end:i.end=i.start,this.selection.setRange(i)},this.findNext=function(e,t){this.find({skipCurrent:!0,backwards:!1},e,t)},this.findPrevious=function(e,t){this.find(e,{skipCurrent:!0,backwards:!0},t)},this.revealRange=function(e,t){this.session.unfold(e),this.selection.setSelectionRange(e);var n=this.renderer.scrollTop;this.renderer.scrollSelectionIntoView(e.start,e.end,.5),t!==!1&&this.renderer.animateScrolling(n)},this.undo=function(){this.session.getUndoManager().undo(this.session),this.renderer.scrollCursorIntoView(null,.5)},this.redo=function(){this.session.getUndoManager().redo(this.session),this.renderer.scrollCursorIntoView(null,.5)},this.destroy=function(){this.renderer.destroy(),this._signal("destroy",this),this.session&&this.session.destroy()},this.setAutoScrollEditorIntoView=function(e){if(!e)return;var t,n=this,r=!1;this.$scrollAnchor||(this.$scrollAnchor=document.createElement("div"));var i=this.$scrollAnchor;i.style.cssText="position:absolute",this.container.insertBefore(i,this.container.firstChild);var s=this.on("changeSelection",function(){r=!0}),o=this.renderer.on("beforeRender",function(){r&&(t=n.renderer.container.getBoundingClientRect())}),u=this.renderer.on("afterRender",function(){if(r&&t&&(n.isFocused()||n.searchBox&&n.searchBox.isFocused())){var e=n.renderer,s=e.$cursorLayer.$pixelPos,o=e.layerConfig,u=s.top-o.offset;s.top>=0&&u+t.top<0?r=!0:s.top<o.height&&s.top+t.top+o.lineHeight>window.innerHeight?r=!1:r=null,r!=null&&(i.style.top=u+"px",i.style.left=s.left+"px",i.style.height=o.lineHeight+"px",i.scrollIntoView(r)),r=t=null}});this.setAutoScrollEditorIntoView=function(e){if(e)return;delete this.setAutoScrollEditorIntoView,this.off("changeSelection",s),this.renderer.off("afterRender",u),this.renderer.off("beforeRender",o)}},this.$resetCursorStyle=function(){var e=this.$cursorStyle||"ace",t=this.renderer.$cursorLayer;if(!t)return;t.setSmoothBlinking(/smooth/.test(e)),t.isBlinking=!this.$readOnly&&e!="wide",i.setCssClass(t.element,"ace_slim-cursors",/slim/.test(e))}}.call(w.prototype),g.defineOptions(w.prototype,"editor",{selectionStyle:{set:function(e){this.onSelectionChange(),this._signal("changeSelectionStyle",{data:e})},initialValue:"line"},highlightActiveLine:{set:function(){this.$updateHighlightActiveLine()},initialValue:!0},highlightSelectedWord:{set:function(e){this.$onSelectionChange()},initialValue:!0},readOnly:{set:function(e){this.textInput.setReadOnly(e),this.$resetCursorStyle()},initialValue:!1},copyWithEmptySelection:{set:function(e){this.textInput.setCopyWithEmptySelection(e)},initialValue:!1},cursorStyle:{set:function(e){this.$resetCursorStyle()},values:["ace","slim","smooth","wide"],initialValue:"ace"},mergeUndoDeltas:{values:[!1,!0,"always"],initialValue:!0},behavioursEnabled:{initialValue:!0},wrapBehavioursEnabled:{initialValue:!0},autoScrollEditorIntoView:{set:function(e){this.setAutoScrollEditorIntoView(e)}},keyboardHandler:{set:function(e){this.setKeyboardHandler(e)},get:function(){return this.$keybindingId},handlesSet:!0},value:{set:function(e){this.session.setValue(e)},get:function(){return this.getValue()},handlesSet:!0,hidden:!0},session:{set:function(e){this.setSession(e)},get:function(){return this.session},handlesSet:!0,hidden:!0},showLineNumbers:{set:function(e){this.renderer.$gutterLayer.setShowLineNumbers(e),this.renderer.$loop.schedule(this.renderer.CHANGE_GUTTER),e&&this.$relativeLineNumbers?E.attach(this):E.detach(this)},initialValue:!0},relativeLineNumbers:{set:function(e){this.$showLineNumbers&&e?E.attach(this):E.detach(this)}},hScrollBarAlwaysVisible:"renderer",vScrollBarAlwaysVisible:"renderer",highlightGutterLine:"renderer",animatedScroll:"renderer",showInvisibles:"renderer",showPrintMargin:"renderer",printMarginColumn:"renderer",printMargin:"renderer",fadeFoldWidgets:"renderer",showFoldWidgets:"renderer",displayIndentGuides:"renderer",showGutter:"renderer",fontSize:"renderer",fontFamily:"renderer",maxLines:"renderer",minLines:"renderer",scrollPastEnd:"renderer",fixedWidthGutter:"renderer",theme:"renderer",hasCssTransforms:"renderer",maxPixelHeight:"renderer",useTextareaForIME:"renderer",scrollSpeed:"$mouseHandler",dragDelay:"$mouseHandler",dragEnabled:"$mouseHandler",focusTimeout:"$mouseHandler",tooltipFollowsMouse:"$mouseHandler",firstLineNumber:"session",overwrite:"session",newLineMode:"session",useWorker:"session",useSoftTabs:"session",navigateWithinSoftTabs:"session",tabSize:"session",wrap:"session",indentedSoftWrap:"session",foldStyle:"session",mode:"session"});var E={getText:function(e,t){return(Math.abs(e.selection.lead.row-t)||t+1+(t<9?"\u00b7":""))+""},getWidth:function(e,t,n){return Math.max(t.toString().length,(n.lastRow+1).toString().length,2)*n.characterWidth},update:function(e,t){t.renderer.$loop.schedule(t.renderer.CHANGE_GUTTER)},attach:function(e){e.renderer.$gutterLayer.$renderer=this,e.on("changeSelection",this.update),this.update(null,e)},detach:function(e){e.renderer.$gutterLayer.$renderer==this&&(e.renderer.$gutterLayer.$renderer=null),e.off("changeSelection",this.update),this.update(null,e)}};t.Editor=w}),ace.define("ace/undomanager",["require","exports","module","ace/range"],function(e,t,n){"use strict";function i(e,t){for(var n=t;n--;){var r=e[n];if(r&&!r[0].ignore){while(n<t-1){var i=d(e[n],e[n+1]);e[n]=i[0],e[n+1]=i[1],n++}return!0}}}function a(e){var t=e.action=="insert",n=e.start,r=e.end,i=(r.row-n.row)*(t?1:-1),s=(r.column-n.column)*(t?1:-1);t&&(r=n);for(var o in this.marks){var a=this.marks[o],f=u(a,n);if(f<0)continue;if(f===0&&t){if(a.bias!=1){a.bias==-1;continue}f=1}var l=t?f:u(a,r);if(l>0){a.row+=i,a.column+=a.row==r.row?s:0;continue}!t&&l<=0&&(a.row=n.row,a.column=n.column,l===0&&(a.bias=1))}}function f(e){return{row:e.row,column:e.column}}function l(e){return{start:f(e.start),end:f(e.end),action:e.action,lines:e.lines.slice()}}function c(e){e=e||this;if(Array.isArray(e))return e.map(c).join("\n");var t="";e.action?(t=e.action=="insert"?"+":"-",t+="["+e.lines+"]"):e.value&&(Array.isArray(e.value)?t=e.value.map(h).join("\n"):t=h(e.value)),e.start&&(t+=h(e));if(e.id||e.rev)t+=" ("+(e.id||e.rev)+")";return t}function h(e){return e.start.row+":"+e.start.column+"=>"+e.end.row+":"+e.end.column}function p(e,t){var n=e.action=="insert",r=t.action=="insert";if(n&&r)if(o(t.start,e.end)>=0)m(t,e,-1);else{if(!(o(t.start,e.start)<=0))return null;m(e,t,1)}else if(n&&!r)if(o(t.start,e.end)>=0)m(t,e,-1);else{if(!(o(t.end,e.start)<=0))return null;m(e,t,-1)}else if(!n&&r)if(o(t.start,e.start)>=0)m(t,e,1);else{if(!(o(t.start,e.start)<=0))return null;m(e,t,1)}else if(!n&&!r)if(o(t.start,e.start)>=0)m(t,e,1);else{if(!(o(t.end,e.start)<=0))return null;m(e,t,-1)}return[t,e]}function d(e,t){for(var n=e.length;n--;)for(var r=0;r<t.length;r++)if(!p(e[n],t[r])){while(n<e.length){while(r--)p(t[r],e[n]);r=t.length,n++}return[e,t]}return e.selectionBefore=t.selectionBefore=e.selectionAfter=t.selectionAfter=null,[t,e]}function v(e,t){var n=e.action=="insert",r=t.action=="insert";if(n&&r)o(e.start,t.start)<0?m(t,e,1):m(e,t,1);else if(n&&!r)o(e.start,t.end)>=0?m(e,t,-1):o(e.start,t.start)<=0?m(t,e,1):(m(e,s.fromPoints(t.start,e.start),-1),m(t,e,1));else if(!n&&r)o(t.start,e.end)>=0?m(t,e,-1):o(t.start,e.start)<=0?m(e,t,1):(m(t,s.fromPoints(e.start,t.start),-1),m(e,t,1));else if(!n&&!r)if(o(t.start,e.end)>=0)m(t,e,-1);else{if(!(o(t.end,e.start)<=0)){var i,u;return o(e.start,t.start)<0&&(i=e,e=y(e,t.start)),o(e.end,t.end)>0&&(u=y(e,t.end)),g(t.end,e.start,e.end,-1),u&&!i&&(e.lines=u.lines,e.start=u.start,e.end=u.end,u=e),[t,i,u].filter(Boolean)}m(e,t,-1)}return[t,e]}function m(e,t,n){g(e.start,t.start,t.end,n),g(e.end,t.start,t.end,n)}function g(e,t,n,r){e.row==(r==1?t:n).row&&(e.column+=r*(n.column-t.column)),e.row+=r*(n.row-t.row)}function y(e,t){var n=e.lines,r=e.end;e.end=f(t);var i=e.end.row-e.start.row,s=n.splice(i,n.length),o=i?t.column:t.column-e.start.column;n.push(s[0].substring(0,o)),s[0]=s[0].substr(o);var u={start:f(t),end:r,lines:s,action:e.action};return u}function b(e,t){t=l(t);for(var n=e.length;n--;){var r=e[n];for(var i=0;i<r.length;i++){var s=r[i],o=v(s,t);t=o[0],o.length!=2&&(o[2]?(r.splice(i+1,1,o[1],o[2]),i++):o[1]||(r.splice(i,1),i--))}r.length||e.splice(n,1)}return e}function w(e,t){for(var n=0;n<t.length;n++){var r=t[n];for(var i=0;i<r.length;i++)b(e,r[i])}}var r=function(){this.$maxRev=0,this.$fromUndo=!1,this.reset()};(function(){this.addSession=function(e){this.$session=e},this.add=function(e,t,n){if(this.$fromUndo)return;if(e==this.$lastDelta)return;if(t===!1||!this.lastDeltas)this.lastDeltas=[],this.$undoStack.push(this.lastDeltas),e.id=this.$rev=++this.$maxRev;if(e.action=="remove"||e.action=="insert")this.$lastDelta=e;this.lastDeltas.push(e)},this.addSelection=function(e,t){this.selections.push({value:e,rev:t||this.$rev})},this.startNewGroup=function(){return this.lastDeltas=null,this.$rev},this.markIgnored=function(e,t){t==null&&(t=this.$rev+1);var n=this.$undoStack;for(var r=n.length;r--;){var i=n[r][0];if(i.id<=e)break;i.id<t&&(i.ignore=!0)}this.lastDeltas=null},this.getSelection=function(e,t){var n=this.selections;for(var r=n.length;r--;){var i=n[r];if(i.rev<e)return t&&(i=n[r+1]),i}},this.getRevision=function(){return this.$rev},this.getDeltas=function(e,t){t==null&&(t=this.$rev+1);var n=this.$undoStack,r=null,i=0;for(var s=n.length;s--;){var o=n[s][0];o.id<t&&!r&&(r=s+1);if(o.id<=e){i=s+1;break}}return n.slice(i,r)},this.getChangedRanges=function(e,t){t==null&&(t=this.$rev+1)},this.getChangedLines=function(e,t){t==null&&(t=this.$rev+1)},this.undo=function(e,t){this.lastDeltas=null;var n=this.$undoStack;if(!i(n,n.length))return;e||(e=this.$session),this.$redoStackBaseRev!==this.$rev&&this.$redoStack.length&&(this.$redoStack=[]),this.$fromUndo=!0;var r=n.pop(),s=null;return r&&r.length&&(s=e.undoChanges(r,t),this.$redoStack.push(r),this.$syncRev()),this.$fromUndo=!1,s},this.redo=function(e,t){this.lastDeltas=null,e||(e=this.$session),this.$fromUndo=!0;if(this.$redoStackBaseRev!=this.$rev){var n=this.getDeltas(this.$redoStackBaseRev,this.$rev+1);w(this.$redoStack,n),this.$redoStackBaseRev=this.$rev,this.$redoStack.forEach(function(e){e[0].id=++this.$maxRev},this)}var r=this.$redoStack.pop(),i=null;return r&&(i=e.redoChanges(r,t),this.$undoStack.push(r),this.$syncRev()),this.$fromUndo=!1,i},this.$syncRev=function(){var e=this.$undoStack,t=e[e.length-1],n=t&&t[0].id||0;this.$redoStackBaseRev=n,this.$rev=n},this.reset=function(){this.lastDeltas=null,this.$lastDelta=null,this.$undoStack=[],this.$redoStack=[],this.$rev=0,this.mark=0,this.$redoStackBaseRev=this.$rev,this.selections=[]},this.canUndo=function(){return this.$undoStack.length>0},this.canRedo=function(){return this.$redoStack.length>0},this.bookmark=function(e){e==undefined&&(e=this.$rev),this.mark=e},this.isAtBookmark=function(){return this.$rev===this.mark},this.toJSON=function(){},this.fromJSON=function(){},this.hasUndo=this.canUndo,this.hasRedo=this.canRedo,this.isClean=this.isAtBookmark,this.markClean=this.bookmark,this.$prettyPrint=function(e){return e?c(e):c(this.$undoStack)+"\n---\n"+c(this.$redoStack)}}).call(r.prototype);var s=e("./range").Range,o=s.comparePoints,u=s.comparePoints;t.UndoManager=r}),ace.define("ace/layer/lines",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../lib/dom"),i=function(e,t){this.element=e,this.canvasHeight=t||5e5,this.element.style.height=this.canvasHeight*2+"px",this.cells=[],this.cellCache=[],this.$offsetCoefficient=0};(function(){this.moveContainer=function(e){r.translate(this.element,0,-(e.firstRowScreen*e.lineHeight%this.canvasHeight)-e.offset*this.$offsetCoefficient)},this.pageChanged=function(e,t){return Math.floor(e.firstRowScreen*e.lineHeight/this.canvasHeight)!==Math.floor(t.firstRowScreen*t.lineHeight/this.canvasHeight)},this.computeLineTop=function(e,t,n){var r=t.firstRowScreen*t.lineHeight,i=Math.floor(r/this.canvasHeight),s=n.documentToScreenRow(e,0)*t.lineHeight;return s-i*this.canvasHeight},this.computeLineHeight=function(e,t,n){return t.lineHeight*n.getRowLength(e)},this.getLength=function(){return this.cells.length},this.get=function(e){return this.cells[e]},this.shift=function(){this.$cacheCell(this.cells.shift())},this.pop=function(){this.$cacheCell(this.cells.pop())},this.push=function(e){if(Array.isArray(e)){this.cells.push.apply(this.cells,e);var t=r.createFragment(this.element);for(var n=0;n<e.length;n++)t.appendChild(e[n].element);this.element.appendChild(t)}else this.cells.push(e),this.element.appendChild(e.element)},this.unshift=function(e){if(Array.isArray(e)){this.cells.unshift.apply(this.cells,e);var t=r.createFragment(this.element);for(var n=0;n<e.length;n++)t.appendChild(e[n].element);this.element.firstChild?this.element.insertBefore(t,this.element.firstChild):this.element.appendChild(t)}else this.cells.unshift(e),this.element.insertAdjacentElement("afterbegin",e.element)},this.last=function(){return this.cells.length?this.cells[this.cells.length-1]:null},this.$cacheCell=function(e){if(!e)return;e.element.remove(),this.cellCache.push(e)},this.createCell=function(e,t,n,i){var s=this.cellCache.pop();if(!s){var o=r.createElement("div");i&&i(o),this.element.appendChild(o),s={element:o,text:"",row:e}}return s.row=e,s}}).call(i.prototype),t.Lines=i}),ace.define("ace/layer/gutter",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter","ace/layer/lines"],function(e,t,n){"use strict";function f(e){var t=document.createTextNode("");e.appendChild(t);var n=r.createElement("span");return e.appendChild(n),e}var r=e("../lib/dom"),i=e("../lib/oop"),s=e("../lib/lang"),o=e("../lib/event_emitter").EventEmitter,u=e("./lines").Lines,a=function(e){this.element=r.createElement("div"),this.element.className="ace_layer ace_gutter-layer",e.appendChild(this.element),this.setShowFoldWidgets(this.$showFoldWidgets),this.gutterWidth=0,this.$annotations=[],this.$updateAnnotations=this.$updateAnnotations.bind(this),this.$lines=new u(this.element),this.$lines.$offsetCoefficient=1};(function(){i.implement(this,o),this.setSession=function(e){this.session&&this.session.removeEventListener("change",this.$updateAnnotations),this.session=e,e&&e.on("change",this.$updateAnnotations)},this.addGutterDecoration=function(e,t){window.console&&console.warn&&console.warn("deprecated use session.addGutterDecoration"),this.session.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){window.console&&console.warn&&console.warn("deprecated use session.removeGutterDecoration"),this.session.removeGutterDecoration(e,t)},this.setAnnotations=function(e){this.$annotations=[];for(var t=0;t<e.length;t++){var n=e[t],r=n.row,i=this.$annotations[r];i||(i=this.$annotations[r]={text:[]});var o=n.text;o=o?s.escapeHTML(o):n.html||"",i.text.indexOf(o)===-1&&i.text.push(o);var u=n.type;u=="error"?i.className=" ace_error":u=="warning"&&i.className!=" ace_error"?i.className=" ace_warning":u=="info"&&!i.className&&(i.className=" ace_info")}},this.$updateAnnotations=function(e){if(!this.$annotations.length)return;var t=e.start.row,n=e.end.row-t;if(n!==0)if(e.action=="remove")this.$annotations.splice(t,n+1,null);else{var r=new Array(n+1);r.unshift(t,1),this.$annotations.splice.apply(this.$annotations,r)}},this.update=function(e){this.config=e;var t=this.session,n=e.firstRow,r=Math.min(e.lastRow+e.gutterOffset,t.getLength()-1);this.oldLastRow=r,this.config=e,this.$lines.moveContainer(e),this.$updateCursorRow();var i=t.getNextFoldLine(n),s=i?i.start.row:Infinity,o=null,u=-1,a=n;for(;;){a>s&&(a=i.end.row+1,i=t.getNextFoldLine(a,i),s=i?i.start.row:Infinity);if(a>r){while(this.$lines.getLength()>u+1)this.$lines.pop();break}o=this.$lines.get(++u),o?o.row=a:(o=this.$lines.createCell(a,e,this.session,f),this.$lines.push(o)),this.$renderCell(o,e,i,a),a++}this._signal("afterRender"),this.$updateGutterWidth(e)},this.$updateGutterWidth=function(e){var t=this.session,n=t.gutterRenderer||this.$renderer,r=t.$firstLineNumber,i=this.$lines.last()?this.$lines.last().text:"";if(this.$fixedWidth||t.$useWrapMode)i=t.getLength()+r-1;var s=n?n.getWidth(t,i,e):i.toString().length*e.characterWidth,o=this.$padding||this.$computePadding();s+=o.left+o.right,s!==this.gutterWidth&&!isNaN(s)&&(this.gutterWidth=s,this.element.parentNode.style.width=this.element.style.width=Math.ceil(this.gutterWidth)+"px",this._signal("changeGutterWidth",s))},this.$updateCursorRow=function(){if(!this.$highlightGutterLine)return;var e=this.session.selection.getCursor();if(this.$cursorRow===e.row)return;this.$cursorRow=e.row},this.updateLineHighlight=function(){if(!this.$highlightGutterLine)return;var e=this.session.selection.cursor.row;this.$cursorRow=e;if(this.$cursorCell&&this.$cursorCell.row==e)return;this.$cursorCell&&(this.$cursorCell.element.className=this.$cursorCell.element.className.replace("ace_gutter-active-line ",""));var t=this.$lines.cells;this.$cursorCell=null;for(var n=0;n<t.length;n++){var r=t[n];if(r.row>=this.$cursorRow){if(r.row>this.$cursorRow){var i=this.session.getFoldLine(this.$cursorRow);if(!(n>0&&i&&i.start.row==t[n-1].row))break;r=t[n-1]}r.element.className="ace_gutter-active-line "+r.element.className,this.$cursorCell=r;break}}},this.scrollLines=function(e){var t=this.config;this.config=e,this.$updateCursorRow();if(this.$lines.pageChanged(t,e))return this.update(e);this.$lines.moveContainer(e);var n=Math.min(e.lastRow+e.gutterOffset,this.session.getLength()-1),r=this.oldLastRow;this.oldLastRow=n;if(!t||r<e.firstRow)return this.update(e);if(n<t.firstRow)return this.update(e);if(t.firstRow<e.firstRow)for(var i=this.session.getFoldedRowCount(t.firstRow,e.firstRow-1);i>0;i--)this.$lines.shift();if(r>n)for(var i=this.session.getFoldedRowCount(n+1,r);i>0;i--)this.$lines.pop();e.firstRow<t.firstRow&&this.$lines.unshift(this.$renderLines(e,e.firstRow,t.firstRow-1)),n>r&&this.$lines.push(this.$renderLines(e,r+1,n)),this.updateLineHighlight(),this._signal("afterRender"),this.$updateGutterWidth(e)},this.$renderLines=function(e,t,n){var r=[],i=t,s=this.session.getNextFoldLine(i),o=s?s.start.row:Infinity;for(;;){i>o&&(i=s.end.row+1,s=this.session.getNextFoldLine(i,s),o=s?s.start.row:Infinity);if(i>n)break;var u=this.$lines.createCell(i,e,this.session,f);this.$renderCell(u,e,s,i),r.push(u),i++}return r},this.$renderCell=function(e,t,n,i){var s=e.element,o=this.session,u=s.childNodes[0],a=s.childNodes[1],f=o.$firstLineNumber,l=o.$breakpoints,c=o.$decorations,h=o.gutterRenderer||this.$renderer,p=this.$showFoldWidgets&&o.foldWidgets,d=n?n.start.row:Number.MAX_VALUE,v="ace_gutter-cell ";this.$highlightGutterLine&&(i==this.$cursorRow||n&&i<this.$cursorRow&&i>=d&&this.$cursorRow<=n.end.row)&&(v+="ace_gutter-active-line ",this.$cursorCell!=e&&(this.$cursorCell&&(this.$cursorCell.element.className=this.$cursorCell.element.className.replace("ace_gutter-active-line ","")),this.$cursorCell=e)),l[i]&&(v+=l[i]),c[i]&&(v+=c[i]),this.$annotations[i]&&(v+=this.$annotations[i].className),s.className!=v&&(s.className=v);if(p){var m=p[i];m==null&&(m=p[i]=o.getFoldWidget(i))}if(m){var v="ace_fold-widget ace_"+m;m=="start"&&i==d&&i<n.end.row?v+=" ace_closed":v+=" ace_open",a.className!=v&&(a.className=v);var g=t.lineHeight+"px";r.setStyle(a.style,"height",g),r.setStyle(a.style,"display","inline-block")}else a&&r.setStyle(a.style,"display","none");var y=(h?h.getText(o,i):i+f).toString();return y!==u.data&&(u.data=y),r.setStyle(e.element.style,"height",this.$lines.computeLineHeight(i,t,o)+"px"),r.setStyle(e.element.style,"top",this.$lines.computeLineTop(i,t,o)+"px"),e.text=y,e},this.$fixedWidth=!1,this.$highlightGutterLine=!0,this.$renderer="",this.setHighlightGutterLine=function(e){this.$highlightGutterLine=e},this.$showLineNumbers=!0,this.$renderer="",this.setShowLineNumbers=function(e){this.$renderer=!e&&{getWidth:function(){return 0},getText:function(){return""}}},this.getShowLineNumbers=function(){return this.$showLineNumbers},this.$showFoldWidgets=!0,this.setShowFoldWidgets=function(e){e?r.addCssClass(this.element,"ace_folding-enabled"):r.removeCssClass(this.element,"ace_folding-enabled"),this.$showFoldWidgets=e,this.$padding=null},this.getShowFoldWidgets=function(){return this.$showFoldWidgets},this.$computePadding=function(){if(!this.element.firstChild)return{left:0,right:0};var e=r.computedStyle(this.element.firstChild);return this.$padding={},this.$padding.left=(parseInt(e.borderLeftWidth)||0)+(parseInt(e.paddingLeft)||0)+1,this.$padding.right=(parseInt(e.borderRightWidth)||0)+(parseInt(e.paddingRight)||0),this.$padding},this.getRegion=function(e){var t=this.$padding||this.$computePadding(),n=this.element.getBoundingClientRect();if(e.x<t.left+n.left)return"markers";if(this.$showFoldWidgets&&e.x>n.right-t.right)return"foldWidgets"}}).call(a.prototype),t.Gutter=a}),ace.define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../range").Range,i=e("../lib/dom"),s=function(e){this.element=i.createElement("div"),this.element.className="ace_layer ace_marker-layer",e.appendChild(this.element)};(function(){function e(e,t,n,r){return(e?1:0)|(t?2:0)|(n?4:0)|(r?8:0)}this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setMarkers=function(e){this.markers=e},this.elt=function(e,t){var n=this.i!=-1&&this.element.childNodes[this.i];n?this.i++:(n=document.createElement("div"),this.element.appendChild(n),this.i=-1),n.style.cssText=t,n.className=e},this.update=function(e){if(!e)return;this.config=e,this.i=0;var t;for(var n in this.markers){var r=this.markers[n];if(!r.range){r.update(t,this,this.session,e);continue}var i=r.range.clipRows(e.firstRow,e.lastRow);if(i.isEmpty())continue;i=i.toScreenRange(this.session);if(r.renderer){var s=this.$getTop(i.start.row,e),o=this.$padding+i.start.column*e.characterWidth;r.renderer(t,i,o,s,e)}else r.type=="fullLine"?this.drawFullLineMarker(t,i,r.clazz,e):r.type=="screenLine"?this.drawScreenLineMarker(t,i,r.clazz,e):i.isMultiLine()?r.type=="text"?this.drawTextMarker(t,i,r.clazz,e):this.drawMultiLineMarker(t,i,r.clazz,e):this.drawSingleLineMarker(t,i,r.clazz+" ace_start"+" ace_br15",e)}if(this.i!=-1)while(this.i<this.element.childElementCount)this.element.removeChild(this.element.lastChild)},this.$getTop=function(e,t){return(e-t.firstRowScreen)*t.lineHeight},this.drawTextMarker=function(t,n,i,s,o){var u=this.session,a=n.start.row,f=n.end.row,l=a,c=0,h=0,p=u.getScreenLastRowColumn(l),d=new r(l,n.start.column,l,h);for(;l<=f;l++)d.start.row=d.end.row=l,d.start.column=l==a?n.start.column:u.getRowWrapIndent(l),d.end.column=p,c=h,h=p,p=l+1<f?u.getScreenLastRowColumn(l+1):l==f?0:n.end.column,this.drawSingleLineMarker(t,d,i+(l==a?" ace_start":"")+" ace_br"+e(l==a||l==a+1&&n.start.column,c<h,h>p,l==f),s,l==f?0:1,o)},this.drawMultiLineMarker=function(e,t,n,r,i){var s=this.$padding,o=r.lineHeight,u=this.$getTop(t.start.row,r),a=s+t.start.column*r.characterWidth;i=i||"";if(this.session.$bidiHandler.isBidiRow(t.start.row)){var f=t.clone();f.end.row=f.start.row,f.end.column=this.session.getLine(f.start.row).length,this.drawBidiSingleLineMarker(e,f,n+" ace_br1 ace_start",r,null,i)}else this.elt(n+" ace_br1 ace_start","height:"+o+"px;"+"right:0;"+"top:"+u+"px;left:"+a+"px;"+(i||""));if(this.session.$bidiHandler.isBidiRow(t.end.row)){var f=t.clone();f.start.row=f.end.row,f.start.column=0,this.drawBidiSingleLineMarker(e,f,n+" ace_br12",r,null,i)}else{u=this.$getTop(t.end.row,r);var l=t.end.column*r.characterWidth;this.elt(n+" ace_br12","height:"+o+"px;"+"width:"+l+"px;"+"top:"+u+"px;"+"left:"+s+"px;"+(i||""))}o=(t.end.row-t.start.row-1)*r.lineHeight;if(o<=0)return;u=this.$getTop(t.start.row+1,r);var c=(t.start.column?1:0)|(t.end.column?0:8);this.elt(n+(c?" ace_br"+c:""),"height:"+o+"px;"+"right:0;"+"top:"+u+"px;"+"left:"+s+"px;"+(i||""))},this.drawSingleLineMarker=function(e,t,n,r,i,s){if(this.session.$bidiHandler.isBidiRow(t.start.row))return this.drawBidiSingleLineMarker(e,t,n,r,i,s);var o=r.lineHeight,u=(t.end.column+(i||0)-t.start.column)*r.characterWidth,a=this.$getTop(t.start.row,r),f=this.$padding+t.start.column*r.characterWidth;this.elt(n,"height:"+o+"px;"+"width:"+u+"px;"+"top:"+a+"px;"+"left:"+f+"px;"+(s||""))},this.drawBidiSingleLineMarker=function(e,t,n,r,i,s){var o=r.lineHeight,u=this.$getTop(t.start.row,r),a=this.$padding,f=this.session.$bidiHandler.getSelections(t.start.column,t.end.column);f.forEach(function(e){this.elt(n,"height:"+o+"px;"+"width:"+e.width+(i||0)+"px;"+"top:"+u+"px;"+"left:"+(a+e.left)+"px;"+(s||""))},this)},this.drawFullLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;t.start.row!=t.end.row&&(o+=this.$getTop(t.end.row,r)-s),this.elt(n,"height:"+o+"px;"+"top:"+s+"px;"+"left:0;right:0;"+(i||""))},this.drawScreenLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;this.elt(n,"height:"+o+"px;"+"top:"+s+"px;"+"left:0;right:0;"+(i||""))}}).call(s.prototype),t.Marker=s}),ace.define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/layer/lines","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/dom"),s=e("../lib/lang"),o=e("./lines").Lines,u=e("../lib/event_emitter").EventEmitter,a=function(e){this.dom=i,this.element=this.dom.createElement("div"),this.element.className="ace_layer ace_text-layer",e.appendChild(this.element),this.$updateEolChar=this.$updateEolChar.bind(this),this.$lines=new o(this.element)};(function(){r.implement(this,u),this.EOF_CHAR="\u00b6",this.EOL_CHAR_LF="\u00ac",this.EOL_CHAR_CRLF="\u00a4",this.EOL_CHAR=this.EOL_CHAR_LF,this.TAB_CHAR="\u2014",this.SPACE_CHAR="\u00b7",this.$padding=0,this.MAX_LINE_LENGTH=1e4,this.$updateEolChar=function(){var e=this.session.doc,t=e.getNewLineCharacter()=="\n"&&e.getNewLineMode()!="windows",n=t?this.EOL_CHAR_LF:this.EOL_CHAR_CRLF;if(this.EOL_CHAR!=n)return this.EOL_CHAR=n,!0},this.setPadding=function(e){this.$padding=e,this.element.style.margin="0 "+e+"px"},this.getLineHeight=function(){return this.$fontMetrics.$characterSize.height||0},this.getCharacterWidth=function(){return this.$fontMetrics.$characterSize.width||0},this.$setFontMetrics=function(e){this.$fontMetrics=e,this.$fontMetrics.on("changeCharacterSize",function(e){this._signal("changeCharacterSize",e)}.bind(this)),this.$pollSizeChanges()},this.checkForSizeChanges=function(){this.$fontMetrics.checkForSizeChanges()},this.$pollSizeChanges=function(){return this.$pollSizeChangesTimer=this.$fontMetrics.$pollSizeChanges()},this.setSession=function(e){this.session=e,e&&this.$computeTabString()},this.showInvisibles=!1,this.setShowInvisibles=function(e){return this.showInvisibles==e?!1:(this.showInvisibles=e,this.$computeTabString(),!0)},this.displayIndentGuides=!0,this.setDisplayIndentGuides=function(e){return this.displayIndentGuides==e?!1:(this.displayIndentGuides=e,this.$computeTabString(),!0)},this.$tabStrings=[],this.onChangeTabSize=this.$computeTabString=function(){var e=this.session.getTabSize();this.tabSize=e;var t=this.$tabStrings=[0];for(var n=1;n<e+1;n++)if(this.showInvisibles){var r=this.dom.createElement("span");r.className="ace_invisible ace_invisible_tab",r.textContent=s.stringRepeat(this.TAB_CHAR,n),t.push(r)}else t.push(this.dom.createTextNode(s.stringRepeat(" ",n),this.element));if(this.displayIndentGuides){this.$indentGuideRe=/\s\S| \t|\t |\s$/;var i="ace_indent-guide",o="",u="";if(this.showInvisibles){i+=" ace_invisible",o=" ace_invisible_space",u=" ace_invisible_tab";var a=s.stringRepeat(this.SPACE_CHAR,this.tabSize),f=s.stringRepeat(this.TAB_CHAR,this.tabSize)}else var a=s.stringRepeat(" ",this.tabSize),f=a;var r=this.dom.createElement("span");r.className=i+o,r.textContent=a,this.$tabStrings[" "]=r;var r=this.dom.createElement("span");r.className=i+u,r.textContent=f,this.$tabStrings[" "]=r}},this.updateLines=function(e,t,n){if(this.config.lastRow!=e.lastRow||this.config.firstRow!=e.firstRow)return this.update(e);this.config=e;var r=Math.max(t,e.firstRow),i=Math.min(n,e.lastRow),s=this.element.childNodes,o=0;for(var u=e.firstRow;u<r;u++){var a=this.session.getFoldLine(u);if(a){if(a.containsRow(r)){r=a.start.row;break}u=a.end.row}o++}var f=!1,u=r,a=this.session.getNextFoldLine(u),l=a?a.start.row:Infinity;for(;;){u>l&&(u=a.end.row+1,a=this.session.getNextFoldLine(u,a),l=a?a.start.row:Infinity);if(u>i)break;var c=s[o++];if(c){this.dom.removeChildren(c),this.$renderLine(c,u,u==l?a:!1);var h=e.lineHeight*this.session.getRowLength(u)+"px";c.style.height!=h&&(f=!0,c.style.height=h)}u++}if(f)while(o<this.$lines.cells.length){var p=this.$lines.cells[o++];p.element.style.top=this.$lines.computeLineTop(p.row,e,this.session)+"px"}},this.scrollLines=function(e){var t=this.config;this.config=e;if(this.$lines.pageChanged(t,e))return this.update(e);this.$lines.moveContainer(e);var n=e.lastRow,r=t?t.lastRow:-1;if(!t||r<e.firstRow)return this.update(e);if(n<t.firstRow)return this.update(e);if(!t||t.lastRow<e.firstRow)return this.update(e);if(e.lastRow<t.firstRow)return this.update(e);if(t.firstRow<e.firstRow)for(var i=this.session.getFoldedRowCount(t.firstRow,e.firstRow-1);i>0;i--)this.$lines.shift();if(t.lastRow>e.lastRow)for(var i=this.session.getFoldedRowCount(e.lastRow+1,t.lastRow);i>0;i--)this.$lines.pop();e.firstRow<t.firstRow&&this.$lines.unshift(this.$renderLinesFragment(e,e.firstRow,t.firstRow-1)),e.lastRow>t.lastRow&&this.$lines.push(this.$renderLinesFragment(e,t.lastRow+1,e.lastRow))},this.$renderLinesFragment=function(e,t,n){var r=[],s=t,o=this.session.getNextFoldLine(s),u=o?o.start.row:Infinity;for(;;){s>u&&(s=o.end.row+1,o=this.session.getNextFoldLine(s,o),u=o?o.start.row:Infinity);if(s>n)break;var a=this.$lines.createCell(s,e,this.session),f=a.element;this.dom.removeChildren(f),i.setStyle(f.style,"height",this.$lines.computeLineHeight(s,e,this.session)+"px"),i.setStyle(f.style,"top",this.$lines.computeLineTop(s,e,this.session)+"px"),this.$renderLine(f,s,s==u?o:!1),this.$useLineGroups()?f.className="ace_line_group":f.className="ace_line",r.push(a),s++}return r},this.update=function(e){this.$lines.moveContainer(e),this.config=e;var t=e.firstRow,n=e.lastRow,r=this.$lines;while(r.getLength())r.pop();r.push(this.$renderLinesFragment(e,t,n))},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderToken=function(e,t,n,r){var o=this,u=/(\t)|( +)|([\x00-\x1f\x80-\xa0\xad\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\uFEFF\uFFF9-\uFFFC]+)|(\u3000)|([\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3001-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]|[\uD800-\uDBFF][\uDC00-\uDFFF])/g,a=this.dom.createFragment(this.element),f,l=0;while(f=u.exec(r)){var c=f[1],h=f[2],p=f[3],d=f[4],v=f[5];if(!o.showInvisibles&&h)continue;var m=l!=f.index?r.slice(l,f.index):"";l=f.index+f[0].length,m&&a.appendChild(this.dom.createTextNode(m,this.element));if(c){var g=o.session.getScreenTabSize(t+f.index);a.appendChild(o.$tabStrings[g].cloneNode(!0)),t+=g-1}else if(h)if(o.showInvisibles){var y=this.dom.createElement("span");y.className="ace_invisible ace_invisible_space",y.textContent=s.stringRepeat(o.SPACE_CHAR,h.length),a.appendChild(y)}else a.appendChild(this.com.createTextNode(h,this.element));else if(p){var y=this.dom.createElement("span");y.className="ace_invisible ace_invisible_space ace_invalid",y.textContent=s.stringRepeat(o.SPACE_CHAR,p.length),a.appendChild(y)}else if(d){var b=o.showInvisibles?o.SPACE_CHAR:"";t+=1;var y=this.dom.createElement("span");y.style.width=o.config.characterWidth*2+"px",y.className=o.showInvisibles?"ace_cjk ace_invisible ace_invisible_space":"ace_cjk",y.textContent=o.showInvisibles?o.SPACE_CHAR:"",a.appendChild(y)}else if(v){t+=1;var y=i.createElement("span");y.style.width=o.config.characterWidth*2+"px",y.className="ace_cjk",y.textContent=v,a.appendChild(y)}}a.appendChild(this.dom.createTextNode(l?r.slice(l):r,this.element));if(!this.$textToken[n.type]){var w="ace_"+n.type.replace(/\./g," ace_"),y=this.dom.createElement("span");n.type=="fold"&&(y.style.width=n.value.length*this.config.characterWidth+"px"),y.className=w,y.appendChild(a),e.appendChild(y)}else e.appendChild(a);return t+r.length},this.renderIndentGuide=function(e,t,n){var r=t.search(this.$indentGuideRe);if(r<=0||r>=n)return t;if(t[0]==" "){r-=r%this.tabSize;var i=r/this.tabSize;for(var s=0;s<i;s++)e.appendChild(this.$tabStrings[" "].cloneNode(!0));return t.substr(r)}if(t[0]==" "){for(var s=0;s<r;s++)e.appendChild(this.$tabStrings[" "].cloneNode(!0));return t.substr(r)}return t},this.$createLineElement=function(e){var t=this.dom.createElement("div");return t.className="ace_line",t.style.height=this.config.lineHeight+"px",t},this.$renderWrappedLine=function(e,t,n){var r=0,i=0,o=n[0],u=0,a=this.$createLineElement();e.appendChild(a);for(var f=0;f<t.length;f++){var l=t[f],c=l.value;if(f==0&&this.displayIndentGuides){r=c.length,c=this.renderIndentGuide(a,c,o);if(!c)continue;r-=c.length}if(r+c.length<o)u=this.$renderToken(a,u,l,c),r+=c.length;else{while(r+c.length>=o)u=this.$renderToken(a,u,l,c.substring(0,o-r)),c=c.substring(o-r),r=o,a=this.$createLineElement(),e.appendChild(a),a.appendChild(this.dom.createTextNode(s.stringRepeat("\u00a0",n.indent),this.element)),i++,u=0,o=n[i]||Number.MAX_VALUE;c.length!=0&&(r+=c.length,u=this.$renderToken(a,u,l,c))}}},this.$renderSimpleLine=function(e,t){var n=0,r=t[0],i=r.value;this.displayIndentGuides&&(i=this.renderIndentGuide(e,i)),i&&(n=this.$renderToken(e,n,r,i));for(var s=1;s<t.length;s++){r=t[s],i=r.value;if(n+i.length>this.MAX_LINE_LENGTH)return this.$renderOverflowMessage(e,n,r,i);n=this.$renderToken(e,n,r,i)}},this.$renderOverflowMessage=function(e,t,n,r){this.$renderToken(e,t,n,r.slice(0,this.MAX_LINE_LENGTH-t));var i=this.dom.createElement("span");i.className="ace_inline_button ace_keyword ace_toggle_wrap",i.style.position="absolute",i.style.right="0",i.textContent="<click to see more...>",e.appendChild(i)},this.$renderLine=function(e,t,n){!n&&n!=0&&(n=this.session.getFoldLine(t));if(n)var r=this.$getFoldLineTokens(t,n);else var r=this.session.getTokens(t);var i=e;if(r.length){var s=this.session.getRowSplitData(t);if(s&&s.length){this.$renderWrappedLine(e,r,s);var i=e.lastChild}else{var i=e;this.$useLineGroups()&&(i=this.$createLineElement(),e.appendChild(i)),this.$renderSimpleLine(i,r)}}else this.$useLineGroups()&&(i=this.$createLineElement(),e.appendChild(i));if(this.showInvisibles&&i){n&&(t=n.end.row);var o=this.dom.createElement("span");o.className="ace_invisible ace_invisible_eol",o.textContent=t==this.session.getLength()-1?this.EOF_CHAR:this.EOL_CHAR,i.appendChild(o)}},this.$getFoldLineTokens=function(e,t){function i(e,t,n){var i=0,s=0;while(s+e[i].value.length<t){s+=e[i].value.length,i++;if(i==e.length)return}if(s!=t){var o=e[i].value.substring(t-s);o.length>n-t&&(o=o.substring(0,n-t)),r.push({type:e[i].type,value:o}),s=t+o.length,i+=1}while(s<n&&i<e.length){var o=e[i].value;o.length+s>n?r.push({type:e[i].type,value:o.substring(0,n-s)}):r.push(e[i]),s+=o.length,i+=1}}var n=this.session,r=[],s=n.getTokens(e);return t.walk(function(e,t,o,u,a){e!=null?r.push({type:"fold",value:e}):(a&&(s=n.getTokens(t)),s.length&&i(s,u,o))},t.end.row,this.session.getLine(t.end.row).length),r},this.$useLineGroups=function(){return this.session.getUseWrapMode()},this.destroy=function(){}}).call(a.prototype),t.Text=a}),ace.define("ace/layer/cursor",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../lib/dom"),i=function(e){this.element=r.createElement("div"),this.element.className="ace_layer ace_cursor-layer",e.appendChild(this.element),this.isVisible=!1,this.isBlinking=!0,this.blinkInterval=1e3,this.smoothBlinking=!1,this.cursors=[],this.cursor=this.addCursor(),r.addCssClass(this.element,"ace_hidden-cursors"),this.$updateCursors=this.$updateOpacity.bind(this)};(function(){this.$updateOpacity=function(e){var t=this.cursors;for(var n=t.length;n--;)r.setStyle(t[n].style,"opacity",e?"":"0")},this.$startCssAnimation=function(){var e=this.cursors;for(var t=e.length;t--;)e[t].style.animationDuration=this.blinkInterval+"ms";setTimeout(function(){r.addCssClass(this.element,"ace_animate-blinking")}.bind(this))},this.$stopCssAnimation=function(){r.removeCssClass(this.element,"ace_animate-blinking")},this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setBlinking=function(e){e!=this.isBlinking&&(this.isBlinking=e,this.restartTimer())},this.setBlinkInterval=function(e){e!=this.blinkInterval&&(this.blinkInterval=e,this.restartTimer())},this.setSmoothBlinking=function(e){e!=this.smoothBlinking&&(this.smoothBlinking=e,r.setCssClass(this.element,"ace_smooth-blinking",e),this.$updateCursors(!0),this.restartTimer())},this.addCursor=function(){var e=r.createElement("div");return e.className="ace_cursor",this.element.appendChild(e),this.cursors.push(e),e},this.removeCursor=function(){if(this.cursors.length>1){var e=this.cursors.pop();return e.parentNode.removeChild(e),e}},this.hideCursor=function(){this.isVisible=!1,r.addCssClass(this.element,"ace_hidden-cursors"),this.restartTimer()},this.showCursor=function(){this.isVisible=!0,r.removeCssClass(this.element,"ace_hidden-cursors"),this.restartTimer()},this.restartTimer=function(){var e=this.$updateCursors;clearInterval(this.intervalId),clearTimeout(this.timeoutId),this.$stopCssAnimation(),this.smoothBlinking&&r.removeCssClass(this.element,"ace_smooth-blinking"),e(!0);if(!this.isBlinking||!this.blinkInterval||!this.isVisible){this.$stopCssAnimation();return}this.smoothBlinking&&setTimeout(function(){r.addCssClass(this.element,"ace_smooth-blinking")}.bind(this));if(r.HAS_CSS_ANIMATION)this.$startCssAnimation();else{var t=function(){this.timeoutId=setTimeout(function(){e(!1)},.6*this.blinkInterval)}.bind(this);this.intervalId=setInterval(function(){e(!0),t()},this.blinkInterval),t()}},this.getPixelPosition=function(e,t){if(!this.config||!this.session)return{left:0,top:0};e||(e=this.session.selection.getCursor());var n=this.session.documentToScreenPosition(e),r=this.$padding+(this.session.$bidiHandler.isBidiRow(n.row,e.row)?this.session.$bidiHandler.getPosLeft(n.column):n.column*this.config.characterWidth),i=(n.row-(t?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:r,top:i}},this.isCursorInView=function(e,t){return e.top>=0&&e.top<t.maxHeight},this.update=function(e){this.config=e;var t=this.session.$selectionMarkers,n=0,i=0;if(t===undefined||t.length===0)t=[{cursor:null}];for(var n=0,s=t.length;n<s;n++){var o=this.getPixelPosition(t[n].cursor,!0);if((o.top>e.height+e.offset||o.top<0)&&n>1)continue;var u=this.cursors[i++]||this.addCursor(),a=u.style;this.drawCursor?this.drawCursor(u,o,e,t[n],this.session):this.isCursorInView(o,e)?(r.setStyle(a,"display","block"),r.translate(u,o.left,o.top),r.setStyle(a,"width",Math.round(e.characterWidth)+"px"),r.setStyle(a,"height",e.lineHeight+"px")):r.setStyle(a,"display","none")}while(this.cursors.length>i)this.removeCursor();var f=this.session.getOverwrite();this.$setOverwrite(f),this.$pixelPos=o,this.restartTimer()},this.drawCursor=null,this.$setOverwrite=function(e){e!=this.overwrite&&(this.overwrite=e,e?r.addCssClass(this.element,"ace_overwrite-cursors"):r.removeCssClass(this.element,"ace_overwrite-cursors"))},this.destroy=function(){clearInterval(this.intervalId),clearTimeout(this.timeoutId)}}).call(i.prototype),t.Cursor=i}),ace.define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./lib/event"),o=e("./lib/event_emitter").EventEmitter,u=32768,a=function(e){this.element=i.createElement("div"),this.element.className="ace_scrollbar ace_scrollbar"+this.classSuffix,this.inner=i.createElement("div"),this.inner.className="ace_scrollbar-inner",this.element.appendChild(this.inner),e.appendChild(this.element),this.setVisible(!1),this.skipEvent=!1,s.addListener(this.element,"scroll",this.onScroll.bind(this)),s.addListener(this.element,"mousedown",s.preventDefault)};(function(){r.implement(this,o),this.setVisible=function(e){this.element.style.display=e?"":"none",this.isVisible=e,this.coeff=1}}).call(a.prototype);var f=function(e,t){a.call(this,e),this.scrollTop=0,this.scrollHeight=0,t.$scrollbarWidth=this.width=i.scrollbarWidth(e.ownerDocument),this.inner.style.width=this.element.style.width=(this.width||15)+5+"px",this.$minWidth=0};r.inherits(f,a),function(){this.classSuffix="-v",this.onScroll=function(){if(!this.skipEvent){this.scrollTop=this.element.scrollTop;if(this.coeff!=1){var e=this.element.clientHeight/this.scrollHeight;this.scrollTop=this.scrollTop*(1-e)/(this.coeff-e)}this._emit("scroll",{data:this.scrollTop})}this.skipEvent=!1},this.getWidth=function(){return Math.max(this.isVisible?this.width:0,this.$minWidth||0)},this.setHeight=function(e){this.element.style.height=e+"px"},this.setInnerHeight=this.setScrollHeight=function(e){this.scrollHeight=e,e>u?(this.coeff=u/e,e=u):this.coeff!=1&&(this.coeff=1),this.inner.style.height=e+"px"},this.setScrollTop=function(e){this.scrollTop!=e&&(this.skipEvent=!0,this.scrollTop=e,this.element.scrollTop=e*this.coeff)}}.call(f.prototype);var l=function(e,t){a.call(this,e),this.scrollLeft=0,this.height=t.$scrollbarWidth,this.inner.style.height=this.element.style.height=(this.height||15)+5+"px"};r.inherits(l,a),function(){this.classSuffix="-h",this.onScroll=function(){this.skipEvent||(this.scrollLeft=this.element.scrollLeft,this._emit("scroll",{data:this.scrollLeft})),this.skipEvent=!1},this.getHeight=function(){return this.isVisible?this.height:0},this.setWidth=function(e){this.element.style.width=e+"px"},this.setInnerWidth=function(e){this.inner.style.width=e+"px"},this.setScrollWidth=function(e){this.inner.style.width=e+"px"},this.setScrollLeft=function(e){this.scrollLeft!=e&&(this.skipEvent=!0,this.scrollLeft=this.element.scrollLeft=e)}}.call(l.prototype),t.ScrollBar=f,t.ScrollBarV=f,t.ScrollBarH=l,t.VScrollBar=f,t.HScrollBar=l}),ace.define("ace/renderloop",["require","exports","module","ace/lib/event"],function(e,t,n){"use strict";var r=e("./lib/event"),i=function(e,t){this.onRender=e,this.pending=!1,this.changes=0,this.$recursionLimit=2,this.window=t||window;var n=this;this._flush=function(e){n.pending=!1;var t=n.changes;t&&(r.blockIdle(100),n.changes=0,n.onRender(t));if(n.changes){if(n.$recursionLimit--<0)return;n.schedule()}else n.$recursionLimit=2}};(function(){this.schedule=function(e){this.changes=this.changes|e,this.changes&&!this.pending&&(r.nextFrame(this._flush),this.pending=!0)},this.clear=function(e){var t=this.changes;return this.changes=0,t}}).call(i.prototype),t.RenderLoop=i}),ace.define("ace/layer/font_metrics",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/event","ace/lib/useragent","ace/lib/event_emitter"],function(e,t,n){var r=e("../lib/oop"),i=e("../lib/dom"),s=e("../lib/lang"),o=e("../lib/event"),u=e("../lib/useragent"),a=e("../lib/event_emitter").EventEmitter,f=256,l=typeof ResizeObserver=="function",c=200,h=t.FontMetrics=function(e){this.el=i.createElement("div"),this.$setMeasureNodeStyles(this.el.style,!0),this.$main=i.createElement("div"),this.$setMeasureNodeStyles(this.$main.style),this.$measureNode=i.createElement("div"),this.$setMeasureNodeStyles(this.$measureNode.style),this.el.appendChild(this.$main),this.el.appendChild(this.$measureNode),e.appendChild(this.el),this.$measureNode.innerHTML=s.stringRepeat("X",f),this.$characterSize={width:0,height:0},l?this.$addObserver():this.checkForSizeChanges()};(function(){r.implement(this,a),this.$characterSize={width:0,height:0},this.$setMeasureNodeStyles=function(e,t){e.width=e.height="auto",e.left=e.top="0px",e.visibility="hidden",e.position="absolute",e.whiteSpace="pre",u.isIE<8?e["font-family"]="inherit":e.font="inherit",e.overflow=t?"hidden":"visible"},this.checkForSizeChanges=function(e){e===undefined&&(e=this.$measureSizes());if(e&&(this.$characterSize.width!==e.width||this.$characterSize.height!==e.height)){this.$measureNode.style.fontWeight="bold";var t=this.$measureSizes();this.$measureNode.style.fontWeight="",this.$characterSize=e,this.charSizes=Object.create(null),this.allowBoldFonts=t&&t.width===e.width&&t.height===e.height,this._emit("changeCharacterSize",{data:e})}},this.$addObserver=function(){var e=this;this.$observer=new window.ResizeObserver(function(t){var n=t[0].contentRect;e.checkForSizeChanges({height:n.height,width:n.width/f})}),this.$observer.observe(this.$measureNode)},this.$pollSizeChanges=function(){if(this.$pollSizeChangesTimer||this.$observer)return this.$pollSizeChangesTimer;var e=this;return this.$pollSizeChangesTimer=o.onIdle(function t(){e.checkForSizeChanges(),o.onIdle(t,500)},500)},this.setPolling=function(e){e?this.$pollSizeChanges():this.$pollSizeChangesTimer&&(clearInterval(this.$pollSizeChangesTimer),this.$pollSizeChangesTimer=0)},this.$measureSizes=function(e){var t={height:(e||this.$measureNode).clientHeight,width:(e||this.$measureNode).clientWidth/f};return t.width===0||t.height===0?null:t},this.$measureCharWidth=function(e){this.$main.innerHTML=s.stringRepeat(e,f);var t=this.$main.getBoundingClientRect();return t.width/f},this.getCharacterWidth=function(e){var t=this.charSizes[e];return t===undefined&&(t=this.charSizes[e]=this.$measureCharWidth(e)/this.$characterSize.width),t},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.$observer&&this.$observer.disconnect(),this.el&&this.el.parentNode&&this.el.parentNode.removeChild(this.el)},this.$getZoom=function e(t){return t?(window.getComputedStyle(t).zoom||1)*e(t.parentElement):1},this.$initTransformMeasureNodes=function(){var e=function(e,t){return["div",{style:"position: absolute;top:"+e+"px;left:"+t+"px;"}]};this.els=i.buildDom([e(0,0),e(c,0),e(0,c),e(c,c)],this.el)},this.transformCoordinates=function(e,t){function r(e,t,n){var r=e[1]*t[0]-e[0]*t[1];return[(-t[1]*n[0]+t[0]*n[1])/r,(+e[1]*n[0]-e[0]*n[1])/r]}function i(e,t){return[e[0]-t[0],e[1]-t[1]]}function s(e,t){return[e[0]+t[0],e[1]+t[1]]}function o(e,t){return[e*t[0],e*t[1]]}function u(e){var t=e.getBoundingClientRect();return[t.left,t.top]}if(e){var n=this.$getZoom(this.el);e=o(1/n,e)}this.els||this.$initTransformMeasureNodes();var a=u(this.els[0]),f=u(this.els[1]),l=u(this.els[2]),h=u(this.els[3]),p=r(i(h,f),i(h,l),i(s(f,l),s(h,a))),d=o(1+p[0],i(f,a)),v=o(1+p[1],i(l,a));if(t){var m=t,g=p[0]*m[0]/c+p[1]*m[1]/c+1,y=s(o(m[0],d),o(m[1],v));return s(o(1/g/c,y),a)}var b=i(e,a),w=r(i(d,o(p[0],b)),i(v,o(p[1],b)),b);return o(c,w)}}).call(h.prototype)}),ace.define("ace/virtual_renderer",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/config","ace/layer/gutter","ace/layer/marker","ace/layer/text","ace/layer/cursor","ace/scrollbar","ace/scrollbar","ace/renderloop","ace/layer/font_metrics","ace/lib/event_emitter","ace/lib/useragent"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./config"),o=e("./layer/gutter").Gutter,u=e("./layer/marker").Marker,a=e("./layer/text").Text,f=e("./layer/cursor").Cursor,l=e("./scrollbar").HScrollBar,c=e("./scrollbar").VScrollBar,h=e("./renderloop").RenderLoop,p=e("./layer/font_metrics").FontMetrics,d=e("./lib/event_emitter").EventEmitter,v='.ace_br1 {border-top-left-radius : 3px;}.ace_br2 {border-top-right-radius : 3px;}.ace_br3 {border-top-left-radius : 3px; border-top-right-radius: 3px;}.ace_br4 {border-bottom-right-radius: 3px;}.ace_br5 {border-top-left-radius : 3px; border-bottom-right-radius: 3px;}.ace_br6 {border-top-right-radius : 3px; border-bottom-right-radius: 3px;}.ace_br7 {border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px;}.ace_br8 {border-bottom-left-radius : 3px;}.ace_br9 {border-top-left-radius : 3px; border-bottom-left-radius: 3px;}.ace_br10{border-top-right-radius : 3px; border-bottom-left-radius: 3px;}.ace_br11{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br13{border-top-left-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br14{border-top-right-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br15{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_editor {position: relative;overflow: hidden;font: 12px/normal \'Monaco\', \'Menlo\', \'Ubuntu Mono\', \'Consolas\', \'source-code-pro\', monospace;direction: ltr;text-align: left;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}.ace_scroller {position: absolute;overflow: hidden;top: 0;bottom: 0;background-color: inherit;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;cursor: text;}.ace_content {position: absolute;box-sizing: border-box;min-width: 100%;contain: style size layout;}.ace_dragging .ace_scroller:before{position: absolute;top: 0;left: 0;right: 0;bottom: 0;content: \'\';background: rgba(250, 250, 250, 0.01);z-index: 1000;}.ace_dragging.ace_dark .ace_scroller:before{background: rgba(0, 0, 0, 0.01);}.ace_selecting, .ace_selecting * {cursor: text !important;}.ace_gutter {position: absolute;overflow : hidden;width: auto;top: 0;bottom: 0;left: 0;cursor: default;z-index: 4;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;contain: style size layout;}.ace_gutter-active-line {position: absolute;left: 0;right: 0;}.ace_scroller.ace_scroll-left {box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;}.ace_gutter-cell {position: absolute;top: 0;left: 0;right: 0;padding-left: 19px;padding-right: 6px;background-repeat: no-repeat;}.ace_gutter-cell.ace_error {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: 2px center;}.ace_gutter-cell.ace_warning {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==");background-position: 2px center;}.ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=");background-position: 2px center;}.ace_dark .ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC");}.ace_scrollbar {contain: strict;position: absolute;right: 0;bottom: 0;z-index: 6;}.ace_scrollbar-inner {position: absolute;cursor: text;left: 0;top: 0;}.ace_scrollbar-v{overflow-x: hidden;overflow-y: scroll;top: 0;}.ace_scrollbar-h {overflow-x: scroll;overflow-y: hidden;left: 0;}.ace_print-margin {position: absolute;height: 100%;}.ace_text-input {position: absolute;z-index: 0;width: 0.5em;height: 1em;opacity: 0;background: transparent;-moz-appearance: none;appearance: none;border: none;resize: none;outline: none;overflow: hidden;font: inherit;padding: 0 1px;margin: 0 -1px;contain: strict;-ms-user-select: text;-moz-user-select: text;-webkit-user-select: text;user-select: text;white-space: pre!important;}.ace_text-input.ace_composition {background: transparent;color: inherit;z-index: 1000;opacity: 1;}.ace_composition_placeholder { color: transparent }.ace_composition_marker { border-bottom: 1px solid;position: absolute;border-radius: 0;margin-top: 1px;}[ace_nocontext=true] {transform: none!important;filter: none!important;perspective: none!important;clip-path: none!important;mask : none!important;contain: none!important;perspective: none!important;mix-blend-mode: initial!important;z-index: auto;}.ace_layer {z-index: 1;position: absolute;overflow: hidden;word-wrap: normal;white-space: pre;height: 100%;width: 100%;box-sizing: border-box;pointer-events: none;}.ace_gutter-layer {position: relative;width: auto;text-align: right;pointer-events: auto;height: 1000000px;contain: style size layout;}.ace_text-layer {font: inherit !important;position: absolute;height: 1000000px;width: 1000000px;contain: style size layout;}.ace_text-layer > .ace_line, .ace_text-layer > .ace_line_group {contain: style size layout;position: absolute;top: 0;left: 0;right: 0;}.ace_hidpi .ace_text-layer,.ace_hidpi .ace_gutter-layer,.ace_hidpi .ace_content,.ace_hidpi .ace_gutter {contain: strict;will-change: transform;}.ace_hidpi .ace_text-layer > .ace_line, .ace_hidpi .ace_text-layer > .ace_line_group {contain: strict;}.ace_cjk {display: inline-block;text-align: center;}.ace_cursor-layer {z-index: 4;}.ace_cursor {z-index: 4;position: absolute;box-sizing: border-box;border-left: 2px solid;transform: translatez(0);}.ace_multiselect .ace_cursor {border-left-width: 1px;}.ace_slim-cursors .ace_cursor {border-left-width: 1px;}.ace_overwrite-cursors .ace_cursor {border-left-width: 0;border-bottom: 1px solid;}.ace_hidden-cursors .ace_cursor {opacity: 0.2;}.ace_smooth-blinking .ace_cursor {transition: opacity 0.18s;}.ace_animate-blinking .ace_cursor {animation-duration: 1000ms;animation-timing-function: step-end;animation-name: blink-ace-animate;animation-iteration-count: infinite;}.ace_animate-blinking.ace_smooth-blinking .ace_cursor {animation-duration: 1000ms;animation-timing-function: ease-in-out;animation-name: blink-ace-animate-smooth;}@keyframes blink-ace-animate {from, to { opacity: 1; }60% { opacity: 0; }}@keyframes blink-ace-animate-smooth {from, to { opacity: 1; }45% { opacity: 1; }60% { opacity: 0; }85% { opacity: 0; }}.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {position: absolute;z-index: 3;}.ace_marker-layer .ace_selection {position: absolute;z-index: 5;}.ace_marker-layer .ace_bracket {position: absolute;z-index: 6;}.ace_marker-layer .ace_active-line {position: absolute;z-index: 2;}.ace_marker-layer .ace_selected-word {position: absolute;z-index: 4;box-sizing: border-box;}.ace_line .ace_fold {box-sizing: border-box;display: inline-block;height: 11px;margin-top: -2px;vertical-align: middle;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=");background-repeat: no-repeat, repeat-x;background-position: center center, top left;color: transparent;border: 1px solid black;border-radius: 2px;cursor: pointer;pointer-events: auto;}.ace_dark .ace_fold {}.ace_fold:hover{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC");}.ace_tooltip {background-color: #FFF;background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));border: 1px solid gray;border-radius: 1px;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);color: black;max-width: 100%;padding: 3px 4px;position: fixed;z-index: 999999;box-sizing: border-box;cursor: default;white-space: pre;word-wrap: break-word;line-height: normal;font-style: normal;font-weight: normal;letter-spacing: normal;pointer-events: none;}.ace_folding-enabled > .ace_gutter-cell {padding-right: 13px;}.ace_fold-widget {box-sizing: border-box;margin: 0 -12px 0 1px;display: none;width: 11px;vertical-align: top;background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: center;border-radius: 3px;border: 1px solid transparent;cursor: pointer;}.ace_folding-enabled .ace_fold-widget {display: inline-block; }.ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==");}.ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==");}.ace_fold-widget:hover {border: 1px solid rgba(0, 0, 0, 0.3);background-color: rgba(255, 255, 255, 0.2);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);}.ace_fold-widget:active {border: 1px solid rgba(0, 0, 0, 0.4);background-color: rgba(0, 0, 0, 0.05);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);}.ace_dark .ace_fold-widget {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC");}.ace_dark .ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget:hover {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);background-color: rgba(255, 255, 255, 0.1);}.ace_dark .ace_fold-widget:active {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);}.ace_inline_button {border: 1px solid lightgray;display: inline-block;margin: -1px 8px;padding: 0 5px;pointer-events: auto;cursor: pointer;}.ace_inline_button:hover {border-color: gray;background: rgba(200,200,200,0.2);display: inline-block;pointer-events: auto;}.ace_fold-widget.ace_invalid {background-color: #FFB4B4;border-color: #DE5555;}.ace_fade-fold-widgets .ace_fold-widget {transition: opacity 0.4s ease 0.05s;opacity: 0;}.ace_fade-fold-widgets:hover .ace_fold-widget {transition: opacity 0.05s ease 0.05s;opacity:1;}.ace_underline {text-decoration: underline;}.ace_bold {font-weight: bold;}.ace_nobold .ace_bold {font-weight: normal;}.ace_italic {font-style: italic;}.ace_error-marker {background-color: rgba(255, 0, 0,0.2);position: absolute;z-index: 9;}.ace_highlight-marker {background-color: rgba(255, 255, 0,0.2);position: absolute;z-index: 8;}',m=e("./lib/useragent"),g=m.isIE;i.importCssString(v,"ace_editor.css");var y=function(e,t){var n=this;this.container=e||i.createElement("div"),i.addCssClass(this.container,"ace_editor"),i.HI_DPI&&i.addCssClass(this.container,"ace_hidpi"),this.setTheme(t),this.$gutter=i.createElement("div"),this.$gutter.className="ace_gutter",this.container.appendChild(this.$gutter),this.$gutter.setAttribute("aria-hidden",!0),this.scroller=i.createElement("div"),this.scroller.className="ace_scroller",this.container.appendChild(this.scroller),this.content=i.createElement("div"),this.content.className="ace_content",this.scroller.appendChild(this.content),this.$gutterLayer=new o(this.$gutter),this.$gutterLayer.on("changeGutterWidth",this.onGutterResize.bind(this)),this.$markerBack=new u(this.content);var r=this.$textLayer=new a(this.content);this.canvas=r.element,this.$markerFront=new u(this.content),this.$cursorLayer=new f(this.content),this.$horizScroll=!1,this.$vScroll=!1,this.scrollBar=this.scrollBarV=new c(this.container,this),this.scrollBarH=new l(this.container,this),this.scrollBarV.addEventListener("scroll",function(e){n.$scrollAnimation||n.session.setScrollTop(e.data-n.scrollMargin.top)}),this.scrollBarH.addEventListener("scroll",function(e){n.$scrollAnimation||n.session.setScrollLeft(e.data-n.scrollMargin.left)}),this.scrollTop=0,this.scrollLeft=0,this.cursorPos={row:0,column:0},this.$fontMetrics=new p(this.container),this.$textLayer.$setFontMetrics(this.$fontMetrics),this.$textLayer.addEventListener("changeCharacterSize",function(e){n.updateCharacterSize(),n.onResize(!0,n.gutterWidth,n.$size.width,n.$size.height),n._signal("changeCharacterSize",e)}),this.$size={width:0,height:0,scrollerHeight:0,scrollerWidth:0,$dirty:!0},this.layerConfig={width:1,padding:0,firstRow:0,firstRowScreen:0,lastRow:0,lineHeight:0,characterWidth:0,minHeight:1,maxHeight:1,offset:0,height:1,gutterOffset:1},this.scrollMargin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.margin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.$keepTextAreaAtCursor=!m.isIOS,this.$loop=new h(this.$renderChanges.bind(this),this.container.ownerDocument.defaultView),this.$loop.schedule(this.CHANGE_FULL),this.updateCharacterSize(),this.setPadding(4),s.resetOptions(this),s._emit("renderer",this)};(function(){this.CHANGE_CURSOR=1,this.CHANGE_MARKER=2,this.CHANGE_GUTTER=4,this.CHANGE_SCROLL=8,this.CHANGE_LINES=16,this.CHANGE_TEXT=32,this.CHANGE_SIZE=64,this.CHANGE_MARKER_BACK=128,this.CHANGE_MARKER_FRONT=256,this.CHANGE_FULL=512,this.CHANGE_H_SCROLL=1024,r.implement(this,d),this.updateCharacterSize=function(){this.$textLayer.allowBoldFonts!=this.$allowBoldFonts&&(this.$allowBoldFonts=this.$textLayer.allowBoldFonts,this.setStyle("ace_nobold",!this.$allowBoldFonts)),this.layerConfig.characterWidth=this.characterWidth=this.$textLayer.getCharacterWidth(),this.layerConfig.lineHeight=this.lineHeight=this.$textLayer.getLineHeight(),this.$updatePrintMargin()},this.setSession=function(e){this.session&&this.session.doc.off("changeNewLineMode",this.onChangeNewLineMode),this.session=e,e&&this.scrollMargin.top&&e.getScrollTop()<=0&&e.setScrollTop(-this.scrollMargin.top),this.$cursorLayer.setSession(e),this.$markerBack.setSession(e),this.$markerFront.setSession(e),this.$gutterLayer.setSession(e),this.$textLayer.setSession(e);if(!e)return;this.$loop.schedule(this.CHANGE_FULL),this.session.$setFontMetrics(this.$fontMetrics),this.scrollBarH.scrollLeft=this.scrollBarV.scrollTop=null,this.onChangeNewLineMode=this.onChangeNewLineMode.bind(this),this.onChangeNewLineMode(),this.session.doc.on("changeNewLineMode",this.onChangeNewLineMode)},this.updateLines=function(e,t,n){t===undefined&&(t=Infinity),this.$changedLines?(this.$changedLines.firstRow>e&&(this.$changedLines.firstRow=e),this.$changedLines.lastRow<t&&(this.$changedLines.lastRow=t)):this.$changedLines={firstRow:e,lastRow:t};if(this.$changedLines.lastRow<this.layerConfig.firstRow){if(!n)return;this.$changedLines.lastRow=this.layerConfig.lastRow}if(this.$changedLines.firstRow>this.layerConfig.lastRow)return;this.$loop.schedule(this.CHANGE_LINES)},this.onChangeNewLineMode=function(){this.$loop.schedule(this.CHANGE_TEXT),this.$textLayer.$updateEolChar(),this.session.$bidiHandler.setEolChar(this.$textLayer.EOL_CHAR)},this.onChangeTabSize=function(){this.$loop.schedule(this.CHANGE_TEXT|this.CHANGE_MARKER),this.$textLayer.onChangeTabSize()},this.updateText=function(){this.$loop.schedule(this.CHANGE_TEXT)},this.updateFull=function(e){e?this.$renderChanges(this.CHANGE_FULL,!0):this.$loop.schedule(this.CHANGE_FULL)},this.updateFontSize=function(){this.$textLayer.checkForSizeChanges()},this.$changes=0,this.$updateSizeAsync=function(){this.$loop.pending?this.$size.$dirty=!0:this.onResize()},this.onResize=function(e,t,n,r){if(this.resizing>2)return;this.resizing>0?this.resizing++:this.resizing=e?1:0;var i=this.container;r||(r=i.clientHeight||i.scrollHeight),n||(n=i.clientWidth||i.scrollWidth);var s=this.$updateCachedSize(e,t,n,r);if(!this.$size.scrollerHeight||!n&&!r)return this.resizing=0;e&&(this.$gutterLayer.$padding=null),e?this.$renderChanges(s|this.$changes,!0):this.$loop.schedule(s|this.$changes),this.resizing&&(this.resizing=0),this.scrollBarV.scrollLeft=this.scrollBarV.scrollTop=null},this.$updateCachedSize=function(e,t,n,r){r-=this.$extraHeight||0;var s=0,o=this.$size,u={width:o.width,height:o.height,scrollerHeight:o.scrollerHeight,scrollerWidth:o.scrollerWidth};r&&(e||o.height!=r)&&(o.height=r,s|=this.CHANGE_SIZE,o.scrollerHeight=o.height,this.$horizScroll&&(o.scrollerHeight-=this.scrollBarH.getHeight()),this.scrollBarV.element.style.bottom=this.scrollBarH.getHeight()+"px",s|=this.CHANGE_SCROLL);if(n&&(e||o.width!=n)){s|=this.CHANGE_SIZE,o.width=n,t==null&&(t=this.$showGutter?this.$gutter.offsetWidth:0),this.gutterWidth=t,i.setStyle(this.scrollBarH.element.style,"left",t+"px"),i.setStyle(this.scroller.style,"left",t+this.margin.left+"px"),o.scrollerWidth=Math.max(0,n-t-this.scrollBarV.getWidth()-this.margin.h),i.setStyle(this.$gutter.style,"left",this.margin.left+"px");var a=this.scrollBarV.getWidth()+"px";i.setStyle(this.scrollBarH.element.style,"right",a),i.setStyle(this.scroller.style,"right",a),i.setStyle(this.scroller.style,"bottom",this.scrollBarH.getHeight());if(this.session&&this.session.getUseWrapMode()&&this.adjustWrapLimit()||e)s|=this.CHANGE_FULL}return o.$dirty=!n||!r,s&&this._signal("resize",u),s},this.onGutterResize=function(e){var t=this.$showGutter?e:0;t!=this.gutterWidth&&(this.$changes|=this.$updateCachedSize(!0,t,this.$size.width,this.$size.height)),this.session.getUseWrapMode()&&this.adjustWrapLimit()?this.$loop.schedule(this.CHANGE_FULL):this.$size.$dirty?this.$loop.schedule(this.CHANGE_FULL):this.$computeLayerConfig()},this.adjustWrapLimit=function(){var e=this.$size.scrollerWidth-this.$padding*2,t=Math.floor(e/this.characterWidth);return this.session.adjustWrapLimit(t,this.$showPrintMargin&&this.$printMarginColumn)},this.setAnimatedScroll=function(e){this.setOption("animatedScroll",e)},this.getAnimatedScroll=function(){return this.$animatedScroll},this.setShowInvisibles=function(e){this.setOption("showInvisibles",e),this.session.$bidiHandler.setShowInvisibles(e)},this.getShowInvisibles=function(){return this.getOption("showInvisibles")},this.getDisplayIndentGuides=function(){return this.getOption("displayIndentGuides")},this.setDisplayIndentGuides=function(e){this.setOption("displayIndentGuides",e)},this.setShowPrintMargin=function(e){this.setOption("showPrintMargin",e)},this.getShowPrintMargin=function(){return this.getOption("showPrintMargin")},this.setPrintMarginColumn=function(e){this.setOption("printMarginColumn",e)},this.getPrintMarginColumn=function(){return this.getOption("printMarginColumn")},this.getShowGutter=function(){return this.getOption("showGutter")},this.setShowGutter=function(e){return this.setOption("showGutter",e)},this.getFadeFoldWidgets=function(){return this.getOption("fadeFoldWidgets")},this.setFadeFoldWidgets=function(e){this.setOption("fadeFoldWidgets",e)},this.setHighlightGutterLine=function(e){this.setOption("highlightGutterLine",e)},this.getHighlightGutterLine=function(){return this.getOption("highlightGutterLine")},this.$updatePrintMargin=function(){if(!this.$showPrintMargin&&!this.$printMarginEl)return;if(!this.$printMarginEl){var e=i.createElement("div");e.className="ace_layer ace_print-margin-layer",this.$printMarginEl=i.createElement("div"),this.$printMarginEl.className="ace_print-margin",e.appendChild(this.$printMarginEl),this.content.insertBefore(e,this.content.firstChild)}var t=this.$printMarginEl.style;t.left=Math.round(this.characterWidth*this.$printMarginColumn+this.$padding)+"px",t.visibility=this.$showPrintMargin?"visible":"hidden",this.session&&this.session.$wrap==-1&&this.adjustWrapLimit()},this.getContainerElement=function(){return this.container},this.getMouseEventTarget=function(){return this.scroller},this.getTextAreaContainer=function(){return this.container},this.$moveTextAreaToCursor=function(){var e=this.textarea.style;if(!this.$keepTextAreaAtCursor){i.translate(this.textarea,-100,0);return}var t=this.$cursorLayer.$pixelPos;if(!t)return;var n=this.$composition;n&&n.markerRange&&(t=this.$cursorLayer.getPixelPosition(n.markerRange.start,!0));var r=this.layerConfig,s=t.top,o=t.left;s-=r.offset;var u=n&&n.useTextareaForIME?this.lineHeight:g?0:1;if(s<0||s>r.height-u){i.translate(this.textarea,0,0);return}var a=1;if(!n)s+=this.lineHeight;else if(n.useTextareaForIME){var f=this.textarea.value;a=this.characterWidth*this.session.$getStringScreenWidth(f)[0],u+=2}else s+=this.lineHeight+2;o-=this.scrollLeft,o>this.$size.scrollerWidth-a&&(o=this.$size.scrollerWidth-a),o+=this.gutterWidth+this.margin.left,i.setStyle(e,"height",u+"px"),i.setStyle(e,"width",a+"px"),i.translate(this.textarea,Math.min(o,this.$size.scrollerWidth-a),Math.min(s,this.$size.height-u))},this.getFirstVisibleRow=function(){return this.layerConfig.firstRow},this.getFirstFullyVisibleRow=function(){return this.layerConfig.firstRow+(this.layerConfig.offset===0?0:1)},this.getLastFullyVisibleRow=function(){var e=this.layerConfig,t=e.lastRow,n=this.session.documentToScreenRow(t,0)*e.lineHeight;return n-this.session.getScrollTop()>e.height-e.lineHeight?t-1:t},this.getLastVisibleRow=function(){return this.layerConfig.lastRow},this.$padding=null,this.setPadding=function(e){this.$padding=e,this.$textLayer.setPadding(e),this.$cursorLayer.setPadding(e),this.$markerFront.setPadding(e),this.$markerBack.setPadding(e),this.$loop.schedule(this.CHANGE_FULL),this.$updatePrintMargin()},this.setScrollMargin=function(e,t,n,r){var i=this.scrollMargin;i.top=e|0,i.bottom=t|0,i.right=r|0,i.left=n|0,i.v=i.top+i.bottom,i.h=i.left+i.right,i.top&&this.scrollTop<=0&&this.session&&this.session.setScrollTop(-i.top),this.updateFull()},this.setMargin=function(e,t,n,r){var i=this.margin;i.top=e|0,i.bottom=t|0,i.right=r|0,i.left=n|0,i.v=i.top+i.bottom,i.h=i.left+i.right,this.$updateCachedSize(!0,this.gutterWidth,this.$size.width,this.$size.height),this.updateFull()},this.getHScrollBarAlwaysVisible=function(){return this.$hScrollBarAlwaysVisible},this.setHScrollBarAlwaysVisible=function(e){this.setOption("hScrollBarAlwaysVisible",e)},this.getVScrollBarAlwaysVisible=function(){return this.$vScrollBarAlwaysVisible},this.setVScrollBarAlwaysVisible=function(e){this.setOption("vScrollBarAlwaysVisible",e)},this.$updateScrollBarV=function(){var e=this.layerConfig.maxHeight,t=this.$size.scrollerHeight;!this.$maxLines&&this.$scrollPastEnd&&(e-=(t-this.lineHeight)*this.$scrollPastEnd,this.scrollTop>e-t&&(e=this.scrollTop+t,this.scrollBarV.scrollTop=null)),this.scrollBarV.setScrollHeight(e+this.scrollMargin.v),this.scrollBarV.setScrollTop(this.scrollTop+this.scrollMargin.top)},this.$updateScrollBarH=function(){this.scrollBarH.setScrollWidth(this.layerConfig.width+2*this.$padding+this.scrollMargin.h),this.scrollBarH.setScrollLeft(this.scrollLeft+this.scrollMargin.left)},this.$frozen=!1,this.freeze=function(){this.$frozen=!0},this.unfreeze=function(){this.$frozen=!1},this.$renderChanges=function(e,t){this.$changes&&(e|=this.$changes,this.$changes=0);if(!this.session||!this.container.offsetWidth||this.$frozen||!e&&!t){this.$changes|=e;return}if(this.$size.$dirty)return this.$changes|=e,this.onResize(!0);this.lineHeight||this.$textLayer.checkForSizeChanges(),this._signal("beforeRender"),this.session&&this.session.$bidiHandler&&this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics);var n=this.layerConfig;if(e&this.CHANGE_FULL||e&this.CHANGE_SIZE||e&this.CHANGE_TEXT||e&this.CHANGE_LINES||e&this.CHANGE_SCROLL||e&this.CHANGE_H_SCROLL){e|=this.$computeLayerConfig()|this.$loop.clear();if(n.firstRow!=this.layerConfig.firstRow&&n.firstRowScreen==this.layerConfig.firstRowScreen){var r=this.scrollTop+(n.firstRow-this.layerConfig.firstRow)*this.lineHeight;r>0&&(this.scrollTop=r,e|=this.CHANGE_SCROLL,e|=this.$computeLayerConfig()|this.$loop.clear())}n=this.layerConfig,this.$updateScrollBarV(),e&this.CHANGE_H_SCROLL&&this.$updateScrollBarH(),i.translate(this.content,-this.scrollLeft,-n.offset);var s=n.width+2*this.$padding+"px",o=n.minHeight+"px";i.setStyle(this.content.style,"width",s),i.setStyle(this.content.style,"height",o)}e&this.CHANGE_H_SCROLL&&(i.translate(this.content,-this.scrollLeft,-n.offset),this.scroller.className=this.scrollLeft<=0?"ace_scroller":"ace_scroller ace_scroll-left");if(e&this.CHANGE_FULL){this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this._signal("afterRender");return}if(e&this.CHANGE_SCROLL){e&this.CHANGE_TEXT||e&this.CHANGE_LINES?this.$textLayer.update(n):this.$textLayer.scrollLines(n),this.$showGutter&&(e&this.CHANGE_GUTTER||e&this.CHANGE_LINES?this.$gutterLayer.update(n):this.$gutterLayer.scrollLines(n)),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this._signal("afterRender");return}e&this.CHANGE_TEXT?(this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n)):e&this.CHANGE_LINES?(this.$updateLines()||e&this.CHANGE_GUTTER&&this.$showGutter)&&this.$gutterLayer.update(n):e&this.CHANGE_TEXT||e&this.CHANGE_GUTTER?this.$showGutter&&this.$gutterLayer.update(n):e&this.CHANGE_CURSOR&&this.$highlightGutterLine&&this.$gutterLayer.updateLineHighlight(n),e&this.CHANGE_CURSOR&&(this.$cursorLayer.update(n),this.$moveTextAreaToCursor()),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_FRONT)&&this.$markerFront.update(n),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_BACK)&&this.$markerBack.update(n),this._signal("afterRender")},this.$autosize=function(){var e=this.session.getScreenLength()*this.lineHeight,t=this.$maxLines*this.lineHeight,n=Math.min(t,Math.max((this.$minLines||1)*this.lineHeight,e))+this.scrollMargin.v+(this.$extraHeight||0);this.$horizScroll&&(n+=this.scrollBarH.getHeight()),this.$maxPixelHeight&&n>this.$maxPixelHeight&&(n=this.$maxPixelHeight);var r=n<=2*this.lineHeight,i=!r&&e>t;if(n!=this.desiredHeight||this.$size.height!=this.desiredHeight||i!=this.$vScroll){i!=this.$vScroll&&(this.$vScroll=i,this.scrollBarV.setVisible(i));var s=this.container.clientWidth;this.container.style.height=n+"px",this.$updateCachedSize(!0,this.$gutterWidth,s,n),this.desiredHeight=n,this._signal("autosize")}},this.$computeLayerConfig=function(){var e=this.session,t=this.$size,n=t.height<=2*this.lineHeight,r=this.session.getScreenLength(),i=r*this.lineHeight,s=this.$getLongestLine(),o=!n&&(this.$hScrollBarAlwaysVisible||t.scrollerWidth-s-2*this.$padding<0),u=this.$horizScroll!==o;u&&(this.$horizScroll=o,this.scrollBarH.setVisible(o));var a=this.$vScroll;this.$maxLines&&this.lineHeight>1&&this.$autosize();var f=t.scrollerHeight+this.lineHeight,l=!this.$maxLines&&this.$scrollPastEnd?(t.scrollerHeight-this.lineHeight)*this.$scrollPastEnd:0;i+=l;var c=this.scrollMargin;this.session.setScrollTop(Math.max(-c.top,Math.min(this.scrollTop,i-t.scrollerHeight+c.bottom))),this.session.setScrollLeft(Math.max(-c.left,Math.min(this.scrollLeft,s+2*this.$padding-t.scrollerWidth+c.right)));var h=!n&&(this.$vScrollBarAlwaysVisible||t.scrollerHeight-i+l<0||this.scrollTop>c.top),p=a!==h;p&&(this.$vScroll=h,this.scrollBarV.setVisible(h));var d=this.scrollTop%this.lineHeight,v=Math.ceil(f/this.lineHeight)-1,m=Math.max(0,Math.round((this.scrollTop-d)/this.lineHeight)),g=m+v,y,b,w=this.lineHeight;m=e.screenToDocumentRow(m,0);var E=e.getFoldLine(m);E&&(m=E.start.row),y=e.documentToScreenRow(m,0),b=e.getRowLength(m)*w,g=Math.min(e.screenToDocumentRow(g,0),e.getLength()-1),f=t.scrollerHeight+e.getRowLength(g)*w+b,d=this.scrollTop-y*w;var S=0;if(this.layerConfig.width!=s||u)S=this.CHANGE_H_SCROLL;if(u||p)S=this.$updateCachedSize(!0,this.gutterWidth,t.width,t.height),this._signal("scrollbarVisibilityChanged"),p&&(s=this.$getLongestLine());return this.layerConfig={width:s,padding:this.$padding,firstRow:m,firstRowScreen:y,lastRow:g,lineHeight:w,characterWidth:this.characterWidth,minHeight:f,maxHeight:i,offset:d,gutterOffset:w?Math.max(0,Math.ceil((d+t.height-t.scrollerHeight)/w)):0,height:this.$size.scrollerHeight},this.session.$bidiHandler&&this.session.$bidiHandler.setContentWidth(s-this.$padding),S},this.$updateLines=function(){if(!this.$changedLines)return;var e=this.$changedLines.firstRow,t=this.$changedLines.lastRow;this.$changedLines=null;var n=this.layerConfig;if(e>n.lastRow+1)return;if(t<n.firstRow)return;if(t===Infinity){this.$showGutter&&this.$gutterLayer.update(n),this.$textLayer.update(n);return}return this.$textLayer.updateLines(n,e,t),!0},this.$getLongestLine=function(){var e=this.session.getScreenWidth();return this.showInvisibles&&!this.session.$useWrapMode&&(e+=1),this.$textLayer&&e>this.$textLayer.MAX_LINE_LENGTH&&(e=this.$textLayer.MAX_LINE_LENGTH+30),Math.max(this.$size.scrollerWidth-2*this.$padding,Math.round(e*this.characterWidth))},this.updateFrontMarkers=function(){this.$markerFront.setMarkers(this.session.getMarkers(!0)),this.$loop.schedule(this.CHANGE_MARKER_FRONT)},this.updateBackMarkers=function(){this.$markerBack.setMarkers(this.session.getMarkers()),this.$loop.schedule(this.CHANGE_MARKER_BACK)},this.addGutterDecoration=function(e,t){this.$gutterLayer.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){this.$gutterLayer.removeGutterDecoration(e,t)},this.updateBreakpoints=function(e){this.$loop.schedule(this.CHANGE_GUTTER)},this.setAnnotations=function(e){this.$gutterLayer.setAnnotations(e),this.$loop.schedule(this.CHANGE_GUTTER)},this.updateCursor=function(){this.$loop.schedule(this.CHANGE_CURSOR)},this.hideCursor=function(){this.$cursorLayer.hideCursor()},this.showCursor=function(){this.$cursorLayer.showCursor()},this.scrollSelectionIntoView=function(e,t,n){this.scrollCursorIntoView(e,n),this.scrollCursorIntoView(t,n)},this.scrollCursorIntoView=function(e,t,n){if(this.$size.scrollerHeight===0)return;var r=this.$cursorLayer.getPixelPosition(e),i=r.left,s=r.top,o=n&&n.top||0,u=n&&n.bottom||0,a=this.$scrollAnimation?this.session.getScrollTop():this.scrollTop;a+o>s?(t&&a+o>s+this.lineHeight&&(s-=t*this.$size.scrollerHeight),s===0&&(s=-this.scrollMargin.top),this.session.setScrollTop(s)):a+this.$size.scrollerHeight-u<s+this.lineHeight&&(t&&a+this.$size.scrollerHeight-u<s-this.lineHeight&&(s+=t*this.$size.scrollerHeight),this.session.setScrollTop(s+this.lineHeight+u-this.$size.scrollerHeight));var f=this.scrollLeft;f>i?(i<this.$padding+2*this.layerConfig.characterWidth&&(i=-this.scrollMargin.left),this.session.setScrollLeft(i)):f+this.$size.scrollerWidth<i+this.characterWidth?this.session.setScrollLeft(Math.round(i+this.characterWidth-this.$size.scrollerWidth)):f<=this.$padding&&i-f<this.characterWidth&&this.session.setScrollLeft(0)},this.getScrollTop=function(){return this.session.getScrollTop()},this.getScrollLeft=function(){return this.session.getScrollLeft()},this.getScrollTopRow=function(){return this.scrollTop/this.lineHeight},this.getScrollBottomRow=function(){return Math.max(0,Math.floor((this.scrollTop+this.$size.scrollerHeight)/this.lineHeight)-1)},this.scrollToRow=function(e){this.session.setScrollTop(e*this.lineHeight)},this.alignCursor=function(e,t){typeof e=="number"&&(e={row:e,column:0});var n=this.$cursorLayer.getPixelPosition(e),r=this.$size.scrollerHeight-this.lineHeight,i=n.top-r*(t||0);return this.session.setScrollTop(i),i},this.STEPS=8,this.$calcSteps=function(e,t){var n=0,r=this.STEPS,i=[],s=function(e,t,n){return n*(Math.pow(e-1,3)+1)+t};for(n=0;n<r;++n)i.push(s(n/this.STEPS,e,t-e));return i},this.scrollToLine=function(e,t,n,r){var i=this.$cursorLayer.getPixelPosition({row:e,column:0}),s=i.top;t&&(s-=this.$size.scrollerHeight/2);var o=this.scrollTop;this.session.setScrollTop(s),n!==!1&&this.animateScrolling(o,r)},this.animateScrolling=function(e,t){var n=this.scrollTop;if(!this.$animatedScroll)return;var r=this;if(e==n)return;if(this.$scrollAnimation){var i=this.$scrollAnimation.steps;if(i.length){e=i[0];if(e==n)return}}var s=r.$calcSteps(e,n);this.$scrollAnimation={from:e,to:n,steps:s},clearInterval(this.$timer),r.session.setScrollTop(s.shift()),r.session.$scrollTop=n,this.$timer=setInterval(function(){s.length?(r.session.setScrollTop(s.shift()),r.session.$scrollTop=n):n!=null?(r.session.$scrollTop=-1,r.session.setScrollTop(n),n=null):(r.$timer=clearInterval(r.$timer),r.$scrollAnimation=null,t&&t())},10)},this.scrollToY=function(e){this.scrollTop!==e&&(this.$loop.schedule(this.CHANGE_SCROLL),this.scrollTop=e)},this.scrollToX=function(e){this.scrollLeft!==e&&(this.scrollLeft=e),this.$loop.schedule(this.CHANGE_H_SCROLL)},this.scrollTo=function(e,t){this.session.setScrollTop(t),this.session.setScrollLeft(t)},this.scrollBy=function(e,t){t&&this.session.setScrollTop(this.session.getScrollTop()+t),e&&this.session.setScrollLeft(this.session.getScrollLeft()+e)},this.isScrollableBy=function(e,t){if(t<0&&this.session.getScrollTop()>=1-this.scrollMargin.top)return!0;if(t>0&&this.session.getScrollTop()+this.$size.scrollerHeight-this.layerConfig.maxHeight<-1+this.scrollMargin.bottom)return!0;if(e<0&&this.session.getScrollLeft()>=1-this.scrollMargin.left)return!0;if(e>0&&this.session.getScrollLeft()+this.$size.scrollerWidth-this.layerConfig.width<-1+this.scrollMargin.right)return!0},this.pixelToScreenCoordinates=function(e,t){var n;if(this.$hasCssTransforms){n={top:0,left:0};var r=this.$fontMetrics.transformCoordinates([e,t]);e=r[1]-this.gutterWidth-this.margin.left,t=r[0]}else n=this.scroller.getBoundingClientRect();var i=e+this.scrollLeft-n.left-this.$padding,s=i/this.characterWidth,o=Math.floor((t+this.scrollTop-n.top)/this.lineHeight),u=this.$blockCursor?Math.floor(s):Math.round(s);return{row:o,column:u,side:s-u>0?1:-1,offsetX:i}},this.screenToTextCoordinates=function(e,t){var n;if(this.$hasCssTransforms){n={top:0,left:0};var r=this.$fontMetrics.transformCoordinates([e,t]);e=r[1]-this.gutterWidth-this.margin.left,t=r[0]}else n=this.scroller.getBoundingClientRect();var i=e+this.scrollLeft-n.left-this.$padding,s=i/this.characterWidth,o=this.$blockCursor?Math.floor(s):Math.round(s),u=Math.floor((t+this.scrollTop-n.top)/this.lineHeight);return this.session.screenToDocumentPosition(u,Math.max(o,0),i)},this.textToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=this.session.documentToScreenPosition(e,t),i=this.$padding+(this.session.$bidiHandler.isBidiRow(r.row,e)?this.session.$bidiHandler.getPosLeft(r.column):Math.round(r.column*this.characterWidth)),s=r.row*this.lineHeight;return{pageX:n.left+i-this.scrollLeft,pageY:n.top+s-this.scrollTop}},this.visualizeFocus=function(){i.addCssClass(this.container,"ace_focus")},this.visualizeBlur=function(){i.removeCssClass(this.container,"ace_focus")},this.showComposition=function(e){this.$composition=e,e.cssText||(e.cssText=this.textarea.style.cssText,e.keepTextAreaAtCursor=this.$keepTextAreaAtCursor),e.useTextareaForIME=this.$useTextareaForIME,this.$useTextareaForIME?(this.$keepTextAreaAtCursor=!0,i.addCssClass(this.textarea,"ace_composition"),this.textarea.style.cssText="",this.$moveTextAreaToCursor(),this.$cursorLayer.element.style.display="none"):e.markerId=this.session.addMarker(e.markerRange,"ace_composition_marker","text")},this.setCompositionText=function(e){var t=this.session.selection.cursor;this.addToken(e,"composition_placeholder",t.row,t.column),this.$moveTextAreaToCursor()},this.hideComposition=function(){if(!this.$composition)return;this.$composition.markerId&&this.session.removeMarker(this.$composition.markerId),i.removeCssClass(this.textarea,"ace_composition"),this.$keepTextAreaAtCursor=this.$composition.keepTextAreaAtCursor,this.textarea.style.cssText=this.$composition.cssText,this.$composition=null,this.$cursorLayer.element.style.display=""},this.addToken=function(e,t,n,r){var i=this.session;i.bgTokenizer.lines[n]=null;var s={type:t,value:e},o=i.getTokens(n);if(r==null)o.push(s);else{var u=0;for(var a=0;a<o.length;a++){var f=o[a];u+=f.value.length;if(r<=u){var l=f.value.length-(u-r),c=f.value.slice(0,l),h=f.value.slice(l);o.splice(a,1,{type:f.type,value:c},s,{type:f.type,value:h});break}}}this.updateLines(n,n)},this.setTheme=function(e,t){function o(r){if(n.$themeId!=e)return t&&t();if(!r||!r.cssClass)throw new Error("couldn't load module "+e+" or it didn't call define");r.$id&&(n.$themeId=r.$id),i.importCssString(r.cssText,r.cssClass,n.container),n.theme&&i.removeCssClass(n.container,n.theme.cssClass);var s="padding"in r?r.padding:"padding"in(n.theme||{})?4:n.$padding;n.$padding&&s!=n.$padding&&n.setPadding(s),n.$theme=r.cssClass,n.theme=r,i.addCssClass(n.container,r.cssClass),i.setCssClass(n.container,"ace_dark",r.isDark),n.$size&&(n.$size.width=0,n.$updateSizeAsync()),n._dispatchEvent("themeLoaded",{theme:r}),t&&t()}var n=this;this.$themeId=e,n._dispatchEvent("themeChange",{theme:e});if(!e||typeof e=="string"){var r=e||this.$options.theme.initialValue;s.loadModule(["theme",r],o)}else o(e)},this.getTheme=function(){return this.$themeId},this.setStyle=function(e,t){i.setCssClass(this.container,e,t!==!1)},this.unsetStyle=function(e){i.removeCssClass(this.container,e)},this.setCursorStyle=function(e){i.setStyle(this.scroller.style,"cursor",e)},this.setMouseCursor=function(e){i.setStyle(this.scroller.style,"cursor",e)},this.attachToShadowRoot=function(){i.importCssString(v,"ace_editor.css",this.container)},this.destroy=function(){this.$fontMetrics.destroy(),this.$cursorLayer.destroy()}}).call(y.prototype),s.defineOptions(y.prototype,"renderer",{animatedScroll:{initialValue:!1},showInvisibles:{set:function(e){this.$textLayer.setShowInvisibles(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!1},showPrintMargin:{set:function(){this.$updatePrintMargin()},initialValue:!0},printMarginColumn:{set:function(){this.$updatePrintMargin()},initialValue:80},printMargin:{set:function(e){typeof e=="number"&&(this.$printMarginColumn=e),this.$showPrintMargin=!!e,this.$updatePrintMargin()},get:function(){return this.$showPrintMargin&&this.$printMarginColumn}},showGutter:{set:function(e){this.$gutter.style.display=e?"block":"none",this.$loop.schedule(this.CHANGE_FULL),this.onGutterResize()},initialValue:!0},fadeFoldWidgets:{set:function(e){i.setCssClass(this.$gutter,"ace_fade-fold-widgets",e)},initialValue:!1},showFoldWidgets:{set:function(e){this.$gutterLayer.setShowFoldWidgets(e),this.$loop.schedule(this.CHANGE_GUTTER)},initialValue:!0},displayIndentGuides:{set:function(e){this.$textLayer.setDisplayIndentGuides(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!0},highlightGutterLine:{set:function(e){this.$gutterLayer.setHighlightGutterLine(e),this.$loop.schedule(this.CHANGE_GUTTER)},initialValue:!0},hScrollBarAlwaysVisible:{set:function(e){(!this.$hScrollBarAlwaysVisible||!this.$horizScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},vScrollBarAlwaysVisible:{set:function(e){(!this.$vScrollBarAlwaysVisible||!this.$vScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},fontSize:{set:function(e){typeof e=="number"&&(e+="px"),this.container.style.fontSize=e,this.updateFontSize()},initialValue:12},fontFamily:{set:function(e){this.container.style.fontFamily=e,this.updateFontSize()}},maxLines:{set:function(e){this.updateFull()}},minLines:{set:function(e){this.$minLines<562949953421311||(this.$minLines=0),this.updateFull()}},maxPixelHeight:{set:function(e){this.updateFull()},initialValue:0},scrollPastEnd:{set:function(e){e=+e||0;if(this.$scrollPastEnd==e)return;this.$scrollPastEnd=e,this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:0,handlesSet:!0},fixedWidthGutter:{set:function(e){this.$gutterLayer.$fixedWidth=!!e,this.$loop.schedule(this.CHANGE_GUTTER)}},theme:{set:function(e){this.setTheme(e)},get:function(){return this.$themeId||this.theme},initialValue:"./theme/textmate",handlesSet:!0},hasCssTransforms:{},useTextareaForIME:{initialValue:!m.isMobile&&!m.isIE}}),t.VirtualRenderer=y}),ace.define("ace/worker/worker_client",["require","exports","module","ace/lib/oop","ace/lib/net","ace/lib/event_emitter","ace/config"],function(e,t,n){"use strict";function u(e){var t="importScripts('"+i.qualifyURL(e)+"');";try{return new Blob([t],{type:"application/javascript"})}catch(n){var r=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder,s=new r;return s.append(t),s.getBlob("application/javascript")}}function a(e){if(typeof Worker=="undefined")return{postMessage:function(){},terminate:function(){}};if(o.get("loadWorkerFromBlob")){var t=u(e),n=window.URL||window.webkitURL,r=n.createObjectURL(t);return new Worker(r)}return new Worker(e)}var r=e("../lib/oop"),i=e("../lib/net"),s=e("../lib/event_emitter").EventEmitter,o=e("../config"),f=function(e){e.postMessage||(e=this.$createWorkerFromOldConfig.apply(this,arguments)),this.$worker=e,this.$sendDeltaQueue=this.$sendDeltaQueue.bind(this),this.changeListener=this.changeListener.bind(this),this.onMessage=this.onMessage.bind(this),this.callbackId=1,this.callbacks={},this.$worker.onmessage=this.onMessage};(function(){r.implement(this,s),this.$createWorkerFromOldConfig=function(t,n,r,i,s){e.nameToUrl&&!e.toUrl&&(e.toUrl=e.nameToUrl);if(o.get("packaged")||!e.toUrl)i=i||o.moduleUrl(n,"worker");else{var u=this.$normalizePath;i=i||u(e.toUrl("ace/worker/worker.js",null,"_"));var f={};t.forEach(function(t){f[t]=u(e.toUrl(t,null,"_").replace(/(\.js)?(\?.*)?$/,""))})}return this.$worker=a(i),s&&this.send("importScripts",s),this.$worker.postMessage({init:!0,tlns:f,module:n,classname:r}),this.$worker},this.onMessage=function(e){var t=e.data;switch(t.type){case"event":this._signal(t.name,{data:t.data});break;case"call":var n=this.callbacks[t.id];n&&(n(t.data),delete this.callbacks[t.id]);break;case"error":this.reportError(t.data);break;case"log":window.console&&console.log&&console.log.apply(console,t.data)}},this.reportError=function(e){window.console&&console.error&&console.error(e)},this.$normalizePath=function(e){return i.qualifyURL(e)},this.terminate=function(){this._signal("terminate",{}),this.deltaQueue=null,this.$worker.terminate(),this.$worker=null,this.$doc&&this.$doc.off("change",this.changeListener),this.$doc=null},this.send=function(e,t){this.$worker.postMessage({command:e,args:t})},this.call=function(e,t,n){if(n){var r=this.callbackId++;this.callbacks[r]=n,t.push(r)}this.send(e,t)},this.emit=function(e,t){try{t.data&&t.data.err&&(t.data.err={message:t.data.err.message,stack:t.data.err.stack,code:t.data.err.code}),this.$worker.postMessage({event:e,data:{data:t.data}})}catch(n){console.error(n.stack)}},this.attachToDocument=function(e){this.$doc&&this.terminate(),this.$doc=e,this.call("setValue",[e.getValue()]),e.on("change",this.changeListener)},this.changeListener=function(e){this.deltaQueue||(this.deltaQueue=[],setTimeout(this.$sendDeltaQueue,0)),e.action=="insert"?this.deltaQueue.push(e.start,e.lines):this.deltaQueue.push(e.start,e.end)},this.$sendDeltaQueue=function(){var e=this.deltaQueue;if(!e)return;this.deltaQueue=null,e.length>50&&e.length>this.$doc.getLength()>>1?this.call("setValue",[this.$doc.getValue()]):this.emit("change",{data:e})}}).call(f.prototype);var l=function(e,t,n){var r=null,i=!1,u=Object.create(s),a=[],l=new f({messageBuffer:a,terminate:function(){},postMessage:function(e){a.push(e);if(!r)return;i?setTimeout(c):c()}});l.setEmitSync=function(e){i=e};var c=function(){var e=a.shift();e.command?r[e.command].apply(r,e.args):e.event&&u._signal(e.event,e.data)};return u.postMessage=function(e){l.onMessage({data:e})},u.callback=function(e,t){this.postMessage({type:"call",id:t,data:e})},u.emit=function(e,t){this.postMessage({type:"event",name:e,data:t})},o.loadModule(["worker",t],function(e){r=new e[n](u);while(a.length)c()}),l};t.UIWorkerClient=l,t.WorkerClient=f,t.createWorker=a}),ace.define("ace/placeholder",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/oop"],function(e,t,n){"use strict";var r=e("./range").Range,i=e("./lib/event_emitter").EventEmitter,s=e("./lib/oop"),o=function(e,t,n,r,i,s){var o=this;this.length=t,this.session=e,this.doc=e.getDocument(),this.mainClass=i,this.othersClass=s,this.$onUpdate=this.onUpdate.bind(this),this.doc.on("change",this.$onUpdate),this.$others=r,this.$onCursorChange=function(){setTimeout(function(){o.onCursorChange()})},this.$pos=n;var u=e.getUndoManager().$undoStack||e.getUndoManager().$undostack||{length:-1};this.$undoStackDepth=u.length,this.setup(),e.selection.on("changeCursor",this.$onCursorChange)};(function(){s.implement(this,i),this.setup=function(){var e=this,t=this.doc,n=this.session;this.selectionBefore=n.selection.toJSON(),n.selection.inMultiSelectMode&&n.selection.toSingleRange(),this.pos=t.createAnchor(this.$pos.row,this.$pos.column);var i=this.pos;i.$insertRight=!0,i.detach(),i.markerId=n.addMarker(new r(i.row,i.column,i.row,i.column+this.length),this.mainClass,null,!1),this.others=[],this.$others.forEach(function(n){var r=t.createAnchor(n.row,n.column);r.$insertRight=!0,r.detach(),e.others.push(r)}),n.setUndoSelect(!1)},this.showOtherMarkers=function(){if(this.othersActive)return;var e=this.session,t=this;this.othersActive=!0,this.others.forEach(function(n){n.markerId=e.addMarker(new r(n.row,n.column,n.row,n.column+t.length),t.othersClass,null,!1)})},this.hideOtherMarkers=function(){if(!this.othersActive)return;this.othersActive=!1;for(var e=0;e<this.others.length;e++)this.session.removeMarker(this.others[e].markerId)},this.onUpdate=function(e){if(this.$updating)return this.updateAnchors(e);var t=e;if(t.start.row!==t.end.row)return;if(t.start.row!==this.pos.row)return;this.$updating=!0;var n=e.action==="insert"?t.end.column-t.start.column:t.start.column-t.end.column,i=t.start.column>=this.pos.column&&t.start.column<=this.pos.column+this.length+1,s=t.start.column-this.pos.column;this.updateAnchors(e),i&&(this.length+=n);if(i&&!this.session.$fromUndo)if(e.action==="insert")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.insertMergedLines(a,e.lines)}else if(e.action==="remove")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.remove(new r(a.row,a.column,a.row,a.column-n))}this.$updating=!1,this.updateMarkers()},this.updateAnchors=function(e){this.pos.onChange(e);for(var t=this.others.length;t--;)this.others[t].onChange(e);this.updateMarkers()},this.updateMarkers=function(){if(this.$updating)return;var e=this,t=this.session,n=function(n,i){t.removeMarker(n.markerId),n.markerId=t.addMarker(new r(n.row,n.column,n.row,n.column+e.length),i,null,!1)};n(this.pos,this.mainClass);for(var i=this.others.length;i--;)n(this.others[i],this.othersClass)},this.onCursorChange=function(e){if(this.$updating||!this.session)return;var t=this.session.selection.getCursor();t.row===this.pos.row&&t.column>=this.pos.column&&t.column<=this.pos.column+this.length?(this.showOtherMarkers(),this._emit("cursorEnter",e)):(this.hideOtherMarkers(),this._emit("cursorLeave",e))},this.detach=function(){this.session.removeMarker(this.pos&&this.pos.markerId),this.hideOtherMarkers(),this.doc.removeEventListener("change",this.$onUpdate),this.session.selection.removeEventListener("changeCursor",this.$onCursorChange),this.session.setUndoSelect(!0),this.session=null},this.cancel=function(){if(this.$undoStackDepth===-1)return;var e=this.session.getUndoManager(),t=(e.$undoStack||e.$undostack).length-this.$undoStackDepth;for(var n=0;n<t;n++)e.undo(this.session,!0);this.selectionBefore&&this.session.selection.fromJSON(this.selectionBefore)}}).call(o.prototype),t.PlaceHolder=o}),ace.define("ace/mouse/multi_select_handler",["require","exports","module","ace/lib/event","ace/lib/useragent"],function(e,t,n){function s(e,t){return e.row==t.row&&e.column==t.column}function o(e){var t=e.domEvent,n=t.altKey,o=t.shiftKey,u=t.ctrlKey,a=e.getAccelKey(),f=e.getButton();u&&i.isMac&&(f=t.button);if(e.editor.inMultiSelectMode&&f==2){e.editor.textInput.onContextMenu(e.domEvent);return}if(!u&&!n&&!a){f===0&&e.editor.inMultiSelectMode&&e.editor.exitMultiSelectMode();return}if(f!==0)return;var l=e.editor,c=l.selection,h=l.inMultiSelectMode,p=e.getDocumentPosition(),d=c.getCursor(),v=e.inSelection()||c.isEmpty()&&s(p,d),m=e.x,g=e.y,y=function(e){m=e.clientX,g=e.clientY},b=l.session,w=l.renderer.pixelToScreenCoordinates(m,g),E=w,S;if(l.$mouseHandler.$enableJumpToDef)u&&n||a&&n?S=o?"block":"add":n&&l.$blockSelectEnabled&&(S="block");else if(a&&!n){S="add";if(!h&&o)return}else n&&l.$blockSelectEnabled&&(S="block");S&&i.isMac&&t.ctrlKey&&l.$mouseHandler.cancelContextMenu();if(S=="add"){if(!h&&v)return;if(!h){var x=c.toOrientedRange();l.addSelectionMarker(x)}var T=c.rangeList.rangeAtPoint(p);l.inVirtualSelectionMode=!0,o&&(T=null,x=c.ranges[0]||x,l.removeSelectionMarker(x)),l.once("mouseup",function(){var e=c.toOrientedRange();T&&e.isEmpty()&&s(T.cursor,e.cursor)?c.substractPoint(e.cursor):(o?c.substractPoint(x.cursor):x&&(l.removeSelectionMarker(x),c.addRange(x)),c.addRange(e)),l.inVirtualSelectionMode=!1})}else if(S=="block"){e.stop(),l.inVirtualSelectionMode=!0;var N,C=[],k=function(){var e=l.renderer.pixelToScreenCoordinates(m,g),t=b.screenToDocumentPosition(e.row,e.column,e.offsetX);if(s(E,e)&&s(t,c.lead))return;E=e,l.selection.moveToPosition(t),l.renderer.scrollCursorIntoView(),l.removeSelectionMarkers(C),C=c.rectangularRangeBlock(E,w),l.$mouseHandler.$clickSelection&&C.length==1&&C[0].isEmpty()&&(C[0]=l.$mouseHandler.$clickSelection.clone()),C.forEach(l.addSelectionMarker,l),l.updateSelectionMarkers()};h&&!a?c.toSingleRange():!h&&a&&(N=c.toOrientedRange(),l.addSelectionMarker(N)),o?w=b.documentToScreenPosition(c.lead):c.moveToPosition(p),E={row:-1,column:-1};var L=function(e){k(),clearInterval(O),l.removeSelectionMarkers(C),C.length||(C=[c.toOrientedRange()]),N&&(l.removeSelectionMarker(N),c.toSingleRange(N));for(var t=0;t<C.length;t++)c.addRange(C[t]);l.inVirtualSelectionMode=!1,l.$mouseHandler.$clickSelection=null},A=k;r.capture(l.container,y,L);var O=setInterval(function(){A()},20);return e.preventDefault()}}var r=e("../lib/event"),i=e("../lib/useragent");t.onMouseDown=o}),ace.define("ace/commands/multi_select_commands",["require","exports","module","ace/keyboard/hash_handler"],function(e,t,n){t.defaultCommands=[{name:"addCursorAbove",exec:function(e){e.selectMoreLines(-1)},bindKey:{win:"Ctrl-Alt-Up",mac:"Ctrl-Alt-Up"},scrollIntoView:"cursor",readOnly:!0},{name:"addCursorBelow",exec:function(e){e.selectMoreLines(1)},bindKey:{win:"Ctrl-Alt-Down",mac:"Ctrl-Alt-Down"},scrollIntoView:"cursor",readOnly:!0},{name:"addCursorAboveSkipCurrent",exec:function(e){e.selectMoreLines(-1,!0)},bindKey:{win:"Ctrl-Alt-Shift-Up",mac:"Ctrl-Alt-Shift-Up"},scrollIntoView:"cursor",readOnly:!0},{name:"addCursorBelowSkipCurrent",exec:function(e){e.selectMoreLines(1,!0)},bindKey:{win:"Ctrl-Alt-Shift-Down",mac:"Ctrl-Alt-Shift-Down"},scrollIntoView:"cursor",readOnly:!0},{name:"selectMoreBefore",exec:function(e){e.selectMore(-1)},bindKey:{win:"Ctrl-Alt-Left",mac:"Ctrl-Alt-Left"},scrollIntoView:"cursor",readOnly:!0},{name:"selectMoreAfter",exec:function(e){e.selectMore(1)},bindKey:{win:"Ctrl-Alt-Right",mac:"Ctrl-Alt-Right"},scrollIntoView:"cursor",readOnly:!0},{name:"selectNextBefore",exec:function(e){e.selectMore(-1,!0)},bindKey:{win:"Ctrl-Alt-Shift-Left",mac:"Ctrl-Alt-Shift-Left"},scrollIntoView:"cursor",readOnly:!0},{name:"selectNextAfter",exec:function(e){e.selectMore(1,!0)},bindKey:{win:"Ctrl-Alt-Shift-Right",mac:"Ctrl-Alt-Shift-Right"},scrollIntoView:"cursor",readOnly:!0},{name:"splitIntoLines",exec:function(e){e.multiSelect.splitIntoLines()},bindKey:{win:"Ctrl-Alt-L",mac:"Ctrl-Alt-L"},readOnly:!0},{name:"alignCursors",exec:function(e){e.alignCursors()},bindKey:{win:"Ctrl-Alt-A",mac:"Ctrl-Alt-A"},scrollIntoView:"cursor"},{name:"findAll",exec:function(e){e.findAll()},bindKey:{win:"Ctrl-Alt-K",mac:"Ctrl-Alt-G"},scrollIntoView:"cursor",readOnly:!0}],t.multiSelectCommands=[{name:"singleSelection",bindKey:"esc",exec:function(e){e.exitMultiSelectMode()},scrollIntoView:"cursor",readOnly:!0,isAvailable:function(e){return e&&e.inMultiSelectMode}}];var r=e("../keyboard/hash_handler").HashHandler;t.keyboardHandler=new r(t.multiSelectCommands)}),ace.define("ace/multi_select",["require","exports","module","ace/range_list","ace/range","ace/selection","ace/mouse/multi_select_handler","ace/lib/event","ace/lib/lang","ace/commands/multi_select_commands","ace/search","ace/edit_session","ace/editor","ace/config"],function(e,t,n){function h(e,t,n){return c.$options.wrap=!0,c.$options.needle=t,c.$options.backwards=n==-1,c.find(e)}function v(e,t){return e.row==t.row&&e.column==t.column}function m(e){if(e.$multiselectOnSessionChange)return;e.$onAddRange=e.$onAddRange.bind(e),e.$onRemoveRange=e.$onRemoveRange.bind(e),e.$onMultiSelect=e.$onMultiSelect.bind(e),e.$onSingleSelect=e.$onSingleSelect.bind(e),e.$multiselectOnSessionChange=t.onSessionChange.bind(e),e.$checkMultiselectChange=e.$checkMultiselectChange.bind(e),e.$multiselectOnSessionChange(e),e.on("changeSession",e.$multiselectOnSessionChange),e.on("mousedown",o),e.commands.addCommands(f.defaultCommands),g(e)}function g(e){function r(t){n&&(e.renderer.setMouseCursor(""),n=!1)}var t=e.textInput.getElement(),n=!1;u.addListener(t,"keydown",function(t){var i=t.keyCode==18&&!(t.ctrlKey||t.shiftKey||t.metaKey);e.$blockSelectEnabled&&i?n||(e.renderer.setMouseCursor("crosshair"),n=!0):n&&r()}),u.addListener(t,"keyup",r),u.addListener(t,"blur",r)}var r=e("./range_list").RangeList,i=e("./range").Range,s=e("./selection").Selection,o=e("./mouse/multi_select_handler").onMouseDown,u=e("./lib/event"),a=e("./lib/lang"),f=e("./commands/multi_select_commands");t.commands=f.defaultCommands.concat(f.multiSelectCommands);var l=e("./search").Search,c=new l,p=e("./edit_session").EditSession;(function(){this.getSelectionMarkers=function(){return this.$selectionMarkers}}).call(p.prototype),function(){this.ranges=null,this.rangeList=null,this.addRange=function(e,t){if(!e)return;if(!this.inMultiSelectMode&&this.rangeCount===0){var n=this.toOrientedRange();this.rangeList.add(n),this.rangeList.add(e);if(this.rangeList.ranges.length!=2)return this.rangeList.removeAll(),t||this.fromOrientedRange(e);this.rangeList.removeAll(),this.rangeList.add(n),this.$onAddRange(n)}e.cursor||(e.cursor=e.end);var r=this.rangeList.add(e);return this.$onAddRange(e),r.length&&this.$onRemoveRange(r),this.rangeCount>1&&!this.inMultiSelectMode&&(this._signal("multiSelect"),this.inMultiSelectMode=!0,this.session.$undoSelect=!1,this.rangeList.attach(this.session)),t||this.fromOrientedRange(e)},this.toSingleRange=function(e){e=e||this.ranges[0];var t=this.rangeList.removeAll();t.length&&this.$onRemoveRange(t),e&&this.fromOrientedRange(e)},this.substractPoint=function(e){var t=this.rangeList.substractPoint(e);if(t)return this.$onRemoveRange(t),t[0]},this.mergeOverlappingRanges=function(){var e=this.rangeList.merge();e.length&&this.$onRemoveRange(e)},this.$onAddRange=function(e){this.rangeCount=this.rangeList.ranges.length,this.ranges.unshift(e),this._signal("addRange",{range:e})},this.$onRemoveRange=function(e){this.rangeCount=this.rangeList.ranges.length;if(this.rangeCount==1&&this.inMultiSelectMode){var t=this.rangeList.ranges.pop();e.push(t),this.rangeCount=0}for(var n=e.length;n--;){var r=this.ranges.indexOf(e[n]);this.ranges.splice(r,1)}this._signal("removeRange",{ranges:e}),this.rangeCount===0&&this.inMultiSelectMode&&(this.inMultiSelectMode=!1,this._signal("singleSelect"),this.session.$undoSelect=!0,this.rangeList.detach(this.session)),t=t||this.ranges[0],t&&!t.isEqual(this.getRange())&&this.fromOrientedRange(t)},this.$initRangeList=function(){if(this.rangeList)return;this.rangeList=new r,this.ranges=[],this.rangeCount=0},this.getAllRanges=function(){return this.rangeCount?this.rangeList.ranges.concat():[this.getRange()]},this.splitIntoLines=function(){if(this.rangeCount>1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var n=this.getRange(),r=this.isBackwards(),s=n.start.row,o=n.end.row;if(s==o){if(r)var u=n.end,a=n.start;else var u=n.start,a=n.end;this.addRange(i.fromPoints(a,a)),this.addRange(i.fromPoints(u,u));return}var f=[],l=this.getLineRange(s,!0);l.start.column=n.start.column,f.push(l);for(var c=s+1;c<o;c++)f.push(this.getLineRange(c,!0));l=this.getLineRange(o,!0),l.end.column=n.end.column,f.push(l),f.forEach(this.addRange,this)}},this.toggleBlockSelection=function(){if(this.rangeCount>1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var r=this.session.documentToScreenPosition(this.cursor),s=this.session.documentToScreenPosition(this.anchor),o=this.rectangularRangeBlock(r,s);o.forEach(this.addRange,this)}},this.rectangularRangeBlock=function(e,t,n){var r=[],s=e.column<t.column;if(s)var o=e.column,u=t.column,a=e.offsetX,f=t.offsetX;else var o=t.column,u=e.column,a=t.offsetX,f=e.offsetX;var l=e.row<t.row;if(l)var c=e.row,h=t.row;else var c=t.row,h=e.row;o<0&&(o=0),c<0&&(c=0),c==h&&(n=!0);var p;for(var d=c;d<=h;d++){var m=i.fromPoints(this.session.screenToDocumentPosition(d,o,a),this.session.screenToDocumentPosition(d,u,f));if(m.isEmpty()){if(p&&v(m.end,p))break;p=m.end}m.cursor=s?m.start:m.end,r.push(m)}l&&r.reverse();if(!n){var g=r.length-1;while(r[g].isEmpty()&&g>0)g--;if(g>0){var y=0;while(r[y].isEmpty())y++}for(var b=g;b>=y;b--)r[b].isEmpty()&&r.splice(b,1)}return r}}.call(s.prototype);var d=e("./editor").Editor;(function(){this.updateSelectionMarkers=function(){this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.addSelectionMarker=function(e){e.cursor||(e.cursor=e.end);var t=this.getSelectionStyle();return e.marker=this.session.addMarker(e,"ace_selection",t),this.session.$selectionMarkers.push(e),this.session.selectionMarkerCount=this.session.$selectionMarkers.length,e},this.removeSelectionMarker=function(e){if(!e.marker)return;this.session.removeMarker(e.marker);var t=this.session.$selectionMarkers.indexOf(e);t!=-1&&this.session.$selectionMarkers.splice(t,1),this.session.selectionMarkerCount=this.session.$selectionMarkers.length},this.removeSelectionMarkers=function(e){var t=this.session.$selectionMarkers;for(var n=e.length;n--;){var r=e[n];if(!r.marker)continue;this.session.removeMarker(r.marker);var i=t.indexOf(r);i!=-1&&t.splice(i,1)}this.session.selectionMarkerCount=t.length},this.$onAddRange=function(e){this.addSelectionMarker(e.range),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onRemoveRange=function(e){this.removeSelectionMarkers(e.ranges),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelect=function(e){if(this.inMultiSelectMode)return;this.inMultiSelectMode=!0,this.setStyle("ace_multiselect"),this.keyBinding.addKeyboardHandler(f.keyboardHandler),this.commands.setDefaultHandler("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onSingleSelect=function(e){if(this.session.multiSelect.inVirtualMode)return;this.inMultiSelectMode=!1,this.unsetStyle("ace_multiselect"),this.keyBinding.removeKeyboardHandler(f.keyboardHandler),this.commands.removeDefaultHandler("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers(),this._emit("changeSelection")},this.$onMultiSelectExec=function(e){var t=e.command,n=e.editor;if(!n.multiSelect)return;if(!t.multiSelectAction){var r=t.exec(n,e.args||{});n.multiSelect.addRange(n.multiSelect.toOrientedRange()),n.multiSelect.mergeOverlappingRanges()}else t.multiSelectAction=="forEach"?r=n.forEachSelection(t,e.args):t.multiSelectAction=="forEachLine"?r=n.forEachSelection(t,e.args,!0):t.multiSelectAction=="single"?(n.exitMultiSelectMode(),r=t.exec(n,e.args||{})):r=t.multiSelectAction(n,e.args||{});return r},this.forEachSelection=function(e,t,n){if(this.inVirtualSelectionMode)return;var r=n&&n.keepOrder,i=n==1||n&&n.$byLines,o=this.session,u=this.selection,a=u.rangeList,f=(r?u:a).ranges,l;if(!f.length)return e.exec?e.exec(this,t||{}):e(this,t||{});var c=u._eventRegistry;u._eventRegistry={};var h=new s(o);this.inVirtualSelectionMode=!0;for(var p=f.length;p--;){if(i)while(p>0&&f[p].start.row==f[p-1].end.row)p--;h.fromOrientedRange(f[p]),h.index=p,this.selection=o.selection=h;var d=e.exec?e.exec(this,t||{}):e(this,t||{});!l&&d!==undefined&&(l=d),h.toOrientedRange(f[p])}h.detach(),this.selection=o.selection=u,this.inVirtualSelectionMode=!1,u._eventRegistry=c,u.mergeOverlappingRanges(),u.ranges[0]&&u.fromOrientedRange(u.ranges[0]);var v=this.renderer.$scrollAnimation;return this.onCursorChange(),this.onSelectionChange(),v&&v.from==v.to&&this.renderer.animateScrolling(v.from),l},this.exitMultiSelectMode=function(){if(!this.inMultiSelectMode||this.inVirtualSelectionMode)return;this.multiSelect.toSingleRange()},this.getSelectedText=function(){var e="";if(this.inMultiSelectMode&&!this.inVirtualSelectionMode){var t=this.multiSelect.rangeList.ranges,n=[];for(var r=0;r<t.length;r++)n.push(this.session.getTextRange(t[r]));var i=this.session.getDocument().getNewLineCharacter();e=n.join(i),e.length==(n.length-1)*i.length&&(e="")}else this.selection.isEmpty()||(e=this.session.getTextRange(this.getSelectionRange()));return e},this.$checkMultiselectChange=function(e,t){if(this.inMultiSelectMode&&!this.inVirtualSelectionMode){var n=this.multiSelect.ranges[0];if(this.multiSelect.isEmpty()&&t==this.multiSelect.anchor)return;var r=t==this.multiSelect.anchor?n.cursor==n.start?n.end:n.start:n.cursor;r.row!=t.row||this.session.$clipPositionToDocument(r.row,r.column).column!=t.column?this.multiSelect.toSingleRange(this.multiSelect.toOrientedRange()):this.multiSelect.mergeOverlappingRanges()}},this.findAll=function(e,t,n){t=t||{},t.needle=e||t.needle;if(t.needle==undefined){var r=this.selection.isEmpty()?this.selection.getWordRange():this.selection.getRange();t.needle=this.session.getTextRange(r)}this.$search.set(t);var i=this.$search.findAll(this.session);if(!i.length)return 0;var s=this.multiSelect;n||s.toSingleRange(i[0]);for(var o=i.length;o--;)s.addRange(i[o],!0);return r&&s.rangeList.rangeAtPoint(r.start)&&s.addRange(r,!0),i.length},this.selectMoreLines=function(e,t){var n=this.selection.toOrientedRange(),r=n.cursor==n.end,s=this.session.documentToScreenPosition(n.cursor);this.selection.$desiredColumn&&(s.column=this.selection.$desiredColumn);var o=this.session.screenToDocumentPosition(s.row+e,s.column);if(!n.isEmpty())var u=this.session.documentToScreenPosition(r?n.end:n.start),a=this.session.screenToDocumentPosition(u.row+e,u.column);else var a=o;if(r){var f=i.fromPoints(o,a);f.cursor=f.start}else{var f=i.fromPoints(a,o);f.cursor=f.end}f.desiredColumn=s.column;if(!this.selection.inMultiSelectMode)this.selection.addRange(n);else if(t)var l=n.cursor;this.selection.addRange(f),l&&this.selection.substractPoint(l)},this.transposeSelections=function(e){var t=this.session,n=t.multiSelect,r=n.ranges;for(var i=r.length;i--;){var s=r[i];if(s.isEmpty()){var o=t.getWordRange(s.start.row,s.start.column);s.start.row=o.start.row,s.start.column=o.start.column,s.end.row=o.end.row,s.end.column=o.end.column}}n.mergeOverlappingRanges();var u=[];for(var i=r.length;i--;){var s=r[i];u.unshift(t.getTextRange(s))}e<0?u.unshift(u.pop()):u.push(u.shift());for(var i=r.length;i--;){var s=r[i],o=s.clone();t.replace(s,u[i]),s.start.row=o.start.row,s.start.column=o.start.column}n.fromOrientedRange(n.ranges[0])},this.selectMore=function(e,t,n){var r=this.session,i=r.multiSelect,s=i.toOrientedRange();if(s.isEmpty()){s=r.getWordRange(s.start.row,s.start.column),s.cursor=e==-1?s.start:s.end,this.multiSelect.addRange(s);if(n)return}var o=r.getTextRange(s),u=h(r,o,e);u&&(u.cursor=e==-1?u.start:u.end,this.session.unfold(u),this.multiSelect.addRange(u),this.renderer.scrollCursorIntoView(null,.5)),t&&this.multiSelect.substractPoint(s.cursor)},this.alignCursors=function(){var e=this.session,t=e.multiSelect,n=t.ranges,r=-1,s=n.filter(function(e){if(e.cursor.row==r)return!0;r=e.cursor.row});if(!n.length||s.length==n.length-1){var o=this.selection.getRange(),u=o.start.row,f=o.end.row,l=u==f;if(l){var c=this.session.getLength(),h;do h=this.session.getLine(f);while(/[=:]/.test(h)&&++f<c);do h=this.session.getLine(u);while(/[=:]/.test(h)&&--u>0);u<0&&(u=0),f>=c&&(f=c-1)}var p=this.session.removeFullLines(u,f);p=this.$reAlignText(p,l),this.session.insert({row:u,column:0},p.join("\n")+"\n"),l||(o.start.column=0,o.end.column=p[p.length-1].length),this.selection.setRange(o)}else{s.forEach(function(e){t.substractPoint(e.cursor)});var d=0,v=Infinity,m=n.map(function(t){var n=t.cursor,r=e.getLine(n.row),i=r.substr(n.column).search(/\S/g);return i==-1&&(i=0),n.column>d&&(d=n.column),i<v&&(v=i),i});n.forEach(function(t,n){var r=t.cursor,s=d-r.column,o=m[n]-v;s>o?e.insert(r,a.stringRepeat(" ",s-o)):e.remove(new i(r.row,r.column,r.row,r.column-s+o)),t.start.column=t.end.column=d,t.start.row=t.end.row=r.row,t.cursor=t.end}),t.fromOrientedRange(n[0]),this.renderer.updateCursor(),this.renderer.updateBackMarkers()}},this.$reAlignText=function(e,t){function u(e){return a.stringRepeat(" ",e)}function f(e){return e[2]?u(i)+e[2]+u(s-e[2].length+o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}function l(e){return e[2]?u(i+s-e[2].length)+e[2]+u(o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}function c(e){return e[2]?u(i)+e[2]+u(o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}var n=!0,r=!0,i,s,o;return e.map(function(e){var t=e.match(/(\s*)(.*?)(\s*)([=:].*)/);return t?i==null?(i=t[1].length,s=t[2].length,o=t[3].length,t):(i+s+o!=t[1].length+t[2].length+t[3].length&&(r=!1),i!=t[1].length&&(n=!1),i>t[1].length&&(i=t[1].length),s<t[2].length&&(s=t[2].length),o>t[3].length&&(o=t[3].length),t):[e]}).map(t?f:n?r?l:f:c)}}).call(d.prototype),t.onSessionChange=function(e){var t=e.session;t&&!t.multiSelect&&(t.$selectionMarkers=[],t.selection.$initRangeList(),t.multiSelect=t.selection),this.multiSelect=t&&t.multiSelect;var n=e.oldSession;n&&(n.multiSelect.off("addRange",this.$onAddRange),n.multiSelect.off("removeRange",this.$onRemoveRange),n.multiSelect.off("multiSelect",this.$onMultiSelect),n.multiSelect.off("singleSelect",this.$onSingleSelect),n.multiSelect.lead.off("change",this.$checkMultiselectChange),n.multiSelect.anchor.off("change",this.$checkMultiselectChange)),t&&(t.multiSelect.on("addRange",this.$onAddRange),t.multiSelect.on("removeRange",this.$onRemoveRange),t.multiSelect.on("multiSelect",this.$onMultiSelect),t.multiSelect.on("singleSelect",this.$onSingleSelect),t.multiSelect.lead.on("change",this.$checkMultiselectChange),t.multiSelect.anchor.on("change",this.$checkMultiselectChange)),t&&this.inMultiSelectMode!=t.selection.inMultiSelectMode&&(t.selection.inMultiSelectMode?this.$onMultiSelect():this.$onSingleSelect())},t.MultiSelect=m,e("./config").defineOptions(d.prototype,"editor",{enableMultiselect:{set:function(e){m(this),e?(this.on("changeSession",this.$multiselectOnSessionChange),this.on("mousedown",o)):(this.off("changeSession",this.$multiselectOnSessionChange),this.off("mousedown",o))},value:!0},enableBlockSelect:{set:function(e){this.$blockSelectEnabled=e},value:!0}})}),ace.define("ace/mode/folding/fold_mode",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../../range").Range,i=t.FoldMode=function(){};(function(){this.foldingStartMarker=null,this.foldingStopMarker=null,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);return this.foldingStartMarker.test(r)?"start":t=="markbeginend"&&this.foldingStopMarker&&this.foldingStopMarker.test(r)?"end":""},this.getFoldWidgetRange=function(e,t,n){return null},this.indentationBlock=function(e,t,n){var i=/\S/,s=e.getLine(t),o=s.search(i);if(o==-1)return;var u=n||s.length,a=e.getLength(),f=t,l=t;while(++t<a){var c=e.getLine(t).search(i);if(c==-1)continue;if(c<=o)break;l=t}if(l>f){var h=e.getLine(l).length;return new r(f,u,l,h)}},this.openingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i+1},u=e.$findClosingBracket(t,o,s);if(!u)return;var a=e.foldWidgets[u.row];return a==null&&(a=e.getFoldWidget(u.row)),a=="start"&&u.row>o.row&&(u.row--,u.column=e.getLine(u.row).length),r.fromPoints(o,u)},this.closingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i},u=e.$findOpeningBracket(t,o);if(!u)return;return u.column++,o.column--,r.fromPoints(u,o)}}).call(i.prototype)}),ace.define("ace/theme/textmate",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";t.isDark=!1,t.cssClass="ace-tm",t.cssText='.ace-tm .ace_gutter {background: #f0f0f0;color: #333;}.ace-tm .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-tm .ace_fold {background-color: #6B72E6;}.ace-tm {background-color: #FFFFFF;color: black;}.ace-tm .ace_cursor {color: black;}.ace-tm .ace_invisible {color: rgb(191, 191, 191);}.ace-tm .ace_storage,.ace-tm .ace_keyword {color: blue;}.ace-tm .ace_constant {color: rgb(197, 6, 11);}.ace-tm .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-tm .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-tm .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-tm .ace_invalid {background-color: rgba(255, 0, 0, 0.1);color: red;}.ace-tm .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-tm .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-tm .ace_support.ace_type,.ace-tm .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-tm .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-tm .ace_string {color: rgb(3, 106, 7);}.ace-tm .ace_comment {color: rgb(76, 136, 107);}.ace-tm .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-tm .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-tm .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-tm .ace_variable {color: rgb(49, 132, 149);}.ace-tm .ace_xml-pe {color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-tm .ace_heading {color: rgb(12, 7, 255);}.ace-tm .ace_list {color:rgb(185, 6, 144);}.ace-tm .ace_meta.ace_tag {color:rgb(0, 22, 142);}.ace-tm .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-tm .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-tm.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;}.ace-tm .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter-active-line {background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}',t.$id="ace/theme/textmate";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}),ace.define("ace/line_widgets",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/range"],function(e,t,n){"use strict";function o(e){this.session=e,this.session.widgetManager=this,this.session.getRowLength=this.getRowLength,this.session.$getWidgetScreenLength=this.$getWidgetScreenLength,this.updateOnChange=this.updateOnChange.bind(this),this.renderWidgets=this.renderWidgets.bind(this),this.measureWidgets=this.measureWidgets.bind(this),this.session._changedWidgets=[],this.$onChangeEditor=this.$onChangeEditor.bind(this),this.session.on("change",this.updateOnChange),this.session.on("changeFold",this.updateOnFold),this.session.on("changeEditor",this.$onChangeEditor)}var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./range").Range;(function(){this.getRowLength=function(e){var t;return this.lineWidgets?t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0:t=0,!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.$getWidgetScreenLength=function(){var e=0;return this.lineWidgets.forEach(function(t){t&&t.rowCount&&!t.hidden&&(e+=t.rowCount)}),e},this.$onChangeEditor=function(e){this.attach(e.editor)},this.attach=function(e){e&&e.widgetManager&&e.widgetManager!=this&&e.widgetManager.detach();if(this.editor==e)return;this.detach(),this.editor=e,e&&(e.widgetManager=this,e.renderer.on("beforeRender",this.measureWidgets),e.renderer.on("afterRender",this.renderWidgets))},this.detach=function(e){var t=this.editor;if(!t)return;this.editor=null,t.widgetManager=null,t.renderer.off("beforeRender",this.measureWidgets),t.renderer.off("afterRender",this.renderWidgets);var n=this.session.lineWidgets;n&&n.forEach(function(e){e&&e.el&&e.el.parentNode&&(e._inDocument=!1,e.el.parentNode.removeChild(e.el))})},this.updateOnFold=function(e,t){var n=t.lineWidgets;if(!n||!e.action)return;var r=e.data,i=r.start.row,s=r.end.row,o=e.action=="add";for(var u=i+1;u<s;u++)n[u]&&(n[u].hidden=o);n[s]&&(o?n[i]?n[s].hidden=o:n[i]=n[s]:(n[i]==n[s]&&(n[i]=undefined),n[s].hidden=o))},this.updateOnChange=function(e){var t=this.session.lineWidgets;if(!t)return;var n=e.start.row,r=e.end.row-n;if(r!==0)if(e.action=="remove"){var i=t.splice(n+1,r);i.forEach(function(e){e&&this.removeLineWidget(e)},this),this.$updateRows()}else{var s=new Array(r);s.unshift(n,0),t.splice.apply(t,s),this.$updateRows()}},this.$updateRows=function(){var e=this.session.lineWidgets;if(!e)return;var t=!0;e.forEach(function(e,n){if(e){t=!1,e.row=n;while(e.$oldWidget)e.$oldWidget.row=n,e=e.$oldWidget}}),t&&(this.session.lineWidgets=null)},this.addLineWidget=function(e){this.session.lineWidgets||(this.session.lineWidgets=new Array(this.session.getLength()));var t=this.session.lineWidgets[e.row];t&&(e.$oldWidget=t,t.el&&t.el.parentNode&&(t.el.parentNode.removeChild(t.el),t._inDocument=!1)),this.session.lineWidgets[e.row]=e,e.session=this.session;var n=this.editor.renderer;e.html&&!e.el&&(e.el=i.createElement("div"),e.el.innerHTML=e.html),e.el&&(i.addCssClass(e.el,"ace_lineWidgetContainer"),e.el.style.position="absolute",e.el.style.zIndex=5,n.container.appendChild(e.el),e._inDocument=!0),e.coverGutter||(e.el.style.zIndex=3),e.pixelHeight==null&&(e.pixelHeight=e.el.offsetHeight),e.rowCount==null&&(e.rowCount=e.pixelHeight/n.layerConfig.lineHeight);var r=this.session.getFoldAt(e.row,0);e.$fold=r;if(r){var s=this.session.lineWidgets;e.row==r.end.row&&!s[r.start.row]?s[r.start.row]=e:e.hidden=!0}return this.session._emit("changeFold",{data:{start:{row:e.row}}}),this.$updateRows(),this.renderWidgets(null,n),this.onWidgetChanged(e),e},this.removeLineWidget=function(e){e._inDocument=!1,e.session=null,e.el&&e.el.parentNode&&e.el.parentNode.removeChild(e.el);if(e.editor&&e.editor.destroy)try{e.editor.destroy()}catch(t){}if(this.session.lineWidgets){var n=this.session.lineWidgets[e.row];if(n==e)this.session.lineWidgets[e.row]=e.$oldWidget,e.$oldWidget&&this.onWidgetChanged(e.$oldWidget);else while(n){if(n.$oldWidget==e){n.$oldWidget=e.$oldWidget;break}n=n.$oldWidget}}this.session._emit("changeFold",{data:{start:{row:e.row}}}),this.$updateRows()},this.getWidgetsAtRow=function(e){var t=this.session.lineWidgets,n=t&&t[e],r=[];while(n)r.push(n),n=n.$oldWidget;return r},this.onWidgetChanged=function(e){this.session._changedWidgets.push(e),this.editor&&this.editor.renderer.updateFull()},this.measureWidgets=function(e,t){var n=this.session._changedWidgets,r=t.layerConfig;if(!n||!n.length)return;var i=Infinity;for(var s=0;s<n.length;s++){var o=n[s];if(!o||!o.el)continue;if(o.session!=this.session)continue;if(!o._inDocument){if(this.session.lineWidgets[o.row]!=o)continue;o._inDocument=!0,t.container.appendChild(o.el)}o.h=o.el.offsetHeight,o.fixedWidth||(o.w=o.el.offsetWidth,o.screenWidth=Math.ceil(o.w/r.characterWidth));var u=o.h/r.lineHeight;o.coverLine&&(u-=this.session.getRowLineCount(o.row),u<0&&(u=0)),o.rowCount!=u&&(o.rowCount=u,o.row<i&&(i=o.row))}i!=Infinity&&(this.session._emit("changeFold",{data:{start:{row:i}}}),this.session.lineWidgetWidth=null),this.session._changedWidgets=[]},this.renderWidgets=function(e,t){var n=t.layerConfig,r=this.session.lineWidgets;if(!r)return;var i=Math.min(this.firstRow,n.firstRow),s=Math.max(this.lastRow,n.lastRow,r.length);while(i>0&&!r[i])i--;this.firstRow=n.firstRow,this.lastRow=n.lastRow,t.$cursorLayer.config=n;for(var o=i;o<=s;o++){var u=r[o];if(!u||!u.el)continue;if(u.hidden){u.el.style.top=-100-(u.pixelHeight||0)+"px";continue}u._inDocument||(u._inDocument=!0,t.container.appendChild(u.el));var a=t.$cursorLayer.getPixelPosition({row:o,column:0},!0).top;u.coverLine||(a+=n.lineHeight*this.session.getRowLineCount(u.row)),u.el.style.top=a-n.offset+"px";var f=u.coverGutter?0:t.gutterWidth;u.fixedWidth||(f-=t.scrollLeft),u.el.style.left=f+"px",u.fullWidth&&u.screenWidth&&(u.el.style.minWidth=n.width+2*n.padding+"px"),u.fixedWidth?u.el.style.right=t.scrollBar.getWidth()+"px":u.el.style.right=""}}}).call(o.prototype),t.LineWidgets=o}),ace.define("ace/ext/error_marker",["require","exports","module","ace/line_widgets","ace/lib/dom","ace/range"],function(e,t,n){"use strict";function o(e,t,n){var r=0,i=e.length-1;while(r<=i){var s=r+i>>1,o=n(t,e[s]);if(o>0)r=s+1;else{if(!(o<0))return s;i=s-1}}return-(r+1)}function u(e,t,n){var r=e.getAnnotations().sort(s.comparePoints);if(!r.length)return;var i=o(r,{row:t,column:-1},s.comparePoints);i<0&&(i=-i-1),i>=r.length?i=n>0?0:r.length-1:i===0&&n<0&&(i=r.length-1);var u=r[i];if(!u||!n)return;if(u.row===t){do u=r[i+=n];while(u&&u.row===t);if(!u)return r.slice()}var a=[];t=u.row;do a[n<0?"unshift":"push"](u),u=r[i+=n];while(u&&u.row==t);return a.length&&a}var r=e("../line_widgets").LineWidgets,i=e("../lib/dom"),s=e("../range").Range;t.showErrorMarker=function(e,t){var n=e.session;n.widgetManager||(n.widgetManager=new r(n),n.widgetManager.attach(e));var s=e.getCursorPosition(),o=s.row,a=n.widgetManager.getWidgetsAtRow(o).filter(function(e){return e.type=="errorMarker"})[0];a?a.destroy():o-=t;var f=u(n,o,t),l;if(f){var c=f[0];s.column=(c.pos&&typeof c.column!="number"?c.pos.sc:c.column)||0,s.row=c.row,l=e.renderer.$gutterLayer.$annotations[s.row]}else{if(a)return;l={text:["Looks good!"],className:"ace_ok"}}e.session.unfold(s.row),e.selection.moveToPosition(s);var h={row:s.row,fixedWidth:!0,coverGutter:!0,el:i.createElement("div"),type:"errorMarker"},p=h.el.appendChild(i.createElement("div")),d=h.el.appendChild(i.createElement("div"));d.className="error_widget_arrow "+l.className;var v=e.renderer.$cursorLayer.getPixelPosition(s).left;d.style.left=v+e.renderer.gutterWidth-5+"px",h.el.className="error_widget_wrapper",p.className="error_widget "+l.className,p.innerHTML=l.text.join("<br>"),p.appendChild(i.createElement("div"));var m=function(e,t,n){if(t===0&&(n==="esc"||n==="return"))return h.destroy(),{command:"null"}};h.destroy=function(){if(e.$mouseHandler.isMousePressed)return;e.keyBinding.removeKeyboardHandler(m),n.widgetManager.removeLineWidget(h),e.off("changeSelection",h.destroy),e.off("changeSession",h.destroy),e.off("mouseup",h.destroy),e.off("change",h.destroy)},e.keyBinding.addKeyboardHandler(m),e.on("changeSelection",h.destroy),e.on("changeSession",h.destroy),e.on("mouseup",h.destroy),e.on("change",h.destroy),e.session.widgetManager.addLineWidget(h),h.el.onmousedown=e.focus.bind(e),e.renderer.scrollCursorIntoView(null,.5,{bottom:h.el.offsetHeight})},i.importCssString(" .error_widget_wrapper { background: inherit; color: inherit; border:none } .error_widget { border-top: solid 2px; border-bottom: solid 2px; margin: 5px 0; padding: 10px 40px; white-space: pre-wrap; } .error_widget.ace_error, .error_widget_arrow.ace_error{ border-color: #ff5a5a } .error_widget.ace_warning, .error_widget_arrow.ace_warning{ border-color: #F1D817 } .error_widget.ace_info, .error_widget_arrow.ace_info{ border-color: #5a5a5a } .error_widget.ace_ok, .error_widget_arrow.ace_ok{ border-color: #5aaa5a } .error_widget_arrow { position: absolute; border: solid 5px; border-top-color: transparent!important; border-right-color: transparent!important; border-left-color: transparent!important; top: -5px; }","")}),ace.define("ace/ace",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/dom","ace/lib/event","ace/range","ace/editor","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/worker/worker_client","ace/keyboard/hash_handler","ace/placeholder","ace/multi_select","ace/mode/folding/fold_mode","ace/theme/textmate","ace/ext/error_marker","ace/config"],function(e,t,n){"use strict";e("./lib/fixoldbrowsers");var r=e("./lib/dom"),i=e("./lib/event"),s=e("./range").Range,o=e("./editor").Editor,u=e("./edit_session").EditSession,a=e("./undomanager").UndoManager,f=e("./virtual_renderer").VirtualRenderer;e("./worker/worker_client"),e("./keyboard/hash_handler"),e("./placeholder"),e("./multi_select"),e("./mode/folding/fold_mode"),e("./theme/textmate"),e("./ext/error_marker"),t.config=e("./config"),t.require=e,typeof define=="function"&&(t.define=define),t.edit=function(e,n){if(typeof e=="string"){var s=e;e=document.getElementById(s);if(!e)throw new Error("ace.edit can't find div #"+s)}if(e&&e.env&&e.env.editor instanceof o)return e.env.editor;var u="";if(e&&/input|textarea/i.test(e.tagName)){var a=e;u=a.value,e=r.createElement("pre"),a.parentNode.replaceChild(e,a)}else e&&(u=e.textContent,e.innerHTML="");var l=t.createEditSession(u),c=new o(new f(e),l,n),h={document:l,editor:c,onResize:c.resize.bind(c,null)};return a&&(h.textarea=a),i.addListener(window,"resize",h.onResize),c.on("destroy",function(){i.removeListener(window,"resize",h.onResize),h.editor.container.env=null}),c.container.env=c.env=h,c},t.createEditSession=function(e,t){var n=new u(e,t);return n.setUndoManager(new a),n},t.Range=s,t.Editor=o,t.EditSession=u,t.UndoManager=a,t.VirtualRenderer=f,t.version="1.4.3"}); (function() { + ace.require(["ace/ace"], function(a) { + if (a) { + a.config.init(true); + a.define = ace.define; + } + if (!window.ace) + window.ace = a; + for (var key in a) if (a.hasOwnProperty(key)) + window.ace[key] = a[key]; + window.ace["default"] = window.ace; + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = window.ace; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/ext-language_tools.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/ext-language_tools.js new file mode 100644 index 0000000..0812c77 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/ext-language_tools.js @@ -0,0 +1,8 @@ +ace.define("ace/snippets",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/anchor","ace/keyboard/hash_handler","ace/tokenizer","ace/lib/dom","ace/editor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=e("./lib/lang"),o=e("./range").Range,u=e("./anchor").Anchor,a=e("./keyboard/hash_handler").HashHandler,f=e("./tokenizer").Tokenizer,l=o.comparePoints,c=function(){this.snippetMap={},this.snippetNameMap={}};(function(){r.implement(this,i),this.getTokenizer=function(){function e(e,t,n){return e=e.substr(1),/^\d+$/.test(e)&&!n.inFormatString?[{tabstopId:parseInt(e,10)}]:[{text:e}]}function t(e){return"(?:[^\\\\"+e+"]|\\\\.)"}return c.$tokenizer=new f({start:[{regex:/:/,onMatch:function(e,t,n){return n.length&&n[0].expectIf?(n[0].expectIf=!1,n[0].elseBranch=n[0],[n[0]]):":"}},{regex:/\\./,onMatch:function(e,t,n){var r=e[1];return r=="}"&&n.length?e=r:"`$\\".indexOf(r)!=-1?e=r:n.inFormatString&&(r=="n"?e="\n":r=="t"?e="\n":"ulULE".indexOf(r)!=-1&&(e={changeCase:r,local:r>"a"})),[e]}},{regex:/}/,onMatch:function(e,t,n){return[n.length?n.shift():e]}},{regex:/\$(?:\d+|\w+)/,onMatch:e},{regex:/\$\{[\dA-Z_a-z]+/,onMatch:function(t,n,r){var i=e(t.substr(1),n,r);return r.unshift(i[0]),i},next:"snippetVar"},{regex:/\n/,token:"newline",merge:!1}],snippetVar:[{regex:"\\|"+t("\\|")+"*\\|",onMatch:function(e,t,n){n[0].choices=e.slice(1,-1).split(",")},next:"start"},{regex:"/("+t("/")+"+)/(?:("+t("/")+"*)/)(\\w*):?",onMatch:function(e,t,n){var r=n[0];return r.fmtString=e,e=this.splitRegex.exec(e),r.guard=e[1],r.fmt=e[2],r.flag=e[3],""},next:"start"},{regex:"`"+t("`")+"*`",onMatch:function(e,t,n){return n[0].code=e.splice(1,-1),""},next:"start"},{regex:"\\?",onMatch:function(e,t,n){n[0]&&(n[0].expectIf=!0)},next:"start"},{regex:"([^:}\\\\]|\\\\.)*:?",token:"",next:"start"}],formatString:[{regex:"/("+t("/")+"+)/",token:"regex"},{regex:"",onMatch:function(e,t,n){n.inFormatString=!0},next:"start"}]}),c.prototype.getTokenizer=function(){return c.$tokenizer},c.$tokenizer},this.tokenizeTmSnippet=function(e,t){return this.getTokenizer().getLineTokens(e,t).tokens.map(function(e){return e.value||e})},this.$getDefaultValue=function(e,t){if(/^[A-Z]\d+$/.test(t)){var n=t.substr(1);return(this.variables[t[0]+"__"]||{})[n]}if(/^\d+$/.test(t))return(this.variables.__||{})[t];t=t.replace(/^TM_/,"");if(!e)return;var r=e.session;switch(t){case"CURRENT_WORD":var i=r.getWordRange();case"SELECTION":case"SELECTED_TEXT":return r.getTextRange(i);case"CURRENT_LINE":return r.getLine(e.getCursorPosition().row);case"PREV_LINE":return r.getLine(e.getCursorPosition().row-1);case"LINE_INDEX":return e.getCursorPosition().column;case"LINE_NUMBER":return e.getCursorPosition().row+1;case"SOFT_TABS":return r.getUseSoftTabs()?"YES":"NO";case"TAB_SIZE":return r.getTabSize();case"FILENAME":case"FILEPATH":return"";case"FULLNAME":return"Ace"}},this.variables={},this.getVariableValue=function(e,t){return this.variables.hasOwnProperty(t)?this.variables[t](e,t)||"":this.$getDefaultValue(e,t)||""},this.tmStrFormat=function(e,t,n){var r=t.flag||"",i=t.guard;i=new RegExp(i,r.replace(/[^gi]/,""));var s=this.tokenizeTmSnippet(t.fmt,"formatString"),o=this,u=e.replace(i,function(){o.variables.__=arguments;var e=o.resolveVariables(s,n),t="E";for(var r=0;r<e.length;r++){var i=e[r];if(typeof i=="object"){e[r]="";if(i.changeCase&&i.local){var u=e[r+1];u&&typeof u=="string"&&(i.changeCase=="u"?e[r]=u[0].toUpperCase():e[r]=u[0].toLowerCase(),e[r+1]=u.substr(1))}else i.changeCase&&(t=i.changeCase)}else t=="U"?e[r]=i.toUpperCase():t=="L"&&(e[r]=i.toLowerCase())}return e.join("")});return this.variables.__=null,u},this.resolveVariables=function(e,t){function o(t){var n=e.indexOf(t,r+1);n!=-1&&(r=n)}var n=[];for(var r=0;r<e.length;r++){var i=e[r];if(typeof i=="string")n.push(i);else{if(typeof i!="object")continue;if(i.skip)o(i);else{if(i.processed<r)continue;if(i.text){var s=this.getVariableValue(t,i.text);s&&i.fmtString&&(s=this.tmStrFormat(s,i)),i.processed=r,i.expectIf==null?s&&(n.push(s),o(i)):s?i.skip=i.elseBranch:o(i)}else i.tabstopId!=null?n.push(i):i.changeCase!=null&&n.push(i)}}}return n},this.insertSnippetForSelection=function(e,t){function f(e){var t=[];for(var n=0;n<e.length;n++){var r=e[n];if(typeof r=="object"){if(a[r.tabstopId])continue;var i=e.lastIndexOf(r,n-1);r=t[i]||{tabstopId:r.tabstopId}}t[n]=r}return t}var n=e.getCursorPosition(),r=e.session.getLine(n.row),i=e.session.getTabString(),s=r.match(/^\s*/)[0];n.column<s.length&&(s=s.slice(0,n.column)),t=t.replace(/\r/g,"");var o=this.tokenizeTmSnippet(t);o=this.resolveVariables(o,e),o=o.map(function(e){return e=="\n"?e+s:typeof e=="string"?e.replace(/\t/g,i):e});var u=[];o.forEach(function(e,t){if(typeof e!="object")return;var n=e.tabstopId,r=u[n];r||(r=u[n]=[],r.index=n,r.value="");if(r.indexOf(e)!==-1)return;r.push(e);var i=o.indexOf(e,t+1);if(i===-1)return;var s=o.slice(t+1,i),a=s.some(function(e){return typeof e=="object"});a&&!r.value?r.value=s:s.length&&(!r.value||typeof r.value!="string")&&(r.value=s.join(""))}),u.forEach(function(e){e.length=0});var a={};for(var l=0;l<o.length;l++){var c=o[l];if(typeof c!="object")continue;var p=c.tabstopId,d=o.indexOf(c,l+1);if(a[p]){a[p]===c&&(a[p]=null);continue}var v=u[p],m=typeof v.value=="string"?[v.value]:f(v.value);m.unshift(l+1,Math.max(0,d-l)),m.push(c),a[p]=c,o.splice.apply(o,m),v.indexOf(c)===-1&&v.push(c)}var g=0,y=0,b="";o.forEach(function(e){if(typeof e=="string"){var t=e.split("\n");t.length>1?(y=t[t.length-1].length,g+=t.length-1):y+=e.length,b+=e}else e.start?e.end={row:g,column:y}:e.start={row:g,column:y}});var w=e.getSelectionRange(),E=e.session.replace(w,b),S=new h(e),x=e.inVirtualSelectionMode&&e.selection.index;S.addTabstops(u,w.start,E,x)},this.insertSnippet=function(e,t){var n=this;if(e.inVirtualSelectionMode)return n.insertSnippetForSelection(e,t);e.forEachSelection(function(){n.insertSnippetForSelection(e,t)},null,{keepOrder:!0}),e.tabstopManager&&e.tabstopManager.tabNext()},this.$getScope=function(e){var t=e.session.$mode.$id||"";t=t.split("/").pop();if(t==="html"||t==="php"){t==="php"&&!e.session.$mode.inlinePhp&&(t="html");var n=e.getCursorPosition(),r=e.session.getState(n.row);typeof r=="object"&&(r=r[0]),r.substring&&(r.substring(0,3)=="js-"?t="javascript":r.substring(0,4)=="css-"?t="css":r.substring(0,4)=="php-"&&(t="php"))}return t},this.getActiveScopes=function(e){var t=this.$getScope(e),n=[t],r=this.snippetMap;return r[t]&&r[t].includeScopes&&n.push.apply(n,r[t].includeScopes),n.push("_"),n},this.expandWithTab=function(e,t){var n=this,r=e.forEachSelection(function(){return n.expandSnippetForSelection(e,t)},null,{keepOrder:!0});return r&&e.tabstopManager&&e.tabstopManager.tabNext(),r},this.expandSnippetForSelection=function(e,t){var n=e.getCursorPosition(),r=e.session.getLine(n.row),i=r.substring(0,n.column),s=r.substr(n.column),o=this.snippetMap,u;return this.getActiveScopes(e).some(function(e){var t=o[e];return t&&(u=this.findMatchingSnippet(t,i,s)),!!u},this),u?t&&t.dryRun?!0:(e.session.doc.removeInLine(n.row,n.column-u.replaceBefore.length,n.column+u.replaceAfter.length),this.variables.M__=u.matchBefore,this.variables.T__=u.matchAfter,this.insertSnippetForSelection(e,u.content),this.variables.M__=this.variables.T__=null,!0):!1},this.findMatchingSnippet=function(e,t,n){for(var r=e.length;r--;){var i=e[r];if(i.startRe&&!i.startRe.test(t))continue;if(i.endRe&&!i.endRe.test(n))continue;if(!i.startRe&&!i.endRe)continue;return i.matchBefore=i.startRe?i.startRe.exec(t):[""],i.matchAfter=i.endRe?i.endRe.exec(n):[""],i.replaceBefore=i.triggerRe?i.triggerRe.exec(t)[0]:"",i.replaceAfter=i.endTriggerRe?i.endTriggerRe.exec(n)[0]:"",i}},this.snippetMap={},this.snippetNameMap={},this.register=function(e,t){function o(e){return e&&!/^\^?\(.*\)\$?$|^\\b$/.test(e)&&(e="(?:"+e+")"),e||""}function u(e,t,n){return e=o(e),t=o(t),n?(e=t+e,e&&e[e.length-1]!="$"&&(e+="$")):(e+=t,e&&e[0]!="^"&&(e="^"+e)),new RegExp(e)}function a(e){e.scope||(e.scope=t||"_"),t=e.scope,n[t]||(n[t]=[],r[t]={});var o=r[t];if(e.name){var a=o[e.name];a&&i.unregister(a),o[e.name]=e}n[t].push(e),e.tabTrigger&&!e.trigger&&(!e.guard&&/^\w/.test(e.tabTrigger)&&(e.guard="\\b"),e.trigger=s.escapeRegExp(e.tabTrigger));if(!e.trigger&&!e.guard&&!e.endTrigger&&!e.endGuard)return;e.startRe=u(e.trigger,e.guard,!0),e.triggerRe=new RegExp(e.trigger),e.endRe=u(e.endTrigger,e.endGuard,!0),e.endTriggerRe=new RegExp(e.endTrigger)}var n=this.snippetMap,r=this.snippetNameMap,i=this;e||(e=[]),e&&e.content?a(e):Array.isArray(e)&&e.forEach(a),this._signal("registerSnippets",{scope:t})},this.unregister=function(e,t){function i(e){var i=r[e.scope||t];if(i&&i[e.name]){delete i[e.name];var s=n[e.scope||t],o=s&&s.indexOf(e);o>=0&&s.splice(o,1)}}var n=this.snippetMap,r=this.snippetNameMap;e.content?i(e):Array.isArray(e)&&e.forEach(i)},this.parseSnippetFile=function(e){e=e.replace(/\r/g,"");var t=[],n={},r=/^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm,i;while(i=r.exec(e)){if(i[1])try{n=JSON.parse(i[1]),t.push(n)}catch(s){}if(i[4])n.content=i[4].replace(/^\t/gm,""),t.push(n),n={};else{var o=i[2],u=i[3];if(o=="regex"){var a=/\/((?:[^\/\\]|\\.)*)|$/g;n.guard=a.exec(u)[1],n.trigger=a.exec(u)[1],n.endTrigger=a.exec(u)[1],n.endGuard=a.exec(u)[1]}else o=="snippet"?(n.tabTrigger=u.match(/^\S*/)[0],n.name||(n.name=u)):n[o]=u}}return t},this.getSnippetByName=function(e,t){var n=this.snippetNameMap,r;return this.getActiveScopes(t).some(function(t){var i=n[t];return i&&(r=i[e]),!!r},this),r}}).call(c.prototype);var h=function(e){if(e.tabstopManager)return e.tabstopManager;e.tabstopManager=this,this.$onChange=this.onChange.bind(this),this.$onChangeSelection=s.delayedCall(this.onChangeSelection.bind(this)).schedule,this.$onChangeSession=this.onChangeSession.bind(this),this.$onAfterExec=this.onAfterExec.bind(this),this.attach(e)};(function(){this.attach=function(e){this.index=0,this.ranges=[],this.tabstops=[],this.$openTabstops=null,this.selectedTabstop=null,this.editor=e,this.editor.on("change",this.$onChange),this.editor.on("changeSelection",this.$onChangeSelection),this.editor.on("changeSession",this.$onChangeSession),this.editor.commands.on("afterExec",this.$onAfterExec),this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler)},this.detach=function(){this.tabstops.forEach(this.removeTabstopMarkers,this),this.ranges=null,this.tabstops=null,this.selectedTabstop=null,this.editor.removeListener("change",this.$onChange),this.editor.removeListener("changeSelection",this.$onChangeSelection),this.editor.removeListener("changeSession",this.$onChangeSession),this.editor.commands.removeListener("afterExec",this.$onAfterExec),this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler),this.editor.tabstopManager=null,this.editor=null},this.onChange=function(e){var t=e,n=e.action[0]=="r",r=e.start,i=e.end,s=r.row,o=i.row,u=o-s,a=i.column-r.column;n&&(u=-u,a=-a);if(!this.$inChange&&n){var f=this.selectedTabstop,c=f&&!f.some(function(e){return l(e.start,r)<=0&&l(e.end,i)>=0});if(c)return this.detach()}var h=this.ranges;for(var p=0;p<h.length;p++){var d=h[p];if(d.end.row<r.row)continue;if(n&&l(r,d.start)<0&&l(i,d.end)>0){this.removeRange(d),p--;continue}d.start.row==s&&d.start.column>r.column&&(d.start.column+=a),d.end.row==s&&d.end.column>=r.column&&(d.end.column+=a),d.start.row>=s&&(d.start.row+=u),d.end.row>=s&&(d.end.row+=u),l(d.start,d.end)>0&&this.removeRange(d)}h.length||this.detach()},this.updateLinkedFields=function(){var e=this.selectedTabstop;if(!e||!e.hasLinkedRanges)return;this.$inChange=!0;var n=this.editor.session,r=n.getTextRange(e.firstNonLinked);for(var i=e.length;i--;){var s=e[i];if(!s.linked)continue;var o=t.snippetManager.tmStrFormat(r,s.original);n.replace(s,o)}this.$inChange=!1},this.onAfterExec=function(e){e.command&&!e.command.readOnly&&this.updateLinkedFields()},this.onChangeSelection=function(){if(!this.editor)return;var e=this.editor.selection.lead,t=this.editor.selection.anchor,n=this.editor.selection.isEmpty();for(var r=this.ranges.length;r--;){if(this.ranges[r].linked)continue;var i=this.ranges[r].contains(e.row,e.column),s=n||this.ranges[r].contains(t.row,t.column);if(i&&s)return}this.detach()},this.onChangeSession=function(){this.detach()},this.tabNext=function(e){var t=this.tabstops.length,n=this.index+(e||1);n=Math.min(Math.max(n,1),t),n==t&&(n=0),this.selectTabstop(n),n===0&&this.detach()},this.selectTabstop=function(e){this.$openTabstops=null;var t=this.tabstops[this.index];t&&this.addTabstopMarkers(t),this.index=e,t=this.tabstops[this.index];if(!t||!t.length)return;this.selectedTabstop=t;if(!this.editor.inVirtualSelectionMode){var n=this.editor.multiSelect;n.toSingleRange(t.firstNonLinked.clone());for(var r=t.length;r--;){if(t.hasLinkedRanges&&t[r].linked)continue;n.addRange(t[r].clone(),!0)}n.ranges[0]&&n.addRange(n.ranges[0].clone())}else this.editor.selection.setRange(t.firstNonLinked);this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler)},this.addTabstops=function(e,t,n){this.$openTabstops||(this.$openTabstops=[]);if(!e[0]){var r=o.fromPoints(n,n);v(r.start,t),v(r.end,t),e[0]=[r],e[0].index=0}var i=this.index,s=[i+1,0],u=this.ranges;e.forEach(function(e,n){var r=this.$openTabstops[n]||e;for(var i=e.length;i--;){var a=e[i],f=o.fromPoints(a.start,a.end||a.start);d(f.start,t),d(f.end,t),f.original=a,f.tabstop=r,u.push(f),r!=e?r.unshift(f):r[i]=f,a.fmtString?(f.linked=!0,r.hasLinkedRanges=!0):r.firstNonLinked||(r.firstNonLinked=f)}r.firstNonLinked||(r.hasLinkedRanges=!1),r===e&&(s.push(r),this.$openTabstops[n]=r),this.addTabstopMarkers(r)},this),s.length>2&&(this.tabstops.length&&s.push(s.splice(2,1)[0]),this.tabstops.splice.apply(this.tabstops,s))},this.addTabstopMarkers=function(e){var t=this.editor.session;e.forEach(function(e){e.markerId||(e.markerId=t.addMarker(e,"ace_snippet-marker","text"))})},this.removeTabstopMarkers=function(e){var t=this.editor.session;e.forEach(function(e){t.removeMarker(e.markerId),e.markerId=null})},this.removeRange=function(e){var t=e.tabstop.indexOf(e);e.tabstop.splice(t,1),t=this.ranges.indexOf(e),this.ranges.splice(t,1),this.editor.session.removeMarker(e.markerId),e.tabstop.length||(t=this.tabstops.indexOf(e.tabstop),t!=-1&&this.tabstops.splice(t,1),this.tabstops.length||this.detach())},this.keyboardHandler=new a,this.keyboardHandler.bindKeys({Tab:function(e){if(t.snippetManager&&t.snippetManager.expandWithTab(e))return;e.tabstopManager.tabNext(1)},"Shift-Tab":function(e){e.tabstopManager.tabNext(-1)},Esc:function(e){e.tabstopManager.detach()},Return:function(e){return!1}})}).call(h.prototype);var p={};p.onChange=u.prototype.onChange,p.setPosition=function(e,t){this.pos.row=e,this.pos.column=t},p.update=function(e,t,n){this.$insertRight=n,this.pos=e,this.onChange(t)};var d=function(e,t){e.row==0&&(e.column+=t.column),e.row+=t.row},v=function(e,t){e.row==t.row&&(e.column-=t.column),e.row-=t.row};e("./lib/dom").importCssString(".ace_snippet-marker { -moz-box-sizing: border-box; box-sizing: border-box; background: rgba(194, 193, 208, 0.09); border: 1px dotted rgba(211, 208, 235, 0.62); position: absolute;}"),t.snippetManager=new c;var m=e("./editor").Editor;(function(){this.insertSnippet=function(e,n){return t.snippetManager.insertSnippet(this,e,n)},this.expandSnippet=function(e){return t.snippetManager.expandWithTab(this,e)}}).call(m.prototype)}),ace.define("ace/autocomplete/popup",["require","exports","module","ace/virtual_renderer","ace/editor","ace/range","ace/lib/event","ace/lib/lang","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../virtual_renderer").VirtualRenderer,i=e("../editor").Editor,s=e("../range").Range,o=e("../lib/event"),u=e("../lib/lang"),a=e("../lib/dom"),f=function(e){var t=new r(e);t.$maxLines=4;var n=new i(t);return n.setHighlightActiveLine(!1),n.setShowPrintMargin(!1),n.renderer.setShowGutter(!1),n.renderer.setHighlightGutterLine(!1),n.$mouseHandler.$focusTimeout=0,n.$highlightTagPending=!0,n},l=function(e){var t=a.createElement("div"),n=new f(t);e&&e.appendChild(t),t.style.display="none",n.renderer.content.style.cursor="default",n.renderer.setStyle("ace_autocomplete"),n.setOption("displayIndentGuides",!1),n.setOption("dragDelay",150);var r=function(){};n.focus=r,n.$isFocused=!0,n.renderer.$cursorLayer.restartTimer=r,n.renderer.$cursorLayer.element.style.opacity=0,n.renderer.$maxLines=8,n.renderer.$keepTextAreaAtCursor=!1,n.setHighlightActiveLine(!1),n.session.highlight(""),n.session.$searchHighlight.clazz="ace_highlight-marker",n.on("mousedown",function(e){var t=e.getDocumentPosition();n.selection.moveToPosition(t),c.start.row=c.end.row=t.row,e.stop()});var i,l=new s(-1,0,-1,Infinity),c=new s(-1,0,-1,Infinity);c.id=n.session.addMarker(c,"ace_active-line","fullLine"),n.setSelectOnHover=function(e){e?l.id&&(n.session.removeMarker(l.id),l.id=null):l.id=n.session.addMarker(l,"ace_line-hover","fullLine")},n.setSelectOnHover(!1),n.on("mousemove",function(e){if(!i){i=e;return}if(i.x==e.x&&i.y==e.y)return;i=e,i.scrollTop=n.renderer.scrollTop;var t=i.getDocumentPosition().row;l.start.row!=t&&(l.id||n.setRow(t),p(t))}),n.renderer.on("beforeRender",function(){if(i&&l.start.row!=-1){i.$pos=null;var e=i.getDocumentPosition().row;l.id||n.setRow(e),p(e,!0)}}),n.renderer.on("afterRender",function(){var e=n.getRow(),t=n.renderer.$textLayer,r=t.element.childNodes[e-t.config.firstRow];r!==t.selectedNode&&t.selectedNode&&a.removeCssClass(t.selectedNode,"ace_selected"),t.selectedNode=r,r&&a.addCssClass(r,"ace_selected")});var h=function(){p(-1)},p=function(e,t){e!==l.start.row&&(l.start.row=l.end.row=e,t||n.session._emit("changeBackMarker"),n._emit("changeHoverMarker"))};n.getHoveredRow=function(){return l.start.row},o.addListener(n.container,"mouseout",h),n.on("hide",h),n.on("changeSelection",h),n.session.doc.getLength=function(){return n.data.length},n.session.doc.getLine=function(e){var t=n.data[e];return typeof t=="string"?t:t&&t.value||""};var d=n.session.bgTokenizer;return d.$tokenizeRow=function(e){function s(e,n){e&&r.push({type:(t.className||"")+(n||""),value:e})}var t=n.data[e],r=[];if(!t)return r;typeof t=="string"&&(t={value:t});var i=t.caption||t.value||t.name,o=i.toLowerCase(),u=(n.filterText||"").toLowerCase(),a=0,f=0;for(var l=0;l<=u.length;l++)if(l!=f&&(t.matchMask&1<<l||l==u.length)){var c=u.slice(f,l);f=l;var h=o.indexOf(c,a);if(h==-1)continue;s(i.slice(a,h),""),a=h+c.length,s(i.slice(h,a),"completion-highlight")}return s(i.slice(a,i.length),""),t.meta&&r.push({type:"completion-meta",value:t.meta}),r},d.$updateOnChange=r,d.start=r,n.session.$computeWidth=function(){return this.screenWidth=0},n.isOpen=!1,n.isTopdown=!1,n.autoSelect=!0,n.filterText="",n.data=[],n.setData=function(e,t){n.filterText=t||"",n.setValue(u.stringRepeat("\n",e.length),-1),n.data=e||[],n.setRow(0)},n.getData=function(e){return n.data[e]},n.getRow=function(){return c.start.row},n.setRow=function(e){e=Math.max(this.autoSelect?0:-1,Math.min(this.data.length,e)),c.start.row!=e&&(n.selection.clearSelection(),c.start.row=c.end.row=e||0,n.session._emit("changeBackMarker"),n.moveCursorTo(e||0,0),n.isOpen&&n._signal("select"))},n.on("changeSelection",function(){n.isOpen&&n.setRow(n.selection.lead.row),n.renderer.scrollCursorIntoView()}),n.hide=function(){this.container.style.display="none",this._signal("hide"),n.isOpen=!1},n.show=function(e,t,r){var s=this.container,o=window.innerHeight,u=window.innerWidth,a=this.renderer,f=a.$maxLines*t*1.4,l=e.top+this.$borderSize,c=l>o/2&&!r;c&&l+t+f>o?(a.$maxPixelHeight=l-2*this.$borderSize,s.style.top="",s.style.bottom=o-l+"px",n.isTopdown=!1):(l+=t,a.$maxPixelHeight=o-l-.2*t,s.style.top=l+"px",s.style.bottom="",n.isTopdown=!0),s.style.display="";var h=e.left;h+s.offsetWidth>u&&(h=u-s.offsetWidth),s.style.left=h+"px",this._signal("show"),i=null,n.isOpen=!0},n.getTextLeftOffset=function(){return this.$borderSize+this.renderer.$padding+this.$imageSize},n.$imageSize=0,n.$borderSize=1,n};a.importCssString(".ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line { background-color: #CAD6FA; z-index: 1;}.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line { background-color: #3a674e;}.ace_editor.ace_autocomplete .ace_line-hover { border: 1px solid #abbffe; margin-top: -1px; background: rgba(233,233,253,0.4); position: absolute; z-index: 2;}.ace_dark.ace_editor.ace_autocomplete .ace_line-hover { border: 1px solid rgba(109, 150, 13, 0.8); background: rgba(58, 103, 78, 0.62);}.ace_completion-meta { opacity: 0.5; margin: 0.9em;}.ace_editor.ace_autocomplete .ace_completion-highlight{ color: #2d69c7;}.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{ color: #93ca12;}.ace_editor.ace_autocomplete { width: 300px; z-index: 200000; border: 1px lightgray solid; position: fixed; box-shadow: 2px 3px 5px rgba(0,0,0,.2); line-height: 1.4; background: #fefefe; color: #111;}.ace_dark.ace_editor.ace_autocomplete { border: 1px #484747 solid; box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.51); line-height: 1.4; background: #25282c; color: #c1c1c1;}","autocompletion.css"),t.AcePopup=l}),ace.define("ace/autocomplete/util",["require","exports","module"],function(e,t,n){"use strict";t.parForEach=function(e,t,n){var r=0,i=e.length;i===0&&n();for(var s=0;s<i;s++)t(e[s],function(e,t){r++,r===i&&n(e,t)})};var r=/[a-zA-Z_0-9\$\-\u00A2-\uFFFF]/;t.retrievePrecedingIdentifier=function(e,t,n){n=n||r;var i=[];for(var s=t-1;s>=0;s--){if(!n.test(e[s]))break;i.push(e[s])}return i.reverse().join("")},t.retrieveFollowingIdentifier=function(e,t,n){n=n||r;var i=[];for(var s=t;s<e.length;s++){if(!n.test(e[s]))break;i.push(e[s])}return i},t.getCompletionPrefix=function(e){var t=e.getCursorPosition(),n=e.session.getLine(t.row),r;return e.completers.forEach(function(e){e.identifierRegexps&&e.identifierRegexps.forEach(function(e){!r&&e&&(r=this.retrievePrecedingIdentifier(n,t.column,e))}.bind(this))}.bind(this)),r||this.retrievePrecedingIdentifier(n,t.column)}}),ace.define("ace/autocomplete",["require","exports","module","ace/keyboard/hash_handler","ace/autocomplete/popup","ace/autocomplete/util","ace/lib/event","ace/lib/lang","ace/lib/dom","ace/snippets"],function(e,t,n){"use strict";var r=e("./keyboard/hash_handler").HashHandler,i=e("./autocomplete/popup").AcePopup,s=e("./autocomplete/util"),o=e("./lib/event"),u=e("./lib/lang"),a=e("./lib/dom"),f=e("./snippets").snippetManager,l=function(){this.autoInsert=!1,this.autoSelect=!0,this.exactMatch=!1,this.gatherCompletionsId=0,this.keyboardHandler=new r,this.keyboardHandler.bindKeys(this.commands),this.blurListener=this.blurListener.bind(this),this.changeListener=this.changeListener.bind(this),this.mousedownListener=this.mousedownListener.bind(this),this.mousewheelListener=this.mousewheelListener.bind(this),this.changeTimer=u.delayedCall(function(){this.updateCompletions(!0)}.bind(this)),this.tooltipTimer=u.delayedCall(this.updateDocTooltip.bind(this),50)};(function(){this.$init=function(){return this.popup=new i(document.body||document.documentElement),this.popup.on("click",function(e){this.insertMatch(),e.stop()}.bind(this)),this.popup.focus=this.editor.focus.bind(this.editor),this.popup.on("show",this.tooltipTimer.bind(null,null)),this.popup.on("select",this.tooltipTimer.bind(null,null)),this.popup.on("changeHoverMarker",this.tooltipTimer.bind(null,null)),this.popup},this.getPopup=function(){return this.popup||this.$init()},this.openPopup=function(e,t,n){this.popup||this.$init(),this.popup.autoSelect=this.autoSelect,this.popup.setData(this.completions.filtered,this.completions.filterText),e.keyBinding.addKeyboardHandler(this.keyboardHandler);var r=e.renderer;this.popup.setRow(this.autoSelect?0:-1);if(!n){this.popup.setTheme(e.getTheme()),this.popup.setFontSize(e.getFontSize());var i=r.layerConfig.lineHeight,s=r.$cursorLayer.getPixelPosition(this.base,!0);s.left-=this.popup.getTextLeftOffset();var o=e.container.getBoundingClientRect();s.top+=o.top-r.layerConfig.offset,s.left+=o.left-e.renderer.scrollLeft,s.left+=r.gutterWidth,this.popup.show(s,i)}else n&&!t&&this.detach()},this.detach=function(){this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler),this.editor.off("changeSelection",this.changeListener),this.editor.off("blur",this.blurListener),this.editor.off("mousedown",this.mousedownListener),this.editor.off("mousewheel",this.mousewheelListener),this.changeTimer.cancel(),this.hideDocTooltip(),this.gatherCompletionsId+=1,this.popup&&this.popup.isOpen&&this.popup.hide(),this.base&&this.base.detach(),this.activated=!1,this.completions=this.base=null},this.changeListener=function(e){var t=this.editor.selection.lead;(t.row!=this.base.row||t.column<this.base.column)&&this.detach(),this.activated?this.changeTimer.schedule():this.detach()},this.blurListener=function(e){var t=document.activeElement,n=this.editor.textInput.getElement(),r=e.relatedTarget&&this.tooltipNode&&this.tooltipNode.contains(e.relatedTarget),i=this.popup&&this.popup.container;t!=n&&t.parentNode!=i&&!r&&t!=this.tooltipNode&&e.relatedTarget!=n&&this.detach()},this.mousedownListener=function(e){this.detach()},this.mousewheelListener=function(e){this.detach()},this.goTo=function(e){var t=this.popup.getRow(),n=this.popup.session.getLength()-1;switch(e){case"up":t=t<=0?n:t-1;break;case"down":t=t>=n?-1:t+1;break;case"start":t=0;break;case"end":t=n}this.popup.setRow(t)},this.insertMatch=function(e,t){e||(e=this.popup.getData(this.popup.getRow()));if(!e)return!1;if(e.completer&&e.completer.insertMatch)e.completer.insertMatch(this.editor,e);else{if(this.completions.filterText){var n=this.editor.selection.getAllRanges();for(var r=0,i;i=n[r];r++)i.start.column-=this.completions.filterText.length,this.editor.session.remove(i)}e.snippet?f.insertSnippet(this.editor,e.snippet):this.editor.execCommand("insertstring",e.value||e)}this.detach()},this.commands={Up:function(e){e.completer.goTo("up")},Down:function(e){e.completer.goTo("down")},"Ctrl-Up|Ctrl-Home":function(e){e.completer.goTo("start")},"Ctrl-Down|Ctrl-End":function(e){e.completer.goTo("end")},Esc:function(e){e.completer.detach()},Return:function(e){return e.completer.insertMatch()},"Shift-Return":function(e){e.completer.insertMatch(null,{deleteSuffix:!0})},Tab:function(e){var t=e.completer.insertMatch();if(!!t||!!e.tabstopManager)return t;e.completer.goTo("down")},PageUp:function(e){e.completer.popup.gotoPageUp()},PageDown:function(e){e.completer.popup.gotoPageDown()}},this.gatherCompletions=function(e,t){var n=e.getSession(),r=e.getCursorPosition(),i=s.getCompletionPrefix(e);this.base=n.doc.createAnchor(r.row,r.column-i.length),this.base.$insertRight=!0;var o=[],u=e.completers.length;return e.completers.forEach(function(a,f){a.getCompletions(e,n,r,i,function(n,r){!n&&r&&(o=o.concat(r)),t(null,{prefix:s.getCompletionPrefix(e),matches:o,finished:--u===0})})}),!0},this.showPopup=function(e){this.editor&&this.detach(),this.activated=!0,this.editor=e,e.completer!=this&&(e.completer&&e.completer.detach(),e.completer=this),e.on("changeSelection",this.changeListener),e.on("blur",this.blurListener),e.on("mousedown",this.mousedownListener),e.on("mousewheel",this.mousewheelListener),this.updateCompletions()},this.updateCompletions=function(e){if(e&&this.base&&this.completions){var t=this.editor.getCursorPosition(),n=this.editor.session.getTextRange({start:this.base,end:t});if(n==this.completions.filterText)return;this.completions.setFilter(n);if(!this.completions.filtered.length)return this.detach();if(this.completions.filtered.length==1&&this.completions.filtered[0].value==n&&!this.completions.filtered[0].snippet)return this.detach();this.openPopup(this.editor,n,e);return}var r=this.gatherCompletionsId;this.gatherCompletions(this.editor,function(t,n){var i=function(){if(!n.finished)return;return this.detach()}.bind(this),s=n.prefix,o=n&&n.matches;if(!o||!o.length)return i();if(s.indexOf(n.prefix)!==0||r!=this.gatherCompletionsId)return;this.completions=new c(o),this.exactMatch&&(this.completions.exactMatch=!0),this.completions.setFilter(s);var u=this.completions.filtered;if(!u.length)return i();if(u.length==1&&u[0].value==s&&!u[0].snippet)return i();if(this.autoInsert&&u.length==1&&n.finished)return this.insertMatch(u[0]);this.openPopup(this.editor,s,e)}.bind(this))},this.cancelContextMenu=function(){this.editor.$mouseHandler.cancelContextMenu()},this.updateDocTooltip=function(){var e=this.popup,t=e.data,n=t&&(t[e.getHoveredRow()]||t[e.getRow()]),r=null;if(!n||!this.editor||!this.popup.isOpen)return this.hideDocTooltip();this.editor.completers.some(function(e){return e.getDocTooltip&&(r=e.getDocTooltip(n)),r}),r||(r=n),typeof r=="string"&&(r={docText:r});if(!r||!r.docHTML&&!r.docText)return this.hideDocTooltip();this.showDocTooltip(r)},this.showDocTooltip=function(e){this.tooltipNode||(this.tooltipNode=a.createElement("div"),this.tooltipNode.className="ace_tooltip ace_doc-tooltip",this.tooltipNode.style.margin=0,this.tooltipNode.style.pointerEvents="auto",this.tooltipNode.tabIndex=-1,this.tooltipNode.onblur=this.blurListener.bind(this),this.tooltipNode.onclick=this.onTooltipClick.bind(this));var t=this.tooltipNode;e.docHTML?t.innerHTML=e.docHTML:e.docText&&(t.textContent=e.docText),t.parentNode||document.body.appendChild(t);var n=this.popup,r=n.container.getBoundingClientRect();t.style.top=n.container.style.top,t.style.bottom=n.container.style.bottom,t.style.display="block",window.innerWidth-r.right<320?r.left<320?n.isTopdown?(t.style.top=r.bottom+"px",t.style.left=r.left+"px",t.style.right="",t.style.bottom=""):(t.style.top=n.container.offsetTop-t.offsetHeight+"px",t.style.left=r.left+"px",t.style.right="",t.style.bottom=""):(t.style.right=window.innerWidth-r.left+"px",t.style.left=""):(t.style.left=r.right+1+"px",t.style.right="")},this.hideDocTooltip=function(){this.tooltipTimer.cancel();if(!this.tooltipNode)return;var e=this.tooltipNode;!this.editor.isFocused()&&document.activeElement==e&&this.editor.focus(),this.tooltipNode=null,e.parentNode&&e.parentNode.removeChild(e)},this.onTooltipClick=function(e){var t=e.target;while(t&&t!=this.tooltipNode){if(t.nodeName=="A"&&t.href){t.rel="noreferrer",t.target="_blank";break}t=t.parentNode}}}).call(l.prototype),l.startCommand={name:"startAutocomplete",exec:function(e){e.completer||(e.completer=new l),e.completer.autoInsert=!1,e.completer.autoSelect=!0,e.completer.showPopup(e),e.completer.cancelContextMenu()},bindKey:"Ctrl-Space|Ctrl-Shift-Space|Alt-Space"};var c=function(e,t){this.all=e,this.filtered=e,this.filterText=t||"",this.exactMatch=!1};(function(){this.setFilter=function(e){if(e.length>this.filterText&&e.lastIndexOf(this.filterText,0)===0)var t=this.filtered;else var t=this.all;this.filterText=e,t=this.filterCompletions(t,this.filterText),t=t.sort(function(e,t){return t.exactMatch-e.exactMatch||t.$score-e.$score||(e.caption||e.value)<(t.caption||t.value)});var n=null;t=t.filter(function(e){var t=e.snippet||e.caption||e.value;return t===n?!1:(n=t,!0)}),this.filtered=t},this.filterCompletions=function(e,t){var n=[],r=t.toUpperCase(),i=t.toLowerCase();e:for(var s=0,o;o=e[s];s++){var u=o.caption||o.value||o.snippet;if(!u)continue;var a=-1,f=0,l=0,c,h;if(this.exactMatch){if(t!==u.substr(0,t.length))continue e}else{var p=u.toLowerCase().indexOf(i);if(p>-1)l=p;else for(var d=0;d<t.length;d++){var v=u.indexOf(i[d],a+1),m=u.indexOf(r[d],a+1);c=v>=0?m<0||v<m?v:m:m;if(c<0)continue e;h=c-a-1,h>0&&(a===-1&&(l+=10),l+=h,f|=1<<d),a=c}}o.matchMask=f,o.exactMatch=l?0:1,o.$score=(o.score||0)-l,n.push(o)}return n}}).call(c.prototype),t.Autocomplete=l,t.FilteredList=c}),ace.define("ace/autocomplete/text_completer",["require","exports","module","ace/range"],function(e,t,n){function s(e,t){var n=e.getTextRange(r.fromPoints({row:0,column:0},t));return n.split(i).length-1}function o(e,t){var n=s(e,t),r=e.getValue().split(i),o=Object.create(null),u=r[n];return r.forEach(function(e,t){if(!e||e===u)return;var i=Math.abs(n-t),s=r.length-i;o[e]?o[e]=Math.max(s,o[e]):o[e]=s}),o}var r=e("../range").Range,i=/[^a-zA-Z_0-9\$\-\u00C0-\u1FFF\u2C00-\uD7FF\w]+/;t.getCompletions=function(e,t,n,r,i){var s=o(t,n),u=Object.keys(s);i(null,u.map(function(e){return{caption:e,value:e,score:s[e],meta:"local"}}))}}),ace.define("ace/ext/language_tools",["require","exports","module","ace/snippets","ace/autocomplete","ace/config","ace/lib/lang","ace/autocomplete/util","ace/autocomplete/text_completer","ace/editor","ace/config"],function(e,t,n){"use strict";var r=e("../snippets").snippetManager,i=e("../autocomplete").Autocomplete,s=e("../config"),o=e("../lib/lang"),u=e("../autocomplete/util"),a=e("../autocomplete/text_completer"),f={getCompletions:function(e,t,n,r,i){if(t.$mode.completer)return t.$mode.completer.getCompletions(e,t,n,r,i);var s=e.session.getState(n.row),o=t.$mode.getCompletions(s,t,n,r);i(null,o)}},l={getCompletions:function(e,t,n,i,s){var o=[],u=t.getTokenAt(n.row,n.column);u&&u.type.match(/(tag-name|tag-open|tag-whitespace|attribute-name|attribute-value)\.xml$/)?o.push("html-tag"):o=r.getActiveScopes(e);var a=r.snippetMap,f=[];o.forEach(function(e){var t=a[e]||[];for(var n=t.length;n--;){var r=t[n],i=r.name||r.tabTrigger;if(!i)continue;f.push({caption:i,snippet:r.content,meta:r.tabTrigger&&!r.name?r.tabTrigger+"\u21e5 ":"snippet",type:"snippet"})}},this),s(null,f)},getDocTooltip:function(e){e.type=="snippet"&&!e.docHTML&&(e.docHTML=["<b>",o.escapeHTML(e.caption),"</b>","<hr></hr>",o.escapeHTML(e.snippet)].join(""))}},c=[l,a,f];t.setCompleters=function(e){c.length=0,e&&c.push.apply(c,e)},t.addCompleter=function(e){c.push(e)},t.textCompleter=a,t.keyWordCompleter=f,t.snippetCompleter=l;var h={name:"expandSnippet",exec:function(e){return r.expandWithTab(e)},bindKey:"Tab"},p=function(e,t){d(t.session.$mode)},d=function(e){var t=e.$id;r.files||(r.files={}),v(t),e.modes&&e.modes.forEach(d)},v=function(e){if(!e||r.files[e])return;var t=e.replace("mode","snippets");r.files[e]={},s.loadModule(t,function(t){t&&(r.files[e]=t,!t.snippets&&t.snippetText&&(t.snippets=r.parseSnippetFile(t.snippetText)),r.register(t.snippets||[],t.scope),t.includeScopes&&(r.snippetMap[t.scope].includeScopes=t.includeScopes,t.includeScopes.forEach(function(e){v("ace/mode/"+e)})))})},m=function(e){var t=e.editor,n=t.completer&&t.completer.activated;if(e.command.name==="backspace")n&&!u.getCompletionPrefix(t)&&t.completer.detach();else if(e.command.name==="insertstring"){var r=u.getCompletionPrefix(t);r&&!n&&(t.completer||(t.completer=new i),t.completer.autoInsert=!1,t.completer.showPopup(t))}},g=e("../editor").Editor;e("../config").defineOptions(g.prototype,"editor",{enableBasicAutocompletion:{set:function(e){e?(this.completers||(this.completers=Array.isArray(e)?e:c),this.commands.addCommand(i.startCommand)):this.commands.removeCommand(i.startCommand)},value:!1},enableLiveAutocompletion:{set:function(e){e?(this.completers||(this.completers=Array.isArray(e)?e:c),this.commands.on("afterExec",m)):this.commands.removeListener("afterExec",m)},value:!1},enableSnippets:{set:function(e){e?(this.commands.addCommand(h),this.on("changeMode",p),p(null,this)):(this.commands.removeCommand(h),this.off("changeMode",p))},value:!1}})}); (function() { + ace.require(["ace/ext/language_tools"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/ext-searchbox.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/ext-searchbox.js new file mode 100644 index 0000000..fda92f1 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/ext-searchbox.js @@ -0,0 +1,8 @@ +ace.define("ace/ext/searchbox",["require","exports","module","ace/lib/dom","ace/lib/lang","ace/lib/event","ace/keyboard/hash_handler","ace/lib/keys"],function(e,t,n){"use strict";var r=e("../lib/dom"),i=e("../lib/lang"),s=e("../lib/event"),o='.ace_search {background-color: #ddd;color: #666;border: 1px solid #cbcbcb;border-top: 0 none;overflow: hidden;margin: 0;padding: 4px 6px 0 4px;position: absolute;top: 0;z-index: 99;white-space: normal;}.ace_search.left {border-left: 0 none;border-radius: 0px 0px 5px 0px;left: 0;}.ace_search.right {border-radius: 0px 0px 0px 5px;border-right: 0 none;right: 0;}.ace_search_form, .ace_replace_form {margin: 0 20px 4px 0;overflow: hidden;line-height: 1.9;}.ace_replace_form {margin-right: 0;}.ace_search_form.ace_nomatch {outline: 1px solid red;}.ace_search_field {border-radius: 3px 0 0 3px;background-color: white;color: black;border: 1px solid #cbcbcb;border-right: 0 none;outline: 0;padding: 0;font-size: inherit;margin: 0;line-height: inherit;padding: 0 6px;min-width: 17em;vertical-align: top;min-height: 1.8em;box-sizing: content-box;}.ace_searchbtn {border: 1px solid #cbcbcb;line-height: inherit;display: inline-block;padding: 0 6px;background: #fff;border-right: 0 none;border-left: 1px solid #dcdcdc;cursor: pointer;margin: 0;position: relative;color: #666;}.ace_searchbtn:last-child {border-radius: 0 3px 3px 0;border-right: 1px solid #cbcbcb;}.ace_searchbtn:disabled {background: none;cursor: default;}.ace_searchbtn:hover {background-color: #eef1f6;}.ace_searchbtn.prev, .ace_searchbtn.next {padding: 0px 0.7em}.ace_searchbtn.prev:after, .ace_searchbtn.next:after {content: "";border: solid 2px #888;width: 0.5em;height: 0.5em;border-width: 2px 0 0 2px;display:inline-block;transform: rotate(-45deg);}.ace_searchbtn.next:after {border-width: 0 2px 2px 0 ;}.ace_searchbtn_close {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAcCAYAAABRVo5BAAAAZ0lEQVR42u2SUQrAMAhDvazn8OjZBilCkYVVxiis8H4CT0VrAJb4WHT3C5xU2a2IQZXJjiQIRMdkEoJ5Q2yMqpfDIo+XY4k6h+YXOyKqTIj5REaxloNAd0xiKmAtsTHqW8sR2W5f7gCu5nWFUpVjZwAAAABJRU5ErkJggg==) no-repeat 50% 0;border-radius: 50%;border: 0 none;color: #656565;cursor: pointer;font: 16px/16px Arial;padding: 0;height: 14px;width: 14px;top: 9px;right: 7px;position: absolute;}.ace_searchbtn_close:hover {background-color: #656565;background-position: 50% 100%;color: white;}.ace_button {margin-left: 2px;cursor: pointer;-webkit-user-select: none;-moz-user-select: none;-o-user-select: none;-ms-user-select: none;user-select: none;overflow: hidden;opacity: 0.7;border: 1px solid rgba(100,100,100,0.23);padding: 1px;box-sizing: border-box!important;color: black;}.ace_button:hover {background-color: #eee;opacity:1;}.ace_button:active {background-color: #ddd;}.ace_button.checked {border-color: #3399ff;opacity:1;}.ace_search_options{margin-bottom: 3px;text-align: right;-webkit-user-select: none;-moz-user-select: none;-o-user-select: none;-ms-user-select: none;user-select: none;clear: both;}.ace_search_counter {float: left;font-family: arial;padding: 0 8px;}',u=e("../keyboard/hash_handler").HashHandler,a=e("../lib/keys"),f=999;r.importCssString(o,"ace_searchbox");var l=function(e,t,n){var i=r.createElement("div");r.buildDom(["div",{"class":"ace_search right"},["span",{action:"hide","class":"ace_searchbtn_close"}],["div",{"class":"ace_search_form"},["input",{"class":"ace_search_field",placeholder:"Search for",spellcheck:"false"}],["span",{action:"findPrev","class":"ace_searchbtn prev"},"\u200b"],["span",{action:"findNext","class":"ace_searchbtn next"},"\u200b"],["span",{action:"findAll","class":"ace_searchbtn",title:"Alt-Enter"},"All"]],["div",{"class":"ace_replace_form"},["input",{"class":"ace_search_field",placeholder:"Replace with",spellcheck:"false"}],["span",{action:"replaceAndFindNext","class":"ace_searchbtn"},"Replace"],["span",{action:"replaceAll","class":"ace_searchbtn"},"All"]],["div",{"class":"ace_search_options"},["span",{action:"toggleReplace","class":"ace_button",title:"Toggle Replace mode",style:"float:left;margin-top:-2px;padding:0 5px;"},"+"],["span",{"class":"ace_search_counter"}],["span",{action:"toggleRegexpMode","class":"ace_button",title:"RegExp Search"},".*"],["span",{action:"toggleCaseSensitive","class":"ace_button",title:"CaseSensitive Search"},"Aa"],["span",{action:"toggleWholeWords","class":"ace_button",title:"Whole Word Search"},"\\b"],["span",{action:"searchInSelection","class":"ace_button",title:"Search In Selection"},"S"]]],i),this.element=i.firstChild,this.setSession=this.setSession.bind(this),this.$init(),this.setEditor(e),r.importCssString(o,"ace_searchbox",e.container)};(function(){this.setEditor=function(e){e.searchBox=this,e.renderer.scroller.appendChild(this.element),this.editor=e},this.setSession=function(e){this.searchRange=null,this.$syncOptions(!0)},this.$initElements=function(e){this.searchBox=e.querySelector(".ace_search_form"),this.replaceBox=e.querySelector(".ace_replace_form"),this.searchOption=e.querySelector("[action=searchInSelection]"),this.replaceOption=e.querySelector("[action=toggleReplace]"),this.regExpOption=e.querySelector("[action=toggleRegexpMode]"),this.caseSensitiveOption=e.querySelector("[action=toggleCaseSensitive]"),this.wholeWordOption=e.querySelector("[action=toggleWholeWords]"),this.searchInput=this.searchBox.querySelector(".ace_search_field"),this.replaceInput=this.replaceBox.querySelector(".ace_search_field"),this.searchCounter=e.querySelector(".ace_search_counter")},this.$init=function(){var e=this.element;this.$initElements(e);var t=this;s.addListener(e,"mousedown",function(e){setTimeout(function(){t.activeInput.focus()},0),s.stopPropagation(e)}),s.addListener(e,"click",function(e){var n=e.target||e.srcElement,r=n.getAttribute("action");r&&t[r]?t[r]():t.$searchBarKb.commands[r]&&t.$searchBarKb.commands[r].exec(t),s.stopPropagation(e)}),s.addCommandKeyListener(e,function(e,n,r){var i=a.keyCodeToString(r),o=t.$searchBarKb.findKeyCommand(n,i);o&&o.exec&&(o.exec(t),s.stopEvent(e))}),this.$onChange=i.delayedCall(function(){t.find(!1,!1)}),s.addListener(this.searchInput,"input",function(){t.$onChange.schedule(20)}),s.addListener(this.searchInput,"focus",function(){t.activeInput=t.searchInput,t.searchInput.value&&t.highlight()}),s.addListener(this.replaceInput,"focus",function(){t.activeInput=t.replaceInput,t.searchInput.value&&t.highlight()})},this.$closeSearchBarKb=new u([{bindKey:"Esc",name:"closeSearchBar",exec:function(e){e.searchBox.hide()}}]),this.$searchBarKb=new u,this.$searchBarKb.bindKeys({"Ctrl-f|Command-f":function(e){var t=e.isReplace=!e.isReplace;e.replaceBox.style.display=t?"":"none",e.replaceOption.checked=!1,e.$syncOptions(),e.searchInput.focus()},"Ctrl-H|Command-Option-F":function(e){if(e.editor.getReadOnly())return;e.replaceOption.checked=!0,e.$syncOptions(),e.replaceInput.focus()},"Ctrl-G|Command-G":function(e){e.findNext()},"Ctrl-Shift-G|Command-Shift-G":function(e){e.findPrev()},esc:function(e){setTimeout(function(){e.hide()})},Return:function(e){e.activeInput==e.replaceInput&&e.replace(),e.findNext()},"Shift-Return":function(e){e.activeInput==e.replaceInput&&e.replace(),e.findPrev()},"Alt-Return":function(e){e.activeInput==e.replaceInput&&e.replaceAll(),e.findAll()},Tab:function(e){(e.activeInput==e.replaceInput?e.searchInput:e.replaceInput).focus()}}),this.$searchBarKb.addCommands([{name:"toggleRegexpMode",bindKey:{win:"Alt-R|Alt-/",mac:"Ctrl-Alt-R|Ctrl-Alt-/"},exec:function(e){e.regExpOption.checked=!e.regExpOption.checked,e.$syncOptions()}},{name:"toggleCaseSensitive",bindKey:{win:"Alt-C|Alt-I",mac:"Ctrl-Alt-R|Ctrl-Alt-I"},exec:function(e){e.caseSensitiveOption.checked=!e.caseSensitiveOption.checked,e.$syncOptions()}},{name:"toggleWholeWords",bindKey:{win:"Alt-B|Alt-W",mac:"Ctrl-Alt-B|Ctrl-Alt-W"},exec:function(e){e.wholeWordOption.checked=!e.wholeWordOption.checked,e.$syncOptions()}},{name:"toggleReplace",exec:function(e){e.replaceOption.checked=!e.replaceOption.checked,e.$syncOptions()}},{name:"searchInSelection",exec:function(e){e.searchOption.checked=!e.searchRange,e.setSearchRange(e.searchOption.checked&&e.editor.getSelectionRange()),e.$syncOptions()}}]),this.setSearchRange=function(e){this.searchRange=e,e?this.searchRangeMarker=this.editor.session.addMarker(e,"ace_active-line"):this.searchRangeMarker&&(this.editor.session.removeMarker(this.searchRangeMarker),this.searchRangeMarker=null)},this.$syncOptions=function(e){r.setCssClass(this.replaceOption,"checked",this.searchRange),r.setCssClass(this.searchOption,"checked",this.searchOption.checked),this.replaceOption.textContent=this.replaceOption.checked?"-":"+",r.setCssClass(this.regExpOption,"checked",this.regExpOption.checked),r.setCssClass(this.wholeWordOption,"checked",this.wholeWordOption.checked),r.setCssClass(this.caseSensitiveOption,"checked",this.caseSensitiveOption.checked);var t=this.editor.getReadOnly();this.replaceOption.style.display=t?"none":"",this.replaceBox.style.display=this.replaceOption.checked&&!t?"":"none",this.find(!1,!1,e)},this.highlight=function(e){this.editor.session.highlight(e||this.editor.$search.$options.re),this.editor.renderer.updateBackMarkers()},this.find=function(e,t,n){var i=this.editor.find(this.searchInput.value,{skipCurrent:e,backwards:t,wrap:!0,regExp:this.regExpOption.checked,caseSensitive:this.caseSensitiveOption.checked,wholeWord:this.wholeWordOption.checked,preventScroll:n,range:this.searchRange}),s=!i&&this.searchInput.value;r.setCssClass(this.searchBox,"ace_nomatch",s),this.editor._emit("findSearchBox",{match:!s}),this.highlight(),this.updateCounter()},this.updateCounter=function(){var e=this.editor,t=e.$search.$options.re,n=0,r=0;if(t){var i=this.searchRange?e.session.getTextRange(this.searchRange):e.getValue(),s=e.session.doc.positionToIndex(e.selection.anchor);this.searchRange&&(s-=e.session.doc.positionToIndex(this.searchRange.start));var o=t.lastIndex=0,u;while(u=t.exec(i)){n++,o=u.index,o<=s&&r++;if(n>f)break;if(!u[0]){t.lastIndex=o+=1;if(o>=i.length)break}}}this.searchCounter.textContent=r+" of "+(n>f?f+"+":n)},this.findNext=function(){this.find(!0,!1)},this.findPrev=function(){this.find(!0,!0)},this.findAll=function(){var e=this.editor.findAll(this.searchInput.value,{regExp:this.regExpOption.checked,caseSensitive:this.caseSensitiveOption.checked,wholeWord:this.wholeWordOption.checked}),t=!e&&this.searchInput.value;r.setCssClass(this.searchBox,"ace_nomatch",t),this.editor._emit("findSearchBox",{match:!t}),this.highlight(),this.hide()},this.replace=function(){this.editor.getReadOnly()||this.editor.replace(this.replaceInput.value)},this.replaceAndFindNext=function(){this.editor.getReadOnly()||(this.editor.replace(this.replaceInput.value),this.findNext())},this.replaceAll=function(){this.editor.getReadOnly()||this.editor.replaceAll(this.replaceInput.value)},this.hide=function(){this.active=!1,this.setSearchRange(null),this.editor.off("changeSession",this.setSession),this.element.style.display="none",this.editor.keyBinding.removeKeyboardHandler(this.$closeSearchBarKb),this.editor.focus()},this.show=function(e,t){this.active=!0,this.editor.on("changeSession",this.setSession),this.element.style.display="",this.replaceOption.checked=t,e&&(this.searchInput.value=e),this.searchInput.focus(),this.searchInput.select(),this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb),this.$syncOptions(!0)},this.isFocused=function(){var e=document.activeElement;return e==this.searchInput||e==this.replaceInput}}).call(l.prototype),t.SearchBox=l,t.Search=function(e,t){var n=e.searchBox||new l(e);n.show(e.session.getTextRange(),t)}}); (function() { + ace.require(["ace/ext/searchbox"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-css.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-css.js new file mode 100644 index 0000000..ee2fb30 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-css.js @@ -0,0 +1,8 @@ +ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom",f=t.supportConstantColor="aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen",l=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"ruleset"},{token:"paren.rparen",regex:"\\}"},{token:"string",regex:"@(?!viewport)",next:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"keyword",regex:"%"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant.numeric",regex:c},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"start"},{token:"paren.rparen",regex:"\\}",next:"start"},{token:"string",regex:";",next:"start"},{token:"keyword",regex:"(?:media|supports|document|charset|import|namespace|media|supports|document|page|font|keyframes|viewport|counter-style|font-feature-values|swash|ornaments|annotation|stylistic|styleset|character-variant)"}],comments:[{token:"comment",regex:"\\/\\*",push:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}]}],ruleset:[{regex:"-(webkit|ms|moz|o)-",token:"text"},{token:"punctuation.operator",regex:"[:;]"},{token:"paren.rparen",regex:"\\}",next:"start"},{include:["strings","url","comments"]},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{include:"url"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}],url:[{token:"support.function",regex:"(?:url(:?-prefix)?|domain|regexp)\\(",push:[{token:"support.function",regex:"\\)",next:"pop"},{defaultToken:"string"}]}],strings:[{token:"string.start",regex:"'",push:[{token:"string.end",regex:"'|$",next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]},{token:"string.start",regex:'"',push:[{token:"string.end",regex:'"|$',next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]}],escapes:[{token:"constant.language.escape",regex:/\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/css_completions",["require","exports","module"],function(e,t,n){"use strict";var r={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,"double":2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{"default":1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},"float":{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,"static":1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},i=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e){if(typeof e[t]!="string")continue;var n=t.replace(/[A-Z]/g,function(e){return"-"+e.toLowerCase()});r.hasOwnProperty(n)||(r[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,r){this.completionsDefined||this.defineCompletions();if(e==="ruleset"||t.$mode.$id=="ace/mode/scss"){var i=t.getLine(n.row).substr(0,n.column);return/:[^;]+$/.test(i)?(/([\w\-]+):[^:]*$/.test(i),this.getPropertyValueCompletions(e,t,n,r)):this.getPropertyCompletions(e,t,n,r)}return[]},this.getPropertyCompletions=function(e,t,n,i){var s=Object.keys(r);return s.map(function(e){return{caption:e,snippet:e+": $0;",meta:"property",score:1e6}})},this.getPropertyValueCompletions=function(e,t,n,i){var s=t.getLine(n.row).substr(0,n.column),o=(/([\w\-]+):[^:]*$/.exec(s)||{})[1];if(!o)return[];var u=[];return o in r&&typeof r[o]=="object"&&(u=Object.keys(r[o])),u.map(function(e){return{caption:e,snippet:e,meta:"property value",score:1e6}})}}).call(i.prototype),t.CssCompletions=i}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"&&n.selection.isEmpty()){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(/^(\s+[^;]|\s*$)/.test(f.substring(s.column)))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"&&n.selection.isEmpty()){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}}),this.add("!important","insertion",function(e,t,n,r,i){if(i==="!"&&n.selection.isEmpty()){var s=n.getCursorPosition(),o=r.doc.getLine(s.row);if(/^\s*(;|}|$)/.test(o.substring(s.column)))return{text:"!important",selection:[10,10]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++n<s){t=e.getLine(n);var f=u.exec(t);if(!f)continue;f[1]?a--:a++;if(!a)break}var l=n;if(l>o)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./css_completions").CssCompletions,f=e("./behaviour/css").CssBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.$completer=new a,this.foldingRules=new l};r.inherits(c,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(c.prototype),t.Mode=c}); (function() { + ace.require(["ace/mode/css"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-handlebars.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-handlebars.js new file mode 100644 index 0000000..4b2d87f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-handlebars.js @@ -0,0 +1,8 @@ +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},s.getTagRule(),{defaultToken:"comment.doc",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";function a(){var e=o.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r=e.charAt(1)=="/"?2:1;if(r==1)t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++;else if(r==2&&t==this.nextState){n[1]--;if(!n[1]||n[1]<0)n.shift(),n.shift()}return[{type:"meta.tag.punctuation."+(r==1?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"</?"+e+"",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),e.length==2&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,f("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function f(e){return[{token:"comment",regex:/\/\*/,next:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[i.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*",u=function(e){var t=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),n="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[i.getStartRule("doc-start"),f("no_regex"),{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+o+")(\\.)(prototype)(\\.)("+o+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+o+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:"+n+")\\b",next:"start"},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:t,regex:o},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(?:(\\s+)(\\w+))?(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:o},{regex:"",token:"empty",next:"no_regex"}],start:[i.getStartRule("doc-start"),f("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:o},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]};if(!e||!e.noES6)this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)n.unshift("start",t);else if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1||this.next.indexOf("jsx")!=-1)return"paren.quasi.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]}),(!e||e.jsx!=0)&&a.call(this);this.embedRules(i,"doc-",[i.getEndRule("no_regex")]),this.normalizeRules()};r.inherits(u,s),t.JavaScriptHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++n<s){t=e.getLine(n);var f=u.exec(t);if(!f)continue;f[1]?a--:a++;if(!a)break}var l=n;if(l>o)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom",f=t.supportConstantColor="aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen",l=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"ruleset"},{token:"paren.rparen",regex:"\\}"},{token:"string",regex:"@(?!viewport)",next:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"keyword",regex:"%"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant.numeric",regex:c},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"start"},{token:"paren.rparen",regex:"\\}",next:"start"},{token:"string",regex:";",next:"start"},{token:"keyword",regex:"(?:media|supports|document|charset|import|namespace|media|supports|document|page|font|keyframes|viewport|counter-style|font-feature-values|swash|ornaments|annotation|stylistic|styleset|character-variant)"}],comments:[{token:"comment",regex:"\\/\\*",push:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}]}],ruleset:[{regex:"-(webkit|ms|moz|o)-",token:"text"},{token:"punctuation.operator",regex:"[:;]"},{token:"paren.rparen",regex:"\\}",next:"start"},{include:["strings","url","comments"]},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{include:"url"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}],url:[{token:"support.function",regex:"(?:url(:?-prefix)?|domain|regexp)\\(",push:[{token:"support.function",regex:"\\)",next:"pop"},{defaultToken:"string"}]}],strings:[{token:"string.start",regex:"'",push:[{token:"string.end",regex:"'|$",next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]},{token:"string.start",regex:'"',push:[{token:"string.end",regex:'"|$',next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]}],escapes:[{token:"constant.language.escape",regex:/\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/css_completions",["require","exports","module"],function(e,t,n){"use strict";var r={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,"double":2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{"default":1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},"float":{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,"static":1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},i=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e){if(typeof e[t]!="string")continue;var n=t.replace(/[A-Z]/g,function(e){return"-"+e.toLowerCase()});r.hasOwnProperty(n)||(r[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,r){this.completionsDefined||this.defineCompletions();if(e==="ruleset"||t.$mode.$id=="ace/mode/scss"){var i=t.getLine(n.row).substr(0,n.column);return/:[^;]+$/.test(i)?(/([\w\-]+):[^:]*$/.test(i),this.getPropertyValueCompletions(e,t,n,r)):this.getPropertyCompletions(e,t,n,r)}return[]},this.getPropertyCompletions=function(e,t,n,i){var s=Object.keys(r);return s.map(function(e){return{caption:e,snippet:e+": $0;",meta:"property",score:1e6}})},this.getPropertyValueCompletions=function(e,t,n,i){var s=t.getLine(n.row).substr(0,n.column),o=(/([\w\-]+):[^:]*$/.exec(s)||{})[1];if(!o)return[];var u=[];return o in r&&typeof r[o]=="object"&&(u=Object.keys(r[o])),u.map(function(e){return{caption:e,snippet:e,meta:"property value",score:1e6}})}}).call(i.prototype),t.CssCompletions=i}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"&&n.selection.isEmpty()){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(/^(\s+[^;]|\s*$)/.test(f.substring(s.column)))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"&&n.selection.isEmpty()){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}}),this.add("!important","insertion",function(e,t,n,r,i){if(i==="!"&&n.selection.isEmpty()){var s=n.getCursorPosition(),o=r.doc.getLine(s.row);if(/^\s*(;|}|$)/.test(o.substring(s.column)))return{text:"!important",selection:[10,10]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./css_completions").CssCompletions,f=e("./behaviour/css").CssBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.$completer=new a,this.foldingRules=new l};r.inherits(c,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){var t="[_:a-zA-Z\u00c0-\uffff][-_:.a-zA-Z0-9\u00c0-\uffff]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.start.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],processing_instruction:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:t},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.end.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:"+t+":)?"+t+")",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:t},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:.]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules((new o({jsx:!1})).getRules(),"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";function u(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),a=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var o=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:o+a+o,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==o&&(u(p,"attribute-value")||u(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(u(p,"tag-whitespace")||u(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(u(p,"attribute-equals")&&(d||c==">")||u(p,"decl-attribute-equals")&&(d||c=="?"))return{text:o+o,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var o=n.getSelectionRange().start,a=new s(r,o.row,o.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(u(f,"tag-name")||u(f,"tag-whitespace")||u(f,"attribute-name")||u(f,"attribute-equals")||u(f,"attribute-value")))return;if(u(f,"reference.attribute-value"))return;if(u(f,"attribute-value")){var l=a.getCurrentTokenColumn()+f.value.length;if(o.column<l)return;if(o.column==l){var c=a.stepForward();if(c&&u(c,"attribute-value"))return;a.stepBackward()}}if(/^\s*>/.test(r.getLine(o.row).slice(o.column)))return;while(!u(f,"tag-name")){f=a.stepBackward();if(f.value=="<"){f=a.stepForward();break}}var h=a.getCurrentTokenRow(),p=a.getCurrentTokenColumn();if(u(a.stepBackward(),"end-tag-open"))return;var d=f.value;h==o.row&&(d=d.substring(0,o.column-p));if(this.voidElements.hasOwnProperty(d.toLowerCase()))return;return{text:"></"+d+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var o=n.getCursorPosition(),u=r.getLine(o.row),a=new s(r,o.row,o.column),f=a.getCurrentToken();if(f&&f.type.indexOf("tag-close")!==-1){if(f.value=="/>")return;while(f&&f.type.indexOf("tag-name")===-1)f=a.stepBackward();if(!f)return;var l=f.value,c=a.getCurrentTokenRow();f=a.stepBackward();if(!f||f.type.indexOf("end-tag")!==-1)return;if(this.voidElements&&!this.voidElements[l]){var h=r.getTokenAt(o.row,o.column+1),u=r.getLine(c),p=this.$getIndent(u),d=p+r.getTabString();return h&&h.value==="</"?{text:"\n"+d+"\n"+p,selection:[1,d.length,1,d.length]}:{text:"\n"+d}}}}})};r.inherits(a,i),t.XmlBehaviour=a}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/<!-/.test(e.getLine(t))?"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.optionalEndTags.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return this.getCommentFoldWidget(e,n)&&e.getCommentFoldRange(n,e.getLine(n).length);var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};r.start.row==r.end.row&&(l.column=r.end.column);while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,a.start.row==a.end.row&&a.start.column<a.end.column&&(a.start.column=a.end.column),s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}function c(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"attribute-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={a:{href:1,target:{_blank:1,top:1},ping:1,rel:{nofollow:1,alternate:1,author:1,bookmark:1,help:1,license:1,next:1,noreferrer:1,prefetch:1,prev:1,search:1,tag:1},media:1,hreflang:1,type:1},abbr:{},address:{},area:{shape:1,coords:1,href:1,hreflang:1,alt:1,target:1,media:1,rel:1,ping:1,type:1},article:{pubdate:1},aside:{},audio:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},muted:{muted:1},preload:{auto:1,metadata:1,none:1}},b:{},base:{href:1,target:1},bdi:{},bdo:{},blockquote:{cite:1},body:{onafterprint:1,onbeforeprint:1,onbeforeunload:1,onhashchange:1,onmessage:1,onoffline:1,onpopstate:1,onredo:1,onresize:1,onstorage:1,onundo:1,onunload:1},br:{},button:{autofocus:1,disabled:{disabled:1},form:1,formaction:1,formenctype:1,formmethod:1,formnovalidate:1,formtarget:1,name:1,value:1,type:{button:1,submit:1}},canvas:{width:1,height:1},caption:{},cite:{},code:{},col:{span:1},colgroup:{span:1},command:{type:1,label:1,icon:1,disabled:1,checked:1,radiogroup:1,command:1},data:{},datalist:{},dd:{},del:{cite:1,datetime:1},details:{open:1},dfn:{},dialog:{open:1},div:{},dl:{},dt:{},em:{},embed:{src:1,height:1,width:1,type:1},fieldset:{disabled:1,form:1,name:1},figcaption:{},figure:{},footer:{},form:{"accept-charset":1,action:1,autocomplete:1,enctype:{"multipart/form-data":1,"application/x-www-form-urlencoded":1},method:{get:1,post:1},name:1,novalidate:1,target:{_blank:1,top:1}},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{},header:{},hr:{},html:{manifest:1},i:{},iframe:{name:1,src:1,height:1,width:1,sandbox:{"allow-same-origin":1,"allow-top-navigation":1,"allow-forms":1,"allow-scripts":1},seamless:{seamless:1}},img:{alt:1,src:1,height:1,width:1,usemap:1,ismap:1},input:{type:{text:1,password:1,hidden:1,checkbox:1,submit:1,radio:1,file:1,button:1,reset:1,image:31,color:1,date:1,datetime:1,"datetime-local":1,email:1,month:1,number:1,range:1,search:1,tel:1,time:1,url:1,week:1},accept:1,alt:1,autocomplete:{on:1,off:1},autofocus:{autofocus:1},checked:{checked:1},disabled:{disabled:1},form:1,formaction:1,formenctype:{"application/x-www-form-urlencoded":1,"multipart/form-data":1,"text/plain":1},formmethod:{get:1,post:1},formnovalidate:{formnovalidate:1},formtarget:{_blank:1,_self:1,_parent:1,_top:1},height:1,list:1,max:1,maxlength:1,min:1,multiple:{multiple:1},name:1,pattern:1,placeholder:1,readonly:{readonly:1},required:{required:1},size:1,src:1,step:1,width:1,files:1,value:1},ins:{cite:1,datetime:1},kbd:{},keygen:{autofocus:1,challenge:{challenge:1},disabled:{disabled:1},form:1,keytype:{rsa:1,dsa:1,ec:1},name:1},label:{form:1,"for":1},legend:{},li:{value:1},link:{href:1,hreflang:1,rel:{stylesheet:1,icon:1},media:{all:1,screen:1,print:1},type:{"text/css":1,"image/png":1,"image/jpeg":1,"image/gif":1},sizes:1},main:{},map:{name:1},mark:{},math:{},menu:{type:1,label:1},meta:{"http-equiv":{"content-type":1},name:{description:1,keywords:1},content:{"text/html; charset=UTF-8":1},charset:1},meter:{value:1,min:1,max:1,low:1,high:1,optimum:1},nav:{},noscript:{href:1},object:{param:1,data:1,type:1,height:1,width:1,usemap:1,name:1,form:1,classid:1},ol:{start:1,reversed:1},optgroup:{disabled:1,label:1},option:{disabled:1,selected:1,label:1,value:1},output:{"for":1,form:1,name:1},p:{},param:{name:1,value:1},pre:{},progress:{value:1,max:1},q:{cite:1},rp:{},rt:{},ruby:{},s:{},samp:{},script:{charset:1,type:{"text/javascript":1},src:1,defer:1,async:1},select:{autofocus:1,disabled:1,form:1,multiple:{multiple:1},name:1,size:1,readonly:{readonly:1}},small:{},source:{src:1,type:1,media:1},span:{},strong:{},style:{type:1,media:{all:1,screen:1,print:1},scoped:1},sub:{},sup:{},svg:{},table:{summary:1},tbody:{},td:{headers:1,rowspan:1,colspan:1},textarea:{autofocus:{autofocus:1},disabled:{disabled:1},form:1,maxlength:1,name:1,placeholder:1,readonly:{readonly:1},required:{required:1},rows:1,cols:1,wrap:{on:1,off:1,hard:1,soft:1}},tfoot:{},th:{headers:1,rowspan:1,colspan:1,scope:1},thead:{},time:{datetime:1},title:{},tr:{},track:{kind:1,src:1,srclang:1,label:1,"default":1},section:{},summary:{},u:{},ul:{},"var":{},video:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},width:1,height:1,poster:1,muted:{muted:1},preload:{auto:1,metadata:1,none:1}},wbr:{}},a=Object.keys(u),h=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);if(!i)return[];if(f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open"))return this.getTagCompletions(e,t,n,r);if(f(i,"tag-whitespace")||f(i,"attribute-name"))return this.getAttributeCompletions(e,t,n,r);if(f(i,"attribute-value"))return this.getAttributeValueCompletions(e,t,n,r);var s=t.getLine(n.row).substr(0,n.column);return/&[a-z]*$/i.test(s)?this.getHTMLEntityCompletions(e,t,n,r):[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:1e6}})},this.getAttributeCompletions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(Object.keys(u[i]))),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:1e6}})},this.getAttributeValueCompletions=function(e,t,n,r){var i=l(t,n),s=c(t,n);if(!i)return[];var o=[];return i in u&&s in u[i]&&typeof u[i][s]=="object"&&(o=Object.keys(u[i][s])),o.map(function(e){return{caption:e,snippet:e,meta:"attribute value",score:1e6}})},this.getHTMLEntityCompletions=function(e,t,n,r){var i=["Aacute;","aacute;","Acirc;","acirc;","acute;","AElig;","aelig;","Agrave;","agrave;","alefsym;","Alpha;","alpha;","amp;","and;","ang;","Aring;","aring;","asymp;","Atilde;","atilde;","Auml;","auml;","bdquo;","Beta;","beta;","brvbar;","bull;","cap;","Ccedil;","ccedil;","cedil;","cent;","Chi;","chi;","circ;","clubs;","cong;","copy;","crarr;","cup;","curren;","Dagger;","dagger;","dArr;","darr;","deg;","Delta;","delta;","diams;","divide;","Eacute;","eacute;","Ecirc;","ecirc;","Egrave;","egrave;","empty;","emsp;","ensp;","Epsilon;","epsilon;","equiv;","Eta;","eta;","ETH;","eth;","Euml;","euml;","euro;","exist;","fnof;","forall;","frac12;","frac14;","frac34;","frasl;","Gamma;","gamma;","ge;","gt;","hArr;","harr;","hearts;","hellip;","Iacute;","iacute;","Icirc;","icirc;","iexcl;","Igrave;","igrave;","image;","infin;","int;","Iota;","iota;","iquest;","isin;","Iuml;","iuml;","Kappa;","kappa;","Lambda;","lambda;","lang;","laquo;","lArr;","larr;","lceil;","ldquo;","le;","lfloor;","lowast;","loz;","lrm;","lsaquo;","lsquo;","lt;","macr;","mdash;","micro;","middot;","minus;","Mu;","mu;","nabla;","nbsp;","ndash;","ne;","ni;","not;","notin;","nsub;","Ntilde;","ntilde;","Nu;","nu;","Oacute;","oacute;","Ocirc;","ocirc;","OElig;","oelig;","Ograve;","ograve;","oline;","Omega;","omega;","Omicron;","omicron;","oplus;","or;","ordf;","ordm;","Oslash;","oslash;","Otilde;","otilde;","otimes;","Ouml;","ouml;","para;","part;","permil;","perp;","Phi;","phi;","Pi;","pi;","piv;","plusmn;","pound;","Prime;","prime;","prod;","prop;","Psi;","psi;","quot;","radic;","rang;","raquo;","rArr;","rarr;","rceil;","rdquo;","real;","reg;","rfloor;","Rho;","rho;","rlm;","rsaquo;","rsquo;","sbquo;","Scaron;","scaron;","sdot;","sect;","shy;","Sigma;","sigma;","sigmaf;","sim;","spades;","sub;","sube;","sum;","sup;","sup1;","sup2;","sup3;","supe;","szlig;","Tau;","tau;","there4;","Theta;","theta;","thetasym;","thinsp;","THORN;","thorn;","tilde;","times;","trade;","Uacute;","uacute;","uArr;","uarr;","Ucirc;","ucirc;","Ugrave;","ugrave;","uml;","upsih;","Upsilon;","upsilon;","Uuml;","uuml;","weierp;","Xi;","xi;","Yacute;","yacute;","yen;","Yuml;","yuml;","Zeta;","zeta;","zwj;","zwnj;"];return i.map(function(e){return{caption:e,snippet:e,meta:"html entity",score:1e6}})}}).call(h.prototype),t.HtmlCompletions=h}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/handlebars_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules"],function(e,t,n){"use strict";function s(e,t){return t.splice(0,3),t.shift()||"start"}var r=e("../lib/oop"),i=e("./html_highlight_rules").HtmlHighlightRules,o=function(){i.call(this);var e={regex:"(?={{)",push:"handlebars"};for(var t in this.$rules)this.$rules[t].unshift(e);this.$rules.handlebars=[{token:"comment.start",regex:"{{!--",push:[{token:"comment.end",regex:"--}}",next:s},{defaultToken:"comment"}]},{token:"comment.start",regex:"{{!",push:[{token:"comment.end",regex:"}}",next:s},{defaultToken:"comment"}]},{token:"support.function",regex:"{{{",push:[{token:"support.function",regex:"}}}",next:s},{token:"variable.parameter",regex:"[a-zA-Z_$][a-zA-Z0-9_$]*"}]},{token:"storage.type.start",regex:"{{[#\\^/&]?",push:[{token:"storage.type.end",regex:"}}",next:s},{token:"variable.parameter",regex:"[a-zA-Z_$][a-zA-Z0-9_$]*"}]}],this.normalizeRules()};r.inherits(o,i),t.HandlebarsHighlightRules=o}),ace.define("ace/mode/behaviour/html",["require","exports","module","ace/lib/oop","ace/mode/behaviour/xml"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour/xml").XmlBehaviour,s=function(){i.call(this)};r.inherits(s,i),t.HtmlBehaviour=s}),ace.define("ace/mode/handlebars",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/handlebars_highlight_rules","ace/mode/behaviour/html","ace/mode/folding/html"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html").Mode,s=e("./handlebars_highlight_rules").HandlebarsHighlightRules,o=e("./behaviour/html").HtmlBehaviour,u=e("./folding/html").FoldMode,a=function(){i.call(this),this.HighlightRules=s,this.$behaviour=new o};r.inherits(a,i),function(){this.blockComment={start:"{{!--",end:"--}}"},this.$id="ace/mode/handlebars"}.call(a.prototype),t.Mode=a}); (function() { + ace.require(["ace/mode/handlebars"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-html.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-html.js new file mode 100644 index 0000000..7cee28c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-html.js @@ -0,0 +1,8 @@ +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},s.getTagRule(),{defaultToken:"comment.doc",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";function a(){var e=o.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r=e.charAt(1)=="/"?2:1;if(r==1)t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++;else if(r==2&&t==this.nextState){n[1]--;if(!n[1]||n[1]<0)n.shift(),n.shift()}return[{type:"meta.tag.punctuation."+(r==1?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"</?"+e+"",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),e.length==2&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,f("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function f(e){return[{token:"comment",regex:/\/\*/,next:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[i.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*",u=function(e){var t=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),n="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[i.getStartRule("doc-start"),f("no_regex"),{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+o+")(\\.)(prototype)(\\.)("+o+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+o+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:"+n+")\\b",next:"start"},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:t,regex:o},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(?:(\\s+)(\\w+))?(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:o},{regex:"",token:"empty",next:"no_regex"}],start:[i.getStartRule("doc-start"),f("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:o},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]};if(!e||!e.noES6)this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)n.unshift("start",t);else if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1||this.next.indexOf("jsx")!=-1)return"paren.quasi.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]}),(!e||e.jsx!=0)&&a.call(this);this.embedRules(i,"doc-",[i.getEndRule("no_regex")]),this.normalizeRules()};r.inherits(u,s),t.JavaScriptHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++n<s){t=e.getLine(n);var f=u.exec(t);if(!f)continue;f[1]?a--:a++;if(!a)break}var l=n;if(l>o)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom",f=t.supportConstantColor="aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen",l=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"ruleset"},{token:"paren.rparen",regex:"\\}"},{token:"string",regex:"@(?!viewport)",next:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"keyword",regex:"%"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant.numeric",regex:c},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"start"},{token:"paren.rparen",regex:"\\}",next:"start"},{token:"string",regex:";",next:"start"},{token:"keyword",regex:"(?:media|supports|document|charset|import|namespace|media|supports|document|page|font|keyframes|viewport|counter-style|font-feature-values|swash|ornaments|annotation|stylistic|styleset|character-variant)"}],comments:[{token:"comment",regex:"\\/\\*",push:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}]}],ruleset:[{regex:"-(webkit|ms|moz|o)-",token:"text"},{token:"punctuation.operator",regex:"[:;]"},{token:"paren.rparen",regex:"\\}",next:"start"},{include:["strings","url","comments"]},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{include:"url"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}],url:[{token:"support.function",regex:"(?:url(:?-prefix)?|domain|regexp)\\(",push:[{token:"support.function",regex:"\\)",next:"pop"},{defaultToken:"string"}]}],strings:[{token:"string.start",regex:"'",push:[{token:"string.end",regex:"'|$",next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]},{token:"string.start",regex:'"',push:[{token:"string.end",regex:'"|$',next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]}],escapes:[{token:"constant.language.escape",regex:/\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/css_completions",["require","exports","module"],function(e,t,n){"use strict";var r={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,"double":2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{"default":1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},"float":{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,"static":1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},i=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e){if(typeof e[t]!="string")continue;var n=t.replace(/[A-Z]/g,function(e){return"-"+e.toLowerCase()});r.hasOwnProperty(n)||(r[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,r){this.completionsDefined||this.defineCompletions();if(e==="ruleset"||t.$mode.$id=="ace/mode/scss"){var i=t.getLine(n.row).substr(0,n.column);return/:[^;]+$/.test(i)?(/([\w\-]+):[^:]*$/.test(i),this.getPropertyValueCompletions(e,t,n,r)):this.getPropertyCompletions(e,t,n,r)}return[]},this.getPropertyCompletions=function(e,t,n,i){var s=Object.keys(r);return s.map(function(e){return{caption:e,snippet:e+": $0;",meta:"property",score:1e6}})},this.getPropertyValueCompletions=function(e,t,n,i){var s=t.getLine(n.row).substr(0,n.column),o=(/([\w\-]+):[^:]*$/.exec(s)||{})[1];if(!o)return[];var u=[];return o in r&&typeof r[o]=="object"&&(u=Object.keys(r[o])),u.map(function(e){return{caption:e,snippet:e,meta:"property value",score:1e6}})}}).call(i.prototype),t.CssCompletions=i}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"&&n.selection.isEmpty()){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(/^(\s+[^;]|\s*$)/.test(f.substring(s.column)))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"&&n.selection.isEmpty()){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}}),this.add("!important","insertion",function(e,t,n,r,i){if(i==="!"&&n.selection.isEmpty()){var s=n.getCursorPosition(),o=r.doc.getLine(s.row);if(/^\s*(;|}|$)/.test(o.substring(s.column)))return{text:"!important",selection:[10,10]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./css_completions").CssCompletions,f=e("./behaviour/css").CssBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.$completer=new a,this.foldingRules=new l};r.inherits(c,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){var t="[_:a-zA-Z\u00c0-\uffff][-_:.a-zA-Z0-9\u00c0-\uffff]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.start.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],processing_instruction:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:t},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.end.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:"+t+":)?"+t+")",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:t},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:.]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules((new o({jsx:!1})).getRules(),"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";function u(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),a=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var o=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:o+a+o,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==o&&(u(p,"attribute-value")||u(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(u(p,"tag-whitespace")||u(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(u(p,"attribute-equals")&&(d||c==">")||u(p,"decl-attribute-equals")&&(d||c=="?"))return{text:o+o,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var o=n.getSelectionRange().start,a=new s(r,o.row,o.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(u(f,"tag-name")||u(f,"tag-whitespace")||u(f,"attribute-name")||u(f,"attribute-equals")||u(f,"attribute-value")))return;if(u(f,"reference.attribute-value"))return;if(u(f,"attribute-value")){var l=a.getCurrentTokenColumn()+f.value.length;if(o.column<l)return;if(o.column==l){var c=a.stepForward();if(c&&u(c,"attribute-value"))return;a.stepBackward()}}if(/^\s*>/.test(r.getLine(o.row).slice(o.column)))return;while(!u(f,"tag-name")){f=a.stepBackward();if(f.value=="<"){f=a.stepForward();break}}var h=a.getCurrentTokenRow(),p=a.getCurrentTokenColumn();if(u(a.stepBackward(),"end-tag-open"))return;var d=f.value;h==o.row&&(d=d.substring(0,o.column-p));if(this.voidElements.hasOwnProperty(d.toLowerCase()))return;return{text:"></"+d+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var o=n.getCursorPosition(),u=r.getLine(o.row),a=new s(r,o.row,o.column),f=a.getCurrentToken();if(f&&f.type.indexOf("tag-close")!==-1){if(f.value=="/>")return;while(f&&f.type.indexOf("tag-name")===-1)f=a.stepBackward();if(!f)return;var l=f.value,c=a.getCurrentTokenRow();f=a.stepBackward();if(!f||f.type.indexOf("end-tag")!==-1)return;if(this.voidElements&&!this.voidElements[l]){var h=r.getTokenAt(o.row,o.column+1),u=r.getLine(c),p=this.$getIndent(u),d=p+r.getTabString();return h&&h.value==="</"?{text:"\n"+d+"\n"+p,selection:[1,d.length,1,d.length]}:{text:"\n"+d}}}}})};r.inherits(a,i),t.XmlBehaviour=a}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/<!-/.test(e.getLine(t))?"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.optionalEndTags.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return this.getCommentFoldWidget(e,n)&&e.getCommentFoldRange(n,e.getLine(n).length);var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};r.start.row==r.end.row&&(l.column=r.end.column);while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,a.start.row==a.end.row&&a.start.column<a.end.column&&(a.start.column=a.end.column),s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}function c(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"attribute-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={a:{href:1,target:{_blank:1,top:1},ping:1,rel:{nofollow:1,alternate:1,author:1,bookmark:1,help:1,license:1,next:1,noreferrer:1,prefetch:1,prev:1,search:1,tag:1},media:1,hreflang:1,type:1},abbr:{},address:{},area:{shape:1,coords:1,href:1,hreflang:1,alt:1,target:1,media:1,rel:1,ping:1,type:1},article:{pubdate:1},aside:{},audio:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},muted:{muted:1},preload:{auto:1,metadata:1,none:1}},b:{},base:{href:1,target:1},bdi:{},bdo:{},blockquote:{cite:1},body:{onafterprint:1,onbeforeprint:1,onbeforeunload:1,onhashchange:1,onmessage:1,onoffline:1,onpopstate:1,onredo:1,onresize:1,onstorage:1,onundo:1,onunload:1},br:{},button:{autofocus:1,disabled:{disabled:1},form:1,formaction:1,formenctype:1,formmethod:1,formnovalidate:1,formtarget:1,name:1,value:1,type:{button:1,submit:1}},canvas:{width:1,height:1},caption:{},cite:{},code:{},col:{span:1},colgroup:{span:1},command:{type:1,label:1,icon:1,disabled:1,checked:1,radiogroup:1,command:1},data:{},datalist:{},dd:{},del:{cite:1,datetime:1},details:{open:1},dfn:{},dialog:{open:1},div:{},dl:{},dt:{},em:{},embed:{src:1,height:1,width:1,type:1},fieldset:{disabled:1,form:1,name:1},figcaption:{},figure:{},footer:{},form:{"accept-charset":1,action:1,autocomplete:1,enctype:{"multipart/form-data":1,"application/x-www-form-urlencoded":1},method:{get:1,post:1},name:1,novalidate:1,target:{_blank:1,top:1}},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{},header:{},hr:{},html:{manifest:1},i:{},iframe:{name:1,src:1,height:1,width:1,sandbox:{"allow-same-origin":1,"allow-top-navigation":1,"allow-forms":1,"allow-scripts":1},seamless:{seamless:1}},img:{alt:1,src:1,height:1,width:1,usemap:1,ismap:1},input:{type:{text:1,password:1,hidden:1,checkbox:1,submit:1,radio:1,file:1,button:1,reset:1,image:31,color:1,date:1,datetime:1,"datetime-local":1,email:1,month:1,number:1,range:1,search:1,tel:1,time:1,url:1,week:1},accept:1,alt:1,autocomplete:{on:1,off:1},autofocus:{autofocus:1},checked:{checked:1},disabled:{disabled:1},form:1,formaction:1,formenctype:{"application/x-www-form-urlencoded":1,"multipart/form-data":1,"text/plain":1},formmethod:{get:1,post:1},formnovalidate:{formnovalidate:1},formtarget:{_blank:1,_self:1,_parent:1,_top:1},height:1,list:1,max:1,maxlength:1,min:1,multiple:{multiple:1},name:1,pattern:1,placeholder:1,readonly:{readonly:1},required:{required:1},size:1,src:1,step:1,width:1,files:1,value:1},ins:{cite:1,datetime:1},kbd:{},keygen:{autofocus:1,challenge:{challenge:1},disabled:{disabled:1},form:1,keytype:{rsa:1,dsa:1,ec:1},name:1},label:{form:1,"for":1},legend:{},li:{value:1},link:{href:1,hreflang:1,rel:{stylesheet:1,icon:1},media:{all:1,screen:1,print:1},type:{"text/css":1,"image/png":1,"image/jpeg":1,"image/gif":1},sizes:1},main:{},map:{name:1},mark:{},math:{},menu:{type:1,label:1},meta:{"http-equiv":{"content-type":1},name:{description:1,keywords:1},content:{"text/html; charset=UTF-8":1},charset:1},meter:{value:1,min:1,max:1,low:1,high:1,optimum:1},nav:{},noscript:{href:1},object:{param:1,data:1,type:1,height:1,width:1,usemap:1,name:1,form:1,classid:1},ol:{start:1,reversed:1},optgroup:{disabled:1,label:1},option:{disabled:1,selected:1,label:1,value:1},output:{"for":1,form:1,name:1},p:{},param:{name:1,value:1},pre:{},progress:{value:1,max:1},q:{cite:1},rp:{},rt:{},ruby:{},s:{},samp:{},script:{charset:1,type:{"text/javascript":1},src:1,defer:1,async:1},select:{autofocus:1,disabled:1,form:1,multiple:{multiple:1},name:1,size:1,readonly:{readonly:1}},small:{},source:{src:1,type:1,media:1},span:{},strong:{},style:{type:1,media:{all:1,screen:1,print:1},scoped:1},sub:{},sup:{},svg:{},table:{summary:1},tbody:{},td:{headers:1,rowspan:1,colspan:1},textarea:{autofocus:{autofocus:1},disabled:{disabled:1},form:1,maxlength:1,name:1,placeholder:1,readonly:{readonly:1},required:{required:1},rows:1,cols:1,wrap:{on:1,off:1,hard:1,soft:1}},tfoot:{},th:{headers:1,rowspan:1,colspan:1,scope:1},thead:{},time:{datetime:1},title:{},tr:{},track:{kind:1,src:1,srclang:1,label:1,"default":1},section:{},summary:{},u:{},ul:{},"var":{},video:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},width:1,height:1,poster:1,muted:{muted:1},preload:{auto:1,metadata:1,none:1}},wbr:{}},a=Object.keys(u),h=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);if(!i)return[];if(f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open"))return this.getTagCompletions(e,t,n,r);if(f(i,"tag-whitespace")||f(i,"attribute-name"))return this.getAttributeCompletions(e,t,n,r);if(f(i,"attribute-value"))return this.getAttributeValueCompletions(e,t,n,r);var s=t.getLine(n.row).substr(0,n.column);return/&[a-z]*$/i.test(s)?this.getHTMLEntityCompletions(e,t,n,r):[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:1e6}})},this.getAttributeCompletions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(Object.keys(u[i]))),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:1e6}})},this.getAttributeValueCompletions=function(e,t,n,r){var i=l(t,n),s=c(t,n);if(!i)return[];var o=[];return i in u&&s in u[i]&&typeof u[i][s]=="object"&&(o=Object.keys(u[i][s])),o.map(function(e){return{caption:e,snippet:e,meta:"attribute value",score:1e6}})},this.getHTMLEntityCompletions=function(e,t,n,r){var i=["Aacute;","aacute;","Acirc;","acirc;","acute;","AElig;","aelig;","Agrave;","agrave;","alefsym;","Alpha;","alpha;","amp;","and;","ang;","Aring;","aring;","asymp;","Atilde;","atilde;","Auml;","auml;","bdquo;","Beta;","beta;","brvbar;","bull;","cap;","Ccedil;","ccedil;","cedil;","cent;","Chi;","chi;","circ;","clubs;","cong;","copy;","crarr;","cup;","curren;","Dagger;","dagger;","dArr;","darr;","deg;","Delta;","delta;","diams;","divide;","Eacute;","eacute;","Ecirc;","ecirc;","Egrave;","egrave;","empty;","emsp;","ensp;","Epsilon;","epsilon;","equiv;","Eta;","eta;","ETH;","eth;","Euml;","euml;","euro;","exist;","fnof;","forall;","frac12;","frac14;","frac34;","frasl;","Gamma;","gamma;","ge;","gt;","hArr;","harr;","hearts;","hellip;","Iacute;","iacute;","Icirc;","icirc;","iexcl;","Igrave;","igrave;","image;","infin;","int;","Iota;","iota;","iquest;","isin;","Iuml;","iuml;","Kappa;","kappa;","Lambda;","lambda;","lang;","laquo;","lArr;","larr;","lceil;","ldquo;","le;","lfloor;","lowast;","loz;","lrm;","lsaquo;","lsquo;","lt;","macr;","mdash;","micro;","middot;","minus;","Mu;","mu;","nabla;","nbsp;","ndash;","ne;","ni;","not;","notin;","nsub;","Ntilde;","ntilde;","Nu;","nu;","Oacute;","oacute;","Ocirc;","ocirc;","OElig;","oelig;","Ograve;","ograve;","oline;","Omega;","omega;","Omicron;","omicron;","oplus;","or;","ordf;","ordm;","Oslash;","oslash;","Otilde;","otilde;","otimes;","Ouml;","ouml;","para;","part;","permil;","perp;","Phi;","phi;","Pi;","pi;","piv;","plusmn;","pound;","Prime;","prime;","prod;","prop;","Psi;","psi;","quot;","radic;","rang;","raquo;","rArr;","rarr;","rceil;","rdquo;","real;","reg;","rfloor;","Rho;","rho;","rlm;","rsaquo;","rsquo;","sbquo;","Scaron;","scaron;","sdot;","sect;","shy;","Sigma;","sigma;","sigmaf;","sim;","spades;","sub;","sube;","sum;","sup;","sup1;","sup2;","sup3;","supe;","szlig;","Tau;","tau;","there4;","Theta;","theta;","thetasym;","thinsp;","THORN;","thorn;","tilde;","times;","trade;","Uacute;","uacute;","uArr;","uarr;","Ucirc;","ucirc;","Ugrave;","ugrave;","uml;","upsih;","Upsilon;","upsilon;","Uuml;","uuml;","weierp;","Xi;","xi;","Yacute;","yacute;","yen;","Yuml;","yuml;","Zeta;","zeta;","zwj;","zwnj;"];return i.map(function(e){return{caption:e,snippet:e,meta:"html entity",score:1e6}})}}).call(h.prototype),t.HtmlCompletions=h}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}); (function() { + ace.require(["ace/mode/html"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-javascript.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-javascript.js new file mode 100644 index 0000000..68ba6a1 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-javascript.js @@ -0,0 +1,8 @@ +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},s.getTagRule(),{defaultToken:"comment.doc",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";function a(){var e=o.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r=e.charAt(1)=="/"?2:1;if(r==1)t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++;else if(r==2&&t==this.nextState){n[1]--;if(!n[1]||n[1]<0)n.shift(),n.shift()}return[{type:"meta.tag.punctuation."+(r==1?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"</?"+e+"",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),e.length==2&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,f("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function f(e){return[{token:"comment",regex:/\/\*/,next:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[i.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*",u=function(e){var t=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),n="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[i.getStartRule("doc-start"),f("no_regex"),{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+o+")(\\.)(prototype)(\\.)("+o+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+o+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:"+n+")\\b",next:"start"},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:t,regex:o},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(?:(\\s+)(\\w+))?(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:o},{regex:"",token:"empty",next:"no_regex"}],start:[i.getStartRule("doc-start"),f("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:o},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]};if(!e||!e.noES6)this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)n.unshift("start",t);else if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1||this.next.indexOf("jsx")!=-1)return"paren.quasi.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]}),(!e||e.jsx!=0)&&a.call(this);this.embedRules(i,"doc-",[i.getEndRule("no_regex")]),this.normalizeRules()};r.inherits(u,s),t.JavaScriptHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++n<s){t=e.getLine(n);var f=u.exec(t);if(!f)continue;f[1]?a--:a++;if(!a)break}var l=n;if(l>o)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(l.prototype),t.Mode=l}); (function() { + ace.require(["ace/mode/javascript"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-json.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-json.js new file mode 100644 index 0000000..dc0bf0b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-json.js @@ -0,0 +1,8 @@ +ace.define("ace/mode/json_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"variable",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]\\s*(?=:)'},{token:"string",regex:'"',next:"string"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:"text",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"comment",regex:"\\/\\/.*$"},{token:"comment.start",regex:"\\/\\*",next:"comment"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],string:[{token:"constant.language.escape",regex:/\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|["\\\/bfnrt])/},{token:"string",regex:'"|$',next:"start"},{defaultToken:"string"}],comment:[{token:"comment.end",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}]}};r.inherits(s,i),t.JsonHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++n<s){t=e.getLine(n);var f=u.exec(t);if(!f)continue;f[1]?a--:a++;if(!a)break}var l=n;if(l>o)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/json",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/json_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./json_highlight_rules").JsonHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./behaviour/cstyle").CstyleBehaviour,a=e("./folding/cstyle").FoldMode,f=e("../worker/worker_client").WorkerClient,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new u,this.foldingRules=new a};r.inherits(l,i),function(){this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t);if(e=="start"){var i=t.match(/^.*[\{\(\[]\s*$/);i&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new f(["ace"],"ace/mode/json_worker","JsonWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/json"}.call(l.prototype),t.Mode=l}); (function() { + ace.require(["ace/mode/json"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-markdown.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-markdown.js new file mode 100644 index 0000000..a7b49b0 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-markdown.js @@ -0,0 +1,8 @@ +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},s.getTagRule(),{defaultToken:"comment.doc",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";function a(){var e=o.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r=e.charAt(1)=="/"?2:1;if(r==1)t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++;else if(r==2&&t==this.nextState){n[1]--;if(!n[1]||n[1]<0)n.shift(),n.shift()}return[{type:"meta.tag.punctuation."+(r==1?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"</?"+e+"",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),e.length==2&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,f("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function f(e){return[{token:"comment",regex:/\/\*/,next:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[i.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*",u=function(e){var t=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),n="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[i.getStartRule("doc-start"),f("no_regex"),{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+o+")(\\.)(prototype)(\\.)("+o+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+o+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:"+n+")\\b",next:"start"},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:t,regex:o},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(?:(\\s+)(\\w+))?(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:o},{regex:"",token:"empty",next:"no_regex"}],start:[i.getStartRule("doc-start"),f("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:o},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]};if(!e||!e.noES6)this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)n.unshift("start",t);else if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1||this.next.indexOf("jsx")!=-1)return"paren.quasi.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]}),(!e||e.jsx!=0)&&a.call(this);this.embedRules(i,"doc-",[i.getEndRule("no_regex")]),this.normalizeRules()};r.inherits(u,s),t.JavaScriptHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++n<s){t=e.getLine(n);var f=u.exec(t);if(!f)continue;f[1]?a--:a++;if(!a)break}var l=n;if(l>o)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){var t="[_:a-zA-Z\u00c0-\uffff][-_:.a-zA-Z0-9\u00c0-\uffff]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.start.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],processing_instruction:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:t},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.end.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:"+t+":)?"+t+")",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:t},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";function u(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),a=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var o=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:o+a+o,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==o&&(u(p,"attribute-value")||u(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(u(p,"tag-whitespace")||u(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(u(p,"attribute-equals")&&(d||c==">")||u(p,"decl-attribute-equals")&&(d||c=="?"))return{text:o+o,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var o=n.getSelectionRange().start,a=new s(r,o.row,o.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(u(f,"tag-name")||u(f,"tag-whitespace")||u(f,"attribute-name")||u(f,"attribute-equals")||u(f,"attribute-value")))return;if(u(f,"reference.attribute-value"))return;if(u(f,"attribute-value")){var l=a.getCurrentTokenColumn()+f.value.length;if(o.column<l)return;if(o.column==l){var c=a.stepForward();if(c&&u(c,"attribute-value"))return;a.stepBackward()}}if(/^\s*>/.test(r.getLine(o.row).slice(o.column)))return;while(!u(f,"tag-name")){f=a.stepBackward();if(f.value=="<"){f=a.stepForward();break}}var h=a.getCurrentTokenRow(),p=a.getCurrentTokenColumn();if(u(a.stepBackward(),"end-tag-open"))return;var d=f.value;h==o.row&&(d=d.substring(0,o.column-p));if(this.voidElements.hasOwnProperty(d.toLowerCase()))return;return{text:"></"+d+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var o=n.getCursorPosition(),u=r.getLine(o.row),a=new s(r,o.row,o.column),f=a.getCurrentToken();if(f&&f.type.indexOf("tag-close")!==-1){if(f.value=="/>")return;while(f&&f.type.indexOf("tag-name")===-1)f=a.stepBackward();if(!f)return;var l=f.value,c=a.getCurrentTokenRow();f=a.stepBackward();if(!f||f.type.indexOf("end-tag")!==-1)return;if(this.voidElements&&!this.voidElements[l]){var h=r.getTokenAt(o.row,o.column+1),u=r.getLine(c),p=this.$getIndent(u),d=p+r.getTabString();return h&&h.value==="</"?{text:"\n"+d+"\n"+p,selection:[1,d.length,1,d.length]}:{text:"\n"+d}}}}})};r.inherits(a,i),t.XmlBehaviour=a}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/<!-/.test(e.getLine(t))?"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.optionalEndTags.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return this.getCommentFoldWidget(e,n)&&e.getCommentFoldRange(n,e.getLine(n).length);var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};r.start.row==r.end.row&&(l.column=r.end.column);while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,a.start.row==a.end.row&&a.start.column<a.end.column&&(a.start.column=a.end.column),s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/xml_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/xml","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./xml_highlight_rules").XmlHighlightRules,u=e("./behaviour/xml").XmlBehaviour,a=e("./folding/xml").FoldMode,f=e("../worker/worker_client").WorkerClient,l=function(){this.HighlightRules=o,this.$behaviour=new u,this.foldingRules=new a};r.inherits(l,s),function(){this.voidElements=i.arrayToMap([]),this.blockComment={start:"<!--",end:"-->"},this.createWorker=function(e){var t=new f(["ace"],"ace/mode/xml_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/xml"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom",f=t.supportConstantColor="aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen",l=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"ruleset"},{token:"paren.rparen",regex:"\\}"},{token:"string",regex:"@(?!viewport)",next:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"keyword",regex:"%"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant.numeric",regex:c},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"start"},{token:"paren.rparen",regex:"\\}",next:"start"},{token:"string",regex:";",next:"start"},{token:"keyword",regex:"(?:media|supports|document|charset|import|namespace|media|supports|document|page|font|keyframes|viewport|counter-style|font-feature-values|swash|ornaments|annotation|stylistic|styleset|character-variant)"}],comments:[{token:"comment",regex:"\\/\\*",push:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}]}],ruleset:[{regex:"-(webkit|ms|moz|o)-",token:"text"},{token:"punctuation.operator",regex:"[:;]"},{token:"paren.rparen",regex:"\\}",next:"start"},{include:["strings","url","comments"]},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{include:"url"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}],url:[{token:"support.function",regex:"(?:url(:?-prefix)?|domain|regexp)\\(",push:[{token:"support.function",regex:"\\)",next:"pop"},{defaultToken:"string"}]}],strings:[{token:"string.start",regex:"'",push:[{token:"string.end",regex:"'|$",next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]},{token:"string.start",regex:'"',push:[{token:"string.end",regex:'"|$',next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]}],escapes:[{token:"constant.language.escape",regex:/\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/css_completions",["require","exports","module"],function(e,t,n){"use strict";var r={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,"double":2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{"default":1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},"float":{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,"static":1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},i=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e){if(typeof e[t]!="string")continue;var n=t.replace(/[A-Z]/g,function(e){return"-"+e.toLowerCase()});r.hasOwnProperty(n)||(r[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,r){this.completionsDefined||this.defineCompletions();if(e==="ruleset"||t.$mode.$id=="ace/mode/scss"){var i=t.getLine(n.row).substr(0,n.column);return/:[^;]+$/.test(i)?(/([\w\-]+):[^:]*$/.test(i),this.getPropertyValueCompletions(e,t,n,r)):this.getPropertyCompletions(e,t,n,r)}return[]},this.getPropertyCompletions=function(e,t,n,i){var s=Object.keys(r);return s.map(function(e){return{caption:e,snippet:e+": $0;",meta:"property",score:1e6}})},this.getPropertyValueCompletions=function(e,t,n,i){var s=t.getLine(n.row).substr(0,n.column),o=(/([\w\-]+):[^:]*$/.exec(s)||{})[1];if(!o)return[];var u=[];return o in r&&typeof r[o]=="object"&&(u=Object.keys(r[o])),u.map(function(e){return{caption:e,snippet:e,meta:"property value",score:1e6}})}}).call(i.prototype),t.CssCompletions=i}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"&&n.selection.isEmpty()){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(/^(\s+[^;]|\s*$)/.test(f.substring(s.column)))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"&&n.selection.isEmpty()){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}}),this.add("!important","insertion",function(e,t,n,r,i){if(i==="!"&&n.selection.isEmpty()){var s=n.getCursorPosition(),o=r.doc.getLine(s.row);if(/^\s*(;|}|$)/.test(o.substring(s.column)))return{text:"!important",selection:[10,10]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./css_completions").CssCompletions,f=e("./behaviour/css").CssBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.$completer=new a,this.foldingRules=new l};r.inherits(c,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:.]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules((new o({jsx:!1})).getRules(),"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}function c(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"attribute-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={a:{href:1,target:{_blank:1,top:1},ping:1,rel:{nofollow:1,alternate:1,author:1,bookmark:1,help:1,license:1,next:1,noreferrer:1,prefetch:1,prev:1,search:1,tag:1},media:1,hreflang:1,type:1},abbr:{},address:{},area:{shape:1,coords:1,href:1,hreflang:1,alt:1,target:1,media:1,rel:1,ping:1,type:1},article:{pubdate:1},aside:{},audio:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},muted:{muted:1},preload:{auto:1,metadata:1,none:1}},b:{},base:{href:1,target:1},bdi:{},bdo:{},blockquote:{cite:1},body:{onafterprint:1,onbeforeprint:1,onbeforeunload:1,onhashchange:1,onmessage:1,onoffline:1,onpopstate:1,onredo:1,onresize:1,onstorage:1,onundo:1,onunload:1},br:{},button:{autofocus:1,disabled:{disabled:1},form:1,formaction:1,formenctype:1,formmethod:1,formnovalidate:1,formtarget:1,name:1,value:1,type:{button:1,submit:1}},canvas:{width:1,height:1},caption:{},cite:{},code:{},col:{span:1},colgroup:{span:1},command:{type:1,label:1,icon:1,disabled:1,checked:1,radiogroup:1,command:1},data:{},datalist:{},dd:{},del:{cite:1,datetime:1},details:{open:1},dfn:{},dialog:{open:1},div:{},dl:{},dt:{},em:{},embed:{src:1,height:1,width:1,type:1},fieldset:{disabled:1,form:1,name:1},figcaption:{},figure:{},footer:{},form:{"accept-charset":1,action:1,autocomplete:1,enctype:{"multipart/form-data":1,"application/x-www-form-urlencoded":1},method:{get:1,post:1},name:1,novalidate:1,target:{_blank:1,top:1}},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{},header:{},hr:{},html:{manifest:1},i:{},iframe:{name:1,src:1,height:1,width:1,sandbox:{"allow-same-origin":1,"allow-top-navigation":1,"allow-forms":1,"allow-scripts":1},seamless:{seamless:1}},img:{alt:1,src:1,height:1,width:1,usemap:1,ismap:1},input:{type:{text:1,password:1,hidden:1,checkbox:1,submit:1,radio:1,file:1,button:1,reset:1,image:31,color:1,date:1,datetime:1,"datetime-local":1,email:1,month:1,number:1,range:1,search:1,tel:1,time:1,url:1,week:1},accept:1,alt:1,autocomplete:{on:1,off:1},autofocus:{autofocus:1},checked:{checked:1},disabled:{disabled:1},form:1,formaction:1,formenctype:{"application/x-www-form-urlencoded":1,"multipart/form-data":1,"text/plain":1},formmethod:{get:1,post:1},formnovalidate:{formnovalidate:1},formtarget:{_blank:1,_self:1,_parent:1,_top:1},height:1,list:1,max:1,maxlength:1,min:1,multiple:{multiple:1},name:1,pattern:1,placeholder:1,readonly:{readonly:1},required:{required:1},size:1,src:1,step:1,width:1,files:1,value:1},ins:{cite:1,datetime:1},kbd:{},keygen:{autofocus:1,challenge:{challenge:1},disabled:{disabled:1},form:1,keytype:{rsa:1,dsa:1,ec:1},name:1},label:{form:1,"for":1},legend:{},li:{value:1},link:{href:1,hreflang:1,rel:{stylesheet:1,icon:1},media:{all:1,screen:1,print:1},type:{"text/css":1,"image/png":1,"image/jpeg":1,"image/gif":1},sizes:1},main:{},map:{name:1},mark:{},math:{},menu:{type:1,label:1},meta:{"http-equiv":{"content-type":1},name:{description:1,keywords:1},content:{"text/html; charset=UTF-8":1},charset:1},meter:{value:1,min:1,max:1,low:1,high:1,optimum:1},nav:{},noscript:{href:1},object:{param:1,data:1,type:1,height:1,width:1,usemap:1,name:1,form:1,classid:1},ol:{start:1,reversed:1},optgroup:{disabled:1,label:1},option:{disabled:1,selected:1,label:1,value:1},output:{"for":1,form:1,name:1},p:{},param:{name:1,value:1},pre:{},progress:{value:1,max:1},q:{cite:1},rp:{},rt:{},ruby:{},s:{},samp:{},script:{charset:1,type:{"text/javascript":1},src:1,defer:1,async:1},select:{autofocus:1,disabled:1,form:1,multiple:{multiple:1},name:1,size:1,readonly:{readonly:1}},small:{},source:{src:1,type:1,media:1},span:{},strong:{},style:{type:1,media:{all:1,screen:1,print:1},scoped:1},sub:{},sup:{},svg:{},table:{summary:1},tbody:{},td:{headers:1,rowspan:1,colspan:1},textarea:{autofocus:{autofocus:1},disabled:{disabled:1},form:1,maxlength:1,name:1,placeholder:1,readonly:{readonly:1},required:{required:1},rows:1,cols:1,wrap:{on:1,off:1,hard:1,soft:1}},tfoot:{},th:{headers:1,rowspan:1,colspan:1,scope:1},thead:{},time:{datetime:1},title:{},tr:{},track:{kind:1,src:1,srclang:1,label:1,"default":1},section:{},summary:{},u:{},ul:{},"var":{},video:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},width:1,height:1,poster:1,muted:{muted:1},preload:{auto:1,metadata:1,none:1}},wbr:{}},a=Object.keys(u),h=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);if(!i)return[];if(f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open"))return this.getTagCompletions(e,t,n,r);if(f(i,"tag-whitespace")||f(i,"attribute-name"))return this.getAttributeCompletions(e,t,n,r);if(f(i,"attribute-value"))return this.getAttributeValueCompletions(e,t,n,r);var s=t.getLine(n.row).substr(0,n.column);return/&[a-z]*$/i.test(s)?this.getHTMLEntityCompletions(e,t,n,r):[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:1e6}})},this.getAttributeCompletions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(Object.keys(u[i]))),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:1e6}})},this.getAttributeValueCompletions=function(e,t,n,r){var i=l(t,n),s=c(t,n);if(!i)return[];var o=[];return i in u&&s in u[i]&&typeof u[i][s]=="object"&&(o=Object.keys(u[i][s])),o.map(function(e){return{caption:e,snippet:e,meta:"attribute value",score:1e6}})},this.getHTMLEntityCompletions=function(e,t,n,r){var i=["Aacute;","aacute;","Acirc;","acirc;","acute;","AElig;","aelig;","Agrave;","agrave;","alefsym;","Alpha;","alpha;","amp;","and;","ang;","Aring;","aring;","asymp;","Atilde;","atilde;","Auml;","auml;","bdquo;","Beta;","beta;","brvbar;","bull;","cap;","Ccedil;","ccedil;","cedil;","cent;","Chi;","chi;","circ;","clubs;","cong;","copy;","crarr;","cup;","curren;","Dagger;","dagger;","dArr;","darr;","deg;","Delta;","delta;","diams;","divide;","Eacute;","eacute;","Ecirc;","ecirc;","Egrave;","egrave;","empty;","emsp;","ensp;","Epsilon;","epsilon;","equiv;","Eta;","eta;","ETH;","eth;","Euml;","euml;","euro;","exist;","fnof;","forall;","frac12;","frac14;","frac34;","frasl;","Gamma;","gamma;","ge;","gt;","hArr;","harr;","hearts;","hellip;","Iacute;","iacute;","Icirc;","icirc;","iexcl;","Igrave;","igrave;","image;","infin;","int;","Iota;","iota;","iquest;","isin;","Iuml;","iuml;","Kappa;","kappa;","Lambda;","lambda;","lang;","laquo;","lArr;","larr;","lceil;","ldquo;","le;","lfloor;","lowast;","loz;","lrm;","lsaquo;","lsquo;","lt;","macr;","mdash;","micro;","middot;","minus;","Mu;","mu;","nabla;","nbsp;","ndash;","ne;","ni;","not;","notin;","nsub;","Ntilde;","ntilde;","Nu;","nu;","Oacute;","oacute;","Ocirc;","ocirc;","OElig;","oelig;","Ograve;","ograve;","oline;","Omega;","omega;","Omicron;","omicron;","oplus;","or;","ordf;","ordm;","Oslash;","oslash;","Otilde;","otilde;","otimes;","Ouml;","ouml;","para;","part;","permil;","perp;","Phi;","phi;","Pi;","pi;","piv;","plusmn;","pound;","Prime;","prime;","prod;","prop;","Psi;","psi;","quot;","radic;","rang;","raquo;","rArr;","rarr;","rceil;","rdquo;","real;","reg;","rfloor;","Rho;","rho;","rlm;","rsaquo;","rsquo;","sbquo;","Scaron;","scaron;","sdot;","sect;","shy;","Sigma;","sigma;","sigmaf;","sim;","spades;","sub;","sube;","sum;","sup;","sup1;","sup2;","sup3;","supe;","szlig;","Tau;","tau;","there4;","Theta;","theta;","thetasym;","thinsp;","THORN;","thorn;","tilde;","times;","trade;","Uacute;","uacute;","uArr;","uarr;","Ucirc;","ucirc;","Ugrave;","ugrave;","uml;","upsih;","Upsilon;","upsilon;","Uuml;","uuml;","weierp;","Xi;","xi;","Yacute;","yacute;","yen;","Yuml;","yuml;","Zeta;","zeta;","zwj;","zwnj;"];return i.map(function(e){return{caption:e,snippet:e,meta:"html entity",score:1e6}})}}).call(h.prototype),t.HtmlCompletions=h}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/markdown_highlight_rules",["require","exports","module","ace/config","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules","ace/mode/html_highlight_rules"],function(e,t,n){"use strict";var r=e("../config").$modes,i=e("../lib/oop"),s=e("../lib/lang"),o=e("./text_highlight_rules").TextHighlightRules,u=e("./html_highlight_rules").HtmlHighlightRules,a=function(e){return"(?:[^"+s.escapeRegExp(e)+"\\\\]|\\\\.)*"},f=function(){u.call(this);var e={token:"support.function",regex:/^\s*(```+[^`]*|~~~+[^~]*)$/,onMatch:function(e,t,n,i){var s=e.match(/^(\s*)([`~]+)(.*)/),o=/[\w-]+|$/.exec(s[3])[0];return r[o]||(o=""),n.unshift("githubblock",[],[s[1],s[2],o],t),this.token},next:"githubblock"},t=[{token:"support.function",regex:".*",onMatch:function(e,t,n,i){var s=n[1],o=n[2][0],u=n[2][1],a=n[2][2],f=/^(\s*)(`+|~+)\s*$/.exec(e);if(f&&f[1].length<o.length+3&&f[2].length>=u.length&&f[2][0]==u[0])return n.splice(0,3),this.next=n.shift(),this.token;this.next="";if(a&&r[a]){var l=r[a].getTokenizer().getLineTokens(e,s.slice(0));return n[1]=l.state,l.tokens}return this.token}}];this.$rules.start.unshift({token:"empty_line",regex:"^$",next:"allowBlock"},{token:"markup.heading.1",regex:"^=+(?=\\s*$)"},{token:"markup.heading.2",regex:"^\\-+(?=\\s*$)"},{token:function(e){return"markup.heading."+e.length},regex:/^#{1,6}(?=\s|$)/,next:"header"},e,{token:"string.blockquote",regex:"^\\s*>\\s*(?:[*+-]|\\d+\\.)?\\s+",next:"blockquote"},{token:"constant",regex:"^ {0,2}(?:(?: ?\\* ?){3,}|(?: ?\\- ?){3,}|(?: ?\\_ ?){3,})\\s*$",next:"allowBlock"},{token:"markup.list",regex:"^\\s{0,3}(?:[*+-]|\\d+\\.)\\s+",next:"listblock-start"},{include:"basic"}),this.addRules({basic:[{token:"constant.language.escape",regex:/\\[\\`*_{}\[\]()#+\-.!]/},{token:"support.function",regex:"(`+)(.*?[^`])(\\1)"},{token:["text","constant","text","url","string","text"],regex:'^([ ]{0,3}\\[)([^\\]]+)(\\]:\\s*)([^ ]+)(\\s*(?:["][^"]+["])?(\\s*))$'},{token:["text","string","text","constant","text"],regex:"(\\[)("+a("]")+")(\\]\\s*\\[)("+a("]")+")(\\])"},{token:["text","string","text","markup.underline","string","text"],regex:"(\\!?\\[)("+a("]")+")(\\]\\()"+'((?:[^\\)\\s\\\\]|\\\\.|\\s(?=[^"]))*)'+'(\\s*"'+a('"')+'"\\s*)?'+"(\\))"},{token:"string.strong",regex:"([*]{2}|[_]{2}(?=\\S))(.*?\\S[*_]*)(\\1)"},{token:"string.emphasis",regex:"([*]|[_](?=\\S))(.*?\\S[*_]*)(\\1)"},{token:["text","url","text"],regex:"(<)((?:https?|ftp|dict):[^'\">\\s]+|(?:mailto:)?[-.\\w]+\\@[-a-z0-9]+(?:\\.[-a-z0-9]+)*\\.[a-z]+)(>)"}],allowBlock:[{token:"support.function",regex:"^ {4}.+",next:"allowBlock"},{token:"empty_line",regex:"^$",next:"allowBlock"},{token:"empty",regex:"",next:"start"}],header:[{regex:"$",next:"start"},{include:"basic"},{defaultToken:"heading"}],"listblock-start":[{token:"support.variable",regex:/(?:\[[ x]\])?/,next:"listblock"}],listblock:[{token:"empty_line",regex:"^$",next:"start"},{token:"markup.list",regex:"^\\s{0,3}(?:[*+-]|\\d+\\.)\\s+",next:"listblock-start"},{include:"basic",noEscape:!0},e,{defaultToken:"list"}],blockquote:[{token:"empty_line",regex:"^\\s*$",next:"start"},{token:"string.blockquote",regex:"^\\s*>\\s*(?:[*+-]|\\d+\\.)?\\s+",next:"blockquote"},{include:"basic",noEscape:!0},{defaultToken:"string.blockquote"}],githubblock:t}),this.normalizeRules()};i.inherits(f,o),t.MarkdownHighlightRules=f}),ace.define("ace/mode/folding/markdown",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.foldingStartMarker=/^(?:[=-]+\s*$|#{1,6} |`{3})/,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);return this.foldingStartMarker.test(r)?r[0]=="`"?e.bgTokenizer.getState(n)=="start"?"end":"start":"start":""},this.getFoldWidgetRange=function(e,t,n){function l(t){return f=e.getTokens(t)[0],f&&f.type.lastIndexOf(c,0)===0}function h(){var e=f.value[0];return e=="="?6:e=="-"?5:7-f.value.search(/[^#]|$/)}var r=e.getLine(n),i=r.length,o=e.getLength(),u=n,a=n;if(!r.match(this.foldingStartMarker))return;if(r[0]=="`"){if(e.bgTokenizer.getState(n)!=="start"){while(++n<o){r=e.getLine(n);if(r[0]=="`"&r.substring(0,3)=="```")break}return new s(u,i,n,0)}while(n-->0){r=e.getLine(n);if(r[0]=="`"&r.substring(0,3)=="```")break}return new s(n,r.length,u,0)}var f,c="markup.heading";if(l(n)){var p=h();while(++n<o){if(!l(n))continue;var d=h();if(d>=p)break}a=n-(!f||["=","-"].indexOf(f.value[0])==-1?1:2);if(a>u)while(a>u&&/^\s*$/.test(e.getLine(a)))a--;if(a>u){var v=e.getLine(a).length;return new s(u,i,a,v)}}}}.call(o.prototype)}),ace.define("ace/mode/sh_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=t.reservedKeywords="!|{|}|case|do|done|elif|else|esac|fi|for|if|in|then|until|while|&|;|export|local|read|typeset|unset|elif|select|set|function|declare|readonly",o=t.languageConstructs="[|]|alias|bg|bind|break|builtin|cd|command|compgen|complete|continue|dirs|disown|echo|enable|eval|exec|exit|fc|fg|getopts|hash|help|history|jobs|kill|let|logout|popd|printf|pushd|pwd|return|set|shift|shopt|source|suspend|test|times|trap|type|ulimit|umask|unalias|wait",u=function(){var e=this.createKeywordMapper({keyword:s,"support.function.builtin":o,"invalid.deprecated":"debugger"},"identifier"),t="(?:(?:[1-9]\\d*)|(?:0))",n="(?:\\.\\d+)",r="(?:\\d+)",i="(?:(?:"+r+"?"+n+")|(?:"+r+"\\.))",u="(?:(?:"+i+"|"+r+")"+")",a="(?:"+u+"|"+i+")",f="(?:&"+r+")",l="[a-zA-Z_][a-zA-Z0-9_]*",c="(?:"+l+"(?==))",h="(?:\\$(?:SHLVL|\\$|\\!|\\?))",p="(?:"+l+"\\s*\\(\\))";this.$rules={start:[{token:"constant",regex:/\\./},{token:["text","comment"],regex:/(^|\s)(#.*)$/},{token:"string.start",regex:'"',push:[{token:"constant.language.escape",regex:/\\(?:[$`"\\]|$)/},{include:"variables"},{token:"keyword.operator",regex:/`/},{token:"string.end",regex:'"',next:"pop"},{defaultToken:"string"}]},{token:"string",regex:"\\$'",push:[{token:"constant.language.escape",regex:/\\(?:[abeEfnrtv\\'"]|x[a-fA-F\d]{1,2}|u[a-fA-F\d]{4}([a-fA-F\d]{4})?|c.|\d{1,3})/},{token:"string",regex:"'",next:"pop"},{defaultToken:"string"}]},{regex:"<<<",token:"keyword.operator"},{stateName:"heredoc",regex:"(<<-?)(\\s*)(['\"`]?)([\\w\\-]+)(['\"`]?)",onMatch:function(e,t,n){var r=e[2]=="-"?"indentedHeredoc":"heredoc",i=e.split(this.splitRegex);return n.push(r,i[4]),[{type:"constant",value:i[1]},{type:"text",value:i[2]},{type:"string",value:i[3]},{type:"support.class",value:i[4]},{type:"string",value:i[5]}]},rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return t[0]==="heredoc"||t[0]==="indentedHeredoc"?t[0]:e}},{token:["keyword","text","text","text","variable"],regex:/(declare|local|readonly)(\s+)(?:(-[fixar]+)(\s+))?([a-zA-Z_][a-zA-Z0-9_]*\b)/},{token:"variable.language",regex:h},{token:"variable",regex:c},{include:"variables"},{token:"support.function",regex:p},{token:"support.function",regex:f},{token:"string",start:"'",end:"'"},{token:"constant.numeric",regex:a},{token:"constant.numeric",regex:t+"\\b"},{token:e,regex:"[a-zA-Z_][a-zA-Z0-9_]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|~|<|>|<=|=>|=|!=|[%&|`]"},{token:"punctuation.operator",regex:";"},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]]"},{token:"paren.rparen",regex:"[\\)\\}]",next:"pop"}],variables:[{token:"variable",regex:/(\$)(\w+)/},{token:["variable","paren.lparen"],regex:/(\$)(\()/,push:"start"},{token:["variable","paren.lparen","keyword.operator","variable","keyword.operator"],regex:/(\$)(\{)([#!]?)(\w+|[*@#?\-$!0_])(:[?+\-=]?|##?|%%?|,,?\/|\^\^?)?/,push:"start"},{token:"variable",regex:/\$[*@#?\-$!0_]/},{token:["variable","paren.lparen"],regex:/(\$)(\{)/,push:"start"}]},this.normalizeRules()};r.inherits(u,i),t.ShHighlightRules=u}),ace.define("ace/mode/sh",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/sh_highlight_rules","ace/range","ace/mode/folding/cstyle","ace/mode/behaviour/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./sh_highlight_rules").ShHighlightRules,o=e("../range").Range,u=e("./folding/cstyle").FoldMode,a=e("./behaviour/cstyle").CstyleBehaviour,f=function(){this.HighlightRules=s,this.foldingRules=new u,this.$behaviour=new a};r.inherits(f,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[:]\s*$/);o&&(r+=n)}return r};var e={pass:1,"return":1,raise:1,"break":1,"continue":1};this.checkOutdent=function(t,n,r){if(r!=="\r\n"&&r!=="\r"&&r!=="\n")return!1;var i=this.getTokenizer().getLineTokens(n.trim(),t).tokens;if(!i)return!1;do var s=i.pop();while(s&&(s.type=="comment"||s.type=="text"&&s.value.match(/^\s+$/)));return s?s.type=="keyword"&&e[s.value]:!1},this.autoOutdent=function(e,t,n){n+=1;var r=this.$getIndent(t.getLine(n)),i=t.getTabString();r.slice(-i.length)==i&&t.remove(new o(n,r.length-i.length,n,r.length))},this.$id="ace/mode/sh"}.call(f.prototype),t.Mode=f}),ace.define("ace/mode/markdown",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript","ace/mode/xml","ace/mode/html","ace/mode/markdown_highlight_rules","ace/mode/folding/markdown","ace/mode/javascript","ace/mode/html","ace/mode/sh","ace/mode/sh","ace/mode/xml","ace/mode/css"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript").Mode,o=e("./xml").Mode,u=e("./html").Mode,a=e("./markdown_highlight_rules").MarkdownHighlightRules,f=e("./folding/markdown").FoldMode,l=function(){this.HighlightRules=a,this.createModeDelegates({javascript:e("./javascript").Mode,html:e("./html").Mode,bash:e("./sh").Mode,sh:e("./sh").Mode,xml:e("./xml").Mode,css:e("./css").Mode}),this.foldingRules=new f,this.$behaviour=this.$defaultBehaviour};r.inherits(l,i),function(){this.type="text",this.blockComment={start:"<!--",end:"-->"},this.getNextLineIndent=function(e,t,n){if(e=="listblock"){var r=/^(\s*)(?:([-+*])|(\d+)\.)(\s+)/.exec(t);if(!r)return"";var i=r[2];return i||(i=parseInt(r[3],10)+1+"."),r[1]+i+r[4]}return this.$getIndent(t)},this.$id="ace/mode/markdown"}.call(l.prototype),t.Mode=l}); (function() { + ace.require(["ace/mode/markdown"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-properties.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-properties.js new file mode 100644 index 0000000..b2ca8d7 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-properties.js @@ -0,0 +1,8 @@ +ace.define("ace/mode/properties_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e=/\\u[0-9a-fA-F]{4}|\\/;this.$rules={start:[{token:"comment",regex:/[!#].*$/},{token:"keyword",regex:/[=:]$/},{token:"keyword",regex:/[=:]/,next:"value"},{token:"constant.language.escape",regex:e},{defaultToken:"variable"}],value:[{regex:/\\$/,token:"string",next:"value"},{regex:/$/,token:"string",next:"start"},{token:"constant.language.escape",regex:e},{defaultToken:"string"}]}};r.inherits(s,i),t.PropertiesHighlightRules=s}),ace.define("ace/mode/properties",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/properties_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./properties_highlight_rules").PropertiesHighlightRules,o=function(){this.HighlightRules=s,this.$behaviour=this.$defaultBehaviour};r.inherits(o,i),function(){this.$id="ace/mode/properties"}.call(o.prototype),t.Mode=o}); (function() { + ace.require(["ace/mode/properties"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-python.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-python.js new file mode 100644 index 0000000..4627a0c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-python.js @@ -0,0 +1,8 @@ +ace.define("ace/mode/python_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|with|yield|async|await|nonlocal",t="True|False|None|NotImplemented|Ellipsis|__debug__",n="abs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|binfile|bin|iter|property|tuple|bool|filter|len|range|type|bytearray|float|list|raw_input|unichr|callable|format|locals|reduce|unicode|chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|__import__|complex|hash|min|apply|delattr|help|next|setattr|set|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern|ascii|breakpoint|bytes",r=this.createKeywordMapper({"invalid.deprecated":"debugger","support.function":n,"variable.language":"self|cls","constant.language":t,keyword:e},"identifier"),i="[uU]?",s="[rR]",o="[fF]",u="(?:[rR][fF]|[fF][rR])",a="(?:(?:[1-9]\\d*)|(?:0))",f="(?:0[oO]?[0-7]+)",l="(?:0[xX][\\dA-Fa-f]+)",c="(?:0[bB][01]+)",h="(?:"+a+"|"+f+"|"+l+"|"+c+")",p="(?:[eE][+-]?\\d+)",d="(?:\\.\\d+)",v="(?:\\d+)",m="(?:(?:"+v+"?"+d+")|(?:"+v+"\\.))",g="(?:(?:"+m+"|"+v+")"+p+")",y="(?:"+g+"|"+m+")",b="\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\abfnrtv'\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})";this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"string",regex:i+'"{3}',next:"qqstring3"},{token:"string",regex:i+'"(?=.)',next:"qqstring"},{token:"string",regex:i+"'{3}",next:"qstring3"},{token:"string",regex:i+"'(?=.)",next:"qstring"},{token:"string",regex:s+'"{3}',next:"rawqqstring3"},{token:"string",regex:s+'"(?=.)',next:"rawqqstring"},{token:"string",regex:s+"'{3}",next:"rawqstring3"},{token:"string",regex:s+"'(?=.)",next:"rawqstring"},{token:"string",regex:o+'"{3}',next:"fqqstring3"},{token:"string",regex:o+'"(?=.)',next:"fqqstring"},{token:"string",regex:o+"'{3}",next:"fqstring3"},{token:"string",regex:o+"'(?=.)",next:"fqstring"},{token:"string",regex:u+'"{3}',next:"rfqqstring3"},{token:"string",regex:u+'"(?=.)',next:"rfqqstring"},{token:"string",regex:u+"'{3}",next:"rfqstring3"},{token:"string",regex:u+"'(?=.)",next:"rfqstring"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|%|@|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"punctuation",regex:",|:|;|\\->|\\+=|\\-=|\\*=|\\/=|\\/\\/=|%=|@=|&=|\\|=|^=|>>=|<<=|\\*\\*="},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+"},{include:"constants"}],qqstring3:[{token:"constant.language.escape",regex:b},{token:"string",regex:'"{3}',next:"start"},{defaultToken:"string"}],qstring3:[{token:"constant.language.escape",regex:b},{token:"string",regex:"'{3}",next:"start"},{defaultToken:"string"}],qqstring:[{token:"constant.language.escape",regex:b},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"start"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:b},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"start"},{defaultToken:"string"}],rawqqstring3:[{token:"string",regex:'"{3}',next:"start"},{defaultToken:"string"}],rawqstring3:[{token:"string",regex:"'{3}",next:"start"},{defaultToken:"string"}],rawqqstring:[{token:"string",regex:"\\\\$",next:"rawqqstring"},{token:"string",regex:'"|$',next:"start"},{defaultToken:"string"}],rawqstring:[{token:"string",regex:"\\\\$",next:"rawqstring"},{token:"string",regex:"'|$",next:"start"},{defaultToken:"string"}],fqqstring3:[{token:"constant.language.escape",regex:b},{token:"string",regex:'"{3}',next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],fqstring3:[{token:"constant.language.escape",regex:b},{token:"string",regex:"'{3}",next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],fqqstring:[{token:"constant.language.escape",regex:b},{token:"string",regex:"\\\\$",next:"fqqstring"},{token:"string",regex:'"|$',next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],fqstring:[{token:"constant.language.escape",regex:b},{token:"string",regex:"'|$",next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],rfqqstring3:[{token:"string",regex:'"{3}',next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],rfqstring3:[{token:"string",regex:"'{3}",next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],rfqqstring:[{token:"string",regex:"\\\\$",next:"rfqqstring"},{token:"string",regex:'"|$',next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],rfqstring:[{token:"string",regex:"'|$",next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],fqstringParRules:[{token:"paren.lparen",regex:"[\\[\\(]"},{token:"paren.rparen",regex:"[\\]\\)]"},{token:"string",regex:"\\s+"},{token:"string",regex:"'(.)*'"},{token:"string",regex:'"(.)*"'},{token:"function.support",regex:"(!s|!r|!a)"},{include:"constants"},{token:"paren.rparen",regex:"}",next:"pop"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"}],constants:[{token:"constant.numeric",regex:"(?:"+y+"|\\d+)[jJ]\\b"},{token:"constant.numeric",regex:y},{token:"constant.numeric",regex:h+"[lL]\\b"},{token:"constant.numeric",regex:h+"\\b"},{token:["punctuation","function.support"],regex:"(\\.)([a-zA-Z_]+)\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"}]},this.normalizeRules()};r.inherits(s,i),t.PythonHighlightRules=s}),ace.define("ace/mode/folding/pythonic",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e){this.foldingStartMarker=new RegExp("([\\[{])(?:\\s*)$|("+e+")(?:\\s*)(?:#.*)?$")};r.inherits(s,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=e.getLine(n),i=r.match(this.foldingStartMarker);if(i)return i[1]?this.openingBracketBlock(e,i[1],n,i.index):i[2]?this.indentationBlock(e,n,i.index+i[2].length):this.indentationBlock(e,n)}}.call(s.prototype)}),ace.define("ace/mode/python",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/python_highlight_rules","ace/mode/folding/pythonic","ace/range"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./python_highlight_rules").PythonHighlightRules,o=e("./folding/pythonic").FoldMode,u=e("../range").Range,a=function(){this.HighlightRules=s,this.foldingRules=new o("\\:"),this.$behaviour=this.$defaultBehaviour};r.inherits(a,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[:]\s*$/);o&&(r+=n)}return r};var e={pass:1,"return":1,raise:1,"break":1,"continue":1};this.checkOutdent=function(t,n,r){if(r!=="\r\n"&&r!=="\r"&&r!=="\n")return!1;var i=this.getTokenizer().getLineTokens(n.trim(),t).tokens;if(!i)return!1;do var s=i.pop();while(s&&(s.type=="comment"||s.type=="text"&&s.value.match(/^\s+$/)));return s?s.type=="keyword"&&e[s.value]:!1},this.autoOutdent=function(e,t,n){n+=1;var r=this.$getIndent(t.getLine(n)),i=t.getTabString();r.slice(-i.length)==i&&t.remove(new u(n,r.length-i.length,n,r.length))},this.$id="ace/mode/python"}.call(a.prototype),t.Mode=a}); (function() { + ace.require(["ace/mode/python"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-sql.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-sql.js new file mode 100644 index 0000000..413eccd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-sql.js @@ -0,0 +1,8 @@ +ace.define("ace/mode/sql_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="select|insert|update|delete|from|where|and|or|group|by|order|limit|offset|having|as|case|when|then|else|end|type|left|right|join|on|outer|desc|asc|union|create|table|primary|key|if|foreign|not|references|default|null|inner|cross|natural|database|drop|grant",t="true|false",n="avg|count|first|last|max|min|sum|ucase|lcase|mid|len|round|rank|now|format|coalesce|ifnull|isnull|nvl",r="int|numeric|decimal|date|varchar|char|bigint|float|double|bit|binary|text|set|timestamp|money|real|number|integer",i=this.createKeywordMapper({"support.function":n,keyword:e,"constant.language":t,"storage.type":r},"identifier",!0);this.$rules={start:[{token:"comment",regex:"--.*$"},{token:"comment",start:"/\\*",end:"\\*/"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"string",regex:"`.*?`"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:i,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\(]"},{token:"paren.rparen",regex:"[\\)]"},{token:"text",regex:"\\s+"}]},this.normalizeRules()};r.inherits(s,i),t.SqlHighlightRules=s}),ace.define("ace/mode/sql",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/sql_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./sql_highlight_rules").SqlHighlightRules,o=function(){this.HighlightRules=s,this.$behaviour=this.$defaultBehaviour};r.inherits(o,i),function(){this.lineCommentStart="--",this.$id="ace/mode/sql"}.call(o.prototype),t.Mode=o}); (function() { + ace.require(["ace/mode/sql"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-swift.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-swift.js new file mode 100644 index 0000000..fdb32dc --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-swift.js @@ -0,0 +1,8 @@ +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},s.getTagRule(),{defaultToken:"comment.doc",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/swift_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./doc_comment_highlight_rules").DocCommentHighlightRules,o=e("./text_highlight_rules").TextHighlightRules,u=function(){function t(e,t){var n=t.nestable||t.interpolation,r=t.interpolation&&t.interpolation.nextState||"start",s={regex:e+(t.multiline?"":"(?=.)"),token:"string.start"},o=[t.escape&&{regex:t.escape,token:"character.escape"},t.interpolation&&{token:"paren.quasi.start",regex:i.escapeRegExp(t.interpolation.lead+t.interpolation.open),push:r},t.error&&{regex:t.error,token:"error.invalid"},{regex:e+(t.multiline?"":"|$"),token:"string.end",next:n?"pop":"start"},{defaultToken:"string"}].filter(Boolean);n?s.push=o:s.next=o;if(!t.interpolation)return s;var u=t.interpolation.open,a=t.interpolation.close,f={regex:"["+i.escapeRegExp(u+a)+"]",onMatch:function(e,t,n){this.next=e==u?this.nextState:"";if(e==u&&n.length)return n.unshift("start",t),"paren";if(e==a&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1)return"paren.quasi.end"}return e==u?"paren.lparen":"paren.rparen"},nextState:r};return[f,s]}function n(){return[{token:"comment",regex:"\\/\\/(?=.)",next:[s.getTagRule(),{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment",caseInsensitive:!0}]},s.getStartRule("doc-start"),{token:"comment.start",regex:/\/\*/,stateName:"nested_comment",push:[s.getTagRule(),{token:"comment.start",regex:/\/\*/,push:"nested_comment"},{token:"comment.end",regex:"\\*\\/",next:"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}var e=this.createKeywordMapper({"variable.language":"",keyword:"__COLUMN__|__FILE__|__FUNCTION__|__LINE__|as|associativity|break|case|class|continue|default|deinit|didSet|do|dynamicType|else|enum|extension|fallthrough|for|func|get|if|import|in|infix|init|inout|is|left|let|let|mutating|new|none|nonmutating|operator|override|postfix|precedence|prefix|protocol|return|right|safe|Self|self|set|struct|subscript|switch|Type|typealias|unowned|unsafe|var|weak|where|while|willSet|convenience|dynamic|final|infix|lazy|mutating|nonmutating|optional|override|postfix|prefix|required|static|guard|defer","storage.type":"bool|double|Double|extension|float|Float|int|Int|open|internal|fileprivate|private|public|string|String","constant.language":"false|Infinity|NaN|nil|no|null|null|off|on|super|this|true|undefined|yes","support.function":""},"identifier");this.$rules={start:[t('"',{escape:/\\(?:[0\\tnr"']|u{[a-fA-F1-9]{0,8}})/,interpolation:{lead:"\\",open:"(",close:")"},error:/\\./,multiline:!1}),n(),{regex:/@[a-zA-Z_$][a-zA-Z_$\d\u0080-\ufffe]*/,token:"variable.parameter"},{regex:/[a-zA-Z_$][a-zA-Z_$\d\u0080-\ufffe]*/,token:e},{token:"constant.numeric",regex:/[+-]?(?:0(?:b[01]+|o[0-7]+|x[\da-fA-F])|\d+(?:(?:\.\d*)?(?:[PpEe][+-]?\d+)?)\b)/},{token:"keyword.operator",regex:/--|\+\+|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/}]},this.embedRules(s,"doc-",[s.getEndRule("start")]),this.normalizeRules()};r.inherits(u,o),t.HighlightRules=u}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++n<s){t=e.getLine(n);var f=u.exec(t);if(!f)continue;f[1]?a--:a++;if(!a)break}var l=n;if(l>o)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/swift",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/swift_highlight_rules","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./swift_highlight_rules").HighlightRules,o=e("./behaviour/cstyle").CstyleBehaviour,u=e("./folding/cstyle").FoldMode,a=function(){this.HighlightRules=s,this.foldingRules=new u,this.$behaviour=new o,this.$behaviour=this.$defaultBehaviour};r.inherits(a,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/",nestable:!0},this.$id="ace/mode/swift"}.call(a.prototype),t.Mode=a}); (function() { + ace.require(["ace/mode/swift"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-text.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-text.js new file mode 100644 index 0000000..ac9e09f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-text.js @@ -0,0 +1,8 @@ +; (function() { + ace.require(["ace/mode/text"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-xml.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-xml.js new file mode 100644 index 0000000..709c38b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-xml.js @@ -0,0 +1,8 @@ +ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){var t="[_:a-zA-Z\u00c0-\uffff][-_:.a-zA-Z0-9\u00c0-\uffff]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.start.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],processing_instruction:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:t},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.end.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:"+t+":)?"+t+")",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:t},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";function u(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),a=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var o=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:o+a+o,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==o&&(u(p,"attribute-value")||u(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(u(p,"tag-whitespace")||u(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(u(p,"attribute-equals")&&(d||c==">")||u(p,"decl-attribute-equals")&&(d||c=="?"))return{text:o+o,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var o=n.getSelectionRange().start,a=new s(r,o.row,o.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(u(f,"tag-name")||u(f,"tag-whitespace")||u(f,"attribute-name")||u(f,"attribute-equals")||u(f,"attribute-value")))return;if(u(f,"reference.attribute-value"))return;if(u(f,"attribute-value")){var l=a.getCurrentTokenColumn()+f.value.length;if(o.column<l)return;if(o.column==l){var c=a.stepForward();if(c&&u(c,"attribute-value"))return;a.stepBackward()}}if(/^\s*>/.test(r.getLine(o.row).slice(o.column)))return;while(!u(f,"tag-name")){f=a.stepBackward();if(f.value=="<"){f=a.stepForward();break}}var h=a.getCurrentTokenRow(),p=a.getCurrentTokenColumn();if(u(a.stepBackward(),"end-tag-open"))return;var d=f.value;h==o.row&&(d=d.substring(0,o.column-p));if(this.voidElements.hasOwnProperty(d.toLowerCase()))return;return{text:"></"+d+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var o=n.getCursorPosition(),u=r.getLine(o.row),a=new s(r,o.row,o.column),f=a.getCurrentToken();if(f&&f.type.indexOf("tag-close")!==-1){if(f.value=="/>")return;while(f&&f.type.indexOf("tag-name")===-1)f=a.stepBackward();if(!f)return;var l=f.value,c=a.getCurrentTokenRow();f=a.stepBackward();if(!f||f.type.indexOf("end-tag")!==-1)return;if(this.voidElements&&!this.voidElements[l]){var h=r.getTokenAt(o.row,o.column+1),u=r.getLine(c),p=this.$getIndent(u),d=p+r.getTabString();return h&&h.value==="</"?{text:"\n"+d+"\n"+p,selection:[1,d.length,1,d.length]}:{text:"\n"+d}}}}})};r.inherits(a,i),t.XmlBehaviour=a}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/<!-/.test(e.getLine(t))?"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.optionalEndTags.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return this.getCommentFoldWidget(e,n)&&e.getCommentFoldRange(n,e.getLine(n).length);var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};r.start.row==r.end.row&&(l.column=r.end.column);while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,a.start.row==a.end.row&&a.start.column<a.end.column&&(a.start.column=a.end.column),s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/xml_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/xml","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./xml_highlight_rules").XmlHighlightRules,u=e("./behaviour/xml").XmlBehaviour,a=e("./folding/xml").FoldMode,f=e("../worker/worker_client").WorkerClient,l=function(){this.HighlightRules=o,this.$behaviour=new u,this.foldingRules=new a};r.inherits(l,s),function(){this.voidElements=i.arrayToMap([]),this.blockComment={start:"<!--",end:"-->"},this.createWorker=function(e){var t=new f(["ace"],"ace/mode/xml_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/xml"}.call(l.prototype),t.Mode=l}); (function() { + ace.require(["ace/mode/xml"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-yaml.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-yaml.js new file mode 100644 index 0000000..e64c0bb --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/mode-yaml.js @@ -0,0 +1,8 @@ +ace.define("ace/mode/yaml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"list.markup",regex:/^(?:-{3}|\.{3})\s*(?=#|$)/},{token:"list.markup",regex:/^\s*[\-?](?:$|\s)/},{token:"constant",regex:"!![\\w//]+"},{token:"constant.language",regex:"[&\\*][a-zA-Z0-9-_]+"},{token:["meta.tag","keyword"],regex:/^(\s*\w.*?)(:(?=\s|$))/},{token:["meta.tag","keyword"],regex:/(\w+?)(\s*:(?=\s|$))/},{token:"keyword.operator",regex:"<<\\w*:\\w*"},{token:"keyword.operator",regex:"-\\s*(?=[{])"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:/[|>][-+\d\s]*$/,onMatch:function(e,t,n,r){var i=/^\s*/.exec(r)[0];return n.length<1?n.push(this.next):n[0]="mlString",n.length<2?n.push(i.length):n[1]=i.length,this.token},next:"mlString"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:/(\b|[+\-\.])[\d_]+(?:(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)(?=[^\d-\w]|$)/},{token:"constant.numeric",regex:/[+\-]?\.inf\b|NaN\b|0x[\dA-Fa-f_]+|0b[10_]+/},{token:"constant.language.boolean",regex:"\\b(?:true|false|TRUE|FALSE|True|False|yes|no)\\b"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:/[^\s,:\[\]\{\}]+/}],mlString:[{token:"indent",regex:/^\s*$/},{token:"indent",regex:/^\s*/,onMatch:function(e,t,n){var r=n[1];return r>=e.length?(this.next="start",n.splice(0)):this.next="mlString",this.token},next:"mlString"},{token:"string",regex:".+"}]},this.normalizeRules()};r.inherits(s,i),t.YamlHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/yaml",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/yaml_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./yaml_highlight_rules").YamlHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./folding/coffee").FoldMode,a=function(){this.HighlightRules=s,this.$outdent=new o,this.foldingRules=new u,this.$behaviour=this.$defaultBehaviour};r.inherits(a,i),function(){this.lineCommentStart=["#"],this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t);if(e=="start"){var i=t.match(/^.*[\{\(\[]\s*$/);i&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/yaml"}.call(a.prototype),t.Mode=a}); (function() { + ace.require(["ace/mode/yaml"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/css.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/css.js new file mode 100644 index 0000000..68d6ea2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/css.js @@ -0,0 +1,8 @@ +ace.define("ace/snippets/css",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="snippet .\n ${1} {\n ${2}\n }\nsnippet !\n !important\nsnippet bdi:m+\n -moz-border-image: url(${1}) ${2:0} ${3:0} ${4:0} ${5:0} ${6:stretch} ${7:stretch};\nsnippet bdi:m\n -moz-border-image: ${1};\nsnippet bdrz:m\n -moz-border-radius: ${1};\nsnippet bxsh:m+\n -moz-box-shadow: ${1:0} ${2:0} ${3:0} #${4:000};\nsnippet bxsh:m\n -moz-box-shadow: ${1};\nsnippet bdi:w+\n -webkit-border-image: url(${1}) ${2:0} ${3:0} ${4:0} ${5:0} ${6:stretch} ${7:stretch};\nsnippet bdi:w\n -webkit-border-image: ${1};\nsnippet bdrz:w\n -webkit-border-radius: ${1};\nsnippet bxsh:w+\n -webkit-box-shadow: ${1:0} ${2:0} ${3:0} #${4:000};\nsnippet bxsh:w\n -webkit-box-shadow: ${1};\nsnippet @f\n @font-face {\n font-family: ${1};\n src: url(${2});\n }\nsnippet @i\n @import url(${1});\nsnippet @m\n @media ${1:print} {\n ${2}\n }\nsnippet bg+\n background: #${1:FFF} url(${2}) ${3:0} ${4:0} ${5:no-repeat};\nsnippet bga\n background-attachment: ${1};\nsnippet bga:f\n background-attachment: fixed;\nsnippet bga:s\n background-attachment: scroll;\nsnippet bgbk\n background-break: ${1};\nsnippet bgbk:bb\n background-break: bounding-box;\nsnippet bgbk:c\n background-break: continuous;\nsnippet bgbk:eb\n background-break: each-box;\nsnippet bgcp\n background-clip: ${1};\nsnippet bgcp:bb\n background-clip: border-box;\nsnippet bgcp:cb\n background-clip: content-box;\nsnippet bgcp:nc\n background-clip: no-clip;\nsnippet bgcp:pb\n background-clip: padding-box;\nsnippet bgc\n background-color: #${1:FFF};\nsnippet bgc:t\n background-color: transparent;\nsnippet bgi\n background-image: url(${1});\nsnippet bgi:n\n background-image: none;\nsnippet bgo\n background-origin: ${1};\nsnippet bgo:bb\n background-origin: border-box;\nsnippet bgo:cb\n background-origin: content-box;\nsnippet bgo:pb\n background-origin: padding-box;\nsnippet bgpx\n background-position-x: ${1};\nsnippet bgpy\n background-position-y: ${1};\nsnippet bgp\n background-position: ${1:0} ${2:0};\nsnippet bgr\n background-repeat: ${1};\nsnippet bgr:n\n background-repeat: no-repeat;\nsnippet bgr:x\n background-repeat: repeat-x;\nsnippet bgr:y\n background-repeat: repeat-y;\nsnippet bgr:r\n background-repeat: repeat;\nsnippet bgz\n background-size: ${1};\nsnippet bgz:a\n background-size: auto;\nsnippet bgz:ct\n background-size: contain;\nsnippet bgz:cv\n background-size: cover;\nsnippet bg\n background: ${1};\nsnippet bg:ie\n filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='${1}',sizingMethod='${2:crop}');\nsnippet bg:n\n background: none;\nsnippet bd+\n border: ${1:1px} ${2:solid} #${3:000};\nsnippet bdb+\n border-bottom: ${1:1px} ${2:solid} #${3:000};\nsnippet bdbc\n border-bottom-color: #${1:000};\nsnippet bdbi\n border-bottom-image: url(${1});\nsnippet bdbi:n\n border-bottom-image: none;\nsnippet bdbli\n border-bottom-left-image: url(${1});\nsnippet bdbli:c\n border-bottom-left-image: continue;\nsnippet bdbli:n\n border-bottom-left-image: none;\nsnippet bdblrz\n border-bottom-left-radius: ${1};\nsnippet bdbri\n border-bottom-right-image: url(${1});\nsnippet bdbri:c\n border-bottom-right-image: continue;\nsnippet bdbri:n\n border-bottom-right-image: none;\nsnippet bdbrrz\n border-bottom-right-radius: ${1};\nsnippet bdbs\n border-bottom-style: ${1};\nsnippet bdbs:n\n border-bottom-style: none;\nsnippet bdbw\n border-bottom-width: ${1};\nsnippet bdb\n border-bottom: ${1};\nsnippet bdb:n\n border-bottom: none;\nsnippet bdbk\n border-break: ${1};\nsnippet bdbk:c\n border-break: close;\nsnippet bdcl\n border-collapse: ${1};\nsnippet bdcl:c\n border-collapse: collapse;\nsnippet bdcl:s\n border-collapse: separate;\nsnippet bdc\n border-color: #${1:000};\nsnippet bdci\n border-corner-image: url(${1});\nsnippet bdci:c\n border-corner-image: continue;\nsnippet bdci:n\n border-corner-image: none;\nsnippet bdf\n border-fit: ${1};\nsnippet bdf:c\n border-fit: clip;\nsnippet bdf:of\n border-fit: overwrite;\nsnippet bdf:ow\n border-fit: overwrite;\nsnippet bdf:r\n border-fit: repeat;\nsnippet bdf:sc\n border-fit: scale;\nsnippet bdf:sp\n border-fit: space;\nsnippet bdf:st\n border-fit: stretch;\nsnippet bdi\n border-image: url(${1}) ${2:0} ${3:0} ${4:0} ${5:0} ${6:stretch} ${7:stretch};\nsnippet bdi:n\n border-image: none;\nsnippet bdl+\n border-left: ${1:1px} ${2:solid} #${3:000};\nsnippet bdlc\n border-left-color: #${1:000};\nsnippet bdli\n border-left-image: url(${1});\nsnippet bdli:n\n border-left-image: none;\nsnippet bdls\n border-left-style: ${1};\nsnippet bdls:n\n border-left-style: none;\nsnippet bdlw\n border-left-width: ${1};\nsnippet bdl\n border-left: ${1};\nsnippet bdl:n\n border-left: none;\nsnippet bdlt\n border-length: ${1};\nsnippet bdlt:a\n border-length: auto;\nsnippet bdrz\n border-radius: ${1};\nsnippet bdr+\n border-right: ${1:1px} ${2:solid} #${3:000};\nsnippet bdrc\n border-right-color: #${1:000};\nsnippet bdri\n border-right-image: url(${1});\nsnippet bdri:n\n border-right-image: none;\nsnippet bdrs\n border-right-style: ${1};\nsnippet bdrs:n\n border-right-style: none;\nsnippet bdrw\n border-right-width: ${1};\nsnippet bdr\n border-right: ${1};\nsnippet bdr:n\n border-right: none;\nsnippet bdsp\n border-spacing: ${1};\nsnippet bds\n border-style: ${1};\nsnippet bds:ds\n border-style: dashed;\nsnippet bds:dtds\n border-style: dot-dash;\nsnippet bds:dtdtds\n border-style: dot-dot-dash;\nsnippet bds:dt\n border-style: dotted;\nsnippet bds:db\n border-style: double;\nsnippet bds:g\n border-style: groove;\nsnippet bds:h\n border-style: hidden;\nsnippet bds:i\n border-style: inset;\nsnippet bds:n\n border-style: none;\nsnippet bds:o\n border-style: outset;\nsnippet bds:r\n border-style: ridge;\nsnippet bds:s\n border-style: solid;\nsnippet bds:w\n border-style: wave;\nsnippet bdt+\n border-top: ${1:1px} ${2:solid} #${3:000};\nsnippet bdtc\n border-top-color: #${1:000};\nsnippet bdti\n border-top-image: url(${1});\nsnippet bdti:n\n border-top-image: none;\nsnippet bdtli\n border-top-left-image: url(${1});\nsnippet bdtli:c\n border-corner-image: continue;\nsnippet bdtli:n\n border-corner-image: none;\nsnippet bdtlrz\n border-top-left-radius: ${1};\nsnippet bdtri\n border-top-right-image: url(${1});\nsnippet bdtri:c\n border-top-right-image: continue;\nsnippet bdtri:n\n border-top-right-image: none;\nsnippet bdtrrz\n border-top-right-radius: ${1};\nsnippet bdts\n border-top-style: ${1};\nsnippet bdts:n\n border-top-style: none;\nsnippet bdtw\n border-top-width: ${1};\nsnippet bdt\n border-top: ${1};\nsnippet bdt:n\n border-top: none;\nsnippet bdw\n border-width: ${1};\nsnippet bd\n border: ${1};\nsnippet bd:n\n border: none;\nsnippet b\n bottom: ${1};\nsnippet b:a\n bottom: auto;\nsnippet bxsh+\n box-shadow: ${1:0} ${2:0} ${3:0} #${4:000};\nsnippet bxsh\n box-shadow: ${1};\nsnippet bxsh:n\n box-shadow: none;\nsnippet bxz\n box-sizing: ${1};\nsnippet bxz:bb\n box-sizing: border-box;\nsnippet bxz:cb\n box-sizing: content-box;\nsnippet cps\n caption-side: ${1};\nsnippet cps:b\n caption-side: bottom;\nsnippet cps:t\n caption-side: top;\nsnippet cl\n clear: ${1};\nsnippet cl:b\n clear: both;\nsnippet cl:l\n clear: left;\nsnippet cl:n\n clear: none;\nsnippet cl:r\n clear: right;\nsnippet cp\n clip: ${1};\nsnippet cp:a\n clip: auto;\nsnippet cp:r\n clip: rect(${1:0} ${2:0} ${3:0} ${4:0});\nsnippet c\n color: #${1:000};\nsnippet ct\n content: ${1};\nsnippet ct:a\n content: attr(${1});\nsnippet ct:cq\n content: close-quote;\nsnippet ct:c\n content: counter(${1});\nsnippet ct:cs\n content: counters(${1});\nsnippet ct:ncq\n content: no-close-quote;\nsnippet ct:noq\n content: no-open-quote;\nsnippet ct:n\n content: normal;\nsnippet ct:oq\n content: open-quote;\nsnippet coi\n counter-increment: ${1};\nsnippet cor\n counter-reset: ${1};\nsnippet cur\n cursor: ${1};\nsnippet cur:a\n cursor: auto;\nsnippet cur:c\n cursor: crosshair;\nsnippet cur:d\n cursor: default;\nsnippet cur:ha\n cursor: hand;\nsnippet cur:he\n cursor: help;\nsnippet cur:m\n cursor: move;\nsnippet cur:p\n cursor: pointer;\nsnippet cur:t\n cursor: text;\nsnippet d\n display: ${1};\nsnippet d:mib\n display: -moz-inline-box;\nsnippet d:mis\n display: -moz-inline-stack;\nsnippet d:b\n display: block;\nsnippet d:cp\n display: compact;\nsnippet d:ib\n display: inline-block;\nsnippet d:itb\n display: inline-table;\nsnippet d:i\n display: inline;\nsnippet d:li\n display: list-item;\nsnippet d:n\n display: none;\nsnippet d:ri\n display: run-in;\nsnippet d:tbcp\n display: table-caption;\nsnippet d:tbc\n display: table-cell;\nsnippet d:tbclg\n display: table-column-group;\nsnippet d:tbcl\n display: table-column;\nsnippet d:tbfg\n display: table-footer-group;\nsnippet d:tbhg\n display: table-header-group;\nsnippet d:tbrg\n display: table-row-group;\nsnippet d:tbr\n display: table-row;\nsnippet d:tb\n display: table;\nsnippet ec\n empty-cells: ${1};\nsnippet ec:h\n empty-cells: hide;\nsnippet ec:s\n empty-cells: show;\nsnippet exp\n expression()\nsnippet fl\n float: ${1};\nsnippet fl:l\n float: left;\nsnippet fl:n\n float: none;\nsnippet fl:r\n float: right;\nsnippet f+\n font: ${1:1em} ${2:Arial},${3:sans-serif};\nsnippet fef\n font-effect: ${1};\nsnippet fef:eb\n font-effect: emboss;\nsnippet fef:eg\n font-effect: engrave;\nsnippet fef:n\n font-effect: none;\nsnippet fef:o\n font-effect: outline;\nsnippet femp\n font-emphasize-position: ${1};\nsnippet femp:a\n font-emphasize-position: after;\nsnippet femp:b\n font-emphasize-position: before;\nsnippet fems\n font-emphasize-style: ${1};\nsnippet fems:ac\n font-emphasize-style: accent;\nsnippet fems:c\n font-emphasize-style: circle;\nsnippet fems:ds\n font-emphasize-style: disc;\nsnippet fems:dt\n font-emphasize-style: dot;\nsnippet fems:n\n font-emphasize-style: none;\nsnippet fem\n font-emphasize: ${1};\nsnippet ff\n font-family: ${1};\nsnippet ff:c\n font-family: ${1:'Monotype Corsiva','Comic Sans MS'},cursive;\nsnippet ff:f\n font-family: ${1:Capitals,Impact},fantasy;\nsnippet ff:m\n font-family: ${1:Monaco,'Courier New'},monospace;\nsnippet ff:ss\n font-family: ${1:Helvetica,Arial},sans-serif;\nsnippet ff:s\n font-family: ${1:Georgia,'Times New Roman'},serif;\nsnippet fza\n font-size-adjust: ${1};\nsnippet fza:n\n font-size-adjust: none;\nsnippet fz\n font-size: ${1};\nsnippet fsm\n font-smooth: ${1};\nsnippet fsm:aw\n font-smooth: always;\nsnippet fsm:a\n font-smooth: auto;\nsnippet fsm:n\n font-smooth: never;\nsnippet fst\n font-stretch: ${1};\nsnippet fst:c\n font-stretch: condensed;\nsnippet fst:e\n font-stretch: expanded;\nsnippet fst:ec\n font-stretch: extra-condensed;\nsnippet fst:ee\n font-stretch: extra-expanded;\nsnippet fst:n\n font-stretch: normal;\nsnippet fst:sc\n font-stretch: semi-condensed;\nsnippet fst:se\n font-stretch: semi-expanded;\nsnippet fst:uc\n font-stretch: ultra-condensed;\nsnippet fst:ue\n font-stretch: ultra-expanded;\nsnippet fs\n font-style: ${1};\nsnippet fs:i\n font-style: italic;\nsnippet fs:n\n font-style: normal;\nsnippet fs:o\n font-style: oblique;\nsnippet fv\n font-variant: ${1};\nsnippet fv:n\n font-variant: normal;\nsnippet fv:sc\n font-variant: small-caps;\nsnippet fw\n font-weight: ${1};\nsnippet fw:b\n font-weight: bold;\nsnippet fw:br\n font-weight: bolder;\nsnippet fw:lr\n font-weight: lighter;\nsnippet fw:n\n font-weight: normal;\nsnippet f\n font: ${1};\nsnippet h\n height: ${1};\nsnippet h:a\n height: auto;\nsnippet l\n left: ${1};\nsnippet l:a\n left: auto;\nsnippet lts\n letter-spacing: ${1};\nsnippet lh\n line-height: ${1};\nsnippet lisi\n list-style-image: url(${1});\nsnippet lisi:n\n list-style-image: none;\nsnippet lisp\n list-style-position: ${1};\nsnippet lisp:i\n list-style-position: inside;\nsnippet lisp:o\n list-style-position: outside;\nsnippet list\n list-style-type: ${1};\nsnippet list:c\n list-style-type: circle;\nsnippet list:dclz\n list-style-type: decimal-leading-zero;\nsnippet list:dc\n list-style-type: decimal;\nsnippet list:d\n list-style-type: disc;\nsnippet list:lr\n list-style-type: lower-roman;\nsnippet list:n\n list-style-type: none;\nsnippet list:s\n list-style-type: square;\nsnippet list:ur\n list-style-type: upper-roman;\nsnippet lis\n list-style: ${1};\nsnippet lis:n\n list-style: none;\nsnippet mb\n margin-bottom: ${1};\nsnippet mb:a\n margin-bottom: auto;\nsnippet ml\n margin-left: ${1};\nsnippet ml:a\n margin-left: auto;\nsnippet mr\n margin-right: ${1};\nsnippet mr:a\n margin-right: auto;\nsnippet mt\n margin-top: ${1};\nsnippet mt:a\n margin-top: auto;\nsnippet m\n margin: ${1};\nsnippet m:4\n margin: ${1:0} ${2:0} ${3:0} ${4:0};\nsnippet m:3\n margin: ${1:0} ${2:0} ${3:0};\nsnippet m:2\n margin: ${1:0} ${2:0};\nsnippet m:0\n margin: 0;\nsnippet m:a\n margin: auto;\nsnippet mah\n max-height: ${1};\nsnippet mah:n\n max-height: none;\nsnippet maw\n max-width: ${1};\nsnippet maw:n\n max-width: none;\nsnippet mih\n min-height: ${1};\nsnippet miw\n min-width: ${1};\nsnippet op\n opacity: ${1};\nsnippet op:ie\n filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=${1:100});\nsnippet op:ms\n -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=${1:100})';\nsnippet orp\n orphans: ${1};\nsnippet o+\n outline: ${1:1px} ${2:solid} #${3:000};\nsnippet oc\n outline-color: ${1:#000};\nsnippet oc:i\n outline-color: invert;\nsnippet oo\n outline-offset: ${1};\nsnippet os\n outline-style: ${1};\nsnippet ow\n outline-width: ${1};\nsnippet o\n outline: ${1};\nsnippet o:n\n outline: none;\nsnippet ovs\n overflow-style: ${1};\nsnippet ovs:a\n overflow-style: auto;\nsnippet ovs:mq\n overflow-style: marquee;\nsnippet ovs:mv\n overflow-style: move;\nsnippet ovs:p\n overflow-style: panner;\nsnippet ovs:s\n overflow-style: scrollbar;\nsnippet ovx\n overflow-x: ${1};\nsnippet ovx:a\n overflow-x: auto;\nsnippet ovx:h\n overflow-x: hidden;\nsnippet ovx:s\n overflow-x: scroll;\nsnippet ovx:v\n overflow-x: visible;\nsnippet ovy\n overflow-y: ${1};\nsnippet ovy:a\n overflow-y: auto;\nsnippet ovy:h\n overflow-y: hidden;\nsnippet ovy:s\n overflow-y: scroll;\nsnippet ovy:v\n overflow-y: visible;\nsnippet ov\n overflow: ${1};\nsnippet ov:a\n overflow: auto;\nsnippet ov:h\n overflow: hidden;\nsnippet ov:s\n overflow: scroll;\nsnippet ov:v\n overflow: visible;\nsnippet pb\n padding-bottom: ${1};\nsnippet pl\n padding-left: ${1};\nsnippet pr\n padding-right: ${1};\nsnippet pt\n padding-top: ${1};\nsnippet p\n padding: ${1};\nsnippet p:4\n padding: ${1:0} ${2:0} ${3:0} ${4:0};\nsnippet p:3\n padding: ${1:0} ${2:0} ${3:0};\nsnippet p:2\n padding: ${1:0} ${2:0};\nsnippet p:0\n padding: 0;\nsnippet pgba\n page-break-after: ${1};\nsnippet pgba:aw\n page-break-after: always;\nsnippet pgba:a\n page-break-after: auto;\nsnippet pgba:l\n page-break-after: left;\nsnippet pgba:r\n page-break-after: right;\nsnippet pgbb\n page-break-before: ${1};\nsnippet pgbb:aw\n page-break-before: always;\nsnippet pgbb:a\n page-break-before: auto;\nsnippet pgbb:l\n page-break-before: left;\nsnippet pgbb:r\n page-break-before: right;\nsnippet pgbi\n page-break-inside: ${1};\nsnippet pgbi:a\n page-break-inside: auto;\nsnippet pgbi:av\n page-break-inside: avoid;\nsnippet pos\n position: ${1};\nsnippet pos:a\n position: absolute;\nsnippet pos:f\n position: fixed;\nsnippet pos:r\n position: relative;\nsnippet pos:s\n position: static;\nsnippet q\n quotes: ${1};\nsnippet q:en\n quotes: '\\201C' '\\201D' '\\2018' '\\2019';\nsnippet q:n\n quotes: none;\nsnippet q:ru\n quotes: '\\00AB' '\\00BB' '\\201E' '\\201C';\nsnippet rz\n resize: ${1};\nsnippet rz:b\n resize: both;\nsnippet rz:h\n resize: horizontal;\nsnippet rz:n\n resize: none;\nsnippet rz:v\n resize: vertical;\nsnippet r\n right: ${1};\nsnippet r:a\n right: auto;\nsnippet tbl\n table-layout: ${1};\nsnippet tbl:a\n table-layout: auto;\nsnippet tbl:f\n table-layout: fixed;\nsnippet tal\n text-align-last: ${1};\nsnippet tal:a\n text-align-last: auto;\nsnippet tal:c\n text-align-last: center;\nsnippet tal:l\n text-align-last: left;\nsnippet tal:r\n text-align-last: right;\nsnippet ta\n text-align: ${1};\nsnippet ta:c\n text-align: center;\nsnippet ta:l\n text-align: left;\nsnippet ta:r\n text-align: right;\nsnippet td\n text-decoration: ${1};\nsnippet td:l\n text-decoration: line-through;\nsnippet td:n\n text-decoration: none;\nsnippet td:o\n text-decoration: overline;\nsnippet td:u\n text-decoration: underline;\nsnippet te\n text-emphasis: ${1};\nsnippet te:ac\n text-emphasis: accent;\nsnippet te:a\n text-emphasis: after;\nsnippet te:b\n text-emphasis: before;\nsnippet te:c\n text-emphasis: circle;\nsnippet te:ds\n text-emphasis: disc;\nsnippet te:dt\n text-emphasis: dot;\nsnippet te:n\n text-emphasis: none;\nsnippet th\n text-height: ${1};\nsnippet th:a\n text-height: auto;\nsnippet th:f\n text-height: font-size;\nsnippet th:m\n text-height: max-size;\nsnippet th:t\n text-height: text-size;\nsnippet ti\n text-indent: ${1};\nsnippet ti:-\n text-indent: -9999px;\nsnippet tj\n text-justify: ${1};\nsnippet tj:a\n text-justify: auto;\nsnippet tj:d\n text-justify: distribute;\nsnippet tj:ic\n text-justify: inter-cluster;\nsnippet tj:ii\n text-justify: inter-ideograph;\nsnippet tj:iw\n text-justify: inter-word;\nsnippet tj:k\n text-justify: kashida;\nsnippet tj:t\n text-justify: tibetan;\nsnippet to+\n text-outline: ${1:0} ${2:0} #${3:000};\nsnippet to\n text-outline: ${1};\nsnippet to:n\n text-outline: none;\nsnippet tr\n text-replace: ${1};\nsnippet tr:n\n text-replace: none;\nsnippet tsh+\n text-shadow: ${1:0} ${2:0} ${3:0} #${4:000};\nsnippet tsh\n text-shadow: ${1};\nsnippet tsh:n\n text-shadow: none;\nsnippet tt\n text-transform: ${1};\nsnippet tt:c\n text-transform: capitalize;\nsnippet tt:l\n text-transform: lowercase;\nsnippet tt:n\n text-transform: none;\nsnippet tt:u\n text-transform: uppercase;\nsnippet tw\n text-wrap: ${1};\nsnippet tw:no\n text-wrap: none;\nsnippet tw:n\n text-wrap: normal;\nsnippet tw:s\n text-wrap: suppress;\nsnippet tw:u\n text-wrap: unrestricted;\nsnippet t\n top: ${1};\nsnippet t:a\n top: auto;\nsnippet va\n vertical-align: ${1};\nsnippet va:bl\n vertical-align: baseline;\nsnippet va:b\n vertical-align: bottom;\nsnippet va:m\n vertical-align: middle;\nsnippet va:sub\n vertical-align: sub;\nsnippet va:sup\n vertical-align: super;\nsnippet va:tb\n vertical-align: text-bottom;\nsnippet va:tt\n vertical-align: text-top;\nsnippet va:t\n vertical-align: top;\nsnippet v\n visibility: ${1};\nsnippet v:c\n visibility: collapse;\nsnippet v:h\n visibility: hidden;\nsnippet v:v\n visibility: visible;\nsnippet whsc\n white-space-collapse: ${1};\nsnippet whsc:ba\n white-space-collapse: break-all;\nsnippet whsc:bs\n white-space-collapse: break-strict;\nsnippet whsc:k\n white-space-collapse: keep-all;\nsnippet whsc:l\n white-space-collapse: loose;\nsnippet whsc:n\n white-space-collapse: normal;\nsnippet whs\n white-space: ${1};\nsnippet whs:n\n white-space: normal;\nsnippet whs:nw\n white-space: nowrap;\nsnippet whs:pl\n white-space: pre-line;\nsnippet whs:pw\n white-space: pre-wrap;\nsnippet whs:p\n white-space: pre;\nsnippet wid\n widows: ${1};\nsnippet w\n width: ${1};\nsnippet w:a\n width: auto;\nsnippet wob\n word-break: ${1};\nsnippet wob:ba\n word-break: break-all;\nsnippet wob:bs\n word-break: break-strict;\nsnippet wob:k\n word-break: keep-all;\nsnippet wob:l\n word-break: loose;\nsnippet wob:n\n word-break: normal;\nsnippet wos\n word-spacing: ${1};\nsnippet wow\n word-wrap: ${1};\nsnippet wow:no\n word-wrap: none;\nsnippet wow:n\n word-wrap: normal;\nsnippet wow:s\n word-wrap: suppress;\nsnippet wow:u\n word-wrap: unrestricted;\nsnippet z\n z-index: ${1};\nsnippet z:a\n z-index: auto;\nsnippet zoo\n zoom: 1;\n",t.scope="css"}); (function() { + ace.require(["ace/snippets/css"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/handlebars.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/handlebars.js new file mode 100644 index 0000000..14bc447 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/handlebars.js @@ -0,0 +1,8 @@ +ace.define("ace/snippets/handlebars",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="handlebars"}); (function() { + ace.require(["ace/snippets/handlebars"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/html.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/html.js new file mode 100644 index 0000000..54a01bc --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/html.js @@ -0,0 +1,8 @@ +ace.define("ace/snippets/html",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='# Some useful Unicode entities\n# Non-Breaking Space\nsnippet nbs\n &nbsp;\n# \u2190\nsnippet left\n &#x2190;\n# \u2192\nsnippet right\n &#x2192;\n# \u2191\nsnippet up\n &#x2191;\n# \u2193\nsnippet down\n &#x2193;\n# \u21a9\nsnippet return\n &#x21A9;\n# \u21e4\nsnippet backtab\n &#x21E4;\n# \u21e5\nsnippet tab\n &#x21E5;\n# \u21e7\nsnippet shift\n &#x21E7;\n# \u2303\nsnippet ctrl\n &#x2303;\n# \u2305\nsnippet enter\n &#x2305;\n# \u2318\nsnippet cmd\n &#x2318;\n# \u2325\nsnippet option\n &#x2325;\n# \u2326\nsnippet delete\n &#x2326;\n# \u232b\nsnippet backspace\n &#x232B;\n# \u238b\nsnippet esc\n &#x238B;\n# Generic Doctype\nsnippet doctype HTML 4.01 Strict\n <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"\n "http://www.w3.org/TR/html4/strict.dtd">\nsnippet doctype HTML 4.01 Transitional\n <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"\n "http://www.w3.org/TR/html4/loose.dtd">\nsnippet doctype HTML 5\n <!DOCTYPE HTML>\nsnippet doctype XHTML 1.0 Frameset\n <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\nsnippet doctype XHTML 1.0 Strict\n <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\nsnippet doctype XHTML 1.0 Transitional\n <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\n "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\nsnippet doctype XHTML 1.1\n <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\n "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n# HTML Doctype 4.01 Strict\nsnippet docts\n <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"\n "http://www.w3.org/TR/html4/strict.dtd">\n# HTML Doctype 4.01 Transitional\nsnippet doct\n <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"\n "http://www.w3.org/TR/html4/loose.dtd">\n# HTML Doctype 5\nsnippet doct5\n <!DOCTYPE html>\n# XHTML Doctype 1.0 Frameset\nsnippet docxf\n <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"\n "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">\n# XHTML Doctype 1.0 Strict\nsnippet docxs\n <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n# XHTML Doctype 1.0 Transitional\nsnippet docxt\n <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\n "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n# XHTML Doctype 1.1\nsnippet docx\n <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\n "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n# html5shiv\nsnippet html5shiv\n <!--[if lte IE 8]>\n <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"><\/script>\n <![endif]-->\nsnippet html5printshiv\n <!--[if lte IE 8]>\n <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"><\/script>\n <![endif]-->\n# Attributes\nsnippet attr\n ${1:attribute}="${2:property}"\nsnippet attr+\n ${1:attribute}="${2:property}" attr+${3}\nsnippet .\n class="${1}"${2}\nsnippet #\n id="${1}"${2}\nsnippet alt\n alt="${1}"${2}\nsnippet charset\n charset="${1:utf-8}"${2}\nsnippet data\n data-${1}="${2:$1}"${3}\nsnippet for\n for="${1}"${2}\nsnippet height\n height="${1}"${2}\nsnippet href\n href="${1:#}"${2}\nsnippet lang\n lang="${1:en}"${2}\nsnippet media\n media="${1}"${2}\nsnippet name\n name="${1}"${2}\nsnippet rel\n rel="${1}"${2}\nsnippet scope\n scope="${1:row}"${2}\nsnippet src\n src="${1}"${2}\nsnippet title=\n title="${1}"${2}\nsnippet type\n type="${1}"${2}\nsnippet value\n value="${1}"${2}\nsnippet width\n width="${1}"${2}\n# Elements\nsnippet a\n <a href="${1:#}">${2:$1}</a>\nsnippet a.\n <a class="${1}" href="${2:#}">${3:$1}</a>\nsnippet a#\n <a id="${1}" href="${2:#}">${3:$1}</a>\nsnippet a:ext\n <a href="http://${1:example.com}">${2:$1}</a>\nsnippet a:mail\n <a href="mailto:${1:joe@example.com}?subject=${2:feedback}">${3:email me}</a>\nsnippet abbr\n <abbr title="${1}">${2}</abbr>\nsnippet address\n <address>\n ${1}\n </address>\nsnippet area\n <area shape="${1:rect}" coords="${2}" href="${3}" alt="${4}" />\nsnippet area+\n <area shape="${1:rect}" coords="${2}" href="${3}" alt="${4}" />\n area+${5}\nsnippet area:c\n <area shape="circle" coords="${1}" href="${2}" alt="${3}" />\nsnippet area:d\n <area shape="default" coords="${1}" href="${2}" alt="${3}" />\nsnippet area:p\n <area shape="poly" coords="${1}" href="${2}" alt="${3}" />\nsnippet area:r\n <area shape="rect" coords="${1}" href="${2}" alt="${3}" />\nsnippet article\n <article>\n ${1}\n </article>\nsnippet article.\n <article class="${1}">\n ${2}\n </article>\nsnippet article#\n <article id="${1}">\n ${2}\n </article>\nsnippet aside\n <aside>\n ${1}\n </aside>\nsnippet aside.\n <aside class="${1}">\n ${2}\n </aside>\nsnippet aside#\n <aside id="${1}">\n ${2}\n </aside>\nsnippet audio\n <audio src="${1}>${2}</audio>\nsnippet b\n <b>${1}</b>\nsnippet base\n <base href="${1}" target="${2}" />\nsnippet bdi\n <bdi>${1}</bdo>\nsnippet bdo\n <bdo dir="${1}">${2}</bdo>\nsnippet bdo:l\n <bdo dir="ltr">${1}</bdo>\nsnippet bdo:r\n <bdo dir="rtl">${1}</bdo>\nsnippet blockquote\n <blockquote>\n ${1}\n </blockquote>\nsnippet body\n <body>\n ${1}\n </body>\nsnippet br\n <br />${1}\nsnippet button\n <button type="${1:submit}">${2}</button>\nsnippet button.\n <button class="${1:button}" type="${2:submit}">${3}</button>\nsnippet button#\n <button id="${1}" type="${2:submit}">${3}</button>\nsnippet button:s\n <button type="submit">${1}</button>\nsnippet button:r\n <button type="reset">${1}</button>\nsnippet canvas\n <canvas>\n ${1}\n </canvas>\nsnippet caption\n <caption>${1}</caption>\nsnippet cite\n <cite>${1}</cite>\nsnippet code\n <code>${1}</code>\nsnippet col\n <col />${1}\nsnippet col+\n <col />\n col+${1}\nsnippet colgroup\n <colgroup>\n ${1}\n </colgroup>\nsnippet colgroup+\n <colgroup>\n <col />\n col+${1}\n </colgroup>\nsnippet command\n <command type="command" label="${1}" icon="${2}" />\nsnippet command:c\n <command type="checkbox" label="${1}" icon="${2}" />\nsnippet command:r\n <command type="radio" radiogroup="${1}" label="${2}" icon="${3}" />\nsnippet datagrid\n <datagrid>\n ${1}\n </datagrid>\nsnippet datalist\n <datalist>\n ${1}\n </datalist>\nsnippet datatemplate\n <datatemplate>\n ${1}\n </datatemplate>\nsnippet dd\n <dd>${1}</dd>\nsnippet dd.\n <dd class="${1}">${2}</dd>\nsnippet dd#\n <dd id="${1}">${2}</dd>\nsnippet del\n <del>${1}</del>\nsnippet details\n <details>${1}</details>\nsnippet dfn\n <dfn>${1}</dfn>\nsnippet dialog\n <dialog>\n ${1}\n </dialog>\nsnippet div\n <div>\n ${1}\n </div>\nsnippet div.\n <div class="${1}">\n ${2}\n </div>\nsnippet div#\n <div id="${1}">\n ${2}\n </div>\nsnippet dl\n <dl>\n ${1}\n </dl>\nsnippet dl.\n <dl class="${1}">\n ${2}\n </dl>\nsnippet dl#\n <dl id="${1}">\n ${2}\n </dl>\nsnippet dl+\n <dl>\n <dt>${1}</dt>\n <dd>${2}</dd>\n dt+${3}\n </dl>\nsnippet dt\n <dt>${1}</dt>\nsnippet dt.\n <dt class="${1}">${2}</dt>\nsnippet dt#\n <dt id="${1}">${2}</dt>\nsnippet dt+\n <dt>${1}</dt>\n <dd>${2}</dd>\n dt+${3}\nsnippet em\n <em>${1}</em>\nsnippet embed\n <embed src=${1} type="${2} />\nsnippet fieldset\n <fieldset>\n ${1}\n </fieldset>\nsnippet fieldset.\n <fieldset class="${1}">\n ${2}\n </fieldset>\nsnippet fieldset#\n <fieldset id="${1}">\n ${2}\n </fieldset>\nsnippet fieldset+\n <fieldset>\n <legend><span>${1}</span></legend>\n ${2}\n </fieldset>\n fieldset+${3}\nsnippet figcaption\n <figcaption>${1}</figcaption>\nsnippet figure\n <figure>${1}</figure>\nsnippet footer\n <footer>\n ${1}\n </footer>\nsnippet footer.\n <footer class="${1}">\n ${2}\n </footer>\nsnippet footer#\n <footer id="${1}">\n ${2}\n </footer>\nsnippet form\n <form action="${1}" method="${2:get}" accept-charset="utf-8">\n ${3}\n </form>\nsnippet form.\n <form class="${1}" action="${2}" method="${3:get}" accept-charset="utf-8">\n ${4}\n </form>\nsnippet form#\n <form id="${1}" action="${2}" method="${3:get}" accept-charset="utf-8">\n ${4}\n </form>\nsnippet h1\n <h1>${1}</h1>\nsnippet h1.\n <h1 class="${1}">${2}</h1>\nsnippet h1#\n <h1 id="${1}">${2}</h1>\nsnippet h2\n <h2>${1}</h2>\nsnippet h2.\n <h2 class="${1}">${2}</h2>\nsnippet h2#\n <h2 id="${1}">${2}</h2>\nsnippet h3\n <h3>${1}</h3>\nsnippet h3.\n <h3 class="${1}">${2}</h3>\nsnippet h3#\n <h3 id="${1}">${2}</h3>\nsnippet h4\n <h4>${1}</h4>\nsnippet h4.\n <h4 class="${1}">${2}</h4>\nsnippet h4#\n <h4 id="${1}">${2}</h4>\nsnippet h5\n <h5>${1}</h5>\nsnippet h5.\n <h5 class="${1}">${2}</h5>\nsnippet h5#\n <h5 id="${1}">${2}</h5>\nsnippet h6\n <h6>${1}</h6>\nsnippet h6.\n <h6 class="${1}">${2}</h6>\nsnippet h6#\n <h6 id="${1}">${2}</h6>\nsnippet head\n <head>\n <meta http-equiv="content-type" content="text/html; charset=utf-8" />\n\n <title>${1:`substitute(Filename(\'\', \'Page Title\'), \'^.\', \'\\u&\', \'\')`}</title>\n ${2}\n </head>\nsnippet header\n <header>\n ${1}\n </header>\nsnippet header.\n <header class="${1}">\n ${2}\n </header>\nsnippet header#\n <header id="${1}">\n ${2}\n </header>\nsnippet hgroup\n <hgroup>\n ${1}\n </hgroup>\nsnippet hgroup.\n <hgroup class="${1}>\n ${2}\n </hgroup>\nsnippet hr\n <hr />${1}\nsnippet html\n <html>\n ${1}\n </html>\nsnippet xhtml\n <html xmlns="http://www.w3.org/1999/xhtml">\n ${1}\n </html>\nsnippet html5\n <!DOCTYPE html>\n <html>\n <head>\n <meta http-equiv="content-type" content="text/html; charset=utf-8" />\n <title>${1:`substitute(Filename(\'\', \'Page Title\'), \'^.\', \'\\u&\', \'\')`}</title>\n ${2:meta}\n </head>\n <body>\n ${3:body}\n </body>\n </html>\nsnippet xhtml5\n <!DOCTYPE html>\n <html xmlns="http://www.w3.org/1999/xhtml">\n <head>\n <meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />\n <title>${1:`substitute(Filename(\'\', \'Page Title\'), \'^.\', \'\\u&\', \'\')`}</title>\n ${2:meta}\n </head>\n <body>\n ${3:body}\n </body>\n </html>\nsnippet i\n <i>${1}</i>\nsnippet iframe\n <iframe src="${1}" frameborder="0"></iframe>${2}\nsnippet iframe.\n <iframe class="${1}" src="${2}" frameborder="0"></iframe>${3}\nsnippet iframe#\n <iframe id="${1}" src="${2}" frameborder="0"></iframe>${3}\nsnippet img\n <img src="${1}" alt="${2}" />${3}\nsnippet img.\n <img class="${1}" src="${2}" alt="${3}" />${4}\nsnippet img#\n <img id="${1}" src="${2}" alt="${3}" />${4}\nsnippet input\n <input type="${1:text/submit/hidden/button/image}" name="${2}" id="${3:$2}" value="${4}" />${5}\nsnippet input.\n <input class="${1}" type="${2:text/submit/hidden/button/image}" name="${3}" id="${4:$3}" value="${5}" />${6}\nsnippet input:text\n <input type="text" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:submit\n <input type="submit" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:hidden\n <input type="hidden" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:button\n <input type="button" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:image\n <input type="image" name="${1}" id="${2:$1}" src="${3}" alt="${4}" />${5}\nsnippet input:checkbox\n <input type="checkbox" name="${1}" id="${2:$1}" />${3}\nsnippet input:radio\n <input type="radio" name="${1}" id="${2:$1}" />${3}\nsnippet input:color\n <input type="color" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:date\n <input type="date" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:datetime\n <input type="datetime" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:datetime-local\n <input type="datetime-local" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:email\n <input type="email" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:file\n <input type="file" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:month\n <input type="month" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:number\n <input type="number" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:password\n <input type="password" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:range\n <input type="range" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:reset\n <input type="reset" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:search\n <input type="search" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:time\n <input type="time" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:url\n <input type="url" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:week\n <input type="week" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet ins\n <ins>${1}</ins>\nsnippet kbd\n <kbd>${1}</kbd>\nsnippet keygen\n <keygen>${1}</keygen>\nsnippet label\n <label for="${2:$1}">${1}</label>\nsnippet label:i\n <label for="${2:$1}">${1}</label>\n <input type="${3:text/submit/hidden/button}" name="${4:$2}" id="${5:$2}" value="${6}" />${7}\nsnippet label:s\n <label for="${2:$1}">${1}</label>\n <select name="${3:$2}" id="${4:$2}">\n <option value="${5}">${6:$5}</option>\n </select>\nsnippet legend\n <legend>${1}</legend>\nsnippet legend+\n <legend><span>${1}</span></legend>\nsnippet li\n <li>${1}</li>\nsnippet li.\n <li class="${1}">${2}</li>\nsnippet li+\n <li>${1}</li>\n li+${2}\nsnippet lia\n <li><a href="${2:#}">${1}</a></li>\nsnippet lia+\n <li><a href="${2:#}">${1}</a></li>\n lia+${3}\nsnippet link\n <link rel="${1}" href="${2}" title="${3}" type="${4}" />${5}\nsnippet link:atom\n <link rel="alternate" href="${1:atom.xml}" title="Atom" type="application/atom+xml" />${2}\nsnippet link:css\n <link rel="stylesheet" href="${2:style.css}" type="text/css" media="${3:all}" />${4}\nsnippet link:favicon\n <link rel="shortcut icon" href="${1:favicon.ico}" type="image/x-icon" />${2}\nsnippet link:rss\n <link rel="alternate" href="${1:rss.xml}" title="RSS" type="application/atom+xml" />${2}\nsnippet link:touch\n <link rel="apple-touch-icon" href="${1:favicon.png}" />${2}\nsnippet map\n <map name="${1}">\n ${2}\n </map>\nsnippet map.\n <map class="${1}" name="${2}">\n ${3}\n </map>\nsnippet map#\n <map name="${1}" id="${2:$1}>\n ${3}\n </map>\nsnippet map+\n <map name="${1}">\n <area shape="${2}" coords="${3}" href="${4}" alt="${5}" />${6}\n </map>${7}\nsnippet mark\n <mark>${1}</mark>\nsnippet menu\n <menu>\n ${1}\n </menu>\nsnippet menu:c\n <menu type="context">\n ${1}\n </menu>\nsnippet menu:t\n <menu type="toolbar">\n ${1}\n </menu>\nsnippet meta\n <meta http-equiv="${1}" content="${2}" />${3}\nsnippet meta:compat\n <meta http-equiv="X-UA-Compatible" content="IE=${1:7,8,edge}" />${3}\nsnippet meta:refresh\n <meta http-equiv="refresh" content="text/html;charset=UTF-8" />${3}\nsnippet meta:utf\n <meta http-equiv="content-type" content="text/html;charset=UTF-8" />${3}\nsnippet meter\n <meter>${1}</meter>\nsnippet nav\n <nav>\n ${1}\n </nav>\nsnippet nav.\n <nav class="${1}">\n ${2}\n </nav>\nsnippet nav#\n <nav id="${1}">\n ${2}\n </nav>\nsnippet noscript\n <noscript>\n ${1}\n </noscript>\nsnippet object\n <object data="${1}" type="${2}">\n ${3}\n </object>${4}\n# Embed QT Movie\nsnippet movie\n <object width="$2" height="$3" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"\n codebase="http://www.apple.com/qtactivex/qtplugin.cab">\n <param name="src" value="$1" />\n <param name="controller" value="$4" />\n <param name="autoplay" value="$5" />\n <embed src="${1:movie.mov}"\n width="${2:320}" height="${3:240}"\n controller="${4:true}" autoplay="${5:true}"\n scale="tofit" cache="true"\n pluginspage="http://www.apple.com/quicktime/download/" />\n </object>${6}\nsnippet ol\n <ol>\n ${1}\n </ol>\nsnippet ol.\n <ol class="${1}>\n ${2}\n </ol>\nsnippet ol#\n <ol id="${1}>\n ${2}\n </ol>\nsnippet ol+\n <ol>\n <li>${1}</li>\n li+${2}\n </ol>\nsnippet opt\n <option value="${1}">${2:$1}</option>\nsnippet opt+\n <option value="${1}">${2:$1}</option>\n opt+${3}\nsnippet optt\n <option>${1}</option>\nsnippet optgroup\n <optgroup>\n <option value="${1}">${2:$1}</option>\n opt+${3}\n </optgroup>\nsnippet output\n <output>${1}</output>\nsnippet p\n <p>${1}</p>\nsnippet param\n <param name="${1}" value="${2}" />${3}\nsnippet pre\n <pre>\n ${1}\n </pre>\nsnippet progress\n <progress>${1}</progress>\nsnippet q\n <q>${1}</q>\nsnippet rp\n <rp>${1}</rp>\nsnippet rt\n <rt>${1}</rt>\nsnippet ruby\n <ruby>\n <rp><rt>${1}</rt></rp>\n </ruby>\nsnippet s\n <s>${1}</s>\nsnippet samp\n <samp>\n ${1}\n </samp>\nsnippet script\n <script type="text/javascript" charset="utf-8">\n ${1}\n <\/script>\nsnippet scriptsrc\n <script src="${1}.js" type="text/javascript" charset="utf-8"><\/script>\nsnippet newscript\n <script type="application/javascript" charset="utf-8">\n ${1}\n <\/script>\nsnippet newscriptsrc\n <script src="${1}.js" type="application/javascript" charset="utf-8"><\/script>\nsnippet section\n <section>\n ${1}\n </section>\nsnippet section.\n <section class="${1}">\n ${2}\n </section>\nsnippet section#\n <section id="${1}">\n ${2}\n </section>\nsnippet select\n <select name="${1}" id="${2:$1}">\n ${3}\n </select>\nsnippet select.\n <select name="${1}" id="${2:$1}" class="${3}>\n ${4}\n </select>\nsnippet select+\n <select name="${1}" id="${2:$1}">\n <option value="${3}">${4:$3}</option>\n opt+${5}\n </select>\nsnippet small\n <small>${1}</small>\nsnippet source\n <source src="${1}" type="${2}" media="${3}" />\nsnippet span\n <span>${1}</span>\nsnippet strong\n <strong>${1}</strong>\nsnippet style\n <style type="text/css" media="${1:all}">\n ${2}\n </style>\nsnippet sub\n <sub>${1}</sub>\nsnippet summary\n <summary>\n ${1}\n </summary>\nsnippet sup\n <sup>${1}</sup>\nsnippet table\n <table border="${1:0}">\n ${2}\n </table>\nsnippet table.\n <table class="${1}" border="${2:0}">\n ${3}\n </table>\nsnippet table#\n <table id="${1}" border="${2:0}">\n ${3}\n </table>\nsnippet tbody\n <tbody>\n ${1}\n </tbody>\nsnippet td\n <td>${1}</td>\nsnippet td.\n <td class="${1}">${2}</td>\nsnippet td#\n <td id="${1}">${2}</td>\nsnippet td+\n <td>${1}</td>\n td+${2}\nsnippet textarea\n <textarea name="${1}" id=${2:$1} rows="${3:8}" cols="${4:40}">${5}</textarea>${6}\nsnippet tfoot\n <tfoot>\n ${1}\n </tfoot>\nsnippet th\n <th>${1}</th>\nsnippet th.\n <th class="${1}">${2}</th>\nsnippet th#\n <th id="${1}">${2}</th>\nsnippet th+\n <th>${1}</th>\n th+${2}\nsnippet thead\n <thead>\n ${1}\n </thead>\nsnippet time\n <time datetime="${1}" pubdate="${2:$1}>${3:$1}</time>\nsnippet title\n <title>${1:`substitute(Filename(\'\', \'Page Title\'), \'^.\', \'\\u&\', \'\')`}</title>\nsnippet tr\n <tr>\n ${1}\n </tr>\nsnippet tr+\n <tr>\n <td>${1}</td>\n td+${2}\n </tr>\nsnippet track\n <track src="${1}" srclang="${2}" label="${3}" default="${4:default}>${5}</track>${6}\nsnippet ul\n <ul>\n ${1}\n </ul>\nsnippet ul.\n <ul class="${1}">\n ${2}\n </ul>\nsnippet ul#\n <ul id="${1}">\n ${2}\n </ul>\nsnippet ul+\n <ul>\n <li>${1}</li>\n li+${2}\n </ul>\nsnippet var\n <var>${1}</var>\nsnippet video\n <video src="${1} height="${2}" width="${3}" preload="${5:none}" autoplay="${6:autoplay}>${7}</video>${8}\nsnippet wbr\n <wbr />${1}\n',t.scope="html"}); (function() { + ace.require(["ace/snippets/html"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/javascript.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/javascript.js new file mode 100644 index 0000000..efe9568 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/javascript.js @@ -0,0 +1,8 @@ +ace.define("ace/snippets/javascript",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='# Prototype\nsnippet proto\n ${1:class_name}.prototype.${2:method_name} = function(${3:first_argument}) {\n ${4:// body...}\n };\n# Function\nsnippet fun\n function ${1?:function_name}(${2:argument}) {\n ${3:// body...}\n }\n# Anonymous Function\nregex /((=)\\s*|(:)\\s*|(\\()|\\b)/f/(\\))?/\nsnippet f\n function${M1?: ${1:functionName}}($2) {\n ${0:$TM_SELECTED_TEXT}\n }${M2?;}${M3?,}${M4?)}\n# Immediate function\ntrigger \\(?f\\(\nendTrigger \\)?\nsnippet f(\n (function(${1}) {\n ${0:${TM_SELECTED_TEXT:/* code */}}\n }(${1}));\n# if\nsnippet if\n if (${1:true}) {\n ${0}\n }\n# if ... else\nsnippet ife\n if (${1:true}) {\n ${2}\n } else {\n ${0}\n }\n# tertiary conditional\nsnippet ter\n ${1:/* condition */} ? ${2:a} : ${3:b}\n# switch\nsnippet switch\n switch (${1:expression}) {\n case \'${3:case}\':\n ${4:// code}\n break;\n ${5}\n default:\n ${2:// code}\n }\n# case\nsnippet case\n case \'${1:case}\':\n ${2:// code}\n break;\n ${3}\n\n# while (...) {...}\nsnippet wh\n while (${1:/* condition */}) {\n ${0:/* code */}\n }\n# try\nsnippet try\n try {\n ${0:/* code */}\n } catch (e) {}\n# do...while\nsnippet do\n do {\n ${2:/* code */}\n } while (${1:/* condition */});\n# Object Method\nsnippet :f\nregex /([,{[])|^\\s*/:f/\n ${1:method_name}: function(${2:attribute}) {\n ${0}\n }${3:,}\n# setTimeout function\nsnippet setTimeout\nregex /\\b/st|timeout|setTimeo?u?t?/\n setTimeout(function() {${3:$TM_SELECTED_TEXT}}, ${1:10});\n# Get Elements\nsnippet gett\n getElementsBy${1:TagName}(\'${2}\')${3}\n# Get Element\nsnippet get\n getElementBy${1:Id}(\'${2}\')${3}\n# console.log (Firebug)\nsnippet cl\n console.log(${1});\n# return\nsnippet ret\n return ${1:result}\n# for (property in object ) { ... }\nsnippet fori\n for (var ${1:prop} in ${2:Things}) {\n ${0:$2[$1]}\n }\n# hasOwnProperty\nsnippet has\n hasOwnProperty(${1})\n# docstring\nsnippet /**\n /**\n * ${1:description}\n *\n */\nsnippet @par\nregex /^\\s*\\*\\s*/@(para?m?)?/\n @param {${1:type}} ${2:name} ${3:description}\nsnippet @ret\n @return {${1:type}} ${2:description}\n# JSON.parse\nsnippet jsonp\n JSON.parse(${1:jstr});\n# JSON.stringify\nsnippet jsons\n JSON.stringify(${1:object});\n# self-defining function\nsnippet sdf\n var ${1:function_name} = function(${2:argument}) {\n ${3:// initial code ...}\n\n $1 = function($2) {\n ${4:// main code}\n };\n }\n# singleton\nsnippet sing\n function ${1:Singleton} (${2:argument}) {\n // the cached instance\n var instance;\n\n // rewrite the constructor\n $1 = function $1($2) {\n return instance;\n };\n \n // carry over the prototype properties\n $1.prototype = this;\n\n // the instance\n instance = new $1();\n\n // reset the constructor pointer\n instance.constructor = $1;\n\n ${3:// code ...}\n\n return instance;\n }\n# class\nsnippet class\nregex /^\\s*/clas{0,2}/\n var ${1:class} = function(${20}) {\n $40$0\n };\n \n (function() {\n ${60:this.prop = ""}\n }).call(${1:class}.prototype);\n \n exports.${1:class} = ${1:class};\n# \nsnippet for-\n for (var ${1:i} = ${2:Things}.length; ${1:i}--; ) {\n ${0:${2:Things}[${1:i}];}\n }\n# for (...) {...}\nsnippet for\n for (var ${1:i} = 0; $1 < ${2:Things}.length; $1++) {\n ${3:$2[$1]}$0\n }\n# for (...) {...} (Improved Native For-Loop)\nsnippet forr\n for (var ${1:i} = ${2:Things}.length - 1; $1 >= 0; $1--) {\n ${3:$2[$1]}$0\n }\n\n\n#modules\nsnippet def\n define(function(require, exports, module) {\n "use strict";\n var ${1/.*\\///} = require("${1}");\n \n $TM_SELECTED_TEXT\n });\nsnippet req\nguard ^\\s*\n var ${1/.*\\///} = require("${1}");\n $0\nsnippet requ\nguard ^\\s*\n var ${1/.*\\/(.)/\\u$1/} = require("${1}").${1/.*\\/(.)/\\u$1/};\n $0\n',t.scope="javascript"}); (function() { + ace.require(["ace/snippets/javascript"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/json.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/json.js new file mode 100644 index 0000000..b27c529 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/json.js @@ -0,0 +1,8 @@ +ace.define("ace/snippets/json",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="json"}); (function() { + ace.require(["ace/snippets/json"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/markdown.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/markdown.js new file mode 100644 index 0000000..15f446f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/markdown.js @@ -0,0 +1,8 @@ +ace.define("ace/snippets/markdown",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='# Markdown\n\n# Includes octopress (http://octopress.org/) snippets\n\nsnippet [\n [${1:text}](http://${2:address} "${3:title}")\nsnippet [*\n [${1:link}](${2:`@*`} "${3:title}")${4}\n\nsnippet [:\n [${1:id}]: http://${2:url} "${3:title}"\nsnippet [:*\n [${1:id}]: ${2:`@*`} "${3:title}"\n\nsnippet ![\n ![${1:alttext}](${2:/images/image.jpg} "${3:title}")\nsnippet ![*\n ![${1:alt}](${2:`@*`} "${3:title}")${4}\n\nsnippet ![:\n ![${1:id}]: ${2:url} "${3:title}"\nsnippet ![:*\n ![${1:id}]: ${2:`@*`} "${3:title}"\n\nsnippet ===\nregex /^/=+/=*//\n ${PREV_LINE/./=/g}\n \n ${0}\nsnippet ---\nregex /^/-+/-*//\n ${PREV_LINE/./-/g}\n \n ${0}\nsnippet blockquote\n {% blockquote %}\n ${1:quote}\n {% endblockquote %}\n\nsnippet blockquote-author\n {% blockquote ${1:author}, ${2:title} %}\n ${3:quote}\n {% endblockquote %}\n\nsnippet blockquote-link\n {% blockquote ${1:author} ${2:URL} ${3:link_text} %}\n ${4:quote}\n {% endblockquote %}\n\nsnippet bt-codeblock-short\n ```\n ${1:code_snippet}\n ```\n\nsnippet bt-codeblock-full\n ``` ${1:language} ${2:title} ${3:URL} ${4:link_text}\n ${5:code_snippet}\n ```\n\nsnippet codeblock-short\n {% codeblock %}\n ${1:code_snippet}\n {% endcodeblock %}\n\nsnippet codeblock-full\n {% codeblock ${1:title} lang:${2:language} ${3:URL} ${4:link_text} %}\n ${5:code_snippet}\n {% endcodeblock %}\n\nsnippet gist-full\n {% gist ${1:gist_id} ${2:filename} %}\n\nsnippet gist-short\n {% gist ${1:gist_id} %}\n\nsnippet img\n {% img ${1:class} ${2:URL} ${3:width} ${4:height} ${5:title_text} ${6:alt_text} %}\n\nsnippet youtube\n {% youtube ${1:video_id} %}\n\n# The quote should appear only once in the text. It is inherently part of it.\n# See http://octopress.org/docs/plugins/pullquote/ for more info.\n\nsnippet pullquote\n {% pullquote %}\n ${1:text} {" ${2:quote} "} ${3:text}\n {% endpullquote %}\n',t.scope="markdown"}); (function() { + ace.require(["ace/snippets/markdown"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/properties.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/properties.js new file mode 100644 index 0000000..25714e2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/properties.js @@ -0,0 +1,8 @@ +ace.define("ace/snippets/properties",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="properties"}); (function() { + ace.require(["ace/snippets/properties"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/python.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/python.js new file mode 100644 index 0000000..2944cc8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/python.js @@ -0,0 +1,8 @@ +ace.define("ace/snippets/python",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='snippet #!\n #!/usr/bin/env python\nsnippet imp\n import ${1:module}\nsnippet from\n from ${1:package} import ${2:module}\n# Module Docstring\nsnippet docs\n \'\'\'\n File: ${1:FILENAME:file_name}\n Author: ${2:author}\n Description: ${3}\n \'\'\'\nsnippet wh\n while ${1:condition}:\n ${2:# TODO: write code...}\n# dowh - does the same as do...while in other languages\nsnippet dowh\n while True:\n ${1:# TODO: write code...}\n if ${2:condition}:\n break\nsnippet with\n with ${1:expr} as ${2:var}:\n ${3:# TODO: write code...}\n# New Class\nsnippet cl\n class ${1:ClassName}(${2:object}):\n """${3:docstring for $1}"""\n def __init__(self, ${4:arg}):\n ${5:super($1, self).__init__()}\n self.$4 = $4\n ${6}\n# New Function\nsnippet def\n def ${1:fname}(${2:`indent(\'.\') ? \'self\' : \'\'`}):\n """${3:docstring for $1}"""\n ${4:# TODO: write code...}\nsnippet deff\n def ${1:fname}(${2:`indent(\'.\') ? \'self\' : \'\'`}):\n ${3:# TODO: write code...}\n# New Method\nsnippet defs\n def ${1:mname}(self, ${2:arg}):\n ${3:# TODO: write code...}\n# New Property\nsnippet property\n def ${1:foo}():\n doc = "${2:The $1 property.}"\n def fget(self):\n ${3:return self._$1}\n def fset(self, value):\n ${4:self._$1 = value}\n# Ifs\nsnippet if\n if ${1:condition}:\n ${2:# TODO: write code...}\nsnippet el\n else:\n ${1:# TODO: write code...}\nsnippet ei\n elif ${1:condition}:\n ${2:# TODO: write code...}\n# For\nsnippet for\n for ${1:item} in ${2:items}:\n ${3:# TODO: write code...}\n# Encodes\nsnippet cutf8\n # -*- coding: utf-8 -*-\nsnippet clatin1\n # -*- coding: latin-1 -*-\nsnippet cascii\n # -*- coding: ascii -*-\n# Lambda\nsnippet ld\n ${1:var} = lambda ${2:vars} : ${3:action}\nsnippet .\n self.\nsnippet try Try/Except\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\nsnippet try Try/Except/Else\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\n else:\n ${5:# TODO: write code...}\nsnippet try Try/Except/Finally\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\n finally:\n ${5:# TODO: write code...}\nsnippet try Try/Except/Else/Finally\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\n else:\n ${5:# TODO: write code...}\n finally:\n ${6:# TODO: write code...}\n# if __name__ == \'__main__\':\nsnippet ifmain\n if __name__ == \'__main__\':\n ${1:main()}\n# __magic__\nsnippet _\n __${1:init}__${2}\n# python debugger (pdb)\nsnippet pdb\n import pdb; pdb.set_trace()\n# ipython debugger (ipdb)\nsnippet ipdb\n import ipdb; ipdb.set_trace()\n# ipython debugger (pdbbb)\nsnippet pdbbb\n import pdbpp; pdbpp.set_trace()\nsnippet pprint\n import pprint; pprint.pprint(${1})${2}\nsnippet "\n """\n ${1:doc}\n """\n# test function/method\nsnippet test\n def test_${1:description}(${2:self}):\n ${3:# TODO: write code...}\n# test case\nsnippet testcase\n class ${1:ExampleCase}(unittest.TestCase):\n \n def test_${2:description}(self):\n ${3:# TODO: write code...}\nsnippet fut\n from __future__ import ${1}\n#getopt\nsnippet getopt\n try:\n # Short option syntax: "hv:"\n # Long option syntax: "help" or "verbose="\n opts, args = getopt.getopt(sys.argv[1:], "${1:short_options}", [${2:long_options}])\n \n except getopt.GetoptError, err:\n # Print debug info\n print str(err)\n ${3:error_action}\n\n for option, argument in opts:\n if option in ("-h", "--help"):\n ${4}\n elif option in ("-v", "--verbose"):\n verbose = argument\n',t.scope="python"}); (function() { + ace.require(["ace/snippets/python"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/sql.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/sql.js new file mode 100644 index 0000000..759a387 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/sql.js @@ -0,0 +1,8 @@ +ace.define("ace/snippets/sql",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="snippet tbl\n create table ${1:table} (\n ${2:columns}\n );\nsnippet col\n ${1:name} ${2:type} ${3:default ''} ${4:not null}\nsnippet ccol\n ${1:name} varchar2(${2:size}) ${3:default ''} ${4:not null}\nsnippet ncol\n ${1:name} number ${3:default 0} ${4:not null}\nsnippet dcol\n ${1:name} date ${3:default sysdate} ${4:not null}\nsnippet ind\n create index ${3:$1_$2} on ${1:table}(${2:column});\nsnippet uind\n create unique index ${1:name} on ${2:table}(${3:column});\nsnippet tblcom\n comment on table ${1:table} is '${2:comment}';\nsnippet colcom\n comment on column ${1:table}.${2:column} is '${3:comment}';\nsnippet addcol\n alter table ${1:table} add (${2:column} ${3:type});\nsnippet seq\n create sequence ${1:name} start with ${2:1} increment by ${3:1} minvalue ${4:1};\nsnippet s*\n select * from ${1:table}\n",t.scope="sql"}); (function() { + ace.require(["ace/snippets/sql"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/swift.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/swift.js new file mode 100644 index 0000000..de9ebe9 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/swift.js @@ -0,0 +1,8 @@ +ace.define("ace/snippets/swift",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="swift"}); (function() { + ace.require(["ace/snippets/swift"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/text.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/text.js new file mode 100644 index 0000000..0a9cf0f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/text.js @@ -0,0 +1,8 @@ +ace.define("ace/snippets/text",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="text"}); (function() { + ace.require(["ace/snippets/text"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/xml.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/xml.js new file mode 100644 index 0000000..7298e36 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/xml.js @@ -0,0 +1,8 @@ +ace.define("ace/snippets/xml",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="xml"}); (function() { + ace.require(["ace/snippets/xml"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/yaml.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/yaml.js new file mode 100644 index 0000000..a62b553 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/snippets/yaml.js @@ -0,0 +1,8 @@ +ace.define("ace/snippets/yaml",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="yaml"}); (function() { + ace.require(["ace/snippets/yaml"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/theme-chrome.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/theme-chrome.js new file mode 100644 index 0000000..cabebe9 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/theme-chrome.js @@ -0,0 +1,8 @@ +ace.define("ace/theme/chrome",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-chrome",t.cssText='.ace-chrome .ace_gutter {background: #ebebeb;color: #333;overflow : hidden;}.ace-chrome .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-chrome {background-color: #FFFFFF;color: black;}.ace-chrome .ace_cursor {color: black;}.ace-chrome .ace_invisible {color: rgb(191, 191, 191);}.ace-chrome .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-chrome .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-chrome .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-chrome .ace_invalid {background-color: rgb(153, 0, 0);color: white;}.ace-chrome .ace_fold {}.ace-chrome .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-chrome .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-chrome .ace_support.ace_type,.ace-chrome .ace_support.ace_class.ace-chrome .ace_support.ace_other {color: rgb(109, 121, 222);}.ace-chrome .ace_variable.ace_parameter {font-style:italic;color:#FD971F;}.ace-chrome .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-chrome .ace_comment {color: #236e24;}.ace-chrome .ace_comment.ace_doc {color: #236e24;}.ace-chrome .ace_comment.ace_doc.ace_tag {color: #236e24;}.ace-chrome .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-chrome .ace_variable {color: rgb(49, 132, 149);}.ace-chrome .ace_xml-pe {color: rgb(104, 104, 91);}.ace-chrome .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-chrome .ace_heading {color: rgb(12, 7, 255);}.ace-chrome .ace_list {color:rgb(185, 6, 144);}.ace-chrome .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-chrome .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-chrome .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-chrome .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-chrome .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-chrome .ace_gutter-active-line {background-color : #dcdcdc;}.ace-chrome .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-chrome .ace_storage,.ace-chrome .ace_keyword,.ace-chrome .ace_meta.ace_tag {color: rgb(147, 15, 128);}.ace-chrome .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-chrome .ace_string {color: #1A1AA6;}.ace-chrome .ace_entity.ace_other.ace_attribute-name {color: #994409;}.ace-chrome .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}';var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}); (function() { + ace.require(["ace/theme/chrome"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/theme-tomorrow.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/theme-tomorrow.js new file mode 100644 index 0000000..985d6b4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/theme-tomorrow.js @@ -0,0 +1,8 @@ +ace.define("ace/theme/tomorrow",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-tomorrow",t.cssText=".ace-tomorrow .ace_gutter {background: #f6f6f6;color: #4D4D4C}.ace-tomorrow .ace_print-margin {width: 1px;background: #f6f6f6}.ace-tomorrow {background-color: #FFFFFF;color: #4D4D4C}.ace-tomorrow .ace_cursor {color: #AEAFAD}.ace-tomorrow .ace_marker-layer .ace_selection {background: #D6D6D6}.ace-tomorrow.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #FFFFFF;}.ace-tomorrow .ace_marker-layer .ace_step {background: rgb(255, 255, 0)}.ace-tomorrow .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #D1D1D1}.ace-tomorrow .ace_marker-layer .ace_active-line {background: #EFEFEF}.ace-tomorrow .ace_gutter-active-line {background-color : #dcdcdc}.ace-tomorrow .ace_marker-layer .ace_selected-word {border: 1px solid #D6D6D6}.ace-tomorrow .ace_invisible {color: #D1D1D1}.ace-tomorrow .ace_keyword,.ace-tomorrow .ace_meta,.ace-tomorrow .ace_storage,.ace-tomorrow .ace_storage.ace_type,.ace-tomorrow .ace_support.ace_type {color: #8959A8}.ace-tomorrow .ace_keyword.ace_operator {color: #3E999F}.ace-tomorrow .ace_constant.ace_character,.ace-tomorrow .ace_constant.ace_language,.ace-tomorrow .ace_constant.ace_numeric,.ace-tomorrow .ace_keyword.ace_other.ace_unit,.ace-tomorrow .ace_support.ace_constant,.ace-tomorrow .ace_variable.ace_parameter {color: #F5871F}.ace-tomorrow .ace_constant.ace_other {color: #666969}.ace-tomorrow .ace_invalid {color: #FFFFFF;background-color: #C82829}.ace-tomorrow .ace_invalid.ace_deprecated {color: #FFFFFF;background-color: #8959A8}.ace-tomorrow .ace_fold {background-color: #4271AE;border-color: #4D4D4C}.ace-tomorrow .ace_entity.ace_name.ace_function,.ace-tomorrow .ace_support.ace_function,.ace-tomorrow .ace_variable {color: #4271AE}.ace-tomorrow .ace_support.ace_class,.ace-tomorrow .ace_support.ace_type {color: #C99E00}.ace-tomorrow .ace_heading,.ace-tomorrow .ace_markup.ace_heading,.ace-tomorrow .ace_string {color: #718C00}.ace-tomorrow .ace_entity.ace_name.ace_tag,.ace-tomorrow .ace_entity.ace_other.ace_attribute-name,.ace-tomorrow .ace_meta.ace_tag,.ace-tomorrow .ace_string.ace_regexp,.ace-tomorrow .ace_variable {color: #C82829}.ace-tomorrow .ace_comment {color: #8E908C}.ace-tomorrow .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bdu3f/BwAlfgctduB85QAAAABJRU5ErkJggg==) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}); (function() { + ace.require(["ace/theme/tomorrow"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/worker-css.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/worker-css.js new file mode 100644 index 0000000..4d750d0 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/worker-css.js @@ -0,0 +1 @@ +"no use strict";!function(e){function t(e,t){var n=e,r="";while(n){var i=t[n];if(typeof i=="string")return i+r;if(i)return i.location.replace(/\/*$/,"/")+(r||i.main||i.name);if(i===!1)return"";var s=n.lastIndexOf("/");if(s===-1)break;r=n.substr(s)+r,n=n.slice(0,s)}return e}if(typeof e.window!="undefined"&&e.document)return;if(e.require&&e.define)return;e.console||(e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console),e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){postMessage({type:"error",data:{message:e,data:i.data,file:t,line:n,col:r,stack:i.stack}})},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(r,i){i||(i=r,r=null);if(!i.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");i=e.normalizeModule(r,i);var s=e.require.modules[i];if(s)return s.initialized||(s.initialized=!0,s.exports=s.factory().exports),s.exports;if(!e.require.tlns)return console.log("unable to load "+i);var o=t(i,e.require.tlns);return o.slice(-3)!=".js"&&(o+=".js"),e.require.id=i,e.require.modules[i]={},importScripts(o),e.require(r,i)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id);if(typeof r!="function"){e.require.modules[t]={exports:r,initialized:!0};return}n.length||(n=["require","exports","module"]);var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.slice(0,r.length).map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},require.tlns={},e.initBaseUrls=function(t){for(var n in t)require.tlns[n]=t[n]},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var n=e.main=null,r=e.sender=null;e.onmessage=function(t){var i=t.data;if(i.event&&r)r._signal(i.event,i.data);else if(i.command)if(n[i.command])n[i.command].apply(n,i.args);else{if(!e[i.command])throw new Error("Unknown command:"+i.command);e[i.command].apply(e,i.args)}else if(i.init){e.initBaseUrls(i.tlns),require("ace/lib/es5-shim"),r=e.sender=e.initSender();var s=require(i.module)[i.classname];n=e.main=new s(r)}}}(this),ace.define("ace/lib/oop",[],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/lib/lang",[],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function s(e){if(typeof e!="object"||!e)return e;var t;if(Array.isArray(e)){t=[];for(var n=0;n<e.length;n++)t[n]=s(e[n]);return t}if(Object.prototype.toString.call(e)!=="[object Object]")return e;t={};for(var n in e)t[n]=s(e[n]);return t},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return(""+e).replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define("ace/range",[],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define("ace/apply_delta",[],function(e,t,n){"use strict";function r(e,t){throw console.log("Invalid Delta:",e),"Invalid Delta: "+t}function i(e,t){return t.row>=0&&t.row<e.length&&t.column>=0&&t.column<=e[t.row].length}function s(e,t){t.action!="insert"&&t.action!="remove"&&r(t,"delta.action must be 'insert' or 'remove'"),t.lines instanceof Array||r(t,"delta.lines must be an Array"),(!t.start||!t.end)&&r(t,"delta.start/end must be an present");var n=t.start;i(e,t.start)||r(t,"delta.start must be contained in document");var s=t.end;t.action=="remove"&&!i(e,s)&&r(t,"delta.end must contained in document for 'remove' actions");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,"delta.range must match delta lines")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||"";switch(t.action){case"insert":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case"remove":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),ace.define("ace/lib/event_emitter",[],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)});if(!t)return new Promise(function(e){t=e})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t)r&&this.setDefaultHandler(e,r.pop());else if(r){var i=r.indexOf(t);i!=-1&&r.splice(i,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?"unshift":"push"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define("ace/anchor",[],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){function e(e,t,n){var r=n?e.column<=t.column:e.column<t.column;return e.row<t.row||e.row==t.row&&r}function t(t,n,r){var i=t.action=="insert",s=(i?1:-1)*(t.end.row-t.start.row),o=(i?1:-1)*(t.end.column-t.start.column),u=t.start,a=i?u:t.end;return e(n,u,r)?{row:n.row,column:n.column}:e(a,n,!r)?{row:n.row+s,column:n.column+(n.row==a.row?o:0)}:{row:u.row,column:u.column}}r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){if(e.start.row==e.end.row&&e.start.row!=this.row)return;if(e.start.row>this.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",[],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./apply_delta").applyDelta,s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=e("./anchor").Anchor,a=function(e){this.$lines=[""],e.length===0?this.$lines=[""]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."),this.insertMergedLines(e,["",""])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:"insert",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e<this.getLength()?(t=t.concat([""]),n=0):(t=[""].concat(t),e--,n=this.$lines[e].length),this.insertMergedLines({row:e,column:n},t)},this.insertMergedLines=function(e,t){var n=this.clippedPos(e.row,e.column),r={row:n.row+t.length-1,column:(t.length==1?n.column:0)+t[t.length-1].length};return this.applyDelta({start:n,end:r,action:"insert",lines:t}),this.clonePos(r)},this.remove=function(e){var t=this.clippedPos(e.start.row,e.start.column),n=this.clippedPos(e.end.row,e.end.column);return this.applyDelta({start:t,end:n,action:"remove",lines:this.getLinesForRange({start:t,end:n})}),this.clonePos(t)},this.removeInLine=function(e,t,n){var r=this.clippedPos(e,t),i=this.clippedPos(e,n);return this.applyDelta({start:r,end:i,action:"remove",lines:this.getLinesForRange({start:r,end:i})},!0),this.clonePos(r)},this.removeFullLines=function(e,t){e=Math.min(Math.max(0,e),this.getLength()-1),t=Math.min(Math.max(0,t),this.getLength()-1);var n=t==this.getLength()-1&&e>0,r=t<this.getLength()-1,i=n?e-1:e,s=n?this.getLine(i).length:0,u=r?t+1:t,a=r?0:this.getLine(u).length,f=new o(i,s,u,a),l=this.$lines.slice(e,t+1);return this.applyDelta({start:f.start,end:f.end,action:"remove",lines:this.getLinesForRange(f)}),l},this.removeNewLine=function(e){e<this.getLength()-1&&e>=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++)this.applyDelta(e[t])},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action=="insert";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4?this.$splitAndapplyLargeDelta(e,2e4):(i(this.$lines,e,t),this._signal("change",e))},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length-t+1,i=e.start.row,s=e.start.column;for(var o=0,u=0;o<r;o=u){u+=t-1;var a=n.slice(o,u);a.push(""),this.applyDelta({start:this.pos(i+o,s),end:this.pos(i+u,s=0),action:e.action,lines:a},!0)}e.lines=n.slice(o),e.start.row=i+o,e.start.column=s,this.applyDelta(e,!0)},this.revertDelta=function(e){this.applyDelta({start:this.clonePos(e.start),end:this.clonePos(e.end),action:e.action=="insert"?"remove":"insert",lines:e.lines.slice()})},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:e+n[s-1].length+r}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(a.prototype),t.Document=a}),ace.define("ace/worker/mirror",[],function(e,t,n){"use strict";var r=e("../range").Range,i=e("../document").Document,s=e("../lib/lang"),o=t.Mirror=function(e){this.sender=e;var t=this.doc=new i(""),n=this.deferredUpdate=s.delayedCall(this.onUpdate.bind(this)),r=this;e.on("change",function(e){var i=e.data;if(i[0].start)t.applyDeltas(i);else for(var s=0;s<i.length;s+=2){if(Array.isArray(i[s+1]))var o={action:"insert",start:i[s],lines:i[s+1]};else var o={action:"remove",start:i[s],end:i[s+1]};t.applyDelta(o,!0)}if(r.$timeout)return n.schedule(r.$timeout);r.onUpdate()})};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(o.prototype)}),ace.define("ace/mode/css/csslint",[],function(require,exports,module){function objectToString(e){return Object.prototype.toString.call(e)}function clone(e,t,n,r){function u(e,n){if(e===null)return null;if(n==0)return e;var a;if(typeof e!="object")return e;if(util.isArray(e))a=[];else if(util.isRegExp(e))a=new RegExp(e.source,util.getRegExpFlags(e)),e.lastIndex&&(a.lastIndex=e.lastIndex);else if(util.isDate(e))a=new Date(e.getTime());else{if(o&&Buffer.isBuffer(e))return a=new Buffer(e.length),e.copy(a),a;typeof r=="undefined"?a=Object.create(Object.getPrototypeOf(e)):a=Object.create(r)}if(t){var f=i.indexOf(e);if(f!=-1)return s[f];i.push(e),s.push(a)}for(var l in e)a[l]=u(e[l],n-1);return a}var i=[],s=[],o=typeof Buffer!="undefined";return typeof t=="undefined"&&(t=!0),typeof n=="undefined"&&(n=Infinity),u(e,n)}function Reporter(e,t){this.messages=[],this.stats=[],this.lines=e,this.ruleset=t}var parserlib={};(function(){function e(){this._listeners={}}function t(e){this._input=e.replace(/\n\r?/g,"\n"),this._line=1,this._col=1,this._cursor=0}function n(e,t,n){this.col=n,this.line=t,this.message=e}function r(e,t,n,r){this.col=n,this.line=t,this.text=e,this.type=r}function i(e,n){this._reader=e?new t(e.toString()):null,this._token=null,this._tokenData=n,this._lt=[],this._ltIndex=0,this._ltIndexCache=[]}e.prototype={constructor:e,addListener:function(e,t){this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push(t)},fire:function(e){typeof e=="string"&&(e={type:e}),typeof e.target!="undefined"&&(e.target=this);if(typeof e.type=="undefined")throw new Error("Event object missing 'type' property.");if(this._listeners[e.type]){var t=this._listeners[e.type].concat();for(var n=0,r=t.length;n<r;n++)t[n].call(this,e)}},removeListener:function(e,t){if(this._listeners[e]){var n=this._listeners[e];for(var r=0,i=n.length;r<i;r++)if(n[r]===t){n.splice(r,1);break}}}},t.prototype={constructor:t,getCol:function(){return this._col},getLine:function(){return this._line},eof:function(){return this._cursor==this._input.length},peek:function(e){var t=null;return e=typeof e=="undefined"?1:e,this._cursor<this._input.length&&(t=this._input.charAt(this._cursor+e-1)),t},read:function(){var e=null;return this._cursor<this._input.length&&(this._input.charAt(this._cursor)=="\n"?(this._line++,this._col=1):this._col++,e=this._input.charAt(this._cursor++)),e},mark:function(){this._bookmark={cursor:this._cursor,line:this._line,col:this._col}},reset:function(){this._bookmark&&(this._cursor=this._bookmark.cursor,this._line=this._bookmark.line,this._col=this._bookmark.col,delete this._bookmark)},readTo:function(e){var t="",n;while(t.length<e.length||t.lastIndexOf(e)!=t.length-e.length){n=this.read();if(!n)throw new Error('Expected "'+e+'" at line '+this._line+", col "+this._col+".");t+=n}return t},readWhile:function(e){var t="",n=this.read();while(n!==null&&e(n))t+=n,n=this.read();return t},readMatch:function(e){var t=this._input.substring(this._cursor),n=null;return typeof e=="string"?t.indexOf(e)===0&&(n=this.readCount(e.length)):e instanceof RegExp&&e.test(t)&&(n=this.readCount(RegExp.lastMatch.length)),n},readCount:function(e){var t="";while(e--)t+=this.read();return t}},n.prototype=new Error,r.fromToken=function(e){return new r(e.value,e.startLine,e.startCol)},r.prototype={constructor:r,valueOf:function(){return this.text},toString:function(){return this.text}},i.createTokenData=function(e){var t=[],n={},r=e.concat([]),i=0,s=r.length+1;r.UNKNOWN=-1,r.unshift({name:"EOF"});for(;i<s;i++)t.push(r[i].name),r[r[i].name]=i,r[i].text&&(n[r[i].text]=i);return r.name=function(e){return t[e]},r.type=function(e){return n[e]},r},i.prototype={constructor:i,match:function(e,t){e instanceof Array||(e=[e]);var n=this.get(t),r=0,i=e.length;while(r<i)if(n==e[r++])return!0;return this.unget(),!1},mustMatch:function(e,t){var r;e instanceof Array||(e=[e]);if(!this.match.apply(this,arguments))throw r=this.LT(1),new n("Expected "+this._tokenData[e[0]].name+" at line "+r.startLine+", col "+r.startCol+".",r.startLine,r.startCol)},advance:function(e,t){while(this.LA(0)!==0&&!this.match(e,t))this.get();return this.LA(0)},get:function(e){var t=this._tokenData,n=this._reader,r,i=0,s=t.length,o=!1,u,a;if(this._lt.length&&this._ltIndex>=0&&this._ltIndex<this._lt.length){i++,this._token=this._lt[this._ltIndex++],a=t[this._token.type];while(a.channel!==undefined&&e!==a.channel&&this._ltIndex<this._lt.length)this._token=this._lt[this._ltIndex++],a=t[this._token.type],i++;if((a.channel===undefined||e===a.channel)&&this._ltIndex<=this._lt.length)return this._ltIndexCache.push(i),this._token.type}return u=this._getToken(),u.type>-1&&!t[u.type].hide&&(u.channel=t[u.type].channel,this._token=u,this._lt.push(u),this._ltIndexCache.push(this._lt.length-this._ltIndex+i),this._lt.length>5&&this._lt.shift(),this._ltIndexCache.length>5&&this._ltIndexCache.shift(),this._ltIndex=this._lt.length),a=t[u.type],a&&(a.hide||a.channel!==undefined&&e!==a.channel)?this.get(e):u.type},LA:function(e){var t=e,n;if(e>0){if(e>5)throw new Error("Too much lookahead.");while(t)n=this.get(),t--;while(t<e)this.unget(),t++}else if(e<0){if(!this._lt[this._ltIndex+e])throw new Error("Too much lookbehind.");n=this._lt[this._ltIndex+e].type}else n=this._token.type;return n},LT:function(e){return this.LA(e),this._lt[this._ltIndex+e-1]},peek:function(){return this.LA(1)},token:function(){return this._token},tokenName:function(e){return e<0||e>this._tokenData.length?"UNKNOWN_TOKEN":this._tokenData[e].name},tokenType:function(e){return this._tokenData[e]||-1},unget:function(){if(!this._ltIndexCache.length)throw new Error("Too much lookahead.");this._ltIndex-=this._ltIndexCache.pop(),this._token=this._lt[this._ltIndex-1]}},parserlib.util={StringReader:t,SyntaxError:n,SyntaxUnit:r,EventTarget:e,TokenStreamBase:i}})(),function(){function Combinator(e,t,n){SyntaxUnit.call(this,e,t,n,Parser.COMBINATOR_TYPE),this.type="unknown",/^\s+$/.test(e)?this.type="descendant":e==">"?this.type="child":e=="+"?this.type="adjacent-sibling":e=="~"&&(this.type="sibling")}function MediaFeature(e,t){SyntaxUnit.call(this,"("+e+(t!==null?":"+t:"")+")",e.startLine,e.startCol,Parser.MEDIA_FEATURE_TYPE),this.name=e,this.value=t}function MediaQuery(e,t,n,r,i){SyntaxUnit.call(this,(e?e+" ":"")+(t?t:"")+(t&&n.length>0?" and ":"")+n.join(" and "),r,i,Parser.MEDIA_QUERY_TYPE),this.modifier=e,this.mediaType=t,this.features=n}function Parser(e){EventTarget.call(this),this.options=e||{},this._tokenStream=null}function PropertyName(e,t,n,r){SyntaxUnit.call(this,e,n,r,Parser.PROPERTY_NAME_TYPE),this.hack=t}function PropertyValue(e,t,n){SyntaxUnit.call(this,e.join(" "),t,n,Parser.PROPERTY_VALUE_TYPE),this.parts=e}function PropertyValueIterator(e){this._i=0,this._parts=e.parts,this._marks=[],this.value=e}function PropertyValuePart(text,line,col){SyntaxUnit.call(this,text,line,col,Parser.PROPERTY_VALUE_PART_TYPE),this.type="unknown";var temp;if(/^([+\-]?[\d\.]+)([a-z]+)$/i.test(text)){this.type="dimension",this.value=+RegExp.$1,this.units=RegExp.$2;switch(this.units.toLowerCase()){case"em":case"rem":case"ex":case"px":case"cm":case"mm":case"in":case"pt":case"pc":case"ch":case"vh":case"vw":case"vmax":case"vmin":this.type="length";break;case"deg":case"rad":case"grad":this.type="angle";break;case"ms":case"s":this.type="time";break;case"hz":case"khz":this.type="frequency";break;case"dpi":case"dpcm":this.type="resolution"}}else/^([+\-]?[\d\.]+)%$/i.test(text)?(this.type="percentage",this.value=+RegExp.$1):/^([+\-]?\d+)$/i.test(text)?(this.type="integer",this.value=+RegExp.$1):/^([+\-]?[\d\.]+)$/i.test(text)?(this.type="number",this.value=+RegExp.$1):/^#([a-f0-9]{3,6})/i.test(text)?(this.type="color",temp=RegExp.$1,temp.length==3?(this.red=parseInt(temp.charAt(0)+temp.charAt(0),16),this.green=parseInt(temp.charAt(1)+temp.charAt(1),16),this.blue=parseInt(temp.charAt(2)+temp.charAt(2),16)):(this.red=parseInt(temp.substring(0,2),16),this.green=parseInt(temp.substring(2,4),16),this.blue=parseInt(temp.substring(4,6),16))):/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i.test(text)?(this.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp.$3):/^rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)?(this.type="color",this.red=+RegExp.$1*255/100,this.green=+RegExp.$2*255/100,this.blue=+RegExp.$3*255/100):/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/i.test(text)?(this.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp.$3,this.alpha=+RegExp.$4):/^rgba\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(text)?(this.type="color",this.red=+RegExp.$1*255/100,this.green=+RegExp.$2*255/100,this.blue=+RegExp.$3*255/100,this.alpha=+RegExp.$4):/^hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100,this.lightness=+RegExp.$3/100):/^hsla\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(text)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100,this.lightness=+RegExp.$3/100,this.alpha=+RegExp.$4):/^url\(["']?([^\)"']+)["']?\)/i.test(text)?(this.type="uri",this.uri=RegExp.$1):/^([^\(]+)\(/i.test(text)?(this.type="function",this.name=RegExp.$1,this.value=text):/^["'][^"']*["']/.test(text)?(this.type="string",this.value=eval(text)):Colors[text.toLowerCase()]?(this.type="color",temp=Colors[text.toLowerCase()].substring(1),this.red=parseInt(temp.substring(0,2),16),this.green=parseInt(temp.substring(2,4),16),this.blue=parseInt(temp.substring(4,6),16)):/^[\,\/]$/.test(text)?(this.type="operator",this.value=text):/^[a-z\-_\u0080-\uFFFF][a-z0-9\-_\u0080-\uFFFF]*$/i.test(text)&&(this.type="identifier",this.value=text)}function Selector(e,t,n){SyntaxUnit.call(this,e.join(" "),t,n,Parser.SELECTOR_TYPE),this.parts=e,this.specificity=Specificity.calculate(this)}function SelectorPart(e,t,n,r,i){SyntaxUnit.call(this,n,r,i,Parser.SELECTOR_PART_TYPE),this.elementName=e,this.modifiers=t}function SelectorSubPart(e,t,n,r){SyntaxUnit.call(this,e,n,r,Parser.SELECTOR_SUB_PART_TYPE),this.type=t,this.args=[]}function Specificity(e,t,n,r){this.a=e,this.b=t,this.c=n,this.d=r}function isHexDigit(e){return e!==null&&h.test(e)}function isDigit(e){return e!==null&&/\d/.test(e)}function isWhitespace(e){return e!==null&&/\s/.test(e)}function isNewLine(e){return e!==null&&nl.test(e)}function isNameStart(e){return e!==null&&/[a-z_\u0080-\uFFFF\\]/i.test(e)}function isNameChar(e){return e!==null&&(isNameStart(e)||/[0-9\-\\]/.test(e))}function isIdentStart(e){return e!==null&&(isNameStart(e)||/\-\\/.test(e))}function mix(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}function TokenStream(e){TokenStreamBase.call(this,e,Tokens)}function ValidationError(e,t,n){this.col=n,this.line=t,this.message=e}var EventTarget=parserlib.util.EventTarget,TokenStreamBase=parserlib.util.TokenStreamBase,StringReader=parserlib.util.StringReader,SyntaxError=parserlib.util.SyntaxError,SyntaxUnit=parserlib.util.SyntaxUnit,Colors={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgrey:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",grey:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32",activeBorder:"Active window border.",activecaption:"Active window caption.",appworkspace:"Background color of multiple document interface.",background:"Desktop background.",buttonface:"The face background color for 3-D elements that appear 3-D due to one layer of surrounding border.",buttonhighlight:"The color of the border facing the light source for 3-D elements that appear 3-D due to one layer of surrounding border.",buttonshadow:"The color of the border away from the light source for 3-D elements that appear 3-D due to one layer of surrounding border.",buttontext:"Text on push buttons.",captiontext:"Text in caption, size box, and scrollbar arrow box.",graytext:"Grayed (disabled) text. This color is set to #000 if the current display driver does not support a solid gray color.",greytext:"Greyed (disabled) text. This color is set to #000 if the current display driver does not support a solid grey color.",highlight:"Item(s) selected in a control.",highlighttext:"Text of item(s) selected in a control.",inactiveborder:"Inactive window border.",inactivecaption:"Inactive window caption.",inactivecaptiontext:"Color of text in an inactive caption.",infobackground:"Background color for tooltip controls.",infotext:"Text color for tooltip controls.",menu:"Menu background.",menutext:"Text in menus.",scrollbar:"Scroll bar gray area.",threeddarkshadow:"The color of the darker (generally outer) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",threedface:"The face background color for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",threedhighlight:"The color of the lighter (generally outer) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",threedlightshadow:"The color of the darker (generally inner) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",threedshadow:"The color of the lighter (generally inner) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",window:"Window background.",windowframe:"Window frame.",windowtext:"Text in windows."};Combinator.prototype=new SyntaxUnit,Combinator.prototype.constructor=Combinator,MediaFeature.prototype=new SyntaxUnit,MediaFeature.prototype.constructor=MediaFeature,MediaQuery.prototype=new SyntaxUnit,MediaQuery.prototype.constructor=MediaQuery,Parser.DEFAULT_TYPE=0,Parser.COMBINATOR_TYPE=1,Parser.MEDIA_FEATURE_TYPE=2,Parser.MEDIA_QUERY_TYPE=3,Parser.PROPERTY_NAME_TYPE=4,Parser.PROPERTY_VALUE_TYPE=5,Parser.PROPERTY_VALUE_PART_TYPE=6,Parser.SELECTOR_TYPE=7,Parser.SELECTOR_PART_TYPE=8,Parser.SELECTOR_SUB_PART_TYPE=9,Parser.prototype=function(){var e=new EventTarget,t,n={constructor:Parser,DEFAULT_TYPE:0,COMBINATOR_TYPE:1,MEDIA_FEATURE_TYPE:2,MEDIA_QUERY_TYPE:3,PROPERTY_NAME_TYPE:4,PROPERTY_VALUE_TYPE:5,PROPERTY_VALUE_PART_TYPE:6,SELECTOR_TYPE:7,SELECTOR_PART_TYPE:8,SELECTOR_SUB_PART_TYPE:9,_stylesheet:function(){var e=this._tokenStream,t=null,n,r,i;this.fire("startstylesheet"),this._charset(),this._skipCruft();while(e.peek()==Tokens.IMPORT_SYM)this._import(),this._skipCruft();while(e.peek()==Tokens.NAMESPACE_SYM)this._namespace(),this._skipCruft();i=e.peek();while(i>Tokens.EOF){try{switch(i){case Tokens.MEDIA_SYM:this._media(),this._skipCruft();break;case Tokens.PAGE_SYM:this._page(),this._skipCruft();break;case Tokens.FONT_FACE_SYM:this._font_face(),this._skipCruft();break;case Tokens.KEYFRAMES_SYM:this._keyframes(),this._skipCruft();break;case Tokens.VIEWPORT_SYM:this._viewport(),this._skipCruft();break;case Tokens.UNKNOWN_SYM:e.get();if(!!this.options.strict)throw new SyntaxError("Unknown @ rule.",e.LT(0).startLine,e.LT(0).startCol);this.fire({type:"error",error:null,message:"Unknown @ rule: "+e.LT(0).value+".",line:e.LT(0).startLine,col:e.LT(0).startCol}),n=0;while(e.advance([Tokens.LBRACE,Tokens.RBRACE])==Tokens.LBRACE)n++;while(n)e.advance([Tokens.RBRACE]),n--;break;case Tokens.S:this._readWhitespace();break;default:if(!this._ruleset())switch(i){case Tokens.CHARSET_SYM:throw r=e.LT(1),this._charset(!1),new SyntaxError("@charset not allowed here.",r.startLine,r.startCol);case Tokens.IMPORT_SYM:throw r=e.LT(1),this._import(!1),new SyntaxError("@import not allowed here.",r.startLine,r.startCol);case Tokens.NAMESPACE_SYM:throw r=e.LT(1),this._namespace(!1),new SyntaxError("@namespace not allowed here.",r.startLine,r.startCol);default:e.get(),this._unexpectedToken(e.token())}}}catch(s){if(!(s instanceof SyntaxError&&!this.options.strict))throw s;this.fire({type:"error",error:s,message:s.message,line:s.line,col:s.col})}i=e.peek()}i!=Tokens.EOF&&this._unexpectedToken(e.token()),this.fire("endstylesheet")},_charset:function(e){var t=this._tokenStream,n,r,i,s;t.match(Tokens.CHARSET_SYM)&&(i=t.token().startLine,s=t.token().startCol,this._readWhitespace(),t.mustMatch(Tokens.STRING),r=t.token(),n=r.value,this._readWhitespace(),t.mustMatch(Tokens.SEMICOLON),e!==!1&&this.fire({type:"charset",charset:n,line:i,col:s}))},_import:function(e){var t=this._tokenStream,n,r,i,s=[];t.mustMatch(Tokens.IMPORT_SYM),i=t.token(),this._readWhitespace(),t.mustMatch([Tokens.STRING,Tokens.URI]),r=t.token().value.replace(/^(?:url\()?["']?([^"']+?)["']?\)?$/,"$1"),this._readWhitespace(),s=this._media_query_list(),t.mustMatch(Tokens.SEMICOLON),this._readWhitespace(),e!==!1&&this.fire({type:"import",uri:r,media:s,line:i.startLine,col:i.startCol})},_namespace:function(e){var t=this._tokenStream,n,r,i,s;t.mustMatch(Tokens.NAMESPACE_SYM),n=t.token().startLine,r=t.token().startCol,this._readWhitespace(),t.match(Tokens.IDENT)&&(i=t.token().value,this._readWhitespace()),t.mustMatch([Tokens.STRING,Tokens.URI]),s=t.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/,"$1"),this._readWhitespace(),t.mustMatch(Tokens.SEMICOLON),this._readWhitespace(),e!==!1&&this.fire({type:"namespace",prefix:i,uri:s,line:n,col:r})},_media:function(){var e=this._tokenStream,t,n,r;e.mustMatch(Tokens.MEDIA_SYM),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),r=this._media_query_list(),e.mustMatch(Tokens.LBRACE),this._readWhitespace(),this.fire({type:"startmedia",media:r,line:t,col:n});for(;;)if(e.peek()==Tokens.PAGE_SYM)this._page();else if(e.peek()==Tokens.FONT_FACE_SYM)this._font_face();else if(e.peek()==Tokens.VIEWPORT_SYM)this._viewport();else if(!this._ruleset())break;e.mustMatch(Tokens.RBRACE),this._readWhitespace(),this.fire({type:"endmedia",media:r,line:t,col:n})},_media_query_list:function(){var e=this._tokenStream,t=[];this._readWhitespace(),(e.peek()==Tokens.IDENT||e.peek()==Tokens.LPAREN)&&t.push(this._media_query());while(e.match(Tokens.COMMA))this._readWhitespace(),t.push(this._media_query());return t},_media_query:function(){var e=this._tokenStream,t=null,n=null,r=null,i=[];e.match(Tokens.IDENT)&&(n=e.token().value.toLowerCase(),n!="only"&&n!="not"?(e.unget(),n=null):r=e.token()),this._readWhitespace(),e.peek()==Tokens.IDENT?(t=this._media_type(),r===null&&(r=e.token())):e.peek()==Tokens.LPAREN&&(r===null&&(r=e.LT(1)),i.push(this._media_expression()));if(t===null&&i.length===0)return null;this._readWhitespace();while(e.match(Tokens.IDENT))e.token().value.toLowerCase()!="and"&&this._unexpectedToken(e.token()),this._readWhitespace(),i.push(this._media_expression());return new MediaQuery(n,t,i,r.startLine,r.startCol)},_media_type:function(){return this._media_feature()},_media_expression:function(){var e=this._tokenStream,t=null,n,r=null;return e.mustMatch(Tokens.LPAREN),this._readWhitespace(),t=this._media_feature(),this._readWhitespace(),e.match(Tokens.COLON)&&(this._readWhitespace(),n=e.LT(1),r=this._expression()),e.mustMatch(Tokens.RPAREN),this._readWhitespace(),new MediaFeature(t,r?new SyntaxUnit(r,n.startLine,n.startCol):null)},_media_feature:function(){var e=this._tokenStream;return e.mustMatch(Tokens.IDENT),SyntaxUnit.fromToken(e.token())},_page:function(){var e=this._tokenStream,t,n,r=null,i=null;e.mustMatch(Tokens.PAGE_SYM),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),e.match(Tokens.IDENT)&&(r=e.token().value,r.toLowerCase()==="auto"&&this._unexpectedToken(e.token())),e.peek()==Tokens.COLON&&(i=this._pseudo_page()),this._readWhitespace(),this.fire({type:"startpage",id:r,pseudo:i,line:t,col:n}),this._readDeclarations(!0,!0),this.fire({type:"endpage",id:r,pseudo:i,line:t,col:n})},_margin:function(){var e=this._tokenStream,t,n,r=this._margin_sym();return r?(t=e.token().startLine,n=e.token().startCol,this.fire({type:"startpagemargin",margin:r,line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endpagemargin",margin:r,line:t,col:n}),!0):!1},_margin_sym:function(){var e=this._tokenStream;return e.match([Tokens.TOPLEFTCORNER_SYM,Tokens.TOPLEFT_SYM,Tokens.TOPCENTER_SYM,Tokens.TOPRIGHT_SYM,Tokens.TOPRIGHTCORNER_SYM,Tokens.BOTTOMLEFTCORNER_SYM,Tokens.BOTTOMLEFT_SYM,Tokens.BOTTOMCENTER_SYM,Tokens.BOTTOMRIGHT_SYM,Tokens.BOTTOMRIGHTCORNER_SYM,Tokens.LEFTTOP_SYM,Tokens.LEFTMIDDLE_SYM,Tokens.LEFTBOTTOM_SYM,Tokens.RIGHTTOP_SYM,Tokens.RIGHTMIDDLE_SYM,Tokens.RIGHTBOTTOM_SYM])?SyntaxUnit.fromToken(e.token()):null},_pseudo_page:function(){var e=this._tokenStream;return e.mustMatch(Tokens.COLON),e.mustMatch(Tokens.IDENT),e.token().value},_font_face:function(){var e=this._tokenStream,t,n;e.mustMatch(Tokens.FONT_FACE_SYM),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),this.fire({type:"startfontface",line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endfontface",line:t,col:n})},_viewport:function(){var e=this._tokenStream,t,n;e.mustMatch(Tokens.VIEWPORT_SYM),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),this.fire({type:"startviewport",line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endviewport",line:t,col:n})},_operator:function(e){var t=this._tokenStream,n=null;if(t.match([Tokens.SLASH,Tokens.COMMA])||e&&t.match([Tokens.PLUS,Tokens.STAR,Tokens.MINUS]))n=t.token(),this._readWhitespace();return n?PropertyValuePart.fromToken(n):null},_combinator:function(){var e=this._tokenStream,t=null,n;return e.match([Tokens.PLUS,Tokens.GREATER,Tokens.TILDE])&&(n=e.token(),t=new Combinator(n.value,n.startLine,n.startCol),this._readWhitespace()),t},_unary_operator:function(){var e=this._tokenStream;return e.match([Tokens.MINUS,Tokens.PLUS])?e.token().value:null},_property:function(){var e=this._tokenStream,t=null,n=null,r,i,s,o;return e.peek()==Tokens.STAR&&this.options.starHack&&(e.get(),i=e.token(),n=i.value,s=i.startLine,o=i.startCol),e.match(Tokens.IDENT)&&(i=e.token(),r=i.value,r.charAt(0)=="_"&&this.options.underscoreHack&&(n="_",r=r.substring(1)),t=new PropertyName(r,n,s||i.startLine,o||i.startCol),this._readWhitespace()),t},_ruleset:function(){var e=this._tokenStream,t,n;try{n=this._selectors_group()}catch(r){if(r instanceof SyntaxError&&!this.options.strict){this.fire({type:"error",error:r,message:r.message,line:r.line,col:r.col}),t=e.advance([Tokens.RBRACE]);if(t!=Tokens.RBRACE)throw r;return!0}throw r}return n&&(this.fire({type:"startrule",selectors:n,line:n[0].line,col:n[0].col}),this._readDeclarations(!0),this.fire({type:"endrule",selectors:n,line:n[0].line,col:n[0].col})),n},_selectors_group:function(){var e=this._tokenStream,t=[],n;n=this._selector();if(n!==null){t.push(n);while(e.match(Tokens.COMMA))this._readWhitespace(),n=this._selector(),n!==null?t.push(n):this._unexpectedToken(e.LT(1))}return t.length?t:null},_selector:function(){var e=this._tokenStream,t=[],n=null,r=null,i=null;n=this._simple_selector_sequence();if(n===null)return null;t.push(n);do{r=this._combinator();if(r!==null)t.push(r),n=this._simple_selector_sequence(),n===null?this._unexpectedToken(e.LT(1)):t.push(n);else{if(!this._readWhitespace())break;i=new Combinator(e.token().value,e.token().startLine,e.token().startCol),r=this._combinator(),n=this._simple_selector_sequence(),n===null?r!==null&&this._unexpectedToken(e.LT(1)):(r!==null?t.push(r):t.push(i),t.push(n))}}while(!0);return new Selector(t,t[0].line,t[0].col)},_simple_selector_sequence:function(){var e=this._tokenStream,t=null,n=[],r="",i=[function(){return e.match(Tokens.HASH)?new SelectorSubPart(e.token().value,"id",e.token().startLine,e.token().startCol):null},this._class,this._attrib,this._pseudo,this._negation],s=0,o=i.length,u=null,a=!1,f,l;f=e.LT(1).startLine,l=e.LT(1).startCol,t=this._type_selector(),t||(t=this._universal()),t!==null&&(r+=t);for(;;){if(e.peek()===Tokens.S)break;while(s<o&&u===null)u=i[s++].call(this);if(u===null){if(r==="")return null;break}s=0,n.push(u),r+=u.toString(),u=null}return r!==""?new SelectorPart(t,n,r,f,l):null},_type_selector:function(){var e=this._tokenStream,t=this._namespace_prefix(),n=this._element_name();return n?(t&&(n.text=t+n.text,n.col-=t.length),n):(t&&(e.unget(),t.length>1&&e.unget()),null)},_class:function(){var e=this._tokenStream,t;return e.match(Tokens.DOT)?(e.mustMatch(Tokens.IDENT),t=e.token(),new SelectorSubPart("."+t.value,"class",t.startLine,t.startCol-1)):null},_element_name:function(){var e=this._tokenStream,t;return e.match(Tokens.IDENT)?(t=e.token(),new SelectorSubPart(t.value,"elementName",t.startLine,t.startCol)):null},_namespace_prefix:function(){var e=this._tokenStream,t="";if(e.LA(1)===Tokens.PIPE||e.LA(2)===Tokens.PIPE)e.match([Tokens.IDENT,Tokens.STAR])&&(t+=e.token().value),e.mustMatch(Tokens.PIPE),t+="|";return t.length?t:null},_universal:function(){var e=this._tokenStream,t="",n;return n=this._namespace_prefix(),n&&(t+=n),e.match(Tokens.STAR)&&(t+="*"),t.length?t:null},_attrib:function(){var e=this._tokenStream,t=null,n,r;return e.match(Tokens.LBRACKET)?(r=e.token(),t=r.value,t+=this._readWhitespace(),n=this._namespace_prefix(),n&&(t+=n),e.mustMatch(Tokens.IDENT),t+=e.token().value,t+=this._readWhitespace(),e.match([Tokens.PREFIXMATCH,Tokens.SUFFIXMATCH,Tokens.SUBSTRINGMATCH,Tokens.EQUALS,Tokens.INCLUDES,Tokens.DASHMATCH])&&(t+=e.token().value,t+=this._readWhitespace(),e.mustMatch([Tokens.IDENT,Tokens.STRING]),t+=e.token().value,t+=this._readWhitespace()),e.mustMatch(Tokens.RBRACKET),new SelectorSubPart(t+"]","attribute",r.startLine,r.startCol)):null},_pseudo:function(){var e=this._tokenStream,t=null,n=":",r,i;return e.match(Tokens.COLON)&&(e.match(Tokens.COLON)&&(n+=":"),e.match(Tokens.IDENT)?(t=e.token().value,r=e.token().startLine,i=e.token().startCol-n.length):e.peek()==Tokens.FUNCTION&&(r=e.LT(1).startLine,i=e.LT(1).startCol-n.length,t=this._functional_pseudo()),t&&(t=new SelectorSubPart(n+t,"pseudo",r,i))),t},_functional_pseudo:function(){var e=this._tokenStream,t=null;return e.match(Tokens.FUNCTION)&&(t=e.token().value,t+=this._readWhitespace(),t+=this._expression(),e.mustMatch(Tokens.RPAREN),t+=")"),t},_expression:function(){var e=this._tokenStream,t="";while(e.match([Tokens.PLUS,Tokens.MINUS,Tokens.DIMENSION,Tokens.NUMBER,Tokens.STRING,Tokens.IDENT,Tokens.LENGTH,Tokens.FREQ,Tokens.ANGLE,Tokens.TIME,Tokens.RESOLUTION,Tokens.SLASH]))t+=e.token().value,t+=this._readWhitespace();return t.length?t:null},_negation:function(){var e=this._tokenStream,t,n,r="",i,s=null;return e.match(Tokens.NOT)&&(r=e.token().value,t=e.token().startLine,n=e.token().startCol,r+=this._readWhitespace(),i=this._negation_arg(),r+=i,r+=this._readWhitespace(),e.match(Tokens.RPAREN),r+=e.token().value,s=new SelectorSubPart(r,"not",t,n),s.args.push(i)),s},_negation_arg:function(){var e=this._tokenStream,t=[this._type_selector,this._universal,function(){return e.match(Tokens.HASH)?new SelectorSubPart(e.token().value,"id",e.token().startLine,e.token().startCol):null},this._class,this._attrib,this._pseudo],n=null,r=0,i=t.length,s,o,u,a;o=e.LT(1).startLine,u=e.LT(1).startCol;while(r<i&&n===null)n=t[r].call(this),r++;return n===null&&this._unexpectedToken(e.LT(1)),n.type=="elementName"?a=new SelectorPart(n,[],n.toString(),o,u):a=new SelectorPart(null,[n],n.toString(),o,u),a},_declaration:function(){var e=this._tokenStream,t=null,n=null,r=null,i=null,s=null,o="";t=this._property();if(t!==null){e.mustMatch(Tokens.COLON),this._readWhitespace(),n=this._expr(),(!n||n.length===0)&&this._unexpectedToken(e.LT(1)),r=this._prio(),o=t.toString();if(this.options.starHack&&t.hack=="*"||this.options.underscoreHack&&t.hack=="_")o=t.text;try{this._validateProperty(o,n)}catch(u){s=u}return this.fire({type:"property",property:t,value:n,important:r,line:t.line,col:t.col,invalid:s}),!0}return!1},_prio:function(){var e=this._tokenStream,t=e.match(Tokens.IMPORTANT_SYM);return this._readWhitespace(),t},_expr:function(e){var t=this._tokenStream,n=[],r=null,i=null;r=this._term(e);if(r!==null){n.push(r);do{i=this._operator(e),i&&n.push(i),r=this._term(e);if(r===null)break;n.push(r)}while(!0)}return n.length>0?new PropertyValue(n,n[0].line,n[0].col):null},_term:function(e){var t=this._tokenStream,n=null,r=null,i=null,s,o,u;return n=this._unary_operator(),n!==null&&(o=t.token().startLine,u=t.token().startCol),t.peek()==Tokens.IE_FUNCTION&&this.options.ieFilters?(r=this._ie_function(),n===null&&(o=t.token().startLine,u=t.token().startCol)):e&&t.match([Tokens.LPAREN,Tokens.LBRACE,Tokens.LBRACKET])?(s=t.token(),i=s.endChar,r=s.value+this._expr(e).text,n===null&&(o=t.token().startLine,u=t.token().startCol),t.mustMatch(Tokens.type(i)),r+=i,this._readWhitespace()):t.match([Tokens.NUMBER,Tokens.PERCENTAGE,Tokens.LENGTH,Tokens.ANGLE,Tokens.TIME,Tokens.FREQ,Tokens.STRING,Tokens.IDENT,Tokens.URI,Tokens.UNICODE_RANGE])?(r=t.token().value,n===null&&(o=t.token().startLine,u=t.token().startCol),this._readWhitespace()):(s=this._hexcolor(),s===null?(n===null&&(o=t.LT(1).startLine,u=t.LT(1).startCol),r===null&&(t.LA(3)==Tokens.EQUALS&&this.options.ieFilters?r=this._ie_function():r=this._function())):(r=s.value,n===null&&(o=s.startLine,u=s.startCol))),r!==null?new PropertyValuePart(n!==null?n+r:r,o,u):null},_function:function(){var e=this._tokenStream,t=null,n=null,r;if(e.match(Tokens.FUNCTION)){t=e.token().value,this._readWhitespace(),n=this._expr(!0),t+=n;if(this.options.ieFilters&&e.peek()==Tokens.EQUALS)do{this._readWhitespace()&&(t+=e.token().value),e.LA(0)==Tokens.COMMA&&(t+=e.token().value),e.match(Tokens.IDENT),t+=e.token().value,e.match(Tokens.EQUALS),t+=e.token().value,r=e.peek();while(r!=Tokens.COMMA&&r!=Tokens.S&&r!=Tokens.RPAREN)e.get(),t+=e.token().value,r=e.peek()}while(e.match([Tokens.COMMA,Tokens.S]));e.match(Tokens.RPAREN),t+=")",this._readWhitespace()}return t},_ie_function:function(){var e=this._tokenStream,t=null,n=null,r;if(e.match([Tokens.IE_FUNCTION,Tokens.FUNCTION])){t=e.token().value;do{this._readWhitespace()&&(t+=e.token().value),e.LA(0)==Tokens.COMMA&&(t+=e.token().value),e.match(Tokens.IDENT),t+=e.token().value,e.match(Tokens.EQUALS),t+=e.token().value,r=e.peek();while(r!=Tokens.COMMA&&r!=Tokens.S&&r!=Tokens.RPAREN)e.get(),t+=e.token().value,r=e.peek()}while(e.match([Tokens.COMMA,Tokens.S]));e.match(Tokens.RPAREN),t+=")",this._readWhitespace()}return t},_hexcolor:function(){var e=this._tokenStream,t=null,n;if(e.match(Tokens.HASH)){t=e.token(),n=t.value;if(!/#[a-f0-9]{3,6}/i.test(n))throw new SyntaxError("Expected a hex color but found '"+n+"' at line "+t.startLine+", col "+t.startCol+".",t.startLine,t.startCol);this._readWhitespace()}return t},_keyframes:function(){var e=this._tokenStream,t,n,r,i="";e.mustMatch(Tokens.KEYFRAMES_SYM),t=e.token(),/^@\-([^\-]+)\-/.test(t.value)&&(i=RegExp.$1),this._readWhitespace(),r=this._keyframe_name(),this._readWhitespace(),e.mustMatch(Tokens.LBRACE),this.fire({type:"startkeyframes",name:r,prefix:i,line:t.startLine,col:t.startCol}),this._readWhitespace(),n=e.peek();while(n==Tokens.IDENT||n==Tokens.PERCENTAGE)this._keyframe_rule(),this._readWhitespace(),n=e.peek();this.fire({type:"endkeyframes",name:r,prefix:i,line:t.startLine,col:t.startCol}),this._readWhitespace(),e.mustMatch(Tokens.RBRACE)},_keyframe_name:function(){var e=this._tokenStream,t;return e.mustMatch([Tokens.IDENT,Tokens.STRING]),SyntaxUnit.fromToken(e.token())},_keyframe_rule:function(){var e=this._tokenStream,t,n=this._key_list();this.fire({type:"startkeyframerule",keys:n,line:n[0].line,col:n[0].col}),this._readDeclarations(!0),this.fire({type:"endkeyframerule",keys:n,line:n[0].line,col:n[0].col})},_key_list:function(){var e=this._tokenStream,t,n,r=[];r.push(this._key()),this._readWhitespace();while(e.match(Tokens.COMMA))this._readWhitespace(),r.push(this._key()),this._readWhitespace();return r},_key:function(){var e=this._tokenStream,t;if(e.match(Tokens.PERCENTAGE))return SyntaxUnit.fromToken(e.token());if(e.match(Tokens.IDENT)){t=e.token();if(/from|to/i.test(t.value))return SyntaxUnit.fromToken(t);e.unget()}this._unexpectedToken(e.LT(1))},_skipCruft:function(){while(this._tokenStream.match([Tokens.S,Tokens.CDO,Tokens.CDC]));},_readDeclarations:function(e,t){var n=this._tokenStream,r;this._readWhitespace(),e&&n.mustMatch(Tokens.LBRACE),this._readWhitespace();try{for(;;){if(!(n.match(Tokens.SEMICOLON)||t&&this._margin())){if(!this._declaration())break;if(!n.match(Tokens.SEMICOLON))break}this._readWhitespace()}n.mustMatch(Tokens.RBRACE),this._readWhitespace()}catch(i){if(!(i instanceof SyntaxError&&!this.options.strict))throw i;this.fire({type:"error",error:i,message:i.message,line:i.line,col:i.col}),r=n.advance([Tokens.SEMICOLON,Tokens.RBRACE]);if(r==Tokens.SEMICOLON)this._readDeclarations(!1,t);else if(r!=Tokens.RBRACE)throw i}},_readWhitespace:function(){var e=this._tokenStream,t="";while(e.match(Tokens.S))t+=e.token().value;return t},_unexpectedToken:function(e){throw new SyntaxError("Unexpected token '"+e.value+"' at line "+e.startLine+", col "+e.startCol+".",e.startLine,e.startCol)},_verifyEnd:function(){this._tokenStream.LA(1)!=Tokens.EOF&&this._unexpectedToken(this._tokenStream.LT(1))},_validateProperty:function(e,t){Validation.validate(e,t)},parse:function(e){this._tokenStream=new TokenStream(e,Tokens),this._stylesheet()},parseStyleSheet:function(e){return this.parse(e)},parseMediaQuery:function(e){this._tokenStream=new TokenStream(e,Tokens);var t=this._media_query();return this._verifyEnd(),t},parsePropertyValue:function(e){this._tokenStream=new TokenStream(e,Tokens),this._readWhitespace();var t=this._expr();return this._readWhitespace(),this._verifyEnd(),t},parseRule:function(e){this._tokenStream=new TokenStream(e,Tokens),this._readWhitespace();var t=this._ruleset();return this._readWhitespace(),this._verifyEnd(),t},parseSelector:function(e){this._tokenStream=new TokenStream(e,Tokens),this._readWhitespace();var t=this._selector();return this._readWhitespace(),this._verifyEnd(),t},parseStyleAttribute:function(e){e+="}",this._tokenStream=new TokenStream(e,Tokens),this._readDeclarations()}};for(t in n)n.hasOwnProperty(t)&&(e[t]=n[t]);return e}();var Properties={"align-items":"flex-start | flex-end | center | baseline | stretch","align-content":"flex-start | flex-end | center | space-between | space-around | stretch","align-self":"auto | flex-start | flex-end | center | baseline | stretch","-webkit-align-items":"flex-start | flex-end | center | baseline | stretch","-webkit-align-content":"flex-start | flex-end | center | space-between | space-around | stretch","-webkit-align-self":"auto | flex-start | flex-end | center | baseline | stretch","alignment-adjust":"auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | <percentage> | <length>","alignment-baseline":"baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical",animation:1,"animation-delay":{multi:"<time>",comma:!0},"animation-direction":{multi:"normal | reverse | alternate | alternate-reverse",comma:!0},"animation-duration":{multi:"<time>",comma:!0},"animation-fill-mode":{multi:"none | forwards | backwards | both",comma:!0},"animation-iteration-count":{multi:"<number> | infinite",comma:!0},"animation-name":{multi:"none | <ident>",comma:!0},"animation-play-state":{multi:"running | paused",comma:!0},"animation-timing-function":1,"-moz-animation-delay":{multi:"<time>",comma:!0},"-moz-animation-direction":{multi:"normal | reverse | alternate | alternate-reverse",comma:!0},"-moz-animation-duration":{multi:"<time>",comma:!0},"-moz-animation-iteration-count":{multi:"<number> | infinite",comma:!0},"-moz-animation-name":{multi:"none | <ident>",comma:!0},"-moz-animation-play-state":{multi:"running | paused",comma:!0},"-ms-animation-delay":{multi:"<time>",comma:!0},"-ms-animation-direction":{multi:"normal | reverse | alternate | alternate-reverse",comma:!0},"-ms-animation-duration":{multi:"<time>",comma:!0},"-ms-animation-iteration-count":{multi:"<number> | infinite",comma:!0},"-ms-animation-name":{multi:"none | <ident>",comma:!0},"-ms-animation-play-state":{multi:"running | paused",comma:!0},"-webkit-animation-delay":{multi:"<time>",comma:!0},"-webkit-animation-direction":{multi:"normal | reverse | alternate | alternate-reverse",comma:!0},"-webkit-animation-duration":{multi:"<time>",comma:!0},"-webkit-animation-fill-mode":{multi:"none | forwards | backwards | both",comma:!0},"-webkit-animation-iteration-count":{multi:"<number> | infinite",comma:!0},"-webkit-animation-name":{multi:"none | <ident>",comma:!0},"-webkit-animation-play-state":{multi:"running | paused",comma:!0},"-o-animation-delay":{multi:"<time>",comma:!0},"-o-animation-direction":{multi:"normal | reverse | alternate | alternate-reverse",comma:!0},"-o-animation-duration":{multi:"<time>",comma:!0},"-o-animation-iteration-count":{multi:"<number> | infinite",comma:!0},"-o-animation-name":{multi:"none | <ident>",comma:!0},"-o-animation-play-state":{multi:"running | paused",comma:!0},appearance:"icon | window | desktop | workspace | document | tooltip | dialog | button | push-button | hyperlink | radio-button | checkbox | menu-item | tab | menu | menubar | pull-down-menu | pop-up-menu | list-menu | radio-group | checkbox-group | outline-tree | range | field | combo-box | signature | password | normal | none | inherit",azimuth:function(e){var t="<angle> | leftwards | rightwards | inherit",n="left-side | far-left | left | center-left | center | center-right | right | far-right | right-side",r=!1,i=!1,s;ValidationTypes.isAny(e,t)||(ValidationTypes.isAny(e,"behind")&&(r=!0,i=!0),ValidationTypes.isAny(e,n)&&(i=!0,r||ValidationTypes.isAny(e,"behind")));if(e.hasNext())throw s=e.next(),i?new ValidationError("Expected end of value but found '"+s+"'.",s.line,s.col):new ValidationError("Expected (<'azimuth'>) but found '"+s+"'.",s.line,s.col)},"backface-visibility":"visible | hidden",background:1,"background-attachment":{multi:"<attachment>",comma:!0},"background-clip":{multi:"<box>",comma:!0},"background-color":"<color> | inherit","background-image":{multi:"<bg-image>",comma:!0},"background-origin":{multi:"<box>",comma:!0},"background-position":{multi:"<bg-position>",comma:!0},"background-repeat":{multi:"<repeat-style>"},"background-size":{multi:"<bg-size>",comma:!0},"baseline-shift":"baseline | sub | super | <percentage> | <length>",behavior:1,binding:1,bleed:"<length>","bookmark-label":"<content> | <attr> | <string>","bookmark-level":"none | <integer>","bookmark-state":"open | closed","bookmark-target":"none | <uri> | <attr>",border:"<border-width> || <border-style> || <color>","border-bottom":"<border-width> || <border-style> || <color>","border-bottom-color":"<color> | inherit","border-bottom-left-radius":"<x-one-radius>","border-bottom-right-radius":"<x-one-radius>","border-bottom-style":"<border-style>","border-bottom-width":"<border-width>","border-collapse":"collapse | separate | inherit","border-color":{multi:"<color> | inherit",max:4},"border-image":1,"border-image-outset":{multi:"<length> | <number>",max:4},"border-image-repeat":{multi:"stretch | repeat | round",max:2},"border-image-slice":function(e){var t=!1,n="<number> | <percentage>",r=!1,i=0,s=4,o;ValidationTypes.isAny(e,"fill")&&(r=!0,t=!0);while(e.hasNext()&&i<s){t=ValidationTypes.isAny(e,n);if(!t)break;i++}r?t=!0:ValidationTypes.isAny(e,"fill");if(e.hasNext())throw o=e.next(),t?new ValidationError("Expected end of value but found '"+o+"'.",o.line,o.col):new ValidationError("Expected ([<number> | <percentage>]{1,4} && fill?) but found '"+o+"'.",o.line,o.col)},"border-image-source":"<image> | none","border-image-width":{multi:"<length> | <percentage> | <number> | auto",max:4},"border-left":"<border-width> || <border-style> || <color>","border-left-color":"<color> | inherit","border-left-style":"<border-style>","border-left-width":"<border-width>","border-radius":function(e){var t=!1,n="<length> | <percentage> | inherit",r=!1,i=!1,s=0,o=8,u;while(e.hasNext()&&s<o){t=ValidationTypes.isAny(e,n);if(!t){if(!(e.peek()=="/"&&s>0&&!r))break;r=!0,o=s+5,e.next()}s++}if(e.hasNext())throw u=e.next(),t?new ValidationError("Expected end of value but found '"+u+"'.",u.line,u.col):new ValidationError("Expected (<'border-radius'>) but found '"+u+"'.",u.line,u.col)},"border-right":"<border-width> || <border-style> || <color>","border-right-color":"<color> | inherit","border-right-style":"<border-style>","border-right-width":"<border-width>","border-spacing":{multi:"<length> | inherit",max:2},"border-style":{multi:"<border-style>",max:4},"border-top":"<border-width> || <border-style> || <color>","border-top-color":"<color> | inherit","border-top-left-radius":"<x-one-radius>","border-top-right-radius":"<x-one-radius>","border-top-style":"<border-style>","border-top-width":"<border-width>","border-width":{multi:"<border-width>",max:4},bottom:"<margin-width> | inherit","-moz-box-align":"start | end | center | baseline | stretch","-moz-box-decoration-break":"slice |clone","-moz-box-direction":"normal | reverse | inherit","-moz-box-flex":"<number>","-moz-box-flex-group":"<integer>","-moz-box-lines":"single | multiple","-moz-box-ordinal-group":"<integer>","-moz-box-orient":"horizontal | vertical | inline-axis | block-axis | inherit","-moz-box-pack":"start | end | center | justify","-webkit-box-align":"start | end | center | baseline | stretch","-webkit-box-decoration-break":"slice |clone","-webkit-box-direction":"normal | reverse | inherit","-webkit-box-flex":"<number>","-webkit-box-flex-group":"<integer>","-webkit-box-lines":"single | multiple","-webkit-box-ordinal-group":"<integer>","-webkit-box-orient":"horizontal | vertical | inline-axis | block-axis | inherit","-webkit-box-pack":"start | end | center | justify","box-shadow":function(e){var t=!1,n;if(!ValidationTypes.isAny(e,"none"))Validation.multiProperty("<shadow>",e,!0,Infinity);else if(e.hasNext())throw n=e.next(),new ValidationError("Expected end of value but found '"+n+"'.",n.line,n.col)},"box-sizing":"content-box | border-box | inherit","break-after":"auto | always | avoid | left | right | page | column | avoid-page | avoid-column","break-before":"auto | always | avoid | left | right | page | column | avoid-page | avoid-column","break-inside":"auto | avoid | avoid-page | avoid-column","caption-side":"top | bottom | inherit",clear:"none | right | left | both | inherit",clip:1,color:"<color> | inherit","color-profile":1,"column-count":"<integer> | auto","column-fill":"auto | balance","column-gap":"<length> | normal","column-rule":"<border-width> || <border-style> || <color>","column-rule-color":"<color>","column-rule-style":"<border-style>","column-rule-width":"<border-width>","column-span":"none | all","column-width":"<length> | auto",columns:1,content:1,"counter-increment":1,"counter-reset":1,crop:"<shape> | auto",cue:"cue-after | cue-before | inherit","cue-after":1,"cue-before":1,cursor:1,direction:"ltr | rtl | inherit",display:"inline | block | list-item | inline-block | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | grid | inline-grid | none | inherit | -moz-box | -moz-inline-block | -moz-inline-box | -moz-inline-grid | -moz-inline-stack | -moz-inline-table | -moz-grid | -moz-grid-group | -moz-grid-line | -moz-groupbox | -moz-deck | -moz-popup | -moz-stack | -moz-marker | -webkit-box | -webkit-inline-box | -ms-flexbox | -ms-inline-flexbox | flex | -webkit-flex | inline-flex | -webkit-inline-flex","dominant-baseline":1,"drop-initial-after-adjust":"central | middle | after-edge | text-after-edge | ideographic | alphabetic | mathematical | <percentage> | <length>","drop-initial-after-align":"baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical","drop-initial-before-adjust":"before-edge | text-before-edge | central | middle | hanging | mathematical | <percentage> | <length>","drop-initial-before-align":"caps-height | baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical","drop-initial-size":"auto | line | <length> | <percentage>","drop-initial-value":"initial | <integer>",elevation:"<angle> | below | level | above | higher | lower | inherit","empty-cells":"show | hide | inherit",filter:1,fit:"fill | hidden | meet | slice","fit-position":1,flex:"<flex>","flex-basis":"<width>","flex-direction":"row | row-reverse | column | column-reverse","flex-flow":"<flex-direction> || <flex-wrap>","flex-grow":"<number>","flex-shrink":"<number>","flex-wrap":"nowrap | wrap | wrap-reverse","-webkit-flex":"<flex>","-webkit-flex-basis":"<width>","-webkit-flex-direction":"row | row-reverse | column | column-reverse","-webkit-flex-flow":"<flex-direction> || <flex-wrap>","-webkit-flex-grow":"<number>","-webkit-flex-shrink":"<number>","-webkit-flex-wrap":"nowrap | wrap | wrap-reverse","-ms-flex":"<flex>","-ms-flex-align":"start | end | center | stretch | baseline","-ms-flex-direction":"row | row-reverse | column | column-reverse | inherit","-ms-flex-order":"<number>","-ms-flex-pack":"start | end | center | justify","-ms-flex-wrap":"nowrap | wrap | wrap-reverse","float":"left | right | none | inherit","float-offset":1,font:1,"font-family":1,"font-size":"<absolute-size> | <relative-size> | <length> | <percentage> | inherit","font-size-adjust":"<number> | none | inherit","font-stretch":"normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded | inherit","font-style":"normal | italic | oblique | inherit","font-variant":"normal | small-caps | inherit","font-weight":"normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit","grid-cell-stacking":"columns | rows | layer","grid-column":1,"grid-columns":1,"grid-column-align":"start | end | center | stretch","grid-column-sizing":1,"grid-column-span":"<integer>","grid-flow":"none | rows | columns","grid-layer":"<integer>","grid-row":1,"grid-rows":1,"grid-row-align":"start | end | center | stretch","grid-row-span":"<integer>","grid-row-sizing":1,"hanging-punctuation":1,height:"<margin-width> | <content-sizing> | inherit","hyphenate-after":"<integer> | auto","hyphenate-before":"<integer> | auto","hyphenate-character":"<string> | auto","hyphenate-lines":"no-limit | <integer>","hyphenate-resource":1,hyphens:"none | manual | auto",icon:1,"image-orientation":"angle | auto","image-rendering":1,"image-resolution":1,"inline-box-align":"initial | last | <integer>","justify-content":"flex-start | flex-end | center | space-between | space-around","-webkit-justify-content":"flex-start | flex-end | center | space-between | space-around",left:"<margin-width> | inherit","letter-spacing":"<length> | normal | inherit","line-height":"<number> | <length> | <percentage> | normal | inherit","line-break":"auto | loose | normal | strict","line-stacking":1,"line-stacking-ruby":"exclude-ruby | include-ruby","line-stacking-shift":"consider-shifts | disregard-shifts","line-stacking-strategy":"inline-line-height | block-line-height | max-height | grid-height","list-style":1,"list-style-image":"<uri> | none | inherit","list-style-position":"inside | outside | inherit","list-style-type":"disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-latin | upper-latin | armenian | georgian | lower-alpha | upper-alpha | none | inherit",margin:{multi:"<margin-width> | inherit",max:4},"margin-bottom":"<margin-width> | inherit","margin-left":"<margin-width> | inherit","margin-right":"<margin-width> | inherit","margin-top":"<margin-width> | inherit",mark:1,"mark-after":1,"mark-before":1,marks:1,"marquee-direction":1,"marquee-play-count":1,"marquee-speed":1,"marquee-style":1,"max-height":"<length> | <percentage> | <content-sizing> | none | inherit","max-width":"<length> | <percentage> | <content-sizing> | none | inherit","max-zoom":"<number> | <percentage> | auto","min-height":"<length> | <percentage> | <content-sizing> | contain-floats | -moz-contain-floats | -webkit-contain-floats | inherit","min-width":"<length> | <percentage> | <content-sizing> | contain-floats | -moz-contain-floats | -webkit-contain-floats | inherit","min-zoom":"<number> | <percentage> | auto","move-to":1,"nav-down":1,"nav-index":1,"nav-left":1,"nav-right":1,"nav-up":1,opacity:"<number> | inherit",order:"<integer>","-webkit-order":"<integer>",orphans:"<integer> | inherit",outline:1,"outline-color":"<color> | invert | inherit","outline-offset":1,"outline-style":"<border-style> | inherit","outline-width":"<border-width> | inherit",overflow:"visible | hidden | scroll | auto | inherit","overflow-style":1,"overflow-wrap":"normal | break-word","overflow-x":1,"overflow-y":1,padding:{multi:"<padding-width> | inherit",max:4},"padding-bottom":"<padding-width> | inherit","padding-left":"<padding-width> | inherit","padding-right":"<padding-width> | inherit","padding-top":"<padding-width> | inherit",page:1,"page-break-after":"auto | always | avoid | left | right | inherit","page-break-before":"auto | always | avoid | left | right | inherit","page-break-inside":"auto | avoid | inherit","page-policy":1,pause:1,"pause-after":1,"pause-before":1,perspective:1,"perspective-origin":1,phonemes:1,pitch:1,"pitch-range":1,"play-during":1,"pointer-events":"auto | none | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all | inherit",position:"static | relative | absolute | fixed | inherit","presentation-level":1,"punctuation-trim":1,quotes:1,"rendering-intent":1,resize:1,rest:1,"rest-after":1,"rest-before":1,richness:1,right:"<margin-width> | inherit",rotation:1,"rotation-point":1,"ruby-align":1,"ruby-overhang":1,"ruby-position":1,"ruby-span":1,size:1,speak:"normal | none | spell-out | inherit","speak-header":"once | always | inherit","speak-numeral":"digits | continuous | inherit","speak-punctuation":"code | none | inherit","speech-rate":1,src:1,stress:1,"string-set":1,"table-layout":"auto | fixed | inherit","tab-size":"<integer> | <length>",target:1,"target-name":1,"target-new":1,"target-position":1,"text-align":"left | right | center | justify | inherit","text-align-last":1,"text-decoration":1,"text-emphasis":1,"text-height":1,"text-indent":"<length> | <percentage> | inherit","text-justify":"auto | none | inter-word | inter-ideograph | inter-cluster | distribute | kashida","text-outline":1,"text-overflow":1,"text-rendering":"auto | optimizeSpeed | optimizeLegibility | geometricPrecision | inherit","text-shadow":1,"text-transform":"capitalize | uppercase | lowercase | none | inherit","text-wrap":"normal | none | avoid",top:"<margin-width> | inherit","-ms-touch-action":"auto | none | pan-x | pan-y","touch-action":"auto | none | pan-x | pan-y",transform:1,"transform-origin":1,"transform-style":1,transition:1,"transition-delay":1,"transition-duration":1,"transition-property":1,"transition-timing-function":1,"unicode-bidi":"normal | embed | isolate | bidi-override | isolate-override | plaintext | inherit","user-modify":"read-only | read-write | write-only | inherit","user-select":"none | text | toggle | element | elements | all | inherit","user-zoom":"zoom | fixed","vertical-align":"auto | use-script | baseline | sub | super | top | text-top | central | middle | bottom | text-bottom | <percentage> | <length>",visibility:"visible | hidden | collapse | inherit","voice-balance":1,"voice-duration":1,"voice-family":1,"voice-pitch":1,"voice-pitch-range":1,"voice-rate":1,"voice-stress":1,"voice-volume":1,volume:1,"white-space":"normal | pre | nowrap | pre-wrap | pre-line | inherit | -pre-wrap | -o-pre-wrap | -moz-pre-wrap | -hp-pre-wrap","white-space-collapse":1,widows:"<integer> | inherit",width:"<length> | <percentage> | <content-sizing> | auto | inherit","word-break":"normal | keep-all | break-all","word-spacing":"<length> | normal | inherit","word-wrap":"normal | break-word","writing-mode":"horizontal-tb | vertical-rl | vertical-lr | lr-tb | rl-tb | tb-rl | bt-rl | tb-lr | bt-lr | lr-bt | rl-bt | lr | rl | tb | inherit","z-index":"<integer> | auto | inherit",zoom:"<number> | <percentage> | normal"};PropertyName.prototype=new SyntaxUnit,PropertyName.prototype.constructor=PropertyName,PropertyName.prototype.toString=function(){return(this.hack?this.hack:"")+this.text},PropertyValue.prototype=new SyntaxUnit,PropertyValue.prototype.constructor=PropertyValue,PropertyValueIterator.prototype.count=function(){return this._parts.length},PropertyValueIterator.prototype.isFirst=function(){return this._i===0},PropertyValueIterator.prototype.hasNext=function(){return this._i<this._parts.length},PropertyValueIterator.prototype.mark=function(){this._marks.push(this._i)},PropertyValueIterator.prototype.peek=function(e){return this.hasNext()?this._parts[this._i+(e||0)]:null},PropertyValueIterator.prototype.next=function(){return this.hasNext()?this._parts[this._i++]:null},PropertyValueIterator.prototype.previous=function(){return this._i>0?this._parts[--this._i]:null},PropertyValueIterator.prototype.restore=function(){this._marks.length&&(this._i=this._marks.pop())},PropertyValuePart.prototype=new SyntaxUnit,PropertyValuePart.prototype.constructor=PropertyValuePart,PropertyValuePart.fromToken=function(e){return new PropertyValuePart(e.value,e.startLine,e.startCol)};var Pseudos={":first-letter":1,":first-line":1,":before":1,":after":1};Pseudos.ELEMENT=1,Pseudos.CLASS=2,Pseudos.isElement=function(e){return e.indexOf("::")===0||Pseudos[e.toLowerCase()]==Pseudos.ELEMENT},Selector.prototype=new SyntaxUnit,Selector.prototype.constructor=Selector,SelectorPart.prototype=new SyntaxUnit,SelectorPart.prototype.constructor=SelectorPart,SelectorSubPart.prototype=new SyntaxUnit,SelectorSubPart.prototype.constructor=SelectorSubPart,Specificity.prototype={constructor:Specificity,compare:function(e){var t=["a","b","c","d"],n,r;for(n=0,r=t.length;n<r;n++){if(this[t[n]]<e[t[n]])return-1;if(this[t[n]]>e[t[n]])return 1}return 0},valueOf:function(){return this.a*1e3+this.b*100+this.c*10+this.d},toString:function(){return this.a+","+this.b+","+this.c+","+this.d}},Specificity.calculate=function(e){function u(e){var t,n,r,a,f=e.elementName?e.elementName.text:"",l;f&&f.charAt(f.length-1)!="*"&&o++;for(t=0,r=e.modifiers.length;t<r;t++){l=e.modifiers[t];switch(l.type){case"class":case"attribute":s++;break;case"id":i++;break;case"pseudo":Pseudos.isElement(l.text)?o++:s++;break;case"not":for(n=0,a=l.args.length;n<a;n++)u(l.args[n])}}}var t,n,r,i=0,s=0,o=0;for(t=0,n=e.parts.length;t<n;t++)r=e.parts[t],r instanceof SelectorPart&&u(r);return new Specificity(0,i,s,o)};var h=/^[0-9a-fA-F]$/,nonascii=/^[\u0080-\uFFFF]$/,nl=/\n|\r\n|\r|\f/;TokenStream.prototype=mix(new TokenStreamBase,{_getToken:function(e){var t,n=this._reader,r=null,i=n.getLine(),s=n.getCol();t=n.read();while(t){switch(t){case"/":n.peek()=="*"?r=this.commentToken(t,i,s):r=this.charToken(t,i,s);break;case"|":case"~":case"^":case"$":case"*":n.peek()=="="?r=this.comparisonToken(t,i,s):r=this.charToken(t,i,s);break;case'"':case"'":r=this.stringToken(t,i,s);break;case"#":isNameChar(n.peek())?r=this.hashToken(t,i,s):r=this.charToken(t,i,s);break;case".":isDigit(n.peek())?r=this.numberToken(t,i,s):r=this.charToken(t,i,s);break;case"-":n.peek()=="-"?r=this.htmlCommentEndToken(t,i,s):isNameStart(n.peek())?r=this.identOrFunctionToken(t,i,s):r=this.charToken(t,i,s);break;case"!":r=this.importantToken(t,i,s);break;case"@":r=this.atRuleToken(t,i,s);break;case":":r=this.notToken(t,i,s);break;case"<":r=this.htmlCommentStartToken(t,i,s);break;case"U":case"u":if(n.peek()=="+"){r=this.unicodeRangeToken(t,i,s);break};default:isDigit(t)?r=this.numberToken(t,i,s):isWhitespace(t)?r=this.whitespaceToken(t,i,s):isIdentStart(t)?r=this.identOrFunctionToken(t,i,s):r=this.charToken(t,i,s)}break}return!r&&t===null&&(r=this.createToken(Tokens.EOF,null,i,s)),r},createToken:function(e,t,n,r,i){var s=this._reader;return i=i||{},{value:t,type:e,channel:i.channel,endChar:i.endChar,hide:i.hide||!1,startLine:n,startCol:r,endLine:s.getLine(),endCol:s.getCol()}},atRuleToken:function(e,t,n){var r=e,i=this._reader,s=Tokens.CHAR,o=!1,u,a;i.mark(),u=this.readName(),r=e+u,s=Tokens.type(r.toLowerCase());if(s==Tokens.CHAR||s==Tokens.UNKNOWN)r.length>1?s=Tokens.UNKNOWN_SYM:(s=Tokens.CHAR,r=e,i.reset());return this.createToken(s,r,t,n)},charToken:function(e,t,n){var r=Tokens.type(e),i={};return r==-1?r=Tokens.CHAR:i.endChar=Tokens[r].endChar,this.createToken(r,e,t,n,i)},commentToken:function(e,t,n){var r=this._reader,i=this.readComment(e);return this.createToken(Tokens.COMMENT,i,t,n)},comparisonToken:function(e,t,n){var r=this._reader,i=e+r.read(),s=Tokens.type(i)||Tokens.CHAR;return this.createToken(s,i,t,n)},hashToken:function(e,t,n){var r=this._reader,i=this.readName(e);return this.createToken(Tokens.HASH,i,t,n)},htmlCommentStartToken:function(e,t,n){var r=this._reader,i=e;return r.mark(),i+=r.readCount(3),i=="<!--"?this.createToken(Tokens.CDO,i,t,n):(r.reset(),this.charToken(e,t,n))},htmlCommentEndToken:function(e,t,n){var r=this._reader,i=e;return r.mark(),i+=r.readCount(2),i=="-->"?this.createToken(Tokens.CDC,i,t,n):(r.reset(),this.charToken(e,t,n))},identOrFunctionToken:function(e,t,n){var r=this._reader,i=this.readName(e),s=Tokens.IDENT;return r.peek()=="("?(i+=r.read(),i.toLowerCase()=="url("?(s=Tokens.URI,i=this.readURI(i),i.toLowerCase()=="url("&&(s=Tokens.FUNCTION)):s=Tokens.FUNCTION):r.peek()==":"&&i.toLowerCase()=="progid"&&(i+=r.readTo("("),s=Tokens.IE_FUNCTION),this.createToken(s,i,t,n)},importantToken:function(e,t,n){var r=this._reader,i=e,s=Tokens.CHAR,o,u;r.mark(),u=r.read();while(u){if(u=="/"){if(r.peek()!="*")break;o=this.readComment(u);if(o==="")break}else{if(!isWhitespace(u)){if(/i/i.test(u)){o=r.readCount(8),/mportant/i.test(o)&&(i+=u+o,s=Tokens.IMPORTANT_SYM);break}break}i+=u+this.readWhitespace()}u=r.read()}return s==Tokens.CHAR?(r.reset(),this.charToken(e,t,n)):this.createToken(s,i,t,n)},notToken:function(e,t,n){var r=this._reader,i=e;return r.mark(),i+=r.readCount(4),i.toLowerCase()==":not("?this.createToken(Tokens.NOT,i,t,n):(r.reset(),this.charToken(e,t,n))},numberToken:function(e,t,n){var r=this._reader,i=this.readNumber(e),s,o=Tokens.NUMBER,u=r.peek();return isIdentStart(u)?(s=this.readName(r.read()),i+=s,/^em$|^ex$|^px$|^gd$|^rem$|^vw$|^vh$|^vmax$|^vmin$|^ch$|^cm$|^mm$|^in$|^pt$|^pc$/i.test(s)?o=Tokens.LENGTH:/^deg|^rad$|^grad$/i.test(s)?o=Tokens.ANGLE:/^ms$|^s$/i.test(s)?o=Tokens.TIME:/^hz$|^khz$/i.test(s)?o=Tokens.FREQ:/^dpi$|^dpcm$/i.test(s)?o=Tokens.RESOLUTION:o=Tokens.DIMENSION):u=="%"&&(i+=r.read(),o=Tokens.PERCENTAGE),this.createToken(o,i,t,n)},stringToken:function(e,t,n){var r=e,i=e,s=this._reader,o=e,u=Tokens.STRING,a=s.read();while(a){i+=a;if(a==r&&o!="\\")break;if(isNewLine(s.peek())&&a!="\\"){u=Tokens.INVALID;break}o=a,a=s.read()}return a===null&&(u=Tokens.INVALID),this.createToken(u,i,t,n)},unicodeRangeToken:function(e,t,n){var r=this._reader,i=e,s,o=Tokens.CHAR;return r.peek()=="+"&&(r.mark(),i+=r.read(),i+=this.readUnicodeRangePart(!0),i.length==2?r.reset():(o=Tokens.UNICODE_RANGE,i.indexOf("?")==-1&&r.peek()=="-"&&(r.mark(),s=r.read(),s+=this.readUnicodeRangePart(!1),s.length==1?r.reset():i+=s))),this.createToken(o,i,t,n)},whitespaceToken:function(e,t,n){var r=this._reader,i=e+this.readWhitespace();return this.createToken(Tokens.S,i,t,n)},readUnicodeRangePart:function(e){var t=this._reader,n="",r=t.peek();while(isHexDigit(r)&&n.length<6)t.read(),n+=r,r=t.peek();if(e)while(r=="?"&&n.length<6)t.read(),n+=r,r=t.peek();return n},readWhitespace:function(){var e=this._reader,t="",n=e.peek();while(isWhitespace(n))e.read(),t+=n,n=e.peek();return t},readNumber:function(e){var t=this._reader,n=e,r=e==".",i=t.peek();while(i){if(isDigit(i))n+=t.read();else{if(i!=".")break;if(r)break;r=!0,n+=t.read()}i=t.peek()}return n},readString:function(){var e=this._reader,t=e.read(),n=t,r=t,i=e.peek();while(i){i=e.read(),n+=i;if(i==t&&r!="\\")break;if(isNewLine(e.peek())&&i!="\\"){n="";break}r=i,i=e.peek()}return i===null&&(n=""),n},readURI:function(e){var t=this._reader,n=e,r="",i=t.peek();t.mark();while(i&&isWhitespace(i))t.read(),i=t.peek();i=="'"||i=='"'?r=this.readString():r=this.readURL(),i=t.peek();while(i&&isWhitespace(i))t.read(),i=t.peek();return r===""||i!=")"?(n=e,t.reset()):n+=r+t.read(),n},readURL:function(){var e=this._reader,t="",n=e.peek();while(/^[!#$%&\\*-~]$/.test(n))t+=e.read(),n=e.peek();return t},readName:function(e){var t=this._reader,n=e||"",r=t.peek();for(;;)if(r=="\\")n+=this.readEscape(t.read()),r=t.peek();else{if(!r||!isNameChar(r))break;n+=t.read(),r=t.peek()}return n},readEscape:function(e){var t=this._reader,n=e||"",r=0,i=t.peek();if(isHexDigit(i))do n+=t.read(),i=t.peek();while(i&&isHexDigit(i)&&++r<6);return n.length==3&&/\s/.test(i)||n.length==7||n.length==1?t.read():i="",n+i},readComment:function(e){var t=this._reader,n=e||"",r=t.read();if(r=="*"){while(r){n+=r;if(n.length>2&&r=="*"&&t.peek()=="/"){n+=t.read();break}r=t.read()}return n}return""}});var Tokens=[{name:"CDO"},{name:"CDC"},{name:"S",whitespace:!0},{name:"COMMENT",comment:!0,hide:!0,channel:"comment"},{name:"INCLUDES",text:"~="},{name:"DASHMATCH",text:"|="},{name:"PREFIXMATCH",text:"^="},{name:"SUFFIXMATCH",text:"$="},{name:"SUBSTRINGMATCH",text:"*="},{name:"STRING"},{name:"IDENT"},{name:"HASH"},{name:"IMPORT_SYM",text:"@import"},{name:"PAGE_SYM",text:"@page"},{name:"MEDIA_SYM",text:"@media"},{name:"FONT_FACE_SYM",text:"@font-face"},{name:"CHARSET_SYM",text:"@charset"},{name:"NAMESPACE_SYM",text:"@namespace"},{name:"VIEWPORT_SYM",text:["@viewport","@-ms-viewport"]},{name:"UNKNOWN_SYM"},{name:"KEYFRAMES_SYM",text:["@keyframes","@-webkit-keyframes","@-moz-keyframes","@-o-keyframes"]},{name:"IMPORTANT_SYM"},{name:"LENGTH"},{name:"ANGLE"},{name:"TIME"},{name:"FREQ"},{name:"DIMENSION"},{name:"PERCENTAGE"},{name:"NUMBER"},{name:"URI"},{name:"FUNCTION"},{name:"UNICODE_RANGE"},{name:"INVALID"},{name:"PLUS",text:"+"},{name:"GREATER",text:">"},{name:"COMMA",text:","},{name:"TILDE",text:"~"},{name:"NOT"},{name:"TOPLEFTCORNER_SYM",text:"@top-left-corner"},{name:"TOPLEFT_SYM",text:"@top-left"},{name:"TOPCENTER_SYM",text:"@top-center"},{name:"TOPRIGHT_SYM",text:"@top-right"},{name:"TOPRIGHTCORNER_SYM",text:"@top-right-corner"},{name:"BOTTOMLEFTCORNER_SYM",text:"@bottom-left-corner"},{name:"BOTTOMLEFT_SYM",text:"@bottom-left"},{name:"BOTTOMCENTER_SYM",text:"@bottom-center"},{name:"BOTTOMRIGHT_SYM",text:"@bottom-right"},{name:"BOTTOMRIGHTCORNER_SYM",text:"@bottom-right-corner"},{name:"LEFTTOP_SYM",text:"@left-top"},{name:"LEFTMIDDLE_SYM",text:"@left-middle"},{name:"LEFTBOTTOM_SYM",text:"@left-bottom"},{name:"RIGHTTOP_SYM",text:"@right-top"},{name:"RIGHTMIDDLE_SYM",text:"@right-middle"},{name:"RIGHTBOTTOM_SYM",text:"@right-bottom"},{name:"RESOLUTION",state:"media"},{name:"IE_FUNCTION"},{name:"CHAR"},{name:"PIPE",text:"|"},{name:"SLASH",text:"/"},{name:"MINUS",text:"-"},{name:"STAR",text:"*"},{name:"LBRACE",endChar:"}",text:"{"},{name:"RBRACE",text:"}"},{name:"LBRACKET",endChar:"]",text:"["},{name:"RBRACKET",text:"]"},{name:"EQUALS",text:"="},{name:"COLON",text:":"},{name:"SEMICOLON",text:";"},{name:"LPAREN",endChar:")",text:"("},{name:"RPAREN",text:")"},{name:"DOT",text:"."}];(function(){var e=[],t={};Tokens.UNKNOWN=-1,Tokens.unshift({name:"EOF"});for(var n=0,r=Tokens.length;n<r;n++){e.push(Tokens[n].name),Tokens[Tokens[n].name]=n;if(Tokens[n].text)if(Tokens[n].text instanceof Array)for(var i=0;i<Tokens[n].text.length;i++)t[Tokens[n].text[i]]=n;else t[Tokens[n].text]=n}Tokens.name=function(t){return e[t]},Tokens.type=function(e){return t[e]||-1}})();var Validation={validate:function(e,t){var n=e.toString().toLowerCase(),r=t.parts,i=new PropertyValueIterator(t),s=Properties[n],o,u,a,f,l,c,h,p,d,v,m;if(!s){if(n.indexOf("-")!==0)throw new ValidationError("Unknown property '"+e+"'.",e.line,e.col)}else typeof s!="number"&&(typeof s=="string"?s.indexOf("||")>-1?this.groupProperty(s,i):this.singleProperty(s,i,1):s.multi?this.multiProperty(s.multi,i,s.comma,s.max||Infinity):typeof s=="function"&&s(i))},singleProperty:function(e,t,n,r){var i=!1,s=t.value,o=0,u;while(t.hasNext()&&o<n){i=ValidationTypes.isAny(t,e);if(!i)break;o++}if(!i)throw t.hasNext()&&!t.isFirst()?(u=t.peek(),new ValidationError("Expected end of value but found '"+u+"'.",u.line,u.col)):new ValidationError("Expected ("+e+") but found '"+s+"'.",s.line,s.col);if(t.hasNext())throw u=t.next(),new ValidationError("Expected end of value but found '"+u+"'.",u.line,u.col)},multiProperty:function(e,t,n,r){var i=!1,s=t.value,o=0,u=!1,a;while(t.hasNext()&&!i&&o<r){if(!ValidationTypes.isAny(t,e))break;o++;if(!t.hasNext())i=!0;else if(n){if(t.peek()!=",")break;a=t.next()}}if(!i)throw t.hasNext()&&!t.isFirst()?(a=t.peek(),new ValidationError("Expected end of value but found '"+a+"'.",a.line,a.col)):(a=t.previous(),n&&a==","?new ValidationError("Expected end of value but found '"+a+"'.",a.line,a.col):new ValidationError("Expected ("+e+") but found '"+s+"'.",s.line,s.col));if(t.hasNext())throw a=t.next(),new ValidationError("Expected end of value but found '"+a+"'.",a.line,a.col)},groupProperty:function(e,t,n){var r=!1,i=t.value,s=e.split("||").length,o={count:0},u=!1,a,f;while(t.hasNext()&&!r){a=ValidationTypes.isAnyOfGroup(t,e);if(!a)break;if(o[a])break;o[a]=1,o.count++,u=!0;if(o.count==s||!t.hasNext())r=!0}if(!r)throw u&&t.hasNext()?(f=t.peek(),new ValidationError("Expected end of value but found '"+f+"'.",f.line,f.col)):new ValidationError("Expected ("+e+") but found '"+i+"'.",i.line,i.col);if(t.hasNext())throw f=t.next(),new ValidationError("Expected end of value but found '"+f+"'.",f.line,f.col)}};ValidationError.prototype=new Error;var ValidationTypes={isLiteral:function(e,t){var n=e.text.toString().toLowerCase(),r=t.split(" | "),i,s,o=!1;for(i=0,s=r.length;i<s&&!o;i++)n==r[i].toLowerCase()&&(o=!0);return o},isSimple:function(e){return!!this.simple[e]},isComplex:function(e){return!!this.complex[e]},isAny:function(e,t){var n=t.split(" | "),r,i,s=!1;for(r=0,i=n.length;r<i&&!s&&e.hasNext();r++)s=this.isType(e,n[r]);return s},isAnyOfGroup:function(e,t){var n=t.split(" || "),r,i,s=!1;for(r=0,i=n.length;r<i&&!s;r++)s=this.isType(e,n[r]);return s?n[r-1]:!1},isType:function(e,t){var n=e.peek(),r=!1;return t.charAt(0)!="<"?(r=this.isLiteral(n,t),r&&e.next()):this.simple[t]?(r=this.simple[t](n),r&&e.next()):r=this.complex[t](e),r},simple:{"<absolute-size>":function(e){return ValidationTypes.isLiteral(e,"xx-small | x-small | small | medium | large | x-large | xx-large")},"<attachment>":function(e){return ValidationTypes.isLiteral(e,"scroll | fixed | local")},"<attr>":function(e){return e.type=="function"&&e.name=="attr"},"<bg-image>":function(e){return this["<image>"](e)||this["<gradient>"](e)||e=="none"},"<gradient>":function(e){return e.type=="function"&&/^(?:\-(?:ms|moz|o|webkit)\-)?(?:repeating\-)?(?:radial\-|linear\-)?gradient/i.test(e)},"<box>":function(e){return ValidationTypes.isLiteral(e,"padding-box | border-box | content-box")},"<content>":function(e){return e.type=="function"&&e.name=="content"},"<relative-size>":function(e){return ValidationTypes.isLiteral(e,"smaller | larger")},"<ident>":function(e){return e.type=="identifier"},"<length>":function(e){return e.type=="function"&&/^(?:\-(?:ms|moz|o|webkit)\-)?calc/i.test(e)?!0:e.type=="length"||e.type=="number"||e.type=="integer"||e=="0"},"<color>":function(e){return e.type=="color"||e=="transparent"},"<number>":function(e){return e.type=="number"||this["<integer>"](e)},"<integer>":function(e){return e.type=="integer"},"<line>":function(e){return e.type=="integer"},"<angle>":function(e){return e.type=="angle"},"<uri>":function(e){return e.type=="uri"},"<image>":function(e){return this["<uri>"](e)},"<percentage>":function(e){return e.type=="percentage"||e=="0"},"<border-width>":function(e){return this["<length>"](e)||ValidationTypes.isLiteral(e,"thin | medium | thick")},"<border-style>":function(e){return ValidationTypes.isLiteral(e,"none | hidden | dotted | dashed | solid | double | groove | ridge | inset | outset")},"<content-sizing>":function(e){return ValidationTypes.isLiteral(e,"fill-available | -moz-available | -webkit-fill-available | max-content | -moz-max-content | -webkit-max-content | min-content | -moz-min-content | -webkit-min-content | fit-content | -moz-fit-content | -webkit-fit-content")},"<margin-width>":function(e){return this["<length>"](e)||this["<percentage>"](e)||ValidationTypes.isLiteral(e,"auto")},"<padding-width>":function(e){return this["<length>"](e)||this["<percentage>"](e)},"<shape>":function(e){return e.type=="function"&&(e.name=="rect"||e.name=="inset-rect")},"<time>":function(e){return e.type=="time"},"<flex-grow>":function(e){return this["<number>"](e)},"<flex-shrink>":function(e){return this["<number>"](e)},"<width>":function(e){return this["<margin-width>"](e)},"<flex-basis>":function(e){return this["<width>"](e)},"<flex-direction>":function(e){return ValidationTypes.isLiteral(e,"row | row-reverse | column | column-reverse")},"<flex-wrap>":function(e){return ValidationTypes.isLiteral(e,"nowrap | wrap | wrap-reverse")}},complex:{"<bg-position>":function(e){var t=this,n=!1,r="<percentage> | <length>",i="left | right",s="top | bottom",o=0,u=function(){return e.hasNext()&&e.peek()!=","};while(e.peek(o)&&e.peek(o)!=",")o++;return o<3?ValidationTypes.isAny(e,i+" | center | "+r)?(n=!0,ValidationTypes.isAny(e,s+" | center | "+r)):ValidationTypes.isAny(e,s)&&(n=!0,ValidationTypes.isAny(e,i+" | center")):ValidationTypes.isAny(e,i)?ValidationTypes.isAny(e,s)?(n=!0,ValidationTypes.isAny(e,r)):ValidationTypes.isAny(e,r)&&(ValidationTypes.isAny(e,s)?(n=!0,ValidationTypes.isAny(e,r)):ValidationTypes.isAny(e,"center")&&(n=!0)):ValidationTypes.isAny(e,s)?ValidationTypes.isAny(e,i)?(n=!0,ValidationTypes.isAny(e,r)):ValidationTypes.isAny(e,r)&&(ValidationTypes.isAny(e,i)?(n=!0,ValidationTypes.isAny(e,r)):ValidationTypes.isAny(e,"center")&&(n=!0)):ValidationTypes.isAny(e,"center")&&ValidationTypes.isAny(e,i+" | "+s)&&(n=!0,ValidationTypes.isAny(e,r)),n},"<bg-size>":function(e){var t=this,n=!1,r="<percentage> | <length> | auto",i,s,o;return ValidationTypes.isAny(e,"cover | contain")?n=!0:ValidationTypes.isAny(e,r)&&(n=!0,ValidationTypes.isAny(e,r)),n},"<repeat-style>":function(e){var t=!1,n="repeat | space | round | no-repeat",r;return e.hasNext()&&(r=e.next(),ValidationTypes.isLiteral(r,"repeat-x | repeat-y")?t=!0:ValidationTypes.isLiteral(r,n)&&(t=!0,e.hasNext()&&ValidationTypes.isLiteral(e.peek(),n)&&e.next())),t},"<shadow>":function(e){var t=!1,n=0,r=!1,i=!1,s;if(e.hasNext()){ValidationTypes.isAny(e,"inset")&&(r=!0),ValidationTypes.isAny(e,"<color>")&&(i=!0);while(ValidationTypes.isAny(e,"<length>")&&n<4)n++;e.hasNext()&&(i||ValidationTypes.isAny(e,"<color>"),r||ValidationTypes.isAny(e,"inset")),t=n>=2&&n<=4}return t},"<x-one-radius>":function(e){var t=!1,n="<length> | <percentage> | inherit";return ValidationTypes.isAny(e,n)&&(t=!0,ValidationTypes.isAny(e,n)),t},"<flex>":function(e){var t,n=!1;ValidationTypes.isAny(e,"none | inherit")?n=!0:ValidationTypes.isType(e,"<flex-grow>")?e.peek()?ValidationTypes.isType(e,"<flex-shrink>")?e.peek()?n=ValidationTypes.isType(e,"<flex-basis>"):n=!0:ValidationTypes.isType(e,"<flex-basis>")&&(n=e.peek()===null):n=!0:ValidationTypes.isType(e,"<flex-basis>")&&(n=!0);if(!n)throw t=e.peek(),new ValidationError("Expected (none | [ <flex-grow> <flex-shrink>? || <flex-basis> ]) but found '"+e.value.text+"'.",t.line,t.col);return n}}};parserlib.css={Colors:Colors,Combinator:Combinator,Parser:Parser,PropertyName:PropertyName,PropertyValue:PropertyValue,PropertyValuePart:PropertyValuePart,MediaFeature:MediaFeature,MediaQuery:MediaQuery,Selector:Selector,SelectorPart:SelectorPart,SelectorSubPart:SelectorSubPart,Specificity:Specificity,TokenStream:TokenStream,Tokens:Tokens,ValidationError:ValidationError}}(),function(){for(var e in parserlib)exports[e]=parserlib[e]}();var util={isArray:function(e){return Array.isArray(e)||typeof e=="object"&&objectToString(e)==="[object Array]"},isDate:function(e){return typeof e=="object"&&objectToString(e)==="[object Date]"},isRegExp:function(e){return typeof e=="object"&&objectToString(e)==="[object RegExp]"},getRegExpFlags:function(e){var t="";return e.global&&(t+="g"),e.ignoreCase&&(t+="i"),e.multiline&&(t+="m"),t}};typeof module=="object"&&(module.exports=clone),clone.clonePrototype=function(e){if(e===null)return null;var t=function(){};return t.prototype=e,new t};var CSSLint=function(){function i(e,t){var r,i=e&&e.match(n),s=i&&i[1];return s&&(r={"true":2,"":1,"false":0,2:2,1:1,0:0},s.toLowerCase().split(",").forEach(function(e){var n=e.split(":"),i=n[0]||"",s=n[1]||"";t[i.trim()]=r[s.trim()]})),t}var e=[],t=[],n=/\/\*csslint([^\*]*)\*\//,r=new parserlib.util.EventTarget;return r.version="@VERSION@",r.addRule=function(t){e.push(t),e[t.id]=t},r.clearRules=function(){e=[]},r.getRules=function(){return[].concat(e).sort(function(e,t){return e.id>t.id?1:0})},r.getRuleset=function(){var t={},n=0,r=e.length;while(n<r)t[e[n++].id]=1;return t},r.addFormatter=function(e){t[e.id]=e},r.getFormatter=function(e){return t[e]},r.format=function(e,t,n,r){var i=this.getFormatter(n),s=null;return i&&(s=i.startFormat(),s+=i.formatResults(e,t,r||{}),s+=i.endFormat()),s},r.hasFormat=function(e){return t.hasOwnProperty(e)},r.verify=function(t,r){var s=0,o,u,a,f=new parserlib.css.Parser({starHack:!0,ieFilters:!0,underscoreHack:!0,strict:!1});u=t.replace(/\n\r?/g,"$split$").split("$split$"),r||(r=this.getRuleset()),n.test(t)&&(r=clone(r),r=i(t,r)),o=new Reporter(u,r),r.errors=2;for(s in r)r.hasOwnProperty(s)&&r[s]&&e[s]&&e[s].init(f,o);try{f.parse(t)}catch(l){o.error("Fatal error, cannot continue: "+l.message,l.line,l.col,{})}return a={messages:o.messages,stats:o.stats,ruleset:o.ruleset},a.messages.sort(function(e,t){return e.rollup&&!t.rollup?1:!e.rollup&&t.rollup?-1:e.line-t.line}),a},r}();Reporter.prototype={constructor:Reporter,error:function(e,t,n,r){this.messages.push({type:"error",line:t,col:n,message:e,evidence:this.lines[t-1],rule:r||{}})},warn:function(e,t,n,r){this.report(e,t,n,r)},report:function(e,t,n,r){this.messages.push({type:this.ruleset[r.id]===2?"error":"warning",line:t,col:n,message:e,evidence:this.lines[t-1],rule:r})},info:function(e,t,n,r){this.messages.push({type:"info",line:t,col:n,message:e,evidence:this.lines[t-1],rule:r})},rollupError:function(e,t){this.messages.push({type:"error",rollup:!0,message:e,rule:t})},rollupWarn:function(e,t){this.messages.push({type:"warning",rollup:!0,message:e,rule:t})},stat:function(e,t){this.stats[e]=t}},CSSLint._Reporter=Reporter,CSSLint.Util={mix:function(e,t){var n;for(n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return n},indexOf:function(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},forEach:function(e,t){if(e.forEach)return e.forEach(t);for(var n=0,r=e.length;n<r;n++)t(e[n],n,e)}},CSSLint.addRule({id:"adjoining-classes",name:"Disallow adjoining classes",desc:"Don't use adjoining classes.",browsers:"IE6",init:function(e,t){var n=this;e.addListener("startrule",function(r){var i=r.selectors,s,o,u,a,f,l,c;for(f=0;f<i.length;f++){s=i[f];for(l=0;l<s.parts.length;l++){o=s.parts[l];if(o.type===e.SELECTOR_PART_TYPE){a=0;for(c=0;c<o.modifiers.length;c++)u=o.modifiers[c],u.type==="class"&&a++,a>1&&t.report("Don't use adjoining classes.",o.line,o.col,n)}}}})}}),CSSLint.addRule({id:"box-model",name:"Beware of broken box size",desc:"Don't use width or height when using padding or border.",browsers:"All",init:function(e,t){function u(){s={},o=!1}function a(){var e,u;if(!o){if(s.height)for(e in i)i.hasOwnProperty(e)&&s[e]&&(u=s[e].value,(e!=="padding"||u.parts.length!==2||u.parts[0].value!==0)&&t.report("Using height with "+e+" can sometimes make elements larger than you expect.",s[e].line,s[e].col,n));if(s.width)for(e in r)r.hasOwnProperty(e)&&s[e]&&(u=s[e].value,(e!=="padding"||u.parts.length!==2||u.parts[1].value!==0)&&t.report("Using width with "+e+" can sometimes make elements larger than you expect.",s[e].line,s[e].col,n))}}var n=this,r={border:1,"border-left":1,"border-right":1,padding:1,"padding-left":1,"padding-right":1},i={border:1,"border-bottom":1,"border-top":1,padding:1,"padding-bottom":1,"padding-top":1},s,o=!1;e.addListener("startrule",u),e.addListener("startfontface",u),e.addListener("startpage",u),e.addListener("startpagemargin",u),e.addListener("startkeyframerule",u),e.addListener("property",function(e){var t=e.property.text.toLowerCase();i[t]||r[t]?!/^0\S*$/.test(e.value)&&(t!=="border"||e.value.toString()!=="none")&&(s[t]={line:e.property.line,col:e.property.col,value:e.value}):/^(width|height)/i.test(t)&&/^(length|percentage)/.test(e.value.parts[0].type)?s[t]=1:t==="box-sizing"&&(o=!0)}),e.addListener("endrule",a),e.addListener("endfontface",a),e.addListener("endpage",a),e.addListener("endpagemargin",a),e.addListener("endkeyframerule",a)}}),CSSLint.addRule({id:"box-sizing",name:"Disallow use of box-sizing",desc:"The box-sizing properties isn't supported in IE6 and IE7.",browsers:"IE6, IE7",tags:["Compatibility"],init:function(e,t){var n=this;e.addListener("property",function(e){var r=e.property.text.toLowerCase();r==="box-sizing"&&t.report("The box-sizing property isn't supported in IE6 and IE7.",e.line,e.col,n)})}}),CSSLint.addRule({id:"bulletproof-font-face",name:"Use the bulletproof @font-face syntax",desc:"Use the bulletproof @font-face syntax to avoid 404's in old IE (http://www.fontspring.com/blog/the-new-bulletproof-font-face-syntax).",browsers:"All",init:function(e,t){var n=this,r=!1,i=!0,s=!1,o,u;e.addListener("startfontface",function(){r=!0}),e.addListener("property",function(e){if(!r)return;var t=e.property.toString().toLowerCase(),n=e.value.toString();o=e.line,u=e.col;if(t==="src"){var a=/^\s?url\(['"].+\.eot\?.*['"]\)\s*format\(['"]embedded-opentype['"]\).*$/i;!n.match(a)&&i?(s=!0,i=!1):n.match(a)&&!i&&(s=!1)}}),e.addListener("endfontface",function(){r=!1,s&&t.report("@font-face declaration doesn't follow the fontspring bulletproof syntax.",o,u,n)})}}),CSSLint.addRule({id:"compatible-vendor-prefixes",name:"Require compatible vendor prefixes",desc:"Include all compatible vendor prefixes to reach a wider range of users.",browsers:"All",init:function(e,t){var n=this,r,i,s,o,u,a,f,l=!1,c=Array.prototype.push,h=[];r={animation:"webkit moz","animation-delay":"webkit moz","animation-direction":"webkit moz","animation-duration":"webkit moz","animation-fill-mode":"webkit moz","animation-iteration-count":"webkit moz","animation-name":"webkit moz","animation-play-state":"webkit moz","animation-timing-function":"webkit moz",appearance:"webkit moz","border-end":"webkit moz","border-end-color":"webkit moz","border-end-style":"webkit moz","border-end-width":"webkit moz","border-image":"webkit moz o","border-radius":"webkit","border-start":"webkit moz","border-start-color":"webkit moz","border-start-style":"webkit moz","border-start-width":"webkit moz","box-align":"webkit moz ms","box-direction":"webkit moz ms","box-flex":"webkit moz ms","box-lines":"webkit ms","box-ordinal-group":"webkit moz ms","box-orient":"webkit moz ms","box-pack":"webkit moz ms","box-sizing":"webkit moz","box-shadow":"webkit moz","column-count":"webkit moz ms","column-gap":"webkit moz ms","column-rule":"webkit moz ms","column-rule-color":"webkit moz ms","column-rule-style":"webkit moz ms","column-rule-width":"webkit moz ms","column-width":"webkit moz ms",hyphens:"epub moz","line-break":"webkit ms","margin-end":"webkit moz","margin-start":"webkit moz","marquee-speed":"webkit wap","marquee-style":"webkit wap","padding-end":"webkit moz","padding-start":"webkit moz","tab-size":"moz o","text-size-adjust":"webkit ms",transform:"webkit moz ms o","transform-origin":"webkit moz ms o",transition:"webkit moz o","transition-delay":"webkit moz o","transition-duration":"webkit moz o","transition-property":"webkit moz o","transition-timing-function":"webkit moz o","user-modify":"webkit moz","user-select":"webkit moz ms","word-break":"epub ms","writing-mode":"epub ms"};for(s in r)if(r.hasOwnProperty(s)){o=[],u=r[s].split(" ");for(a=0,f=u.length;a<f;a++)o.push("-"+u[a]+"-"+s);r[s]=o,c.apply(h,o)}e.addListener("startrule",function(){i=[]}),e.addListener("startkeyframes",function(e){l=e.prefix||!0}),e.addListener("endkeyframes",function(){l=!1}),e.addListener("property",function(e){var t=e.property;CSSLint.Util.indexOf(h,t.text)>-1&&(!l||typeof l!="string"||t.text.indexOf("-"+l+"-")!==0)&&i.push(t)}),e.addListener("endrule",function(){if(!i.length)return;var e={},s,o,u,a,f,l,c,h,p,d;for(s=0,o=i.length;s<o;s++){u=i[s];for(a in r)r.hasOwnProperty(a)&&(f=r[a],CSSLint.Util.indexOf(f,u.text)>-1&&(e[a]||(e[a]={full:f.slice(0),actual:[],actualNodes:[]}),CSSLint.Util.indexOf(e[a].actual,u.text)===-1&&(e[a].actual.push(u.text),e[a].actualNodes.push(u))))}for(a in e)if(e.hasOwnProperty(a)){l=e[a],c=l.full,h=l.actual;if(c.length>h.length)for(s=0,o=c.length;s<o;s++)p=c[s],CSSLint.Util.indexOf(h,p)===-1&&(d=h.length===1?h[0]:h.length===2?h.join(" and "):h.join(", "),t.report("The property "+p+" is compatible with "+d+" and should be included as well.",l.actualNodes[0].line,l.actualNodes[0].col,n))}})}}),CSSLint.addRule({id:"display-property-grouping",name:"Require properties appropriate for display",desc:"Certain properties shouldn't be used with certain display property values.",browsers:"All",init:function(e,t){function s(e,s,o){i[e]&&(typeof r[e]!="string"||i[e].value.toLowerCase()!==r[e])&&t.report(o||e+" can't be used with display: "+s+".",i[e].line,i[e].col,n)}function o(){i={}}function u(){var e=i.display?i.display.value:null;if(e)switch(e){case"inline":s("height",e),s("width",e),s("margin",e),s("margin-top",e),s("margin-bottom",e),s("float",e,"display:inline has no effect on floated elements (but may be used to fix the IE6 double-margin bug).");break;case"block":s("vertical-align",e);break;case"inline-block":s("float",e);break;default:e.indexOf("table-")===0&&(s("margin",e),s("margin-left",e),s("margin-right",e),s("margin-top",e),s("margin-bottom",e),s("float",e))}}var n=this,r={display:1,"float":"none",height:1,width:1,margin:1,"margin-left":1,"margin-right":1,"margin-bottom":1,"margin-top":1,padding:1,"padding-left":1,"padding-right":1,"padding-bottom":1,"padding-top":1,"vertical-align":1},i;e.addListener("startrule",o),e.addListener("startfontface",o),e.addListener("startkeyframerule",o),e.addListener("startpagemargin",o),e.addListener("startpage",o),e.addListener("property",function(e){var t=e.property.text.toLowerCase();r[t]&&(i[t]={value:e.value.text,line:e.property.line,col:e.property.col})}),e.addListener("endrule",u),e.addListener("endfontface",u),e.addListener("endkeyframerule",u),e.addListener("endpagemargin",u),e.addListener("endpage",u)}}),CSSLint.addRule({id:"duplicate-background-images",name:"Disallow duplicate background images",desc:"Every background-image should be unique. Use a common class for e.g. sprites.",browsers:"All",init:function(e,t){var n=this,r={};e.addListener("property",function(e){var i=e.property.text,s=e.value,o,u;if(i.match(/background/i))for(o=0,u=s.parts.length;o<u;o++)s.parts[o].type==="uri"&&(typeof r[s.parts[o].uri]=="undefined"?r[s.parts[o].uri]=e:t.report("Background image '"+s.parts[o].uri+"' was used multiple times, first declared at line "+r[s.parts[o].uri].line+", col "+r[s.parts[o].uri].col+".",e.line,e.col,n))})}}),CSSLint.addRule({id:"duplicate-properties",name:"Disallow duplicate properties",desc:"Duplicate properties must appear one after the other.",browsers:"All",init:function(e,t){function s(){r={}}var n=this,r,i;e.addListener("startrule",s),e.addListener("startfontface",s),e.addListener("startpage",s),e.addListener("startpagemargin",s),e.addListener("startkeyframerule",s),e.addListener("property",function(e){var s=e.property,o=s.text.toLowerCase();r[o]&&(i!==o||r[o]===e.value.text)&&t.report("Duplicate property '"+e.property+"' found.",e.line,e.col,n),r[o]=e.value.text,i=o})}}),CSSLint.addRule({id:"empty-rules",name:"Disallow empty rules",desc:"Rules without any properties specified should be removed.",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("startrule",function(){r=0}),e.addListener("property",function(){r++}),e.addListener("endrule",function(e){var i=e.selectors;r===0&&t.report("Rule is empty.",i[0].line,i[0].col,n)})}}),CSSLint.addRule({id:"errors",name:"Parsing Errors",desc:"This rule looks for recoverable syntax errors.",browsers:"All",init:function(e,t){var n=this;e.addListener("error",function(e){t.error(e.message,e.line,e.col,n)})}}),CSSLint.addRule({id:"fallback-colors",name:"Require fallback colors",desc:"For older browsers that don't support RGBA, HSL, or HSLA, provide a fallback color.",browsers:"IE6,IE7,IE8",init:function(e,t){function o(){s={},r=null}var n=this,r,i={color:1,background:1,"border-color":1,"border-top-color":1,"border-right-color":1,"border-bottom-color":1,"border-left-color":1,border:1,"border-top":1,"border-right":1,"border-bottom":1,"border-left":1,"background-color":1},s;e.addListener("startrule",o),e.addListener("startfontface",o),e.addListener("startpage",o),e.addListener("startpagemargin",o),e.addListener("startkeyframerule",o),e.addListener("property",function(e){var s=e.property,o=s.text.toLowerCase(),u=e.value.parts,a=0,f="",l=u.length;if(i[o])while(a<l)u[a].type==="color"&&("alpha"in u[a]||"hue"in u[a]?(/([^\)]+)\(/.test(u[a])&&(f=RegExp.$1.toUpperCase()),(!r||r.property.text.toLowerCase()!==o||r.colorType!=="compat")&&t.report("Fallback "+o+" (hex or RGB) should precede "+f+" "+o+".",e.line,e.col,n)):e.colorType="compat"),a++;r=e})}}),CSSLint.addRule({id:"floats",name:"Disallow too many floats",desc:"This rule tests if the float property is used too many times",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("property",function(e){e.property.text.toLowerCase()==="float"&&e.value.text.toLowerCase()!=="none"&&r++}),e.addListener("endstylesheet",function(){t.stat("floats",r),r>=10&&t.rollupWarn("Too many floats ("+r+"), you're probably using them for layout. Consider using a grid system instead.",n)})}}),CSSLint.addRule({id:"font-faces",name:"Don't use too many web fonts",desc:"Too many different web fonts in the same stylesheet.",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("startfontface",function(){r++}),e.addListener("endstylesheet",function(){r>5&&t.rollupWarn("Too many @font-face declarations ("+r+").",n)})}}),CSSLint.addRule({id:"font-sizes",name:"Disallow too many font sizes",desc:"Checks the number of font-size declarations.",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("property",function(e){e.property.toString()==="font-size"&&r++}),e.addListener("endstylesheet",function(){t.stat("font-sizes",r),r>=10&&t.rollupWarn("Too many font-size declarations ("+r+"), abstraction needed.",n)})}}),CSSLint.addRule({id:"gradients",name:"Require all gradient definitions",desc:"When using a vendor-prefixed gradient, make sure to use them all.",browsers:"All",init:function(e,t){var n=this,r;e.addListener("startrule",function(){r={moz:0,webkit:0,oldWebkit:0,o:0}}),e.addListener("property",function(e){/\-(moz|o|webkit)(?:\-(?:linear|radial))\-gradient/i.test(e.value)?r[RegExp.$1]=1:/\-webkit\-gradient/i.test(e.value)&&(r.oldWebkit=1)}),e.addListener("endrule",function(e){var i=[];r.moz||i.push("Firefox 3.6+"),r.webkit||i.push("Webkit (Safari 5+, Chrome)"),r.oldWebkit||i.push("Old Webkit (Safari 4+, Chrome)"),r.o||i.push("Opera 11.1+"),i.length&&i.length<4&&t.report("Missing vendor-prefixed CSS gradients for "+i.join(", ")+".",e.selectors[0].line,e.selectors[0].col,n)})}}),CSSLint.addRule({id:"ids",name:"Disallow IDs in selectors",desc:"Selectors should not contain IDs.",browsers:"All",init:function(e,t){var n=this;e.addListener("startrule",function(r){var i=r.selectors,s,o,u,a,f,l,c;for(f=0;f<i.length;f++){s=i[f],a=0;for(l=0;l<s.parts.length;l++){o=s.parts[l];if(o.type===e.SELECTOR_PART_TYPE)for(c=0;c<o.modifiers.length;c++)u=o.modifiers[c],u.type==="id"&&a++}a===1?t.report("Don't use IDs in selectors.",s.line,s.col,n):a>1&&t.report(a+" IDs in the selector, really?",s.line,s.col,n)}})}}),CSSLint.addRule({id:"import",name:"Disallow @import",desc:"Don't use @import, use <link> instead.",browsers:"All",init:function(e,t){var n=this;e.addListener("import",function(e){t.report("@import prevents parallel downloads, use <link> instead.",e.line,e.col,n)})}}),CSSLint.addRule({id:"important",name:"Disallow !important",desc:"Be careful when using !important declaration",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("property",function(e){e.important===!0&&(r++,t.report("Use of !important",e.line,e.col,n))}),e.addListener("endstylesheet",function(){t.stat("important",r),r>=10&&t.rollupWarn("Too many !important declarations ("+r+"), try to use less than 10 to avoid specificity issues.",n)})}}),CSSLint.addRule({id:"known-properties",name:"Require use of known properties",desc:"Properties should be known (listed in CSS3 specification) or be a vendor-prefixed property.",browsers:"All",init:function(e,t){var n=this;e.addListener("property",function(e){e.invalid&&t.report(e.invalid.message,e.line,e.col,n)})}}),CSSLint.addRule({id:"order-alphabetical",name:"Alphabetical order",desc:"Assure properties are in alphabetical order",browsers:"All",init:function(e,t){var n=this,r,i=function(){r=[]};e.addListener("startrule",i),e.addListener("startfontface",i),e.addListener("startpage",i),e.addListener("startpagemargin",i),e.addListener("startkeyframerule",i),e.addListener("property",function(e){var t=e.property.text,n=t.toLowerCase().replace(/^-.*?-/,"");r.push(n)}),e.addListener("endrule",function(e){var i=r.join(","),s=r.sort().join(",");i!==s&&t.report("Rule doesn't have all its properties in alphabetical ordered.",e.line,e.col,n)})}}),CSSLint.addRule({id:"outline-none",name:"Disallow outline: none",desc:"Use of outline: none or outline: 0 should be limited to :focus rules.",browsers:"All",tags:["Accessibility"],init:function(e,t){function i(e){e.selectors?r={line:e.line,col:e.col,selectors:e.selectors,propCount:0,outline:!1}:r=null}function s(){r&&r.outline&&(r.selectors.toString().toLowerCase().indexOf(":focus")===-1?t.report("Outlines should only be modified using :focus.",r.line,r.col,n):r.propCount===1&&t.report("Outlines shouldn't be hidden unless other visual changes are made.",r.line,r.col,n))}var n=this,r;e.addListener("startrule",i),e.addListener("startfontface",i),e.addListener("startpage",i),e.addListener("startpagemargin",i),e.addListener("startkeyframerule",i),e.addListener("property",function(e){var t=e.property.text.toLowerCase(),n=e.value;r&&(r.propCount++,t==="outline"&&(n.toString()==="none"||n.toString()==="0")&&(r.outline=!0))}),e.addListener("endrule",s),e.addListener("endfontface",s),e.addListener("endpage",s),e.addListener("endpagemargin",s),e.addListener("endkeyframerule",s)}}),CSSLint.addRule({id:"overqualified-elements",name:"Disallow overqualified elements",desc:"Don't use classes or IDs with elements (a.foo or a#foo).",browsers:"All",init:function(e,t){var n=this,r={};e.addListener("startrule",function(i){var s=i.selectors,o,u,a,f,l,c;for(f=0;f<s.length;f++){o=s[f];for(l=0;l<o.parts.length;l++){u=o.parts[l];if(u.type===e.SELECTOR_PART_TYPE)for(c=0;c<u.modifiers.length;c++)a=u.modifiers[c],u.elementName&&a.type==="id"?t.report("Element ("+u+") is overqualified, just use "+a+" without element name.",u.line,u.col,n):a.type==="class"&&(r[a]||(r[a]=[]),r[a].push({modifier:a,part:u}))}}}),e.addListener("endstylesheet",function(){var e;for(e in r)r.hasOwnProperty(e)&&r[e].length===1&&r[e][0].part.elementName&&t.report("Element ("+r[e][0].part+") is overqualified, just use "+r[e][0].modifier+" without element name.",r[e][0].part.line,r[e][0].part.col,n)})}}),CSSLint.addRule({id:"qualified-headings",name:"Disallow qualified headings",desc:"Headings should not be qualified (namespaced).",browsers:"All",init:function(e,t){var n=this;e.addListener("startrule",function(r){var i=r.selectors,s,o,u,a;for(u=0;u<i.length;u++){s=i[u];for(a=0;a<s.parts.length;a++)o=s.parts[a],o.type===e.SELECTOR_PART_TYPE&&o.elementName&&/h[1-6]/.test(o.elementName.toString())&&a>0&&t.report("Heading ("+o.elementName+") should not be qualified.",o.line,o.col,n)}})}}),CSSLint.addRule({id:"regex-selectors",name:"Disallow selectors that look like regexs",desc:"Selectors that look like regular expressions are slow and should be avoided.",browsers:"All",init:function(e,t){var n=this;e.addListener("startrule",function(r){var i=r.selectors,s,o,u,a,f,l;for(a=0;a<i.length;a++){s=i[a];for(f=0;f<s.parts.length;f++){o=s.parts[f];if(o.type===e.SELECTOR_PART_TYPE)for(l=0;l<o.modifiers.length;l++)u=o.modifiers[l],u.type==="attribute"&&/([\~\|\^\$\*]=)/.test(u)&&t.report("Attribute selectors with "+RegExp.$1+" are slow!",u.line,u.col,n)}}})}}),CSSLint.addRule({id:"rules-count",name:"Rules Count",desc:"Track how many rules there are.",browsers:"All",init:function(e,t){var n=0;e.addListener("startrule",function(){n++}),e.addListener("endstylesheet",function(){t.stat("rule-count",n)})}}),CSSLint.addRule({id:"selector-max-approaching",name:"Warn when approaching the 4095 selector limit for IE",desc:"Will warn when selector count is >= 3800 selectors.",browsers:"IE",init:function(e,t){var n=this,r=0;e.addListener("startrule",function(e){r+=e.selectors.length}),e.addListener("endstylesheet",function(){r>=3800&&t.report("You have "+r+" selectors. Internet Explorer supports a maximum of 4095 selectors per stylesheet. Consider refactoring.",0,0,n)})}}),CSSLint.addRule({id:"selector-max",name:"Error when past the 4095 selector limit for IE",desc:"Will error when selector count is > 4095.",browsers:"IE",init:function(e,t){var n=this,r=0;e.addListener("startrule",function(e){r+=e.selectors.length}),e.addListener("endstylesheet",function(){r>4095&&t.report("You have "+r+" selectors. Internet Explorer supports a maximum of 4095 selectors per stylesheet. Consider refactoring.",0,0,n)})}}),CSSLint.addRule({id:"selector-newline",name:"Disallow new-line characters in selectors",desc:"New-line characters in selectors are usually a forgotten comma and not a descendant combinator.",browsers:"All",init:function(e,t){function r(e){var r,i,s,o,u,a,f,l,c,h,p,d=e.selectors;for(r=0,i=d.length;r<i;r++){s=d[r];for(o=0,a=s.parts.length;o<a;o++)for(u=o+1;u<a;u++)f=s.parts[o],l=s.parts[u],c=f.type,h=f.line,p=l.line,c==="descendant"&&p>h&&t.report("newline character found in selector (forgot a comma?)",h,d[r].parts[0].col,n)}}var n=this;e.addListener("startrule",r)}}),CSSLint.addRule({id:"shorthand",name:"Require shorthand properties",desc:"Use shorthand properties where possible.",browsers:"All",init:function(e,t){function f(){u={}}function l(e){var r,i,s,o;for(r in a)if(a.hasOwnProperty(r)){o=0;for(i=0,s=a[r].length;i<s;i++)o+=u[a[r][i]]?1:0;o===a[r].length&&t.report("The properties "+a[r].join(", ")+" can be replaced by "+r+".",e.line,e.col,n)}}var n=this,r,i,s,o={},u,a={margin:["margin-top","margin-bottom","margin-left","margin-right"],padding:["padding-top","padding-bottom","padding-left","padding-right"]};for(r in a)if(a.hasOwnProperty(r))for(i=0,s=a[r].length;i<s;i++)o[a[r][i]]=r;e.addListener("startrule",f),e.addListener("startfontface",f),e.addListener("property",function(e){var t=e.property.toString().toLowerCase();o[t]&&(u[t]=1)}),e.addListener("endrule",l),e.addListener("endfontface",l)}}),CSSLint.addRule({id:"star-property-hack",name:"Disallow properties with a star prefix",desc:"Checks for the star property hack (targets IE6/7)",browsers:"All",init:function(e,t){var n=this;e.addListener("property",function(e){var r=e.property;r.hack==="*"&&t.report("Property with star prefix found.",e.property.line,e.property.col,n)})}}),CSSLint.addRule({id:"text-indent",name:"Disallow negative text-indent",desc:"Checks for text indent less than -99px",browsers:"All",init:function(e,t){function s(){r=!1,i="inherit"}function o(){r&&i!=="ltr"&&t.report("Negative text-indent doesn't work well with RTL. If you use text-indent for image replacement explicitly set direction for that item to ltr.",r.line,r.col,n)}var n=this,r,i;e.addListener("startrule",s),e.addListener("startfontface",s),e.addListener("property",function(e){var t=e.property.toString().toLowerCase(),n=e.value;t==="text-indent"&&n.parts[0].value<-99?r=e.property:t==="direction"&&n.toString()==="ltr"&&(i="ltr")}),e.addListener("endrule",o),e.addListener("endfontface",o)}}),CSSLint.addRule({id:"underscore-property-hack",name:"Disallow properties with an underscore prefix",desc:"Checks for the underscore property hack (targets IE6)",browsers:"All",init:function(e,t){var n=this;e.addListener("property",function(e){var r=e.property;r.hack==="_"&&t.report("Property with underscore prefix found.",e.property.line,e.property.col,n)})}}),CSSLint.addRule({id:"unique-headings",name:"Headings should only be defined once",desc:"Headings should be defined only once.",browsers:"All",init:function(e,t){var n=this,r={h1:0,h2:0,h3:0,h4:0,h5:0,h6:0};e.addListener("startrule",function(e){var i=e.selectors,s,o,u,a,f;for(a=0;a<i.length;a++){s=i[a],o=s.parts[s.parts.length-1];if(o.elementName&&/(h[1-6])/i.test(o.elementName.toString())){for(f=0;f<o.modifiers.length;f++)if(o.modifiers[f].type==="pseudo"){u=!0;break}u||(r[RegExp.$1]++,r[RegExp.$1]>1&&t.report("Heading ("+o.elementName+") has already been defined.",o.line,o.col,n))}}}),e.addListener("endstylesheet",function(){var e,i=[];for(e in r)r.hasOwnProperty(e)&&r[e]>1&&i.push(r[e]+" "+e+"s");i.length&&t.rollupWarn("You have "+i.join(", ")+" defined in this stylesheet.",n)})}}),CSSLint.addRule({id:"universal-selector",name:"Disallow universal selector",desc:"The universal selector (*) is known to be slow.",browsers:"All",init:function(e,t){var n=this;e.addListener("startrule",function(e){var r=e.selectors,i,s,o;for(o=0;o<r.length;o++)i=r[o],s=i.parts[i.parts.length-1],s.elementName==="*"&&t.report(n.desc,s.line,s.col,n)})}}),CSSLint.addRule({id:"unqualified-attributes",name:"Disallow unqualified attribute selectors",desc:"Unqualified attribute selectors are known to be slow.",browsers:"All",init:function(e,t){var n=this;e.addListener("startrule",function(r){var i=r.selectors,s,o,u,a,f;for(a=0;a<i.length;a++){s=i[a],o=s.parts[s.parts.length-1];if(o.type===e.SELECTOR_PART_TYPE)for(f=0;f<o.modifiers.length;f++)u=o.modifiers[f],u.type==="attribute"&&(!o.elementName||o.elementName==="*")&&t.report(n.desc,o.line,o.col,n)}})}}),CSSLint.addRule({id:"vendor-prefix",name:"Require standard property with vendor prefix",desc:"When using a vendor-prefixed property, make sure to include the standard one.",browsers:"All",init:function(e,t){function o(){r={},i=1}function u(){var e,i,o,u,a,f=[];for(e in r)s[e]&&f.push({actual:e,needed:s[e]});for(i=0,o=f.length;i<o;i++)u=f[i].needed,a=f[i].actual,r[u]?r[u][0].pos<r[a][0].pos&&t.report("Standard property '"+u+"' should come after vendor-prefixed property '"+a+"'.",r[a][0].name.line,r[a][0].name.col,n):t.report("Missing standard property '"+u+"' to go along with '"+a+"'.",r[a][0].name.line,r[a][0].name.col,n)}var n=this,r,i,s={"-webkit-border-radius":"border-radius","-webkit-border-top-left-radius":"border-top-left-radius","-webkit-border-top-right-radius":"border-top-right-radius","-webkit-border-bottom-left-radius":"border-bottom-left-radius","-webkit-border-bottom-right-radius":"border-bottom-right-radius","-o-border-radius":"border-radius","-o-border-top-left-radius":"border-top-left-radius","-o-border-top-right-radius":"border-top-right-radius","-o-border-bottom-left-radius":"border-bottom-left-radius","-o-border-bottom-right-radius":"border-bottom-right-radius","-moz-border-radius":"border-radius","-moz-border-radius-topleft":"border-top-left-radius","-moz-border-radius-topright":"border-top-right-radius","-moz-border-radius-bottomleft":"border-bottom-left-radius","-moz-border-radius-bottomright":"border-bottom-right-radius","-moz-column-count":"column-count","-webkit-column-count":"column-count","-moz-column-gap":"column-gap","-webkit-column-gap":"column-gap","-moz-column-rule":"column-rule","-webkit-column-rule":"column-rule","-moz-column-rule-style":"column-rule-style","-webkit-column-rule-style":"column-rule-style","-moz-column-rule-color":"column-rule-color","-webkit-column-rule-color":"column-rule-color","-moz-column-rule-width":"column-rule-width","-webkit-column-rule-width":"column-rule-width","-moz-column-width":"column-width","-webkit-column-width":"column-width","-webkit-column-span":"column-span","-webkit-columns":"columns","-moz-box-shadow":"box-shadow","-webkit-box-shadow":"box-shadow","-moz-transform":"transform","-webkit-transform":"transform","-o-transform":"transform","-ms-transform":"transform","-moz-transform-origin":"transform-origin","-webkit-transform-origin":"transform-origin","-o-transform-origin":"transform-origin","-ms-transform-origin":"transform-origin","-moz-box-sizing":"box-sizing","-webkit-box-sizing":"box-sizing"};e.addListener("startrule",o),e.addListener("startfontface",o),e.addListener("startpage",o),e.addListener("startpagemargin",o),e.addListener("startkeyframerule",o),e.addListener("property",function(e){var t=e.property.text.toLowerCase();r[t]||(r[t]=[]),r[t].push({name:e.property,value:e.value,pos:i++})}),e.addListener("endrule",u),e.addListener("endfontface",u),e.addListener("endpage",u),e.addListener("endpagemargin",u),e.addListener("endkeyframerule",u)}}),CSSLint.addRule({id:"zero-units",name:"Disallow units for 0 values",desc:"You don't need to specify units when a value is 0.",browsers:"All",init:function(e,t){var n=this;e.addListener("property",function(e){var r=e.value.parts,i=0,s=r.length;while(i<s)(r[i].units||r[i].type==="percentage")&&r[i].value===0&&r[i].type!=="time"&&t.report("Values of 0 shouldn't have units specified.",r[i].line,r[i].col,n),i++})}}),function(){var e=function(e){return!e||e.constructor!==String?"":e.replace(/[\"&><]/g,function(e){switch(e){case'"':return"&quot;";case"&":return"&amp;";case"<":return"&lt;";case">":return"&gt;"}})};CSSLint.addFormatter({id:"checkstyle-xml",name:"Checkstyle XML format",startFormat:function(){return'<?xml version="1.0" encoding="utf-8"?><checkstyle>'},endFormat:function(){return"</checkstyle>"},readError:function(t,n){return'<file name="'+e(t)+'"><error line="0" column="0" severty="error" message="'+e(n)+'"></error></file>'},formatResults:function(t,n){var r=t.messages,i=[],s=function(e){return!!e&&"name"in e?"net.csslint."+e.name.replace(/\s/g,""):""};return r.length>0&&(i.push('<file name="'+n+'">'),CSSLint.Util.forEach(r,function(t){t.rollup||i.push('<error line="'+t.line+'" column="'+t.col+'" severity="'+t.type+'"'+' message="'+e(t.message)+'" source="'+s(t.rule)+'"/>')}),i.push("</file>")),i.join("")}})}(),CSSLint.addFormatter({id:"compact",name:"Compact, 'porcelain' format",startFormat:function(){return""},endFormat:function(){return""},formatResults:function(e,t,n){var r=e.messages,i="";n=n||{};var s=function(e){return e.charAt(0).toUpperCase()+e.slice(1)};return r.length===0?n.quiet?"":t+": Lint Free!":(CSSLint.Util.forEach(r,function(e){e.rollup?i+=t+": "+s(e.type)+" - "+e.message+"\n":i+=t+": "+"line "+e.line+", col "+e.col+", "+s(e.type)+" - "+e.message+" ("+e.rule.id+")\n"}),i)}}),CSSLint.addFormatter({id:"csslint-xml",name:"CSSLint XML format",startFormat:function(){return'<?xml version="1.0" encoding="utf-8"?><csslint>'},endFormat:function(){return"</csslint>"},formatResults:function(e,t){var n=e.messages,r=[],i=function(e){return!e||e.constructor!==String?"":e.replace(/\"/g,"'").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")};return n.length>0&&(r.push('<file name="'+t+'">'),CSSLint.Util.forEach(n,function(e){e.rollup?r.push('<issue severity="'+e.type+'" reason="'+i(e.message)+'" evidence="'+i(e.evidence)+'"/>'):r.push('<issue line="'+e.line+'" char="'+e.col+'" severity="'+e.type+'"'+' reason="'+i(e.message)+'" evidence="'+i(e.evidence)+'"/>')}),r.push("</file>")),r.join("")}}),CSSLint.addFormatter({id:"junit-xml",name:"JUNIT XML format",startFormat:function(){return'<?xml version="1.0" encoding="utf-8"?><testsuites>'},endFormat:function(){return"</testsuites>"},formatResults:function(e,t){var n=e.messages,r=[],i={error:0,failure:0},s=function(e){return!!e&&"name"in e?"net.csslint."+e.name.replace(/\s/g,""):""},o=function(e){return!e||e.constructor!==String?"":e.replace(/\"/g,"'").replace(/</g,"&lt;").replace(/>/g,"&gt;")};return n.length>0&&(n.forEach(function(e){var t=e.type==="warning"?"error":e.type;e.rollup||(r.push('<testcase time="0" name="'+s(e.rule)+'">'),r.push("<"+t+' message="'+o(e.message)+'"><![CDATA['+e.line+":"+e.col+":"+o(e.evidence)+"]]></"+t+">"),r.push("</testcase>"),i[t]+=1)}),r.unshift('<testsuite time="0" tests="'+n.length+'" skipped="0" errors="'+i.error+'" failures="'+i.failure+'" package="net.csslint" name="'+t+'">'),r.push("</testsuite>")),r.join("")}}),CSSLint.addFormatter({id:"lint-xml",name:"Lint XML format",startFormat:function(){return'<?xml version="1.0" encoding="utf-8"?><lint>'},endFormat:function(){return"</lint>"},formatResults:function(e,t){var n=e.messages,r=[],i=function(e){return!e||e.constructor!==String?"":e.replace(/\"/g,"'").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")};return n.length>0&&(r.push('<file name="'+t+'">'),CSSLint.Util.forEach(n,function(e){e.rollup?r.push('<issue severity="'+e.type+'" reason="'+i(e.message)+'" evidence="'+i(e.evidence)+'"/>'):r.push('<issue line="'+e.line+'" char="'+e.col+'" severity="'+e.type+'"'+' reason="'+i(e.message)+'" evidence="'+i(e.evidence)+'"/>')}),r.push("</file>")),r.join("")}}),CSSLint.addFormatter({id:"text",name:"Plain Text",startFormat:function(){return""},endFormat:function(){return""},formatResults:function(e,t,n){var r=e.messages,i="";n=n||{};if(r.length===0)return n.quiet?"":"\n\ncsslint: No errors in "+t+".";i="\n\ncsslint: There ",r.length===1?i+="is 1 problem":i+="are "+r.length+" problems",i+=" in "+t+".";var s=t.lastIndexOf("/"),o=t;return s===-1&&(s=t.lastIndexOf("\\")),s>-1&&(o=t.substring(s+1)),CSSLint.Util.forEach(r,function(e,t){i=i+"\n\n"+o,e.rollup?(i+="\n"+(t+1)+": "+e.type,i+="\n"+e.message):(i+="\n"+(t+1)+": "+e.type+" at line "+e.line+", col "+e.col,i+="\n"+e.message,i+="\n"+e.evidence)}),i}}),module.exports.CSSLint=CSSLint}),ace.define("ace/mode/css_worker",[],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("../worker/mirror").Mirror,o=e("./css/csslint").CSSLint,u=t.Worker=function(e){s.call(this,e),this.setTimeout(400),this.ruleset=null,this.setDisabledRules("ids|order-alphabetical"),this.setInfoRules("adjoining-classes|qualified-headings|zero-units|gradients|import|outline-none|vendor-prefix")};r.inherits(u,s),function(){this.setInfoRules=function(e){typeof e=="string"&&(e=e.split("|")),this.infoRules=i.arrayToMap(e),this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.setDisabledRules=function(e){if(!e)this.ruleset=null;else{typeof e=="string"&&(e=e.split("|"));var t={};o.getRules().forEach(function(e){t[e.id]=!0}),e.forEach(function(e){delete t[e]}),this.ruleset=t}this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.onUpdate=function(){var e=this.doc.getValue();if(!e)return this.sender.emit("annotate",[]);var t=this.infoRules,n=o.verify(e,this.ruleset);this.sender.emit("annotate",n.messages.map(function(e){return{row:e.line-1,column:e.col-1,text:e.message,type:t[e.rule.id]?"info":e.type,rule:e.rule.name}}))}}.call(u.prototype)}),ace.define("ace/lib/es5-shim",[],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)=="[object Array]"});var m=Object("a"),g=m[0]!="a"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _=" \n\x0b\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";if(!String.prototype.trim||_.trim()){_="["+_+"]";var D=new RegExp("^"+_+_+"*"),P=new RegExp(_+_+"*$");String.prototype.trim=function(){return String(this).replace(D,"").replace(P,"")}}var F=function(e){if(e==null)throw new TypeError("can't convert "+e+" to object");return Object(e)}}) \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/worker-html.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/worker-html.js new file mode 100644 index 0000000..bfbaa84 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/worker-html.js @@ -0,0 +1 @@ +"no use strict";!function(e){function t(e,t){var n=e,r="";while(n){var i=t[n];if(typeof i=="string")return i+r;if(i)return i.location.replace(/\/*$/,"/")+(r||i.main||i.name);if(i===!1)return"";var s=n.lastIndexOf("/");if(s===-1)break;r=n.substr(s)+r,n=n.slice(0,s)}return e}if(typeof e.window!="undefined"&&e.document)return;if(e.require&&e.define)return;e.console||(e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console),e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){postMessage({type:"error",data:{message:e,data:i.data,file:t,line:n,col:r,stack:i.stack}})},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(r,i){i||(i=r,r=null);if(!i.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");i=e.normalizeModule(r,i);var s=e.require.modules[i];if(s)return s.initialized||(s.initialized=!0,s.exports=s.factory().exports),s.exports;if(!e.require.tlns)return console.log("unable to load "+i);var o=t(i,e.require.tlns);return o.slice(-3)!=".js"&&(o+=".js"),e.require.id=i,e.require.modules[i]={},importScripts(o),e.require(r,i)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id);if(typeof r!="function"){e.require.modules[t]={exports:r,initialized:!0};return}n.length||(n=["require","exports","module"]);var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.slice(0,r.length).map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},require.tlns={},e.initBaseUrls=function(t){for(var n in t)require.tlns[n]=t[n]},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var n=e.main=null,r=e.sender=null;e.onmessage=function(t){var i=t.data;if(i.event&&r)r._signal(i.event,i.data);else if(i.command)if(n[i.command])n[i.command].apply(n,i.args);else{if(!e[i.command])throw new Error("Unknown command:"+i.command);e[i.command].apply(e,i.args)}else if(i.init){e.initBaseUrls(i.tlns),require("ace/lib/es5-shim"),r=e.sender=e.initSender();var s=require(i.module)[i.classname];n=e.main=new s(r)}}}(this),ace.define("ace/lib/oop",[],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/lib/lang",[],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function s(e){if(typeof e!="object"||!e)return e;var t;if(Array.isArray(e)){t=[];for(var n=0;n<e.length;n++)t[n]=s(e[n]);return t}if(Object.prototype.toString.call(e)!=="[object Object]")return e;t={};for(var n in e)t[n]=s(e[n]);return t},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return(""+e).replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define("ace/range",[],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define("ace/apply_delta",[],function(e,t,n){"use strict";function r(e,t){throw console.log("Invalid Delta:",e),"Invalid Delta: "+t}function i(e,t){return t.row>=0&&t.row<e.length&&t.column>=0&&t.column<=e[t.row].length}function s(e,t){t.action!="insert"&&t.action!="remove"&&r(t,"delta.action must be 'insert' or 'remove'"),t.lines instanceof Array||r(t,"delta.lines must be an Array"),(!t.start||!t.end)&&r(t,"delta.start/end must be an present");var n=t.start;i(e,t.start)||r(t,"delta.start must be contained in document");var s=t.end;t.action=="remove"&&!i(e,s)&&r(t,"delta.end must contained in document for 'remove' actions");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,"delta.range must match delta lines")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||"";switch(t.action){case"insert":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case"remove":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),ace.define("ace/lib/event_emitter",[],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)});if(!t)return new Promise(function(e){t=e})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t)r&&this.setDefaultHandler(e,r.pop());else if(r){var i=r.indexOf(t);i!=-1&&r.splice(i,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?"unshift":"push"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define("ace/anchor",[],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){function e(e,t,n){var r=n?e.column<=t.column:e.column<t.column;return e.row<t.row||e.row==t.row&&r}function t(t,n,r){var i=t.action=="insert",s=(i?1:-1)*(t.end.row-t.start.row),o=(i?1:-1)*(t.end.column-t.start.column),u=t.start,a=i?u:t.end;return e(n,u,r)?{row:n.row,column:n.column}:e(a,n,!r)?{row:n.row+s,column:n.column+(n.row==a.row?o:0)}:{row:u.row,column:u.column}}r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){if(e.start.row==e.end.row&&e.start.row!=this.row)return;if(e.start.row>this.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",[],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./apply_delta").applyDelta,s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=e("./anchor").Anchor,a=function(e){this.$lines=[""],e.length===0?this.$lines=[""]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."),this.insertMergedLines(e,["",""])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:"insert",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e<this.getLength()?(t=t.concat([""]),n=0):(t=[""].concat(t),e--,n=this.$lines[e].length),this.insertMergedLines({row:e,column:n},t)},this.insertMergedLines=function(e,t){var n=this.clippedPos(e.row,e.column),r={row:n.row+t.length-1,column:(t.length==1?n.column:0)+t[t.length-1].length};return this.applyDelta({start:n,end:r,action:"insert",lines:t}),this.clonePos(r)},this.remove=function(e){var t=this.clippedPos(e.start.row,e.start.column),n=this.clippedPos(e.end.row,e.end.column);return this.applyDelta({start:t,end:n,action:"remove",lines:this.getLinesForRange({start:t,end:n})}),this.clonePos(t)},this.removeInLine=function(e,t,n){var r=this.clippedPos(e,t),i=this.clippedPos(e,n);return this.applyDelta({start:r,end:i,action:"remove",lines:this.getLinesForRange({start:r,end:i})},!0),this.clonePos(r)},this.removeFullLines=function(e,t){e=Math.min(Math.max(0,e),this.getLength()-1),t=Math.min(Math.max(0,t),this.getLength()-1);var n=t==this.getLength()-1&&e>0,r=t<this.getLength()-1,i=n?e-1:e,s=n?this.getLine(i).length:0,u=r?t+1:t,a=r?0:this.getLine(u).length,f=new o(i,s,u,a),l=this.$lines.slice(e,t+1);return this.applyDelta({start:f.start,end:f.end,action:"remove",lines:this.getLinesForRange(f)}),l},this.removeNewLine=function(e){e<this.getLength()-1&&e>=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++)this.applyDelta(e[t])},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action=="insert";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4?this.$splitAndapplyLargeDelta(e,2e4):(i(this.$lines,e,t),this._signal("change",e))},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length-t+1,i=e.start.row,s=e.start.column;for(var o=0,u=0;o<r;o=u){u+=t-1;var a=n.slice(o,u);a.push(""),this.applyDelta({start:this.pos(i+o,s),end:this.pos(i+u,s=0),action:e.action,lines:a},!0)}e.lines=n.slice(o),e.start.row=i+o,e.start.column=s,this.applyDelta(e,!0)},this.revertDelta=function(e){this.applyDelta({start:this.clonePos(e.start),end:this.clonePos(e.end),action:e.action=="insert"?"remove":"insert",lines:e.lines.slice()})},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:e+n[s-1].length+r}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(a.prototype),t.Document=a}),ace.define("ace/worker/mirror",[],function(e,t,n){"use strict";var r=e("../range").Range,i=e("../document").Document,s=e("../lib/lang"),o=t.Mirror=function(e){this.sender=e;var t=this.doc=new i(""),n=this.deferredUpdate=s.delayedCall(this.onUpdate.bind(this)),r=this;e.on("change",function(e){var i=e.data;if(i[0].start)t.applyDeltas(i);else for(var s=0;s<i.length;s+=2){if(Array.isArray(i[s+1]))var o={action:"insert",start:i[s],lines:i[s+1]};else var o={action:"remove",start:i[s],end:i[s+1]};t.applyDelta(o,!0)}if(r.$timeout)return n.schedule(r.$timeout);r.onUpdate()})};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(o.prototype)}),ace.define("ace/mode/html/saxparser",[],function(e,t,n){n.exports=function r(t,n,i){function s(u,a){if(!n[u]){if(!t[u]){var f=typeof e=="function"&&e;if(!a&&f)return f(u,!0);if(o)return o(u,!0);throw new Error("Cannot find module '"+u+"'")}var l=n[u]={exports:{}};t[u][0].call(l.exports,function(e){var n=t[u][1][e];return s(n?n:e)},l,l.exports,r,t,n,i)}return n[u].exports}var o=typeof e=="function"&&e;for(var u=0;u<i.length;u++)s(i[u]);return s}({1:[function(e,t,n){function r(e){if(e.namespaceURI==="http://www.w3.org/1999/xhtml")return e.localName==="applet"||e.localName==="caption"||e.localName==="marquee"||e.localName==="object"||e.localName==="table"||e.localName==="td"||e.localName==="th";if(e.namespaceURI==="http://www.w3.org/1998/Math/MathML")return e.localName==="mi"||e.localName==="mo"||e.localName==="mn"||e.localName==="ms"||e.localName==="mtext"||e.localName==="annotation-xml";if(e.namespaceURI==="http://www.w3.org/2000/svg")return e.localName==="foreignObject"||e.localName==="desc"||e.localName==="title"}function i(e){return r(e)||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="ol"||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="ul"}function s(e){return e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="table"||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="html"}function o(e){return e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="tbody"||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="tfoot"||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="thead"||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="html"}function u(e){return e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="tr"||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="html"}function a(e){return r(e)||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="button"}function f(e){return(e.namespaceURI!=="http://www.w3.org/1999/xhtml"||e.localName!=="optgroup")&&(e.namespaceURI!=="http://www.w3.org/1999/xhtml"||e.localName!=="option")}function l(){this.elements=[],this.rootNode=null,this.headElement=null,this.bodyElement=null}l.prototype._inScope=function(e,t){for(var n=this.elements.length-1;n>=0;n--){var r=this.elements[n];if(r.localName===e)return!0;if(t(r))return!1}},l.prototype.push=function(e){this.elements.push(e)},l.prototype.pushHtmlElement=function(e){this.rootNode=e.node,this.push(e)},l.prototype.pushHeadElement=function(e){this.headElement=e.node,this.push(e)},l.prototype.pushBodyElement=function(e){this.bodyElement=e.node,this.push(e)},l.prototype.pop=function(){return this.elements.pop()},l.prototype.remove=function(e){this.elements.splice(this.elements.indexOf(e),1)},l.prototype.popUntilPopped=function(e){var t;do t=this.pop();while(t.localName!=e)},l.prototype.popUntilTableScopeMarker=function(){while(!s(this.top))this.pop()},l.prototype.popUntilTableBodyScopeMarker=function(){while(!o(this.top))this.pop()},l.prototype.popUntilTableRowScopeMarker=function(){while(!u(this.top))this.pop()},l.prototype.item=function(e){return this.elements[e]},l.prototype.contains=function(e){return this.elements.indexOf(e)!==-1},l.prototype.inScope=function(e){return this._inScope(e,r)},l.prototype.inListItemScope=function(e){return this._inScope(e,i)},l.prototype.inTableScope=function(e){return this._inScope(e,s)},l.prototype.inButtonScope=function(e){return this._inScope(e,a)},l.prototype.inSelectScope=function(e){return this._inScope(e,f)},l.prototype.hasNumberedHeaderElementInScope=function(){for(var e=this.elements.length-1;e>=0;e--){var t=this.elements[e];if(t.isNumberedHeader())return!0;if(r(t))return!1}},l.prototype.furthestBlockForFormattingElement=function(e){var t=null;for(var n=this.elements.length-1;n>=0;n--){var r=this.elements[n];if(r.node===e)break;r.isSpecial()&&(t=r)}return t},l.prototype.findIndex=function(e){for(var t=this.elements.length-1;t>=0;t--)if(this.elements[t].localName==e)return t;return-1},l.prototype.remove_openElements_until=function(e){var t=!1,n;while(!t)n=this.elements.pop(),t=e(n);return n},Object.defineProperty(l.prototype,"top",{get:function(){return this.elements[this.elements.length-1]}}),Object.defineProperty(l.prototype,"length",{get:function(){return this.elements.length}}),n.ElementStack=l},{}],2:[function(e,t,n){function o(e){return e>="0"&&e<="9"||e>="a"&&e<="z"||e>="A"&&e<="Z"}function u(e){return e>="0"&&e<="9"||e>="a"&&e<="f"||e>="A"&&e<="F"}function a(e){return e>="0"&&e<="9"}var r=e("html5-entities"),i=e("./InputStream").InputStream,s={};Object.keys(r).forEach(function(e){for(var t=0;t<e.length;t++)s[e.substring(0,t+1)]=!0});var f={};f.consumeEntity=function(e,t,n){var f="",l="",c=e.char();if(c===i.EOF)return!1;l+=c;if(c==" "||c=="\n"||c=="\x0b"||c==" "||c=="<"||c=="&")return e.unget(l),!1;if(n===c)return e.unget(l),!1;if(c=="#"){c=e.shift(1);if(c===i.EOF)return t._parseError("expected-numeric-entity-but-got-eof"),e.unget(l),!1;l+=c;var h=10,p=a;if(c=="x"||c=="X"){h=16,p=u,c=e.shift(1);if(c===i.EOF)return t._parseError("expected-numeric-entity-but-got-eof"),e.unget(l),!1;l+=c}if(p(c)){var d="";while(c!==i.EOF&&p(c))d+=c,c=e.char();d=parseInt(d,h);var v=this.replaceEntityNumbers(d);v&&(t._parseError("invalid-numeric-entity-replaced"),d=v);if(d>65535&&d<=1114111){d-=65536;var m=((1047552&d)>>10)+55296,g=(1023&d)+56320;f=String.fromCharCode(m,g)}else f=String.fromCharCode(d);return c!==";"&&(t._parseError("numeric-entity-without-semicolon"),e.unget(c)),f}return e.unget(l),t._parseError("expected-numeric-entity"),!1}if(c>="a"&&c<="z"||c>="A"&&c<="Z"){var y="";while(s[l]){r[l]&&(y=l);if(c==";")break;c=e.char();if(c===i.EOF)break;l+=c}return y?(f=r[y],c===";"||!n||!o(c)&&c!=="="?(l.length>y.length&&e.unget(l.substring(y.length)),c!==";"&&t._parseError("named-entity-without-semicolon"),f):(e.unget(l),!1)):(t._parseError("expected-named-entity"),e.unget(l),!1)}},f.replaceEntityNumbers=function(e){switch(e){case 0:return 65533;case 19:return 16;case 128:return 8364;case 129:return 129;case 130:return 8218;case 131:return 402;case 132:return 8222;case 133:return 8230;case 134:return 8224;case 135:return 8225;case 136:return 710;case 137:return 8240;case 138:return 352;case 139:return 8249;case 140:return 338;case 141:return 141;case 142:return 381;case 143:return 143;case 144:return 144;case 145:return 8216;case 146:return 8217;case 147:return 8220;case 148:return 8221;case 149:return 8226;case 150:return 8211;case 151:return 8212;case 152:return 732;case 153:return 8482;case 154:return 353;case 155:return 8250;case 156:return 339;case 157:return 157;case 158:return 382;case 159:return 376;default:if(e>=55296&&e<=57343||e>1114111)return 65533;if(e>=1&&e<=8||e>=14&&e<=31||e>=127&&e<=159||e>=64976&&e<=65007||e==11||e==65534||e==131070||e==3145726||e==196607||e==262142||e==262143||e==327678||e==327679||e==393214||e==393215||e==458750||e==458751||e==524286||e==524287||e==589822||e==589823||e==655358||e==655359||e==720894||e==720895||e==786430||e==786431||e==851966||e==851967||e==917502||e==917503||e==983038||e==983039||e==1048574||e==1048575||e==1114110||e==1114111)return e}},n.EntityParser=f},{"./InputStream":3,"html5-entities":12}],3:[function(e,t,n){function r(){this.data="",this.start=0,this.committed=0,this.eof=!1,this.lastLocation={line:0,column:0}}r.EOF=-1,r.DRAIN=-2,r.prototype={slice:function(){if(this.start>=this.data.length){if(!this.eof)throw r.DRAIN;return r.EOF}return this.data.slice(this.start,this.data.length)},"char":function(){if(!this.eof&&this.start>=this.data.length-1)throw r.DRAIN;if(this.start>=this.data.length)return r.EOF;var e=this.data[this.start++];return e==="\r"&&(e="\n"),e},advance:function(e){this.start+=e;if(this.start>=this.data.length){if(!this.eof)throw r.DRAIN;return r.EOF}this.committed>this.data.length/2&&(this.lastLocation=this.location(),this.data=this.data.slice(this.committed),this.start=this.start-this.committed,this.committed=0)},matchWhile:function(e){if(this.eof&&this.start>=this.data.length)return"";var t=new RegExp("^"+e+"+"),n=t.exec(this.slice());if(n){if(!this.eof&&n[0].length==this.data.length-this.start)throw r.DRAIN;return this.advance(n[0].length),n[0]}return""},matchUntil:function(e){var t,n;n=this.slice();if(n===r.EOF)return"";if(t=(new RegExp(e+(this.eof?"|$":""))).exec(n)){var i=this.data.slice(this.start,this.start+t.index);return this.advance(t.index),i.replace(/\r/g,"\n").replace(/\n{2,}/g,"\n")}throw r.DRAIN},append:function(e){this.data+=e},shift:function(e){if(!this.eof&&this.start+e>=this.data.length)throw r.DRAIN;if(this.eof&&this.start>=this.data.length)return r.EOF;var t=this.data.slice(this.start,this.start+e).toString();return this.advance(Math.min(e,this.data.length-this.start)),t},peek:function(e){if(!this.eof&&this.start+e>=this.data.length)throw r.DRAIN;return this.eof&&this.start>=this.data.length?r.EOF:this.data.slice(this.start,Math.min(this.start+e,this.data.length)).toString()},length:function(){return this.data.length-this.start-1},unget:function(e){if(e===r.EOF)return;this.start-=e.length},undo:function(){this.start=this.committed},commit:function(){this.committed=this.start},location:function(){var e=this.lastLocation.line,t=this.lastLocation.column,n=this.data.slice(0,this.committed),r=n.match(/\n/g),i=r?e+r.length:e,s=r?n.length-n.lastIndexOf("\n")-1:t+n.length;return{line:i,column:s}}},n.InputStream=r},{}],4:[function(e,t,n){function i(e,t,n,r){this.localName=t,this.namespaceURI=e,this.attributes=n,this.node=r}function s(e,t){for(var n=0;n<e.attributes.length;n++)if(e.attributes[n].nodeName==t)return e.attributes[n].nodeValue;return null}var r={"http://www.w3.org/1999/xhtml":["address","applet","area","article","aside","base","basefont","bgsound","blockquote","body","br","button","caption","center","col","colgroup","dd","details","dir","div","dl","dt","embed","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","iframe","img","input","isindex","li","link","listing","main","marquee","menu","menuitem","meta","nav","noembed","noframes","noscript","object","ol","p","param","plaintext","pre","script","section","select","source","style","summary","table","tbody","td","textarea","tfoot","th","thead","title","tr","track","ul","wbr","xmp"],"http://www.w3.org/1998/Math/MathML":["mi","mo","mn","ms","mtext","annotation-xml"],"http://www.w3.org/2000/svg":["foreignObject","desc","title"]};i.prototype.isSpecial=function(){return this.namespaceURI in r&&r[this.namespaceURI].indexOf(this.localName)>-1},i.prototype.isFosterParenting=function(){return this.namespaceURI==="http://www.w3.org/1999/xhtml"?this.localName==="table"||this.localName==="tbody"||this.localName==="tfoot"||this.localName==="thead"||this.localName==="tr":!1},i.prototype.isNumberedHeader=function(){return this.namespaceURI==="http://www.w3.org/1999/xhtml"?this.localName==="h1"||this.localName==="h2"||this.localName==="h3"||this.localName==="h4"||this.localName==="h5"||this.localName==="h6":!1},i.prototype.isForeign=function(){return this.namespaceURI!="http://www.w3.org/1999/xhtml"},i.prototype.isHtmlIntegrationPoint=function(){if(this.namespaceURI==="http://www.w3.org/1998/Math/MathML"){if(this.localName!=="annotation-xml")return!1;var e=s(this,"encoding");return e?(e=e.toLowerCase(),e==="text/html"||e==="application/xhtml+xml"):!1}return this.namespaceURI==="http://www.w3.org/2000/svg"?this.localName==="foreignObject"||this.localName==="desc"||this.localName==="title":!1},i.prototype.isMathMLTextIntegrationPoint=function(){return this.namespaceURI==="http://www.w3.org/1998/Math/MathML"?this.localName==="mi"||this.localName==="mo"||this.localName==="mn"||this.localName==="ms"||this.localName==="mtext":!1},n.StackItem=i},{}],5:[function(e,t,n){function s(e){return e===" "||e==="\n"||e===" "||e==="\r"||e==="\f"}function o(e){return e>="A"&&e<="Z"||e>="a"&&e<="z"}function u(e){this._tokenHandler=e,this._state=u.DATA,this._inputStream=new r,this._currentToken=null,this._temporaryBuffer="",this._additionalAllowedCharacter=""}var r=e("./InputStream").InputStream,i=e("./EntityParser").EntityParser;u.prototype._parseError=function(e,t){this._tokenHandler.parseError(e,t)},u.prototype._emitToken=function(e){if(e.type==="StartTag")for(var t=1;t<e.data.length;t++)e.data[t].nodeName||e.data.splice(t--,1);else e.type==="EndTag"&&(e.selfClosing&&this._parseError("self-closing-flag-on-end-tag"),e.data.length!==0&&this._parseError("attributes-in-end-tag"));this._tokenHandler.processToken(e),e.type==="StartTag"&&e.selfClosing&&!this._tokenHandler.isSelfClosingFlagAcknowledged()&&this._parseError("non-void-element-with-trailing-solidus",{name:e.name})},u.prototype._emitCurrentToken=function(){this._state=u.DATA,this._emitToken(this._currentToken)},u.prototype._currentAttribute=function(){return this._currentToken.data[this._currentToken.data.length-1]},u.prototype.setState=function(e){this._state=e},u.prototype.tokenize=function(e){function n(e){var n=e.char();if(n===r.EOF)return t._emitToken({type:"EOF",data:null}),!1;if(n==="&")t.setState(a);else if(n==="<")t.setState(j);else if(n==="\0")t._emitToken({type:"Characters",data:n}),e.commit();else{var i=e.matchUntil("&|<|\0");t._emitToken({type:"Characters",data:n+i}),e.commit()}return!0}function a(e){var r=i.consumeEntity(e,t);return t.setState(n),t._emitToken({type:"Characters",data:r||"&"}),!0}function f(e){var n=e.char();if(n===r.EOF)return t._emitToken({type:"EOF",data:null}),!1;if(n==="&")t.setState(l);else if(n==="<")t.setState(d);else if(n==="\0")t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),e.commit();else{var i=e.matchUntil("&|<|\0");t._emitToken({type:"Characters",data:n+i}),e.commit()}return!0}function l(e){var n=i.consumeEntity(e,t);return t.setState(f),t._emitToken({type:"Characters",data:n||"&"}),!0}function c(e){var n=e.char();if(n===r.EOF)return t._emitToken({type:"EOF",data:null}),!1;if(n==="<")t.setState(g);else if(n==="\0")t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),e.commit();else{var i=e.matchUntil("<|\0");t._emitToken({type:"Characters",data:n+i})}return!0}function h(e){var n=e.char();if(n===r.EOF)return t._emitToken({type:"EOF",data:null}),!1;if(n==="\0")t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),e.commit();else{var i=e.matchUntil("\0");t._emitToken({type:"Characters",data:n+i})}return!0}function p(e){var n=e.char();if(n===r.EOF)return t._emitToken({type:"EOF",data:null}),!1;if(n==="<")t.setState(w);else if(n==="\0")t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),e.commit();else{var i=e.matchUntil("<|\0");t._emitToken({type:"Characters",data:n+i})}return!0}function d(e){var n=e.char();return n==="/"?(this._temporaryBuffer="",t.setState(v)):(t._emitToken({type:"Characters",data:"<"}),e.unget(n),t.setState(f)),!0}function v(e){var n=e.char();return o(n)?(this._temporaryBuffer+=n,t.setState(m)):(t._emitToken({type:"Characters",data:"</"}),e.unget(n),t.setState(f)),!0}function m(e){var r=t._currentToken&&t._currentToken.name===this._temporaryBuffer.toLowerCase(),i=e.char();return s(i)&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t.setState(q)):i==="/"&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t.setState(K)):i===">"&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t._emitCurrentToken(),t.setState(n)):o(i)?(this._temporaryBuffer+=i,e.commit()):(t._emitToken({type:"Characters",data:"</"+this._temporaryBuffer}),e.unget(i),t.setState(f)),!0}function g(e){var n=e.char();return n==="/"?(this._temporaryBuffer="",t.setState(y)):(t._emitToken({type:"Characters",data:"<"}),e.unget(n),t.setState(c)),!0}function y(e){var n=e.char();return o(n)?(this._temporaryBuffer+=n,t.setState(b)):(t._emitToken({type:"Characters",data:"</"}),e.unget(n),t.setState(c)),!0}function b(e){var r=t._currentToken&&t._currentToken.name===this._temporaryBuffer.toLowerCase(),i=e.char();return s(i)&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t.setState(q)):i==="/"&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t.setState(K)):i===">"&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t._emitCurrentToken(),t.setState(n)):o(i)?(this._temporaryBuffer+=i,e.commit()):(t._emitToken({type:"Characters",data:"</"+this._temporaryBuffer}),e.unget(i),t.setState(c)),!0}function w(e){var n=e.char();return n==="/"?(this._temporaryBuffer="",t.setState(E)):n==="!"?(t._emitToken({type:"Characters",data:"<!"}),t.setState(x)):(t._emitToken({type:"Characters",data:"<"}),e.unget(n),t.setState(p)),!0}function E(e){var n=e.char();return o(n)?(this._temporaryBuffer+=n,t.setState(S)):(t._emitToken({type:"Characters",data:"</"}),e.unget(n),t.setState(p)),!0}function S(e){var n=t._currentToken&&t._currentToken.name===this._temporaryBuffer.toLowerCase(),r=e.char();return s(r)&&n?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t.setState(q)):r==="/"&&n?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t.setState(K)):r===">"&&n?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t._emitCurrentToken()):o(r)?(this._temporaryBuffer+=r,e.commit()):(t._emitToken({type:"Characters",data:"</"+this._temporaryBuffer}),e.unget(r),t.setState(p)),!0}function x(e){var n=e.char();return n==="-"?(t._emitToken({type:"Characters",data:"-"}),t.setState(T)):(e.unget(n),t.setState(p)),!0}function T(e){var n=e.char();return n==="-"?(t._emitToken({type:"Characters",data:"-"}),t.setState(k)):(e.unget(n),t.setState(p)),!0}function N(e){var i=e.char();if(i===r.EOF)e.unget(i),t.setState(n);else if(i==="-")t._emitToken({type:"Characters",data:"-"}),t.setState(C);else if(i==="<")t.setState(L);else if(i==="\0")t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),e.commit();else{var s=e.matchUntil("<|-|\0");t._emitToken({type:"Characters",data:i+s})}return!0}function C(e){var i=e.char();return i===r.EOF?(e.unget(i),t.setState(n)):i==="-"?(t._emitToken({type:"Characters",data:"-"}),t.setState(k)):i==="<"?t.setState(L):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),t.setState(N)):(t._emitToken({type:"Characters",data:i}),t.setState(N)),!0}function k(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-script"),e.unget(i),t.setState(n)):i==="<"?t.setState(L):i===">"?(t._emitToken({type:"Characters",data:">"}),t.setState(p)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),t.setState(N)):(t._emitToken({type:"Characters",data:i}),t.setState(N)),!0}function L(e){var n=e.char();return n==="/"?(this._temporaryBuffer="",t.setState(A)):o(n)?(t._emitToken({type:"Characters",data:"<"+n}),this._temporaryBuffer=n,t.setState(M)):(t._emitToken({type:"Characters",data:"<"}),e.unget(n),t.setState(N)),!0}function A(e){var n=e.char();return o(n)?(this._temporaryBuffer=n,t.setState(O)):(t._emitToken({type:"Characters",data:"</"}),e.unget(n),t.setState(N)),!0}function O(e){var r=t._currentToken&&t._currentToken.name===this._temporaryBuffer.toLowerCase(),i=e.char();return s(i)&&r?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t.setState(q)):i==="/"&&r?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t.setState(K)):i===">"&&r?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t.setState(n),t._emitCurrentToken()):o(i)?(this._temporaryBuffer+=i,e.commit()):(t._emitToken({type:"Characters",data:"</"+this._temporaryBuffer}),e.unget(i),t.setState(N)),!0}function M(e){var n=e.char();return s(n)||n==="/"||n===">"?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer.toLowerCase()==="script"?t.setState(_):t.setState(N)):o(n)?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer+=n,e.commit()):(e.unget(n),t.setState(N)),!0}function _(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-script"),e.unget(i),t.setState(n)):i==="-"?(t._emitToken({type:"Characters",data:"-"}),t.setState(D)):i==="<"?(t._emitToken({type:"Characters",data:"<"}),t.setState(H)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),e.commit()):(t._emitToken({type:"Characters",data:i}),e.commit()),!0}function D(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-script"),e.unget(i),t.setState(n)):i==="-"?(t._emitToken({type:"Characters",data:"-"}),t.setState(P)):i==="<"?(t._emitToken({type:"Characters",data:"<"}),t.setState(H)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),t.setState(_)):(t._emitToken({type:"Characters",data:i}),t.setState(_)),!0}function P(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-script"),e.unget(i),t.setState(n)):i==="-"?(t._emitToken({type:"Characters",data:"-"}),e.commit()):i==="<"?(t._emitToken({type:"Characters",data:"<"}),t.setState(H)):i===">"?(t._emitToken({type:"Characters",data:">"}),t.setState(p)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),t.setState(_)):(t._emitToken({type:"Characters",data:i}),t.setState(_)),!0}function H(e){var n=e.char();return n==="/"?(t._emitToken({type:"Characters",data:"/"}),this._temporaryBuffer="",t.setState(B)):(e.unget(n),t.setState(_)),!0}function B(e){var n=e.char();return s(n)||n==="/"||n===">"?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer.toLowerCase()==="script"?t.setState(N):t.setState(_)):o(n)?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer+=n,e.commit()):(e.unget(n),t.setState(_)),!0}function j(e){var i=e.char();return i===r.EOF?(t._parseError("bare-less-than-sign-at-eof"),t._emitToken({type:"Characters",data:"<"}),e.unget(i),t.setState(n)):o(i)?(t._currentToken={type:"StartTag",name:i.toLowerCase(),data:[]},t.setState(I)):i==="!"?t.setState(G):i==="/"?t.setState(F):i===">"?(t._parseError("expected-tag-name-but-got-right-bracket"),t._emitToken({type:"Characters",data:"<>"}),t.setState(n)):i==="?"?(t._parseError("expected-tag-name-but-got-question-mark"),e.unget(i),t.setState(Q)):(t._parseError("expected-tag-name"),t._emitToken({type:"Characters",data:"<"}),e.unget(i),t.setState(n)),!0}function F(e){var i=e.char();return i===r.EOF?(t._parseError("expected-closing-tag-but-got-eof"),t._emitToken({type:"Characters",data:"</"}),e.unget(i),t.setState(n)):o(i)?(t._currentToken={type:"EndTag",name:i.toLowerCase(),data:[]},t.setState(I)):i===">"?(t._parseError("expected-closing-tag-but-got-right-bracket"),t.setState(n)):(t._parseError("expected-closing-tag-but-got-char",{data:i}),e.unget(i),t.setState(Q)),!0}function I(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-tag-name"),e.unget(i),t.setState(n)):s(i)?t.setState(q):o(i)?t._currentToken.name+=i.toLowerCase():i===">"?t._emitCurrentToken():i==="/"?t.setState(K):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.name+="\ufffd"):t._currentToken.name+=i,e.commit(),!0}function q(e){var i=e.char();if(i===r.EOF)t._parseError("expected-attribute-name-but-got-eof"),e.unget(i),t.setState(n);else{if(s(i))return!0;o(i)?(t._currentToken.data.push({nodeName:i.toLowerCase(),nodeValue:""}),t.setState(R)):i===">"?t._emitCurrentToken():i==="/"?t.setState(K):i==="'"||i==='"'||i==="="||i==="<"?(t._parseError("invalid-character-in-attribute-name"),t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data.push({nodeName:"\ufffd",nodeValue:""})):(t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R))}return!0}function R(e){var i=e.char(),u=!0,a=!1;i===r.EOF?(t._parseError("eof-in-attribute-name"),e.unget(i),t.setState(n),a=!0):i==="="?t.setState(z):o(i)?(t._currentAttribute().nodeName+=i.toLowerCase(),u=!1):i===">"?a=!0:s(i)?t.setState(U):i==="/"?t.setState(K):i==="'"||i==='"'?(t._parseError("invalid-character-in-attribute-name"),t._currentAttribute().nodeName+=i,u=!1):i==="\0"?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeName+="\ufffd"):(t._currentAttribute().nodeName+=i,u=!1);if(u){var f=t._currentToken.data,l=f[f.length-1];for(var c=f.length-2;c>=0;c--)if(l.nodeName===f[c].nodeName){t._parseError("duplicate-attribute",{name:l.nodeName}),l.nodeName=null;break}a&&t._emitCurrentToken()}else e.commit();return!0}function U(e){var i=e.char();if(i===r.EOF)t._parseError("expected-end-of-tag-but-got-eof"),e.unget(i),t.setState(n);else{if(s(i))return!0;i==="="?t.setState(z):i===">"?t._emitCurrentToken():o(i)?(t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R)):i==="/"?t.setState(K):i==="'"||i==='"'||i==="<"?(t._parseError("invalid-character-after-attribute-name"),t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data.push({nodeName:"\ufffd",nodeValue:""})):(t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R))}return!0}function z(e){var i=e.char();if(i===r.EOF)t._parseError("expected-attribute-value-but-got-eof"),e.unget(i),t.setState(n);else{if(s(i))return!0;i==='"'?t.setState(W):i==="&"?(t.setState(V),e.unget(i)):i==="'"?t.setState(X):i===">"?(t._parseError("expected-attribute-value-but-got-right-bracket"),t._emitCurrentToken()):i==="="||i==="<"||i==="`"?(t._parseError("unexpected-character-in-unquoted-attribute-value"),t._currentAttribute().nodeValue+=i,t.setState(V)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd"):(t._currentAttribute().nodeValue+=i,t.setState(V))}return!0}function W(e){var i=e.char();if(i===r.EOF)t._parseError("eof-in-attribute-value-double-quote"),e.unget(i),t.setState(n);else if(i==='"')t.setState(J);else if(i==="&")this._additionalAllowedCharacter='"',t.setState($);else if(i==="\0")t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd";else{var s=e.matchUntil('[\0"&]');i+=s,t._currentAttribute().nodeValue+=i}return!0}function X(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-attribute-value-single-quote"),e.unget(i),t.setState(n)):i==="'"?t.setState(J):i==="&"?(this._additionalAllowedCharacter="'",t.setState($)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd"):t._currentAttribute().nodeValue+=i+e.matchUntil("\0|['&]"),!0}function V(e){var i=e.char();if(i===r.EOF)t._parseError("eof-after-attribute-value"),e.unget(i),t.setState(n);else if(s(i))t.setState(q);else if(i==="&")this._additionalAllowedCharacter=">",t.setState($);else if(i===">")t._emitCurrentToken();else if(i==='"'||i==="'"||i==="="||i==="`"||i==="<")t._parseError("unexpected-character-in-unquoted-attribute-value"),t._currentAttribute().nodeValue+=i,e.commit();else if(i==="\0")t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd";else{var o=e.matchUntil("\0|[ \n\x0b\f \r&<>\"'=`]");o===r.EOF&&(t._parseError("eof-in-attribute-value-no-quotes"),t._emitCurrentToken()),e.commit(),t._currentAttribute().nodeValue+=i+o}return!0}function $(e){var n=i.consumeEntity(e,t,this._additionalAllowedCharacter);return this._currentAttribute().nodeValue+=n||"&",this._additionalAllowedCharacter==='"'?t.setState(W):this._additionalAllowedCharacter==="'"?t.setState(X):this._additionalAllowedCharacter===">"&&t.setState(V),!0}function J(e){var i=e.char();return i===r.EOF?(t._parseError("eof-after-attribute-value"),e.unget(i),t.setState(n)):s(i)?t.setState(q):i===">"?(t.setState(n),t._emitCurrentToken()):i==="/"?t.setState(K):(t._parseError("unexpected-character-after-attribute-value"),e.unget(i),t.setState(q)),!0}function K(e){var i=e.char();return i===r.EOF?(t._parseError("unexpected-eof-after-solidus-in-tag"),e.unget(i),t.setState(n)):i===">"?(t._currentToken.selfClosing=!0,t.setState(n),t._emitCurrentToken()):(t._parseError("unexpected-character-after-solidus-in-tag"),e.unget(i),t.setState(q)),!0}function Q(e){var r=e.matchUntil(">");return r=r.replace(/\u0000/g,"\ufffd"),e.char(),t._emitToken({type:"Comment",data:r}),t.setState(n),!0}function G(e){var n=e.shift(2);if(n==="--")t._currentToken={type:"Comment",data:""},t.setState(Z);else{var i=e.shift(5);if(i===r.EOF||n===r.EOF)return t._parseError("expected-dashes-or-doctype"),t.setState(Q),e.unget(n),!0;n+=i,n.toUpperCase()==="DOCTYPE"?(t._currentToken={type:"Doctype",name:"",publicId:null,systemId:null,forceQuirks:!1},t.setState(st)):t._tokenHandler.isCdataSectionAllowed()&&n==="[CDATA["?t.setState(Y):(t._parseError("expected-dashes-or-doctype"),e.unget(n),t.setState(Q))}return!0}function Y(e){var r=e.matchUntil("]]>");return e.shift(3),r&&t._emitToken({type:"Characters",data:r}),t.setState(n),!0}function Z(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(et):i===">"?(t._parseError("incorrect-comment"),t._emitToken(t._currentToken),t.setState(n)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="\ufffd"):(t._currentToken.data+=i,t.setState(tt)),!0}function et(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(rt):i===">"?(t._parseError("incorrect-comment"),t._emitToken(t._currentToken),t.setState(n)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="\ufffd"):(t._currentToken.data+="-"+i,t.setState(tt)),!0}function tt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(nt):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="\ufffd"):(t._currentToken.data+=i,e.commit()),!0}function nt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment-end-dash"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(rt):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="-\ufffd",t.setState(tt)):(t._currentToken.data+="-"+i+e.matchUntil("\0|-"),e.char()),!0}function rt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment-double-dash"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i===">"?(t._emitToken(t._currentToken),t.setState(n)):i==="!"?(t._parseError("unexpected-bang-after-double-dash-in-comment"),t.setState(it)):i==="-"?(t._parseError("unexpected-dash-after-double-dash-in-comment"),t._currentToken.data+=i):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="--\ufffd",t.setState(tt)):(t._parseError("unexpected-char-in-comment"),t._currentToken.data+="--"+i,t.setState(tt)),!0}function it(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment-end-bang-state"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i===">"?(t._emitToken(t._currentToken),t.setState(n)):i==="-"?(t._currentToken.data+="--!",t.setState(nt)):(t._currentToken.data+="--!"+i,t.setState(tt)),!0}function st(e){var i=e.char();return i===r.EOF?(t._parseError("expected-doctype-name-but-got-eof"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)?t.setState(ot):(t._parseError("need-space-after-doctype"),e.unget(i),t.setState(ot)),!0}function ot(e){var i=e.char();return i===r.EOF?(t._parseError("expected-doctype-name-but-got-eof"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)||(i===">"?(t._parseError("expected-doctype-name-but-got-right-bracket"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):(o(i)&&(i=i.toLowerCase()),t._currentToken.name=i,t.setState(ut))),!0}function ut(e){var i=e.char();return i===r.EOF?(t._currentToken.forceQuirks=!0,e.unget(i),t._parseError("eof-in-doctype-name"),t.setState(n),t._emitCurrentToken()):s(i)?t.setState(at):i===">"?(t.setState(n),t._emitCurrentToken()):(o(i)&&(i=i.toLowerCase()),t._currentToken.name+=i,e.commit()),!0}function at(e){var i=e.char();if(i===r.EOF)t._currentToken.forceQuirks=!0,e.unget(i),t._parseError("eof-in-doctype"),t.setState(n),t._emitCurrentToken();else if(!s(i))if(i===">")t.setState(n),t._emitCurrentToken();else{if(["p","P"].indexOf(i)>-1){var o=[["u","U"],["b","B"],["l","L"],["i","I"],["c","C"]],u=o.every(function(t){return i=e.char(),t.indexOf(i)>-1});if(u)return t.setState(ft),!0}else if(["s","S"].indexOf(i)>-1){var o=[["y","Y"],["s","S"],["t","T"],["e","E"],["m","M"]],u=o.every(function(t){return i=e.char(),t.indexOf(i)>-1});if(u)return t.setState(vt),!0}e.unget(i),t._currentToken.forceQuirks=!0,i===r.EOF?(t._parseError("eof-in-doctype"),e.unget(i),t.setState(n),t._emitCurrentToken()):(t._parseError("expected-space-or-right-bracket-in-doctype",{data:i}),t.setState(wt))}return!0}function ft(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)?t.setState(lt):i==="'"||i==='"'?(t._parseError("unexpected-char-in-doctype"),e.unget(i),t.setState(lt)):(e.unget(i),t.setState(lt)),!0}function lt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)||(i==='"'?(t._currentToken.publicId="",t.setState(ct)):i==="'"?(t._currentToken.publicId="",t.setState(ht)):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt))),!0}function ct(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):i==='"'?t.setState(pt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):t._currentToken.publicId+=i,!0}function ht(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):i==="'"?t.setState(pt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):t._currentToken.publicId+=i,!0}function pt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)?t.setState(dt):i===">"?(t.setState(n),t._emitCurrentToken()):i==='"'?(t._parseError("unexpected-char-in-doctype"),t._currentToken.systemId="",t.setState(gt)):i==="'"?(t._parseError("unexpected-char-in-doctype"),t._currentToken.systemId="",t.setState(yt)):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt)),!0}function dt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)||(i===">"?(t._emitCurrentToken(),t.setState(n)):i==='"'?(t._currentToken.systemId="",t.setState(gt)):i==="'"?(t._currentToken.systemId="",t.setState(yt)):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt))),!0}function vt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)?t.setState(mt):i==="'"||i==='"'?(t._parseError("unexpected-char-in-doctype"),e.unget(i),t.setState(mt)):(e.unget(i),t.setState(mt)),!0}function mt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)||(i==='"'?(t._currentToken.systemId="",t.setState(gt)):i==="'"?(t._currentToken.systemId="",t.setState(yt)):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),t.setState(n)):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt))),!0}function gt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):i==='"'?t.setState(bt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),t.setState(n)):t._currentToken.systemId+=i,!0}function yt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):i==="'"?t.setState(bt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),t.setState(n)):t._currentToken.systemId+=i,!0}function bt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)||(i===">"?(t._emitCurrentToken(),t.setState(n)):(t._parseError("unexpected-char-in-doctype"),t.setState(wt))),!0}function wt(e){var i=e.char();return i===r.EOF?(e.unget(i),t._emitCurrentToken(),t.setState(n)):i===">"&&(t._emitCurrentToken(),t.setState(n)),!0}u.DATA=n,u.RCDATA=f,u.RAWTEXT=c,u.SCRIPT_DATA=p,u.PLAINTEXT=h,this._state=u.DATA,this._inputStream.append(e),this._tokenHandler.startTokenization(this),this._inputStream.eof=!0;var t=this;while(this._state.call(this,this._inputStream));},Object.defineProperty(u.prototype,"lineNumber",{get:function(){return this._inputStream.location().line}}),Object.defineProperty(u.prototype,"columnNumber",{get:function(){return this._inputStream.location().column}}),n.Tokenizer=u},{"./EntityParser":2,"./InputStream":3}],6:[function(e,t,n){function c(e){return e===" "||e==="\n"||e===" "||e==="\r"||e==="\f"}function h(e){return c(e)||e==="\ufffd"}function p(e){for(var t=0;t<e.length;t++){var n=e[t];if(!c(n))return!1}return!0}function d(e){for(var t=0;t<e.length;t++){var n=e[t];if(!h(n))return!1}return!0}function v(e,t){for(var n=0;n<e.attributes.length;n++){var r=e.attributes[n];if(r.nodeName===t)return r}return null}function m(e){this.characters=e,this.current=0,this.end=this.characters.length}function g(){this.tokenizer=null,this.errorHandler=null,this.scriptingEnabled=!1,this.document=null,this.head=null,this.form=null,this.openElements=new a,this.activeFormattingElements=[],this.insertionMode=null,this.insertionModeName="",this.originalInsertionMode="",this.inQuirksMode=!1,this.compatMode="no quirks",this.framesetOk=!0,this.redirectAttachToFosterParent=!1,this.selfClosingFlagAcknowledged=!1,this.context="",this.pendingTableCharacters=[],this.shouldSkipLeadingNewline=!1;var e=this,t=this.insertionModes={};t.base={end_tag_handlers:{"-default":"endTagOther"},start_tag_handlers:{"-default":"startTagOther"},processEOF:function(){e.generateImpliedEndTags(),e.openElements.length>2?e.parseError("expected-closing-tag-but-got-eof"):e.openElements.length==2&&e.openElements.item(1).localName!="body"?e.parseError("expected-closing-tag-but-got-eof"):e.context&&e.openElements.length>1},processComment:function(t){e.insertComment(t,e.currentStackItem().node)},processDoctype:function(t,n,r,i){e.parseError("unexpected-doctype")},processStartTag:function(e,t,n){if(this[this.start_tag_handlers[e]])this[this.start_tag_handlers[e]](e,t,n);else{if(!this[this.start_tag_handlers["-default"]])throw new Error("No handler found for "+e);this[this.start_tag_handlers["-default"]](e,t,n)}},processEndTag:function(e){if(this[this.end_tag_handlers[e]])this[this.end_tag_handlers[e]](e);else{if(!this[this.end_tag_handlers["-default"]])throw new Error("No handler found for "+e);this[this.end_tag_handlers["-default"]](e)}},startTagHtml:function(e,n){t.inBody.startTagHtml(e,n)}},t.initial=Object.create(t.base),t.initial.processEOF=function(){e.parseError("expected-doctype-but-got-eof"),this.anythingElse(),e.insertionMode.processEOF()},t.initial.processComment=function(t){e.insertComment(t,e.document)},t.initial.processDoctype=function(t,n,r,i){function s(e){return n.toLowerCase().indexOf(e)===0}e.insertDoctype(t||"",n||"",r||""),i||t!="html"||n!=null&&(["+//silmaril//dtd html pro v0r11 19970101//","-//advasoft ltd//dtd html 3.0 aswedit + extensions//","-//as//dtd html 3.0 aswedit + extensions//","-//ietf//dtd html 2.0 level 1//","-//ietf//dtd html 2.0 level 2//","-//ietf//dtd html 2.0 strict level 1//","-//ietf//dtd html 2.0 strict level 2//","-//ietf//dtd html 2.0 strict//","-//ietf//dtd html 2.0//","-//ietf//dtd html 2.1e//","-//ietf//dtd html 3.0//","-//ietf//dtd html 3.0//","-//ietf//dtd html 3.2 final//","-//ietf//dtd html 3.2//","-//ietf//dtd html 3//","-//ietf//dtd html level 0//","-//ietf//dtd html level 0//","-//ietf//dtd html level 1//","-//ietf//dtd html level 1//","-//ietf//dtd html level 2//","-//ietf//dtd html level 2//","-//ietf//dtd html level 3//","-//ietf//dtd html level 3//","-//ietf//dtd html strict level 0//","-//ietf//dtd html strict level 0//","-//ietf//dtd html strict level 1//","-//ietf//dtd html strict level 1//","-//ietf//dtd html strict level 2//","-//ietf//dtd html strict level 2//","-//ietf//dtd html strict level 3//","-//ietf//dtd html strict level 3//","-//ietf//dtd html strict//","-//ietf//dtd html strict//","-//ietf//dtd html strict//","-//ietf//dtd html//","-//ietf//dtd html//","-//ietf//dtd html//","-//metrius//dtd metrius presentational//","-//microsoft//dtd internet explorer 2.0 html strict//","-//microsoft//dtd internet explorer 2.0 html//","-//microsoft//dtd internet explorer 2.0 tables//","-//microsoft//dtd internet explorer 3.0 html strict//","-//microsoft//dtd internet explorer 3.0 html//","-//microsoft//dtd internet explorer 3.0 tables//","-//netscape comm. corp.//dtd html//","-//netscape comm. corp.//dtd strict html//","-//o'reilly and associates//dtd html 2.0//","-//o'reilly and associates//dtd html extended 1.0//","-//spyglass//dtd html 2.0 extended//","-//sq//dtd html 2.0 hotmetal + extensions//","-//sun microsystems corp.//dtd hotjava html//","-//sun microsystems corp.//dtd hotjava strict html//","-//w3c//dtd html 3 1995-03-24//","-//w3c//dtd html 3.2 draft//","-//w3c//dtd html 3.2 final//","-//w3c//dtd html 3.2//","-//w3c//dtd html 3.2s draft//","-//w3c//dtd html 4.0 frameset//","-//w3c//dtd html 4.0 transitional//","-//w3c//dtd html experimental 19960712//","-//w3c//dtd html experimental 970421//","-//w3c//dtd w3 html//","-//w3o//dtd w3 html 3.0//","-//webtechs//dtd mozilla html 2.0//","-//webtechs//dtd mozilla html//","html"].some(s)||["-//w3o//dtd w3 html strict 3.0//en//","-/w3c/dtd html 4.0 transitional/en","html"].indexOf(n.toLowerCase())>-1||r==null&&["-//w3c//dtd html 4.01 transitional//","-//w3c//dtd html 4.01 frameset//"].some(s))||r!=null&&r.toLowerCase()=="http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"?(e.compatMode="quirks",e.parseError("quirky-doctype")):n!=null&&(["-//w3c//dtd xhtml 1.0 transitional//","-//w3c//dtd xhtml 1.0 frameset//"].some(s)||r!=null&&["-//w3c//dtd html 4.01 transitional//","-//w3c//dtd html 4.01 frameset//"].indexOf(n.toLowerCase())>-1)?(e.compatMode="limited quirks",e.parseError("almost-standards-doctype")):n=="-//W3C//DTD HTML 4.0//EN"&&(r==null||r=="http://www.w3.org/TR/REC-html40/strict.dtd")||n=="-//W3C//DTD HTML 4.01//EN"&&(r==null||r=="http://www.w3.org/TR/html4/strict.dtd")||n=="-//W3C//DTD XHTML 1.0 Strict//EN"&&r=="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"||n=="-//W3C//DTD XHTML 1.1//EN"&&r=="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"||(r!=null&&r!="about:legacy-compat"||n!=null)&&e.parseError("unknown-doctype"),e.setInsertionMode("beforeHTML")},t.initial.processCharacters=function(t){t.skipLeadingWhitespace();if(!t.length)return;e.parseError("expected-doctype-but-got-chars"),this.anythingElse(),e.insertionMode.processCharacters(t)},t.initial.processStartTag=function(t,n,r){e.parseError("expected-doctype-but-got-start-tag",{name:t}),this.anythingElse(),e.insertionMode.processStartTag(t,n,r)},t.initial.processEndTag=function(t){e.parseError("expected-doctype-but-got-end-tag",{name:t}),this.anythingElse(),e.insertionMode.processEndTag(t)},t.initial.anythingElse=function(){e.compatMode="quirks",e.setInsertionMode("beforeHTML")},t.beforeHTML=Object.create(t.base),t.beforeHTML.start_tag_handlers={html:"startTagHtml","-default":"startTagOther"},t.beforeHTML.processEOF=function(){this.anythingElse(),e.insertionMode.processEOF()},t.beforeHTML.processComment=function(t){e.insertComment(t,e.document)},t.beforeHTML.processCharacters=function(t){t.skipLeadingWhitespace();if(!t.length)return;this.anythingElse(),e.insertionMode.processCharacters(t)},t.beforeHTML.startTagHtml=function(t,n,r){e.insertHtmlElement(n),e.setInsertionMode("beforeHead")},t.beforeHTML.startTagOther=function(t,n,r){this.anythingElse(),e.insertionMode.processStartTag(t,n,r)},t.beforeHTML.processEndTag=function(t){this.anythingElse(),e.insertionMode.processEndTag(t)},t.beforeHTML.anythingElse=function(){e.insertHtmlElement(),e.setInsertionMode("beforeHead")},t.afterAfterBody=Object.create(t.base),t.afterAfterBody.start_tag_handlers={html:"startTagHtml","-default":"startTagOther"},t.afterAfterBody.processComment=function(t){e.insertComment(t,e.document)},t.afterAfterBody.processDoctype=function(e){t.inBody.processDoctype(e)},t.afterAfterBody.startTagHtml=function(e,n){t.inBody.startTagHtml(e,n)},t.afterAfterBody.startTagOther=function(t,n,r){e.parseError("unexpected-start-tag",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processStartTag(t,n,r)},t.afterAfterBody.endTagOther=function(t){e.parseError("unexpected-end-tag",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processEndTag(t)},t.afterAfterBody.processCharacters=function(n){if(!p(n.characters))return e.parseError("unexpected-char-after-body"),e.setInsertionMode("inBody"),e.insertionMode.processCharacters(n);t.inBody.processCharacters(n)},t.afterBody=Object.create(t.base),t.afterBody.end_tag_handlers={html:"endTagHtml","-default":"endTagOther"},t.afterBody.processComment=function(t){e.insertComment(t,e.openElements.rootNode)},t.afterBody.processCharacters=function(n){if(!p(n.characters))return e.parseError("unexpected-char-after-body"),e.setInsertionMode("inBody"),e.insertionMode.processCharacters(n);t.inBody.processCharacters(n)},t.afterBody.processStartTag=function(t,n,r){e.parseError("unexpected-start-tag-after-body",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processStartTag(t,n,r)},t.afterBody.endTagHtml=function(t){e.context?e.parseError("end-html-in-innerhtml"):e.setInsertionMode("afterAfterBody")},t.afterBody.endTagOther=function(t){e.parseError("unexpected-end-tag-after-body",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processEndTag(t)},t.afterFrameset=Object.create(t.base),t.afterFrameset.start_tag_handlers={html:"startTagHtml",noframes:"startTagNoframes","-default":"startTagOther"},t.afterFrameset.end_tag_handlers={html:"endTagHtml","-default":"endTagOther"},t.afterFrameset.processCharacters=function(t){var n=t.takeRemaining(),r="";for(var i=0;i<n.length;i++){var s=n[i];c(s)&&(r+=s)}r&&e.insertText(r),r.length<n.length&&e.parseError("expected-eof-but-got-char")},t.afterFrameset.startTagNoframes=function(e,n){t.inHead.processStartTag(e,n)},t.afterFrameset.startTagOther=function(t,n){e.parseError("unexpected-start-tag-after-frameset",{name:t})},t.afterFrameset.endTagHtml=function(t){e.setInsertionMode("afterAfterFrameset")},t.afterFrameset.endTagOther=function(t){e.parseError("unexpected-end-tag-after-frameset",{name:t})},t.beforeHead=Object.create(t.base),t.beforeHead.start_tag_handlers={html:"startTagHtml",head:"startTagHead","-default":"startTagOther"},t.beforeHead.end_tag_handlers={html:"endTagImplyHead",head:"endTagImplyHead",body:"endTagImplyHead",br:"endTagImplyHead","-default":"endTagOther"},t.beforeHead.processEOF=function(){this.startTagHead("head",[]),e.insertionMode.processEOF()},t.beforeHead.processCharacters=function(t){t.skipLeadingWhitespace();if(!t.length)return;this.startTagHead("head",[]),e.insertionMode.processCharacters(t)},t.beforeHead.startTagHead=function(t,n){e.insertHeadElement(n),e.setInsertionMode("inHead")},t.beforeHead.startTagOther=function(t,n,r){this.startTagHead("head",[]),e.insertionMode.processStartTag(t,n,r)},t.beforeHead.endTagImplyHead=function(t){this.startTagHead("head",[]),e.insertionMode.processEndTag(t)},t.beforeHead.endTagOther=function(t){e.parseError("end-tag-after-implied-root",{name:t})},t.inHead=Object.create(t.base),t.inHead.start_tag_handlers={html:"startTagHtml",head:"startTagHead",title:"startTagTitle",script:"startTagScript",style:"startTagNoFramesStyle",noscript:"startTagNoScript",noframes:"startTagNoFramesStyle",base:"startTagBaseBasefontBgsoundLink",basefont:"startTagBaseBasefontBgsoundLink",bgsound:"startTagBaseBasefontBgsoundLink",link:"startTagBaseBasefontBgsoundLink",meta:"startTagMeta","-default":"startTagOther"},t.inHead.end_tag_handlers={head:"endTagHead",html:"endTagHtmlBodyBr",body:"endTagHtmlBodyBr",br:"endTagHtmlBodyBr","-default":"endTagOther"},t.inHead.processEOF=function(){var t=e.currentStackItem().localName;["title","style","script"].indexOf(t)!=-1&&(e.parseError("expected-named-closing-tag-but-got-eof",{name:t}),e.popElement()),this.anythingElse(),e.insertionMode.processEOF()},t.inHead.processCharacters=function(t){var n=t.takeLeadingWhitespace();n&&e.insertText(n);if(!t.length)return;this.anythingElse(),e.insertionMode.processCharacters(t)},t.inHead.startTagHtml=function(e,n){t.inBody.processStartTag(e,n)},t.inHead.startTagHead=function(t,n){e.parseError("two-heads-are-not-better-than-one")},t.inHead.startTagTitle=function(t,n){e.processGenericRCDATAStartTag(t,n)},t.inHead.startTagNoScript=function(t,n){if(e.scriptingEnabled)return e.processGenericRawTextStartTag(t,n);e.insertElement(t,n),e.setInsertionMode("inHeadNoscript")},t.inHead.startTagNoFramesStyle=function(t,n){e.processGenericRawTextStartTag(t,n)},t.inHead.startTagScript=function(t,n){e.insertElement(t,n),e.tokenizer.setState(u.SCRIPT_DATA),e.originalInsertionMode=e.insertionModeName,e.setInsertionMode("text")},t.inHead.startTagBaseBasefontBgsoundLink=function(t,n){e.insertSelfClosingElement(t,n)},t.inHead.startTagMeta=function(t,n){e.insertSelfClosingElement(t,n)},t.inHead.startTagOther=function(t,n,r){this.anythingElse(),e.insertionMode.processStartTag(t,n,r)},t.inHead.endTagHead=function(t){e.openElements.item(e.openElements.length-1).localName=="head"?e.openElements.pop():e.parseError("unexpected-end-tag",{name:"head"}),e.setInsertionMode("afterHead")},t.inHead.endTagHtmlBodyBr=function(t){this.anythingElse(),e.insertionMode.processEndTag(t)},t.inHead.endTagOther=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inHead.anythingElse=function(){this.endTagHead("head")},t.afterHead=Object.create(t.base),t.afterHead.start_tag_handlers={html:"startTagHtml",head:"startTagHead",body:"startTagBody",frameset:"startTagFrameset",base:"startTagFromHead",link:"startTagFromHead",meta:"startTagFromHead",script:"startTagFromHead",style:"startTagFromHead",title:"startTagFromHead","-default":"startTagOther"},t.afterHead.end_tag_handlers={body:"endTagBodyHtmlBr",html:"endTagBodyHtmlBr",br:"endTagBodyHtmlBr","-default":"endTagOther"},t.afterHead.processEOF=function(){this.anythingElse(),e.insertionMode.processEOF()},t.afterHead.processCharacters=function(t){var n=t.takeLeadingWhitespace();n&&e.insertText(n);if(!t.length)return;this.anythingElse(),e.insertionMode.processCharacters(t)},t.afterHead.startTagHtml=function(e,n){t.inBody.processStartTag(e,n)},t.afterHead.startTagBody=function(t,n){e.framesetOk=!1,e.insertBodyElement(n),e.setInsertionMode("inBody")},t.afterHead.startTagFrameset=function(t,n){e.insertElement(t,n),e.setInsertionMode("inFrameset")},t.afterHead.startTagFromHead=function(n,r,i){e.parseError("unexpected-start-tag-out-of-my-head",{name:n}),e.openElements.push(e.head),t.inHead.processStartTag(n,r,i),e.openElements.remove(e.head)},t.afterHead.startTagHead=function(t,n,r){e.parseError("unexpected-start-tag",{name:t})},t.afterHead.startTagOther=function(t,n,r){this.anythingElse(),e.insertionMode.processStartTag(t,n,r)},t.afterHead.endTagBodyHtmlBr=function(t){this.anythingElse(),e.insertionMode.processEndTag(t)},t.afterHead.endTagOther=function(t){e.parseError("unexpected-end-tag",{name:t})},t.afterHead.anythingElse=function(){e.insertBodyElement([]),e.setInsertionMode("inBody"),e.framesetOk=!0},t.inBody=Object.create(t.base),t.inBody.start_tag_handlers={html:"startTagHtml",head:"startTagMisplaced",base:"startTagProcessInHead",basefont:"startTagProcessInHead",bgsound:"startTagProcessInHead",link:"startTagProcessInHead",meta:"startTagProcessInHead",noframes:"startTagProcessInHead",script:"startTagProcessInHead",style:"startTagProcessInHead",title:"startTagProcessInHead",body:"startTagBody",form:"startTagForm",plaintext:"startTagPlaintext",a:"startTagA",button:"startTagButton",xmp:"startTagXmp",table:"startTagTable",hr:"startTagHr",image:"startTagImage",input:"startTagInput",textarea:"startTagTextarea",select:"startTagSelect",isindex:"startTagIsindex",applet:"startTagAppletMarqueeObject",marquee:"startTagAppletMarqueeObject",object:"startTagAppletMarqueeObject",li:"startTagListItem",dd:"startTagListItem",dt:"startTagListItem",address:"startTagCloseP",article:"startTagCloseP",aside:"startTagCloseP",blockquote:"startTagCloseP",center:"startTagCloseP",details:"startTagCloseP",dir:"startTagCloseP",div:"startTagCloseP",dl:"startTagCloseP",fieldset:"startTagCloseP",figcaption:"startTagCloseP",figure:"startTagCloseP",footer:"startTagCloseP",header:"startTagCloseP",hgroup:"startTagCloseP",main:"startTagCloseP",menu:"startTagCloseP",nav:"startTagCloseP",ol:"startTagCloseP",p:"startTagCloseP",section:"startTagCloseP",summary:"startTagCloseP",ul:"startTagCloseP",listing:"startTagPreListing",pre:"startTagPreListing",b:"startTagFormatting",big:"startTagFormatting",code:"startTagFormatting",em:"startTagFormatting",font:"startTagFormatting",i:"startTagFormatting",s:"startTagFormatting",small:"startTagFormatting",strike:"startTagFormatting",strong:"startTagFormatting",tt:"startTagFormatting",u:"startTagFormatting",nobr:"startTagNobr",area:"startTagVoidFormatting",br:"startTagVoidFormatting",embed:"startTagVoidFormatting",img:"startTagVoidFormatting",keygen:"startTagVoidFormatting",wbr:"startTagVoidFormatting",param:"startTagParamSourceTrack",source:"startTagParamSourceTrack",track:"startTagParamSourceTrack",iframe:"startTagIFrame",noembed:"startTagRawText",noscript:"startTagRawText",h1:"startTagHeading",h2:"startTagHeading",h3:"startTagHeading",h4:"startTagHeading",h5:"startTagHeading",h6:"startTagHeading",caption:"startTagMisplaced",col:"startTagMisplaced",colgroup:"startTagMisplaced",frame:"startTagMisplaced",frameset:"startTagFrameset",tbody:"startTagMisplaced",td:"startTagMisplaced",tfoot:"startTagMisplaced",th:"startTagMisplaced",thead:"startTagMisplaced",tr:"startTagMisplaced",option:"startTagOptionOptgroup",optgroup:"startTagOptionOptgroup",math:"startTagMath",svg:"startTagSVG",rt:"startTagRpRt",rp:"startTagRpRt","-default":"startTagOther"},t.inBody.end_tag_handlers={p:"endTagP",body:"endTagBody",html:"endTagHtml",address:"endTagBlock",article:"endTagBlock",aside:"endTagBlock",blockquote:"endTagBlock",button:"endTagBlock",center:"endTagBlock",details:"endTagBlock",dir:"endTagBlock",div:"endTagBlock",dl:"endTagBlock",fieldset:"endTagBlock",figcaption:"endTagBlock",figure:"endTagBlock",footer:"endTagBlock",header:"endTagBlock",hgroup:"endTagBlock",listing:"endTagBlock",main:"endTagBlock",menu:"endTagBlock",nav:"endTagBlock",ol:"endTagBlock",pre:"endTagBlock",section:"endTagBlock",summary:"endTagBlock",ul:"endTagBlock",form:"endTagForm",applet:"endTagAppletMarqueeObject",marquee:"endTagAppletMarqueeObject",object:"endTagAppletMarqueeObject",dd:"endTagListItem",dt:"endTagListItem",li:"endTagListItem",h1:"endTagHeading",h2:"endTagHeading",h3:"endTagHeading",h4:"endTagHeading",h5:"endTagHeading",h6:"endTagHeading",a:"endTagFormatting",b:"endTagFormatting",big:"endTagFormatting",code:"endTagFormatting",em:"endTagFormatting",font:"endTagFormatting",i:"endTagFormatting",nobr:"endTagFormatting",s:"endTagFormatting",small:"endTagFormatting",strike:"endTagFormatting",strong:"endTagFormatting",tt:"endTagFormatting",u:"endTagFormatting",br:"endTagBr","-default":"endTagOther"},t.inBody.processCharacters=function(t){e.shouldSkipLeadingNewline&&(e.shouldSkipLeadingNewline=!1,t.skipAtMostOneLeadingNewline()),e.reconstructActiveFormattingElements();var n=t.takeRemaining();n=n.replace(/\u0000/g,function(t,n){return e.parseError("invalid-codepoint"),""});if(!n)return;e.insertText(n),e.framesetOk&&!d(n)&&(e.framesetOk=!1)},t.inBody.startTagHtml=function(t,n){e.parseError("non-html-root"),e.addAttributesToElement(e.openElements.rootNode,n)},t.inBody.startTagProcessInHead=function(e,n){t.inHead.processStartTag(e,n)},t.inBody.startTagBody=function(t,n){e.parseError("unexpected-start-tag",{name:"body"}),e.openElements.length==1||e.openElements.item(1).localName!="body"?r.ok(e.context):(e.framesetOk=!1,e.addAttributesToElement(e.openElements.bodyElement,n))},t.inBody.startTagFrameset=function(t,n){e.parseError("unexpected-start-tag",{name:"frameset"});if(e.openElements.length==1||e.openElements.item(1).localName!="body")r.ok(e.context);else if(e.framesetOk){e.detachFromParent(e.openElements.bodyElement);while(e.openElements.length>1)e.openElements.pop();e.insertElement(t,n),e.setInsertionMode("inFrameset")}},t.inBody.startTagCloseP=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n)},t.inBody.startTagPreListing=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.framesetOk=!1,e.shouldSkipLeadingNewline=!0},t.inBody.startTagForm=function(t,n){e.form?e.parseError("unexpected-start-tag",{name:t}):(e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.form=e.currentStackItem())},t.inBody.startTagRpRt=function(t,n){e.openElements.inScope("ruby")&&(e.generateImpliedEndTags(),e.currentStackItem().localName!="ruby"&&e.parseError("unexpected-start-tag",{name:t})),e.insertElement(t,n)},t.inBody.startTagListItem=function(t,n){var r={li:["li"],dd:["dd","dt"],dt:["dd","dt"]},i=r[t],s=e.openElements;for(var o=s.length-1;o>=0;o--){var u=s.item(o);if(i.indexOf(u.localName)!=-1){e.insertionMode.processEndTag(u.localName);break}if(u.isSpecial()&&u.localName!=="p"&&u.localName!=="address"&&u.localName!=="div")break}e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.framesetOk=!1},t.inBody.startTagPlaintext=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.tokenizer.setState(u.PLAINTEXT)},t.inBody.startTagHeading=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.currentStackItem().isNumberedHeader()&&(e.parseError("unexpected-start-tag",{name:t}),e.popElement()),e.insertElement(t,n)},t.inBody.startTagA=function(t,n){var r=e.elementInActiveFormattingElements("a");r&&(e.parseError("unexpected-start-tag-implies-end-tag",{startName:"a",endName:"a"}),e.adoptionAgencyEndTag("a"),e.openElements.contains(r)&&e.openElements.remove(r),e.removeElementFromActiveFormattingElements(r)),e.reconstructActiveFormattingElements(),e.insertFormattingElement(t,n)},t.inBody.startTagFormatting=function(t,n){e.reconstructActiveFormattingElements(),e.insertFormattingElement(t,n)},t.inBody.startTagNobr=function(t,n){e.reconstructActiveFormattingElements(),e.openElements.inScope("nobr")&&(e.parseError("unexpected-start-tag-implies-end-tag",{startName:"nobr",endName:"nobr"}),this.processEndTag("nobr"),e.reconstructActiveFormattingElements()),e.insertFormattingElement(t,n)},t.inBody.startTagButton=function(t,n){e.openElements.inScope("button")?(e.parseError("unexpected-start-tag-implies-end-tag",{startName:"button",endName:"button"}),this.processEndTag("button"),e.insertionMode.processStartTag(t,n)):(e.framesetOk=!1,e.reconstructActiveFormattingElements(),e.insertElement(t,n))},t.inBody.startTagAppletMarqueeObject=function(t,n){e.reconstructActiveFormattingElements(),e.insertElement(t,n),e.activeFormattingElements.push(l),e.framesetOk=!1},t.inBody.endTagAppletMarqueeObject=function(t){e.openElements.inScope(t)?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.popUntilPopped(t),e.clearActiveFormattingElements()):e.parseError("unexpected-end-tag",{name:t})},t.inBody.startTagXmp=function(t,n){e.openElements.inButtonScope("p")&&this.processEndTag("p"),e.reconstructActiveFormattingElements(),e.processGenericRawTextStartTag(t,n),e.framesetOk=!1},t.inBody.startTagTable=function(t,n){e.compatMode!=="quirks"&&e.openElements.inButtonScope("p")&&this.processEndTag("p"),e.insertElement(t,n),e.setInsertionMode("inTable"),e.framesetOk=!1},t.inBody.startTagVoidFormatting=function(t,n){e.reconstructActiveFormattingElements(),e.insertSelfClosingElement(t,n),e.framesetOk=!1},t.inBody.startTagParamSourceTrack=function(t,n){e.insertSelfClosingElement(t,n)},t.inBody.startTagHr=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertSelfClosingElement(t,n),e.framesetOk=!1},t.inBody.startTagImage=function(t,n){e.parseError("unexpected-start-tag-treated-as",{originalName:"image",newName:"img"}),this.processStartTag("img",n)},t.inBody.startTagInput=function(t,n){var r=e.framesetOk;this.startTagVoidFormatting(t,n);for(var i in n)if(n[i].nodeName=="type"){n[i].nodeValue.toLowerCase()=="hidden"&&(e.framesetOk=r);break}},t.inBody.startTagIsindex=function(t,n){e.parseError("deprecated-tag",{name:"isindex"}),e.selfClosingFlagAcknowledged=!0;if(e.form)return;var r=[],i=[],s="This is a searchable index. Enter search keywords: ";for(var o in n)switch(n[o].nodeName){case"action":r.push({nodeName:"action",nodeValue:n[o].nodeValue});break;case"prompt":s=n[o].nodeValue;break;case"name":break;default:i.push({nodeName:n[o].nodeName,nodeValue:n[o].nodeValue})}i.push({nodeName:"name",nodeValue:"isindex"}),this.processStartTag("form",r),this.processStartTag("hr"),this.processStartTag("label"),this.processCharacters(new m(s)),this.processStartTag("input",i),this.processEndTag("label"),this.processStartTag("hr"),this.processEndTag("form")},t.inBody.startTagTextarea=function(t,n){e.insertElement(t,n),e.tokenizer.setState(u.RCDATA),e.originalInsertionMode=e.insertionModeName,e.shouldSkipLeadingNewline=!0,e.framesetOk=!1,e.setInsertionMode("text")},t.inBody.startTagIFrame=function(t,n){e.framesetOk=!1,this.startTagRawText(t,n)},t.inBody.startTagRawText=function(t,n){e.processGenericRawTextStartTag(t,n)},t.inBody.startTagSelect=function(t,n){e.reconstructActiveFormattingElements(),e.insertElement(t,n),e.framesetOk=!1;var r=e.insertionModeName;r=="inTable"||r=="inCaption"||r=="inColumnGroup"||r=="inTableBody"||r=="inRow"||r=="inCell"?e.setInsertionMode("inSelectInTable"):e.setInsertionMode("inSelect")},t.inBody.startTagMisplaced=function(t,n){e.parseError("unexpected-start-tag-ignored",{name:t})},t.inBody.endTagMisplaced=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagBr=function(t){e.parseError("unexpected-end-tag-treated-as",{originalName:"br",newName:"br element"}),e.reconstructActiveFormattingElements(),e.insertElement(t,[]),e.popElement()},t.inBody.startTagOptionOptgroup=function(t,n){e.currentStackItem().localName=="option"&&e.popElement(),e.reconstructActiveFormattingElements(),e.insertElement(t,n)},t.inBody.startTagOther=function(t,n){e.reconstructActiveFormattingElements(),e.insertElement(t,n)},t.inBody.endTagOther=function(t){var n;for(var r=e.openElements.length-1;r>0;r--){n=e.openElements.item(r);if(n.localName==t){e.generateImpliedEndTags(t),e.currentStackItem().localName!=t&&e.parseError("unexpected-end-tag",{name:t}),e.openElements.remove_openElements_until(function(e){return e===n});break}if(n.isSpecial()){e.parseError("unexpected-end-tag",{name:t});break}}},t.inBody.startTagMath=function(t,n,r){e.reconstructActiveFormattingElements(),n=e.adjustMathMLAttributes(n),n=e.adjustForeignAttributes(n),e.insertForeignElement(t,n,"http://www.w3.org/1998/Math/MathML",r)},t.inBody.startTagSVG=function(t,n,r){e.reconstructActiveFormattingElements(),n=e.adjustSVGAttributes(n),n=e.adjustForeignAttributes(n),e.insertForeignElement(t,n,"http://www.w3.org/2000/svg",r)},t.inBody.endTagP=function(t){e.openElements.inButtonScope("p")?(e.generateImpliedEndTags("p"),e.currentStackItem().localName!="p"&&e.parseError("unexpected-implied-end-tag",{name:"p"}),e.openElements.popUntilPopped(t)):(e.parseError("unexpected-end-tag",{name:"p"}),this.startTagCloseP("p",[]),this.endTagP("p"))},t.inBody.endTagBody=function(t){if(!e.openElements.inScope("body")){e.parseError("unexpected-end-tag",{name:t});return}e.currentStackItem().localName!="body"&&e.parseError("expected-one-end-tag-but-got-another",{expectedName:e.currentStackItem().localName,gotName:t}),e.setInsertionMode("afterBody")},t.inBody.endTagHtml=function(t){if(!e.openElements.inScope("body")){e.parseError("unexpected-end-tag",{name:t});return}e.currentStackItem().localName!="body"&&e.parseError("expected-one-end-tag-but-got-another",{expectedName:e.currentStackItem().localName,gotName:t}),e.setInsertionMode("afterBody"),e.insertionMode.processEndTag(t)},t.inBody.endTagBlock=function(t){e.openElements.inScope(t)?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.popUntilPopped(t)):e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagForm=function(t){var n=e.form;e.form=null,!n||!e.openElements.inScope(t)?e.parseError("unexpected-end-tag",{name:t}):(e.generateImpliedEndTags(),e.currentStackItem()!=n&&e.parseError("end-tag-too-early-ignored",{name:"form"}),e.openElements.remove(n))},t.inBody.endTagListItem=function(t){e.openElements.inListItemScope(t)?(e.generateImpliedEndTags(t),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.popUntilPopped(t)):e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagHeading=function(t){if(!e.openElements.hasNumberedHeaderElementInScope()){e.parseError("unexpected-end-tag",{name:t});return}e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.remove_openElements_until(function(e){return e.isNumberedHeader()})},t.inBody.endTagFormatting=function(t,n){e.adoptionAgencyEndTag(t)||this.endTagOther(t,n)},t.inCaption=Object.create(t.base),t.inCaption.start_tag_handlers={html:"startTagHtml",caption:"startTagTableElement",col:"startTagTableElement",colgroup:"startTagTableElement",tbody:"startTagTableElement",td:"startTagTableElement",tfoot:"startTagTableElement",thead:"startTagTableElement",tr:"startTagTableElement","-default":"startTagOther"},t.inCaption.end_tag_handlers={caption:"endTagCaption",table:"endTagTable",body:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",tbody:"endTagIgnore",td:"endTagIgnore",tfood:"endTagIgnore",thead:"endTagIgnore",tr:"endTagIgnore","-default":"endTagOther"},t.inCaption.processCharacters=function(e){t.inBody.processCharacters(e)},t.inCaption.startTagTableElement=function(t,n){e.parseError("unexpected-end-tag",{name:t});var r=!e.openElements.inTableScope("caption");e.insertionMode.processEndTag("caption"),r||e.insertionMode.processStartTag(t,n)},t.inCaption.startTagOther=function(e,n,r){t.inBody.processStartTag(e,n,r)},t.inCaption.endTagCaption=function(t){e.openElements.inTableScope("caption")?(e.generateImpliedEndTags(),e.currentStackItem().localName!="caption"&&e.parseError("expected-one-end-tag-but-got-another",{gotName:"caption",expectedName:e.currentStackItem().localName}),e.openElements.popUntilPopped("caption"),e.clearActiveFormattingElements(),e.setInsertionMode("inTable")):(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t}))},t.inCaption.endTagTable=function(t){e.parseError("unexpected-end-table-in-caption");var n=!e.openElements.inTableScope("caption");e.insertionMode.processEndTag("caption"),n||e.insertionMode.processEndTag(t)},t.inCaption.endTagIgnore=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inCaption.endTagOther=function(e){t.inBody.processEndTag(e)},t.inCell=Object.create(t.base),t.inCell.start_tag_handlers={html:"startTagHtml",caption:"startTagTableOther",col:"startTagTableOther",colgroup:"startTagTableOther",tbody:"startTagTableOther",td:"startTagTableOther",tfoot:"startTagTableOther",th:"startTagTableOther",thead:"startTagTableOther",tr:"startTagTableOther","-default":"startTagOther"},t.inCell.end_tag_handlers={td:"endTagTableCell",th:"endTagTableCell",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",table:"endTagImply",tbody:"endTagImply",tfoot:"endTagImply",thead:"endTagImply",tr:"endTagImply","-default":"endTagOther"},t.inCell.processCharacters=function(e){t.inBody.processCharacters(e)},t.inCell.startTagTableOther=function(t,n,r){e.openElements.inTableScope("td")||e.openElements.inTableScope("th")?(this.closeCell(),e.insertionMode.processStartTag(t,n,r)):e.parseError("unexpected-start-tag",{name:t})},t.inCell.startTagOther=function(e,n,r){t.inBody.processStartTag(e,n,r)},t.inCell.endTagTableCell=function(t){e.openElements.inTableScope(t)?(e.generateImpliedEndTags(t),e.currentStackItem().localName!=t.toLowerCase()?(e.parseError("unexpected-cell-end-tag",{name:t}),e.openElements.popUntilPopped(t)):e.popElement(),e.clearActiveFormattingElements(),e.setInsertionMode("inRow")):e.parseError("unexpected-end-tag",{name:t})},t.inCell.endTagIgnore=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inCell.endTagImply=function(t){e.openElements.inTableScope(t)?(this.closeCell(),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inCell.endTagOther=function(e){t.inBody.processEndTag(e)},t.inCell.closeCell=function(){e.openElements.inTableScope("td")?this.endTagTableCell("td"):e.openElements.inTableScope("th")&&this.endTagTableCell("th")},t.inColumnGroup=Object.create(t.base),t.inColumnGroup.start_tag_handlers={html:"startTagHtml",col:"startTagCol","-default":"startTagOther"},t.inColumnGroup.end_tag_handlers={colgroup:"endTagColgroup",col:"endTagCol","-default":"endTagOther"},t.inColumnGroup.ignoreEndTagColgroup=function(){return e.currentStackItem().localName=="html"},t.inColumnGroup.processCharacters=function(t){var n=t.takeLeadingWhitespace();n&&e.insertText(n);if(!t.length)return;var r=this.ignoreEndTagColgroup();this.endTagColgroup("colgroup"),r||e.insertionMode.processCharacters(t)},t.inColumnGroup.startTagCol=function(t,n){e.insertSelfClosingElement(t,n)},t.inColumnGroup.startTagOther=function(t,n,r){var i=this.ignoreEndTagColgroup();this.endTagColgroup("colgroup"),i||e.insertionMode.processStartTag(t,n,r)},t.inColumnGroup.endTagColgroup=function(t){this.ignoreEndTagColgroup()?(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t})):(e.popElement(),e.setInsertionMode("inTable"))},t.inColumnGroup.endTagCol=function(t){e.parseError("no-end-tag",{name:"col"})},t.inColumnGroup.endTagOther=function(t){var n=this.ignoreEndTagColgroup();this.endTagColgroup("colgroup"),n||e.insertionMode.processEndTag(t)},t.inForeignContent=Object.create(t.base),t.inForeignContent.processStartTag=function(t,n,r){if(["b","big","blockquote","body","br","center","code","dd","div","dl","dt","em","embed","h1","h2","h3","h4","h5","h6","head","hr","i","img","li","listing","menu","meta","nobr","ol","p","pre","ruby","s","small","span","strong","strike","sub","sup","table","tt","u","ul","var"].indexOf(t)!=-1||t=="font"&&n.some(function(e){return["color","face","size"].indexOf(e.nodeName)>=0})){e.parseError("unexpected-html-element-in-foreign-content",{name:t});while(e.currentStackItem().isForeign()&&!e.currentStackItem().isHtmlIntegrationPoint()&&!e.currentStackItem().isMathMLTextIntegrationPoint())e.openElements.pop();e.insertionMode.processStartTag(t,n,r);return}e.currentStackItem().namespaceURI=="http://www.w3.org/1998/Math/MathML"&&(n=e.adjustMathMLAttributes(n)),e.currentStackItem().namespaceURI=="http://www.w3.org/2000/svg"&&(t=e.adjustSVGTagNameCase(t),n=e.adjustSVGAttributes(n)),n=e.adjustForeignAttributes(n),e.insertForeignElement(t,n,e.currentStackItem().namespaceURI,r)},t.inForeignContent.processEndTag=function(t){var n=e.currentStackItem(),r=e.openElements.length-1;n.localName.toLowerCase()!=t&&e.parseError("unexpected-end-tag",{name:t});for(;;){if(r===0)break;if(n.localName.toLowerCase()==t){while(e.openElements.pop()!=n);break}r-=1,n=e.openElements.item(r);if(n.isForeign())continue;e.insertionMode.processEndTag(t);break}},t.inForeignContent.processCharacters=function(t){var n=t.takeRemaining();n=n.replace(/\u0000/g,function(t,n){return e.parseError("invalid-codepoint"),"\ufffd"}),e.framesetOk&&!d(n)&&(e.framesetOk=!1),e.insertText(n)},t.inHeadNoscript=Object.create(t.base),t.inHeadNoscript.start_tag_handlers={html:"startTagHtml",basefont:"startTagBasefontBgsoundLinkMetaNoframesStyle",bgsound:"startTagBasefontBgsoundLinkMetaNoframesStyle",link:"startTagBasefontBgsoundLinkMetaNoframesStyle",meta:"startTagBasefontBgsoundLinkMetaNoframesStyle",noframes:"startTagBasefontBgsoundLinkMetaNoframesStyle",style:"startTagBasefontBgsoundLinkMetaNoframesStyle",head:"startTagHeadNoscript",noscript:"startTagHeadNoscript","-default":"startTagOther"},t.inHeadNoscript.end_tag_handlers={noscript:"endTagNoscript",br:"endTagBr","-default":"endTagOther"},t.inHeadNoscript.processCharacters=function(t){var n=t.takeLeadingWhitespace();n&&e.insertText(n);if(!t.length)return;e.parseError("unexpected-char-in-frameset"),this.anythingElse(),e.insertionMode.processCharacters(t)},t.inHeadNoscript.processComment=function(e){t.inHead.processComment(e)},t.inHeadNoscript.startTagBasefontBgsoundLinkMetaNoframesStyle=function(e,n){t.inHead.processStartTag(e,n)},t.inHeadNoscript.startTagHeadNoscript=function(t,n){e.parseError("unexpected-start-tag-in-frameset",{name:t})},t.inHeadNoscript.startTagOther=function(t,n){e.parseError("unexpected-start-tag-in-frameset",{name:t}),this.anythingElse(),e.insertionMode.processStartTag(t,n)},t.inHeadNoscript.endTagBr=function(t,n){e.parseError("unexpected-end-tag-in-frameset",{name:t}),this.anythingElse(),e.insertionMode.processEndTag(t,n)},t.inHeadNoscript.endTagNoscript=function(t,n){e.popElement(),e.setInsertionMode("inHead")},t.inHeadNoscript.endTagOther=function(t,n){e.parseError("unexpected-end-tag-in-frameset",{name:t})},t.inHeadNoscript.anythingElse=function(){e.popElement(),e.setInsertionMode("inHead")},t.inFrameset=Object.create(t.base),t.inFrameset.start_tag_handlers={html:"startTagHtml",frameset:"startTagFrameset",frame:"startTagFrame",noframes:"startTagNoframes","-default":"startTagOther"},t.inFrameset.end_tag_handlers={frameset:"endTagFrameset",noframes:"endTagNoframes","-default":"endTagOther"},t.inFrameset.processCharacters=function(t){e.parseError("unexpected-char-in-frameset")},t.inFrameset.startTagFrameset=function(t,n){e.insertElement(t,n)},t.inFrameset.startTagFrame=function(t,n){e.insertSelfClosingElement(t,n)},t.inFrameset.startTagNoframes=function(e,n){t.inBody.processStartTag(e,n)},t.inFrameset.startTagOther=function(t,n){e.parseError("unexpected-start-tag-in-frameset",{name:t})},t.inFrameset.endTagFrameset=function(t,n){e.currentStackItem().localName=="html"?e.parseError("unexpected-frameset-in-frameset-innerhtml"):e.popElement(),!e.context&&e.currentStackItem().localName!="frameset"&&e.setInsertionMode("afterFrameset")},t.inFrameset.endTagNoframes=function(e){t.inBody.processEndTag(e)},t.inFrameset.endTagOther=function(t){e.parseError("unexpected-end-tag-in-frameset",{name:t})},t.inTable=Object.create(t.base),t.inTable.start_tag_handlers={html:"startTagHtml",caption:"startTagCaption",colgroup:"startTagColgroup",col:"startTagCol",table:"startTagTable",tbody:"startTagRowGroup",tfoot:"startTagRowGroup",thead:"startTagRowGroup",td:"startTagImplyTbody",th:"startTagImplyTbody",tr:"startTagImplyTbody",style:"startTagStyleScript",script:"startTagStyleScript",input:"startTagInput",form:"startTagForm","-default":"startTagOther"},t.inTable.end_tag_handlers={table:"endTagTable",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",tbody:"endTagIgnore",td:"endTagIgnore",tfoot:"endTagIgnore",th:"endTagIgnore",thead:"endTagIgnore",tr:"endTagIgnore","-default":"endTagOther"},t.inTable.processCharacters=function(n){if(e.currentStackItem().isFosterParenting()){var r=e.insertionModeName;e.setInsertionMode("inTableText"),e.originalInsertionMode=r,e.insertionMode.processCharacters(n)}else e.redirectAttachToFosterParent=!0,t.inBody.processCharacters(n),e.redirectAttachToFosterParent=!1},t.inTable.startTagCaption=function(t,n){e.openElements.popUntilTableScopeMarker(),e.activeFormattingElements.push(l),e.insertElement(t,n),e.setInsertionMode("inCaption")},t.inTable.startTagColgroup=function(t,n){e.openElements.popUntilTableScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inColumnGroup")},t.inTable.startTagCol=function(t,n){this.startTagColgroup("colgroup",[]),e.insertionMode.processStartTag(t,n)},t.inTable.startTagRowGroup=function(t,n){e.openElements.popUntilTableScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inTableBody")},t.inTable.startTagImplyTbody=function(t,n){this.startTagRowGroup("tbody",[]),e.insertionMode.processStartTag(t,n)},t.inTable.startTagTable=function(t,n){e.parseError("unexpected-start-tag-implies-end-tag",{startName:"table",endName:"table"}),e.insertionMode.processEndTag("table"),e.context||e.insertionMode.processStartTag(t,n)},t.inTable.startTagStyleScript=function(e,n){t.inHead.processStartTag(e,n)},t.inTable.startTagInput=function(t,n){for(var r in n)if(n[r].nodeName.toLowerCase()=="type"){if(n[r].nodeValue.toLowerCase()=="hidden"){e.parseError("unexpected-hidden-input-in-table"),e.insertElement(t,n),e.openElements.pop();return}break}this.startTagOther(t,n)},t.inTable.startTagForm=function(t,n){e.parseError("unexpected-form-in-table"),e.form||(e.insertElement(t,n),e.form=e.currentStackItem(),e.openElements.pop())},t.inTable.startTagOther=function(n,r,i){e.parseError("unexpected-start-tag-implies-table-voodoo",{name:n}),e.redirectAttachToFosterParent=!0,t.inBody.processStartTag(n,r,i),e.redirectAttachToFosterParent=!1},t.inTable.endTagTable=function(t){e.openElements.inTableScope(t)?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early-named",{gotName:"table",expectedName:e.currentStackItem().localName}),e.openElements.popUntilPopped("table"),e.resetInsertionMode()):(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t}))},t.inTable.endTagIgnore=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inTable.endTagOther=function(n){e.parseError("unexpected-end-tag-implies-table-voodoo",{name:n}),e.redirectAttachToFosterParent=!0,t.inBody.processEndTag(n),e.redirectAttachToFosterParent=!1},t.inTableText=Object.create(t.base),t.inTableText.flushCharacters=function(){var t=e.pendingTableCharacters.join("");p(t)?e.insertText(t):(e.redirectAttachToFosterParent=!0,e.reconstructActiveFormattingElements(),e.insertText(t),e.framesetOk=!1,e.redirectAttachToFosterParent=!1),e.pendingTableCharacters=[]},t.inTableText.processComment=function(t){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processComment(t)},t.inTableText.processEOF=function(t){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processEOF()},t.inTableText.processCharacters=function(t){var n=t.takeRemaining();n=n.replace(/\u0000/g,function(t,n){return e.parseError("invalid-codepoint"),""});if(!n)return;e.pendingTableCharacters.push(n)},t.inTableText.processStartTag=function(t,n,r){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processStartTag(t,n,r)},t.inTableText.processEndTag=function(t,n){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processEndTag(t,n)},t.inTableBody=Object.create(t.base),t.inTableBody.start_tag_handlers={html:"startTagHtml",tr:"startTagTr",td:"startTagTableCell",th:"startTagTableCell",caption:"startTagTableOther",col:"startTagTableOther",colgroup:"startTagTableOther",tbody:"startTagTableOther",tfoot:"startTagTableOther",thead:"startTagTableOther","-default":"startTagOther"},t.inTableBody.end_tag_handlers={table:"endTagTable",tbody:"endTagTableRowGroup",tfoot:"endTagTableRowGroup",thead:"endTagTableRowGroup",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",td:"endTagIgnore",th:"endTagIgnore",tr:"endTagIgnore","-default":"endTagOther"},t.inTableBody.processCharacters=function(e){t.inTable.processCharacters(e)},t.inTableBody.startTagTr=function(t,n){e.openElements.popUntilTableBodyScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inRow")},t.inTableBody.startTagTableCell=function(t,n){e.parseError("unexpected-cell-in-table-body",{name:t}),this.startTagTr("tr",[]),e.insertionMode.processStartTag(t,n)},t.inTableBody.startTagTableOther=function(t,n){e.openElements.inTableScope("tbody")||e.openElements.inTableScope("thead")||e.openElements.inTableScope("tfoot")?(e.openElements.popUntilTableBodyScopeMarker(),this.endTagTableRowGroup(e.currentStackItem().localName),e.insertionMode.processStartTag(t,n)):e.parseError("unexpected-start-tag",{name:t})},t.inTableBody.startTagOther=function(e,n){t.inTable.processStartTag(e,n)},t.inTableBody.endTagTableRowGroup=function(t){e.openElements.inTableScope(t)?(e.openElements.popUntilTableBodyScopeMarker(),e.popElement(),e.setInsertionMode("inTable")):e.parseError("unexpected-end-tag-in-table-body",{name:t})},t.inTableBody.endTagTable=function(t){e.openElements.inTableScope("tbody")||e.openElements.inTableScope("thead")||e.openElements.inTableScope("tfoot")?(e.openElements.popUntilTableBodyScopeMarker(),this.endTagTableRowGroup(e.currentStackItem().localName),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inTableBody.endTagIgnore=function(t){e.parseError("unexpected-end-tag-in-table-body",{name:t})},t.inTableBody.endTagOther=function(e){t.inTable.processEndTag(e)},t.inSelect=Object.create(t.base),t.inSelect.start_tag_handlers={html:"startTagHtml",option:"startTagOption",optgroup:"startTagOptgroup",select:"startTagSelect",input:"startTagInput",keygen:"startTagInput",textarea:"startTagInput",script:"startTagScript","-default":"startTagOther"},t.inSelect.end_tag_handlers={option:"endTagOption",optgroup:"endTagOptgroup",select:"endTagSelect",caption:"endTagTableElements",table:"endTagTableElements",tbody:"endTagTableElements",tfoot:"endTagTableElements",thead:"endTagTableElements",tr:"endTagTableElements",td:"endTagTableElements",th:"endTagTableElements","-default":"endTagOther"},t.inSelect.processCharacters=function(t){var n=t.takeRemaining();n=n.replace(/\u0000/g,function(t,n){return e.parseError("invalid-codepoint"),""});if(!n)return;e.insertText(n)},t.inSelect.startTagOption=function(t,n){e.currentStackItem().localName=="option"&&e.popElement(),e.insertElement(t,n)},t.inSelect.startTagOptgroup=function(t,n){e.currentStackItem().localName=="option"&&e.popElement(),e.currentStackItem().localName=="optgroup"&&e.popElement(),e.insertElement(t,n)},t.inSelect.endTagOption=function(t){if(e.currentStackItem().localName!=="option"){e.parseError("unexpected-end-tag-in-select",{name:t});return}e.popElement()},t.inSelect.endTagOptgroup=function(t){e.currentStackItem().localName=="option"&&e.openElements.item(e.openElements.length-2).localName=="optgroup"&&e.popElement(),e.currentStackItem().localName=="optgroup"?e.popElement():e.parseError("unexpected-end-tag-in-select",{name:"optgroup"})},t.inSelect.startTagSelect=function(t){e.parseError("unexpected-select-in-select"),this.endTagSelect("select")},t.inSelect.endTagSelect=function(t){e.openElements.inTableScope("select")?(e.openElements.popUntilPopped("select"),e.resetInsertionMode()):e.parseError("unexpected-end-tag",{name:t})},t.inSelect.startTagInput=function(t,n){e.parseError("unexpected-input-in-select"),e.openElements.inSelectScope("select")&&(this.endTagSelect("select"),e.insertionMode.processStartTag(t,n))},t.inSelect.startTagScript=function(e,n){t.inHead.processStartTag(e,n)},t.inSelect.endTagTableElements=function(t){e.parseError("unexpected-end-tag-in-select",{name:t}),e.openElements.inTableScope(t)&&(this.endTagSelect("select"),e.insertionMode.processEndTag(t))},t.inSelect.startTagOther=function(t,n){e.parseError("unexpected-start-tag-in-select",{name:t})},t.inSelect.endTagOther=function(t){e.parseError("unexpected-end-tag-in-select",{name:t})},t.inSelectInTable=Object.create(t.base),t.inSelectInTable.start_tag_handlers={caption:"startTagTable",table:"startTagTable",tbody:"startTagTable",tfoot:"startTagTable",thead:"startTagTable",tr:"startTagTable",td:"startTagTable",th:"startTagTable","-default":"startTagOther"},t.inSelectInTable.end_tag_handlers={caption:"endTagTable",table:"endTagTable",tbody:"endTagTable",tfoot:"endTagTable",thead:"endTagTable",tr:"endTagTable",td:"endTagTable",th:"endTagTable","-default":"endTagOther"},t.inSelectInTable.processCharacters=function(e){t.inSelect.processCharacters(e)},t.inSelectInTable.startTagTable=function(t,n){e.parseError("unexpected-table-element-start-tag-in-select-in-table",{name:t}),this.endTagOther("select"),e.insertionMode.processStartTag(t,n)},t.inSelectInTable.startTagOther=function(e,n,r){t.inSelect.processStartTag(e,n,r)},t.inSelectInTable.endTagTable=function(t){e.parseError("unexpected-table-element-end-tag-in-select-in-table",{name:t}),e.openElements.inTableScope(t)&&(this.endTagOther("select"),e.insertionMode.processEndTag(t))},t.inSelectInTable.endTagOther=function(e){t.inSelect.processEndTag(e)},t.inRow=Object.create(t.base),t.inRow.start_tag_handlers={html:"startTagHtml",td:"startTagTableCell",th:"startTagTableCell",caption:"startTagTableOther",col:"startTagTableOther",colgroup:"startTagTableOther",tbody:"startTagTableOther",tfoot:"startTagTableOther",thead:"startTagTableOther",tr:"startTagTableOther","-default":"startTagOther"},t.inRow.end_tag_handlers={tr:"endTagTr",table:"endTagTable",tbody:"endTagTableRowGroup",tfoot:"endTagTableRowGroup",thead:"endTagTableRowGroup",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",td:"endTagIgnore",th:"endTagIgnore","-default":"endTagOther"},t.inRow.processCharacters=function(e){t.inTable.processCharacters(e)},t.inRow.startTagTableCell=function(t,n){e.openElements.popUntilTableRowScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inCell"),e.activeFormattingElements.push(l)},t.inRow.startTagTableOther=function(t,n){var r=this.ignoreEndTagTr();this.endTagTr("tr"),r||e.insertionMode.processStartTag(t,n)},t.inRow.startTagOther=function(e,n,r){t.inTable.processStartTag(e,n,r)},t.inRow.endTagTr=function(t){this.ignoreEndTagTr()?(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t})):(e.openElements.popUntilTableRowScopeMarker(),e.popElement(),e.setInsertionMode("inTableBody"))},t.inRow.endTagTable=function(t){var n=this.ignoreEndTagTr();this.endTagTr("tr"),n||e.insertionMode.processEndTag(t)},t.inRow.endTagTableRowGroup=function(t){e.openElements.inTableScope(t)?(this.endTagTr("tr"),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inRow.endTagIgnore=function(t){e.parseError("unexpected-end-tag-in-table-row",{name:t})},t.inRow.endTagOther=function(e){t.inTable.processEndTag(e)},t.inRow.ignoreEndTagTr=function(){return!e.openElements.inTableScope("tr")},t.afterAfterFrameset=Object.create(t.base),t.afterAfterFrameset.start_tag_handlers={html:"startTagHtml",noframes:"startTagNoFrames","-default":"startTagOther"},t.afterAfterFrameset.processEOF=function(){},t.afterAfterFrameset.processComment=function(t){e.insertComment(t,e.document)},t.afterAfterFrameset.processCharacters=function(t){var n=t.takeRemaining(),r="";for(var i=0;i<n.length;i++){var s=n[i];c(s)&&(r+=s)}r&&(e.reconstructActiveFormattingElements(),e.insertText(r)),r.length<n.length&&e.parseError("expected-eof-but-got-char")},t.afterAfterFrameset.startTagNoFrames=function(e,n){t.inHead.processStartTag(e,n)},t.afterAfterFrameset.startTagOther=function(t,n,r){e.parseError("expected-eof-but-got-start-tag",{name:t})},t.afterAfterFrameset.processEndTag=function(t,n){e.parseError("expected-eof-but-got-end-tag",{name:t})},t.text=Object.create(t.base),t.text.start_tag_handlers={"-default":"startTagOther"},t.text.end_tag_handlers={script:"endTagScript","-default":"endTagOther"},t.text.processCharacters=function(t){e.shouldSkipLeadingNewline&&(e.shouldSkipLeadingNewline=!1,t.skipAtMostOneLeadingNewline());var n=t.takeRemaining();if(!n)return;e.insertText(n)},t.text.processEOF=function(){e.parseError("expected-named-closing-tag-but-got-eof",{name:e.currentStackItem().localName}),e.openElements.pop(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processEOF()},t.text.startTagOther=function(e){throw"Tried to process start tag "+e+" in RCDATA/RAWTEXT mode"},t.text.endTagScript=function(t){var n=e.openElements.pop();r.ok(n.localName=="script"),e.setInsertionMode(e.originalInsertionMode)},t.text.endTagOther=function(t){e.openElements.pop(),e.setInsertionMode(e.originalInsertionMode)}}function y(e,t){return e.replace(new RegExp("{[0-9a-z-]+}","gi"),function(e){return t[e.slice(1,-1)]||e})}var r=e("assert"),i=e("./messages.json"),s=e("./constants"),o=e("events").EventEmitter,u=e("./Tokenizer").Tokenizer,a=e("./ElementStack").ElementStack,f=e("./StackItem").StackItem,l={};m.prototype.skipAtMostOneLeadingNewline=function(){this.characters[this.current]==="\n"&&this.current++},m.prototype.skipLeadingWhitespace=function(){while(c(this.characters[this.current]))if(++this.current==this.end)return},m.prototype.skipLeadingNonWhitespace=function(){while(!c(this.characters[this.current]))if(++this.current==this.end)return},m.prototype.takeRemaining=function(){return this.characters.substring(this.current)},m.prototype.takeLeadingWhitespace=function(){var e=this.current;return this.skipLeadingWhitespace(),e===this.current?"":this.characters.substring(e,this.current-e)},Object.defineProperty(m.prototype,"length",{get:function(){return this.end-this.current}}),g.prototype.setInsertionMode=function(e){this.insertionMode=this.insertionModes[e],this.insertionModeName=e},g.prototype.adoptionAgencyEndTag=function(e){function i(e){return e===r}var t=8,n=3,r,s=0;while(s++<t){r=this.elementInActiveFormattingElements(e);if(!r||this.openElements.contains(r)&&!this.openElements.inScope(r.localName))return this.parseError("adoption-agency-1.1",{name:e}),!1;if(!this.openElements.contains(r))return this.parseError("adoption-agency-1.2",{name:e}),this.removeElementFromActiveFormattingElements(r),!0;this.openElements.inScope(r.localName)||this.parseError("adoption-agency-4.4",{name:e}),r!=this.currentStackItem()&&this.parseError("adoption-agency-1.3",{name:e});var o=this.openElements.furthestBlockForFormattingElement(r.node);if(!o)return this.openElements.remove_openElements_until(i),this.removeElementFromActiveFormattingElements(r),!0;var u=this.openElements.elements.indexOf(r),a=this.openElements.item(u-1),l=this.activeFormattingElements.indexOf(r),c=o,h=o,p=this.openElements.elements.indexOf(c),d=0;while(d++<n){p-=1,c=this.openElements.item(p);if(this.activeFormattingElements.indexOf(c)<0){this.openElements.elements.splice(p,1);continue}if(c==r)break;h==o&&(l=this.activeFormattingElements.indexOf(c)+1);var v=this.createElement(c.namespaceURI,c.localName,c.attributes),m=new f(c.namespaceURI,c.localName,c.attributes,v);this.activeFormattingElements[this.activeFormattingElements.indexOf(c)]=m,this.openElements.elements[this.openElements.elements.indexOf(c)]=m,c=m,this.detachFromParent(h.node),this.attachNode(h.node,c.node),h=c}this.detachFromParent(h.node),a.isFosterParenting()?this.insertIntoFosterParent(h.node):this.attachNode(h.node,a.node);var v=this.createElement("http://www.w3.org/1999/xhtml",r.localName,r.attributes),g=new f(r.namespaceURI,r.localName,r.attributes,v);this.reparentChildren(o.node,v),this.attachNode(v,o.node),this.removeElementFromActiveFormattingElements(r),this.activeFormattingElements.splice(Math.min(l,this.activeFormattingElements.length),0,g),this.openElements.remove(r),this.openElements.elements.splice(this.openElements.elements.indexOf(o)+1,0,g)}return!0},g.prototype.start=function(){throw"Not mplemented"},g.prototype.startTokenization=function(e){this.tokenizer=e,this.compatMode="no quirks",this.originalInsertionMode="initial",this.framesetOk=!0,this.openElements=new a,this.activeFormattingElements=[],this.start();if(this.context){switch(this.context){case"title":case"textarea":this.tokenizer.setState(u.RCDATA);break;case"style":case"xmp":case"iframe":case"noembed":case"noframes":this.tokenizer.setState(u.RAWTEXT);break;case"script":this.tokenizer.setState(u.SCRIPT_DATA);break;case"noscript":this.scriptingEnabled&&this.tokenizer.setState(u.RAWTEXT);break;case"plaintext":this.tokenizer.setState(u.PLAINTEXT)}this.insertHtmlElement(),this.resetInsertionMode()}else this.setInsertionMode("initial")},g.prototype.processToken=function(e){this.selfClosingFlagAcknowledged=!1;var t=this.openElements.top||null,n;!t||!t.isForeign()||t.isMathMLTextIntegrationPoint()&&(e.type=="StartTag"&&!(e.name in{mglyph:0,malignmark:0})||e.type==="Characters")||t.namespaceURI=="http://www.w3.org/1998/Math/MathML"&&t.localName=="annotation-xml"&&e.type=="StartTag"&&e.name=="svg"||t.isHtmlIntegrationPoint()&&e.type in{StartTag:0,Characters:0}||e.type=="EOF"?n=this.insertionMode:n=this.insertionModes.inForeignContent;switch(e.type){case"Characters":var r=new m(e.data);n.processCharacters(r);break;case"Comment":n.processComment(e.data);break;case"StartTag":n.processStartTag(e.name,e.data,e.selfClosing);break;case"EndTag":n.processEndTag(e.name);break;case"Doctype":n.processDoctype(e.name,e.publicId,e.systemId,e.forceQuirks);break;case"EOF":n.processEOF()}},g.prototype.isCdataSectionAllowed=function(){return this.openElements.length>0&&this.currentStackItem().isForeign()},g.prototype.isSelfClosingFlagAcknowledged=function(){return this.selfClosingFlagAcknowledged},g.prototype.createElement=function(e,t,n){throw new Error("Not implemented")},g.prototype.attachNode=function(e,t){throw new Error("Not implemented")},g.prototype.attachNodeToFosterParent=function(e,t,n){throw new Error("Not implemented")},g.prototype.detachFromParent=function(e){throw new Error("Not implemented")},g.prototype.addAttributesToElement=function(e,t){throw new Error("Not implemented")},g.prototype.insertHtmlElement=function(e){var t=this.createElement("http://www.w3.org/1999/xhtml","html",e);return this.attachNode(t,this.document),this.openElements.pushHtmlElement(new f("http://www.w3.org/1999/xhtml","html",e,t)),t},g.prototype.insertHeadElement=function(e){var t=this.createElement("http://www.w3.org/1999/xhtml","head",e);return this.head=new f("http://www.w3.org/1999/xhtml","head",e,t),this.attachNode(t,this.openElements.top.node),this.openElements.pushHeadElement(this.head),t},g.prototype.insertBodyElement=function(e){var t=this.createElement("http://www.w3.org/1999/xhtml","body",e);return this.attachNode(t,this.openElements.top.node),this.openElements.pushBodyElement(new f("http://www.w3.org/1999/xhtml","body",e,t)),t},g.prototype.insertIntoFosterParent=function(e){var t=this.openElements.findIndex("table"),n=this.openElements.item(t).node;if(t===0)return this.attachNode(e,n);this.attachNodeToFosterParent(e,n,this.openElements.item(t-1).node)},g.prototype.insertElement=function(e,t,n,r){n||(n="http://www.w3.org/1999/xhtml");var i=this.createElement(n,e,t);this.shouldFosterParent()?this.insertIntoFosterParent(i):this.attachNode(i,this.openElements.top.node),r||this.openElements.push(new f(n,e,t,i))},g.prototype.insertFormattingElement=function(e,t){this.insertElement(e,t,"http://www.w3.org/1999/xhtml"),this.appendElementToActiveFormattingElements(this.currentStackItem())},g.prototype.insertSelfClosingElement=function(e,t){this.selfClosingFlagAcknowledged=!0,this.insertElement(e,t,"http://www.w3.org/1999/xhtml",!0)},g.prototype.insertForeignElement=function(e,t,n,r){r&&(this.selfClosingFlagAcknowledged=!0),this.insertElement(e,t,n,r)},g.prototype.insertComment=function(e,t){throw new Error("Not implemented")},g.prototype.insertDoctype=function(e,t,n){throw new Error("Not implemented")},g.prototype.insertText=function(e){throw new Error("Not implemented")},g.prototype.currentStackItem=function(){return this.openElements.top},g.prototype.popElement=function(){return this.openElements.pop()},g.prototype.shouldFosterParent=function(){return this.redirectAttachToFosterParent&&this.currentStackItem().isFosterParenting()},g.prototype.generateImpliedEndTags=function(e){var t=this.openElements.top.localName;["dd","dt","li","option","optgroup","p","rp","rt"].indexOf(t)!=-1&&t!=e&&(this.popElement(),this.generateImpliedEndTags(e))},g.prototype.reconstructActiveFormattingElements=function(){if(this.activeFormattingElements.length===0)return;var e=this.activeFormattingElements.length-1,t=this.activeFormattingElements[e];if(t==l||this.openElements.contains(t))return;while(t!=l&&!this.openElements.contains(t)){e-=1,t=this.activeFormattingElements[e];if(!t)break}for(;;){e+=1,t=this.activeFormattingElements[e],this.insertElement(t.localName,t.attributes);var n=this.currentStackItem();this.activeFormattingElements[e]=n;if(n==this.activeFormattingElements[this.activeFormattingElements.length-1])break}},g.prototype.ensureNoahsArkCondition=function(e){var t=3;if(this.activeFormattingElements.length<t)return;var n=[],r=e.attributes.length;for(var i=this.activeFormattingElements.length-1;i>=0;i--){var s=this.activeFormattingElements[i];if(s===l)break;if(e.localName!==s.localName||e.namespaceURI!==s.namespaceURI)continue;if(s.attributes.length!=r)continue;n.push(s)}if(n.length<t)return;var o=[],u=e.attributes;for(var i=0;i<u.length;i++){var a=u[i];for(var f=0;f<n.length;f++){var s=n[f],c=v(s,a.nodeName);c&&c.nodeValue===a.nodeValue&&o.push(s)}if(o.length<t)return;n=o,o=[]}for(var i=t-1;i<n.length;i++)this.removeElementFromActiveFormattingElements(n[i])},g.prototype.appendElementToActiveFormattingElements=function(e){this.ensureNoahsArkCondition(e),this.activeFormattingElements.push(e)},g.prototype.removeElementFromActiveFormattingElements=function(e){var t=this.activeFormattingElements.indexOf(e);t>=0&&this.activeFormattingElements.splice(t,1)},g.prototype.elementInActiveFormattingElements=function(e){var t=this.activeFormattingElements;for(var n=t.length-1;n>=0;n--){if(t[n]==l)break;if(t[n].localName==e)return t[n]}return!1},g.prototype.clearActiveFormattingElements=function(){while(this.activeFormattingElements.length!==0&&this.activeFormattingElements.pop()!=l);},g.prototype.reparentChildren=function(e,t){throw new Error("Not implemented")},g.prototype.setFragmentContext=function(e){this.context=e},g.prototype.parseError=function(e,t){if(!this.errorHandler)return;var n=y(i[e],t);this.errorHandler.error(n,this.tokenizer._inputStream.location(),e)},g.prototype.resetInsertionMode=function(){var e=!1,t=null;for(var n=this.openElements.length-1;n>=0;n--){t=this.openElements.item(n),n===0&&(r.ok(this.context),e=!0,t=new f("http://www.w3.org/1999/xhtml",this.context,[],null));if(t.namespaceURI==="http://www.w3.org/1999/xhtml"){if(t.localName==="select")return this.setInsertionMode("inSelect");if(t.localName==="td"||t.localName==="th")return this.setInsertionMode("inCell");if(t.localName==="tr")return this.setInsertionMode("inRow");if(t.localName==="tbody"||t.localName==="thead"||t.localName==="tfoot")return this.setInsertionMode("inTableBody");if(t.localName==="caption")return this.setInsertionMode("inCaption");if(t.localName==="colgroup")return this.setInsertionMode("inColumnGroup");if(t.localName==="table")return this.setInsertionMode("inTable");if(t.localName==="head"&&!e)return this.setInsertionMode("inHead");if(t.localName==="body")return this.setInsertionMode("inBody");if(t.localName==="frameset")return this.setInsertionMode("inFrameset");if(t.localName==="html")return this.openElements.headElement?this.setInsertionMode("afterHead"):this.setInsertionMode("beforeHead")}if(e)return this.setInsertionMode("inBody")}},g.prototype.processGenericRCDATAStartTag=function(e,t){this.insertElement(e,t),this.tokenizer.setState(u.RCDATA),this.originalInsertionMode=this.insertionModeName,this.setInsertionMode("text")},g.prototype.processGenericRawTextStartTag=function(e,t){this.insertElement(e,t),this.tokenizer.setState(u.RAWTEXT),this.originalInsertionMode=this.insertionModeName,this.setInsertionMode("text")},g.prototype.adjustMathMLAttributes=function(e){return e.forEach(function(e){e.namespaceURI="http://www.w3.org/1998/Math/MathML",s.MATHMLAttributeMap[e.nodeName]&&(e.nodeName=s.MATHMLAttributeMap[e.nodeName])}),e},g.prototype.adjustSVGTagNameCase=function(e){return s.SVGTagMap[e]||e},g.prototype.adjustSVGAttributes=function(e){return e.forEach(function(e){e.namespaceURI="http://www.w3.org/2000/svg",s.SVGAttributeMap[e.nodeName]&&(e.nodeName=s.SVGAttributeMap[e.nodeName])}),e},g.prototype.adjustForeignAttributes=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=s.ForeignAttributeMap[n.nodeName];r&&(n.nodeName=r.localName,n.prefix=r.prefix,n.namespaceURI=r.namespaceURI)}return e},n.TreeBuilder=g},{"./ElementStack":1,"./StackItem":4,"./Tokenizer":5,"./constants":7,"./messages.json":8,assert:13,events:16}],7:[function(e,t,n){n.SVGTagMap={altglyph:"altGlyph",altglyphdef:"altGlyphDef",altglyphitem:"altGlyphItem",animatecolor:"animateColor",animatemotion:"animateMotion",animatetransform:"animateTransform",clippath:"clipPath",feblend:"feBlend",fecolormatrix:"feColorMatrix",fecomponenttransfer:"feComponentTransfer",fecomposite:"feComposite",feconvolvematrix:"feConvolveMatrix",fediffuselighting:"feDiffuseLighting",fedisplacementmap:"feDisplacementMap",fedistantlight:"feDistantLight",feflood:"feFlood",fefunca:"feFuncA",fefuncb:"feFuncB",fefuncg:"feFuncG",fefuncr:"feFuncR",fegaussianblur:"feGaussianBlur",feimage:"feImage",femerge:"feMerge",femergenode:"feMergeNode",femorphology:"feMorphology",feoffset:"feOffset",fepointlight:"fePointLight",fespecularlighting:"feSpecularLighting",fespotlight:"feSpotLight",fetile:"feTile",feturbulence:"feTurbulence",foreignobject:"foreignObject",glyphref:"glyphRef",lineargradient:"linearGradient",radialgradient:"radialGradient",textpath:"textPath"},n.MATHMLAttributeMap={definitionurl:"definitionURL"},n.SVGAttributeMap={attributename:"attributeName",attributetype:"attributeType",basefrequency:"baseFrequency",baseprofile:"baseProfile",calcmode:"calcMode",clippathunits:"clipPathUnits",contentscripttype:"contentScriptType",contentstyletype:"contentStyleType",diffuseconstant:"diffuseConstant",edgemode:"edgeMode",externalresourcesrequired:"externalResourcesRequired",filterres:"filterRes",filterunits:"filterUnits",glyphref:"glyphRef",gradienttransform:"gradientTransform",gradientunits:"gradientUnits",kernelmatrix:"kernelMatrix",kernelunitlength:"kernelUnitLength",keypoints:"keyPoints",keysplines:"keySplines",keytimes:"keyTimes",lengthadjust:"lengthAdjust",limitingconeangle:"limitingConeAngle",markerheight:"markerHeight",markerunits:"markerUnits",markerwidth:"markerWidth",maskcontentunits:"maskContentUnits",maskunits:"maskUnits",numoctaves:"numOctaves",pathlength:"pathLength",patterncontentunits:"patternContentUnits",patterntransform:"patternTransform",patternunits:"patternUnits",pointsatx:"pointsAtX",pointsaty:"pointsAtY",pointsatz:"pointsAtZ",preservealpha:"preserveAlpha",preserveaspectratio:"preserveAspectRatio",primitiveunits:"primitiveUnits",refx:"refX",refy:"refY",repeatcount:"repeatCount",repeatdur:"repeatDur",requiredextensions:"requiredExtensions",requiredfeatures:"requiredFeatures",specularconstant:"specularConstant",specularexponent:"specularExponent",spreadmethod:"spreadMethod",startoffset:"startOffset",stddeviation:"stdDeviation",stitchtiles:"stitchTiles",surfacescale:"surfaceScale",systemlanguage:"systemLanguage",tablevalues:"tableValues",targetx:"targetX",targety:"targetY",textlength:"textLength",viewbox:"viewBox",viewtarget:"viewTarget",xchannelselector:"xChannelSelector",ychannelselector:"yChannelSelector",zoomandpan:"zoomAndPan"},n.ForeignAttributeMap={"xlink:actuate":{prefix:"xlink",localName:"actuate",namespaceURI:"http://www.w3.org/1999/xlink"},"xlink:arcrole":{prefix:"xlink",localName:"arcrole",namespaceURI:"http://www.w3.org/1999/xlink"},"xlink:href":{prefix:"xlink",localName:"href",namespaceURI:"http://www.w3.org/1999/xlink"},"xlink:role":{prefix:"xlink",localName:"role",namespaceURI:"http://www.w3.org/1999/xlink"},"xlink:show":{prefix:"xlink",localName:"show",namespaceURI:"http://www.w3.org/1999/xlink"},"xlink:title":{prefix:"xlink",localName:"title",namespaceURI:"http://www.w3.org/1999/xlink"},"xlink:type":{prefix:"xlink",localName:"title",namespaceURI:"http://www.w3.org/1999/xlink"},"xml:base":{prefix:"xml",localName:"base",namespaceURI:"http://www.w3.org/XML/1998/namespace"},"xml:lang":{prefix:"xml",localName:"lang",namespaceURI:"http://www.w3.org/XML/1998/namespace"},"xml:space":{prefix:"xml",localName:"space",namespaceURI:"http://www.w3.org/XML/1998/namespace"},xmlns:{prefix:null,localName:"xmlns",namespaceURI:"http://www.w3.org/2000/xmlns/"},"xmlns:xlink":{prefix:"xmlns",localName:"xlink",namespaceURI:"http://www.w3.org/2000/xmlns/"}}},{}],8:[function(e,t,n){t.exports={"null-character":"Null character in input stream, replaced with U+FFFD.","invalid-codepoint":"Invalid codepoint in stream","incorrectly-placed-solidus":"Solidus (/) incorrectly placed in tag.","incorrect-cr-newline-entity":"Incorrect CR newline entity, replaced with LF.","illegal-windows-1252-entity":"Entity used with illegal number (windows-1252 reference).","cant-convert-numeric-entity":"Numeric entity couldn't be converted to character (codepoint U+{charAsInt}).","invalid-numeric-entity-replaced":"Numeric entity represents an illegal codepoint. Expanded to the C1 controls range.","numeric-entity-without-semicolon":"Numeric entity didn't end with ';'.","expected-numeric-entity-but-got-eof":"Numeric entity expected. Got end of file instead.","expected-numeric-entity":"Numeric entity expected but none found.","named-entity-without-semicolon":"Named entity didn't end with ';'.","expected-named-entity":"Named entity expected. Got none.","attributes-in-end-tag":"End tag contains unexpected attributes.","self-closing-flag-on-end-tag":"End tag contains unexpected self-closing flag.","bare-less-than-sign-at-eof":"End of file after <.","expected-tag-name-but-got-right-bracket":"Expected tag name. Got '>' instead.","expected-tag-name-but-got-question-mark":"Expected tag name. Got '?' instead. (HTML doesn't support processing instructions.)","expected-tag-name":"Expected tag name. Got something else instead.","expected-closing-tag-but-got-right-bracket":"Expected closing tag. Got '>' instead. Ignoring '</>'.","expected-closing-tag-but-got-eof":"Expected closing tag. Unexpected end of file.","expected-closing-tag-but-got-char":"Expected closing tag. Unexpected character '{data}' found.","eof-in-tag-name":"Unexpected end of file in the tag name.","expected-attribute-name-but-got-eof":"Unexpected end of file. Expected attribute name instead.","eof-in-attribute-name":"Unexpected end of file in attribute name.","invalid-character-in-attribute-name":"Invalid character in attribute name.","duplicate-attribute":"Dropped duplicate attribute '{name}' on tag.","expected-end-of-tag-but-got-eof":"Unexpected end of file. Expected = or end of tag.","expected-attribute-value-but-got-eof":"Unexpected end of file. Expected attribute value.","expected-attribute-value-but-got-right-bracket":"Expected attribute value. Got '>' instead.","unexpected-character-in-unquoted-attribute-value":"Unexpected character in unquoted attribute","invalid-character-after-attribute-name":"Unexpected character after attribute name.","unexpected-character-after-attribute-value":"Unexpected character after attribute value.","eof-in-attribute-value-double-quote":'Unexpected end of file in attribute value (").',"eof-in-attribute-value-single-quote":"Unexpected end of file in attribute value (').","eof-in-attribute-value-no-quotes":"Unexpected end of file in attribute value.","eof-after-attribute-value":"Unexpected end of file after attribute value.","unexpected-eof-after-solidus-in-tag":"Unexpected end of file in tag. Expected >.","unexpected-character-after-solidus-in-tag":"Unexpected character after / in tag. Expected >.","expected-dashes-or-doctype":"Expected '--' or 'DOCTYPE'. Not found.","unexpected-bang-after-double-dash-in-comment":"Unexpected ! after -- in comment.","incorrect-comment":"Incorrect comment.","eof-in-comment":"Unexpected end of file in comment.","eof-in-comment-end-dash":"Unexpected end of file in comment (-).","unexpected-dash-after-double-dash-in-comment":"Unexpected '-' after '--' found in comment.","eof-in-comment-double-dash":"Unexpected end of file in comment (--).","eof-in-comment-end-bang-state":"Unexpected end of file in comment.","unexpected-char-in-comment":"Unexpected character in comment found.","need-space-after-doctype":"No space after literal string 'DOCTYPE'.","expected-doctype-name-but-got-right-bracket":"Unexpected > character. Expected DOCTYPE name.","expected-doctype-name-but-got-eof":"Unexpected end of file. Expected DOCTYPE name.","eof-in-doctype-name":"Unexpected end of file in DOCTYPE name.","eof-in-doctype":"Unexpected end of file in DOCTYPE.","expected-space-or-right-bracket-in-doctype":"Expected space or '>'. Got '{data}'.","unexpected-end-of-doctype":"Unexpected end of DOCTYPE.","unexpected-char-in-doctype":"Unexpected character in DOCTYPE.","eof-in-bogus-doctype":"Unexpected end of file in bogus doctype.","eof-in-innerhtml":"Unexpected EOF in inner html mode.","unexpected-doctype":"Unexpected DOCTYPE. Ignored.","non-html-root":"html needs to be the first start tag.","expected-doctype-but-got-eof":"Unexpected End of file. Expected DOCTYPE.","unknown-doctype":"Erroneous DOCTYPE. Expected <!DOCTYPE html>.","quirky-doctype":"Quirky doctype. Expected <!DOCTYPE html>.","almost-standards-doctype":"Almost standards mode doctype. Expected <!DOCTYPE html>.","obsolete-doctype":"Obsolete doctype. Expected <!DOCTYPE html>.","expected-doctype-but-got-chars":"Non-space characters found without seeing a doctype first. Expected e.g. <!DOCTYPE html>.","expected-doctype-but-got-start-tag":"Start tag seen without seeing a doctype first. Expected e.g. <!DOCTYPE html>.","expected-doctype-but-got-end-tag":"End tag seen without seeing a doctype first. Expected e.g. <!DOCTYPE html>.","end-tag-after-implied-root":"Unexpected end tag ({name}) after the (implied) root element.","expected-named-closing-tag-but-got-eof":"Unexpected end of file. Expected end tag ({name}).","two-heads-are-not-better-than-one":"Unexpected start tag head in existing head. Ignored.","unexpected-end-tag":"Unexpected end tag ({name}). Ignored.","unexpected-implied-end-tag":"End tag {name} implied, but there were open elements.","unexpected-start-tag-out-of-my-head":"Unexpected start tag ({name}) that can be in head. Moved.","unexpected-start-tag":"Unexpected start tag ({name}).","missing-end-tag":"Missing end tag ({name}).","missing-end-tags":"Missing end tags ({name}).","unexpected-start-tag-implies-end-tag":"Unexpected start tag ({startName}) implies end tag ({endName}).","unexpected-start-tag-treated-as":"Unexpected start tag ({originalName}). Treated as {newName}.","deprecated-tag":"Unexpected start tag {name}. Don't use it!","unexpected-start-tag-ignored":"Unexpected start tag {name}. Ignored.","expected-one-end-tag-but-got-another":"Unexpected end tag ({gotName}). Missing end tag ({expectedName}).","end-tag-too-early":"End tag ({name}) seen too early. Expected other end tag.","end-tag-too-early-named":"Unexpected end tag ({gotName}). Expected end tag ({expectedName}.","end-tag-too-early-ignored":"End tag ({name}) seen too early. Ignored.","adoption-agency-1.1":"End tag ({name}) violates step 1, paragraph 1 of the adoption agency algorithm.","adoption-agency-1.2":"End tag ({name}) violates step 1, paragraph 2 of the adoption agency algorithm.","adoption-agency-1.3":"End tag ({name}) violates step 1, paragraph 3 of the adoption agency algorithm.","adoption-agency-4.4":"End tag ({name}) violates step 4, paragraph 4 of the adoption agency algorithm.","unexpected-end-tag-treated-as":"Unexpected end tag ({originalName}). Treated as {newName}.","no-end-tag":"This element ({name}) has no end tag.","unexpected-implied-end-tag-in-table":"Unexpected implied end tag ({name}) in the table phase.","unexpected-implied-end-tag-in-table-body":"Unexpected implied end tag ({name}) in the table body phase.","unexpected-char-implies-table-voodoo":"Unexpected non-space characters in table context caused voodoo mode.","unexpected-hidden-input-in-table":"Unexpected input with type hidden in table context.","unexpected-form-in-table":"Unexpected form in table context.","unexpected-start-tag-implies-table-voodoo":"Unexpected start tag ({name}) in table context caused voodoo mode.","unexpected-end-tag-implies-table-voodoo":"Unexpected end tag ({name}) in table context caused voodoo mode.","unexpected-cell-in-table-body":"Unexpected table cell start tag ({name}) in the table body phase.","unexpected-cell-end-tag":"Got table cell end tag ({name}) while required end tags are missing.","unexpected-end-tag-in-table-body":"Unexpected end tag ({name}) in the table body phase. Ignored.","unexpected-implied-end-tag-in-table-row":"Unexpected implied end tag ({name}) in the table row phase.","unexpected-end-tag-in-table-row":"Unexpected end tag ({name}) in the table row phase. Ignored.","unexpected-select-in-select":"Unexpected select start tag in the select phase treated as select end tag.","unexpected-input-in-select":"Unexpected input start tag in the select phase.","unexpected-start-tag-in-select":"Unexpected start tag token ({name}) in the select phase. Ignored.","unexpected-end-tag-in-select":"Unexpected end tag ({name}) in the select phase. Ignored.","unexpected-table-element-start-tag-in-select-in-table":"Unexpected table element start tag ({name}) in the select in table phase.","unexpected-table-element-end-tag-in-select-in-table":"Unexpected table element end tag ({name}) in the select in table phase.","unexpected-char-after-body":"Unexpected non-space characters in the after body phase.","unexpected-start-tag-after-body":"Unexpected start tag token ({name}) in the after body phase.","unexpected-end-tag-after-body":"Unexpected end tag token ({name}) in the after body phase.","unexpected-char-in-frameset":"Unepxected characters in the frameset phase. Characters ignored.","unexpected-start-tag-in-frameset":"Unexpected start tag token ({name}) in the frameset phase. Ignored.","unexpected-frameset-in-frameset-innerhtml":"Unexpected end tag token (frameset in the frameset phase (innerHTML).","unexpected-end-tag-in-frameset":"Unexpected end tag token ({name}) in the frameset phase. Ignored.","unexpected-char-after-frameset":"Unexpected non-space characters in the after frameset phase. Ignored.","unexpected-start-tag-after-frameset":"Unexpected start tag ({name}) in the after frameset phase. Ignored.","unexpected-end-tag-after-frameset":"Unexpected end tag ({name}) in the after frameset phase. Ignored.","expected-eof-but-got-char":"Unexpected non-space characters. Expected end of file.","expected-eof-but-got-start-tag":"Unexpected start tag ({name}). Expected end of file.","expected-eof-but-got-end-tag":"Unexpected end tag ({name}). Expected end of file.","unexpected-end-table-in-caption":"Unexpected end table tag in caption. Generates implied end caption.","end-html-in-innerhtml":"Unexpected html end tag in inner html mode.","eof-in-table":"Unexpected end of file. Expected table content.","eof-in-script":"Unexpected end of file. Expected script content.","non-void-element-with-trailing-solidus":"Trailing solidus not allowed on element {name}.","unexpected-html-element-in-foreign-content":'HTML start tag "{name}" in a foreign namespace context.',"unexpected-start-tag-in-table":"Unexpected {name}. Expected table content."}},{}],9:[function(e,t,n){function o(){this.contentHandler=null,this._errorHandler=null,this._treeBuilder=new r,this._tokenizer=new i(this._treeBuilder),this._scriptingEnabled=!1}var r=e("./SAXTreeBuilder").SAXTreeBuilder,i=e("../Tokenizer").Tokenizer,s=e("./TreeParser").TreeParser;o.prototype.parse=function(e){this._tokenizer.tokenize(e);var t=this._treeBuilder.document;t&&(new s(this.contentHandler)).parse(t)},o.prototype.parseFragment=function(e,t){this._treeBuilder.setFragmentContext(t),this._tokenizer.tokenize(e);var n=this._treeBuilder.getFragment();n&&(new s(this.contentHandler)).parse(n)},Object.defineProperty(o.prototype,"scriptingEnabled",{get:function(){return this._scriptingEnabled},set:function(e){this._scriptingEnabled=e,this._treeBuilder.scriptingEnabled=e}}),Object.defineProperty(o.prototype,"errorHandler",{get:function(){return this._errorHandler},set:function(e){this._errorHandler=e,this._treeBuilder.errorHandler=e}}),n.SAXParser=o},{"../Tokenizer":5,"./SAXTreeBuilder":10,"./TreeParser":11}],10:[function(e,t,n){function s(){i.call(this)}function o(e,t){for(var n=0;n<e.attributes.length;n++){var r=e.attributes[n];if(r.nodeName===t)return r.nodeValue}}function a(e){e?(this.columnNumber=e.columnNumber,this.lineNumber=e.lineNumber):(this.columnNumber=-1,this.lineNumber=-1),this.parentNode=null,this.nextSibling=null,this.firstChild=null}function f(e){a.call(this,e),this.lastChild=null,this._endLocator=null}function l(e){f.call(this,e),this.nodeType=u.DOCUMENT}function c(){f.call(this,new Locator),this.nodeType=u.DOCUMENT_FRAGMENT}function h(e,t,n,r,i,s){f.call(this,e),this.uri=t,this.localName=n,this.qName=r,this.attributes=i,this.prefixMappings=s,this.nodeType=u.ELEMENT}function p(e,t){a.call(this,e),this.data=t,this.nodeType=u.CHARACTERS}function d(e,t){a.call(this,e),this.data=t,this.nodeType=u.IGNORABLE_WHITESPACE}function v(e,t){a.call(this,e),this.data=t,this.nodeType=u.COMMENT}function m(e){f.call(this,e),this.nodeType=u.CDATA}function g(e){f.call(this),this.name=e,this.nodeType=u.ENTITY}function y(e){a.call(this),this.name=e,this.nodeType=u.SKIPPED_ENTITY}function b(e,t){a.call(this),this.target=e,this.data=t}function w(e,t,n){f.call(this),this.name=e,this.publicIdentifier=t,this.systemIdentifier=n,this.nodeType=u.DTD}var r=e("util"),i=e("../TreeBuilder").TreeBuilder;r.inherits(s,i),s.prototype.start=function(e){this.document=new l(this.tokenizer)},s.prototype.end=function(){this.document.endLocator=this.tokenizer},s.prototype.insertDoctype=function(e,t,n){var r=new w(this.tokenizer,e,t,n);r.endLocator=this.tokenizer,this.document.appendChild(r)},s.prototype.createElement=function(e,t,n){var r=new h(this.tokenizer,e,t,t,n||[]);return r},s.prototype.insertComment=function(e,t){t||(t=this.currentStackItem());var n=new v(this.tokenizer,e);t.appendChild(n)},s.prototype.appendCharacters=function(e,t){var n=new p(this.tokenizer,t);e.appendChild(n)},s.prototype.insertText=function(e){if(this.redirectAttachToFosterParent&&this.openElements.top.isFosterParenting()){var t=this.openElements.findIndex("table"),n=this.openElements.item(t),r=n.node;if(t===0)return this.appendCharacters(r,e);var i=new p(this.tokenizer,e),s=r.parentNode;if(s){s.insertBetween(i,r.previousSibling,r);return}var o=this.openElements.item(t-1).node;o.appendChild(i);return}this.appendCharacters(this.currentStackItem().node,e)},s.prototype.attachNode=function(e,t){t.appendChild(e)},s.prototype.attachNodeToFosterParent=function(e,t,n){var r=t.parentNode;r?r.insertBetween(e,t.previousSibling,t):n.appendChild(e)},s.prototype.detachFromParent=function(e){e.detach()},s.prototype.reparentChildren=function(e,t){t.appendChildren(e.firstChild)},s.prototype.getFragment=function(){var e=new c;return this.reparentChildren(this.openElements.rootNode,e),e},s.prototype.addAttributesToElement=function(e,t){for(var n=0;n<t.length;n++){var r=t[n];o(e,r.nodeName)||e.attributes.push(r)}};var u={CDATA:1,CHARACTERS:2,COMMENT:3,DOCUMENT:4,DOCUMENT_FRAGMENT:5,DTD:6,ELEMENT:7,ENTITY:8,IGNORABLE_WHITESPACE:9,PROCESSING_INSTRUCTION:10,SKIPPED_ENTITY:11};a.prototype.visit=function(e){throw new Error("Not Implemented")},a.prototype.revisit=function(e){return},a.prototype.detach=function(){this.parentNode!==null&&(this.parentNode.removeChild(this),this.parentNode=null)},Object.defineProperty(a.prototype,"previousSibling",{get:function(){var e=null,t=this.parentNode.firstChild;for(;;){if(this==t)return e;e=t,t=t.nextSibling}}}),f.prototype=Object.create(a.prototype),f.prototype.insertBefore=function(e,t){if(!t)return this.appendChild(e);e.detach(),e.parentNode=this;if(this.firstChild==t)e.nextSibling=t,this.firstChild=e;else{var n=this.firstChild,r=this.firstChild.nextSibling;while(r!=t)n=r,r=r.nextSibling;n.nextSibling=e,e.nextSibling=r}return e},f.prototype.insertBetween=function(e,t,n){return n?(e.detach(),e.parentNode=this,e.nextSibling=n,t?t.nextSibling=e:firstChild=e,e):this.appendChild(e)},f.prototype.appendChild=function(e){return e.detach(),e.parentNode=this,this.firstChild?this.lastChild.nextSibling=e:this.firstChild=e,this.lastChild=e,e},f.prototype.appendChildren=function(e){var t=e.firstChild;if(!t)return;var n=e;this.firstChild?this.lastChild.nextSibling=t:this.firstChild=t,this.lastChild=n.lastChild;do t.parentNode=this;while(t=t.nextSibling);n.firstChild=null,n.lastChild=null},f.prototype.removeChild=function(e){if(this.firstChild==e)this.firstChild=e.nextSibling,this.lastChild==e&&(this.lastChild=null);else{var t=this.firstChild,n=this.firstChild.nextSibling;while(n!=e)t=n,n=n.nextSibling;t.nextSibling=e.nextSibling,this.lastChild==e&&(this.lastChild=t)}return e.parentNode=null,e},Object.defineProperty(f.prototype,"endLocator",{get:function(){return this._endLocator},set:function(e){this._endLocator={lineNumber:e.lineNumber,columnNumber:e.columnNumber}}}),l.prototype=Object.create(f.prototype),l.prototype.visit=function(e){e.startDocument(this)},l.prototype.revisit=function(e){e.endDocument(this.endLocator)},c.prototype=Object.create(f.prototype),c.prototype.visit=function(e){},h.prototype=Object.create(f.prototype),h.prototype.visit=function(e){if(this.prefixMappings)for(var t in prefixMappings){var n=prefixMappings[t];e.startPrefixMapping(n.getPrefix(),n.getUri(),this)}e.startElement(this.uri,this.localName,this.qName,this.attributes,this)},h.prototype.revisit=function(e){e.endElement(this.uri,this.localName,this.qName,this.endLocator);if(this.prefixMappings)for(var t in prefixMappings){var n=prefixMappings[t];e.endPrefixMapping(n.getPrefix(),this.endLocator)}},p.prototype=Object.create(a.prototype),p.prototype.visit=function(e){e.characters(this.data,0,this.data.length,this)},d.prototype=Object.create(a.prototype),d.prototype.visit=function(e){e.ignorableWhitespace(this.data,0,this.data.length,this)},v.prototype=Object.create(a.prototype),v.prototype.visit=function(e){e.comment(this.data,0,this.data.length,this)},m.prototype=Object.create(f.prototype),m.prototype.visit=function(e){e.startCDATA(this)},m.prototype.revisit=function(e){e.endCDATA(this.endLocator)},g.prototype=Object.create(f.prototype),g.prototype.visit=function(e){e.startEntity(this.name,this)},g.prototype.revisit=function(e){e.endEntity(this.name)},y.prototype=Object.create(a.prototype),y.prototype.visit=function(e){e.skippedEntity(this.name,this)},b.prototype=Object.create(a.prototype),b.prototype.visit=function(e){e.processingInstruction(this.target,this.data,this)},b.prototype.getNodeType=function(){return u.PROCESSING_INSTRUCTION},w.prototype=Object.create(f.prototype),w.prototype.visit=function(e){e.startDTD(this.name,this.publicIdentifier,this.systemIdentifier,this)},w.prototype.revisit=function(e){e.endDTD()},n.SAXTreeBuilder=s},{"../TreeBuilder":6,util:20}],11:[function(e,t,n){function r(e,t){this.contentHandler,this.lexicalHandler,this.locatorDelegate;if(!e)throw new IllegalArgumentException("contentHandler was null.");this.contentHandler=e,t?this.lexicalHandler=t:this.lexicalHandler=new i}function i(){}r.prototype.parse=function(e){this.contentHandler.documentLocator=this;var t=e,n;for(;;){t.visit(this);if(n=t.firstChild){t=n;continue}for(;;){t.revisit(this);if(t==e)return;if(n=t.nextSibling){t=n;break}t=t.parentNode}}},r.prototype.characters=function(e,t,n,r){this.locatorDelegate=r,this.contentHandler.characters(e,t,n)},r.prototype.endDocument=function(e){this.locatorDelegate=e,this.contentHandler.endDocument()},r.prototype.endElement=function(e,t,n,r){this.locatorDelegate=r,this.contentHandler.endElement(e,t,n)},r.prototype.endPrefixMapping=function(e,t){this.locatorDelegate=t,this.contentHandler.endPrefixMapping(e)},r.prototype.ignorableWhitespace=function(e,t,n,r){this.locatorDelegate=r,this.contentHandler.ignorableWhitespace(e,t,n)},r.prototype.processingInstruction=function(e,t,n){this.locatorDelegate=n,this.contentHandler.processingInstruction(e,t)},r.prototype.skippedEntity=function(e,t){this.locatorDelegate=t,this.contentHandler.skippedEntity(e)},r.prototype.startDocument=function(e){this.locatorDelegate=e,this.contentHandler.startDocument()},r.prototype.startElement=function(e,t,n,r,i){this.locatorDelegate=i,this.contentHandler.startElement(e,t,n,r)},r.prototype.startPrefixMapping=function(e,t,n){this.locatorDelegate=n,this.contentHandler.startPrefixMapping(e,t)},r.prototype.comment=function(e,t,n,r){this.locatorDelegate=r,this.lexicalHandler.comment(e,t,n)},r.prototype.endCDATA=function(e){this.locatorDelegate=e,this.lexicalHandler.endCDATA()},r.prototype.endDTD=function(e){this.locatorDelegate=e,this.lexicalHandler.endDTD()},r.prototype.endEntity=function(e,t){this.locatorDelegate=t,this.lexicalHandler.endEntity(e)},r.prototype.startCDATA=function(e){this.locatorDelegate=e,this.lexicalHandler.startCDATA()},r.prototype.startDTD=function(e,t,n,r){this.locatorDelegate=r,this.lexicalHandler.startDTD(e,t,n)},r.prototype.startEntity=function(e,t){this.locatorDelegate=t,this.lexicalHandler.startEntity(e)},Object.defineProperty(r.prototype,"columnNumber",{get:function(){return this.locatorDelegate?this.locatorDelegate.columnNumber:-1}}),Object.defineProperty(r.prototype,"lineNumber",{get:function(){return this.locatorDelegate?this.locatorDelegate.lineNumber:-1}}),i.prototype.comment=function(){},i.prototype.endCDATA=function(){},i.prototype.endDTD=function(){},i.prototype.endEntity=function(){},i.prototype.startCDATA=function(){},i.prototype.startDTD=function(){},i.prototype.startEntity=function(){},n.TreeParser=r},{}],12:[function(e,t,n){t.exports={"Aacute;":"\u00c1",Aacute:"\u00c1","aacute;":"\u00e1",aacute:"\u00e1","Abreve;":"\u0102","abreve;":"\u0103","ac;":"\u223e","acd;":"\u223f","acE;":"\u223e\u0333","Acirc;":"\u00c2",Acirc:"\u00c2","acirc;":"\u00e2",acirc:"\u00e2","acute;":"\u00b4",acute:"\u00b4","Acy;":"\u0410","acy;":"\u0430","AElig;":"\u00c6",AElig:"\u00c6","aelig;":"\u00e6",aelig:"\u00e6","af;":"\u2061","Afr;":"\ud835\udd04","afr;":"\ud835\udd1e","Agrave;":"\u00c0",Agrave:"\u00c0","agrave;":"\u00e0",agrave:"\u00e0","alefsym;":"\u2135","aleph;":"\u2135","Alpha;":"\u0391","alpha;":"\u03b1","Amacr;":"\u0100","amacr;":"\u0101","amalg;":"\u2a3f","amp;":"&",amp:"&","AMP;":"&",AMP:"&","andand;":"\u2a55","And;":"\u2a53","and;":"\u2227","andd;":"\u2a5c","andslope;":"\u2a58","andv;":"\u2a5a","ang;":"\u2220","ange;":"\u29a4","angle;":"\u2220","angmsdaa;":"\u29a8","angmsdab;":"\u29a9","angmsdac;":"\u29aa","angmsdad;":"\u29ab","angmsdae;":"\u29ac","angmsdaf;":"\u29ad","angmsdag;":"\u29ae","angmsdah;":"\u29af","angmsd;":"\u2221","angrt;":"\u221f","angrtvb;":"\u22be","angrtvbd;":"\u299d","angsph;":"\u2222","angst;":"\u00c5","angzarr;":"\u237c","Aogon;":"\u0104","aogon;":"\u0105","Aopf;":"\ud835\udd38","aopf;":"\ud835\udd52","apacir;":"\u2a6f","ap;":"\u2248","apE;":"\u2a70","ape;":"\u224a","apid;":"\u224b","apos;":"'","ApplyFunction;":"\u2061","approx;":"\u2248","approxeq;":"\u224a","Aring;":"\u00c5",Aring:"\u00c5","aring;":"\u00e5",aring:"\u00e5","Ascr;":"\ud835\udc9c","ascr;":"\ud835\udcb6","Assign;":"\u2254","ast;":"*","asymp;":"\u2248","asympeq;":"\u224d","Atilde;":"\u00c3",Atilde:"\u00c3","atilde;":"\u00e3",atilde:"\u00e3","Auml;":"\u00c4",Auml:"\u00c4","auml;":"\u00e4",auml:"\u00e4","awconint;":"\u2233","awint;":"\u2a11","backcong;":"\u224c","backepsilon;":"\u03f6","backprime;":"\u2035","backsim;":"\u223d","backsimeq;":"\u22cd","Backslash;":"\u2216","Barv;":"\u2ae7","barvee;":"\u22bd","barwed;":"\u2305","Barwed;":"\u2306","barwedge;":"\u2305","bbrk;":"\u23b5","bbrktbrk;":"\u23b6","bcong;":"\u224c","Bcy;":"\u0411","bcy;":"\u0431","bdquo;":"\u201e","becaus;":"\u2235","because;":"\u2235","Because;":"\u2235","bemptyv;":"\u29b0","bepsi;":"\u03f6","bernou;":"\u212c","Bernoullis;":"\u212c","Beta;":"\u0392","beta;":"\u03b2","beth;":"\u2136","between;":"\u226c","Bfr;":"\ud835\udd05","bfr;":"\ud835\udd1f","bigcap;":"\u22c2","bigcirc;":"\u25ef","bigcup;":"\u22c3","bigodot;":"\u2a00","bigoplus;":"\u2a01","bigotimes;":"\u2a02","bigsqcup;":"\u2a06","bigstar;":"\u2605","bigtriangledown;":"\u25bd","bigtriangleup;":"\u25b3","biguplus;":"\u2a04","bigvee;":"\u22c1","bigwedge;":"\u22c0","bkarow;":"\u290d","blacklozenge;":"\u29eb","blacksquare;":"\u25aa","blacktriangle;":"\u25b4","blacktriangledown;":"\u25be","blacktriangleleft;":"\u25c2","blacktriangleright;":"\u25b8","blank;":"\u2423","blk12;":"\u2592","blk14;":"\u2591","blk34;":"\u2593","block;":"\u2588","bne;":"=\u20e5","bnequiv;":"\u2261\u20e5","bNot;":"\u2aed","bnot;":"\u2310","Bopf;":"\ud835\udd39","bopf;":"\ud835\udd53","bot;":"\u22a5","bottom;":"\u22a5","bowtie;":"\u22c8","boxbox;":"\u29c9","boxdl;":"\u2510","boxdL;":"\u2555","boxDl;":"\u2556","boxDL;":"\u2557","boxdr;":"\u250c","boxdR;":"\u2552","boxDr;":"\u2553","boxDR;":"\u2554","boxh;":"\u2500","boxH;":"\u2550","boxhd;":"\u252c","boxHd;":"\u2564","boxhD;":"\u2565","boxHD;":"\u2566","boxhu;":"\u2534","boxHu;":"\u2567","boxhU;":"\u2568","boxHU;":"\u2569","boxminus;":"\u229f","boxplus;":"\u229e","boxtimes;":"\u22a0","boxul;":"\u2518","boxuL;":"\u255b","boxUl;":"\u255c","boxUL;":"\u255d","boxur;":"\u2514","boxuR;":"\u2558","boxUr;":"\u2559","boxUR;":"\u255a","boxv;":"\u2502","boxV;":"\u2551","boxvh;":"\u253c","boxvH;":"\u256a","boxVh;":"\u256b","boxVH;":"\u256c","boxvl;":"\u2524","boxvL;":"\u2561","boxVl;":"\u2562","boxVL;":"\u2563","boxvr;":"\u251c","boxvR;":"\u255e","boxVr;":"\u255f","boxVR;":"\u2560","bprime;":"\u2035","breve;":"\u02d8","Breve;":"\u02d8","brvbar;":"\u00a6",brvbar:"\u00a6","bscr;":"\ud835\udcb7","Bscr;":"\u212c","bsemi;":"\u204f","bsim;":"\u223d","bsime;":"\u22cd","bsolb;":"\u29c5","bsol;":"\\","bsolhsub;":"\u27c8","bull;":"\u2022","bullet;":"\u2022","bump;":"\u224e","bumpE;":"\u2aae","bumpe;":"\u224f","Bumpeq;":"\u224e","bumpeq;":"\u224f","Cacute;":"\u0106","cacute;":"\u0107","capand;":"\u2a44","capbrcup;":"\u2a49","capcap;":"\u2a4b","cap;":"\u2229","Cap;":"\u22d2","capcup;":"\u2a47","capdot;":"\u2a40","CapitalDifferentialD;":"\u2145","caps;":"\u2229\ufe00","caret;":"\u2041","caron;":"\u02c7","Cayleys;":"\u212d","ccaps;":"\u2a4d","Ccaron;":"\u010c","ccaron;":"\u010d","Ccedil;":"\u00c7",Ccedil:"\u00c7","ccedil;":"\u00e7",ccedil:"\u00e7","Ccirc;":"\u0108","ccirc;":"\u0109","Cconint;":"\u2230","ccups;":"\u2a4c","ccupssm;":"\u2a50","Cdot;":"\u010a","cdot;":"\u010b","cedil;":"\u00b8",cedil:"\u00b8","Cedilla;":"\u00b8","cemptyv;":"\u29b2","cent;":"\u00a2",cent:"\u00a2","centerdot;":"\u00b7","CenterDot;":"\u00b7","cfr;":"\ud835\udd20","Cfr;":"\u212d","CHcy;":"\u0427","chcy;":"\u0447","check;":"\u2713","checkmark;":"\u2713","Chi;":"\u03a7","chi;":"\u03c7","circ;":"\u02c6","circeq;":"\u2257","circlearrowleft;":"\u21ba","circlearrowright;":"\u21bb","circledast;":"\u229b","circledcirc;":"\u229a","circleddash;":"\u229d","CircleDot;":"\u2299","circledR;":"\u00ae","circledS;":"\u24c8","CircleMinus;":"\u2296","CirclePlus;":"\u2295","CircleTimes;":"\u2297","cir;":"\u25cb","cirE;":"\u29c3","cire;":"\u2257","cirfnint;":"\u2a10","cirmid;":"\u2aef","cirscir;":"\u29c2","ClockwiseContourIntegral;":"\u2232","CloseCurlyDoubleQuote;":"\u201d","CloseCurlyQuote;":"\u2019","clubs;":"\u2663","clubsuit;":"\u2663","colon;":":","Colon;":"\u2237","Colone;":"\u2a74","colone;":"\u2254","coloneq;":"\u2254","comma;":",","commat;":"@","comp;":"\u2201","compfn;":"\u2218","complement;":"\u2201","complexes;":"\u2102","cong;":"\u2245","congdot;":"\u2a6d","Congruent;":"\u2261","conint;":"\u222e","Conint;":"\u222f","ContourIntegral;":"\u222e","copf;":"\ud835\udd54","Copf;":"\u2102","coprod;":"\u2210","Coproduct;":"\u2210","copy;":"\u00a9",copy:"\u00a9","COPY;":"\u00a9",COPY:"\u00a9","copysr;":"\u2117","CounterClockwiseContourIntegral;":"\u2233","crarr;":"\u21b5","cross;":"\u2717","Cross;":"\u2a2f","Cscr;":"\ud835\udc9e","cscr;":"\ud835\udcb8","csub;":"\u2acf","csube;":"\u2ad1","csup;":"\u2ad0","csupe;":"\u2ad2","ctdot;":"\u22ef","cudarrl;":"\u2938","cudarrr;":"\u2935","cuepr;":"\u22de","cuesc;":"\u22df","cularr;":"\u21b6","cularrp;":"\u293d","cupbrcap;":"\u2a48","cupcap;":"\u2a46","CupCap;":"\u224d","cup;":"\u222a","Cup;":"\u22d3","cupcup;":"\u2a4a","cupdot;":"\u228d","cupor;":"\u2a45","cups;":"\u222a\ufe00","curarr;":"\u21b7","curarrm;":"\u293c","curlyeqprec;":"\u22de","curlyeqsucc;":"\u22df","curlyvee;":"\u22ce","curlywedge;":"\u22cf","curren;":"\u00a4",curren:"\u00a4","curvearrowleft;":"\u21b6","curvearrowright;":"\u21b7","cuvee;":"\u22ce","cuwed;":"\u22cf","cwconint;":"\u2232","cwint;":"\u2231","cylcty;":"\u232d","dagger;":"\u2020","Dagger;":"\u2021","daleth;":"\u2138","darr;":"\u2193","Darr;":"\u21a1","dArr;":"\u21d3","dash;":"\u2010","Dashv;":"\u2ae4","dashv;":"\u22a3","dbkarow;":"\u290f","dblac;":"\u02dd","Dcaron;":"\u010e","dcaron;":"\u010f","Dcy;":"\u0414","dcy;":"\u0434","ddagger;":"\u2021","ddarr;":"\u21ca","DD;":"\u2145","dd;":"\u2146","DDotrahd;":"\u2911","ddotseq;":"\u2a77","deg;":"\u00b0",deg:"\u00b0","Del;":"\u2207","Delta;":"\u0394","delta;":"\u03b4","demptyv;":"\u29b1","dfisht;":"\u297f","Dfr;":"\ud835\udd07","dfr;":"\ud835\udd21","dHar;":"\u2965","dharl;":"\u21c3","dharr;":"\u21c2","DiacriticalAcute;":"\u00b4","DiacriticalDot;":"\u02d9","DiacriticalDoubleAcute;":"\u02dd","DiacriticalGrave;":"`","DiacriticalTilde;":"\u02dc","diam;":"\u22c4","diamond;":"\u22c4","Diamond;":"\u22c4","diamondsuit;":"\u2666","diams;":"\u2666","die;":"\u00a8","DifferentialD;":"\u2146","digamma;":"\u03dd","disin;":"\u22f2","div;":"\u00f7","divide;":"\u00f7",divide:"\u00f7","divideontimes;":"\u22c7","divonx;":"\u22c7","DJcy;":"\u0402","djcy;":"\u0452","dlcorn;":"\u231e","dlcrop;":"\u230d","dollar;":"$","Dopf;":"\ud835\udd3b","dopf;":"\ud835\udd55","Dot;":"\u00a8","dot;":"\u02d9","DotDot;":"\u20dc","doteq;":"\u2250","doteqdot;":"\u2251","DotEqual;":"\u2250","dotminus;":"\u2238","dotplus;":"\u2214","dotsquare;":"\u22a1","doublebarwedge;":"\u2306","DoubleContourIntegral;":"\u222f","DoubleDot;":"\u00a8","DoubleDownArrow;":"\u21d3","DoubleLeftArrow;":"\u21d0","DoubleLeftRightArrow;":"\u21d4","DoubleLeftTee;":"\u2ae4","DoubleLongLeftArrow;":"\u27f8","DoubleLongLeftRightArrow;":"\u27fa","DoubleLongRightArrow;":"\u27f9","DoubleRightArrow;":"\u21d2","DoubleRightTee;":"\u22a8","DoubleUpArrow;":"\u21d1","DoubleUpDownArrow;":"\u21d5","DoubleVerticalBar;":"\u2225","DownArrowBar;":"\u2913","downarrow;":"\u2193","DownArrow;":"\u2193","Downarrow;":"\u21d3","DownArrowUpArrow;":"\u21f5","DownBreve;":"\u0311","downdownarrows;":"\u21ca","downharpoonleft;":"\u21c3","downharpoonright;":"\u21c2","DownLeftRightVector;":"\u2950","DownLeftTeeVector;":"\u295e","DownLeftVectorBar;":"\u2956","DownLeftVector;":"\u21bd","DownRightTeeVector;":"\u295f","DownRightVectorBar;":"\u2957","DownRightVector;":"\u21c1","DownTeeArrow;":"\u21a7","DownTee;":"\u22a4","drbkarow;":"\u2910","drcorn;":"\u231f","drcrop;":"\u230c","Dscr;":"\ud835\udc9f","dscr;":"\ud835\udcb9","DScy;":"\u0405","dscy;":"\u0455","dsol;":"\u29f6","Dstrok;":"\u0110","dstrok;":"\u0111","dtdot;":"\u22f1","dtri;":"\u25bf","dtrif;":"\u25be","duarr;":"\u21f5","duhar;":"\u296f","dwangle;":"\u29a6","DZcy;":"\u040f","dzcy;":"\u045f","dzigrarr;":"\u27ff","Eacute;":"\u00c9",Eacute:"\u00c9","eacute;":"\u00e9",eacute:"\u00e9","easter;":"\u2a6e","Ecaron;":"\u011a","ecaron;":"\u011b","Ecirc;":"\u00ca",Ecirc:"\u00ca","ecirc;":"\u00ea",ecirc:"\u00ea","ecir;":"\u2256","ecolon;":"\u2255","Ecy;":"\u042d","ecy;":"\u044d","eDDot;":"\u2a77","Edot;":"\u0116","edot;":"\u0117","eDot;":"\u2251","ee;":"\u2147","efDot;":"\u2252","Efr;":"\ud835\udd08","efr;":"\ud835\udd22","eg;":"\u2a9a","Egrave;":"\u00c8",Egrave:"\u00c8","egrave;":"\u00e8",egrave:"\u00e8","egs;":"\u2a96","egsdot;":"\u2a98","el;":"\u2a99","Element;":"\u2208","elinters;":"\u23e7","ell;":"\u2113","els;":"\u2a95","elsdot;":"\u2a97","Emacr;":"\u0112","emacr;":"\u0113","empty;":"\u2205","emptyset;":"\u2205","EmptySmallSquare;":"\u25fb","emptyv;":"\u2205","EmptyVerySmallSquare;":"\u25ab","emsp13;":"\u2004","emsp14;":"\u2005","emsp;":"\u2003","ENG;":"\u014a","eng;":"\u014b","ensp;":"\u2002","Eogon;":"\u0118","eogon;":"\u0119","Eopf;":"\ud835\udd3c","eopf;":"\ud835\udd56","epar;":"\u22d5","eparsl;":"\u29e3","eplus;":"\u2a71","epsi;":"\u03b5","Epsilon;":"\u0395","epsilon;":"\u03b5","epsiv;":"\u03f5","eqcirc;":"\u2256","eqcolon;":"\u2255","eqsim;":"\u2242","eqslantgtr;":"\u2a96","eqslantless;":"\u2a95","Equal;":"\u2a75","equals;":"=","EqualTilde;":"\u2242","equest;":"\u225f","Equilibrium;":"\u21cc","equiv;":"\u2261","equivDD;":"\u2a78","eqvparsl;":"\u29e5","erarr;":"\u2971","erDot;":"\u2253","escr;":"\u212f","Escr;":"\u2130","esdot;":"\u2250","Esim;":"\u2a73","esim;":"\u2242","Eta;":"\u0397","eta;":"\u03b7","ETH;":"\u00d0",ETH:"\u00d0","eth;":"\u00f0",eth:"\u00f0","Euml;":"\u00cb",Euml:"\u00cb","euml;":"\u00eb",euml:"\u00eb","euro;":"\u20ac","excl;":"!","exist;":"\u2203","Exists;":"\u2203","expectation;":"\u2130","exponentiale;":"\u2147","ExponentialE;":"\u2147","fallingdotseq;":"\u2252","Fcy;":"\u0424","fcy;":"\u0444","female;":"\u2640","ffilig;":"\ufb03","fflig;":"\ufb00","ffllig;":"\ufb04","Ffr;":"\ud835\udd09","ffr;":"\ud835\udd23","filig;":"\ufb01","FilledSmallSquare;":"\u25fc","FilledVerySmallSquare;":"\u25aa","fjlig;":"fj","flat;":"\u266d","fllig;":"\ufb02","fltns;":"\u25b1","fnof;":"\u0192","Fopf;":"\ud835\udd3d","fopf;":"\ud835\udd57","forall;":"\u2200","ForAll;":"\u2200","fork;":"\u22d4","forkv;":"\u2ad9","Fouriertrf;":"\u2131","fpartint;":"\u2a0d","frac12;":"\u00bd",frac12:"\u00bd","frac13;":"\u2153","frac14;":"\u00bc",frac14:"\u00bc","frac15;":"\u2155","frac16;":"\u2159","frac18;":"\u215b","frac23;":"\u2154","frac25;":"\u2156","frac34;":"\u00be",frac34:"\u00be","frac35;":"\u2157","frac38;":"\u215c","frac45;":"\u2158","frac56;":"\u215a","frac58;":"\u215d","frac78;":"\u215e","frasl;":"\u2044","frown;":"\u2322","fscr;":"\ud835\udcbb","Fscr;":"\u2131","gacute;":"\u01f5","Gamma;":"\u0393","gamma;":"\u03b3","Gammad;":"\u03dc","gammad;":"\u03dd","gap;":"\u2a86","Gbreve;":"\u011e","gbreve;":"\u011f","Gcedil;":"\u0122","Gcirc;":"\u011c","gcirc;":"\u011d","Gcy;":"\u0413","gcy;":"\u0433","Gdot;":"\u0120","gdot;":"\u0121","ge;":"\u2265","gE;":"\u2267","gEl;":"\u2a8c","gel;":"\u22db","geq;":"\u2265","geqq;":"\u2267","geqslant;":"\u2a7e","gescc;":"\u2aa9","ges;":"\u2a7e","gesdot;":"\u2a80","gesdoto;":"\u2a82","gesdotol;":"\u2a84","gesl;":"\u22db\ufe00","gesles;":"\u2a94","Gfr;":"\ud835\udd0a","gfr;":"\ud835\udd24","gg;":"\u226b","Gg;":"\u22d9","ggg;":"\u22d9","gimel;":"\u2137","GJcy;":"\u0403","gjcy;":"\u0453","gla;":"\u2aa5","gl;":"\u2277","glE;":"\u2a92","glj;":"\u2aa4","gnap;":"\u2a8a","gnapprox;":"\u2a8a","gne;":"\u2a88","gnE;":"\u2269","gneq;":"\u2a88","gneqq;":"\u2269","gnsim;":"\u22e7","Gopf;":"\ud835\udd3e","gopf;":"\ud835\udd58","grave;":"`","GreaterEqual;":"\u2265","GreaterEqualLess;":"\u22db","GreaterFullEqual;":"\u2267","GreaterGreater;":"\u2aa2","GreaterLess;":"\u2277","GreaterSlantEqual;":"\u2a7e","GreaterTilde;":"\u2273","Gscr;":"\ud835\udca2","gscr;":"\u210a","gsim;":"\u2273","gsime;":"\u2a8e","gsiml;":"\u2a90","gtcc;":"\u2aa7","gtcir;":"\u2a7a","gt;":">",gt:">","GT;":">",GT:">","Gt;":"\u226b","gtdot;":"\u22d7","gtlPar;":"\u2995","gtquest;":"\u2a7c","gtrapprox;":"\u2a86","gtrarr;":"\u2978","gtrdot;":"\u22d7","gtreqless;":"\u22db","gtreqqless;":"\u2a8c","gtrless;":"\u2277","gtrsim;":"\u2273","gvertneqq;":"\u2269\ufe00","gvnE;":"\u2269\ufe00","Hacek;":"\u02c7","hairsp;":"\u200a","half;":"\u00bd","hamilt;":"\u210b","HARDcy;":"\u042a","hardcy;":"\u044a","harrcir;":"\u2948","harr;":"\u2194","hArr;":"\u21d4","harrw;":"\u21ad","Hat;":"^","hbar;":"\u210f","Hcirc;":"\u0124","hcirc;":"\u0125","hearts;":"\u2665","heartsuit;":"\u2665","hellip;":"\u2026","hercon;":"\u22b9","hfr;":"\ud835\udd25","Hfr;":"\u210c","HilbertSpace;":"\u210b","hksearow;":"\u2925","hkswarow;":"\u2926","hoarr;":"\u21ff","homtht;":"\u223b","hookleftarrow;":"\u21a9","hookrightarrow;":"\u21aa","hopf;":"\ud835\udd59","Hopf;":"\u210d","horbar;":"\u2015","HorizontalLine;":"\u2500","hscr;":"\ud835\udcbd","Hscr;":"\u210b","hslash;":"\u210f","Hstrok;":"\u0126","hstrok;":"\u0127","HumpDownHump;":"\u224e","HumpEqual;":"\u224f","hybull;":"\u2043","hyphen;":"\u2010","Iacute;":"\u00cd",Iacute:"\u00cd","iacute;":"\u00ed",iacute:"\u00ed","ic;":"\u2063","Icirc;":"\u00ce",Icirc:"\u00ce","icirc;":"\u00ee",icirc:"\u00ee","Icy;":"\u0418","icy;":"\u0438","Idot;":"\u0130","IEcy;":"\u0415","iecy;":"\u0435","iexcl;":"\u00a1",iexcl:"\u00a1","iff;":"\u21d4","ifr;":"\ud835\udd26","Ifr;":"\u2111","Igrave;":"\u00cc",Igrave:"\u00cc","igrave;":"\u00ec",igrave:"\u00ec","ii;":"\u2148","iiiint;":"\u2a0c","iiint;":"\u222d","iinfin;":"\u29dc","iiota;":"\u2129","IJlig;":"\u0132","ijlig;":"\u0133","Imacr;":"\u012a","imacr;":"\u012b","image;":"\u2111","ImaginaryI;":"\u2148","imagline;":"\u2110","imagpart;":"\u2111","imath;":"\u0131","Im;":"\u2111","imof;":"\u22b7","imped;":"\u01b5","Implies;":"\u21d2","incare;":"\u2105","in;":"\u2208","infin;":"\u221e","infintie;":"\u29dd","inodot;":"\u0131","intcal;":"\u22ba","int;":"\u222b","Int;":"\u222c","integers;":"\u2124","Integral;":"\u222b","intercal;":"\u22ba","Intersection;":"\u22c2","intlarhk;":"\u2a17","intprod;":"\u2a3c","InvisibleComma;":"\u2063","InvisibleTimes;":"\u2062","IOcy;":"\u0401","iocy;":"\u0451","Iogon;":"\u012e","iogon;":"\u012f","Iopf;":"\ud835\udd40","iopf;":"\ud835\udd5a","Iota;":"\u0399","iota;":"\u03b9","iprod;":"\u2a3c","iquest;":"\u00bf",iquest:"\u00bf","iscr;":"\ud835\udcbe","Iscr;":"\u2110","isin;":"\u2208","isindot;":"\u22f5","isinE;":"\u22f9","isins;":"\u22f4","isinsv;":"\u22f3","isinv;":"\u2208","it;":"\u2062","Itilde;":"\u0128","itilde;":"\u0129","Iukcy;":"\u0406","iukcy;":"\u0456","Iuml;":"\u00cf",Iuml:"\u00cf","iuml;":"\u00ef",iuml:"\u00ef","Jcirc;":"\u0134","jcirc;":"\u0135","Jcy;":"\u0419","jcy;":"\u0439","Jfr;":"\ud835\udd0d","jfr;":"\ud835\udd27","jmath;":"\u0237","Jopf;":"\ud835\udd41","jopf;":"\ud835\udd5b","Jscr;":"\ud835\udca5","jscr;":"\ud835\udcbf","Jsercy;":"\u0408","jsercy;":"\u0458","Jukcy;":"\u0404","jukcy;":"\u0454","Kappa;":"\u039a","kappa;":"\u03ba","kappav;":"\u03f0","Kcedil;":"\u0136","kcedil;":"\u0137","Kcy;":"\u041a","kcy;":"\u043a","Kfr;":"\ud835\udd0e","kfr;":"\ud835\udd28","kgreen;":"\u0138","KHcy;":"\u0425","khcy;":"\u0445","KJcy;":"\u040c","kjcy;":"\u045c","Kopf;":"\ud835\udd42","kopf;":"\ud835\udd5c","Kscr;":"\ud835\udca6","kscr;":"\ud835\udcc0","lAarr;":"\u21da","Lacute;":"\u0139","lacute;":"\u013a","laemptyv;":"\u29b4","lagran;":"\u2112","Lambda;":"\u039b","lambda;":"\u03bb","lang;":"\u27e8","Lang;":"\u27ea","langd;":"\u2991","langle;":"\u27e8","lap;":"\u2a85","Laplacetrf;":"\u2112","laquo;":"\u00ab",laquo:"\u00ab","larrb;":"\u21e4","larrbfs;":"\u291f","larr;":"\u2190","Larr;":"\u219e","lArr;":"\u21d0","larrfs;":"\u291d","larrhk;":"\u21a9","larrlp;":"\u21ab","larrpl;":"\u2939","larrsim;":"\u2973","larrtl;":"\u21a2","latail;":"\u2919","lAtail;":"\u291b","lat;":"\u2aab","late;":"\u2aad","lates;":"\u2aad\ufe00","lbarr;":"\u290c","lBarr;":"\u290e","lbbrk;":"\u2772","lbrace;":"{","lbrack;":"[","lbrke;":"\u298b","lbrksld;":"\u298f","lbrkslu;":"\u298d","Lcaron;":"\u013d","lcaron;":"\u013e","Lcedil;":"\u013b","lcedil;":"\u013c","lceil;":"\u2308","lcub;":"{","Lcy;":"\u041b","lcy;":"\u043b","ldca;":"\u2936","ldquo;":"\u201c","ldquor;":"\u201e","ldrdhar;":"\u2967","ldrushar;":"\u294b","ldsh;":"\u21b2","le;":"\u2264","lE;":"\u2266","LeftAngleBracket;":"\u27e8","LeftArrowBar;":"\u21e4","leftarrow;":"\u2190","LeftArrow;":"\u2190","Leftarrow;":"\u21d0","LeftArrowRightArrow;":"\u21c6","leftarrowtail;":"\u21a2","LeftCeiling;":"\u2308","LeftDoubleBracket;":"\u27e6","LeftDownTeeVector;":"\u2961","LeftDownVectorBar;":"\u2959","LeftDownVector;":"\u21c3","LeftFloor;":"\u230a","leftharpoondown;":"\u21bd","leftharpoonup;":"\u21bc","leftleftarrows;":"\u21c7","leftrightarrow;":"\u2194","LeftRightArrow;":"\u2194","Leftrightarrow;":"\u21d4","leftrightarrows;":"\u21c6","leftrightharpoons;":"\u21cb","leftrightsquigarrow;":"\u21ad","LeftRightVector;":"\u294e","LeftTeeArrow;":"\u21a4","LeftTee;":"\u22a3","LeftTeeVector;":"\u295a","leftthreetimes;":"\u22cb","LeftTriangleBar;":"\u29cf","LeftTriangle;":"\u22b2","LeftTriangleEqual;":"\u22b4","LeftUpDownVector;":"\u2951","LeftUpTeeVector;":"\u2960","LeftUpVectorBar;":"\u2958","LeftUpVector;":"\u21bf","LeftVectorBar;":"\u2952","LeftVector;":"\u21bc","lEg;":"\u2a8b","leg;":"\u22da","leq;":"\u2264","leqq;":"\u2266","leqslant;":"\u2a7d","lescc;":"\u2aa8","les;":"\u2a7d","lesdot;":"\u2a7f","lesdoto;":"\u2a81","lesdotor;":"\u2a83","lesg;":"\u22da\ufe00","lesges;":"\u2a93","lessapprox;":"\u2a85","lessdot;":"\u22d6","lesseqgtr;":"\u22da","lesseqqgtr;":"\u2a8b","LessEqualGreater;":"\u22da","LessFullEqual;":"\u2266","LessGreater;":"\u2276","lessgtr;":"\u2276","LessLess;":"\u2aa1","lesssim;":"\u2272","LessSlantEqual;":"\u2a7d","LessTilde;":"\u2272","lfisht;":"\u297c","lfloor;":"\u230a","Lfr;":"\ud835\udd0f","lfr;":"\ud835\udd29","lg;":"\u2276","lgE;":"\u2a91","lHar;":"\u2962","lhard;":"\u21bd","lharu;":"\u21bc","lharul;":"\u296a","lhblk;":"\u2584","LJcy;":"\u0409","ljcy;":"\u0459","llarr;":"\u21c7","ll;":"\u226a","Ll;":"\u22d8","llcorner;":"\u231e","Lleftarrow;":"\u21da","llhard;":"\u296b","lltri;":"\u25fa","Lmidot;":"\u013f","lmidot;":"\u0140","lmoustache;":"\u23b0","lmoust;":"\u23b0","lnap;":"\u2a89","lnapprox;":"\u2a89","lne;":"\u2a87","lnE;":"\u2268","lneq;":"\u2a87","lneqq;":"\u2268","lnsim;":"\u22e6","loang;":"\u27ec","loarr;":"\u21fd","lobrk;":"\u27e6","longleftarrow;":"\u27f5","LongLeftArrow;":"\u27f5","Longleftarrow;":"\u27f8","longleftrightarrow;":"\u27f7","LongLeftRightArrow;":"\u27f7","Longleftrightarrow;":"\u27fa","longmapsto;":"\u27fc","longrightarrow;":"\u27f6","LongRightArrow;":"\u27f6","Longrightarrow;":"\u27f9","looparrowleft;":"\u21ab","looparrowright;":"\u21ac","lopar;":"\u2985","Lopf;":"\ud835\udd43","lopf;":"\ud835\udd5d","loplus;":"\u2a2d","lotimes;":"\u2a34","lowast;":"\u2217","lowbar;":"_","LowerLeftArrow;":"\u2199","LowerRightArrow;":"\u2198","loz;":"\u25ca","lozenge;":"\u25ca","lozf;":"\u29eb","lpar;":"(","lparlt;":"\u2993","lrarr;":"\u21c6","lrcorner;":"\u231f","lrhar;":"\u21cb","lrhard;":"\u296d","lrm;":"\u200e","lrtri;":"\u22bf","lsaquo;":"\u2039","lscr;":"\ud835\udcc1","Lscr;":"\u2112","lsh;":"\u21b0","Lsh;":"\u21b0","lsim;":"\u2272","lsime;":"\u2a8d","lsimg;":"\u2a8f","lsqb;":"[","lsquo;":"\u2018","lsquor;":"\u201a","Lstrok;":"\u0141","lstrok;":"\u0142","ltcc;":"\u2aa6","ltcir;":"\u2a79","lt;":"<",lt:"<","LT;":"<",LT:"<","Lt;":"\u226a","ltdot;":"\u22d6","lthree;":"\u22cb","ltimes;":"\u22c9","ltlarr;":"\u2976","ltquest;":"\u2a7b","ltri;":"\u25c3","ltrie;":"\u22b4","ltrif;":"\u25c2","ltrPar;":"\u2996","lurdshar;":"\u294a","luruhar;":"\u2966","lvertneqq;":"\u2268\ufe00","lvnE;":"\u2268\ufe00","macr;":"\u00af",macr:"\u00af","male;":"\u2642","malt;":"\u2720","maltese;":"\u2720","Map;":"\u2905","map;":"\u21a6","mapsto;":"\u21a6","mapstodown;":"\u21a7","mapstoleft;":"\u21a4","mapstoup;":"\u21a5","marker;":"\u25ae","mcomma;":"\u2a29","Mcy;":"\u041c","mcy;":"\u043c","mdash;":"\u2014","mDDot;":"\u223a","measuredangle;":"\u2221","MediumSpace;":"\u205f","Mellintrf;":"\u2133","Mfr;":"\ud835\udd10","mfr;":"\ud835\udd2a","mho;":"\u2127","micro;":"\u00b5",micro:"\u00b5","midast;":"*","midcir;":"\u2af0","mid;":"\u2223","middot;":"\u00b7",middot:"\u00b7","minusb;":"\u229f","minus;":"\u2212","minusd;":"\u2238","minusdu;":"\u2a2a","MinusPlus;":"\u2213","mlcp;":"\u2adb","mldr;":"\u2026","mnplus;":"\u2213","models;":"\u22a7","Mopf;":"\ud835\udd44","mopf;":"\ud835\udd5e","mp;":"\u2213","mscr;":"\ud835\udcc2","Mscr;":"\u2133","mstpos;":"\u223e","Mu;":"\u039c","mu;":"\u03bc","multimap;":"\u22b8","mumap;":"\u22b8","nabla;":"\u2207","Nacute;":"\u0143","nacute;":"\u0144","nang;":"\u2220\u20d2","nap;":"\u2249","napE;":"\u2a70\u0338","napid;":"\u224b\u0338","napos;":"\u0149","napprox;":"\u2249","natural;":"\u266e","naturals;":"\u2115","natur;":"\u266e","nbsp;":"\u00a0",nbsp:"\u00a0","nbump;":"\u224e\u0338","nbumpe;":"\u224f\u0338","ncap;":"\u2a43","Ncaron;":"\u0147","ncaron;":"\u0148","Ncedil;":"\u0145","ncedil;":"\u0146","ncong;":"\u2247","ncongdot;":"\u2a6d\u0338","ncup;":"\u2a42","Ncy;":"\u041d","ncy;":"\u043d","ndash;":"\u2013","nearhk;":"\u2924","nearr;":"\u2197","neArr;":"\u21d7","nearrow;":"\u2197","ne;":"\u2260","nedot;":"\u2250\u0338","NegativeMediumSpace;":"\u200b","NegativeThickSpace;":"\u200b","NegativeThinSpace;":"\u200b","NegativeVeryThinSpace;":"\u200b","nequiv;":"\u2262","nesear;":"\u2928","nesim;":"\u2242\u0338","NestedGreaterGreater;":"\u226b","NestedLessLess;":"\u226a","NewLine;":"\n","nexist;":"\u2204","nexists;":"\u2204","Nfr;":"\ud835\udd11","nfr;":"\ud835\udd2b","ngE;":"\u2267\u0338","nge;":"\u2271","ngeq;":"\u2271","ngeqq;":"\u2267\u0338","ngeqslant;":"\u2a7e\u0338","nges;":"\u2a7e\u0338","nGg;":"\u22d9\u0338","ngsim;":"\u2275","nGt;":"\u226b\u20d2","ngt;":"\u226f","ngtr;":"\u226f","nGtv;":"\u226b\u0338","nharr;":"\u21ae","nhArr;":"\u21ce","nhpar;":"\u2af2","ni;":"\u220b","nis;":"\u22fc","nisd;":"\u22fa","niv;":"\u220b","NJcy;":"\u040a","njcy;":"\u045a","nlarr;":"\u219a","nlArr;":"\u21cd","nldr;":"\u2025","nlE;":"\u2266\u0338","nle;":"\u2270","nleftarrow;":"\u219a","nLeftarrow;":"\u21cd","nleftrightarrow;":"\u21ae","nLeftrightarrow;":"\u21ce","nleq;":"\u2270","nleqq;":"\u2266\u0338","nleqslant;":"\u2a7d\u0338","nles;":"\u2a7d\u0338","nless;":"\u226e","nLl;":"\u22d8\u0338","nlsim;":"\u2274","nLt;":"\u226a\u20d2","nlt;":"\u226e","nltri;":"\u22ea","nltrie;":"\u22ec","nLtv;":"\u226a\u0338","nmid;":"\u2224","NoBreak;":"\u2060","NonBreakingSpace;":"\u00a0","nopf;":"\ud835\udd5f","Nopf;":"\u2115","Not;":"\u2aec","not;":"\u00ac",not:"\u00ac","NotCongruent;":"\u2262","NotCupCap;":"\u226d","NotDoubleVerticalBar;":"\u2226","NotElement;":"\u2209","NotEqual;":"\u2260","NotEqualTilde;":"\u2242\u0338","NotExists;":"\u2204","NotGreater;":"\u226f","NotGreaterEqual;":"\u2271","NotGreaterFullEqual;":"\u2267\u0338","NotGreaterGreater;":"\u226b\u0338","NotGreaterLess;":"\u2279","NotGreaterSlantEqual;":"\u2a7e\u0338","NotGreaterTilde;":"\u2275","NotHumpDownHump;":"\u224e\u0338","NotHumpEqual;":"\u224f\u0338","notin;":"\u2209","notindot;":"\u22f5\u0338","notinE;":"\u22f9\u0338","notinva;":"\u2209","notinvb;":"\u22f7","notinvc;":"\u22f6","NotLeftTriangleBar;":"\u29cf\u0338","NotLeftTriangle;":"\u22ea","NotLeftTriangleEqual;":"\u22ec","NotLess;":"\u226e","NotLessEqual;":"\u2270","NotLessGreater;":"\u2278","NotLessLess;":"\u226a\u0338","NotLessSlantEqual;":"\u2a7d\u0338","NotLessTilde;":"\u2274","NotNestedGreaterGreater;":"\u2aa2\u0338","NotNestedLessLess;":"\u2aa1\u0338","notni;":"\u220c","notniva;":"\u220c","notnivb;":"\u22fe","notnivc;":"\u22fd","NotPrecedes;":"\u2280","NotPrecedesEqual;":"\u2aaf\u0338","NotPrecedesSlantEqual;":"\u22e0","NotReverseElement;":"\u220c","NotRightTriangleBar;":"\u29d0\u0338","NotRightTriangle;":"\u22eb","NotRightTriangleEqual;":"\u22ed","NotSquareSubset;":"\u228f\u0338","NotSquareSubsetEqual;":"\u22e2","NotSquareSuperset;":"\u2290\u0338","NotSquareSupersetEqual;":"\u22e3","NotSubset;":"\u2282\u20d2","NotSubsetEqual;":"\u2288","NotSucceeds;":"\u2281","NotSucceedsEqual;":"\u2ab0\u0338","NotSucceedsSlantEqual;":"\u22e1","NotSucceedsTilde;":"\u227f\u0338","NotSuperset;":"\u2283\u20d2","NotSupersetEqual;":"\u2289","NotTilde;":"\u2241","NotTildeEqual;":"\u2244","NotTildeFullEqual;":"\u2247","NotTildeTilde;":"\u2249","NotVerticalBar;":"\u2224","nparallel;":"\u2226","npar;":"\u2226","nparsl;":"\u2afd\u20e5","npart;":"\u2202\u0338","npolint;":"\u2a14","npr;":"\u2280","nprcue;":"\u22e0","nprec;":"\u2280","npreceq;":"\u2aaf\u0338","npre;":"\u2aaf\u0338","nrarrc;":"\u2933\u0338","nrarr;":"\u219b","nrArr;":"\u21cf","nrarrw;":"\u219d\u0338","nrightarrow;":"\u219b","nRightarrow;":"\u21cf","nrtri;":"\u22eb","nrtrie;":"\u22ed","nsc;":"\u2281","nsccue;":"\u22e1","nsce;":"\u2ab0\u0338","Nscr;":"\ud835\udca9","nscr;":"\ud835\udcc3","nshortmid;":"\u2224","nshortparallel;":"\u2226","nsim;":"\u2241","nsime;":"\u2244","nsimeq;":"\u2244","nsmid;":"\u2224","nspar;":"\u2226","nsqsube;":"\u22e2","nsqsupe;":"\u22e3","nsub;":"\u2284","nsubE;":"\u2ac5\u0338","nsube;":"\u2288","nsubset;":"\u2282\u20d2","nsubseteq;":"\u2288","nsubseteqq;":"\u2ac5\u0338","nsucc;":"\u2281","nsucceq;":"\u2ab0\u0338","nsup;":"\u2285","nsupE;":"\u2ac6\u0338","nsupe;":"\u2289","nsupset;":"\u2283\u20d2","nsupseteq;":"\u2289","nsupseteqq;":"\u2ac6\u0338","ntgl;":"\u2279","Ntilde;":"\u00d1",Ntilde:"\u00d1","ntilde;":"\u00f1",ntilde:"\u00f1","ntlg;":"\u2278","ntriangleleft;":"\u22ea","ntrianglelefteq;":"\u22ec","ntriangleright;":"\u22eb","ntrianglerighteq;":"\u22ed","Nu;":"\u039d","nu;":"\u03bd","num;":"#","numero;":"\u2116","numsp;":"\u2007","nvap;":"\u224d\u20d2","nvdash;":"\u22ac","nvDash;":"\u22ad","nVdash;":"\u22ae","nVDash;":"\u22af","nvge;":"\u2265\u20d2","nvgt;":">\u20d2","nvHarr;":"\u2904","nvinfin;":"\u29de","nvlArr;":"\u2902","nvle;":"\u2264\u20d2","nvlt;":"<\u20d2","nvltrie;":"\u22b4\u20d2","nvrArr;":"\u2903","nvrtrie;":"\u22b5\u20d2","nvsim;":"\u223c\u20d2","nwarhk;":"\u2923","nwarr;":"\u2196","nwArr;":"\u21d6","nwarrow;":"\u2196","nwnear;":"\u2927","Oacute;":"\u00d3",Oacute:"\u00d3","oacute;":"\u00f3",oacute:"\u00f3","oast;":"\u229b","Ocirc;":"\u00d4",Ocirc:"\u00d4","ocirc;":"\u00f4",ocirc:"\u00f4","ocir;":"\u229a","Ocy;":"\u041e","ocy;":"\u043e","odash;":"\u229d","Odblac;":"\u0150","odblac;":"\u0151","odiv;":"\u2a38","odot;":"\u2299","odsold;":"\u29bc","OElig;":"\u0152","oelig;":"\u0153","ofcir;":"\u29bf","Ofr;":"\ud835\udd12","ofr;":"\ud835\udd2c","ogon;":"\u02db","Ograve;":"\u00d2",Ograve:"\u00d2","ograve;":"\u00f2",ograve:"\u00f2","ogt;":"\u29c1","ohbar;":"\u29b5","ohm;":"\u03a9","oint;":"\u222e","olarr;":"\u21ba","olcir;":"\u29be","olcross;":"\u29bb","oline;":"\u203e","olt;":"\u29c0","Omacr;":"\u014c","omacr;":"\u014d","Omega;":"\u03a9","omega;":"\u03c9","Omicron;":"\u039f","omicron;":"\u03bf","omid;":"\u29b6","ominus;":"\u2296","Oopf;":"\ud835\udd46","oopf;":"\ud835\udd60","opar;":"\u29b7","OpenCurlyDoubleQuote;":"\u201c","OpenCurlyQuote;":"\u2018","operp;":"\u29b9","oplus;":"\u2295","orarr;":"\u21bb","Or;":"\u2a54","or;":"\u2228","ord;":"\u2a5d","order;":"\u2134","orderof;":"\u2134","ordf;":"\u00aa",ordf:"\u00aa","ordm;":"\u00ba",ordm:"\u00ba","origof;":"\u22b6","oror;":"\u2a56","orslope;":"\u2a57","orv;":"\u2a5b","oS;":"\u24c8","Oscr;":"\ud835\udcaa","oscr;":"\u2134","Oslash;":"\u00d8",Oslash:"\u00d8","oslash;":"\u00f8",oslash:"\u00f8","osol;":"\u2298","Otilde;":"\u00d5",Otilde:"\u00d5","otilde;":"\u00f5",otilde:"\u00f5","otimesas;":"\u2a36","Otimes;":"\u2a37","otimes;":"\u2297","Ouml;":"\u00d6",Ouml:"\u00d6","ouml;":"\u00f6",ouml:"\u00f6","ovbar;":"\u233d","OverBar;":"\u203e","OverBrace;":"\u23de","OverBracket;":"\u23b4","OverParenthesis;":"\u23dc","para;":"\u00b6",para:"\u00b6","parallel;":"\u2225","par;":"\u2225","parsim;":"\u2af3","parsl;":"\u2afd","part;":"\u2202","PartialD;":"\u2202","Pcy;":"\u041f","pcy;":"\u043f","percnt;":"%","period;":".","permil;":"\u2030","perp;":"\u22a5","pertenk;":"\u2031","Pfr;":"\ud835\udd13","pfr;":"\ud835\udd2d","Phi;":"\u03a6","phi;":"\u03c6","phiv;":"\u03d5","phmmat;":"\u2133","phone;":"\u260e","Pi;":"\u03a0","pi;":"\u03c0","pitchfork;":"\u22d4","piv;":"\u03d6","planck;":"\u210f","planckh;":"\u210e","plankv;":"\u210f","plusacir;":"\u2a23","plusb;":"\u229e","pluscir;":"\u2a22","plus;":"+","plusdo;":"\u2214","plusdu;":"\u2a25","pluse;":"\u2a72","PlusMinus;":"\u00b1","plusmn;":"\u00b1",plusmn:"\u00b1","plussim;":"\u2a26","plustwo;":"\u2a27","pm;":"\u00b1","Poincareplane;":"\u210c","pointint;":"\u2a15","popf;":"\ud835\udd61","Popf;":"\u2119","pound;":"\u00a3",pound:"\u00a3","prap;":"\u2ab7","Pr;":"\u2abb","pr;":"\u227a","prcue;":"\u227c","precapprox;":"\u2ab7","prec;":"\u227a","preccurlyeq;":"\u227c","Precedes;":"\u227a","PrecedesEqual;":"\u2aaf","PrecedesSlantEqual;":"\u227c","PrecedesTilde;":"\u227e","preceq;":"\u2aaf","precnapprox;":"\u2ab9","precneqq;":"\u2ab5","precnsim;":"\u22e8","pre;":"\u2aaf","prE;":"\u2ab3","precsim;":"\u227e","prime;":"\u2032","Prime;":"\u2033","primes;":"\u2119","prnap;":"\u2ab9","prnE;":"\u2ab5","prnsim;":"\u22e8","prod;":"\u220f","Product;":"\u220f","profalar;":"\u232e","profline;":"\u2312","profsurf;":"\u2313","prop;":"\u221d","Proportional;":"\u221d","Proportion;":"\u2237","propto;":"\u221d","prsim;":"\u227e","prurel;":"\u22b0","Pscr;":"\ud835\udcab","pscr;":"\ud835\udcc5","Psi;":"\u03a8","psi;":"\u03c8","puncsp;":"\u2008","Qfr;":"\ud835\udd14","qfr;":"\ud835\udd2e","qint;":"\u2a0c","qopf;":"\ud835\udd62","Qopf;":"\u211a","qprime;":"\u2057","Qscr;":"\ud835\udcac","qscr;":"\ud835\udcc6","quaternions;":"\u210d","quatint;":"\u2a16","quest;":"?","questeq;":"\u225f","quot;":'"',quot:'"',"QUOT;":'"',QUOT:'"',"rAarr;":"\u21db","race;":"\u223d\u0331","Racute;":"\u0154","racute;":"\u0155","radic;":"\u221a","raemptyv;":"\u29b3","rang;":"\u27e9","Rang;":"\u27eb","rangd;":"\u2992","range;":"\u29a5","rangle;":"\u27e9","raquo;":"\u00bb",raquo:"\u00bb","rarrap;":"\u2975","rarrb;":"\u21e5","rarrbfs;":"\u2920","rarrc;":"\u2933","rarr;":"\u2192","Rarr;":"\u21a0","rArr;":"\u21d2","rarrfs;":"\u291e","rarrhk;":"\u21aa","rarrlp;":"\u21ac","rarrpl;":"\u2945","rarrsim;":"\u2974","Rarrtl;":"\u2916","rarrtl;":"\u21a3","rarrw;":"\u219d","ratail;":"\u291a","rAtail;":"\u291c","ratio;":"\u2236","rationals;":"\u211a","rbarr;":"\u290d","rBarr;":"\u290f","RBarr;":"\u2910","rbbrk;":"\u2773","rbrace;":"}","rbrack;":"]","rbrke;":"\u298c","rbrksld;":"\u298e","rbrkslu;":"\u2990","Rcaron;":"\u0158","rcaron;":"\u0159","Rcedil;":"\u0156","rcedil;":"\u0157","rceil;":"\u2309","rcub;":"}","Rcy;":"\u0420","rcy;":"\u0440","rdca;":"\u2937","rdldhar;":"\u2969","rdquo;":"\u201d","rdquor;":"\u201d","rdsh;":"\u21b3","real;":"\u211c","realine;":"\u211b","realpart;":"\u211c","reals;":"\u211d","Re;":"\u211c","rect;":"\u25ad","reg;":"\u00ae",reg:"\u00ae","REG;":"\u00ae",REG:"\u00ae","ReverseElement;":"\u220b","ReverseEquilibrium;":"\u21cb","ReverseUpEquilibrium;":"\u296f","rfisht;":"\u297d","rfloor;":"\u230b","rfr;":"\ud835\udd2f","Rfr;":"\u211c","rHar;":"\u2964","rhard;":"\u21c1","rharu;":"\u21c0","rharul;":"\u296c","Rho;":"\u03a1","rho;":"\u03c1","rhov;":"\u03f1","RightAngleBracket;":"\u27e9","RightArrowBar;":"\u21e5","rightarrow;":"\u2192","RightArrow;":"\u2192","Rightarrow;":"\u21d2","RightArrowLeftArrow;":"\u21c4","rightarrowtail;":"\u21a3","RightCeiling;":"\u2309","RightDoubleBracket;":"\u27e7","RightDownTeeVector;":"\u295d","RightDownVectorBar;":"\u2955","RightDownVector;":"\u21c2","RightFloor;":"\u230b","rightharpoondown;":"\u21c1","rightharpoonup;":"\u21c0","rightleftarrows;":"\u21c4","rightleftharpoons;":"\u21cc","rightrightarrows;":"\u21c9","rightsquigarrow;":"\u219d","RightTeeArrow;":"\u21a6","RightTee;":"\u22a2","RightTeeVector;":"\u295b","rightthreetimes;":"\u22cc","RightTriangleBar;":"\u29d0","RightTriangle;":"\u22b3","RightTriangleEqual;":"\u22b5","RightUpDownVector;":"\u294f","RightUpTeeVector;":"\u295c","RightUpVectorBar;":"\u2954","RightUpVector;":"\u21be","RightVectorBar;":"\u2953","RightVector;":"\u21c0","ring;":"\u02da","risingdotseq;":"\u2253","rlarr;":"\u21c4","rlhar;":"\u21cc","rlm;":"\u200f","rmoustache;":"\u23b1","rmoust;":"\u23b1","rnmid;":"\u2aee","roang;":"\u27ed","roarr;":"\u21fe","robrk;":"\u27e7","ropar;":"\u2986","ropf;":"\ud835\udd63","Ropf;":"\u211d","roplus;":"\u2a2e","rotimes;":"\u2a35","RoundImplies;":"\u2970","rpar;":")","rpargt;":"\u2994","rppolint;":"\u2a12","rrarr;":"\u21c9","Rrightarrow;":"\u21db","rsaquo;":"\u203a","rscr;":"\ud835\udcc7","Rscr;":"\u211b","rsh;":"\u21b1","Rsh;":"\u21b1","rsqb;":"]","rsquo;":"\u2019","rsquor;":"\u2019","rthree;":"\u22cc","rtimes;":"\u22ca","rtri;":"\u25b9","rtrie;":"\u22b5","rtrif;":"\u25b8","rtriltri;":"\u29ce","RuleDelayed;":"\u29f4","ruluhar;":"\u2968","rx;":"\u211e","Sacute;":"\u015a","sacute;":"\u015b","sbquo;":"\u201a","scap;":"\u2ab8","Scaron;":"\u0160","scaron;":"\u0161","Sc;":"\u2abc","sc;":"\u227b","sccue;":"\u227d","sce;":"\u2ab0","scE;":"\u2ab4","Scedil;":"\u015e","scedil;":"\u015f","Scirc;":"\u015c","scirc;":"\u015d","scnap;":"\u2aba","scnE;":"\u2ab6","scnsim;":"\u22e9","scpolint;":"\u2a13","scsim;":"\u227f","Scy;":"\u0421","scy;":"\u0441","sdotb;":"\u22a1","sdot;":"\u22c5","sdote;":"\u2a66","searhk;":"\u2925","searr;":"\u2198","seArr;":"\u21d8","searrow;":"\u2198","sect;":"\u00a7",sect:"\u00a7","semi;":";","seswar;":"\u2929","setminus;":"\u2216","setmn;":"\u2216","sext;":"\u2736","Sfr;":"\ud835\udd16","sfr;":"\ud835\udd30","sfrown;":"\u2322","sharp;":"\u266f","SHCHcy;":"\u0429","shchcy;":"\u0449","SHcy;":"\u0428","shcy;":"\u0448","ShortDownArrow;":"\u2193","ShortLeftArrow;":"\u2190","shortmid;":"\u2223","shortparallel;":"\u2225","ShortRightArrow;":"\u2192","ShortUpArrow;":"\u2191","shy;":"\u00ad",shy:"\u00ad","Sigma;":"\u03a3","sigma;":"\u03c3","sigmaf;":"\u03c2","sigmav;":"\u03c2","sim;":"\u223c","simdot;":"\u2a6a","sime;":"\u2243","simeq;":"\u2243","simg;":"\u2a9e","simgE;":"\u2aa0","siml;":"\u2a9d","simlE;":"\u2a9f","simne;":"\u2246","simplus;":"\u2a24","simrarr;":"\u2972","slarr;":"\u2190","SmallCircle;":"\u2218","smallsetminus;":"\u2216","smashp;":"\u2a33","smeparsl;":"\u29e4","smid;":"\u2223","smile;":"\u2323","smt;":"\u2aaa","smte;":"\u2aac","smtes;":"\u2aac\ufe00","SOFTcy;":"\u042c","softcy;":"\u044c","solbar;":"\u233f","solb;":"\u29c4","sol;":"/","Sopf;":"\ud835\udd4a","sopf;":"\ud835\udd64","spades;":"\u2660","spadesuit;":"\u2660","spar;":"\u2225","sqcap;":"\u2293","sqcaps;":"\u2293\ufe00","sqcup;":"\u2294","sqcups;":"\u2294\ufe00","Sqrt;":"\u221a","sqsub;":"\u228f","sqsube;":"\u2291","sqsubset;":"\u228f","sqsubseteq;":"\u2291","sqsup;":"\u2290","sqsupe;":"\u2292","sqsupset;":"\u2290","sqsupseteq;":"\u2292","square;":"\u25a1","Square;":"\u25a1","SquareIntersection;":"\u2293","SquareSubset;":"\u228f","SquareSubsetEqual;":"\u2291","SquareSuperset;":"\u2290","SquareSupersetEqual;":"\u2292","SquareUnion;":"\u2294","squarf;":"\u25aa","squ;":"\u25a1","squf;":"\u25aa","srarr;":"\u2192","Sscr;":"\ud835\udcae","sscr;":"\ud835\udcc8","ssetmn;":"\u2216","ssmile;":"\u2323","sstarf;":"\u22c6","Star;":"\u22c6","star;":"\u2606","starf;":"\u2605","straightepsilon;":"\u03f5","straightphi;":"\u03d5","strns;":"\u00af","sub;":"\u2282","Sub;":"\u22d0","subdot;":"\u2abd","subE;":"\u2ac5","sube;":"\u2286","subedot;":"\u2ac3","submult;":"\u2ac1","subnE;":"\u2acb","subne;":"\u228a","subplus;":"\u2abf","subrarr;":"\u2979","subset;":"\u2282","Subset;":"\u22d0","subseteq;":"\u2286","subseteqq;":"\u2ac5","SubsetEqual;":"\u2286","subsetneq;":"\u228a","subsetneqq;":"\u2acb","subsim;":"\u2ac7","subsub;":"\u2ad5","subsup;":"\u2ad3","succapprox;":"\u2ab8","succ;":"\u227b","succcurlyeq;":"\u227d","Succeeds;":"\u227b","SucceedsEqual;":"\u2ab0","SucceedsSlantEqual;":"\u227d","SucceedsTilde;":"\u227f","succeq;":"\u2ab0","succnapprox;":"\u2aba","succneqq;":"\u2ab6","succnsim;":"\u22e9","succsim;":"\u227f","SuchThat;":"\u220b","sum;":"\u2211","Sum;":"\u2211","sung;":"\u266a","sup1;":"\u00b9",sup1:"\u00b9","sup2;":"\u00b2",sup2:"\u00b2","sup3;":"\u00b3",sup3:"\u00b3","sup;":"\u2283","Sup;":"\u22d1","supdot;":"\u2abe","supdsub;":"\u2ad8","supE;":"\u2ac6","supe;":"\u2287","supedot;":"\u2ac4","Superset;":"\u2283","SupersetEqual;":"\u2287","suphsol;":"\u27c9","suphsub;":"\u2ad7","suplarr;":"\u297b","supmult;":"\u2ac2","supnE;":"\u2acc","supne;":"\u228b","supplus;":"\u2ac0","supset;":"\u2283","Supset;":"\u22d1","supseteq;":"\u2287","supseteqq;":"\u2ac6","supsetneq;":"\u228b","supsetneqq;":"\u2acc","supsim;":"\u2ac8","supsub;":"\u2ad4","supsup;":"\u2ad6","swarhk;":"\u2926","swarr;":"\u2199","swArr;":"\u21d9","swarrow;":"\u2199","swnwar;":"\u292a","szlig;":"\u00df",szlig:"\u00df","Tab;":" ","target;":"\u2316","Tau;":"\u03a4","tau;":"\u03c4","tbrk;":"\u23b4","Tcaron;":"\u0164","tcaron;":"\u0165","Tcedil;":"\u0162","tcedil;":"\u0163","Tcy;":"\u0422","tcy;":"\u0442","tdot;":"\u20db","telrec;":"\u2315","Tfr;":"\ud835\udd17","tfr;":"\ud835\udd31","there4;":"\u2234","therefore;":"\u2234","Therefore;":"\u2234","Theta;":"\u0398","theta;":"\u03b8","thetasym;":"\u03d1","thetav;":"\u03d1","thickapprox;":"\u2248","thicksim;":"\u223c","ThickSpace;":"\u205f\u200a","ThinSpace;":"\u2009","thinsp;":"\u2009","thkap;":"\u2248","thksim;":"\u223c","THORN;":"\u00de",THORN:"\u00de","thorn;":"\u00fe",thorn:"\u00fe","tilde;":"\u02dc","Tilde;":"\u223c","TildeEqual;":"\u2243","TildeFullEqual;":"\u2245","TildeTilde;":"\u2248","timesbar;":"\u2a31","timesb;":"\u22a0","times;":"\u00d7",times:"\u00d7","timesd;":"\u2a30","tint;":"\u222d","toea;":"\u2928","topbot;":"\u2336","topcir;":"\u2af1","top;":"\u22a4","Topf;":"\ud835\udd4b","topf;":"\ud835\udd65","topfork;":"\u2ada","tosa;":"\u2929","tprime;":"\u2034","trade;":"\u2122","TRADE;":"\u2122","triangle;":"\u25b5","triangledown;":"\u25bf","triangleleft;":"\u25c3","trianglelefteq;":"\u22b4","triangleq;":"\u225c","triangleright;":"\u25b9","trianglerighteq;":"\u22b5","tridot;":"\u25ec","trie;":"\u225c","triminus;":"\u2a3a","TripleDot;":"\u20db","triplus;":"\u2a39","trisb;":"\u29cd","tritime;":"\u2a3b","trpezium;":"\u23e2","Tscr;":"\ud835\udcaf","tscr;":"\ud835\udcc9","TScy;":"\u0426","tscy;":"\u0446","TSHcy;":"\u040b","tshcy;":"\u045b","Tstrok;":"\u0166","tstrok;":"\u0167","twixt;":"\u226c","twoheadleftarrow;":"\u219e","twoheadrightarrow;":"\u21a0","Uacute;":"\u00da",Uacute:"\u00da","uacute;":"\u00fa",uacute:"\u00fa","uarr;":"\u2191","Uarr;":"\u219f","uArr;":"\u21d1","Uarrocir;":"\u2949","Ubrcy;":"\u040e","ubrcy;":"\u045e","Ubreve;":"\u016c","ubreve;":"\u016d","Ucirc;":"\u00db",Ucirc:"\u00db","ucirc;":"\u00fb",ucirc:"\u00fb","Ucy;":"\u0423","ucy;":"\u0443","udarr;":"\u21c5","Udblac;":"\u0170","udblac;":"\u0171","udhar;":"\u296e","ufisht;":"\u297e","Ufr;":"\ud835\udd18","ufr;":"\ud835\udd32","Ugrave;":"\u00d9",Ugrave:"\u00d9","ugrave;":"\u00f9",ugrave:"\u00f9","uHar;":"\u2963","uharl;":"\u21bf","uharr;":"\u21be","uhblk;":"\u2580","ulcorn;":"\u231c","ulcorner;":"\u231c","ulcrop;":"\u230f","ultri;":"\u25f8","Umacr;":"\u016a","umacr;":"\u016b","uml;":"\u00a8",uml:"\u00a8","UnderBar;":"_","UnderBrace;":"\u23df","UnderBracket;":"\u23b5","UnderParenthesis;":"\u23dd","Union;":"\u22c3","UnionPlus;":"\u228e","Uogon;":"\u0172","uogon;":"\u0173","Uopf;":"\ud835\udd4c","uopf;":"\ud835\udd66","UpArrowBar;":"\u2912","uparrow;":"\u2191","UpArrow;":"\u2191","Uparrow;":"\u21d1","UpArrowDownArrow;":"\u21c5","updownarrow;":"\u2195","UpDownArrow;":"\u2195","Updownarrow;":"\u21d5","UpEquilibrium;":"\u296e","upharpoonleft;":"\u21bf","upharpoonright;":"\u21be","uplus;":"\u228e","UpperLeftArrow;":"\u2196","UpperRightArrow;":"\u2197","upsi;":"\u03c5","Upsi;":"\u03d2","upsih;":"\u03d2","Upsilon;":"\u03a5","upsilon;":"\u03c5","UpTeeArrow;":"\u21a5","UpTee;":"\u22a5","upuparrows;":"\u21c8","urcorn;":"\u231d","urcorner;":"\u231d","urcrop;":"\u230e","Uring;":"\u016e","uring;":"\u016f","urtri;":"\u25f9","Uscr;":"\ud835\udcb0","uscr;":"\ud835\udcca","utdot;":"\u22f0","Utilde;":"\u0168","utilde;":"\u0169","utri;":"\u25b5","utrif;":"\u25b4","uuarr;":"\u21c8","Uuml;":"\u00dc",Uuml:"\u00dc","uuml;":"\u00fc",uuml:"\u00fc","uwangle;":"\u29a7","vangrt;":"\u299c","varepsilon;":"\u03f5","varkappa;":"\u03f0","varnothing;":"\u2205","varphi;":"\u03d5","varpi;":"\u03d6","varpropto;":"\u221d","varr;":"\u2195","vArr;":"\u21d5","varrho;":"\u03f1","varsigma;":"\u03c2","varsubsetneq;":"\u228a\ufe00","varsubsetneqq;":"\u2acb\ufe00","varsupsetneq;":"\u228b\ufe00","varsupsetneqq;":"\u2acc\ufe00","vartheta;":"\u03d1","vartriangleleft;":"\u22b2","vartriangleright;":"\u22b3","vBar;":"\u2ae8","Vbar;":"\u2aeb","vBarv;":"\u2ae9","Vcy;":"\u0412","vcy;":"\u0432","vdash;":"\u22a2","vDash;":"\u22a8","Vdash;":"\u22a9","VDash;":"\u22ab","Vdashl;":"\u2ae6","veebar;":"\u22bb","vee;":"\u2228","Vee;":"\u22c1","veeeq;":"\u225a","vellip;":"\u22ee","verbar;":"|","Verbar;":"\u2016","vert;":"|","Vert;":"\u2016","VerticalBar;":"\u2223","VerticalLine;":"|","VerticalSeparator;":"\u2758","VerticalTilde;":"\u2240","VeryThinSpace;":"\u200a","Vfr;":"\ud835\udd19","vfr;":"\ud835\udd33","vltri;":"\u22b2","vnsub;":"\u2282\u20d2","vnsup;":"\u2283\u20d2","Vopf;":"\ud835\udd4d","vopf;":"\ud835\udd67","vprop;":"\u221d","vrtri;":"\u22b3","Vscr;":"\ud835\udcb1","vscr;":"\ud835\udccb","vsubnE;":"\u2acb\ufe00","vsubne;":"\u228a\ufe00","vsupnE;":"\u2acc\ufe00","vsupne;":"\u228b\ufe00","Vvdash;":"\u22aa","vzigzag;":"\u299a","Wcirc;":"\u0174","wcirc;":"\u0175","wedbar;":"\u2a5f","wedge;":"\u2227","Wedge;":"\u22c0","wedgeq;":"\u2259","weierp;":"\u2118","Wfr;":"\ud835\udd1a","wfr;":"\ud835\udd34","Wopf;":"\ud835\udd4e","wopf;":"\ud835\udd68","wp;":"\u2118","wr;":"\u2240","wreath;":"\u2240","Wscr;":"\ud835\udcb2","wscr;":"\ud835\udccc","xcap;":"\u22c2","xcirc;":"\u25ef","xcup;":"\u22c3","xdtri;":"\u25bd","Xfr;":"\ud835\udd1b","xfr;":"\ud835\udd35","xharr;":"\u27f7","xhArr;":"\u27fa","Xi;":"\u039e","xi;":"\u03be","xlarr;":"\u27f5","xlArr;":"\u27f8","xmap;":"\u27fc","xnis;":"\u22fb","xodot;":"\u2a00","Xopf;":"\ud835\udd4f","xopf;":"\ud835\udd69","xoplus;":"\u2a01","xotime;":"\u2a02","xrarr;":"\u27f6","xrArr;":"\u27f9","Xscr;":"\ud835\udcb3","xscr;":"\ud835\udccd","xsqcup;":"\u2a06","xuplus;":"\u2a04","xutri;":"\u25b3","xvee;":"\u22c1","xwedge;":"\u22c0","Yacute;":"\u00dd",Yacute:"\u00dd","yacute;":"\u00fd",yacute:"\u00fd","YAcy;":"\u042f","yacy;":"\u044f","Ycirc;":"\u0176","ycirc;":"\u0177","Ycy;":"\u042b","ycy;":"\u044b","yen;":"\u00a5",yen:"\u00a5","Yfr;":"\ud835\udd1c","yfr;":"\ud835\udd36","YIcy;":"\u0407","yicy;":"\u0457","Yopf;":"\ud835\udd50","yopf;":"\ud835\udd6a","Yscr;":"\ud835\udcb4","yscr;":"\ud835\udcce","YUcy;":"\u042e","yucy;":"\u044e","yuml;":"\u00ff",yuml:"\u00ff","Yuml;":"\u0178","Zacute;":"\u0179","zacute;":"\u017a","Zcaron;":"\u017d","zcaron;":"\u017e","Zcy;":"\u0417","zcy;":"\u0437","Zdot;":"\u017b","zdot;":"\u017c","zeetrf;":"\u2128","ZeroWidthSpace;":"\u200b","Zeta;":"\u0396","zeta;":"\u03b6","zfr;":"\ud835\udd37","Zfr;":"\u2128","ZHcy;":"\u0416","zhcy;":"\u0436","zigrarr;":"\u21dd","zopf;":"\ud835\udd6b","Zopf;":"\u2124","Zscr;":"\ud835\udcb5","zscr;":"\ud835\udccf","zwj;":"\u200d","zwnj;":"\u200c"}},{}],13:[function(e,t,n){function u(e,t){return r.isUndefined(t)?""+t:r.isNumber(t)&&(isNaN(t)||!isFinite(t))?t.toString():r.isFunction(t)||r.isRegExp(t)?t.toString():t}function a(e,t){return r.isString(e)?e.length<t?e:e.slice(0,t):e}function f(e){return a(JSON.stringify(e.actual,u),128)+" "+e.operator+" "+a(JSON.stringify(e.expected,u),128)}function l(e,t,n,r,i){throw new o.AssertionError({message:n,actual:e,expected:t,operator:r,stackStartFunction:i})}function c(e,t){e||l(e,!0,t,"==",o.ok)}function h(e,t){if(e===t)return!0;if(r.isBuffer(e)&&r.isBuffer(t)){if(e.length!=t.length)return!1;for(var n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}return r.isDate(e)&&r.isDate(t)?e.getTime()===t.getTime():r.isRegExp(e)&&r.isRegExp(t)?e.source===t.source&&e.global===t.global&&e.multiline===t.multiline&&e.lastIndex===t.lastIndex&&e.ignoreCase===t.ignoreCase:!r.isObject(e)&&!r.isObject(t)?e==t:d(e,t)}function p(e){return Object.prototype.toString.call(e)=="[object Arguments]"}function d(e,t){if(r.isNullOrUndefined(e)||r.isNullOrUndefined(t))return!1;if(e.prototype!==t.prototype)return!1;if(p(e))return p(t)?(e=i.call(e),t=i.call(t),h(e,t)):!1;try{var n=g(e),s=g(t),o,u}catch(a){return!1}if(n.length!=s.length)return!1;n.sort(),s.sort();for(u=n.length-1;u>=0;u--)if(n[u]!=s[u])return!1;for(u=n.length-1;u>=0;u--){o=n[u];if(!h(e[o],t[o]))return!1}return!0}function v(e,t){return!e||!t?!1:Object.prototype.toString.call(t)=="[object RegExp]"?t.test(e):e instanceof t?!0:t.call({},e)===!0?!0:!1}function m(e,t,n,i){var s;r.isString(n)&&(i=n,n=null);try{t()}catch(o){s=o}i=(n&&n.name?" ("+n.name+").":".")+(i?" "+i:"."),e&&!s&&l(s,n,"Missing expected exception"+i),!e&&v(s,n)&&l(s,n,"Got unwanted exception"+i);if(e&&s&&n&&!v(s,n)||!e&&s)throw s}var r=e("util/"),i=Array.prototype.slice,s=Object.prototype.hasOwnProperty,o=t.exports=c;o.AssertionError=function(t){this.name="AssertionError",this.actual=t.actual,this.expected=t.expected,this.operator=t.operator,t.message?(this.message=t.message,this.generatedMessage=!1):(this.message=f(this),this.generatedMessage=!0);var n=t.stackStartFunction||l;if(Error.captureStackTrace)Error.captureStackTrace(this,n);else{var r=new Error;if(r.stack){var i=r.stack,s=n.name,o=i.indexOf("\n"+s);if(o>=0){var u=i.indexOf("\n",o+1);i=i.substring(u+1)}this.stack=i}}},r.inherits(o.AssertionError,Error),o.fail=l,o.ok=c,o.equal=function(t,n,r){t!=n&&l(t,n,r,"==",o.equal)},o.notEqual=function(t,n,r){t==n&&l(t,n,r,"!=",o.notEqual)},o.deepEqual=function(t,n,r){h(t,n)||l(t,n,r,"deepEqual",o.deepEqual)},o.notDeepEqual=function(t,n,r){h(t,n)&&l(t,n,r,"notDeepEqual",o.notDeepEqual)},o.strictEqual=function(t,n,r){t!==n&&l(t,n,r,"===",o.strictEqual)},o.notStrictEqual=function(t,n,r){t===n&&l(t,n,r,"!==",o.notStrictEqual)},o.throws=function(e,t,n){m.apply(this,[!0].concat(i.call(arguments)))},o.doesNotThrow=function(e,t){m.apply(this,[!1].concat(i.call(arguments)))},o.ifError=function(e){if(e)throw e};var g=Object.keys||function(e){var t=[];for(var n in e)s.call(e,n)&&t.push(n);return t}},{"util/":15}],14:[function(e,t,n){t.exports=function(t){return t&&typeof t=="object"&&typeof t.copy=="function"&&typeof t.fill=="function"&&typeof t.readUInt8=="function"}},{}],15:[function(e,t,n){(function(t,r){function u(e,t){var r={seen:[],stylize:f};return arguments.length>=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),y(t)?r.showHidden=t:t&&n._extend(r,t),T(r.showHidden)&&(r.showHidden=!1),T(r.depth)&&(r.depth=2),T(r.colors)&&(r.colors=!1),T(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=a),c(r,e,r.depth)}function a(e,t){var n=u.styles[t];return n?"["+u.colors[n][0]+"m"+e+"["+u.colors[n][1]+"m":e}function f(e,t){return e}function l(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}function c(e,t,r){if(e.customInspect&&t&&A(t.inspect)&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var i=t.inspect(r,e);return S(i)||(i=c(e,i,r)),i}var s=h(e,t);if(s)return s;var o=Object.keys(t),u=l(o);e.showHidden&&(o=Object.getOwnPropertyNames(t));if(L(t)&&(o.indexOf("message")>=0||o.indexOf("description")>=0))return p(t);if(o.length===0){if(A(t)){var a=t.name?": "+t.name:"";return e.stylize("[Function"+a+"]","special")}if(N(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(k(t))return e.stylize(Date.prototype.toString.call(t),"date");if(L(t))return p(t)}var f="",y=!1,b=["{","}"];g(t)&&(y=!0,b=["[","]"]);if(A(t)){var w=t.name?": "+t.name:"";f=" [Function"+w+"]"}N(t)&&(f=" "+RegExp.prototype.toString.call(t)),k(t)&&(f=" "+Date.prototype.toUTCString.call(t)),L(t)&&(f=" "+p(t));if(o.length!==0||!!y&&t.length!=0){if(r<0)return N(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var E;return y?E=d(e,t,r,u,o):E=o.map(function(n){return v(e,t,r,u,n,y)}),e.seen.pop(),m(E,f,b)}return b[0]+f+b[1]}function h(e,t){if(T(t))return e.stylize("undefined","undefined");if(S(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(E(t))return e.stylize(""+t,"number");if(y(t))return e.stylize(""+t,"boolean");if(b(t))return e.stylize("null","null")}function p(e){return"["+Error.prototype.toString.call(e)+"]"}function d(e,t,n,r,i){var s=[];for(var o=0,u=t.length;o<u;++o)H(t,String(o))?s.push(v(e,t,n,r,String(o),!0)):s.push("");return i.forEach(function(i){i.match(/^\d+$/)||s.push(v(e,t,n,r,i,!0))}),s}function v(e,t,n,r,i,s){var o,u,a;a=Object.getOwnPropertyDescriptor(t,i)||{value:t[i]},a.get?a.set?u=e.stylize("[Getter/Setter]","special"):u=e.stylize("[Getter]","special"):a.set&&(u=e.stylize("[Setter]","special")),H(r,i)||(o="["+i+"]"),u||(e.seen.indexOf(a.value)<0?(b(n)?u=c(e,a.value,null):u=c(e,a.value,n-1),u.indexOf("\n")>-1&&(s?u=u.split("\n").map(function(e){return" "+e}).join("\n").substr(2):u="\n"+u.split("\n").map(function(e){return" "+e}).join("\n"))):u=e.stylize("[Circular]","special"));if(T(o)){if(s&&i.match(/^\d+$/))return u;o=JSON.stringify(""+i),o.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(o=o.substr(1,o.length-2),o=e.stylize(o,"name")):(o=o.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),o=e.stylize(o,"string"))}return o+": "+u}function m(e,t,n){var r=0,i=e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0);return i>60?n[0]+(t===""?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function g(e){return Array.isArray(e)}function y(e){return typeof e=="boolean"}function b(e){return e===null}function w(e){return e==null}function E(e){return typeof e=="number"}function S(e){return typeof e=="string"}function x(e){return typeof e=="symbol"}function T(e){return e===void 0}function N(e){return C(e)&&M(e)==="[object RegExp]"}function C(e){return typeof e=="object"&&e!==null}function k(e){return C(e)&&M(e)==="[object Date]"}function L(e){return C(e)&&(M(e)==="[object Error]"||e instanceof Error)}function A(e){return typeof e=="function"}function O(e){return e===null||typeof e=="boolean"||typeof e=="number"||typeof e=="string"||typeof e=="symbol"||typeof e=="undefined"}function M(e){return Object.prototype.toString.call(e)}function _(e){return e<10?"0"+e.toString(10):e.toString(10)}function P(){var e=new Date,t=[_(e.getHours()),_(e.getMinutes()),_(e.getSeconds())].join(":");return[e.getDate(),D[e.getMonth()],t].join(" ")}function H(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var i=/%[sdj%]/g;n.format=function(e){if(!S(e)){var t=[];for(var n=0;n<arguments.length;n++)t.push(u(arguments[n]));return t.join(" ")}var n=1,r=arguments,s=r.length,o=String(e).replace(i,function(e){if(e==="%%")return"%";if(n>=s)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(t){return"[Circular]"};default:return e}});for(var a=r[n];n<s;a=r[++n])b(a)||!C(a)?o+=" "+a:o+=" "+u(a);return o},n.deprecate=function(e,i){function o(){if(!s){if(t.throwDeprecation)throw new Error(i);t.traceDeprecation?console.trace(i):console.error(i),s=!0}return e.apply(this,arguments)}if(T(r.process))return function(){return n.deprecate(e,i).apply(this,arguments)};if(t.noDeprecation===!0)return e;var s=!1;return o};var s={},o;n.debuglog=function(e){T(o)&&(o=t.env.NODE_DEBUG||""),e=e.toUpperCase();if(!s[e])if((new RegExp("\\b"+e+"\\b","i")).test(o)){var r=t.pid;s[e]=function(){var t=n.format.apply(n,arguments);console.error("%s %d: %s",e,r,t)}}else s[e]=function(){};return s[e]},n.inspect=u,u.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},u.styles={special:"cyan",number:"yellow","boolean":"yellow","undefined":"grey","null":"bold",string:"green",date:"magenta",regexp:"red"},n.isArray=g,n.isBoolean=y,n.isNull=b,n.isNullOrUndefined=w,n.isNumber=E,n.isString=S,n.isSymbol=x,n.isUndefined=T,n.isRegExp=N,n.isObject=C,n.isDate=k,n.isError=L,n.isFunction=A,n.isPrimitive=O,n.isBuffer=e("./support/isBuffer");var D=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];n.log=function(){console.log("%s - %s",P(),n.format.apply(n,arguments))},n.inherits=e("inherits"),n._extend=function(e,t){if(!t||!C(t))return e;var n=Object.keys(t),r=n.length;while(r--)e[n[r]]=t[n[r]];return e}}).call(this,e("/usr/local/lib/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"),typeof self!="undefined"?self:typeof window!="undefined"?window:{})},{"./support/isBuffer":14,"/usr/local/lib/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":18,inherits:17}],16:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||undefined}function i(e){return typeof e=="function"}function s(e){return typeof e=="number"}function o(e){return typeof e=="object"&&e!==null}function u(e){return e===void 0}t.exports=r,r.EventEmitter=r,r.prototype._events=undefined,r.prototype._maxListeners=undefined,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!s(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,s,a,f;this._events||(this._events={});if(e==="error")if(!this._events.error||o(this._events.error)&&!this._events.error.length)throw t=arguments[1],t instanceof Error?t:TypeError('Uncaught, unspecified "error" event.');n=this._events[e];if(u(n))return!1;if(i(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:r=arguments.length,s=new Array(r-1);for(a=1;a<r;a++)s[a-1]=arguments[a];n.apply(this,s)}else if(o(n)){r=arguments.length,s=new Array(r-1);for(a=1;a<r;a++)s[a-1]=arguments[a];f=n.slice(),r=f.length;for(a=0;a<r;a++)f[a].apply(this,s)}return!0},r.prototype.addListener=function(e,t){var n;if(!i(t))throw TypeError("listener must be a function");this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,i(t.listener)?t.listener:t),this._events[e]?o(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t;if(o(this._events[e])&&!this._events[e].warned){var n;u(this._maxListeners)?n=r.defaultMaxListeners:n=this._maxListeners,n&&n>0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),console.trace())}return this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function r(){this.removeListener(e,r),n||(n=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var n=!1;return r.listener=t,this.on(e,r),this},r.prototype.removeListener=function(e,t){var n,r,s,u;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;n=this._events[e],s=n.length,r=-1;if(n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(o(n)){for(u=s;u-->0;)if(n[u]===t||n[u].listener&&n[u].listener===t){r=u;break}if(r<0)return this;n.length===1?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return arguments.length===0?this._events={}:this._events[e]&&delete this._events[e],this;if(arguments.length===0){for(t in this._events){if(t==="removeListener")continue;this.removeAllListeners(t)}return this.removeAllListeners("removeListener"),this._events={},this}n=this._events[e];if(i(n))this.removeListener(e,n);else while(n.length)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return!this._events||!this._events[e]?t=[]:i(this._events[e])?t=[this._events[e]]:t=this._events[e].slice(),t},r.listenerCount=function(e,t){var n;return!e._events||!e._events[t]?n=0:i(e._events[t])?n=1:n=e._events[t].length,n}},{}],17:[function(e,t,n){typeof Object.create=="function"?t.exports=function(t,n){t.super_=n,t.prototype=Object.create(n.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(t,n){t.super_=n;var r=function(){};r.prototype=n.prototype,t.prototype=new r,t.prototype.constructor=t}},{}],18:[function(e,t,n){function i(){}var r=t.exports={};r.nextTick=function(){var e=typeof window!="undefined"&&window.setImmediate,t=typeof window!="undefined"&&window.postMessage&&window.addEventListener;if(e)return function(e){return window.setImmediate(e)};if(t){var n=[];return window.addEventListener("message",function(e){var t=e.source;if((t===window||t===null)&&e.data==="process-tick"){e.stopPropagation();if(n.length>0){var r=n.shift();r()}}},!0),function(t){n.push(t),window.postMessage("process-tick","*")}}return function(t){setTimeout(t,0)}}(),r.title="browser",r.browser=!0,r.env={},r.argv=[],r.on=i,r.once=i,r.off=i,r.emit=i,r.binding=function(e){throw new Error("process.binding is not supported")},r.cwd=function(){return"/"},r.chdir=function(e){throw new Error("process.chdir is not supported")}},{}],19:[function(e,t,n){t.exports=e(14)},{}],20:[function(e,t,n){t.exports=e(15)},{"./support/isBuffer":19,"/usr/local/lib/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":18,inherits:17}]},{},[9])(9)}),ace.define("ace/mode/html_worker",[],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("../worker/mirror").Mirror,o=e("./html/saxparser").SAXParser,u={"expected-doctype-but-got-start-tag":"info","expected-doctype-but-got-chars":"info","non-html-root":"info"},a=t.Worker=function(e){s.call(this,e),this.setTimeout(400),this.context=null};r.inherits(a,s),function(){this.setOptions=function(e){this.context=e.context},this.onUpdate=function(){var e=this.doc.getValue();if(!e)return;var t=new o,n=[],r=function(){};t.contentHandler={startDocument:r,endDocument:r,startElement:r,endElement:r,characters:r},t.errorHandler={error:function(e,t,r){n.push({row:t.line,column:t.column,text:e,type:u[r]||"error"})}},this.context?t.parseFragment(e,this.context):t.parse(e),this.sender.emit("error",n)}}.call(a.prototype)}),ace.define("ace/lib/es5-shim",[],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)=="[object Array]"});var m=Object("a"),g=m[0]!="a"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _=" \n\x0b\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";if(!String.prototype.trim||_.trim()){_="["+_+"]";var D=new RegExp("^"+_+_+"*"),P=new RegExp(_+_+"*$");String.prototype.trim=function(){return String(this).replace(D,"").replace(P,"")}}var F=function(e){if(e==null)throw new TypeError("can't convert "+e+" to object");return Object(e)}}) \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/worker-javascript.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/worker-javascript.js new file mode 100644 index 0000000..3e88229 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/worker-javascript.js @@ -0,0 +1 @@ +"no use strict";!function(e){function t(e,t){var n=e,r="";while(n){var i=t[n];if(typeof i=="string")return i+r;if(i)return i.location.replace(/\/*$/,"/")+(r||i.main||i.name);if(i===!1)return"";var s=n.lastIndexOf("/");if(s===-1)break;r=n.substr(s)+r,n=n.slice(0,s)}return e}if(typeof e.window!="undefined"&&e.document)return;if(e.require&&e.define)return;e.console||(e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console),e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){postMessage({type:"error",data:{message:e,data:i.data,file:t,line:n,col:r,stack:i.stack}})},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(r,i){i||(i=r,r=null);if(!i.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");i=e.normalizeModule(r,i);var s=e.require.modules[i];if(s)return s.initialized||(s.initialized=!0,s.exports=s.factory().exports),s.exports;if(!e.require.tlns)return console.log("unable to load "+i);var o=t(i,e.require.tlns);return o.slice(-3)!=".js"&&(o+=".js"),e.require.id=i,e.require.modules[i]={},importScripts(o),e.require(r,i)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id);if(typeof r!="function"){e.require.modules[t]={exports:r,initialized:!0};return}n.length||(n=["require","exports","module"]);var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.slice(0,r.length).map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},require.tlns={},e.initBaseUrls=function(t){for(var n in t)require.tlns[n]=t[n]},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var n=e.main=null,r=e.sender=null;e.onmessage=function(t){var i=t.data;if(i.event&&r)r._signal(i.event,i.data);else if(i.command)if(n[i.command])n[i.command].apply(n,i.args);else{if(!e[i.command])throw new Error("Unknown command:"+i.command);e[i.command].apply(e,i.args)}else if(i.init){e.initBaseUrls(i.tlns),require("ace/lib/es5-shim"),r=e.sender=e.initSender();var s=require(i.module)[i.classname];n=e.main=new s(r)}}}(this),ace.define("ace/lib/oop",[],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/range",[],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define("ace/apply_delta",[],function(e,t,n){"use strict";function r(e,t){throw console.log("Invalid Delta:",e),"Invalid Delta: "+t}function i(e,t){return t.row>=0&&t.row<e.length&&t.column>=0&&t.column<=e[t.row].length}function s(e,t){t.action!="insert"&&t.action!="remove"&&r(t,"delta.action must be 'insert' or 'remove'"),t.lines instanceof Array||r(t,"delta.lines must be an Array"),(!t.start||!t.end)&&r(t,"delta.start/end must be an present");var n=t.start;i(e,t.start)||r(t,"delta.start must be contained in document");var s=t.end;t.action=="remove"&&!i(e,s)&&r(t,"delta.end must contained in document for 'remove' actions");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,"delta.range must match delta lines")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||"";switch(t.action){case"insert":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case"remove":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),ace.define("ace/lib/event_emitter",[],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)});if(!t)return new Promise(function(e){t=e})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t)r&&this.setDefaultHandler(e,r.pop());else if(r){var i=r.indexOf(t);i!=-1&&r.splice(i,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?"unshift":"push"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define("ace/anchor",[],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){function e(e,t,n){var r=n?e.column<=t.column:e.column<t.column;return e.row<t.row||e.row==t.row&&r}function t(t,n,r){var i=t.action=="insert",s=(i?1:-1)*(t.end.row-t.start.row),o=(i?1:-1)*(t.end.column-t.start.column),u=t.start,a=i?u:t.end;return e(n,u,r)?{row:n.row,column:n.column}:e(a,n,!r)?{row:n.row+s,column:n.column+(n.row==a.row?o:0)}:{row:u.row,column:u.column}}r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){if(e.start.row==e.end.row&&e.start.row!=this.row)return;if(e.start.row>this.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",[],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./apply_delta").applyDelta,s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=e("./anchor").Anchor,a=function(e){this.$lines=[""],e.length===0?this.$lines=[""]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."),this.insertMergedLines(e,["",""])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:"insert",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e<this.getLength()?(t=t.concat([""]),n=0):(t=[""].concat(t),e--,n=this.$lines[e].length),this.insertMergedLines({row:e,column:n},t)},this.insertMergedLines=function(e,t){var n=this.clippedPos(e.row,e.column),r={row:n.row+t.length-1,column:(t.length==1?n.column:0)+t[t.length-1].length};return this.applyDelta({start:n,end:r,action:"insert",lines:t}),this.clonePos(r)},this.remove=function(e){var t=this.clippedPos(e.start.row,e.start.column),n=this.clippedPos(e.end.row,e.end.column);return this.applyDelta({start:t,end:n,action:"remove",lines:this.getLinesForRange({start:t,end:n})}),this.clonePos(t)},this.removeInLine=function(e,t,n){var r=this.clippedPos(e,t),i=this.clippedPos(e,n);return this.applyDelta({start:r,end:i,action:"remove",lines:this.getLinesForRange({start:r,end:i})},!0),this.clonePos(r)},this.removeFullLines=function(e,t){e=Math.min(Math.max(0,e),this.getLength()-1),t=Math.min(Math.max(0,t),this.getLength()-1);var n=t==this.getLength()-1&&e>0,r=t<this.getLength()-1,i=n?e-1:e,s=n?this.getLine(i).length:0,u=r?t+1:t,a=r?0:this.getLine(u).length,f=new o(i,s,u,a),l=this.$lines.slice(e,t+1);return this.applyDelta({start:f.start,end:f.end,action:"remove",lines:this.getLinesForRange(f)}),l},this.removeNewLine=function(e){e<this.getLength()-1&&e>=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++)this.applyDelta(e[t])},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action=="insert";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4?this.$splitAndapplyLargeDelta(e,2e4):(i(this.$lines,e,t),this._signal("change",e))},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length-t+1,i=e.start.row,s=e.start.column;for(var o=0,u=0;o<r;o=u){u+=t-1;var a=n.slice(o,u);a.push(""),this.applyDelta({start:this.pos(i+o,s),end:this.pos(i+u,s=0),action:e.action,lines:a},!0)}e.lines=n.slice(o),e.start.row=i+o,e.start.column=s,this.applyDelta(e,!0)},this.revertDelta=function(e){this.applyDelta({start:this.clonePos(e.start),end:this.clonePos(e.end),action:e.action=="insert"?"remove":"insert",lines:e.lines.slice()})},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:e+n[s-1].length+r}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(a.prototype),t.Document=a}),ace.define("ace/lib/lang",[],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function s(e){if(typeof e!="object"||!e)return e;var t;if(Array.isArray(e)){t=[];for(var n=0;n<e.length;n++)t[n]=s(e[n]);return t}if(Object.prototype.toString.call(e)!=="[object Object]")return e;t={};for(var n in e)t[n]=s(e[n]);return t},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return(""+e).replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define("ace/worker/mirror",[],function(e,t,n){"use strict";var r=e("../range").Range,i=e("../document").Document,s=e("../lib/lang"),o=t.Mirror=function(e){this.sender=e;var t=this.doc=new i(""),n=this.deferredUpdate=s.delayedCall(this.onUpdate.bind(this)),r=this;e.on("change",function(e){var i=e.data;if(i[0].start)t.applyDeltas(i);else for(var s=0;s<i.length;s+=2){if(Array.isArray(i[s+1]))var o={action:"insert",start:i[s],lines:i[s+1]};else var o={action:"remove",start:i[s],end:i[s+1]};t.applyDelta(o,!0)}if(r.$timeout)return n.schedule(r.$timeout);r.onUpdate()})};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(o.prototype)}),ace.define("ace/mode/javascript/jshint",[],function(e,t,n){n.exports=function r(t,n,i){function o(u,a){if(!n[u]){if(!t[u]){var f=typeof e=="function"&&e;if(!a&&f)return f(u,!0);if(s)return s(u,!0);var l=new Error("Cannot find module '"+u+"'");throw l.code="MODULE_NOT_FOUND",l}var c=n[u]={exports:{}};t[u][0].call(c.exports,function(e){var n=t[u][1][e];return o(n?n:e)},c,c.exports,r,t,n,i)}return n[u].exports}var s=typeof e=="function"&&e;for(var u=0;u<i.length;u++)o(i[u]);return o(i[0])}({"/node_modules/browserify/node_modules/events/events.js":[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||undefined}function i(e){return typeof e=="function"}function s(e){return typeof e=="number"}function o(e){return typeof e=="object"&&e!==null}function u(e){return e===void 0}t.exports=r,r.EventEmitter=r,r.prototype._events=undefined,r.prototype._maxListeners=undefined,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!s(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,s,a,f;this._events||(this._events={});if(e==="error")if(!this._events.error||o(this._events.error)&&!this._events.error.length)throw t=arguments[1],t instanceof Error?t:TypeError('Uncaught, unspecified "error" event.');n=this._events[e];if(u(n))return!1;if(i(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:r=arguments.length,s=new Array(r-1);for(a=1;a<r;a++)s[a-1]=arguments[a];n.apply(this,s)}else if(o(n)){r=arguments.length,s=new Array(r-1);for(a=1;a<r;a++)s[a-1]=arguments[a];f=n.slice(),r=f.length;for(a=0;a<r;a++)f[a].apply(this,s)}return!0},r.prototype.addListener=function(e,t){var n;if(!i(t))throw TypeError("listener must be a function");this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,i(t.listener)?t.listener:t),this._events[e]?o(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t;if(o(this._events[e])&&!this._events[e].warned){var n;u(this._maxListeners)?n=r.defaultMaxListeners:n=this._maxListeners,n&&n>0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),typeof console.trace=="function"&&console.trace())}return this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function r(){this.removeListener(e,r),n||(n=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var n=!1;return r.listener=t,this.on(e,r),this},r.prototype.removeListener=function(e,t){var n,r,s,u;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;n=this._events[e],s=n.length,r=-1;if(n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(o(n)){for(u=s;u-->0;)if(n[u]===t||n[u].listener&&n[u].listener===t){r=u;break}if(r<0)return this;n.length===1?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return arguments.length===0?this._events={}:this._events[e]&&delete this._events[e],this;if(arguments.length===0){for(t in this._events){if(t==="removeListener")continue;this.removeAllListeners(t)}return this.removeAllListeners("removeListener"),this._events={},this}n=this._events[e];if(i(n))this.removeListener(e,n);else while(n.length)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return!this._events||!this._events[e]?t=[]:i(this._events[e])?t=[this._events[e]]:t=this._events[e].slice(),t},r.listenerCount=function(e,t){var n;return!e._events||!e._events[t]?n=0:i(e._events[t])?n=1:n=e._events[t].length,n}},{}],"/node_modules/jshint/data/ascii-identifier-data.js":[function(e,t,n){var r=[];for(var i=0;i<128;i++)r[i]=i===36||i>=65&&i<=90||i===95||i>=97&&i<=122;var s=[];for(var i=0;i<128;i++)s[i]=r[i]||i>=48&&i<=57;t.exports={asciiIdentifierStartTable:r,asciiIdentifierPartTable:s}},{}],"/node_modules/jshint/lodash.js":[function(e,t,n){(function(e){(function(){function $(e,t,n){var r=e.length,i=n?r:-1;while(n?i--:++i<r)if(t(e[i],i,e))return i;return-1}function J(e,t,n){if(t!==t)return G(e,n);var r=n-1,i=e.length;while(++r<i)if(e[r]===t)return r;return-1}function K(e){return typeof e=="function"||!1}function Q(e){return typeof e=="string"?e:e==null?"":e+""}function G(e,t,n){var r=e.length,i=t+(n?0:-1);while(n?i--:++i<r){var s=e[i];if(s!==s)return i}return-1}function Y(e){return!!e&&typeof e=="object"}function Ct(){}function Lt(e,t){var n=-1,r=e.length;t||(t=Array(r));while(++n<r)t[n]=e[n];return t}function At(e,t){var n=-1,r=e.length;while(++n<r)if(t(e[n],n,e)===!1)break;return e}function Ot(e,t){var n=-1,r=e.length,i=-1,s=[];while(++n<r){var o=e[n];t(o,n,e)&&(s[++i]=o)}return s}function Mt(e,t){var n=-1,r=e.length,i=Array(r);while(++n<r)i[n]=t(e[n],n,e);return i}function _t(e){var t=-1,n=e.length,r=wt;while(++t<n){var i=e[t];i>r&&(r=i)}return r}function Dt(e,t){var n=-1,r=e.length;while(++n<r)if(t(e[n],n,e))return!0;return!1}function Pt(e,t,n){var i=rr(t);lt.apply(i,bn(t));var s=-1,o=i.length;while(++s<o){var u=i[s],a=e[u],f=n(a,t[u],u,e,t);if((f===f?f!==a:a===a)||a===r&&!(u in e))e[u]=f}return e}function Bt(e,t,n){n||(n={});var r=-1,i=t.length;while(++r<i){var s=t[r];n[s]=e[s]}return n}function jt(e,t,n){var i=typeof e;return i=="function"?t===r?e:on(e,t,n):e==null?lr:i=="object"?Jt(e):t===r?cr(e):Kt(e,t)}function Ft(e,t,n,i,s,u,a){var f;n&&(f=s?n(e,i,s):n(e));if(f!==r)return f;if(!Jn(e))return e;var l=Xn(e);if(l){f=wn(e);if(!t)return Lt(e,f)}else{var h=rt.call(e),p=h==c;if(!(h==d||h==o||p&&!s))return F[h]?Sn(e,h,t):s?e:{};f=En(p?{}:e);if(!t)return Ht(f,e)}u||(u=[]),a||(a=[]);var v=u.length;while(v--)if(u[v]==e)return a[v];return u.push(e),a.push(f),(l?At:zt)(e,function(r,i){f[i]=Ft(r,t,n,i,e,u,a)}),f}function qt(e,t){var n=[];return It(e,function(e,r,i){t(e,r,i)&&n.push(e)}),n}function Ut(e,t){return Rt(e,t,ir)}function zt(e,t){return Rt(e,t,rr)}function Wt(e,t,n){if(e==null)return;n!==r&&n in On(e)&&(t=[n]);var i=-1,s=t.length;while(e!=null&&++i<s)var o=e=e[t[i]];return o}function Xt(e,t,n,r,i,s){if(e===t)return e!==0||1/e==1/t;var o=typeof e,u=typeof t;return o!="function"&&o!="object"&&u!="function"&&u!="object"||e==null||t==null?e!==e&&t!==t:Vt(e,t,Xt,n,r,i,s)}function Vt(e,t,n,r,i,s,a){var f=Xn(e),l=Xn(t),c=u,h=u;f||(c=rt.call(e),c==o?c=d:c!=d&&(f=Zn(e))),l||(h=rt.call(t),h==o?h=d:h!=d&&(l=Zn(t)));var p=c==d,v=h==d,m=c==h;if(m&&!f&&!p)return dn(e,t,c);if(!i){var g=p&&nt.call(e,"__wrapped__"),y=v&&nt.call(t,"__wrapped__");if(g||y)return n(g?e.value():e,y?t.value():t,r,i,s,a)}if(!m)return!1;s||(s=[]),a||(a=[]);var b=s.length;while(b--)if(s[b]==e)return a[b]==t;s.push(e),a.push(t);var w=(f?pn:vn)(e,t,n,r,i,s,a);return s.pop(),a.pop(),w}function $t(e,t,n,i,s){var o=-1,u=t.length,a=!s;while(++o<u)if(a&&i[o]?n[o]!==e[t[o]]:!(t[o]in e))return!1;o=-1;while(++o<u){var f=t[o],l=e[f],c=n[o];if(a&&i[o])var h=l!==r||f in e;else h=s?s(l,c,f):r,h===r&&(h=Xt(c,l,s,!0));if(!h)return!1}return!0}function Jt(e){var t=rr(e),n=t.length;if(!n)return fr(!0);if(n==1){var i=t[0],s=e[i];if(kn(s))return function(e){return e==null?!1:e[i]===s&&(s!==r||i in On(e))}}var o=Array(n),u=Array(n);while(n--)s=e[t[n]],o[n]=s,u[n]=kn(s);return function(e){return e!=null&&$t(On(e),t,o,u)}}function Kt(e,t){var n=Xn(e),i=Nn(e)&&kn(t),s=e+"";return e=Mn(e),function(o){if(o==null)return!1;var u=s;o=On(o);if((n||!i)&&!(u in o)){o=e.length==1?o:Wt(o,en(e,0,-1));if(o==null)return!1;u=Pn(e),o=On(o)}return o[u]===t?t!==r||u in o:Xt(t,o[u],null,!0)}}function Qt(e,t,n,i,s){if(!Jn(e))return e;var o=Cn(t.length)&&(Xn(t)||Zn(t));if(!o){var u=rr(t);lt.apply(u,bn(t))}return At(u||t,function(a,f){u&&(f=a,a=t[f]);if(Y(a))i||(i=[]),s||(s=[]),Gt(e,t,f,Qt,n,i,s);else{var l=e[f],c=n?n(l,a,f,e,t):r,h=c===r;h&&(c=a),(o||c!==r)&&(h||(c===c?c!==l:l===l))&&(e[f]=c)}}),e}function Gt(e,t,n,i,s,o,u){var a=o.length,f=t[n];while(a--)if(o[a]==f){e[n]=u[a];return}var l=e[n],c=s?s(l,f,n,e,t):r,h=c===r;h&&(c=f,Cn(f.length)&&(Xn(f)||Zn(f))?c=Xn(l)?l:yn(l)?Lt(l):[]:Gn(f)||Wn(f)?c=Wn(l)?er(l):Gn(l)?l:{}:h=!1),o.push(f),u.push(c);if(h)e[n]=i(c,f,s,o,u);else if(c===c?c!==l:l===l)e[n]=c}function Yt(e){return function(t){return t==null?r:t[e]}}function Zt(e){var t=e+"";return e=Mn(e),function(n){return Wt(n,e,t)}}function en(e,t,n){var i=-1,s=e.length;t=t==null?0:+t||0,t<0&&(t=-t>s?0:s+t),n=n===r||n>s?s:+n||0,n<0&&(n+=s),s=t>n?0:n-t>>>0,t>>>=0;var o=Array(s);while(++i<s)o[i]=e[i+t];return o}function tn(e,t){var n;return It(e,function(e,r,i){return n=t(e,r,i),!n}),!!n}function nn(e,t){var n=-1,r=t.length,i=Array(r);while(++n<r)i[n]=e[t[n]];return i}function rn(e,t,n){var r=0,i=e?e.length:r;if(typeof t=="number"&&t===t&&i<=xt){while(r<i){var s=r+i>>>1,o=e[s];(n?o<=t:o<t)?r=s+1:i=s}return i}return sn(e,t,lr,n)}function sn(e,t,n,i){t=n(t);var s=0,o=e?e.length:0,u=t!==t,a=t===r;while(s<o){var f=ut((s+o)/2),l=n(e[f]),c=l===l;if(u)var h=c||i;else a?h=c&&(i||l!==r):h=i?l<=t:l<t;h?s=f+1:o=f}return bt(o,St)}function on(e,t,n){if(typeof e!="function")return lr;if(t===r)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 3:return function(n,r,i){return e.call(t,n,r,i)};case 4:return function(n,r,i,s){return e.call(t,n,r,i,s)};case 5:return function(n,r,i,s,o){return e.call(t,n,r,i,s,o)}}return function(){return e.apply(t,arguments)}}function un(e){return ot.call(e,0)}function an(e){return Un(function(t,n){var r=-1,i=t==null?0:n.length,s=i>2&&n[i-2],o=i>2&&n[2],u=i>1&&n[i-1];typeof s=="function"?(s=on(s,u,5),i-=2):(s=typeof u=="function"?u:null,i-=s?1:0),o&&Tn(n[0],n[1],o)&&(s=i<3?null:s,i=1);while(++r<i){var a=n[r];a&&e(t,a,s)}return t})}function fn(e,t){return function(n,r){var i=n?yn(n):0;if(!Cn(i))return e(n,r);var s=t?i:-1,o=On(n);while(t?s--:++s<i)if(r(o[s],s,o)===!1)break;return n}}function ln(e){return function(t,n,r){var i=On(t),s=r(t),o=s.length,u=e?o:-1;while(e?u--:++u<o){var a=s[u];if(n(i[a],a,i)===!1)break}return t}}function cn(e){return function(t,n,r){return!t||!t.length?-1:(n=mn(n,r,3),$(t,n,e))}}function hn(e,t){return function(n,i,s){return typeof i=="function"&&s===r&&Xn(n)?e(n,i):t(n,on(i,s,3))}}function pn(e,t,n,i,s,o,u){var a=-1,f=e.length,l=t.length,c=!0;if(f!=l&&!(s&&l>f))return!1;while(c&&++a<f){var h=e[a],p=t[a];c=r,i&&(c=s?i(p,h,a):i(h,p,a));if(c===r)if(s){var d=l;while(d--){p=t[d],c=h&&h===p||n(h,p,i,s,o,u);if(c)break}}else c=h&&h===p||n(h,p,i,s,o,u)}return!!c}function dn(e,t,n){switch(n){case a:case f:return+e==+t;case l:return e.name==t.name&&e.message==t.message;case p:return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case v:case g:return e==t+""}return!1}function vn(e,t,n,i,s,o,u){var a=rr(e),f=a.length,l=rr(t),c=l.length;if(f!=c&&!s)return!1;var h=s,p=-1;while(++p<f){var d=a[p],v=s?d in t:nt.call(t,d);if(v){var m=e[d],g=t[d];v=r,i&&(v=s?i(g,m,d):i(m,g,d)),v===r&&(v=m&&m===g||n(m,g,i,s,o,u))}if(!v)return!1;h||(h=d=="constructor")}if(!h){var y=e.constructor,b=t.constructor;if(y!=b&&"constructor"in e&&"constructor"in t&&!(typeof y=="function"&&y instanceof y&&typeof b=="function"&&b instanceof b))return!1}return!0}function mn(e,t,n){var r=Ct.callback||ar;return r=r===ar?jt:r,n?r(e,t,n):r}function gn(e,t,n){var r=Ct.indexOf||Dn;return r=r===Dn?J:r,e?r(e,t,n):r}function wn(e){var t=e.length,n=new e.constructor(t);return t&&typeof e[0]=="string"&&nt.call(e,"index")&&(n.index=e.index,n.input=e.input),n}function En(e){var t=e.constructor;return typeof t=="function"&&t instanceof t||(t=Object),new t}function Sn(e,t,n){var r=e.constructor;switch(t){case b:return un(e);case a:case f:return new r(+e);case w:case E:case S:case x:case T:case N:case C:case k:case L:var i=e.buffer;return new r(n?un(i):i,e.byteOffset,e.length);case p:case g:return new r(e);case v:var s=new r(e.source,H.exec(e));s.lastIndex=e.lastIndex}return s}function xn(e,t){return e=+e,t=t==null?Nt:t,e>-1&&e%1==0&&e<t}function Tn(e,t,n){if(!Jn(n))return!1;var r=typeof t;if(r=="number")var i=yn(n),s=Cn(i)&&xn(t,i);else s=r=="string"&&t in n;if(s){var o=n[t];return e===e?e===o:o!==o}return!1}function Nn(e,t){var n=typeof e;if(n=="string"&&O.test(e)||n=="number")return!0;if(Xn(e))return!1;var r=!A.test(e);return r||t!=null&&e in On(t)}function Cn(e){return typeof e=="number"&&e>-1&&e%1==0&&e<=Nt}function kn(e){return e===e&&(e===0?1/e>0:!Jn(e))}function Ln(e){var t,n=Ct.support;if(!Y(e)||rt.call(e)!=d||!nt.call(e,"constructor")&&(t=e.constructor,typeof t=="function"&&!(t instanceof t)))return!1;var i;return Ut(e,function(e,t){i=t}),i===r||nt.call(e,i)}function An(e){var t=ir(e),n=t.length,r=n&&e.length,i=Ct.support,s=r&&Cn(r)&&(Xn(e)||i.nonEnumArgs&&Wn(e)),o=-1,u=[];while(++o<n){var a=t[o];(s&&xn(a,r)||nt.call(e,a))&&u.push(a)}return u}function On(e){return Jn(e)?e:Object(e)}function Mn(e){if(Xn(e))return e;var t=[];return Q(e).replace(M,function(e,n,r,i){t.push(r?i.replace(P,"$1"):n||e)}),t}function Dn(e,t,n){var r=e?e.length:0;if(!r)return-1;if(typeof n=="number")n=n<0?yt(r+n,0):n;else if(n){var i=rn(e,t),s=e[i];return(t===t?t===s:s!==s)?i:-1}return J(e,t,n||0)}function Pn(e){var t=e?e.length:0;return t?e[t-1]:r}function Hn(e,t,n){var r=e?e.length:0;return r?(n&&typeof n!="number"&&Tn(e,t,n)&&(t=0,n=r),en(e,t,n)):[]}function Bn(e){var t=-1,n=(e&&e.length&&_t(Mt(e,yn)))>>>0,r=Array(n);while(++t<n)r[t]=Mt(e,Yt(t));return r}function In(e,t,n,r){var i=e?yn(e):0;return Cn(i)||(e=or(e),i=e.length),i?(typeof n!="number"||r&&Tn(t,n,r)?n=0:n=n<0?yt(i+n,0):n||0,typeof e=="string"||!Xn(e)&&Yn(e)?n<i&&e.indexOf(t,n)>-1:gn(e,t,n)>-1):!1}function qn(e,t,n){var r=Xn(e)?Ot:qt;return t=mn(t,n,3),r(e,function(e,n,r){return!t(e,n,r)})}function Rn(e,t,n){var i=Xn(e)?Dt:tn;n&&Tn(e,t,n)&&(t=null);if(typeof t!="function"||n!==r)t=mn(t,n,3);return i(e,t)}function Un(e,t){if(typeof e!="function")throw new TypeError(s);return t=yt(t===r?e.length-1:+t||0,0),function(){var n=arguments,r=-1,i=yt(n.length-t,0),s=Array(i);while(++r<i)s[r]=n[t+r];switch(t){case 0:return e.call(this,s);case 1:return e.call(this,n[0],s);case 2:return e.call(this,n[0],n[1],s)}var o=Array(t+1);r=-1;while(++r<t)o[r]=n[r];return o[t]=s,e.apply(this,o)}}function zn(e,t,n,r){return t&&typeof t!="boolean"&&Tn(e,t,n)?t=!1:typeof t=="function"&&(r=n,n=t,t=!1),n=typeof n=="function"&&on(n,r,1),Ft(e,t,n)}function Wn(e){var t=Y(e)?e.length:r;return Cn(t)&&rt.call(e)==o}function Vn(e){if(e==null)return!0;var t=yn(e);return Cn(t)&&(Xn(e)||Yn(e)||Wn(e)||Y(e)&&$n(e.splice))?!t:!rr(e).length}function Jn(e){var t=typeof e;return t=="function"||!!e&&t=="object"}function Kn(e){return e==null?!1:rt.call(e)==c?it.test(tt.call(e)):Y(e)&&B.test(e)}function Qn(e){return typeof e=="number"||Y(e)&&rt.call(e)==p}function Yn(e){return typeof e=="string"||Y(e)&&rt.call(e)==g}function Zn(e){return Y(e)&&Cn(e.length)&&!!j[rt.call(e)]}function er(e){return Bt(e,ir(e))}function nr(e,t){if(e==null)return!1;var n=nt.call(e,t);return!n&&!Nn(t)&&(t=Mn(t),e=t.length==1?e:Wt(e,en(t,0,-1)),t=Pn(t),n=e!=null&&nt.call(e,t)),n}function ir(e){if(e==null)return[];Jn(e)||(e=Object(e));var t=e.length;t=t&&Cn(t)&&(Xn(e)||kt.nonEnumArgs&&Wn(e))&&t||0;var n=e.constructor,r=-1,i=typeof n=="function"&&n.prototype===e,s=Array(t),o=t>0;while(++r<t)s[r]=r+"";for(var u in e)(!o||!xn(u,t))&&(u!="constructor"||!i&&!!nt.call(e,u))&&s.push(u);return s}function or(e){return nn(e,rr(e))}function ur(e){return e=Q(e),e&&D.test(e)?e.replace(_,"\\$&"):e}function ar(e,t,n){return n&&Tn(e,t,n)&&(t=null),jt(e,t)}function fr(e){return function(){return e}}function lr(e){return e}function cr(e){return Nn(e)?Yt(e):Zt(e)}var r,i="3.7.0",s="Expected a function",o="[object Arguments]",u="[object Array]",a="[object Boolean]",f="[object Date]",l="[object Error]",c="[object Function]",h="[object Map]",p="[object Number]",d="[object Object]",v="[object RegExp]",m="[object Set]",g="[object String]",y="[object WeakMap]",b="[object ArrayBuffer]",w="[object Float32Array]",E="[object Float64Array]",S="[object Int8Array]",x="[object Int16Array]",T="[object Int32Array]",N="[object Uint8Array]",C="[object Uint8ClampedArray]",k="[object Uint16Array]",L="[object Uint32Array]",A=/\.|\[(?:[^[\]]+|(["'])(?:(?!\1)[^\n\\]|\\.)*?)\1\]/,O=/^\w*$/,M=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,_=/[.*+?^${}()|[\]\/\\]/g,D=RegExp(_.source),P=/\\(\\)?/g,H=/\w*$/,B=/^\[object .+?Constructor\]$/,j={};j[w]=j[E]=j[S]=j[x]=j[T]=j[N]=j[C]=j[k]=j[L]=!0,j[o]=j[u]=j[b]=j[a]=j[f]=j[l]=j[c]=j[h]=j[p]=j[d]=j[v]=j[m]=j[g]=j[y]=!1;var F={};F[o]=F[u]=F[b]=F[a]=F[f]=F[w]=F[E]=F[S]=F[x]=F[T]=F[p]=F[d]=F[v]=F[g]=F[N]=F[C]=F[k]=F[L]=!0,F[l]=F[c]=F[h]=F[m]=F[y]=!1;var I={"function":!0,object:!0},q=I[typeof n]&&n&&!n.nodeType&&n,R=I[typeof t]&&t&&!t.nodeType&&t,U=q&&R&&typeof e=="object"&&e&&e.Object&&e,z=I[typeof self]&&self&&self.Object&&self,W=I[typeof window]&&window&&window.Object&&window,X=R&&R.exports===q&&q,V=U||W!==(this&&this.window)&&W||z||this,Z=Array.prototype,et=Object.prototype,tt=Function.prototype.toString,nt=et.hasOwnProperty,rt=et.toString,it=RegExp("^"+ur(rt).replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),st=Kn(st=V.ArrayBuffer)&&st,ot=Kn(ot=st&&(new st(0)).slice)&&ot,ut=Math.floor,at=Kn(at=Object.getOwnPropertySymbols)&&at,ft=Kn(ft=Object.getPrototypeOf)&&ft,lt=Z.push,ct=Kn(Object.preventExtensions=Object.preventExtensions)&&ct,ht=et.propertyIsEnumerable,pt=Kn(pt=V.Uint8Array)&&pt,dt=function(){try{var e=Kn(e=V.Float64Array)&&e,t=new e(new st(10),0,1)&&e}catch(n){}return t}(),vt=function(){var e={1:0},t=ct&&Kn(t=Object.assign)&&t;try{t(ct(e),"xo")}catch(n){}return!e[1]&&t}(),mt=Kn(mt=Array.isArray)&&mt,gt=Kn(gt=Object.keys)&&gt,yt=Math.max,bt=Math.min,wt=Number.NEGATIVE_INFINITY,Et=Math.pow(2,32)-1,St=Et-1,xt=Et>>>1,Tt=dt?dt.BYTES_PER_ELEMENT:0,Nt=Math.pow(2,53)-1,kt=Ct.support={};(function(e){var t=function(){this.x=e},n={0:e,length:e},r=[];t.prototype={valueOf:e,y:e};for(var i in new t)r.push(i);kt.funcDecomp=/\bthis\b/.test(function(){return this}),kt.funcNames=typeof Function.name=="string";try{kt.nonEnumArgs=!ht.call(arguments,1)}catch(s){kt.nonEnumArgs=!0}})(1,0);var Ht=vt||function(e,t){return t==null?e:Bt(t,bn(t),Bt(t,rr(t),e))},It=fn(zt),Rt=ln();ot||(un=!st||!pt?fr(null):function(e){var t=e.byteLength,n=dt?ut(t/Tt):0,r=n*Tt,i=new st(t);if(n){var s=new dt(i,0,n);s.set(new dt(e,0,n))}return t!=r&&(s=new pt(i,r),s.set(new pt(e,r))),i});var yn=Yt("length"),bn=at?function(e){return at(On(e))}:fr([]),_n=cn(!0),jn=Un(Bn),Fn=hn(At,It),Xn=mt||function(e){return Y(e)&&Cn(e.length)&&rt.call(e)==u},$n=K(/x/)||pt&&!K(pt)?function(e){return rt.call(e)==c}:K,Gn=ft?function(e){if(!e||rt.call(e)!=d)return!1;var t=e.valueOf,n=Kn(t)&&(n=ft(t))&&ft(n);return n?e==n||ft(e)==n:Ln(e)}:Ln,tr=an(function(e,t,n){return n?Pt(e,t,n):Ht(e,t)}),rr=gt?function(e){if(e)var t=e.constructor,n=e.length;return typeof t=="function"&&t.prototype===e||typeof e!="function"&&Cn(n)?An(e):Jn(e)?gt(e):[]}:An,sr=an(Qt);Ct.assign=tr,Ct.callback=ar,Ct.constant=fr,Ct.forEach=Fn,Ct.keys=rr,Ct.keysIn=ir,Ct.merge=sr,Ct.property=cr,Ct.reject=qn,Ct.restParam=Un,Ct.slice=Hn,Ct.toPlainObject=er,Ct.unzip=Bn,Ct.values=or,Ct.zip=jn,Ct.each=Fn,Ct.extend=tr,Ct.iteratee=ar,Ct.clone=zn,Ct.escapeRegExp=ur,Ct.findLastIndex=_n,Ct.has=nr,Ct.identity=lr,Ct.includes=In,Ct.indexOf=Dn,Ct.isArguments=Wn,Ct.isArray=Xn,Ct.isEmpty=Vn,Ct.isFunction=$n,Ct.isNative=Kn,Ct.isNumber=Qn,Ct.isObject=Jn,Ct.isPlainObject=Gn,Ct.isString=Yn,Ct.isTypedArray=Zn,Ct.last=Pn,Ct.some=Rn,Ct.any=Rn,Ct.contains=In,Ct.include=In,Ct.VERSION=i,q&&R?X?(R.exports=Ct)._=Ct:q._=Ct:V._=Ct}).call(this)}).call(this,typeof global!="undefined"?global:typeof self!="undefined"?self:typeof window!="undefined"?window:{})},{}],"/node_modules/jshint/src/jshint.js":[function(e,t,n){var r=e("../lodash"),i=e("events"),s=e("./vars.js"),o=e("./messages.js"),u=e("./lex.js").Lexer,a=e("./reg.js"),f=e("./state.js").state,l=e("./style.js"),c=e("./options.js"),h=e("./scope-manager.js"),p=function(){"use strict";function k(e,t){return e=e.trim(),/^[+-]W\d{3}$/g.test(e)?!0:c.validNames.indexOf(e)===-1&&t.type!=="jslint"&&!r.has(c.removed,e)?(q("E001",t,e),!1):!0}function L(e){return Object.prototype.toString.call(e)==="[object String]"}function A(e,t){return e?!e.identifier||e.value!==t?!1:!0:!1}function O(e){if(!e.reserved)return!1;var t=e.meta;if(t&&t.isFutureReservedWord&&f.inES5()){if(!t.es5)return!1;if(t.strictOnly&&!f.option.strict&&!f.isStrict())return!1;if(e.isProperty)return!1}return!0}function M(e,t){return e.replace(/\{([^{}]*)\}/g,function(e,n){var r=t[n];return typeof r=="string"||typeof r=="number"?r:e})}function D(e,t){Object.keys(t).forEach(function(n){if(r.has(p.blacklist,n))return;e[n]=t[n]})}function P(){if(f.option.enforceall){for(var e in c.bool.enforcing)f.option[e]===undefined&&!c.noenforceall[e]&&(f.option[e]=!0);for(var t in c.bool.relaxing)f.option[t]===undefined&&(f.option[t]=!1)}}function H(){P(),!f.option.esversion&&!f.option.moz&&(f.option.es3?f.option.esversion=3:f.option.esnext?f.option.esversion=6:f.option.esversion=5),f.inES5()&&D(S,s.ecmaIdentifiers[5]),f.inES6()&&D(S,s.ecmaIdentifiers[6]),f.option.module&&(f.option.strict===!0&&(f.option.strict="global"),f.inES6()||F("W134",f.tokens.next,"module",6)),f.option.couch&&D(S,s.couch),f.option.qunit&&D(S,s.qunit),f.option.rhino&&D(S,s.rhino),f.option.shelljs&&(D(S,s.shelljs),D(S,s.node)),f.option.typed&&D(S,s.typed),f.option.phantom&&(D(S,s.phantom),f.option.strict===!0&&(f.option.strict="global")),f.option.prototypejs&&D(S,s.prototypejs),f.option.node&&(D(S,s.node),D(S,s.typed),f.option.strict===!0&&(f.option.strict="global")),f.option.devel&&D(S,s.devel),f.option.dojo&&D(S,s.dojo),f.option.browser&&(D(S,s.browser),D(S,s.typed)),f.option.browserify&&(D(S,s.browser),D(S,s.typed),D(S,s.browserify),f.option.strict===!0&&(f.option.strict="global")),f.option.nonstandard&&D(S,s.nonstandard),f.option.jasmine&&D(S,s.jasmine),f.option.jquery&&D(S,s.jquery),f.option.mootools&&D(S,s.mootools),f.option.worker&&D(S,s.worker),f.option.wsh&&D(S,s.wsh),f.option.globalstrict&&f.option.strict!==!1&&(f.option.strict="global"),f.option.yui&&D(S,s.yui),f.option.mocha&&D(S,s.mocha)}function B(e,t,n){var r=Math.floor(t/f.lines.length*100),i=o.errors[e].desc;throw{name:"JSHintError",line:t,character:n,message:i+" ("+r+"% scanned).",raw:i,code:e}}function j(){var e=f.ignoredLines;if(r.isEmpty(e))return;p.errors=r.reject(p.errors,function(t){return e[t.line]})}function F(e,t,n,r,i,s){var u,a,l,c;if(/^W\d{3}$/.test(e)){if(f.ignored[e])return;c=o.warnings[e]}else/E\d{3}/.test(e)?c=o.errors[e]:/I\d{3}/.test(e)&&(c=o.info[e]);return t=t||f.tokens.next||{},t.id==="(end)"&&(t=f.tokens.curr),a=t.line||0,u=t.from||0,l={id:"(error)",raw:c.desc,code:c.code,evidence:f.lines[a-1]||"",line:a,character:u,scope:p.scope,a:n,b:r,c:i,d:s},l.reason=M(c.desc,l),p.errors.push(l),j(),p.errors.length>=f.option.maxerr&&B("E043",a,u),l}function I(e,t,n,r,i,s,o){return F(e,{line:t,from:n},r,i,s,o)}function q(e,t,n,r,i,s){F(e,t,n,r,i,s)}function R(e,t,n,r,i,s,o){return q(e,{line:t,from:n},r,i,s,o)}function U(e,t){var n;return n={id:"(internal)",elem:e,value:t},p.internals.push(n),n}function z(){var e=f.tokens.next,t=e.body.match(/(-\s+)?[^\s,:]+(?:\s*:\s*(-\s+)?[^\s,]+)?/g)||[],i={};if(e.type==="globals"){t.forEach(function(n,r){n=n.split(":");var s=(n[0]||"").trim(),o=(n[1]||"").trim();if(s==="-"||!s.length){if(r>0&&r===t.length-1)return;q("E002",e);return}s.charAt(0)==="-"?(s=s.slice(1),o=!1,p.blacklist[s]=s,delete S[s]):i[s]=o==="true"}),D(S,i);for(var s in i)r.has(i,s)&&(n[s]=e)}e.type==="exported"&&t.forEach(function(n,r){if(!n.length){if(r>0&&r===t.length-1)return;q("E002",e);return}f.funct["(scope)"].addExported(n)}),e.type==="members"&&(E=E||{},t.forEach(function(e){var t=e.charAt(0),n=e.charAt(e.length-1);t===n&&(t==='"'||t==="'")&&(e=e.substr(1,e.length-2).replace('\\"','"')),E[e]=!1}));var o=["maxstatements","maxparams","maxdepth","maxcomplexity","maxerr","maxlen","indent"];if(e.type==="jshint"||e.type==="jslint")t.forEach(function(t){t=t.split(":");var n=(t[0]||"").trim(),i=(t[1]||"").trim();if(!k(n,e))return;if(o.indexOf(n)>=0){if(i!=="false"){i=+i;if(typeof i!="number"||!isFinite(i)||i<=0||Math.floor(i)!==i){q("E032",e,t[1].trim());return}f.option[n]=i}else f.option[n]=n==="indent"?4:!1;return}if(n==="validthis"){if(f.funct["(global)"])return void q("E009");if(i!=="true"&&i!=="false")return void q("E002",e);f.option.validthis=i==="true";return}if(n==="quotmark"){switch(i){case"true":case"false":f.option.quotmark=i==="true";break;case"double":case"single":f.option.quotmark=i;break;default:q("E002",e)}return}if(n==="shadow"){switch(i){case"true":f.option.shadow=!0;break;case"outer":f.option.shadow="outer";break;case"false":case"inner":f.option.shadow="inner";break;default:q("E002",e)}return}if(n==="unused"){switch(i){case"true":f.option.unused=!0;break;case"false":f.option.unused=!1;break;case"vars":case"strict":f.option.unused=i;break;default:q("E002",e)}return}if(n==="latedef"){switch(i){case"true":f.option.latedef=!0;break;case"false":f.option.latedef=!1;break;case"nofunc":f.option.latedef="nofunc";break;default:q("E002",e)}return}if(n==="ignore"){switch(i){case"line":f.ignoredLines[e.line]=!0,j();break;default:q("E002",e)}return}if(n==="strict"){switch(i){case"true":f.option.strict=!0;break;case"false":f.option.strict=!1;break;case"func":case"global":case"implied":f.option.strict=i;break;default:q("E002",e)}return}n==="module"&&(zt(f.funct)||q("E055",f.tokens.next,"module"));var s={es3:3,es5:5,esnext:6};if(r.has(s,n)){switch(i){case"true":f.option.moz=!1,f.option.esversion=s[n];break;case"false":f.option.moz||(f.option.esversion=5);break;default:q("E002",e)}return}if(n==="esversion"){switch(i){case"5":f.inES5(!0)&&F("I003");case"3":case"6":f.option.moz=!1,f.option.esversion=+i;break;case"2015":f.option.moz=!1,f.option.esversion=6;break;default:q("E002",e)}zt(f.funct)||q("E055",f.tokens.next,"esversion");return}var u=/^([+-])(W\d{3})$/g.exec(n);if(u){f.ignored[u[2]]=u[1]==="-";return}var a;if(i==="true"||i==="false"){e.type==="jslint"?(a=c.renamed[n]||n,f.option[a]=i==="true",c.inverted[a]!==undefined&&(f.option[a]=!f.option[a])):f.option[n]=i==="true",n==="newcap"&&(f.option["(explicitNewcap)"]=!0);return}q("E002",e)}),H()}function W(e){var t=e||0,n=y.length,r;if(t<n)return y[t];while(n<=t)r=y[n],r||(r=y[n]=b.token()),n+=1;return!r&&f.tokens.next.id==="(end)"?f.tokens.next:r}function X(){var e=0,t;do t=W(e++);while(t.id==="(endline)");return t}function V(e,t){switch(f.tokens.curr.id){case"(number)":f.tokens.next.id==="."&&F("W005",f.tokens.curr);break;case"-":(f.tokens.next.id==="-"||f.tokens.next.id==="--")&&F("W006");break;case"+":(f.tokens.next.id==="+"||f.tokens.next.id==="++")&&F("W007")}e&&f.tokens.next.id!==e&&(t?f.tokens.next.id==="(end)"?q("E019",t,t.id):q("E020",f.tokens.next,e,t.id,t.line,f.tokens.next.value):(f.tokens.next.type!=="(identifier)"||f.tokens.next.value!==e)&&F("W116",f.tokens.next,e,f.tokens.next.value)),f.tokens.prev=f.tokens.curr,f.tokens.curr=f.tokens.next;for(;;){f.tokens.next=y.shift()||b.token(),f.tokens.next||B("E041",f.tokens.curr.line);if(f.tokens.next.id==="(end)"||f.tokens.next.id==="(error)")return;f.tokens.next.check&&f.tokens.next.check();if(f.tokens.next.isSpecial)f.tokens.next.type==="falls through"?f.tokens.curr.caseFallsThrough=!0:z();else if(f.tokens.next.id!=="(endline)")break}}function $(e){return e.infix||!e.identifier&&!e.template&&!!e.led}function J(){var e=f.tokens.curr,t=f.tokens.next;return t.id===";"||t.id==="}"||t.id===":"?!0:$(t)===$(e)||e.id==="yield"&&f.inMoz()?e.line!==G(t):!1}function K(e){return!e.left&&e.arity!=="unary"}function Q(e,t){var n,i=!1,s=!1,o=!1;f.nameStack.push(),!t&&f.tokens.next.value==="let"&&W(0).value==="("&&(f.inMoz()||F("W118",f.tokens.next,"let expressions"),o=!0,f.funct["(scope)"].stack(),V("let"),V("("),f.tokens.prev.fud(),V(")")),f.tokens.next.id==="(end)"&&q("E006",f.tokens.curr);var u=f.option.asi&&f.tokens.prev.line!==G(f.tokens.curr)&&r.contains(["]",")"],f.tokens.prev.id)&&r.contains(["[","("],f.tokens.curr.id);u&&F("W014",f.tokens.curr,f.tokens.curr.id),V(),t&&(f.funct["(verb)"]=f.tokens.curr.value,f.tokens.curr.beginsStmt=!0);if(t===!0&&f.tokens.curr.fud)n=f.tokens.curr.fud();else{f.tokens.curr.nud?n=f.tokens.curr.nud():q("E030",f.tokens.curr,f.tokens.curr.id);while((e<f.tokens.next.lbp||f.tokens.next.type==="(template)")&&!J())i=f.tokens.curr.value==="Array",s=f.tokens.curr.value==="Object",n&&(n.value||n.first&&n.first.value)&&(n.value!=="new"||n.first&&n.first.value&&n.first.value===".")&&(i=!1,n.value!==f.tokens.curr.value&&(s=!1)),V(),i&&f.tokens.curr.id==="("&&f.tokens.next.id===")"&&F("W009",f.tokens.curr),s&&f.tokens.curr.id==="("&&f.tokens.next.id===")"&&F("W010",f.tokens.curr),n&&f.tokens.curr.led?n=f.tokens.curr.led(n):q("E033",f.tokens.curr,f.tokens.curr.id)}return o&&f.funct["(scope)"].unstack(),f.nameStack.pop(),n}function G(e){return e.startLine||e.line}function Y(e,t){e=e||f.tokens.curr,t=t||f.tokens.next,!f.option.laxbreak&&e.line!==G(t)&&F("W014",t,t.value)}function Z(e){e=e||f.tokens.curr,e.line!==G(f.tokens.next)&&F("E022",e,e.value)}function et(e,t){e.line!==G(t)&&(f.option.laxcomma||(tt.first&&(F("I001"),tt.first=!1),F("W014",e,t.value)))}function tt(e){e=e||{},e.peek?et(f.tokens.prev,f.tokens.curr):(et(f.tokens.curr,f.tokens.next),V(","));if(f.tokens.next.identifier&&(!e.property||!f.inES5()))switch(f.tokens.next.value){case"break":case"case":case"catch":case"continue":case"default":case"do":case"else":case"finally":case"for":case"if":case"in":case"instanceof":case"return":case"switch":case"throw":case"try":case"var":case"let":case"while":case"with":return q("E024",f.tokens.next,f.tokens.next.value),!1}if(f.tokens.next.type==="(punctuator)")switch(f.tokens.next.value){case"}":case"]":case",":if(e.allowTrailing)return!0;case")":return q("E024",f.tokens.next,f.tokens.next.value),!1}return!0}function nt(e,t){var n=f.syntax[e];if(!n||typeof n!="object")f.syntax[e]=n={id:e,lbp:t,value:e};return n}function rt(e){var t=nt(e,0);return t.delim=!0,t}function it(e,t){var n=rt(e);return n.identifier=n.reserved=!0,n.fud=t,n}function st(e,t){var n=it(e,t);return n.block=!0,n}function ot(e){var t=e.id.charAt(0);if(t>="a"&&t<="z"||t>="A"&&t<="Z")e.identifier=e.reserved=!0;return e}function ut(e,t){var n=nt(e,150);return ot(n),n.nud=typeof t=="function"?t:function(){this.arity="unary",this.right=Q(150);if(this.id==="++"||this.id==="--")f.option.plusplus?F("W016",this,this.id):this.right&&(!this.right.identifier||O(this.right))&&this.right.id!=="."&&this.right.id!=="["&&F("W017",this),this.right&&this.right.isMetaProperty?q("E031",this):this.right&&this.right.identifier&&f.funct["(scope)"].block.modify(this.right.value,this);return this},n}function at(e,t){var n=rt(e);return n.type=e,n.nud=t,n}function ft(e,t){var n=at(e,t);return n.identifier=!0,n.reserved=!0,n}function lt(e,t){var n=at(e,t&&t.nud||function(){return this});return t=t||{},t.isFutureReservedWord=!0,n.value=e,n.identifier=!0,n.reserved=!0,n.meta=t,n}function ct(e,t){return ft(e,function(){return typeof t=="function"&&t(this),this})}function ht(e,t,n,r){var i=nt(e,n);return ot(i),i.infix=!0,i.led=function(i){return r||Y(f.tokens.prev,f.tokens.curr),(e==="in"||e==="instanceof")&&i.id==="!"&&F("W018",i,"!"),typeof t=="function"?t(i,this):(this.left=i,this.right=Q(n),this)},i}function pt(e){var t=nt(e,42);return t.led=function(e){return Y(f.tokens.prev,f.tokens.curr),this.left=e,this.right=Xt({type:"arrow",loneArg:e}),this},t}function dt(e,t){var n=nt(e,100);return n.led=function(e){Y(f.tokens.prev,f.tokens.curr),this.left=e;var n=this.right=Q(100);return A(e,"NaN")||A(n,"NaN")?F("W019",this):t&&t.apply(this,[e,n]),(!e||!n)&&B("E041",f.tokens.curr.line),e.id==="!"&&F("W018",e,"!"),n.id==="!"&&F("W018",n,"!"),this},n}function vt(e){return e&&(e.type==="(number)"&&+e.value===0||e.type==="(string)"&&e.value===""||e.type==="null"&&!f.option.eqnull||e.type==="true"||e.type==="false"||e.type==="undefined")}function gt(e,t,n){var i;return n.option.notypeof?!1:!e||!t?!1:(i=n.inES6()?mt.es6:mt.es3,t.type==="(identifier)"&&t.value==="typeof"&&e.type==="(string)"?!r.contains(i,e.value):!1)}function yt(e,t){var n=!1;return e.type==="this"&&t.funct["(context)"]===null?n=!0:e.type==="(identifier)"&&(t.option.node&&e.value==="global"?n=!0:t.option.browser&&(e.value==="window"||e.value==="document")&&(n=!0)),n}function bt(e){function n(e){if(typeof e!="object")return;return e.right==="prototype"?e:n(e.left)}function r(e){while(!e.identifier&&typeof e.left=="object")e=e.left;if(e.identifier&&t.indexOf(e.value)>=0)return e.value}var t=["Array","ArrayBuffer","Boolean","Collator","DataView","Date","DateTimeFormat","Error","EvalError","Float32Array","Float64Array","Function","Infinity","Intl","Int16Array","Int32Array","Int8Array","Iterator","Number","NumberFormat","Object","RangeError","ReferenceError","RegExp","StopIteration","String","SyntaxError","TypeError","Uint16Array","Uint32Array","Uint8Array","Uint8ClampedArray","URIError"],i=n(e);if(i)return r(i)}function wt(e,t,n){var r=n&&n.allowDestructuring;t=t||e;if(f.option.freeze){var i=bt(e);i&&F("W121",e,i)}return e.identifier&&!e.isMetaProperty&&f.funct["(scope)"].block.reassign(e.value,e),e.id==="."?((!e.left||e.left.value==="arguments"&&!f.isStrict())&&F("E031",t),f.nameStack.set(f.tokens.prev),!0):e.id==="{"||e.id==="["?(r&&f.tokens.curr.left.destructAssign?f.tokens.curr.left.destructAssign.forEach(function(e){e.id&&f.funct["(scope)"].block.modify(e.id,e.token)}):e.id==="{"||!e.left?F("E031",t):e.left.value==="arguments"&&!f.isStrict()&&F("E031",t),e.id==="["&&f.nameStack.set(e.right),!0):e.isMetaProperty?(q("E031",t),!0):e.identifier&&!O(e)?(f.funct["(scope)"].labeltype(e.value)==="exception"&&F("W022",e),f.nameStack.set(e),!0):(e===f.syntax["function"]&&F("W023",f.tokens.curr),!1)}function Et(e,t,n){var r=ht(e,typeof t=="function"?t:function(e,t){t.left=e;if(e&&wt(e,t,{allowDestructuring:!0}))return t.right=Q(10),t;q("E031",t)},n);return r.exps=!0,r.assign=!0,r}function St(e,t,n){var r=nt(e,n);return ot(r),r.led=typeof t=="function"?t:function(e){return f.option.bitwise&&F("W016",this,this.id),this.left=e,this.right=Q(n),this},r}function xt(e){return Et(e,function(e,t){f.option.bitwise&&F("W016",t,t.id);if(e&&wt(e,t))return t.right=Q(10),t;q("E031",t)},20)}function Tt(e){var t=nt(e,150);return t.led=function(e){return f.option.plusplus?F("W016",this,this.id):(!e.identifier||O(e))&&e.id!=="."&&e.id!=="["&&F("W017",this),e.isMetaProperty?q("E031",this):e&&e.identifier&&f.funct["(scope)"].block.modify(e.value,e),this.left=e,this},t}function Nt(e,t,n){if(!f.tokens.next.identifier)return;n||V();var r=f.tokens.curr,i=f.tokens.curr.value;return O(r)?t&&f.inES5()?i:e&&i==="undefined"?i:(F("W024",f.tokens.curr,f.tokens.curr.id),i):i}function Ct(e,t){var n=Nt(e,t,!1);if(n)return n;if(f.tokens.next.value==="..."){f.inES6(!0)||F("W119",f.tokens.next,"spread/rest operator","6"),V();if(pn(f.tokens.next,"...")){F("E024",f.tokens.next,"...");while(pn(f.tokens.next,"..."))V()}if(!f.tokens.next.identifier){F("E024",f.tokens.curr,"...");return}return Ct(e,t)}q("E030",f.tokens.next,f.tokens.next.value),f.tokens.next.id!==";"&&V()}function kt(e){var t=0,n;if(f.tokens.next.id!==";"||e.inBracelessBlock)return;for(;;){do n=W(t),t+=1;while(n.id!=="(end)"&&n.id==="(comment)");if(n.reach)return;if(n.id!=="(endline)"){if(n.id==="function"){f.option.latedef===!0&&F("W026",n);break}F("W027",n,n.value,e.value);break}}}function Lt(){if(f.tokens.next.id!==";"){if(f.tokens.next.isUnclosed)return V();var e=G(f.tokens.next)===f.tokens.curr.line&&f.tokens.next.id!=="(end)",t=pn(f.tokens.next,"}");e&&!t?R("E058",f.tokens.curr.line,f.tokens.curr.character):f.option.asi||(t&&!f.option.lastsemic||!e)&&I("W033",f.tokens.curr.line,f.tokens.curr.character)}else V(";")}function At(){var e=g,t,n=f.tokens.next,r=!1;if(n.id===";"){V(";");return}var i=O(n);i&&n.meta&&n.meta.isFutureReservedWord&&W().id===":"&&(F("W024",n,n.id),i=!1),n.identifier&&!i&&W().id===":"&&(V(),V(":"),r=!0,f.funct["(scope)"].stack(),f.funct["(scope)"].block.addBreakLabel(n.value,{token:f.tokens.curr}),!f.tokens.next.labelled&&f.tokens.next.value!=="{"&&F("W028",f.tokens.next,n.value,f.tokens.next.value),f.tokens.next.label=n.value,n=f.tokens.next);if(n.id==="{"){var s=f.funct["(verb)"]==="case"&&f.tokens.curr.value===":";_t(!0,!0,!1,!1,s);return}return t=Q(0,!0),t&&(!t.identifier||t.value!=="function")&&(t.type!=="(punctuator)"||!t.left||!t.left.identifier||t.left.value!=="function")&&!f.isStrict()&&f.option.strict==="global"&&F("E007"),n.block||(!f.option.expr&&(!t||!t.exps)?F("W030",f.tokens.curr):f.option.nonew&&t&&t.left&&t.id==="("&&t.left.id==="new"&&F("W031",n),Lt()),g=e,r&&f.funct["(scope)"].unstack(),t}function Ot(){var e=[],t;while(!f.tokens.next.reach&&f.tokens.next.id!=="(end)")f.tokens.next.id===";"?(t=W(),(!t||t.id!=="("&&t.id!=="[")&&F("W032"),V(";")):e.push(At());return e}function Mt(){var e,t,n;while(f.tokens.next.id==="(string)"){t=W(0);if(t.id==="(endline)"){e=1;do n=W(e++);while(n.id==="(endline)");if(n.id===";")t=n;else{if(n.value==="["||n.value===".")break;(!f.option.asi||n.value==="(")&&F("W033",f.tokens.next)}}else{if(t.id==="."||t.id==="[")break;t.id!==";"&&F("W033",t)}V();var r=f.tokens.curr.value;(f.directive[r]||r==="use strict"&&f.option.strict==="implied")&&F("W034",f.tokens.curr,r),f.directive[r]=!0,t.id===";"&&V(";")}f.isStrict()&&(f.option["(explicitNewcap)"]||(f.option.newcap=!0),f.option.undef=!0)}function _t(e,t,n,i,s){var o,u=m,a=g,l,c,h,p;m=e,c=f.tokens.next;var d=f.funct["(metrics)"];d.nestedBlockDepth+=1,d.verifyMaxNestedBlockDepthPerFunction();if(f.tokens.next.id==="{"){V("{"),f.funct["(scope)"].stack(),h=f.tokens.curr.line;if(f.tokens.next.id!=="}"){g+=f.option.indent;while(!e&&f.tokens.next.from>g)g+=f.option.indent;if(n){l={};for(p in f.directive)r.has(f.directive,p)&&(l[p]=f.directive[p]);Mt(),f.option.strict&&f.funct["(context)"]["(global)"]&&!l["use strict"]&&!f.isStrict()&&F("E007")}o=Ot(),d.statementCount+=o.length,g-=f.option.indent}V("}",c),n&&(f.funct["(scope)"].validateParams(),l&&(f.directive=l)),f.funct["(scope)"].unstack(),g=a}else if(!e)if(n){f.funct["(scope)"].stack(),l={},t&&!i&&!f.inMoz()&&q("W118",f.tokens.curr,"function closure expressions");if(!t)for(p in f.directive)r.has(f.directive,p)&&(l[p]=f.directive[p]);Q(10),f.option.strict&&f.funct["(context)"]["(global)"]&&!l["use strict"]&&!f.isStrict()&&F("E007"),f.funct["(scope)"].unstack()}else q("E021",f.tokens.next,"{",f.tokens.next.value);else f.funct["(noblockscopedvar)"]=f.tokens.next.id!=="for",f.funct["(scope)"].stack(),(!t||f.option.curly)&&F("W116",f.tokens.next,"{",f.tokens.next.value),f.tokens.next.inBracelessBlock=!0,g+=f.option.indent,o=[At()],g-=f.option.indent,f.funct["(scope)"].unstack(),delete f.funct["(noblockscopedvar)"];switch(f.funct["(verb)"]){case"break":case"continue":case"return":case"throw":if(s)break;default:f.funct["(verb)"]=null}return m=u,e&&f.option.noempty&&(!o||o.length===0)&&F("W035",f.tokens.prev),d.nestedBlockDepth-=1,o}function Dt(e){E&&typeof E[e]!="boolean"&&F("W036",f.tokens.curr,e),typeof w[e]=="number"?w[e]+=1:w[e]=1}function Bt(){var e={};e.exps=!0,f.funct["(comparray)"].stack();var t=!1;return f.tokens.next.value!=="for"&&(t=!0,f.inMoz()||F("W116",f.tokens.next,"for",f.tokens.next.value),f.funct["(comparray)"].setState("use"),e.right=Q(10)),V("for"),f.tokens.next.value==="each"&&(V("each"),f.inMoz()||F("W118",f.tokens.curr,"for each")),V("("),f.funct["(comparray)"].setState("define"),e.left=Q(130),r.contains(["in","of"],f.tokens.next.value)?V():q("E045",f.tokens.curr),f.funct["(comparray)"].setState("generate"),Q(10),V(")"),f.tokens.next.value==="if"&&(V("if"),V("("),f.funct["(comparray)"].setState("filter"),e.filter=Q(10),V(")")),t||(f.funct["(comparray)"].setState("use"),e.right=Q(10)),V("]"),f.funct["(comparray)"].unstack(),e}function jt(){return f.funct["(statement)"]&&f.funct["(statement)"].type==="class"||f.funct["(context)"]&&f.funct["(context)"]["(verb)"]==="class"}function Ft(e){return e.identifier||e.id==="(string)"||e.id==="(number)"}function It(e){var t,n=!0;return typeof e=="object"?t=e:(n=e,t=Nt(!1,!0,n)),t?typeof t=="object"&&(t.id==="(string)"||t.id==="(identifier)"?t=t.value:t.id==="(number)"&&(t=t.value.toString())):f.tokens.next.id==="(string)"?(t=f.tokens.next.value,n||V()):f.tokens.next.id==="(number)"&&(t=f.tokens.next.value.toString(),n||V()),t==="hasOwnProperty"&&F("W001"),t}function qt(e){function h(e){f.funct["(scope)"].addParam.apply(f.funct["(scope)"],e)}var t,n=[],i,s=[],o,u=!1,a=!1,l=0,c=e&&e.loneArg;if(c&&c.identifier===!0)return f.funct["(scope)"].addParam(c.value,c),{arity:1,params:[c.value]};t=f.tokens.next,(!e||!e.parsedOpening)&&V("(");if(f.tokens.next.id===")"){V(")");return}for(;;){l++;var p=[];if(r.contains(["{","["],f.tokens.next.id)){s=Gt();for(o in s)o=s[o],o.id&&(n.push(o.id),p.push([o.id,o.token]))}else{pn(f.tokens.next,"...")&&(a=!0),i=Ct(!0);if(i)n.push(i),p.push([i,f.tokens.curr]);else while(!hn(f.tokens.next,[",",")"]))V()}u&&f.tokens.next.id!=="="&&q("W138",f.tokens.current),f.tokens.next.id==="="&&(f.inES6()||F("W119",f.tokens.next,"default parameters","6"),V("="),u=!0,Q(10)),p.forEach(h);if(f.tokens.next.id!==",")return V(")",t),{arity:l,params:n};a&&F("W131",f.tokens.next),tt()}}function Rt(e,t,n){var i={"(name)":e,"(breakage)":0,"(loopage)":0,"(tokens)":{},"(properties)":{},"(catch)":!1,"(global)":!1,"(line)":null,"(character)":null,"(metrics)":null,"(statement)":null,"(context)":null,"(scope)":null,"(comparray)":null,"(generator)":null,"(arrow)":null,"(params)":null};return t&&r.extend(i,{"(line)":t.line,"(character)":t.character,"(metrics)":Vt(t)}),r.extend(i,n),i["(context)"]&&(i["(scope)"]=i["(context)"]["(scope)"],i["(comparray)"]=i["(context)"]["(comparray)"]),i}function Ut(e){return"(scope)"in e}function zt(e){return e["(global)"]&&!e["(verb)"]}function Wt(e){function i(){if(f.tokens.curr.template&&f.tokens.curr.tail&&f.tokens.curr.context===t)return!0;var e=f.tokens.next.template&&f.tokens.next.tail&&f.tokens.next.context===t;return e&&V(),e||f.tokens.next.isUnclosed}var t=this.context,n=this.noSubst,r=this.depth;if(!n)while(!i())!f.tokens.next.template||f.tokens.next.depth>r?Q(0):V();return{id:"(template)",type:"(template)",tag:e}}function Xt(e){var t,n,r,i,s,o,u,a,l=f.option,c=f.ignored;e&&(r=e.name,i=e.statement,s=e.classExprBinding,o=e.type==="generator",u=e.type==="arrow",a=e.ignoreLoopFunc),f.option=Object.create(f.option),f.ignored=Object.create(f.ignored),f.funct=Rt(r||f.nameStack.infer(),f.tokens.next,{"(statement)":i,"(context)":f.funct,"(arrow)":u,"(generator)":o}),t=f.funct,n=f.tokens.curr,n.funct=f.funct,v.push(f.funct),f.funct["(scope)"].stack("functionouter");var h=r||s;h&&f.funct["(scope)"].block.add(h,s?"class":"function",f.tokens.curr,!1),f.funct["(scope)"].stack("functionparams");var p=qt(e);return p?(f.funct["(params)"]=p.params,f.funct["(metrics)"].arity=p.arity,f.funct["(metrics)"].verifyMaxParametersPerFunction()):f.funct["(metrics)"].arity=0,u&&(f.inES6(!0)||F("W119",f.tokens.curr,"arrow function syntax (=>)","6"),e.loneArg||V("=>")),_t(!1,!0,!0,u),!f.option.noyield&&o&&f.funct["(generator)"]!=="yielded"&&F("W124",f.tokens.curr),f.funct["(metrics)"].verifyMaxStatementsPerFunction(),f.funct["(metrics)"].verifyMaxComplexityPerFunction(),f.funct["(unusedOption)"]=f.option.unused,f.option=l,f.ignored=c,f.funct["(last)"]=f.tokens.curr.line,f.funct["(lastcharacter)"]=f.tokens.curr.character,f.funct["(scope)"].unstack(),f.funct["(scope)"].unstack(),f.funct=f.funct["(context)"],!a&&!f.option.loopfunc&&f.funct["(loopage)"]&&t["(isCapturing)"]&&F("W083",n),t}function Vt(e){return{statementCount:0,nestedBlockDepth:-1,ComplexityCount:1,arity:0,verifyMaxStatementsPerFunction:function(){f.option.maxstatements&&this.statementCount>f.option.maxstatements&&F("W071",e,this.statementCount)},verifyMaxParametersPerFunction:function(){r.isNumber(f.option.maxparams)&&this.arity>f.option.maxparams&&F("W072",e,this.arity)},verifyMaxNestedBlockDepthPerFunction:function(){f.option.maxdepth&&this.nestedBlockDepth>0&&this.nestedBlockDepth===f.option.maxdepth+1&&F("W073",null,this.nestedBlockDepth)},verifyMaxComplexityPerFunction:function(){var t=f.option.maxcomplexity,n=this.ComplexityCount;t&&n>t&&F("W074",e,n)}}}function $t(){f.funct["(metrics)"].ComplexityCount+=1}function Jt(e){var t,n;e&&(t=e.id,n=e.paren,t===","&&(e=e.exprs[e.exprs.length-1])&&(t=e.id,n=n||e.paren));switch(t){case"=":case"+=":case"-=":case"*=":case"%=":case"&=":case"|=":case"^=":case"/=":!n&&!f.option.boss&&F("W084")}}function Kt(e){if(f.inES5())for(var t in e)e[t]&&e[t].setterToken&&!e[t].getterToken&&F("W078",e[t].setterToken)}function Qt(e,t){if(pn(f.tokens.next,".")){var n=f.tokens.curr.id;V(".");var r=Ct();return f.tokens.curr.isMetaProperty=!0,e!==r?q("E057",f.tokens.prev,n,r):t(),f.tokens.curr}}function Gt(e){var t=e&&e.assignment;return f.inES6()||F("W104",f.tokens.curr,t?"destructuring assignment":"destructuring binding","6"),Yt(e)}function Yt(e){var t,n=[],r=e&&e.openingParsed,i=e&&e.assignment,s=i?{assignment:i}:null,o=r?f.tokens.curr:f.tokens.next,u=function(){var e;if(hn(f.tokens.next,["[","{"])){t=Yt(s);for(var r in t)r=t[r],n.push({id:r.id,token:r.token})}else if(pn(f.tokens.next,","))n.push({id:null,token:f.tokens.curr});else{if(!pn(f.tokens.next,"(")){var o=pn(f.tokens.next,"...");if(i){var a=o?W(0):f.tokens.next;a.identifier||F("E030",a,a.value);var l=Q(155);l&&(wt(l),l.identifier&&(e=l.value))}else e=Ct();return e&&n.push({id:e,token:f.tokens.curr}),o}V("("),u(),V(")")}return!1},a=function(){var e;pn(f.tokens.next,"[")?(V("["),Q(10),V("]"),V(":"),u()):f.tokens.next.id==="(string)"||f.tokens.next.id==="(number)"?(V(),V(":"),u()):(e=Ct(),pn(f.tokens.next,":")?(V(":"),u()):e&&(i&&wt(f.tokens.curr),n.push({id:e,token:f.tokens.curr})))};if(pn(o,"[")){r||V("["),pn(f.tokens.next,"]")&&F("W137",f.tokens.curr);var l=!1;while(!pn(f.tokens.next,"]"))u()&&!l&&pn(f.tokens.next,",")&&(F("W130",f.tokens.next),l=!0),pn(f.tokens.next,"=")&&(pn(f.tokens.prev,"...")?V("]"):V("="),f.tokens.next.id==="undefined"&&F("W080",f.tokens.prev,f.tokens.prev.value),Q(10)),pn(f.tokens.next,"]")||V(",");V("]")}else if(pn(o,"{")){r||V("{"),pn(f.tokens.next,"}")&&F("W137",f.tokens.curr);while(!pn(f.tokens.next,"}")){a(),pn(f.tokens.next,"=")&&(V("="),f.tokens.next.id==="undefined"&&F("W080",f.tokens.prev,f.tokens.prev.value),Q(10));if(!pn(f.tokens.next,"}")){V(",");if(pn(f.tokens.next,"}"))break}}V("}")}return n}function Zt(e,t){var n=t.first;if(!n)return;r.zip(e,Array.isArray(n)?n:[n]).forEach(function(e){var t=e[0],n=e[1];t&&n?t.first=n:t&&t.first&&!n&&F("W080",t.first,t.first.value)})}function en(e,t,n){var i=n&&n.prefix,s=n&&n.inexport,o=e==="let",u=e==="const",a,l,c,h;f.inES6()||F("W104",f.tokens.curr,e,"6"),o&&f.tokens.next.value==="("?(f.inMoz()||F("W118",f.tokens.next,"let block"),V("("),f.funct["(scope)"].stack(),h=!0):f.funct["(noblockscopedvar)"]&&q("E048",f.tokens.curr,u?"Const":"Let"),t.first=[];for(;;){var p=[];r.contains(["{","["],f.tokens.next.value)?(a=Gt(),l=!1):(a=[{id:Ct(),token:f.tokens.curr}],l=!0),!i&&u&&f.tokens.next.id!=="="&&F("E012",f.tokens.curr,f.tokens.curr.value);for(var d in a)a.hasOwnProperty(d)&&(d=a[d],f.funct["(scope)"].block.isGlobal()&&S[d.id]===!1&&F("W079",d.token,d.id),d.id&&!f.funct["(noblockscopedvar)"]&&(f.funct["(scope)"].addlabel(d.id,{type:e,token:d.token}),p.push(d.token),l&&s&&f.funct["(scope)"].setExported(d.token.value,d.token)));f.tokens.next.id==="="&&(V("="),!i&&f.tokens.next.id==="undefined"&&F("W080",f.tokens.prev,f.tokens.prev.value),!i&&W(0).id==="="&&f.tokens.next.identifier&&F("W120",f.tokens.next,f.tokens.next.value),c=Q(i?120:10),l?a[0].first=c:Zt(p,c)),t.first=t.first.concat(p);if(f.tokens.next.id!==",")break;tt()}return h&&(V(")"),_t(!0,!0),t.block=!0,f.funct["(scope)"].unstack()),t}function sn(e){return f.inES6()||F("W104",f.tokens.curr,"class","6"),e?(this.name=Ct(),f.funct["(scope)"].addlabel(this.name,{type:"class",token:f.tokens.curr})):f.tokens.next.identifier&&f.tokens.next.value!=="extends"?(this.name=Ct(),this.namedExpr=!0):this.name=f.nameStack.infer(),on(this),this}function on(e){var t=f.inClassBody;f.tokens.next.value==="extends"&&(V("extends"),e.heritage=Q(10)),f.inClassBody=!0,V("{"),e.body=un(e),V("}"),f.inClassBody=t}function un(e){var t,n,r,i,s=Object.create(null),o=Object.create(null),u;for(var a=0;f.tokens.next.id!=="}";++a){t=f.tokens.next,n=!1,r=!1,i=null;if(t.id===";"){F("W032"),V(";");continue}t.id==="*"&&(r=!0,V("*"),t=f.tokens.next);if(t.id==="[")t=cn(),u=!0;else{if(!Ft(t)){F("W052",f.tokens.next,f.tokens.next.value||f.tokens.next.type),V();continue}V(),u=!1;if(t.identifier&&t.value==="static"){pn(f.tokens.next,"*")&&(r=!0,V("*"));if(Ft(f.tokens.next)||f.tokens.next.id==="[")u=f.tokens.next.id==="[",n=!0,t=f.tokens.next,f.tokens.next.id==="["?t=cn():V()}t.identifier&&(t.value==="get"||t.value==="set")&&(Ft(f.tokens.next)||f.tokens.next.id==="[")&&(u=f.tokens.next.id==="[",i=t,t=f.tokens.next,f.tokens.next.id==="["?t=cn():V())}if(!pn(f.tokens.next,"(")){q("E054",f.tokens.next,f.tokens.next.value);while(f.tokens.next.id!=="}"&&!pn(f.tokens.next,"("))V();f.tokens.next.value!=="("&&Xt({statement:e})}u||(i?ln(i.value,n?o:s,t.value,t,!0,n):(t.value==="constructor"?f.nameStack.set(e):f.nameStack.set(t),fn(n?o:s,t.value,t,!0,n)));if(i&&t.value==="constructor"){var l=i.value==="get"?"class getter method":"class setter method";q("E049",t,l,"constructor")}else t.value==="prototype"&&q("E049",t,"class method","prototype");It(t),Xt({statement:e,type:r?"generator":null,classExprBinding:e.namedExpr?e.name:null})}Kt(s)}function fn(e,t,n,r,i){var s=["key","class method","static class method"];s=s[(r||!1)+(i||!1)],n.identifier&&(t=n.value),e[t]&&t!=="__proto__"?F("W075",f.tokens.next,s,t):e[t]=Object.create(null),e[t].basic=!0,e[t].basictkn=n}function ln(e,t,n,r,i,s){var o=e==="get"?"getterToken":"setterToken",u="";i?(s&&(u+="static "),u+=e+"ter method"):u="key",f.tokens.curr.accessorType=e,f.nameStack.set(r),t[n]?(t[n].basic||t[n][o])&&n!=="__proto__"&&F("W075",f.tokens.next,u,n):t[n]=Object.create(null),t[n][o]=r}function cn(){V("["),f.inES6()||F("W119",f.tokens.curr,"computed property names","6");var e=Q(10);return V("]"),e}function hn(e,t){return e.type==="(punctuator)"?r.contains(t,e.value):!1}function pn(e,t){return e.type==="(punctuator)"&&e.value===t}function dn(){var e=an();e.notJson?(!f.inES6()&&e.isDestAssign&&F("W104",f.tokens.curr,"destructuring assignment","6"),Ot()):(f.option.laxbreak=!0,f.jsonMode=!0,mn())}function mn(){function e(){var e={},t=f.tokens.next;V("{");if(f.tokens.next.id!=="}")for(;;){if(f.tokens.next.id==="(end)")q("E026",f.tokens.next,t.line);else{if(f.tokens.next.id==="}"){F("W094",f.tokens.curr);break}f.tokens.next.id===","?q("E028",f.tokens.next):f.tokens.next.id!=="(string)"&&F("W095",f.tokens.next,f.tokens.next.value)}e[f.tokens.next.value]===!0?F("W075",f.tokens.next,"key",f.tokens.next.value):f.tokens.next.value==="__proto__"&&!f.option.proto||f.tokens.next.value==="__iterator__"&&!f.option.iterator?F("W096",f.tokens.next,f.tokens.next.value):e[f.tokens.next.value]=!0,V(),V(":"),mn();if(f.tokens.next.id!==",")break;V(",")}V("}")}function t(){var e=f.tokens.next;V("[");if(f.tokens.next.id!=="]")for(;;){if(f.tokens.next.id==="(end)")q("E027",f.tokens.next,e.line);else{if(f.tokens.next.id==="]"){F("W094",f.tokens.curr);break}f.tokens.next.id===","&&q("E028",f.tokens.next)}mn();if(f.tokens.next.id!==",")break;V(",")}V("]")}switch(f.tokens.next.id){case"{":e();break;case"[":t();break;case"true":case"false":case"null":case"(number)":case"(string)":V();break;case"-":V("-"),V("(number)");break;default:q("E003",f.tokens.next)}}var e,t={"<":!0,"<=":!0,"==":!0,"===":!0,"!==":!0,"!=":!0,">":!0,">=":!0,"+":!0,"-":!0,"*":!0,"/":!0,"%":!0},n,d=["closure","exception","global","label","outer","unused","var"],v,m,g,y,b,w,E,S,x,T,N=[],C=new i.EventEmitter,mt={};mt.legacy=["xml","unknown"],mt.es3=["undefined","boolean","number","string","function","object"],mt.es3=mt.es3.concat(mt.legacy),mt.es6=mt.es3.concat("symbol"),at("(number)",function(){return this}),at("(string)",function(){return this}),f.syntax["(identifier)"]={type:"(identifier)",lbp:0,identifier:!0,nud:function(){var e=this.value;return f.tokens.next.id==="=>"?this:(f.funct["(comparray)"].check(e)||f.funct["(scope)"].block.use(e,f.tokens.curr),this)},led:function(){q("E033",f.tokens.next,f.tokens.next.value)}};var Pt={lbp:0,identifier:!1,template:!0};f.syntax["(template)"]=r.extend({type:"(template)",nud:Wt,led:Wt,noSubst:!1},Pt),f.syntax["(template middle)"]=r.extend({type:"(template middle)",middle:!0,noSubst:!1},Pt),f.syntax["(template tail)"]=r.extend({type:"(template tail)",tail:!0,noSubst:!1},Pt),f.syntax["(no subst template)"]=r.extend({type:"(template)",nud:Wt,led:Wt,noSubst:!0,tail:!0},Pt),at("(regexp)",function(){return this}),rt("(endline)"),rt("(begin)"),rt("(end)").reach=!0,rt("(error)").reach=!0,rt("}").reach=!0,rt(")"),rt("]"),rt('"').reach=!0,rt("'").reach=!0,rt(";"),rt(":").reach=!0,rt("#"),ft("else"),ft("case").reach=!0,ft("catch"),ft("default").reach=!0,ft("finally"),ct("arguments",function(e){f.isStrict()&&f.funct["(global)"]&&F("E008",e)}),ct("eval"),ct("false"),ct("Infinity"),ct("null"),ct("this",function(e){f.isStrict()&&!jt()&&!f.option.validthis&&(f.funct["(statement)"]&&f.funct["(name)"].charAt(0)>"Z"||f.funct["(global)"])&&F("W040",e)}),ct("true"),ct("undefined"),Et("=","assign",20),Et("+=","assignadd",20),Et("-=","assignsub",20),Et("*=","assignmult",20),Et("/=","assigndiv",20).nud=function(){q("E014")},Et("%=","assignmod",20),xt("&="),xt("|="),xt("^="),xt("<<="),xt(">>="),xt(">>>="),ht(",",function(e,t){var n;t.exprs=[e],f.option.nocomma&&F("W127");if(!tt({peek:!0}))return t;for(;;){if(!(n=Q(10)))break;t.exprs.push(n);if(f.tokens.next.value!==","||!tt())break}return t},10,!0),ht("?",function(e,t){return $t(),t.left=e,t.right=Q(10),V(":"),t["else"]=Q(10),t},30);var Ht=40;ht("||",function(e,t){return $t(),t.left=e,t.right=Q(Ht),t},Ht),ht("&&","and",50),St("|","bitor",70),St("^","bitxor",80),St("&","bitand",90),dt("==",function(e,t){var n=f.option.eqnull&&((e&&e.value)==="null"||(t&&t.value)==="null");switch(!0){case!n&&f.option.eqeqeq:this.from=this.character,F("W116",this,"===","==");break;case vt(e):F("W041",this,"===",e.value);break;case vt(t):F("W041",this,"===",t.value);break;case gt(t,e,f):F("W122",this,t.value);break;case gt(e,t,f):F("W122",this,e.value)}return this}),dt("===",function(e,t){return gt(t,e,f)?F("W122",this,t.value):gt(e,t,f)&&F("W122",this,e.value),this}),dt("!=",function(e,t){var n=f.option.eqnull&&((e&&e.value)==="null"||(t&&t.value)==="null");return!n&&f.option.eqeqeq?(this.from=this.character,F("W116",this,"!==","!=")):vt(e)?F("W041",this,"!==",e.value):vt(t)?F("W041",this,"!==",t.value):gt(t,e,f)?F("W122",this,t.value):gt(e,t,f)&&F("W122",this,e.value),this}),dt("!==",function(e,t){return gt(t,e,f)?F("W122",this,t.value):gt(e,t,f)&&F("W122",this,e.value),this}),dt("<"),dt(">"),dt("<="),dt(">="),St("<<","shiftleft",120),St(">>","shiftright",120),St(">>>","shiftrightunsigned",120),ht("in","in",120),ht("instanceof","instanceof",120),ht("+",function(e,t){var n;return t.left=e,t.right=n=Q(130),e&&n&&e.id==="(string)"&&n.id==="(string)"?(e.value+=n.value,e.character=n.character,!f.option.scripturl&&a.javascriptURL.test(e.value)&&F("W050",e),e):t},130),ut("+","num"),ut("+++",function(){return F("W007"),this.arity="unary",this.right=Q(150),this}),ht("+++",function(e){return F("W007"),this.left=e,this.right=Q(130),this},130),ht("-","sub",130),ut("-","neg"),ut("---",function(){return F("W006"),this.arity="unary",this.right=Q(150),this}),ht("---",function(e){return F("W006"),this.left=e,this.right=Q(130),this},130),ht("*","mult",140),ht("/","div",140),ht("%","mod",140),Tt("++"),ut("++","preinc"),f.syntax["++"].exps=!0,Tt("--"),ut("--","predec"),f.syntax["--"].exps=!0,ut("delete",function(){var e=Q(10);return e?(e.id!=="."&&e.id!=="["&&F("W051"),this.first=e,e.identifier&&!f.isStrict()&&(e.forgiveUndef=!0),this):this}).exps=!0,ut("~",function(){return f.option.bitwise&&F("W016",this,"~"),this.arity="unary",this.right=Q(150),this}),ut("...",function(){return f.inES6(!0)||F("W119",this,"spread/rest operator","6"),!f.tokens.next.identifier&&f.tokens.next.type!=="(string)"&&!hn(f.tokens.next,["[","("])&&q("E030",f.tokens.next,f.tokens.next.value),Q(150),this}),ut("!",function(){return this.arity="unary",this.right=Q(150),this.right||B("E041",this.line||0),t[this.right.id]===!0&&F("W018",this,"!"),this}),ut("typeof",function(){var e=Q(150);return this.first=this.right=e,e||B("E041",this.line||0,this.character||0),e.identifier&&(e.forgiveUndef=!0),this}),ut("new",function(){var e=Qt("target",function(){f.inES6(!0)||F("W119",f.tokens.prev,"new.target","6");var e,t=f.funct;while(t){e=!t["(global)"];if(!t["(arrow)"])break;t=t["(context)"]}e||F("W136",f.tokens.prev,"new.target")});if(e)return e;var t=Q(155),n;if(t&&t.id!=="function")if(t.identifier){t["new"]=!0;switch(t.value){case"Number":case"String":case"Boolean":case"Math":case"JSON":F("W053",f.tokens.prev,t.value);break;case"Symbol":f.inES6()&&F("W053",f.tokens.prev,t.value);break;case"Function":f.option.evil||F("W054");break;case"Date":case"RegExp":case"this":break;default:t.id!=="function"&&(n=t.value.substr(0,1),f.option.newcap&&(n<"A"||n>"Z")&&!f.funct["(scope)"].isPredefined(t.value)&&F("W055",f.tokens.curr))}}else t.id!=="."&&t.id!=="["&&t.id!=="("&&F("W056",f.tokens.curr);else f.option.supernew||F("W057",this);return f.tokens.next.id!=="("&&!f.option.supernew&&F("W058",f.tokens.curr,f.tokens.curr.value),this.first=this.right=t,this}),f.syntax["new"].exps=!0,ut("void").exps=!0,ht(".",function(e,t){var n=Ct(!1,!0);return typeof n=="string"&&Dt(n),t.left=e,t.right=n,n&&n==="hasOwnProperty"&&f.tokens.next.value==="="&&F("W001"),!e||e.value!=="arguments"||n!=="callee"&&n!=="caller"?!f.option.evil&&e&&e.value==="document"&&(n==="write"||n==="writeln")&&F("W060",e):f.option.noarg?F("W059",e,n):f.isStrict()&&q("E008"),!f.option.evil&&(n==="eval"||n==="execScript")&&yt(e,f)&&F("W061"),t},160,!0),ht("(",function(e,t){f.option.immed&&e&&!e.immed&&e.id==="function"&&F("W062");var n=0,r=[];e&&e.type==="(identifier)"&&e.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)&&"Array Number String Boolean Date Object Error Symbol".indexOf(e.value)===-1&&(e.value==="Math"?F("W063",e):f.option.newcap&&F("W064",e));if(f.tokens.next.id!==")")for(;;){r[r.length]=Q(10),n+=1;if(f.tokens.next.id!==",")break;tt()}return V(")"),typeof e=="object"&&(!f.inES5()&&e.value==="parseInt"&&n===1&&F("W065",f.tokens.curr),f.option.evil||(e.value==="eval"||e.value==="Function"||e.value==="execScript"?(F("W061",e),r[0]&&[0].id==="(string)"&&U(e,r[0].value)):!r[0]||r[0].id!=="(string)"||e.value!=="setTimeout"&&e.value!=="setInterval"?r[0]&&r[0].id==="(string)"&&e.value==="."&&e.left.value==="window"&&(e.right==="setTimeout"||e.right==="setInterval")&&(F("W066",e),U(e,r[0].value)):(F("W066",e),U(e,r[0].value))),!e.identifier&&e.id!=="."&&e.id!=="["&&e.id!=="=>"&&e.id!=="("&&e.id!=="&&"&&e.id!=="||"&&e.id!=="?"&&(!f.inES6()||!e["(name)"])&&F("W067",t)),t.left=e,t},155,!0).exps=!0,ut("(",function(){var e=f.tokens.next,t,n=-1,r,i,s,o,u=1,a=f.tokens.curr,l=f.tokens.prev,c=!f.option.singleGroups;do e.value==="("?u+=1:e.value===")"&&(u-=1),n+=1,t=e,e=W(n);while((u!==0||t.value!==")")&&e.value!==";"&&e.type!=="(end)");f.tokens.next.id==="function"&&(i=f.tokens.next.immed=!0);if(e.value==="=>")return Xt({type:"arrow",parsedOpening:!0});var h=[];if(f.tokens.next.id!==")")for(;;){h.push(Q(10));if(f.tokens.next.id!==",")break;f.option.nocomma&&F("W127"),tt()}V(")",this),f.option.immed&&h[0]&&h[0].id==="function"&&f.tokens.next.id!=="("&&f.tokens.next.id!=="."&&f.tokens.next.id!=="["&&F("W068",this);if(!h.length)return;return h.length>1?(r=Object.create(f.syntax[","]),r.exprs=h,s=h[0],o=h[h.length-1],c||(c=l.assign||l.delim)):(r=s=o=h[0],c||(c=a.beginsStmt&&(r.id==="{"||i||Ut(r))||i&&(!J()||f.tokens.prev.id!=="}")||Ut(r)&&!J()||r.id==="{"&&l.id==="=>"||r.type==="(number)"&&pn(e,".")&&/^\d+$/.test(r.value))),r&&(!c&&(s.left||s.right||r.exprs)&&(c=!K(l)&&s.lbp<=l.lbp||!J()&&o.lbp<f.tokens.next.lbp),c||F("W126",a),r.paren=!0),r}),pt("=>"),ht("[",function(e,t){var n=Q(10),r;return n&&n.type==="(string)"&&(!f.option.evil&&(n.value==="eval"||n.value==="execScript")&&yt(e,f)&&F("W061"),Dt(n.value),!f.option.sub&&a.identifier.test(n.value)&&(r=f.syntax[n.value],(!r||!O(r))&&F("W069",f.tokens.prev,n.value))),V("]",t),n&&n.value==="hasOwnProperty"&&f.tokens.next.value==="="&&F("W001"),t.left=e,t.right=n,t},160,!0),ut("[",function(){var e=an();if(e.isCompArray)return!f.option.esnext&&!f.inMoz()&&F("W118",f.tokens.curr,"array comprehension"),Bt();if(e.isDestAssign)return this.destructAssign=Gt({openingParsed:!0,assignment:!0}),this;var t=f.tokens.curr.line!==G(f.tokens.next);this.first=[],t&&(g+=f.option.indent,f.tokens.next.from===g+f.option.indent&&(g+=f.option.indent));while(f.tokens.next.id!=="(end)"){while(f.tokens.next.id===","){if(!f.option.elision){if(!!f.inES5()){F("W128");do V(",");while(f.tokens.next.id===",");continue}F("W070")}V(",")}if(f.tokens.next.id==="]")break;this.first.push(Q(10));if(f.tokens.next.id!==",")break;tt({allowTrailing:!0});if(f.tokens.next.id==="]"&&!f.inES5()){F("W070",f.tokens.curr);break}}return t&&(g-=f.option.indent),V("]",this),this}),function(e){e.nud=function(){var e,t,n,r,i,s=!1,o,u=Object.create(null);e=f.tokens.curr.line!==G(f.tokens.next),e&&(g+=f.option.indent,f.tokens.next.from===g+f.option.indent&&(g+=f.option.indent));var a=an();if(a.isDestAssign)return this.destructAssign=Gt({openingParsed:!0,assignment:!0}),this;for(;;){if(f.tokens.next.id==="}")break;o=f.tokens.next.value;if(!f.tokens.next.identifier||X().id!==","&&X().id!=="}")if(W().id===":"||o!=="get"&&o!=="set"){f.tokens.next.value==="*"&&f.tokens.next.type==="(punctuator)"?(f.inES6()||F("W104",f.tokens.next,"generator functions","6"),V("*"),s=!0):s=!1;if(f.tokens.next.id==="[")n=cn(),f.nameStack.set(n);else{f.nameStack.set(f.tokens.next),n=It(),fn(u,n,f.tokens.next);if(typeof n!="string")break}f.tokens.next.value==="("?(f.inES6()||F("W104",f.tokens.curr,"concise methods","6"),Xt({type:s?"generator":null})):(V(":"),Q(10))}else V(o),f.inES5()||q("E034"),n=It(),!n&&!f.inES6()&&q("E035"),n&&ln(o,u,n,f.tokens.curr),i=f.tokens.next,t=Xt(),r=t["(params)"],o==="get"&&n&&r?F("W076",i,r[0],n):o==="set"&&n&&(!r||r.length!==1)&&F("W077",i,n);else f.inES6()||F("W104",f.tokens.next,"object short notation","6"),n=It(!0),fn(u,n,f.tokens.next),Q(10);Dt(n);if(f.tokens.next.id!==",")break;tt({allowTrailing:!0,property:!0}),f.tokens.next.id===","?F("W070",f.tokens.curr):f.tokens.next.id==="}"&&!f.inES5()&&F("W070",f.tokens.curr)}return e&&(g-=f.option.indent),V("}",this),Kt(u),this},e.fud=function(){q("E036",f.tokens.curr)}}(rt("{"));var tn=it("const",function(e){return en("const",this,e)});tn.exps=!0;var nn=it("let",function(e){return en("let",this,e)});nn.exps=!0;var rn=it("var",function(e){var t=e&&e.prefix,n=e&&e.inexport,i,o,u,a=e&&e.implied,l=!e||!e.ignore;this.first=[];for(;;){var c=[];r.contains(["{","["],f.tokens.next.value)?(i=Gt(),o=!1):(i=[{id:Ct(),token:f.tokens.curr}],o=!0),(!t||!a)&&l&&f.option.varstmt&&F("W132",this),this.first=this.first.concat(c);for(var h in i)i.hasOwnProperty(h)&&(h=i[h],!a&&f.funct["(global)"]&&(S[h.id]===!1?F("W079",h.token,h.id):f.option.futurehostile===!1&&(!f.inES5()&&s.ecmaIdentifiers[5][h.id]===!1||!f.inES6()&&s.ecmaIdentifiers[6][h.id]===!1)&&F("W129",h.token,h.id)),h.id&&(a==="for"?(f.funct["(scope)"].has(h.id)||l&&F("W088",h.token,h.id),f.funct["(scope)"].block.use(h.id,h.token)):(f.funct["(scope)"].addlabel(h.id,{type:"var",token:h.token}),o&&n&&f.funct["(scope)"].setExported(h.id,h.token)),c.push(h.token)));f.tokens.next.id==="="&&(f.nameStack.set(f.tokens.curr),V("="),!t&&l&&!f.funct["(loopage)"]&&f.tokens.next.id==="undefined"&&F("W080",f.tokens.prev,f.tokens.prev.value),W(0).id==="="&&f.tokens.next.identifier&&(!t&&l&&!f.funct["(params)"]||f.funct["(params)"].indexOf(f.tokens.next.value)===-1)&&F("W120",f.tokens.next,f.tokens.next.value),u=Q(t?120:10),o?i[0].first=u:Zt(c,u));if(f.tokens.next.id!==",")break;tt()}return this});rn.exps=!0,st("class",function(){return sn.call(this,!0)}),st("function",function(e){var t=e&&e.inexport,n=!1;f.tokens.next.value==="*"&&(V("*"),f.inES6({strict:!0})?n=!0:F("W119",f.tokens.curr,"function*","6")),m&&F("W082",f.tokens.curr);var r=Nt();return f.funct["(scope)"].addlabel(r,{type:"function",token:f.tokens.curr}),r===undefined?F("W025"):t&&f.funct["(scope)"].setExported(r,f.tokens.prev),Xt({name:r,statement:this,type:n?"generator":null,ignoreLoopFunc:m}),f.tokens.next.id==="("&&f.tokens.next.line===f.tokens.curr.line&&q("E039"),this}),ut("function",function(){var e=!1;f.tokens.next.value==="*"&&(f.inES6()||F("W119",f.tokens.curr,"function*","6"),V("*"),e=!0);var t=Nt();return Xt({name:t,type:e?"generator":null}),this}),st("if",function(){var e=f.tokens.next;$t(),f.condition=!0,V("(");var t=Q(0);Jt(t);var n=null;f.option.forin&&f.forinifcheckneeded&&(f.forinifcheckneeded=!1,n=f.forinifchecks[f.forinifchecks.length-1],t.type==="(punctuator)"&&t.value==="!"?n.type="(negative)":n.type="(positive)"),V(")",e),f.condition=!1;var r=_t(!0,!0);return n&&n.type==="(negative)"&&r&&r[0]&&r[0].type==="(identifier)"&&r[0].value==="continue"&&(n.type="(negative-with-continue)"),f.tokens.next.id==="else"&&(V("else"),f.tokens.next.id==="if"||f.tokens.next.id==="switch"?At():_t(!0,!0)),this}),st("try",function(){function t(){V("catch"),V("("),f.funct["(scope)"].stack("catchparams");if(hn(f.tokens.next,["[","{"])){var e=Gt();r.each(e,function(e){e.id&&f.funct["(scope)"].addParam(e.id,e,"exception")})}else f.tokens.next.type!=="(identifier)"?F("E030",f.tokens.next,f.tokens.next.value):f.funct["(scope)"].addParam(Ct(),f.tokens.curr,"exception");f.tokens.next.value==="if"&&(f.inMoz()||F("W118",f.tokens.curr,"catch filter"),V("if"),Q(0)),V(")"),_t(!1),f.funct["(scope)"].unstack()}var e;_t(!0);while(f.tokens.next.id==="catch")$t(),e&&!f.inMoz()&&F("W118",f.tokens.next,"multiple catch blocks"),t(),e=!0;if(f.tokens.next.id==="finally"){V("finally"),_t(!0);return}return e||q("E021",f.tokens.next,"catch",f.tokens.next.value),this}),st("while",function(){var e=f.tokens.next;return f.funct["(breakage)"]+=1,f.funct["(loopage)"]+=1,$t(),V("("),Jt(Q(0)),V(")",e),_t(!0,!0),f.funct["(breakage)"]-=1,f.funct["(loopage)"]-=1,this}).labelled=!0,st("with",function(){var e=f.tokens.next;return f.isStrict()?q("E010",f.tokens.curr):f.option.withstmt||F("W085",f.tokens.curr),V("("),Q(0),V(")",e),_t(!0,!0),this}),st("switch",function(){var e=f.tokens.next,t=!1,n=!1;f.funct["(breakage)"]+=1,V("("),Jt(Q(0)),V(")",e),e=f.tokens.next,V("{"),f.tokens.next.from===g&&(n=!0),n||(g+=f.option.indent),this.cases=[];for(;;)switch(f.tokens.next.id){case"case":switch(f.funct["(verb)"]){case"yield":case"break":case"case":case"continue":case"return":case"switch":case"throw":break;default:f.tokens.curr.caseFallsThrough||F("W086",f.tokens.curr,"case")}V("case"),this.cases.push(Q(0)),$t(),t=!0,V(":"),f.funct["(verb)"]="case";break;case"default":switch(f.funct["(verb)"]){case"yield":case"break":case"continue":case"return":case"throw":break;default:this.cases.length&&(f.tokens.curr.caseFallsThrough||F("W086",f.tokens.curr,"default"))}V("default"),t=!0,V(":");break;case"}":n||(g-=f.option.indent),V("}",e),f.funct["(breakage)"]-=1,f.funct["(verb)"]=undefined;return;case"(end)":q("E023",f.tokens.next,"}");return;default:g+=f.option.indent;if(t)switch(f.tokens.curr.id){case",":q("E040");return;case":":t=!1,Ot();break;default:q("E025",f.tokens.curr);return}else{if(f.tokens.curr.id!==":"){q("E021",f.tokens.next,"case",f.tokens.next.value);return}V(":"),q("E024",f.tokens.curr,":"),Ot()}g-=f.option.indent}return this}).labelled=!0,it("debugger",function(){return f.option.debug||F("W087",this),this}).exps=!0,function(){var e=it("do",function(){f.funct["(breakage)"]+=1,f.funct["(loopage)"]+=1,$t(),this.first=_t(!0,!0),V("while");var e=f.tokens.next;return V("("),Jt(Q(0)),V(")",e),f.funct["(breakage)"]-=1,f.funct["(loopage)"]-=1,this});e.labelled=!0,e.exps=!0}(),st("for",function(){var e,t=f.tokens.next,n=!1,i=null;t.value==="each"&&(i=t,V("each"),f.inMoz()||F("W118",f.tokens.curr,"for each")),$t(),V("(");var s,o=0,u=["in","of"],a=0,l,c;hn(f.tokens.next,["{","["])&&++a;do{s=W(o),++o,hn(s,["{","["])?++a:hn(s,["}","]"])&&--a;if(a<0)break;a===0&&(!l&&pn(s,",")?l=s:!c&&pn(s,"=")&&(c=s))}while(a>0||!r.contains(u,s.value)&&s.value!==";"&&s.type!=="(end)");if(r.contains(u,s.value)){!f.inES6()&&s.value==="of"&&F("W104",s,"for of","6");var h=!c&&!l;c&&q("W133",l,s.value,"initializer is forbidden"),l&&q("W133",l,s.value,"more than one ForBinding"),f.tokens.next.id==="var"?(V("var"),f.tokens.curr.fud({prefix:!0})):f.tokens.next.id==="let"||f.tokens.next.id==="const"?(V(f.tokens.next.id),n=!0,f.funct["(scope)"].stack(),f.tokens.curr.fud({prefix:!0})):Object.create(rn).fud({prefix:!0,implied:"for",ignore:!h}),V(s.value),Q(20),V(")",t),s.value==="in"&&f.option.forin&&(f.forinifcheckneeded=!0,f.forinifchecks===undefined&&(f.forinifchecks=[]),f.forinifchecks.push({type:"(none)"})),f.funct["(breakage)"]+=1,f.funct["(loopage)"]+=1,e=_t(!0,!0);if(s.value==="in"&&f.option.forin){if(f.forinifchecks&&f.forinifchecks.length>0){var p=f.forinifchecks.pop();(e&&e.length>0&&(typeof e[0]!="object"||e[0].value!=="if")||p.type==="(positive)"&&e.length>1||p.type==="(negative)")&&F("W089",this)}f.forinifcheckneeded=!1}f.funct["(breakage)"]-=1,f.funct["(loopage)"]-=1}else{i&&q("E045",i);if(f.tokens.next.id!==";")if(f.tokens.next.id==="var")V("var"),f.tokens.curr.fud();else if(f.tokens.next.id==="let")V("let"),n=!0,f.funct["(scope)"].stack(),f.tokens.curr.fud();else for(;;){Q(0,"for");if(f.tokens.next.id!==",")break;l()}Z(f.tokens.curr),V(";"),f.funct["(loopage)"]+=1,f.tokens.next.id!==";"&&Jt(Q(0)),Z(f.tokens.curr),V(";"),f.tokens.next.id===";"&&q("E021",f.tokens.next,")",";");if(f.tokens.next.id!==")")for(;;){Q(0,"for");if(f.tokens.next.id!==",")break;l()}V(")",t),f.funct["(breakage)"]+=1,_t(!0,!0),f.funct["(breakage)"]-=1,f.funct["(loopage)"]-=1}return n&&f.funct["(scope)"].unstack(),this}).labelled=!0,it("break",function(){var e=f.tokens.next.value;return f.option.asi||Z(this),f.tokens.next.id!==";"&&!f.tokens.next.reach&&f.tokens.curr.line===G(f.tokens.next)?(f.funct["(scope)"].funct.hasBreakLabel(e)||F("W090",f.tokens.next,e),this.first=f.tokens.next,V()):f.funct["(breakage)"]===0&&F("W052",f.tokens.next,this.value),kt(this),this}).exps=!0,it("continue",function(){var e=f.tokens.next.value;return f.funct["(breakage)"]===0&&F("W052",f.tokens.next,this.value),f.funct["(loopage)"]||F("W052",f.tokens.next,this.value),f.option.asi||Z(this),f.tokens.next.id!==";"&&!f.tokens.next.reach&&f.tokens.curr.line===G(f.tokens.next)&&(f.funct["(scope)"].funct.hasBreakLabel(e)||F("W090",f.tokens.next,e),this.first=f.tokens.next,V()),kt(this),this}).exps=!0,it("return",function(){return this.line===G(f.tokens.next)?f.tokens.next.id!==";"&&!f.tokens.next.reach&&(this.first=Q(0),this.first&&this.first.type==="(punctuator)"&&this.first.value==="="&&!this.first.paren&&!f.option.boss&&I("W093",this.first.line,this.first.character)):f.tokens.next.type==="(punctuator)"&&["[","{","+","-"].indexOf(f.tokens.next.value)>-1&&Z(this),kt(this),this}).exps=!0,function(e){e.exps=!0,e.lbp=25}(ut("yield",function(){var e=f.tokens.prev;f.inES6(!0)&&!f.funct["(generator)"]?("(catch)"!==f.funct["(name)"]||!f.funct["(context)"]["(generator)"])&&q("E046",f.tokens.curr,"yield"):f.inES6()||F("W104",f.tokens.curr,"yield","6"),f.funct["(generator)"]="yielded";var t=!1;f.tokens.next.value==="*"&&(t=!0,V("*"));if(this.line===G(f.tokens.next)||!f.inMoz()){if(t||f.tokens.next.id!==";"&&!f.option.asi&&!f.tokens.next.reach&&f.tokens.next.nud)Y(f.tokens.curr,f.tokens.next),this.first=Q(10),this.first.type==="(punctuator)"&&this.first.value==="="&&!this.first.paren&&!f.option.boss&&I("W093",this.first.line,this.first.character);f.inMoz()&&f.tokens.next.id!==")"&&(e.lbp>30||!e.assign&&!J()||e.id==="yield")&&q("E050",this)}else f.option.asi||Z(this);return this})),it("throw",function(){return Z(this),this.first=Q(20),kt(this),this}).exps=!0,it("import",function(){f.inES6()||F("W119",f.tokens.curr,"import","6");if(f.tokens.next.type==="(string)")return V("(string)"),this;if(f.tokens.next.identifier){this.name=Ct(),f.funct["(scope)"].addlabel(this.name,{type:"const",token:f.tokens.curr});if(f.tokens.next.value!==",")return V("from"),V("(string)"),this;V(",")}if(f.tokens.next.id==="*")V("*"),V("as"),f.tokens.next.identifier&&(this.name=Ct(),f.funct["(scope)"].addlabel(this.name,{type:"const",token:f.tokens.curr}));else{V("{");for(;;){if(f.tokens.next.value==="}"){V("}");break}var e;f.tokens.next.type==="default"?(e="default",V("default")):e=Ct(),f.tokens.next.value==="as"&&(V("as"),e=Ct()),f.funct["(scope)"].addlabel(e,{type:"const",token:f.tokens.curr});if(f.tokens.next.value!==","){if(f.tokens.next.value==="}"){V("}");break}q("E024",f.tokens.next,f.tokens.next.value);break}V(",")}}return V("from"),V("(string)"),this}).exps=!0,it("export",function(){var e=!0,t,n;f.inES6()||(F("W119",f.tokens.curr,"export","6"),e=!1),f.funct["(scope)"].block.isGlobal()||(q("E053",f.tokens.curr),e=!1);if(f.tokens.next.value==="*")return V("*"),V("from"),V("(string)"),this;if(f.tokens.next.type==="default"){f.nameStack.set(f.tokens.next),V("default");var r=f.tokens.next.id;if(r==="function"||r==="class")this.block=!0;return t=W(),Q(10),n=t.value,this.block&&(f.funct["(scope)"].addlabel(n,{type:r,token:t}),f.funct["(scope)"].setExported(n,t)),this}if(f.tokens.next.value==="{"){V("{");var i=[];for(;;){f.tokens.next.identifier||q("E030",f.tokens.next,f.tokens.next.value),V(),i.push(f.tokens.curr),f.tokens.next.value==="as"&&(V("as"),f.tokens.next.identifier||q("E030",f.tokens.next,f.tokens.next.value),V());if(f.tokens.next.value!==","){if(f.tokens.next.value==="}"){V("}");break}q("E024",f.tokens.next,f.tokens.next.value);break}V(",")}return f.tokens.next.value==="from"?(V("from"),V("(string)")):e&&i.forEach(function(e){f.funct["(scope)"].setExported(e.value,e)}),this}if(f.tokens.next.id==="var")V("var"),f.tokens.curr.fud({inexport:!0});else if(f.tokens.next.id==="let")V("let"),f.tokens.curr.fud({inexport:!0});else if(f.tokens.next.id==="const")V("const"),f.tokens.curr.fud({inexport:!0});else if(f.tokens.next.id==="function")this.block=!0,V("function"),f.syntax["function"].fud({inexport:!0});else if(f.tokens.next.id==="class"){this.block=!0,V("class");var s=f.tokens.next;f.syntax["class"].fud(),f.funct["(scope)"].setExported(s.value,s)}else q("E024",f.tokens.next,f.tokens.next.value);return this}).exps=!0,lt("abstract"),lt("boolean"),lt("byte"),lt("char"),lt("class",{es5:!0,nud:sn}),lt("double"),lt("enum",{es5:!0}),lt("export",{es5:!0}),lt("extends",{es5:!0}),lt("final"),lt("float"),lt("goto"),lt("implements",{es5:!0,strictOnly:!0}),lt("import",{es5:!0}),lt("int"),lt("interface",{es5:!0,strictOnly:!0}),lt("long"),lt("native"),lt("package",{es5:!0,strictOnly:!0}),lt("private",{es5:!0,strictOnly:!0}),lt("protected",{es5:!0,strictOnly:!0}),lt("public",{es5:!0,strictOnly:!0}),lt("short"),lt("static",{es5:!0,strictOnly:!0}),lt("super",{es5:!0}),lt("synchronized"),lt("transient"),lt("volatile");var an=function(){var e,t,n,r=-1,i=0,s={};hn(f.tokens.curr,["[","{"])&&(i+=1);do{n=r===-1?f.tokens.curr:e,e=r===-1?f.tokens.next:W(r),t=W(r+1),r+=1,hn(e,["[","{"])?i+=1:hn(e,["]","}"])&&(i-=1);if(i===1&&e.identifier&&e.value==="for"&&!pn(n,".")){s.isCompArray=!0,s.notJson=!0;break}if(i===0&&hn(e,["}","]"])){if(t.value==="="){s.isDestAssign=!0,s.notJson=!0;break}if(t.value==="."){s.notJson=!0;break}}pn(e,";")&&(s.isBlock=!0,s.notJson=!0)}while(i>0&&e.id!=="(end)");return s},vn=function(){function i(e){var t=n.variables.filter(function(t){if(t.value===e)return t.undef=!1,e}).length;return t!==0}function s(e){var t=n.variables.filter(function(t){if(t.value===e&&!t.undef)return t.unused===!0&&(t.unused=!1),e}).length;return t===0}var e=function(){this.mode="use",this.variables=[]},t=[],n;return{stack:function(){n=new e,t.push(n)},unstack:function(){n.variables.filter(function(e){e.unused&&F("W098",e.token,e.raw_text||e.value),e.undef&&f.funct["(scope)"].block.use(e.value,e.token)}),t.splice(-1,1),n=t[t.length-1]},setState:function(e){r.contains(["use","define","generate","filter"],e)&&(n.mode=e)},check:function(e){if(!n)return;return n&&n.mode==="use"?(s(e)&&n.variables.push({funct:f.funct,token:f.tokens.curr,value:e,undef:!0,unused:!1}),!0):n&&n.mode==="define"?(i(e)||n.variables.push({funct:f.funct,token:f.tokens.curr,value:e,undef:!1,unused:!0}),!0):n&&n.mode==="generate"?(f.funct["(scope)"].block.use(e,f.tokens.curr),!0):n&&n.mode==="filter"?(s(e)&&f.funct["(scope)"].block.use(e,f.tokens.curr),!0):!1}}},gn=function(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")},yn=function(t,i,o){function U(e,t){if(!e)return;!Array.isArray(e)&&typeof e=="object"&&(e=Object.keys(e)),e.forEach(t)}var a,l,c,d,A,O,M={},P={};i=r.clone(i),f.reset(),i&&i.scope?p.scope=i.scope:(p.errors=[],p.undefs=[],p.internals=[],p.blacklist={},p.scope="(main)"),S=Object.create(null),D(S,s.ecmaIdentifiers[3]),D(S,s.reservedVars),D(S,o||{}),n=Object.create(null);var j=Object.create(null);if(i){U(i.predef||null,function(e){var t,n;e[0]==="-"?(t=e.slice(1),p.blacklist[t]=t,delete S[t]):(n=Object.getOwnPropertyDescriptor(i.predef,e),S[e]=n?n.value:!1)}),U(i.exported||null,function(e){j[e]=!0}),delete i.predef,delete i.exported,O=Object.keys(i);for(c=0;c<O.length;c++)if(/^-W\d{3}$/g.test(O[c]))P[O[c].slice(1)]=!0;else{var z=O[c];M[z]=i[z],(z==="esversion"&&i[z]===5||z==="es5"&&i[z])&&F("I003"),O[c]==="newcap"&&i[z]===!1&&(M["(explicitNewcap)"]=!0)}}f.option=M,f.ignored=P,f.option.indent=f.option.indent||4,f.option.maxerr=f.option.maxerr||50,g=1;var W=h(f,S,j,n);W.on("warning",function(e){F.apply(null,[e.code,e.token].concat(e.data))}),W.on("error",function(e){q.apply(null,[e.code,e.token].concat(e.data))}),f.funct=Rt("(global)",null,{"(global)":!0,"(scope)":W,"(comparray)":vn(),"(metrics)":Vt(f.tokens.next)}),v=[f.funct],T=[],x=null,w={},E=null,m=!1,y=[];if(!L(t)&&!Array.isArray(t))return R("E004",0),!1;e={get isJSON(){return f.jsonMode},getOption:function(e){return f.option[e]||null},getCache:function(e){return f.cache[e]},setCache:function(e,t){f.cache[e]=t},warn:function(e,t){I.apply(null,[e,t.line,t.char].concat(t.data))},on:function(e,t){e.split(" ").forEach(function(e){C.on(e,t)}.bind(this))}},C.removeAllListeners(),(N||[]).forEach(function(t){t(e)}),f.tokens.prev=f.tokens.curr=f.tokens.next=f.syntax["(begin)"],i&&i.ignoreDelimiters&&(Array.isArray(i.ignoreDelimiters)||(i.ignoreDelimiters=[i.ignoreDelimiters]),i.ignoreDelimiters.forEach(function(e){if(!e.start||!e.end)return;d=gn(e.start)+"[\\s\\S]*?"+gn(e.end),A=new RegExp(d,"ig"),t=t.replace(A,function(e){return e.replace(/./g," ")})})),b=new u(t),b.on("warning",function(e){I.apply(null,[e.code,e.line,e.character].concat(e.data))}),b.on("error",function(e){R.apply(null,[e.code,e.line,e.character].concat(e.data))}),b.on("fatal",function(e){B("E041",e.line,e.from)}),b.on("Identifier",function(e){C.emit("Identifier",e)}),b.on("String",function(e){C.emit("String",e)}),b.on("Number",function(e){C.emit("Number",e)}),b.start();for(var X in i)r.has(i,X)&&k(X,f.tokens.curr);H(),D(S,o||{}),tt.first=!0;try{V();switch(f.tokens.next.id){case"{":case"[":dn();break;default:Mt(),f.directive["use strict"]&&f.option.strict!=="global"&&F("W097",f.tokens.prev),Ot()}f.tokens.next.id!=="(end)"&&B("E041",f.tokens.curr.line),f.funct["(scope)"].unstack()}catch($){if(!$||$.name!=="JSHintError")throw $;var J=f.tokens.next||{};p.errors.push({scope:"(main)",raw:$.raw,code:$.code,reason:$.message,line:$.line||J.line,character:$.character||J.from},null)}if(p.scope==="(main)"){i=i||{};for(a=0;a<p.internals.length;a+=1)l=p.internals[a],i.scope=l.elem,yn(l.value,i,o)}return p.errors.length===0};return yn.addModule=function(e){N.push(e)},yn.addModule(l.register),yn.data=function(){var e={functions:[],options:f.option},t,n,r,i,s,o;yn.errors.length&&(e.errors=yn.errors),f.jsonMode&&(e.json=!0);var u=f.funct["(scope)"].getImpliedGlobals();u.length>0&&(e.implieds=u),T.length>0&&(e.urls=T),o=f.funct["(scope)"].getUsedOrDefinedGlobals(),o.length>0&&(e.globals=o);for(r=1;r<v.length;r+=1){n=v[r],t={};for(i=0;i<d.length;i+=1)t[d[i]]=[];for(i=0;i<d.length;i+=1)t[d[i]].length===0&&delete t[d[i]];t.name=n["(name)"],t.param=n["(params)"],t.line=n["(line)"],t.character=n["(character)"],t.last=n["(last)"],t.lastcharacter=n["(lastcharacter)"],t.metrics={complexity:n["(metrics)"].ComplexityCount,parameters:n["(metrics)"].arity,statements:n["(metrics)"].statementCount},e.functions.push(t)}var a=f.funct["(scope)"].getUnuseds();a.length>0&&(e.unused=a);for(s in w)if(typeof w[s]=="number"){e.member=w;break}return e},yn.jshint=yn,yn}();typeof n=="object"&&n&&(n.JSHINT=p)},{"../lodash":"/node_modules/jshint/lodash.js","./lex.js":"/node_modules/jshint/src/lex.js","./messages.js":"/node_modules/jshint/src/messages.js","./options.js":"/node_modules/jshint/src/options.js","./reg.js":"/node_modules/jshint/src/reg.js","./scope-manager.js":"/node_modules/jshint/src/scope-manager.js","./state.js":"/node_modules/jshint/src/state.js","./style.js":"/node_modules/jshint/src/style.js","./vars.js":"/node_modules/jshint/src/vars.js",events:"/node_modules/browserify/node_modules/events/events.js"}],"/node_modules/jshint/src/lex.js":[function(e,t,n){"use strict";function h(){var e=[];return{push:function(t){e.push(t)},check:function(){for(var t=0;t<e.length;++t)e[t]();e.splice(0,e.length)}}}function p(e){var t=e;typeof t=="string"&&(t=t.replace(/\r\n/g,"\n").replace(/\r/g,"\n").split("\n")),t[0]&&t[0].substr(0,2)==="#!"&&(t[0].indexOf("node")!==-1&&(o.option.node=!0),t[0]=""),this.emitter=new i.EventEmitter,this.source=e,this.setLines(t),this.prereg=!0,this.line=0,this.char=1,this.from=1,this.input="",this.inComment=!1,this.context=[],this.templateStarts=[];for(var n=0;n<o.option.indent;n+=1)o.tab+=" ";this.ignoreLinterErrors=!1}var r=e("../lodash"),i=e("events"),s=e("./reg.js"),o=e("./state.js").state,u=e("../data/ascii-identifier-data.js"),a=u.asciiIdentifierStartTable,f=u.asciiIdentifierPartTable,l={Identifier:1,Punctuator:2,NumericLiteral:3,StringLiteral:4,Comment:5,Keyword:6,NullLiteral:7,BooleanLiteral:8,RegExp:9,TemplateHead:10,TemplateMiddle:11,TemplateTail:12,NoSubstTemplate:13},c={Block:1,Template:2};p.prototype={_lines:[],inContext:function(e){return this.context.length>0&&this.context[this.context.length-1].type===e},pushContext:function(e){this.context.push({type:e})},popContext:function(){return this.context.pop()},isContext:function(e){return this.context.length>0&&this.context[this.context.length-1]===e},currentContext:function(){return this.context.length>0&&this.context[this.context.length-1]},getLines:function(){return this._lines=o.lines,this._lines},setLines:function(e){this._lines=e,o.lines=this._lines},peek:function(e){return this.input.charAt(e||0)},skip:function(e){e=e||1,this.char+=e,this.input=this.input.slice(e)},on:function(e,t){e.split(" ").forEach(function(e){this.emitter.on(e,t)}.bind(this))},trigger:function(){this.emitter.emit.apply(this.emitter,Array.prototype.slice.call(arguments))},triggerAsync:function(e,t,n,r){n.push(function(){r()&&this.trigger(e,t)}.bind(this))},scanPunctuator:function(){var e=this.peek(),t,n,r;switch(e){case".":if(/^[0-9]$/.test(this.peek(1)))return null;if(this.peek(1)==="."&&this.peek(2)===".")return{type:l.Punctuator,value:"..."};case"(":case")":case";":case",":case"[":case"]":case":":case"~":case"?":return{type:l.Punctuator,value:e};case"{":return this.pushContext(c.Block),{type:l.Punctuator,value:e};case"}":return this.inContext(c.Block)&&this.popContext(),{type:l.Punctuator,value:e};case"#":return{type:l.Punctuator,value:e};case"":return null}return t=this.peek(1),n=this.peek(2),r=this.peek(3),e===">"&&t===">"&&n===">"&&r==="="?{type:l.Punctuator,value:">>>="}:e==="="&&t==="="&&n==="="?{type:l.Punctuator,value:"==="}:e==="!"&&t==="="&&n==="="?{type:l.Punctuator,value:"!=="}:e===">"&&t===">"&&n===">"?{type:l.Punctuator,value:">>>"}:e==="<"&&t==="<"&&n==="="?{type:l.Punctuator,value:"<<="}:e===">"&&t===">"&&n==="="?{type:l.Punctuator,value:">>="}:e==="="&&t===">"?{type:l.Punctuator,value:e+t}:e===t&&"+-<>&|".indexOf(e)>=0?{type:l.Punctuator,value:e+t}:"<>=!+-*%&|^".indexOf(e)>=0?t==="="?{type:l.Punctuator,value:e+t}:{type:l.Punctuator,value:e}:e==="/"?t==="="?{type:l.Punctuator,value:"/="}:{type:l.Punctuator,value:"/"}:null},scanComments:function(){function u(e,t,n){var r=["jshint","jslint","members","member","globals","global","exported"],i=!1,u=e+t,a="plain";return n=n||{},n.isMultiline&&(u+="*/"),t=t.replace(/\n/g," "),e==="/*"&&s.fallsThrough.test(t)&&(i=!0,a="falls through"),r.forEach(function(n){if(i)return;if(e==="//"&&n!=="jshint")return;t.charAt(n.length)===" "&&t.substr(0,n.length)===n&&(i=!0,e+=n,t=t.substr(n.length)),!i&&t.charAt(0)===" "&&t.charAt(n.length+1)===" "&&t.substr(1,n.length)===n&&(i=!0,e=e+" "+n,t=t.substr(n.length+1));if(!i)return;switch(n){case"member":a="members";break;case"global":a="globals";break;default:var r=t.split(":").map(function(e){return e.replace(/^\s+/,"").replace(/\s+$/,"")});if(r.length===2)switch(r[0]){case"ignore":switch(r[1]){case"start":o.ignoringLinterErrors=!0,i=!1;break;case"end":o.ignoringLinterErrors=!1,i=!1}}a=n}}),{type:l.Comment,commentType:a,value:u,body:t,isSpecial:i,isMultiline:n.isMultiline||!1,isMalformed:n.isMalformed||!1}}var e=this.peek(),t=this.peek(1),n=this.input.substr(2),r=this.line,i=this.char,o=this;if(e==="*"&&t==="/")return this.trigger("error",{code:"E018",line:r,character:i}),this.skip(2),null;if(e!=="/"||t!=="*"&&t!=="/")return null;if(t==="/")return this.skip(this.input.length),u("//",n);var a="";if(t==="*"){this.inComment=!0,this.skip(2);while(this.peek()!=="*"||this.peek(1)!=="/")if(this.peek()===""){a+="\n";if(!this.nextLine())return this.trigger("error",{code:"E017",line:r,character:i}),this.inComment=!1,u("/*",a,{isMultiline:!0,isMalformed:!0})}else a+=this.peek(),this.skip();return this.skip(2),this.inComment=!1,u("/*",a,{isMultiline:!0})}},scanKeyword:function(){var e=/^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input),t=["if","in","do","var","for","new","try","let","this","else","case","void","with","enum","while","break","catch","throw","const","yield","class","super","return","typeof","delete","switch","export","import","default","finally","extends","function","continue","debugger","instanceof"];return e&&t.indexOf(e[0])>=0?{type:l.Keyword,value:e[0]}:null},scanIdentifier:function(){function i(e){return e>256}function s(e){return e>256}function o(e){return/^[0-9a-fA-F]$/.test(e)}function p(e){return e.replace(/\\u([0-9a-fA-F]{4})/g,function(e,t){return String.fromCharCode(parseInt(t,16))})}var e="",t=0,n,r,u=function(){t+=1;if(this.peek(t)!=="u")return null;var e=this.peek(t+1),n=this.peek(t+2),r=this.peek(t+3),i=this.peek(t+4),u;return o(e)&&o(n)&&o(r)&&o(i)?(u=parseInt(e+n+r+i,16),f[u]||s(u)?(t+=5,"\\u"+e+n+r+i):null):null}.bind(this),c=function(){var e=this.peek(t),n=e.charCodeAt(0);return n===92?u():n<128?a[n]?(t+=1,e):null:i(n)?(t+=1,e):null}.bind(this),h=function(){var e=this.peek(t),n=e.charCodeAt(0);return n===92?u():n<128?f[n]?(t+=1,e):null:s(n)?(t+=1,e):null}.bind(this);r=c();if(r===null)return null;e=r;for(;;){r=h();if(r===null)break;e+=r}switch(e){case"true":case"false":n=l.BooleanLiteral;break;case"null":n=l.NullLiteral;break;default:n=l.Identifier}return{type:n,value:p(e),text:e,tokenLength:e.length}},scanNumericLiteral:function(){function f(e){return/^[0-9]$/.test(e)}function c(e){return/^[0-7]$/.test(e)}function h(e){return/^[01]$/.test(e)}function p(e){return/^[0-9a-fA-F]$/.test(e)}function d(e){return e==="$"||e==="_"||e==="\\"||e>="a"&&e<="z"||e>="A"&&e<="Z"}var e=0,t="",n=this.input.length,r=this.peek(e),i,s=f,u=10,a=!1;if(r!=="."&&!f(r))return null;if(r!=="."){t=this.peek(e),e+=1,r=this.peek(e);if(t==="0"){if(r==="x"||r==="X")s=p,u=16,e+=1,t+=r;if(r==="o"||r==="O")s=c,u=8,o.inES6(!0)||this.trigger("warning",{code:"W119",line:this.line,character:this.char,data:["Octal integer literal","6"]}),e+=1,t+=r;if(r==="b"||r==="B")s=h,u=2,o.inES6(!0)||this.trigger("warning",{code:"W119",line:this.line,character:this.char,data:["Binary integer literal","6"]}),e+=1,t+=r;c(r)&&(s=c,u=8,a=!0,i=!1,e+=1,t+=r),!c(r)&&f(r)&&(e+=1,t+=r)}while(e<n){r=this.peek(e);if(a&&f(r))i=!0;else if(!s(r))break;t+=r,e+=1}if(s!==f){if(!a&&t.length<=2)return{type:l.NumericLiteral,value:t,isMalformed:!0};if(e<n){r=this.peek(e);if(d(r))return null}return{type:l.NumericLiteral,value:t,base:u,isLegacy:a,isMalformed:!1}}}if(r==="."){t+=r,e+=1;while(e<n){r=this.peek(e);if(!f(r))break;t+=r,e+=1}}if(r==="e"||r==="E"){t+=r,e+=1,r=this.peek(e);if(r==="+"||r==="-")t+=this.peek(e),e+=1;r=this.peek(e);if(!f(r))return null;t+=r,e+=1;while(e<n){r=this.peek(e);if(!f(r))break;t+=r,e+=1}}if(e<n){r=this.peek(e);if(d(r))return null}return{type:l.NumericLiteral,value:t,base:u,isMalformed:!isFinite(t)}},scanEscapeSequence:function(e){var t=!1,n=1;this.skip();var r=this.peek();switch(r){case"'":this.triggerAsync("warning",{code:"W114",line:this.line,character:this.char,data:["\\'"]},e,function(){return o.jsonMode});break;case"b":r="\\b";break;case"f":r="\\f";break;case"n":r="\\n";break;case"r":r="\\r";break;case"t":r="\\t";break;case"0":r="\\0";var i=parseInt(this.peek(1),10);this.triggerAsync("warning",{code:"W115",line:this.line,character:this.char},e,function(){return i>=0&&i<=7&&o.isStrict()});break;case"u":var s=this.input.substr(1,4),u=parseInt(s,16);isNaN(u)&&this.trigger("warning",{code:"W052",line:this.line,character:this.char,data:["u"+s]}),r=String.fromCharCode(u),n=5;break;case"v":this.triggerAsync("warning",{code:"W114",line:this.line,character:this.char,data:["\\v"]},e,function(){return o.jsonMode}),r="\x0b";break;case"x":var a=parseInt(this.input.substr(1,2),16);this.triggerAsync("warning",{code:"W114",line:this.line,character:this.char,data:["\\x-"]},e,function(){return o.jsonMode}),r=String.fromCharCode(a),n=3;break;case"\\":r="\\\\";break;case'"':r='\\"';break;case"/":break;case"":t=!0,r=""}return{"char":r,jump:n,allowNewLine:t}},scanTemplateLiteral:function(e){var t,n="",r,i=this.line,s=this.char,u=this.templateStarts.length;if(!o.inES6(!0))return null;if(this.peek()==="`")t=l.TemplateHead,this.templateStarts.push({line:this.line,"char":this.char}),u=this.templateStarts.length,this.skip(1),this.pushContext(c.Template);else{if(!this.inContext(c.Template)||this.peek()!=="}")return null;t=l.TemplateMiddle}while(this.peek()!=="`"){while((r=this.peek())===""){n+="\n";if(!this.nextLine()){var a=this.templateStarts.pop();return this.trigger("error",{code:"E052",line:a.line,character:a.char}),{type:t,value:n,startLine:i,startChar:s,isUnclosed:!0,depth:u,context:this.popContext()}}}if(r==="$"&&this.peek(1)==="{")return n+="${",this.skip(2),{type:t,value:n,startLine:i,startChar:s,isUnclosed:!1,depth:u,context:this.currentContext()};if(r==="\\"){var f=this.scanEscapeSequence(e);n+=f.char,this.skip(f.jump)}else r!=="`"&&(n+=r,this.skip(1))}return t=t===l.TemplateHead?l.NoSubstTemplate:l.TemplateTail,this.skip(1),this.templateStarts.pop(),{type:t,value:n,startLine:i,startChar:s,isUnclosed:!1,depth:u,context:this.popContext()}},scanStringLiteral:function(e){var t=this.peek();if(t!=='"'&&t!=="'")return null;this.triggerAsync("warning",{code:"W108",line:this.line,character:this.char},e,function(){return o.jsonMode&&t!=='"'});var n="",r=this.line,i=this.char,s=!1;this.skip();while(this.peek()!==t)if(this.peek()===""){s?(s=!1,this.triggerAsync("warning",{code:"W043",line:this.line,character:this.char},e,function(){return!o.option.multistr}),this.triggerAsync("warning",{code:"W042",line:this.line,character:this.char},e,function(){return o.jsonMode&&o.option.multistr})):this.trigger("warning",{code:"W112",line:this.line,character:this.char});if(!this.nextLine())return this.trigger("error",{code:"E029",line:r,character:i}),{type:l.StringLiteral,value:n,startLine:r,startChar:i,isUnclosed:!0,quote:t}}else{s=!1;var u=this.peek(),a=1;u<" "&&this.trigger("warning",{code:"W113",line:this.line,character:this.char,data:["<non-printable>"]});if(u==="\\"){var f=this.scanEscapeSequence(e);u=f.char,a=f.jump,s=f.allowNewLine}n+=u,this.skip(a)}return this.skip(),{type:l.StringLiteral,value:n,startLine:r,startChar:i,isUnclosed:!1,quote:t}},scanRegExp:function(){var e=0,t=this.input.length,n=this.peek(),r=n,i="",s=[],o=!1,u=!1,a,f=function(){n<" "&&(o=!0,this.trigger("warning",{code:"W048",line:this.line,character:this.char})),n==="<"&&(o=!0,this.trigger("warning",{code:"W049",line:this.line,character:this.char,data:[n]}))}.bind(this);if(!this.prereg||n!=="/")return null;e+=1,a=!1;while(e<t){n=this.peek(e),r+=n,i+=n;if(u){n==="]"&&(this.peek(e-1)!=="\\"||this.peek(e-2)==="\\")&&(u=!1),n==="\\"&&(e+=1,n=this.peek(e),i+=n,r+=n,f()),e+=1;continue}if(n==="\\"){e+=1,n=this.peek(e),i+=n,r+=n,f();if(n==="/"){e+=1;continue}if(n==="["){e+=1;continue}}if(n==="["){u=!0,e+=1;continue}if(n==="/"){i=i.substr(0,i.length-1),a=!0,e+=1;break}e+=1}if(!a)return this.trigger("error",{code:"E015",line:this.line,character:this.from}),void this.trigger("fatal",{line:this.line,from:this.from});while(e<t){n=this.peek(e);if(!/[gim]/.test(n))break;s.push(n),r+=n,e+=1}try{new RegExp(i,s.join(""))}catch(c){o=!0,this.trigger("error",{code:"E016",line:this.line,character:this.char,data:[c.message]})}return{type:l.RegExp,value:r,flags:s,isMalformed:o}},scanNonBreakingSpaces:function(){return o.option.nonbsp?this.input.search(/(\u00A0)/):-1},scanUnsafeChars:function(){return this.input.search(s.unsafeChars)},next:function(e){this.from=this.char;var t;if(/\s/.test(this.peek())){t=this.char;while(/\s/.test(this.peek()))this.from+=1,this.skip()}var n=this.scanComments()||this.scanStringLiteral(e)||this.scanTemplateLiteral(e);return n?n:(n=this.scanRegExp()||this.scanPunctuator()||this.scanKeyword()||this.scanIdentifier()||this.scanNumericLiteral(),n?(this.skip(n.tokenLength||n.value.length),n):null)},nextLine:function(){var e;if(this.line>=this.getLines().length)return!1;this.input=this.getLines()[this.line],this.line+=1,this.char=1,this.from=1;var t=this.input.trim(),n=function(){return r.some(arguments,function(e){return t.indexOf(e)===0})},i=function(){return r.some(arguments,function(e){return t.indexOf(e,t.length-e.length)!==-1})};this.ignoringLinterErrors===!0&&!n("/*","//")&&(!this.inComment||!i("*/"))&&(this.input=""),e=this.scanNonBreakingSpaces(),e>=0&&this.trigger("warning",{code:"W125",line:this.line,character:e+1}),this.input=this.input.replace(/\t/g,o.tab),e=this.scanUnsafeChars(),e>=0&&this.trigger("warning",{code:"W100",line:this.line,character:e});if(!this.ignoringLinterErrors&&o.option.maxlen&&o.option.maxlen<this.input.length){var u=this.inComment||n.call(t,"//")||n.call(t,"/*"),a=!u||!s.maxlenException.test(t);a&&this.trigger("warning",{code:"W101",line:this.line,character:this.input.length})}return!0},start:function(){this.nextLine()},token:function(){function n(e,t){if(!e.reserved)return!1;var n=e.meta;if(n&&n.isFutureReservedWord&&o.inES5()){if(!n.es5)return!1;if(n.strictOnly&&!o.option.strict&&!o.isStrict())return!1;if(t)return!1}return!0}var e=h(),t,i=function(t,i,s,u){var a;t!=="(endline)"&&t!=="(end)"&&(this.prereg=!1);if(t==="(punctuator)"){switch(i){case".":case")":case"~":case"#":case"]":case"++":case"--":this.prereg=!1;break;default:this.prereg=!0}a=Object.create(o.syntax[i]||o.syntax["(error)"])}if(t==="(identifier)"){if(i==="return"||i==="case"||i==="typeof")this.prereg=!0;r.has(o.syntax,i)&&(a=Object.create(o.syntax[i]||o.syntax["(error)"]),n(a,s&&t==="(identifier)")||(a=null))}return a||(a=Object.create(o.syntax[t])),a.identifier=t==="(identifier)",a.type=a.type||t,a.value=i,a.line=this.line,a.character=this.char,a.from=this.from,a.identifier&&u&&(a.raw_text=u.text||u.value),u&&u.startLine&&u.startLine!==this.line&&(a.startLine=u.startLine),u&&u.context&&(a.context=u.context),u&&u.depth&&(a.depth=u.depth),u&&u.isUnclosed&&(a.isUnclosed=u.isUnclosed),s&&a.identifier&&(a.isProperty=s),a.check=e.check,a}.bind(this);for(;;){if(!this.input.length)return this.nextLine()?i("(endline)",""):this.exhausted?null:(this.exhausted=!0,i("(end)",""));t=this.next(e);if(!t){this.input.length&&(this.trigger("error",{code:"E024",line:this.line,character:this.char,data:[this.peek()]}),this.input="");continue}switch(t.type){case l.StringLiteral:return this.triggerAsync("String",{line:this.line,"char":this.char,from:this.from,startLine:t.startLine,startChar:t.startChar,value:t.value,quote:t.quote},e,function(){return!0}),i("(string)",t.value,null,t);case l.TemplateHead:return this.trigger("TemplateHead",{line:this.line,"char":this.char,from:this.from,startLine:t.startLine,startChar:t.startChar,value:t.value}),i("(template)",t.value,null,t);case l.TemplateMiddle:return this.trigger("TemplateMiddle",{line:this.line,"char":this.char,from:this.from,startLine:t.startLine,startChar:t.startChar,value:t.value}),i("(template middle)",t.value,null,t);case l.TemplateTail:return this.trigger("TemplateTail",{line:this.line,"char":this.char,from:this.from,startLine:t.startLine,startChar:t.startChar,value:t.value}),i("(template tail)",t.value,null,t);case l.NoSubstTemplate:return this.trigger("NoSubstTemplate",{line:this.line,"char":this.char,from:this.from,startLine:t.startLine,startChar:t.startChar,value:t.value}),i("(no subst template)",t.value,null,t);case l.Identifier:this.triggerAsync("Identifier",{line:this.line,"char":this.char,from:this.form,name:t.value,raw_name:t.text,isProperty:o.tokens.curr.id==="."},e,function(){return!0});case l.Keyword:case l.NullLiteral:case l.BooleanLiteral:return i("(identifier)",t.value,o.tokens.curr.id===".",t);case l.NumericLiteral:return t.isMalformed&&this.trigger("warning",{code:"W045",line:this.line,character:this.char,data:[t.value]}),this.triggerAsync("warning",{code:"W114",line:this.line,character:this.char,data:["0x-"]},e,function(){return t.base===16&&o.jsonMode}),this.triggerAsync("warning",{code:"W115",line:this.line,character:this.char},e,function(){return o.isStrict()&&t.base===8&&t.isLegacy}),this.trigger("Number",{line:this.line,"char":this.char,from:this.from,value:t.value,base:t.base,isMalformed:t.malformed}),i("(number)",t.value);case l.RegExp:return i("(regexp)",t.value);case l.Comment:o.tokens.curr.comment=!0;if(t.isSpecial)return{id:"(comment)",value:t.value,body:t.body,type:t.commentType,isSpecial:t.isSpecial,line:this.line,character:this.char,from:this.from};break;case"":break;default:return i("(punctuator)",t.value)}}}},n.Lexer=p,n.Context=c},{"../data/ascii-identifier-data.js":"/node_modules/jshint/data/ascii-identifier-data.js","../lodash":"/node_modules/jshint/lodash.js","./reg.js":"/node_modules/jshint/src/reg.js","./state.js":"/node_modules/jshint/src/state.js",events:"/node_modules/browserify/node_modules/events/events.js"}],"/node_modules/jshint/src/messages.js":[function(e,t,n){"use strict";var r=e("../lodash"),i={E001:"Bad option: '{a}'.",E002:"Bad option value.",E003:"Expected a JSON value.",E004:"Input is neither a string nor an array of strings.",E005:"Input is empty.",E006:"Unexpected early end of program.",E007:'Missing "use strict" statement.',E008:"Strict violation.",E009:"Option 'validthis' can't be used in a global scope.",E010:"'with' is not allowed in strict mode.",E011:"'{a}' has already been declared.",E012:"const '{a}' is initialized to 'undefined'.",E013:"Attempting to override '{a}' which is a constant.",E014:"A regular expression literal can be confused with '/='.",E015:"Unclosed regular expression.",E016:"Invalid regular expression.",E017:"Unclosed comment.",E018:"Unbegun comment.",E019:"Unmatched '{a}'.",E020:"Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",E021:"Expected '{a}' and instead saw '{b}'.",E022:"Line breaking error '{a}'.",E023:"Missing '{a}'.",E024:"Unexpected '{a}'.",E025:"Missing ':' on a case clause.",E026:"Missing '}' to match '{' from line {a}.",E027:"Missing ']' to match '[' from line {a}.",E028:"Illegal comma.",E029:"Unclosed string.",E030:"Expected an identifier and instead saw '{a}'.",E031:"Bad assignment.",E032:"Expected a small integer or 'false' and instead saw '{a}'.",E033:"Expected an operator and instead saw '{a}'.",E034:"get/set are ES5 features.",E035:"Missing property name.",E036:"Expected to see a statement and instead saw a block.",E037:null,E038:null,E039:"Function declarations are not invocable. Wrap the whole function invocation in parens.",E040:"Each value should have its own case label.",E041:"Unrecoverable syntax error.",E042:"Stopping.",E043:"Too many errors.",E044:null,E045:"Invalid for each loop.",E046:"A yield statement shall be within a generator function (with syntax: `function*`)",E047:null,E048:"{a} declaration not directly within block.",E049:"A {a} cannot be named '{b}'.",E050:"Mozilla requires the yield expression to be parenthesized here.",E051:null,E052:"Unclosed template literal.",E053:"Export declaration must be in global scope.",E054:"Class properties must be methods. Expected '(' but instead saw '{a}'.",E055:"The '{a}' option cannot be set after any executable code.",E056:"'{a}' was used before it was declared, which is illegal for '{b}' variables.",E057:"Invalid meta property: '{a}.{b}'.",E058:"Missing semicolon."},s={W001:"'hasOwnProperty' is a really bad name.",W002:"Value of '{a}' may be overwritten in IE 8 and earlier.",W003:"'{a}' was used before it was defined.",W004:"'{a}' is already defined.",W005:"A dot following a number can be confused with a decimal point.",W006:"Confusing minuses.",W007:"Confusing plusses.",W008:"A leading decimal point can be confused with a dot: '{a}'.",W009:"The array literal notation [] is preferable.",W010:"The object literal notation {} is preferable.",W011:null,W012:null,W013:null,W014:"Bad line breaking before '{a}'.",W015:null,W016:"Unexpected use of '{a}'.",W017:"Bad operand.",W018:"Confusing use of '{a}'.",W019:"Use the isNaN function to compare with NaN.",W020:"Read only.",W021:"Reassignment of '{a}', which is is a {b}. Use 'var' or 'let' to declare bindings that may change.",W022:"Do not assign to the exception parameter.",W023:"Expected an identifier in an assignment and instead saw a function invocation.",W024:"Expected an identifier and instead saw '{a}' (a reserved word).",W025:"Missing name in function declaration.",W026:"Inner functions should be listed at the top of the outer function.",W027:"Unreachable '{a}' after '{b}'.",W028:"Label '{a}' on {b} statement.",W030:"Expected an assignment or function call and instead saw an expression.",W031:"Do not use 'new' for side effects.",W032:"Unnecessary semicolon.",W033:"Missing semicolon.",W034:'Unnecessary directive "{a}".',W035:"Empty block.",W036:"Unexpected /*member '{a}'.",W037:"'{a}' is a statement label.",W038:"'{a}' used out of scope.",W039:"'{a}' is not allowed.",W040:"Possible strict violation.",W041:"Use '{a}' to compare with '{b}'.",W042:"Avoid EOL escaping.",W043:"Bad escaping of EOL. Use option multistr if needed.",W044:"Bad or unnecessary escaping.",W045:"Bad number '{a}'.",W046:"Don't use extra leading zeros '{a}'.",W047:"A trailing decimal point can be confused with a dot: '{a}'.",W048:"Unexpected control character in regular expression.",W049:"Unexpected escaped character '{a}' in regular expression.",W050:"JavaScript URL.",W051:"Variables should not be deleted.",W052:"Unexpected '{a}'.",W053:"Do not use {a} as a constructor.",W054:"The Function constructor is a form of eval.",W055:"A constructor name should start with an uppercase letter.",W056:"Bad constructor.",W057:"Weird construction. Is 'new' necessary?",W058:"Missing '()' invoking a constructor.",W059:"Avoid arguments.{a}.",W060:"document.write can be a form of eval.",W061:"eval can be harmful.",W062:"Wrap an immediate function invocation in parens to assist the reader in understanding that the expression is the result of a function, and not the function itself.",W063:"Math is not a function.",W064:"Missing 'new' prefix when invoking a constructor.",W065:"Missing radix parameter.",W066:"Implied eval. Consider passing a function instead of a string.",W067:"Bad invocation.",W068:"Wrapping non-IIFE function literals in parens is unnecessary.",W069:"['{a}'] is better written in dot notation.",W070:"Extra comma. (it breaks older versions of IE)",W071:"This function has too many statements. ({a})",W072:"This function has too many parameters. ({a})",W073:"Blocks are nested too deeply. ({a})",W074:"This function's cyclomatic complexity is too high. ({a})",W075:"Duplicate {a} '{b}'.",W076:"Unexpected parameter '{a}' in get {b} function.",W077:"Expected a single parameter in set {a} function.",W078:"Setter is defined without getter.",W079:"Redefinition of '{a}'.",W080:"It's not necessary to initialize '{a}' to 'undefined'.",W081:null,W082:"Function declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.",W083:"Don't make functions within a loop.",W084:"Assignment in conditional expression",W085:"Don't use 'with'.",W086:"Expected a 'break' statement before '{a}'.",W087:"Forgotten 'debugger' statement?",W088:"Creating global 'for' variable. Should be 'for (var {a} ...'.",W089:"The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.",W090:"'{a}' is not a statement label.",W091:null,W093:"Did you mean to return a conditional instead of an assignment?",W094:"Unexpected comma.",W095:"Expected a string and instead saw {a}.",W096:"The '{a}' key may produce unexpected results.",W097:'Use the function form of "use strict".',W098:"'{a}' is defined but never used.",W099:null,W100:"This character may get silently deleted by one or more browsers.",W101:"Line is too long.",W102:null,W103:"The '{a}' property is deprecated.",W104:"'{a}' is available in ES{b} (use 'esversion: {b}') or Mozilla JS extensions (use moz).",W105:"Unexpected {a} in '{b}'.",W106:"Identifier '{a}' is not in camel case.",W107:"Script URL.",W108:"Strings must use doublequote.",W109:"Strings must use singlequote.",W110:"Mixed double and single quotes.",W112:"Unclosed string.",W113:"Control character in string: {a}.",W114:"Avoid {a}.",W115:"Octal literals are not allowed in strict mode.",W116:"Expected '{a}' and instead saw '{b}'.",W117:"'{a}' is not defined.",W118:"'{a}' is only available in Mozilla JavaScript extensions (use moz option).",W119:"'{a}' is only available in ES{b} (use 'esversion: {b}').",W120:"You might be leaking a variable ({a}) here.",W121:"Extending prototype of native object: '{a}'.",W122:"Invalid typeof value '{a}'",W123:"'{a}' is already defined in outer scope.",W124:"A generator function shall contain a yield statement.",W125:"This line contains non-breaking spaces: http://jshint.com/doc/options/#nonbsp",W126:"Unnecessary grouping operator.",W127:"Unexpected use of a comma operator.",W128:"Empty array elements require elision=true.",W129:"'{a}' is defined in a future version of JavaScript. Use a different variable name to avoid migration issues.",W130:"Invalid element after rest element.",W131:"Invalid parameter after rest parameter.",W132:"`var` declarations are forbidden. Use `let` or `const` instead.",W133:"Invalid for-{a} loop left-hand-side: {b}.",W134:"The '{a}' option is only available when linting ECMAScript {b} code.",W135:"{a} may not be supported by non-browser environments.",W136:"'{a}' must be in function scope.",W137:"Empty destructuring.",W138:"Regular parameters should not come after default parameters."},o={I001:"Comma warnings can be turned off with 'laxcomma'.",I002:null,I003:"ES5 option is now set per default"};n.errors={},n.warnings={},n.info={},r.each(i,function(e,t){n.errors[t]={code:t,desc:e}}),r.each(s,function(e,t){n.warnings[t]={code:t,desc:e}}),r.each(o,function(e,t){n.info[t]={code:t,desc:e}})},{"../lodash":"/node_modules/jshint/lodash.js"}],"/node_modules/jshint/src/name-stack.js":[function(e,t,n){"use strict";function r(){this._stack=[]}Object.defineProperty(r.prototype,"length",{get:function(){return this._stack.length}}),r.prototype.push=function(){this._stack.push(null)},r.prototype.pop=function(){this._stack.pop()},r.prototype.set=function(e){this._stack[this.length-1]=e},r.prototype.infer=function(){var e=this._stack[this.length-1],t="",n;if(!e||e.type==="class")e=this._stack[this.length-2];return e?(n=e.type,n!=="(string)"&&n!=="(number)"&&n!=="(identifier)"&&n!=="default"?"(expression)":(e.accessorType&&(t=e.accessorType+" "),t+e.value)):"(empty)"},t.exports=r},{}],"/node_modules/jshint/src/options.js":[function(e,t,n){"use strict";n.bool={enforcing:{bitwise:!0,freeze:!0,camelcase:!0,curly:!0,eqeqeq:!0,futurehostile:!0,notypeof:!0,es3:!0,es5:!0,forin:!0,funcscope:!0,immed:!0,iterator:!0,newcap:!0,noarg:!0,nocomma:!0,noempty:!0,nonbsp:!0,nonew:!0,undef:!0,singleGroups:!1,varstmt:!1,enforceall:!1},relaxing:{asi:!0,multistr:!0,debug:!0,boss:!0,evil:!0,globalstrict:!0,plusplus:!0,proto:!0,scripturl:!0,sub:!0,supernew:!0,laxbreak:!0,laxcomma:!0,validthis:!0,withstmt:!0,moz:!0,noyield:!0,eqnull:!0,lastsemic:!0,loopfunc:!0,expr:!0,esnext:!0,elision:!0},environments:{mootools:!0,couch:!0,jasmine:!0,jquery:!0,node:!0,qunit:!0,rhino:!0,shelljs:!0,prototypejs:!0,yui:!0,mocha:!0,module:!0,wsh:!0,worker:!0,nonstandard:!0,browser:!0,browserify:!0,devel:!0,dojo:!0,typed:!0,phantom:!0},obsolete:{onecase:!0,regexp:!0,regexdash:!0}},n.val={maxlen:!1,indent:!1,maxerr:!1,predef:!1,globals:!1,quotmark:!1,scope:!1,maxstatements:!1,maxdepth:!1,maxparams:!1,maxcomplexity:!1,shadow:!1,strict:!0,unused:!0,latedef:!1,ignore:!1,ignoreDelimiters:!1,esversion:5},n.inverted={bitwise:!0,forin:!0,newcap:!0,plusplus:!0,regexp:!0,undef:!0,eqeqeq:!0,strict:!0},n.validNames=Object.keys(n.val).concat(Object.keys(n.bool.relaxing)).concat(Object.keys(n.bool.enforcing)).concat(Object.keys(n.bool.obsolete)).concat(Object.keys(n.bool.environments)),n.renamed={eqeq:"eqeqeq",windows:"wsh",sloppy:"strict"},n.removed={nomen:!0,onevar:!0,passfail:!0,white:!0,gcl:!0,smarttabs:!0,trailing:!0},n.noenforceall={varstmt:!0,strict:!0}},{}],"/node_modules/jshint/src/reg.js":[function(e,t,n){"use strict";n.unsafeString=/@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i,n.unsafeChars=/[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,n.needEsc=/[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,n.needEscGlobal=/[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,n.starSlash=/\*\//,n.identifier=/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,n.javascriptURL=/^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i,n.fallsThrough=/^\s*falls?\sthrough\s*$/,n.maxlenException=/^(?:(?:\/\/|\/\*|\*) ?)?[^ ]+$/},{}],"/node_modules/jshint/src/scope-manager.js":[function(e,t,n){"use strict";var r=e("../lodash"),i=e("events"),s={},o=function(e,t,n,o){function f(e){u={"(labels)":Object.create(null),"(usages)":Object.create(null),"(breakLabels)":Object.create(null),"(parent)":u,"(type)":e,"(params)":e==="functionparams"||e==="catchparams"?[]:null},a.push(u)}function v(e,t){d.emit("warning",{code:e,token:t,data:r.slice(arguments,2)})}function m(e,t){d.emit("warning",{code:e,token:t,data:r.slice(arguments,2)})}function g(e){u["(usages)"][e]||(u["(usages)"][e]={"(modified)":[],"(reassigned)":[],"(tokens)":[]})}function w(){if(u["(type)"]==="functionparams"){E();return}var e=u["(labels)"];for(var t in e)e[t]&&e[t]["(type)"]!=="exception"&&e[t]["(unused)"]&&b(t,e[t]["(token)"],"var")}function E(){var t=u["(params)"];if(!t)return;var n=t.pop(),r;while(n){var i=u["(labels)"][n];r=y(e.funct["(unusedOption)"]);if(n==="undefined")return;if(i["(unused)"])b(n,i["(token)"],"param",e.funct["(unusedOption)"]);else if(r==="last-param")return;n=t.pop()}}function S(e){for(var t=a.length-1;t>=0;--t){var n=a[t]["(labels)"];if(n[e])return n}}function x(e){for(var t=a.length-1;t>=0;t--){var n=a[t];if(n["(usages)"][e])return n["(usages)"][e];if(n===l)break}return!1}function T(t,n){if(e.option.shadow!=="outer")return;var r=l["(type)"]==="global",i=u["(type)"]==="functionparams",s=!r;for(var o=0;o<a.length;o++){var f=a[o];!i&&a[o+1]===l&&(s=!1),s&&f["(labels)"][t]&&v("W123",n,t),f["(breakLabels)"][t]&&v("W123",n,t)}}function N(t,n,r){e.option.latedef&&(e.option.latedef===!0&&t==="function"||t!=="function")&&v("W003",r,n)}var u,a=[];f("global"),u["(predefined)"]=t;var l=u,c=Object.create(null),h=Object.create(null),p=[],d=new i.EventEmitter,y=function(t){return t===undefined&&(t=e.option.unused),t===!0&&(t="last-param"),t},b=function(e,t,n,r){var i=t.line,s=t.from,o=t.raw_text||e;r=y(r);var u={vars:["var"],"last-param":["var","param"],strict:["var","param","last-param"]};r&&u[r]&&u[r].indexOf(n)!==-1&&v("W098",{line:i,from:s},o),(r||n==="var")&&p.push({name:e,line:i,character:s})},C={on:function(e,t){e.split(" ").forEach(function(e){d.on(e,t)})},isPredefined:function(e){return!this.has(e)&&r.has(a[0]["(predefined)"],e)},stack:function(e){var t=u;f(e),!e&&t["(type)"]==="functionparams"&&(u["(isFuncBody)"]=!0,u["(context)"]=l,l=u)},unstack:function(){var t=a.length>1?a[a.length-2]:null,n=u===l,i=u["(type)"]==="functionparams",f=u["(type)"]==="functionouter",p,d,g=u["(usages)"],y=u["(labels)"],E=Object.keys(g);g.__proto__&&E.indexOf("__proto__")===-1&&E.push("__proto__");for(p=0;p<E.length;p++){var S=E[p],x=g[S],T=y[S];if(T){var N=T["(type)"];if(T["(useOutsideOfScope)"]&&!e.option.funcscope){var C=x["(tokens)"];if(C)for(d=0;d<C.length;d++)T["(function)"]===C[d]["(function)"]&&m("W038",C[d],S)}u["(labels)"][S]["(unused)"]=!1;if(N==="const"&&x["(modified)"])for(d=0;d<x["(modified)"].length;d++)m("E013",x["(modified)"][d],S);if((N==="function"||N==="class")&&x["(reassigned)"])for(d=0;d<x["(reassigned)"].length;d++)m("W021",x["(reassigned)"][d],S,N);continue}f&&(e.funct["(isCapturing)"]=!0);if(t)if(!t["(usages)"][S])t["(usages)"][S]=x,n&&(t["(usages)"][S]["(onlyUsedSubFunction)"]=!0);else{var k=t["(usages)"][S];k["(modified)"]=k["(modified)"].concat(x["(modified)"]),k["(tokens)"]=k["(tokens)"].concat(x["(tokens)"]),k["(reassigned)"]=k["(reassigned)"].concat(x["(reassigned)"]),k["(onlyUsedSubFunction)"]=!1}else if(typeof u["(predefined)"][S]=="boolean"){delete o[S],c[S]=s;if(u["(predefined)"][S]===!1&&x["(reassigned)"])for(d=0;d<x["(reassigned)"].length;d++)v("W020",x["(reassigned)"][d])}else if(x["(tokens)"])for(d=0;d<x["(tokens)"].length;d++){var L=x["(tokens)"][d];L.forgiveUndef||(e.option.undef&&!L.ignoreUndef&&v("W117",L,S),h[S]?h[S].line.push(L.line):h[S]={name:S,line:[L.line]})}}t||Object.keys(o).forEach(function(e){b(e,o[e],"var")});if(t&&!n&&!i&&!f){var A=Object.keys(y);for(p=0;p<A.length;p++){var O=A[p];!y[O]["(blockscoped)"]&&y[O]["(type)"]!=="exception"&&!this.funct.has(O,{excludeCurrent:!0})&&(t["(labels)"][O]=y[O],l["(type)"]!=="global"&&(t["(labels)"][O]["(useOutsideOfScope)"]=!0),delete y[O])}}w(),a.pop(),n&&(l=a[r.findLastIndex(a,function(e){return e["(isFuncBody)"]||e["(type)"]==="global"})]),u=t},addParam:function(t,n,i){i=i||"param";if(i==="exception"){var s=this.funct.labeltype(t);s&&s!=="exception"&&(e.option.node||v("W002",e.tokens.next,t))}r.has(u["(labels)"],t)?u["(labels)"][t].duplicated=!0:(T(t,n,i),u["(labels)"][t]={"(type)":i,"(token)":n,"(unused)":!0},u["(params)"].push(t));if(r.has(u["(usages)"],t)){var o=u["(usages)"][t];o["(onlyUsedSubFunction)"]?N(i,t,n):v("E056",n,t,i)}},validateParams:function(){if(l["(type)"]==="global")return;var t=e.isStrict(),n=l["(parent)"];if(!n["(params)"])return;n["(params)"].forEach(function(r){var i=n["(labels)"][r];i&&i.duplicated&&(t?v("E011",i["(token)"],r):e.option.shadow!==!0&&v("W004",i["(token)"],r))})},getUsedOrDefinedGlobals:function(){var e=Object.keys(c);return c.__proto__===s&&e.indexOf("__proto__")===-1&&e.push("__proto__"),e},getImpliedGlobals:function(){var e=r.values(h),t=!1;return h.__proto__&&(t=e.some(function(e){return e.name==="__proto__"}),t||e.push(h.__proto__)),e},getUnuseds:function(){return p},has:function(e){return Boolean(S(e))},labeltype:function(e){var t=S(e);return t?t[e]["(type)"]:null},addExported:function(e){var t=a[0]["(labels)"];if(r.has(o,e))delete o[e];else if(r.has(t,e))t[e]["(unused)"]=!1;else{for(var i=1;i<a.length;i++){var s=a[i];if(!!s["(type)"])break;if(r.has(s["(labels)"],e)&&!s["(labels)"][e]["(blockscoped)"]){s["(labels)"][e]["(unused)"]=!1;return}}n[e]=!0}},setExported:function(e,t){this.block.use(e,t)},addlabel:function(t,i){var o=i.type,a=i.token,f=o==="let"||o==="const"||o==="class",h=(f?u:l)["(type)"]==="global"&&r.has(n,t);T(t,a,o);if(f){var p=u["(labels)"][t];!p&&u===l&&u["(type)"]!=="global"&&(p=!!l["(parent)"]["(labels)"][t]);if(!p&&u["(usages)"][t]){var d=u["(usages)"][t];d["(onlyUsedSubFunction)"]?N(o,t,a):v("E056",a,t,o)}p?v("E011",a,t):e.option.shadow==="outer"&&C.funct.has(t)&&v("W004",a,t),C.block.add(t,o,a,!h)}else{var m=C.funct.has(t);!m&&x(t)&&N(o,t,a),C.funct.has(t,{onlyBlockscoped:!0})?v("E011",a,t):e.option.shadow!==!0&&m&&t!=="__proto__"&&l["(type)"]!=="global"&&v("W004",a,t),C.funct.add(t,o,a,!h),l["(type)"]==="global"&&(c[t]=s)}},funct:{labeltype:function(e,t){var n=t&&t.onlyBlockscoped,r=t&&t.excludeParams,i=a.length-(t&&t.excludeCurrent?2:1);for(var s=i;s>=0;s--){var o=a[s];if(o["(labels)"][e]&&(!n||o["(labels)"][e]["(blockscoped)"]))return o["(labels)"][e]["(type)"];var u=r?a[s-1]:o;if(u&&u["(type)"]==="functionparams")return null}return null},hasBreakLabel:function(e){for(var t=a.length-1;t>=0;t--){var n=a[t];if(n["(breakLabels)"][e])return!0;if(n["(type)"]==="functionparams")return!1}return!1},has:function(e,t){return Boolean(this.labeltype(e,t))},add:function(e,t,n,r){u["(labels)"][e]={"(type)":t,"(token)":n,"(blockscoped)":!1,"(function)":l,"(unused)":r}}},block:{isGlobal:function(){return u["(type)"]==="global"},use:function(t,n){var r=l["(parent)"];r&&r["(labels)"][t]&&r["(labels)"][t]["(type)"]==="param"&&(C.funct.has(t,{excludeParams:!0,onlyBlockscoped:!0})||(r["(labels)"][t]["(unused)"]=!1)),n&&(e.ignored.W117||e.option.undef===!1)&&(n.ignoreUndef=!0),g(t),n&&(n["(function)"]=l,u["(usages)"][t]["(tokens)"].push(n))},reassign:function(e,t){this.modify(e,t),u["(usages)"][e]["(reassigned)"].push(t)},modify:function(e,t){g(e),u["(usages)"][e]["(modified)"].push(t)},add:function(e,t,n,r){u["(labels)"][e]={"(type)":t,"(token)":n,"(blockscoped)":!0,"(unused)":r}},addBreakLabel:function(t,n){var r=n.token;C.funct.hasBreakLabel(t)?v("E011",r,t):e.option.shadow==="outer"&&(C.funct.has(t)?v("W004",r,t):T(t,r)),u["(breakLabels)"][t]=r}}};return C};t.exports=o},{"../lodash":"/node_modules/jshint/lodash.js",events:"/node_modules/browserify/node_modules/events/events.js"}],"/node_modules/jshint/src/state.js":[function(e,t,n){"use strict";var r=e("./name-stack.js"),i={syntax:{},isStrict:function(){return this.directive["use strict"]||this.inClassBody||this.option.module||this.option.strict==="implied"},inMoz:function(){return this.option.moz},inES6:function(){return this.option.moz||this.option.esversion>=6},inES5:function(e){return e?(!this.option.esversion||this.option.esversion===5)&&!this.option.moz:!this.option.esversion||this.option.esversion>=5||this.option.moz},reset:function(){this.tokens={prev:null,next:null,curr:null},this.option={},this.funct=null,this.ignored={},this.directive={},this.jsonMode=!1,this.jsonWarnings=[],this.lines=[],this.tab="",this.cache={},this.ignoredLines={},this.forinifcheckneeded=!1,this.nameStack=new r,this.inClassBody=!1}};n.state=i},{"./name-stack.js":"/node_modules/jshint/src/name-stack.js"}],"/node_modules/jshint/src/style.js":[function(e,t,n){"use strict";n.register=function(e){e.on("Identifier",function(n){if(e.getOption("proto"))return;n.name==="__proto__"&&e.warn("W103",{line:n.line,"char":n.char,data:[n.name,"6"]})}),e.on("Identifier",function(n){if(e.getOption("iterator"))return;n.name==="__iterator__"&&e.warn("W103",{line:n.line,"char":n.char,data:[n.name]})}),e.on("Identifier",function(n){if(!e.getOption("camelcase"))return;n.name.replace(/^_+|_+$/g,"").indexOf("_")>-1&&!n.name.match(/^[A-Z0-9_]*$/)&&e.warn("W106",{line:n.line,"char":n.from,data:[n.name]})}),e.on("String",function(n){var r=e.getOption("quotmark"),i;if(!r)return;r==="single"&&n.quote!=="'"&&(i="W109"),r==="double"&&n.quote!=='"'&&(i="W108"),r===!0&&(e.getCache("quotmark")||e.setCache("quotmark",n.quote),e.getCache("quotmark")!==n.quote&&(i="W110")),i&&e.warn(i,{line:n.line,"char":n.char})}),e.on("Number",function(n){n.value.charAt(0)==="."&&e.warn("W008",{line:n.line,"char":n.char,data:[n.value]}),n.value.substr(n.value.length-1)==="."&&e.warn("W047",{line:n.line,"char":n.char,data:[n.value]}),/^00+/.test(n.value)&&e.warn("W046",{line:n.line,"char":n.char,data:[n.value]})}),e.on("String",function(n){var r=/^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i;if(e.getOption("scripturl"))return;r.test(n.value)&&e.warn("W107",{line:n.line,"char":n.char})})}},{}],"/node_modules/jshint/src/vars.js":[function(e,t,n){"use strict";n.reservedVars={arguments:!1,NaN:!1},n.ecmaIdentifiers={3:{Array:!1,Boolean:!1,Date:!1,decodeURI:!1,decodeURIComponent:!1,encodeURI:!1,encodeURIComponent:!1,Error:!1,eval:!1,EvalError:!1,Function:!1,hasOwnProperty:!1,isFinite:!1,isNaN:!1,Math:!1,Number:!1,Object:!1,parseInt:!1,parseFloat:!1,RangeError:!1,ReferenceError:!1,RegExp:!1,String:!1,SyntaxError:!1,TypeError:!1,URIError:!1},5:{JSON:!1},6:{Map:!1,Promise:!1,Proxy:!1,Reflect:!1,Set:!1,Symbol:!1,WeakMap:!1,WeakSet:!1}},n.browser={Audio:!1,Blob:!1,addEventListener:!1,applicationCache:!1,atob:!1,blur:!1,btoa:!1,cancelAnimationFrame:!1,CanvasGradient:!1,CanvasPattern:!1,CanvasRenderingContext2D:!1,CSS:!1,clearInterval:!1,clearTimeout:!1,close:!1,closed:!1,Comment:!1,CustomEvent:!1,DOMParser:!1,defaultStatus:!1,Document:!1,document:!1,DocumentFragment:!1,Element:!1,ElementTimeControl:!1,Event:!1,event:!1,fetch:!1,FileReader:!1,FormData:!1,focus:!1,frames:!1,getComputedStyle:!1,HTMLElement:!1,HTMLAnchorElement:!1,HTMLBaseElement:!1,HTMLBlockquoteElement:!1,HTMLBodyElement:!1,HTMLBRElement:!1,HTMLButtonElement:!1,HTMLCanvasElement:!1,HTMLCollection:!1,HTMLDirectoryElement:!1,HTMLDivElement:!1,HTMLDListElement:!1,HTMLFieldSetElement:!1,HTMLFontElement:!1,HTMLFormElement:!1,HTMLFrameElement:!1,HTMLFrameSetElement:!1,HTMLHeadElement:!1,HTMLHeadingElement:!1,HTMLHRElement:!1,HTMLHtmlElement:!1,HTMLIFrameElement:!1,HTMLImageElement:!1,HTMLInputElement:!1,HTMLIsIndexElement:!1,HTMLLabelElement:!1,HTMLLayerElement:!1,HTMLLegendElement:!1,HTMLLIElement:!1,HTMLLinkElement:!1,HTMLMapElement:!1,HTMLMenuElement:!1,HTMLMetaElement:!1,HTMLModElement:!1,HTMLObjectElement:!1,HTMLOListElement:!1,HTMLOptGroupElement:!1,HTMLOptionElement:!1,HTMLParagraphElement:!1,HTMLParamElement:!1,HTMLPreElement:!1,HTMLQuoteElement:!1,HTMLScriptElement:!1,HTMLSelectElement:!1,HTMLStyleElement:!1,HTMLTableCaptionElement:!1,HTMLTableCellElement:!1,HTMLTableColElement:!1,HTMLTableElement:!1,HTMLTableRowElement:!1,HTMLTableSectionElement:!1,HTMLTemplateElement:!1,HTMLTextAreaElement:!1,HTMLTitleElement:!1,HTMLUListElement:!1,HTMLVideoElement:!1,history:!1,Image:!1,Intl:!1,length:!1,localStorage:!1,location:!1,matchMedia:!1,MessageChannel:!1,MessageEvent:!1,MessagePort:!1,MouseEvent:!1,moveBy:!1,moveTo:!1,MutationObserver:!1,name:!1,Node:!1,NodeFilter:!1,NodeList:!1,Notification:!1,navigator:!1,onbeforeunload:!0,onblur:!0,onerror:!0,onfocus:!0,onload:!0,onresize:!0,onunload:!0,open:!1,openDatabase:!1,opener:!1,Option:!1,parent:!1,performance:!1,print:!1,Range:!1,requestAnimationFrame:!1,removeEventListener:!1,resizeBy:!1,resizeTo:!1,screen:!1,scroll:!1,scrollBy:!1,scrollTo:!1,sessionStorage:!1,setInterval:!1,setTimeout:!1,SharedWorker:!1,status:!1,SVGAElement:!1,SVGAltGlyphDefElement:!1,SVGAltGlyphElement:!1,SVGAltGlyphItemElement:!1,SVGAngle:!1,SVGAnimateColorElement:!1,SVGAnimateElement:!1,SVGAnimateMotionElement:!1,SVGAnimateTransformElement:!1,SVGAnimatedAngle:!1,SVGAnimatedBoolean:!1,SVGAnimatedEnumeration:!1,SVGAnimatedInteger:!1,SVGAnimatedLength:!1,SVGAnimatedLengthList:!1,SVGAnimatedNumber:!1,SVGAnimatedNumberList:!1,SVGAnimatedPathData:!1,SVGAnimatedPoints:!1,SVGAnimatedPreserveAspectRatio:!1,SVGAnimatedRect:!1,SVGAnimatedString:!1,SVGAnimatedTransformList:!1,SVGAnimationElement:!1,SVGCSSRule:!1,SVGCircleElement:!1,SVGClipPathElement:!1,SVGColor:!1,SVGColorProfileElement:!1,SVGColorProfileRule:!1,SVGComponentTransferFunctionElement:!1,SVGCursorElement:!1,SVGDefsElement:!1,SVGDescElement:!1,SVGDocument:!1,SVGElement:!1,SVGElementInstance:!1,SVGElementInstanceList:!1,SVGEllipseElement:!1,SVGExternalResourcesRequired:!1,SVGFEBlendElement:!1,SVGFEColorMatrixElement:!1,SVGFEComponentTransferElement:!1,SVGFECompositeElement:!1,SVGFEConvolveMatrixElement:!1,SVGFEDiffuseLightingElement:!1,SVGFEDisplacementMapElement:!1,SVGFEDistantLightElement:!1,SVGFEFloodElement:!1,SVGFEFuncAElement:!1,SVGFEFuncBElement:!1,SVGFEFuncGElement:!1,SVGFEFuncRElement:!1,SVGFEGaussianBlurElement:!1,SVGFEImageElement:!1,SVGFEMergeElement:!1,SVGFEMergeNodeElement:!1,SVGFEMorphologyElement:!1,SVGFEOffsetElement:!1,SVGFEPointLightElement:!1,SVGFESpecularLightingElement:!1,SVGFESpotLightElement:!1,SVGFETileElement:!1,SVGFETurbulenceElement:!1,SVGFilterElement:!1,SVGFilterPrimitiveStandardAttributes:!1,SVGFitToViewBox:!1,SVGFontElement:!1,SVGFontFaceElement:!1,SVGFontFaceFormatElement:!1,SVGFontFaceNameElement:!1,SVGFontFaceSrcElement:!1,SVGFontFaceUriElement:!1,SVGForeignObjectElement:!1,SVGGElement:!1,SVGGlyphElement:!1,SVGGlyphRefElement:!1,SVGGradientElement:!1,SVGHKernElement:!1,SVGICCColor:!1,SVGImageElement:!1,SVGLangSpace:!1,SVGLength:!1,SVGLengthList:!1,SVGLineElement:!1,SVGLinearGradientElement:!1,SVGLocatable:!1,SVGMPathElement:!1,SVGMarkerElement:!1,SVGMaskElement:!1,SVGMatrix:!1,SVGMetadataElement:!1,SVGMissingGlyphElement:!1,SVGNumber:!1,SVGNumberList:!1,SVGPaint:!1,SVGPathElement:!1,SVGPathSeg:!1,SVGPathSegArcAbs:!1,SVGPathSegArcRel:!1,SVGPathSegClosePath:!1,SVGPathSegCurvetoCubicAbs:!1,SVGPathSegCurvetoCubicRel:!1,SVGPathSegCurvetoCubicSmoothAbs:!1,SVGPathSegCurvetoCubicSmoothRel:!1,SVGPathSegCurvetoQuadraticAbs:!1,SVGPathSegCurvetoQuadraticRel:!1,SVGPathSegCurvetoQuadraticSmoothAbs:!1,SVGPathSegCurvetoQuadraticSmoothRel:!1,SVGPathSegLinetoAbs:!1,SVGPathSegLinetoHorizontalAbs:!1,SVGPathSegLinetoHorizontalRel:!1,SVGPathSegLinetoRel:!1,SVGPathSegLinetoVerticalAbs:!1,SVGPathSegLinetoVerticalRel:!1,SVGPathSegList:!1,SVGPathSegMovetoAbs:!1,SVGPathSegMovetoRel:!1,SVGPatternElement:!1,SVGPoint:!1,SVGPointList:!1,SVGPolygonElement:!1,SVGPolylineElement:!1,SVGPreserveAspectRatio:!1,SVGRadialGradientElement:!1,SVGRect:!1,SVGRectElement:!1,SVGRenderingIntent:!1,SVGSVGElement:!1,SVGScriptElement:!1,SVGSetElement:!1,SVGStopElement:!1,SVGStringList:!1,SVGStylable:!1,SVGStyleElement:!1,SVGSwitchElement:!1,SVGSymbolElement:!1,SVGTRefElement:!1,SVGTSpanElement:!1,SVGTests:!1,SVGTextContentElement:!1,SVGTextElement:!1,SVGTextPathElement:!1,SVGTextPositioningElement:!1,SVGTitleElement:!1,SVGTransform:!1,SVGTransformList:!1,SVGTransformable:!1,SVGURIReference:!1,SVGUnitTypes:!1,SVGUseElement:!1,SVGVKernElement:!1,SVGViewElement:!1,SVGViewSpec:!1,SVGZoomAndPan:!1,Text:!1,TextDecoder:!1,TextEncoder:!1,TimeEvent:!1,top:!1,URL:!1,WebGLActiveInfo:!1,WebGLBuffer:!1,WebGLContextEvent:!1,WebGLFramebuffer:!1,WebGLProgram:!1,WebGLRenderbuffer:!1,WebGLRenderingContext:!1,WebGLShader:!1,WebGLShaderPrecisionFormat:!1,WebGLTexture:!1,WebGLUniformLocation:!1,WebSocket:!1,window:!1,Window:!1,Worker:!1,XDomainRequest:!1,XMLHttpRequest:!1,XMLSerializer:!1,XPathEvaluator:!1,XPathException:!1,XPathExpression:!1,XPathNamespace:!1,XPathNSResolver:!1,XPathResult:!1},n.devel={alert:!1,confirm:!1,console:!1,Debug:!1,opera:!1,prompt:!1},n.worker={importScripts:!0,postMessage:!0,self:!0,FileReaderSync:!0},n.nonstandard={escape:!1,unescape:!1},n.couch={require:!1,respond:!1,getRow:!1,emit:!1,send:!1,start:!1,sum:!1,log:!1,exports:!1,module:!1,provides:!1},n.node={__filename:!1,__dirname:!1,GLOBAL:!1,global:!1,module:!1,require:!1,Buffer:!0,console:!0,exports:!0,process:!0,setTimeout:!0,clearTimeout:!0,setInterval:!0,clearInterval:!0,setImmediate:!0,clearImmediate:!0},n.browserify={__filename:!1,__dirname:!1,global:!1,module:!1,require:!1,Buffer:!0,exports:!0,process:!0},n.phantom={phantom:!0,require:!0,WebPage:!0,console:!0,exports:!0},n.qunit={asyncTest:!1,deepEqual:!1,equal:!1,expect:!1,module:!1,notDeepEqual:!1,notEqual:!1,notPropEqual:!1,notStrictEqual:!1,ok:!1,propEqual:!1,QUnit:!1,raises:!1,start:!1,stop:!1,strictEqual:!1,test:!1,"throws":!1},n.rhino={defineClass:!1,deserialize:!1,gc:!1,help:!1,importClass:!1,importPackage:!1,java:!1,load:!1,loadClass:!1,Packages:!1,print:!1,quit:!1,readFile:!1,readUrl:!1,runCommand:!1,seal:!1,serialize:!1,spawn:!1,sync:!1,toint32:!1,version:!1},n.shelljs={target:!1,echo:!1,exit:!1,cd:!1,pwd:!1,ls:!1,find:!1,cp:!1,rm:!1,mv:!1,mkdir:!1,test:!1,cat:!1,sed:!1,grep:!1,which:!1,dirs:!1,pushd:!1,popd:!1,env:!1,exec:!1,chmod:!1,config:!1,error:!1,tempdir:!1},n.typed={ArrayBuffer:!1,ArrayBufferView:!1,DataView:!1,Float32Array:!1,Float64Array:!1,Int16Array:!1,Int32Array:!1,Int8Array:!1,Uint16Array:!1,Uint32Array:!1,Uint8Array:!1,Uint8ClampedArray:!1},n.wsh={ActiveXObject:!0,Enumerator:!0,GetObject:!0,ScriptEngine:!0,ScriptEngineBuildVersion:!0,ScriptEngineMajorVersion:!0,ScriptEngineMinorVersion:!0,VBArray:!0,WSH:!0,WScript:!0,XDomainRequest:!0},n.dojo={dojo:!1,dijit:!1,dojox:!1,define:!1,require:!1},n.jquery={$:!1,jQuery:!1},n.mootools={$:!1,$$:!1,Asset:!1,Browser:!1,Chain:!1,Class:!1,Color:!1,Cookie:!1,Core:!1,Document:!1,DomReady:!1,DOMEvent:!1,DOMReady:!1,Drag:!1,Element:!1,Elements:!1,Event:!1,Events:!1,Fx:!1,Group:!1,Hash:!1,HtmlTable:!1,IFrame:!1,IframeShim:!1,InputValidator:!1,instanceOf:!1,Keyboard:!1,Locale:!1,Mask:!1,MooTools:!1,Native:!1,Options:!1,OverText:!1,Request:!1,Scroller:!1,Slick:!1,Slider:!1,Sortables:!1,Spinner:!1,Swiff:!1,Tips:!1,Type:!1,typeOf:!1,URI:!1,Window:!1},n.prototypejs={$:!1,$$:!1,$A:!1,$F:!1,$H:!1,$R:!1,$break:!1,$continue:!1,$w:!1,Abstract:!1,Ajax:!1,Class:!1,Enumerable:!1,Element:!1,Event:!1,Field:!1,Form:!1,Hash:!1,Insertion:!1,ObjectRange:!1,PeriodicalExecuter:!1,Position:!1,Prototype:!1,Selector:!1,Template:!1,Toggle:!1,Try:!1,Autocompleter:!1,Builder:!1,Control:!1,Draggable:!1,Draggables:!1,Droppables:!1,Effect:!1,Sortable:!1,SortableObserver:!1,Sound:!1,Scriptaculous:!1},n.yui={YUI:!1,Y:!1,YUI_config:!1},n.mocha={mocha:!1,describe:!1,xdescribe:!1,it:!1,xit:!1,context:!1,xcontext:!1,before:!1,after:!1,beforeEach:!1,afterEach:!1,suite:!1,test:!1,setup:!1,teardown:!1,suiteSetup:!1,suiteTeardown:!1},n.jasmine={jasmine:!1,describe:!1,xdescribe:!1,it:!1,xit:!1,beforeEach:!1,afterEach:!1,setFixtures:!1,loadFixtures:!1,spyOn:!1,expect:!1,runs:!1,waitsFor:!1,waits:!1,beforeAll:!1,afterAll:!1,fail:!1,fdescribe:!1,fit:!1,pending:!1}},{}]},{},["/node_modules/jshint/src/jshint.js"])}),ace.define("ace/mode/javascript_worker",[],function(require,exports,module){"use strict";function startRegex(e){return RegExp("^("+e.join("|")+")")}var oop=require("../lib/oop"),Mirror=require("../worker/mirror").Mirror,lint=require("./javascript/jshint").JSHINT,disabledWarningsRe=startRegex(["Bad for in variable '(.+)'.",'Missing "use strict"']),errorsRe=startRegex(["Unexpected","Expected ","Confusing (plus|minus)","\\{a\\} unterminated regular expression","Unclosed ","Unmatched ","Unbegun comment","Bad invocation","Missing space after","Missing operator at"]),infoRe=startRegex(["Expected an assignment","Bad escapement of EOL","Unexpected comma","Unexpected space","Missing radix parameter.","A leading decimal point can","\\['{a}'\\] is better written in dot notation.","'{a}' used out of scope"]),JavaScriptWorker=exports.JavaScriptWorker=function(e){Mirror.call(this,e),this.setTimeout(500),this.setOptions()};oop.inherits(JavaScriptWorker,Mirror),function(){this.setOptions=function(e){this.options=e||{esnext:!0,moz:!0,devel:!0,browser:!0,node:!0,laxcomma:!0,laxbreak:!0,lastsemic:!0,onevar:!1,passfail:!1,maxerr:100,expr:!0,multistr:!0,globalstrict:!0},this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.changeOptions=function(e){oop.mixin(this.options,e),this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.isValidJS=function(str){try{eval("throw 0;"+str)}catch(e){if(e===0)return!0}return!1},this.onUpdate=function(){var e=this.doc.getValue();e=e.replace(/^#!.*\n/,"\n");if(!e)return this.sender.emit("annotate",[]);var t=[],n=this.isValidJS(e)?"warning":"error";lint(e,this.options,this.options.globals);var r=lint.errors,i=!1;for(var s=0;s<r.length;s++){var o=r[s];if(!o)continue;var u=o.raw,a="warning";if(u=="Missing semicolon."){var f=o.evidence.substr(o.character);f=f.charAt(f.search(/\S/)),n=="error"&&f&&/[\w\d{(['"]/.test(f)?(o.reason='Missing ";" before statement',a="error"):a="info"}else{if(disabledWarningsRe.test(u))continue;infoRe.test(u)?a="info":errorsRe.test(u)?(i=!0,a=n):u=="'{a}' is not defined."?a="warning":u=="'{a}' is defined but never used."&&(a="info")}t.push({row:o.line-1,column:o.character-1,text:o.reason,type:a,raw:u}),i}this.sender.emit("annotate",t)}}.call(JavaScriptWorker.prototype)}),ace.define("ace/lib/es5-shim",[],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)=="[object Array]"});var m=Object("a"),g=m[0]!="a"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _=" \n\x0b\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";if(!String.prototype.trim||_.trim()){_="["+_+"]";var D=new RegExp("^"+_+_+"*"),P=new RegExp(_+_+"*$");String.prototype.trim=function(){return String(this).replace(D,"").replace(P,"")}}var F=function(e){if(e==null)throw new TypeError("can't convert "+e+" to object");return Object(e)}}) \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/worker-json.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/worker-json.js new file mode 100644 index 0000000..5a63253 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/worker-json.js @@ -0,0 +1 @@ +"no use strict";!function(e){function t(e,t){var n=e,r="";while(n){var i=t[n];if(typeof i=="string")return i+r;if(i)return i.location.replace(/\/*$/,"/")+(r||i.main||i.name);if(i===!1)return"";var s=n.lastIndexOf("/");if(s===-1)break;r=n.substr(s)+r,n=n.slice(0,s)}return e}if(typeof e.window!="undefined"&&e.document)return;if(e.require&&e.define)return;e.console||(e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console),e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){postMessage({type:"error",data:{message:e,data:i.data,file:t,line:n,col:r,stack:i.stack}})},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(r,i){i||(i=r,r=null);if(!i.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");i=e.normalizeModule(r,i);var s=e.require.modules[i];if(s)return s.initialized||(s.initialized=!0,s.exports=s.factory().exports),s.exports;if(!e.require.tlns)return console.log("unable to load "+i);var o=t(i,e.require.tlns);return o.slice(-3)!=".js"&&(o+=".js"),e.require.id=i,e.require.modules[i]={},importScripts(o),e.require(r,i)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id);if(typeof r!="function"){e.require.modules[t]={exports:r,initialized:!0};return}n.length||(n=["require","exports","module"]);var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.slice(0,r.length).map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},require.tlns={},e.initBaseUrls=function(t){for(var n in t)require.tlns[n]=t[n]},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var n=e.main=null,r=e.sender=null;e.onmessage=function(t){var i=t.data;if(i.event&&r)r._signal(i.event,i.data);else if(i.command)if(n[i.command])n[i.command].apply(n,i.args);else{if(!e[i.command])throw new Error("Unknown command:"+i.command);e[i.command].apply(e,i.args)}else if(i.init){e.initBaseUrls(i.tlns),require("ace/lib/es5-shim"),r=e.sender=e.initSender();var s=require(i.module)[i.classname];n=e.main=new s(r)}}}(this),ace.define("ace/lib/oop",[],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/range",[],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define("ace/apply_delta",[],function(e,t,n){"use strict";function r(e,t){throw console.log("Invalid Delta:",e),"Invalid Delta: "+t}function i(e,t){return t.row>=0&&t.row<e.length&&t.column>=0&&t.column<=e[t.row].length}function s(e,t){t.action!="insert"&&t.action!="remove"&&r(t,"delta.action must be 'insert' or 'remove'"),t.lines instanceof Array||r(t,"delta.lines must be an Array"),(!t.start||!t.end)&&r(t,"delta.start/end must be an present");var n=t.start;i(e,t.start)||r(t,"delta.start must be contained in document");var s=t.end;t.action=="remove"&&!i(e,s)&&r(t,"delta.end must contained in document for 'remove' actions");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,"delta.range must match delta lines")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||"";switch(t.action){case"insert":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case"remove":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),ace.define("ace/lib/event_emitter",[],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)});if(!t)return new Promise(function(e){t=e})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t)r&&this.setDefaultHandler(e,r.pop());else if(r){var i=r.indexOf(t);i!=-1&&r.splice(i,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?"unshift":"push"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define("ace/anchor",[],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){function e(e,t,n){var r=n?e.column<=t.column:e.column<t.column;return e.row<t.row||e.row==t.row&&r}function t(t,n,r){var i=t.action=="insert",s=(i?1:-1)*(t.end.row-t.start.row),o=(i?1:-1)*(t.end.column-t.start.column),u=t.start,a=i?u:t.end;return e(n,u,r)?{row:n.row,column:n.column}:e(a,n,!r)?{row:n.row+s,column:n.column+(n.row==a.row?o:0)}:{row:u.row,column:u.column}}r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){if(e.start.row==e.end.row&&e.start.row!=this.row)return;if(e.start.row>this.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",[],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./apply_delta").applyDelta,s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=e("./anchor").Anchor,a=function(e){this.$lines=[""],e.length===0?this.$lines=[""]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."),this.insertMergedLines(e,["",""])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:"insert",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e<this.getLength()?(t=t.concat([""]),n=0):(t=[""].concat(t),e--,n=this.$lines[e].length),this.insertMergedLines({row:e,column:n},t)},this.insertMergedLines=function(e,t){var n=this.clippedPos(e.row,e.column),r={row:n.row+t.length-1,column:(t.length==1?n.column:0)+t[t.length-1].length};return this.applyDelta({start:n,end:r,action:"insert",lines:t}),this.clonePos(r)},this.remove=function(e){var t=this.clippedPos(e.start.row,e.start.column),n=this.clippedPos(e.end.row,e.end.column);return this.applyDelta({start:t,end:n,action:"remove",lines:this.getLinesForRange({start:t,end:n})}),this.clonePos(t)},this.removeInLine=function(e,t,n){var r=this.clippedPos(e,t),i=this.clippedPos(e,n);return this.applyDelta({start:r,end:i,action:"remove",lines:this.getLinesForRange({start:r,end:i})},!0),this.clonePos(r)},this.removeFullLines=function(e,t){e=Math.min(Math.max(0,e),this.getLength()-1),t=Math.min(Math.max(0,t),this.getLength()-1);var n=t==this.getLength()-1&&e>0,r=t<this.getLength()-1,i=n?e-1:e,s=n?this.getLine(i).length:0,u=r?t+1:t,a=r?0:this.getLine(u).length,f=new o(i,s,u,a),l=this.$lines.slice(e,t+1);return this.applyDelta({start:f.start,end:f.end,action:"remove",lines:this.getLinesForRange(f)}),l},this.removeNewLine=function(e){e<this.getLength()-1&&e>=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++)this.applyDelta(e[t])},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action=="insert";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4?this.$splitAndapplyLargeDelta(e,2e4):(i(this.$lines,e,t),this._signal("change",e))},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length-t+1,i=e.start.row,s=e.start.column;for(var o=0,u=0;o<r;o=u){u+=t-1;var a=n.slice(o,u);a.push(""),this.applyDelta({start:this.pos(i+o,s),end:this.pos(i+u,s=0),action:e.action,lines:a},!0)}e.lines=n.slice(o),e.start.row=i+o,e.start.column=s,this.applyDelta(e,!0)},this.revertDelta=function(e){this.applyDelta({start:this.clonePos(e.start),end:this.clonePos(e.end),action:e.action=="insert"?"remove":"insert",lines:e.lines.slice()})},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:e+n[s-1].length+r}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(a.prototype),t.Document=a}),ace.define("ace/lib/lang",[],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function s(e){if(typeof e!="object"||!e)return e;var t;if(Array.isArray(e)){t=[];for(var n=0;n<e.length;n++)t[n]=s(e[n]);return t}if(Object.prototype.toString.call(e)!=="[object Object]")return e;t={};for(var n in e)t[n]=s(e[n]);return t},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return(""+e).replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define("ace/worker/mirror",[],function(e,t,n){"use strict";var r=e("../range").Range,i=e("../document").Document,s=e("../lib/lang"),o=t.Mirror=function(e){this.sender=e;var t=this.doc=new i(""),n=this.deferredUpdate=s.delayedCall(this.onUpdate.bind(this)),r=this;e.on("change",function(e){var i=e.data;if(i[0].start)t.applyDeltas(i);else for(var s=0;s<i.length;s+=2){if(Array.isArray(i[s+1]))var o={action:"insert",start:i[s],lines:i[s+1]};else var o={action:"remove",start:i[s],end:i[s+1]};t.applyDelta(o,!0)}if(r.$timeout)return n.schedule(r.$timeout);r.onUpdate()})};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(o.prototype)}),ace.define("ace/mode/json/json_parse",[],function(e,t,n){"use strict";var r,i,s={'"':'"',"\\":"\\","/":"/",b:"\b",f:"\f",n:"\n",r:"\r",t:" "},o,u=function(e){throw{name:"SyntaxError",message:e,at:r,text:o}},a=function(e){return e&&e!==i&&u("Expected '"+e+"' instead of '"+i+"'"),i=o.charAt(r),r+=1,i},f=function(){var e,t="";i==="-"&&(t="-",a("-"));while(i>="0"&&i<="9")t+=i,a();if(i==="."){t+=".";while(a()&&i>="0"&&i<="9")t+=i}if(i==="e"||i==="E"){t+=i,a();if(i==="-"||i==="+")t+=i,a();while(i>="0"&&i<="9")t+=i,a()}e=+t;if(!isNaN(e))return e;u("Bad number")},l=function(){var e,t,n="",r;if(i==='"')while(a()){if(i==='"')return a(),n;if(i==="\\"){a();if(i==="u"){r=0;for(t=0;t<4;t+=1){e=parseInt(a(),16);if(!isFinite(e))break;r=r*16+e}n+=String.fromCharCode(r)}else{if(typeof s[i]!="string")break;n+=s[i]}}else{if(i=="\n"||i=="\r")break;n+=i}}u("Bad string")},c=function(){while(i&&i<=" ")a()},h=function(){switch(i){case"t":return a("t"),a("r"),a("u"),a("e"),!0;case"f":return a("f"),a("a"),a("l"),a("s"),a("e"),!1;case"n":return a("n"),a("u"),a("l"),a("l"),null}u("Unexpected '"+i+"'")},p,d=function(){var e=[];if(i==="["){a("["),c();if(i==="]")return a("]"),e;while(i){e.push(p()),c();if(i==="]")return a("]"),e;a(","),c()}}u("Bad array")},v=function(){var e,t={};if(i==="{"){a("{"),c();if(i==="}")return a("}"),t;while(i){e=l(),c(),a(":"),Object.hasOwnProperty.call(t,e)&&u('Duplicate key "'+e+'"'),t[e]=p(),c();if(i==="}")return a("}"),t;a(","),c()}}u("Bad object")};return p=function(){c();switch(i){case"{":return v();case"[":return d();case'"':return l();case"-":return f();default:return i>="0"&&i<="9"?f():h()}},function(e,t){var n;return o=e,r=0,i=" ",n=p(),c(),i&&u("Syntax error"),typeof t=="function"?function s(e,n){var r,i,o=e[n];if(o&&typeof o=="object")for(r in o)Object.hasOwnProperty.call(o,r)&&(i=s(o,r),i!==undefined?o[r]=i:delete o[r]);return t.call(e,n,o)}({"":n},""):n}}),ace.define("ace/mode/json_worker",[],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../worker/mirror").Mirror,s=e("./json/json_parse"),o=t.JsonWorker=function(e){i.call(this,e),this.setTimeout(200)};r.inherits(o,i),function(){this.onUpdate=function(){var e=this.doc.getValue(),t=[];try{e&&s(e)}catch(n){var r=this.doc.indexToPosition(n.at-1);t.push({row:r.row,column:r.column,text:n.message,type:"error"})}this.sender.emit("annotate",t)}}.call(o.prototype)}),ace.define("ace/lib/es5-shim",[],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)=="[object Array]"});var m=Object("a"),g=m[0]!="a"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _=" \n\x0b\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";if(!String.prototype.trim||_.trim()){_="["+_+"]";var D=new RegExp("^"+_+_+"*"),P=new RegExp(_+_+"*$");String.prototype.trim=function(){return String(this).replace(D,"").replace(P,"")}}var F=function(e){if(e==null)throw new TypeError("can't convert "+e+" to object");return Object(e)}}) \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/worker-xml.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/worker-xml.js new file mode 100644 index 0000000..9e706ea --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/ace/worker-xml.js @@ -0,0 +1 @@ +"no use strict";!function(e){function t(e,t){var n=e,r="";while(n){var i=t[n];if(typeof i=="string")return i+r;if(i)return i.location.replace(/\/*$/,"/")+(r||i.main||i.name);if(i===!1)return"";var s=n.lastIndexOf("/");if(s===-1)break;r=n.substr(s)+r,n=n.slice(0,s)}return e}if(typeof e.window!="undefined"&&e.document)return;if(e.require&&e.define)return;e.console||(e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console),e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){postMessage({type:"error",data:{message:e,data:i.data,file:t,line:n,col:r,stack:i.stack}})},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(r,i){i||(i=r,r=null);if(!i.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");i=e.normalizeModule(r,i);var s=e.require.modules[i];if(s)return s.initialized||(s.initialized=!0,s.exports=s.factory().exports),s.exports;if(!e.require.tlns)return console.log("unable to load "+i);var o=t(i,e.require.tlns);return o.slice(-3)!=".js"&&(o+=".js"),e.require.id=i,e.require.modules[i]={},importScripts(o),e.require(r,i)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id);if(typeof r!="function"){e.require.modules[t]={exports:r,initialized:!0};return}n.length||(n=["require","exports","module"]);var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.slice(0,r.length).map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},require.tlns={},e.initBaseUrls=function(t){for(var n in t)require.tlns[n]=t[n]},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var n=e.main=null,r=e.sender=null;e.onmessage=function(t){var i=t.data;if(i.event&&r)r._signal(i.event,i.data);else if(i.command)if(n[i.command])n[i.command].apply(n,i.args);else{if(!e[i.command])throw new Error("Unknown command:"+i.command);e[i.command].apply(e,i.args)}else if(i.init){e.initBaseUrls(i.tlns),require("ace/lib/es5-shim"),r=e.sender=e.initSender();var s=require(i.module)[i.classname];n=e.main=new s(r)}}}(this),ace.define("ace/lib/oop",[],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/lib/lang",[],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function s(e){if(typeof e!="object"||!e)return e;var t;if(Array.isArray(e)){t=[];for(var n=0;n<e.length;n++)t[n]=s(e[n]);return t}if(Object.prototype.toString.call(e)!=="[object Object]")return e;t={};for(var n in e)t[n]=s(e[n]);return t},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return(""+e).replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define("ace/range",[],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define("ace/apply_delta",[],function(e,t,n){"use strict";function r(e,t){throw console.log("Invalid Delta:",e),"Invalid Delta: "+t}function i(e,t){return t.row>=0&&t.row<e.length&&t.column>=0&&t.column<=e[t.row].length}function s(e,t){t.action!="insert"&&t.action!="remove"&&r(t,"delta.action must be 'insert' or 'remove'"),t.lines instanceof Array||r(t,"delta.lines must be an Array"),(!t.start||!t.end)&&r(t,"delta.start/end must be an present");var n=t.start;i(e,t.start)||r(t,"delta.start must be contained in document");var s=t.end;t.action=="remove"&&!i(e,s)&&r(t,"delta.end must contained in document for 'remove' actions");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,"delta.range must match delta lines")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||"";switch(t.action){case"insert":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case"remove":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),ace.define("ace/lib/event_emitter",[],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)});if(!t)return new Promise(function(e){t=e})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t)r&&this.setDefaultHandler(e,r.pop());else if(r){var i=r.indexOf(t);i!=-1&&r.splice(i,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?"unshift":"push"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define("ace/anchor",[],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){function e(e,t,n){var r=n?e.column<=t.column:e.column<t.column;return e.row<t.row||e.row==t.row&&r}function t(t,n,r){var i=t.action=="insert",s=(i?1:-1)*(t.end.row-t.start.row),o=(i?1:-1)*(t.end.column-t.start.column),u=t.start,a=i?u:t.end;return e(n,u,r)?{row:n.row,column:n.column}:e(a,n,!r)?{row:n.row+s,column:n.column+(n.row==a.row?o:0)}:{row:u.row,column:u.column}}r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){if(e.start.row==e.end.row&&e.start.row!=this.row)return;if(e.start.row>this.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",[],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./apply_delta").applyDelta,s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=e("./anchor").Anchor,a=function(e){this.$lines=[""],e.length===0?this.$lines=[""]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."),this.insertMergedLines(e,["",""])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:"insert",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e<this.getLength()?(t=t.concat([""]),n=0):(t=[""].concat(t),e--,n=this.$lines[e].length),this.insertMergedLines({row:e,column:n},t)},this.insertMergedLines=function(e,t){var n=this.clippedPos(e.row,e.column),r={row:n.row+t.length-1,column:(t.length==1?n.column:0)+t[t.length-1].length};return this.applyDelta({start:n,end:r,action:"insert",lines:t}),this.clonePos(r)},this.remove=function(e){var t=this.clippedPos(e.start.row,e.start.column),n=this.clippedPos(e.end.row,e.end.column);return this.applyDelta({start:t,end:n,action:"remove",lines:this.getLinesForRange({start:t,end:n})}),this.clonePos(t)},this.removeInLine=function(e,t,n){var r=this.clippedPos(e,t),i=this.clippedPos(e,n);return this.applyDelta({start:r,end:i,action:"remove",lines:this.getLinesForRange({start:r,end:i})},!0),this.clonePos(r)},this.removeFullLines=function(e,t){e=Math.min(Math.max(0,e),this.getLength()-1),t=Math.min(Math.max(0,t),this.getLength()-1);var n=t==this.getLength()-1&&e>0,r=t<this.getLength()-1,i=n?e-1:e,s=n?this.getLine(i).length:0,u=r?t+1:t,a=r?0:this.getLine(u).length,f=new o(i,s,u,a),l=this.$lines.slice(e,t+1);return this.applyDelta({start:f.start,end:f.end,action:"remove",lines:this.getLinesForRange(f)}),l},this.removeNewLine=function(e){e<this.getLength()-1&&e>=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++)this.applyDelta(e[t])},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action=="insert";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4?this.$splitAndapplyLargeDelta(e,2e4):(i(this.$lines,e,t),this._signal("change",e))},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length-t+1,i=e.start.row,s=e.start.column;for(var o=0,u=0;o<r;o=u){u+=t-1;var a=n.slice(o,u);a.push(""),this.applyDelta({start:this.pos(i+o,s),end:this.pos(i+u,s=0),action:e.action,lines:a},!0)}e.lines=n.slice(o),e.start.row=i+o,e.start.column=s,this.applyDelta(e,!0)},this.revertDelta=function(e){this.applyDelta({start:this.clonePos(e.start),end:this.clonePos(e.end),action:e.action=="insert"?"remove":"insert",lines:e.lines.slice()})},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:e+n[s-1].length+r}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(a.prototype),t.Document=a}),ace.define("ace/worker/mirror",[],function(e,t,n){"use strict";var r=e("../range").Range,i=e("../document").Document,s=e("../lib/lang"),o=t.Mirror=function(e){this.sender=e;var t=this.doc=new i(""),n=this.deferredUpdate=s.delayedCall(this.onUpdate.bind(this)),r=this;e.on("change",function(e){var i=e.data;if(i[0].start)t.applyDeltas(i);else for(var s=0;s<i.length;s+=2){if(Array.isArray(i[s+1]))var o={action:"insert",start:i[s],lines:i[s+1]};else var o={action:"remove",start:i[s],end:i[s+1]};t.applyDelta(o,!0)}if(r.$timeout)return n.schedule(r.$timeout);r.onUpdate()})};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(o.prototype)}),ace.define("ace/mode/xml/sax",[],function(e,t,n){function d(){}function v(e,t,n,r,i){function s(e){if(e>65535){e-=65536;var t=55296+(e>>10),n=56320+(e&1023);return String.fromCharCode(t,n)}return String.fromCharCode(e)}function o(e){var t=e.slice(1,-1);return t in n?n[t]:t.charAt(0)==="#"?s(parseInt(t.substr(1).replace("x","0x"))):(i.error("entity not found:"+e),e)}function u(t){var n=e.substring(v,t).replace(/&#?\w+;/g,o);h&&a(v),r.characters(n,0,t-v),v=t}function a(t,n){while(t>=l&&(n=c.exec(e)))f=n.index,l=f+n[0].length,h.lineNumber++;h.columnNumber=t-f+1}var f=0,l=0,c=/.+(?:\r\n?|\n)|.*$/g,h=r.locator,p=[{currentNSMap:t}],d={},v=0;for(;;){var E=e.indexOf("<",v);if(E<0){if(!e.substr(v).match(/^\s*$/)){var N=r.document,C=N.createTextNode(e.substr(v));N.appendChild(C),r.currentElement=C}return}E>v&&u(E);switch(e.charAt(E+1)){case"/":var k=e.indexOf(">",E+3),L=e.substring(E+2,k),A;if(!(p.length>1)){i.fatalError("end tag name not found for: "+L);break}A=p.pop();var O=A.localNSMap;A.tagName!=L&&i.fatalError("end tag name: "+L+" does not match the current start tagName: "+A.tagName),r.endElement(A.uri,A.localName,L);if(O)for(var M in O)r.endPrefixMapping(M);k++;break;case"?":h&&a(E),k=x(e,E,r);break;case"!":h&&a(E),k=S(e,E,r,i);break;default:try{h&&a(E);var _=new T,k=g(e,E,_,o,i),D=_.length;if(D&&h){var P=m(h,{});for(var E=0;E<D;E++){var H=_[E];a(H.offset),H.offset=m(h,{})}m(P,h)}!_.closed&&w(e,k,_.tagName,d)&&(_.closed=!0,n.nbsp||i.warning("unclosed xml attribute")),y(_,r,p),_.uri==="http://www.w3.org/1999/xhtml"&&!_.closed?k=b(e,k,_.tagName,o,r):k++}catch(B){i.error("element parse error: "+B),k=-1}}k<0?u(E+1):v=k}}function m(e,t){return t.lineNumber=e.lineNumber,t.columnNumber=e.columnNumber,t}function g(e,t,n,r,i){var s,d,v=++t,m=o;for(;;){var g=e.charAt(v);switch(g){case"=":if(m===u)s=e.slice(t,v),m=f;else{if(m!==a)throw new Error("attribute equal must after attrName");m=f}break;case"'":case'"':if(m===f){t=v+1,v=e.indexOf(g,t);if(!(v>0))throw new Error("attribute value no end '"+g+"' match");d=e.slice(t,v).replace(/&#?\w+;/g,r),n.add(s,d,t-1),m=c}else{if(m!=l)throw new Error('attribute value must after "="');d=e.slice(t,v).replace(/&#?\w+;/g,r),n.add(s,d,t),i.warning('attribute "'+s+'" missed start quot('+g+")!!"),t=v+1,m=c}break;case"/":switch(m){case o:n.setTagName(e.slice(t,v));case c:case h:case p:m=p,n.closed=!0;case l:case u:case a:break;default:throw new Error("attribute invalid close char('/')")}break;case"":i.error("unexpected end of input");case">":switch(m){case o:n.setTagName(e.slice(t,v));case c:case h:case p:break;case l:case u:d=e.slice(t,v),d.slice(-1)==="/"&&(n.closed=!0,d=d.slice(0,-1));case a:m===a&&(d=s),m==l?(i.warning('attribute "'+d+'" missed quot(")!!'),n.add(s,d.replace(/&#?\w+;/g,r),t)):(i.warning('attribute "'+d+'" missed value!! "'+d+'" instead!!'),n.add(d,d,t));break;case f:throw new Error("attribute value missed!!")}return v;case"\u0080":g=" ";default:if(g<=" ")switch(m){case o:n.setTagName(e.slice(t,v)),m=h;break;case u:s=e.slice(t,v),m=a;break;case l:var d=e.slice(t,v).replace(/&#?\w+;/g,r);i.warning('attribute "'+d+'" missed quot(")!!'),n.add(s,d,t);case c:m=h}else switch(m){case a:i.warning('attribute "'+s+'" missed value!! "'+s+'" instead!!'),n.add(s,s,t),t=v,m=u;break;case c:i.warning('attribute space is required"'+s+'"!!');case h:m=u,t=v;break;case f:m=l,t=v;break;case p:throw new Error("elements closed character '/' and '>' must be connected to")}}v++}}function y(e,t,n){var r=e.tagName,i=null,s=n[n.length-1].currentNSMap,o=e.length;while(o--){var u=e[o],a=u.qName,f=u.value,l=a.indexOf(":");if(l>0)var c=u.prefix=a.slice(0,l),h=a.slice(l+1),p=c==="xmlns"&&h;else h=a,c=null,p=a==="xmlns"&&"";u.localName=h,p!==!1&&(i==null&&(i={},E(s,s={})),s[p]=i[p]=f,u.uri="http://www.w3.org/2000/xmlns/",t.startPrefixMapping(p,f))}var o=e.length;while(o--){u=e[o];var c=u.prefix;c&&(c==="xml"&&(u.uri="http://www.w3.org/XML/1998/namespace"),c!=="xmlns"&&(u.uri=s[c]))}var l=r.indexOf(":");l>0?(c=e.prefix=r.slice(0,l),h=e.localName=r.slice(l+1)):(c=null,h=e.localName=r);var d=e.uri=s[c||""];t.startElement(d,h,r,e);if(e.closed){t.endElement(d,h,r);if(i)for(c in i)t.endPrefixMapping(c)}else e.currentNSMap=s,e.localNSMap=i,n.push(e)}function b(e,t,n,r,i){if(/^(?:script|textarea)$/i.test(n)){var s=e.indexOf("</"+n+">",t),o=e.substring(t+1,s);if(/[&<]/.test(o))return/^script$/i.test(n)?(i.characters(o,0,o.length),s):(o=o.replace(/&#?\w+;/g,r),i.characters(o,0,o.length),s)}return t+1}function w(e,t,n,r){var i=r[n];return i==null&&(i=r[n]=e.lastIndexOf("</"+n+">")),i<t}function E(e,t){for(var n in e)t[n]=e[n]}function S(e,t,n,r){var i=e.charAt(t+2);switch(i){case"-":if(e.charAt(t+3)==="-"){var s=e.indexOf("-->",t+4);return s>t?(n.comment(e,t+4,s-t-4),s+3):(r.error("Unclosed comment"),-1)}return-1;default:if(e.substr(t+3,6)=="CDATA["){var s=e.indexOf("]]>",t+9);return n.startCDATA(),n.characters(e,t+9,s-t-9),n.endCDATA(),s+3}var o=C(e,t),u=o.length;if(u>1&&/!doctype/i.test(o[0][0])){var a=o[1][0],f=u>3&&/^public$/i.test(o[2][0])&&o[3][0],l=u>4&&o[4][0],c=o[u-1];return n.startDTD(a,f&&f.replace(/^(['"])(.*?)\1$/,"$2"),l&&l.replace(/^(['"])(.*?)\1$/,"$2")),n.endDTD(),c.index+c[0].length}}return-1}function x(e,t,n){var r=e.indexOf("?>",t);if(r){var i=e.substring(t,r).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);if(i){var s=i[0].length;return n.processingInstruction(i[1],i[2]),r+2}return-1}return-1}function T(e){}function N(e,t){return e.__proto__=t,e}function C(e,t){var n,r=[],i=/'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;i.lastIndex=t,i.exec(e);while(n=i.exec(e)){r.push(n);if(n[1])return r}}var r=/[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/,i=new RegExp("[\\-\\.0-9"+r.source.slice(1,-1)+"\u00b7\u0300-\u036f\\ux203F-\u2040]"),s=new RegExp("^"+r.source+i.source+"*(?::"+r.source+i.source+"*)?$"),o=0,u=1,a=2,f=3,l=4,c=5,h=6,p=7;return d.prototype={parse:function(e,t,n){var r=this.domBuilder;r.startDocument(),E(t,t={}),v(e,t,n,r,this.errorHandler),r.endDocument()}},T.prototype={setTagName:function(e){if(!s.test(e))throw new Error("invalid tagName:"+e);this.tagName=e},add:function(e,t,n){if(!s.test(e))throw new Error("invalid attribute:"+e);this[this.length++]={qName:e,value:t,offset:n}},length:0,getLocalName:function(e){return this[e].localName},getOffset:function(e){return this[e].offset},getQName:function(e){return this[e].qName},getURI:function(e){return this[e].uri},getValue:function(e){return this[e].value}},N({},N.prototype)instanceof N||(N=function(e,t){function n(){}n.prototype=t,n=new n;for(t in e)n[t]=e[t];return n}),d}),ace.define("ace/mode/xml/dom",[],function(e,t,n){function r(e,t){for(var n in e)t[n]=e[n]}function i(e,t){var n=function(){},i=e.prototype;if(Object.create){var s=Object.create(t.prototype);i.__proto__=s}i instanceof t||(n.prototype=t.prototype,n=new n,r(i,n),e.prototype=i=n),i.constructor!=e&&(typeof e!="function"&&console.error("unknown Class:"+e),i.constructor=e)}function B(e,t){if(t instanceof Error)var n=t;else n=this,Error.call(this,w[e]),this.message=w[e],Error.captureStackTrace&&Error.captureStackTrace(this,B);return n.code=e,t&&(this.message=this.message+": "+t),n}function j(){}function F(e,t){this._node=e,this._refresh=t,I(this)}function I(e){var t=e._node._inc||e._node.ownerDocument._inc;if(e._inc!=t){var n=e._refresh(e._node);gt(e,"length",n.length),r(n,e),e._inc=t}}function q(){}function R(e,t){var n=e.length;while(n--)if(e[n]===t)return n}function U(e,t,n,r){r?t[R(t,r)]=n:t[t.length++]=n;if(e){n.ownerElement=e;var i=e.ownerDocument;i&&(r&&Q(i,e,r),K(i,e,n))}}function z(e,t,n){var r=R(t,n);if(!(r>=0))throw new B(L,new Error);var i=t.length-1;while(r<i)t[r]=t[++r];t.length=i;if(e){var s=e.ownerDocument;s&&(Q(s,e,n),n.ownerElement=null)}}function W(e){this._features={};if(e)for(var t in e)this._features=e[t]}function X(){}function V(e){return e=="<"&&"&lt;"||e==">"&&"&gt;"||e=="&"&&"&amp;"||e=='"'&&"&quot;"||"&#"+e.charCodeAt()+";"}function $(e,t){if(t(e))return!0;if(e=e.firstChild)do if($(e,t))return!0;while(e=e.nextSibling)}function J(){}function K(e,t,n){e&&e._inc++;var r=n.namespaceURI;r=="http://www.w3.org/2000/xmlns/"&&(t._nsMap[n.prefix?n.localName:""]=n.value)}function Q(e,t,n,r){e&&e._inc++;var i=n.namespaceURI;i=="http://www.w3.org/2000/xmlns/"&&delete t._nsMap[n.prefix?n.localName:""]}function G(e,t,n){if(e&&e._inc){e._inc++;var r=t.childNodes;if(n)r[r.length++]=n;else{var i=t.firstChild,s=0;while(i)r[s++]=i,i=i.nextSibling;r.length=s}}}function Y(e,t){var n=t.previousSibling,r=t.nextSibling;return n?n.nextSibling=r:e.firstChild=r,r?r.previousSibling=n:e.lastChild=n,G(e.ownerDocument,e),t}function Z(e,t,n){var r=t.parentNode;r&&r.removeChild(t);if(t.nodeType===g){var i=t.firstChild;if(i==null)return t;var s=t.lastChild}else i=s=t;var o=n?n.previousSibling:e.lastChild;i.previousSibling=o,s.nextSibling=n,o?o.nextSibling=i:e.firstChild=i,n==null?e.lastChild=s:n.previousSibling=s;do i.parentNode=e;while(i!==s&&(i=i.nextSibling));return G(e.ownerDocument||e,e),t.nodeType==g&&(t.firstChild=t.lastChild=null),t}function et(e,t){var n=t.parentNode;if(n){var r=e.lastChild;n.removeChild(t);var r=e.lastChild}var r=e.lastChild;return t.parentNode=e,t.previousSibling=r,t.nextSibling=null,r?r.nextSibling=t:e.firstChild=t,e.lastChild=t,G(e.ownerDocument,e,t),t}function tt(){this._nsMap={}}function nt(){}function rt(){}function it(){}function st(){}function ot(){}function ut(){}function at(){}function ft(){}function lt(){}function ct(){}function ht(){}function pt(){}function dt(e,t){switch(e.nodeType){case u:var n=e.attributes,r=n.length,i=e.firstChild,o=e.tagName,h=s===e.namespaceURI;t.push("<",o);for(var y=0;y<r;y++)dt(n.item(y),t);if(i||h&&!/^(?:meta|link|img|br|hr|input|button)$/i.test(o)){t.push(">");if(h&&/^script$/i.test(o))i&&t.push(i.data);else while(i)dt(i,t),i=i.nextSibling;t.push("</",o,">")}else t.push("/>");return;case v:case g:var i=e.firstChild;while(i)dt(i,t),i=i.nextSibling;return;case a:return t.push(" ",e.name,'="',e.value.replace(/[<&"]/g,V),'"');case f:return t.push(e.data.replace(/[<&]/g,V));case l:return t.push("<![CDATA[",e.data,"]]>");case d:return t.push("<!--",e.data,"-->");case m:var b=e.publicId,w=e.systemId;t.push("<!DOCTYPE ",e.name);if(b)t.push(' PUBLIC "',b),w&&w!="."&&t.push('" "',w),t.push('">');else if(w&&w!=".")t.push(' SYSTEM "',w,'">');else{var E=e.internalSubset;E&&t.push(" [",E,"]"),t.push(">")}return;case p:return t.push("<?",e.target," ",e.data,"?>");case c:return t.push("&",e.nodeName,";");default:t.push("??",e.nodeName)}}function vt(e,t,n){var r;switch(t.nodeType){case u:r=t.cloneNode(!1),r.ownerDocument=e;case g:break;case a:n=!0}r||(r=t.cloneNode(!1)),r.ownerDocument=e,r.parentNode=null;if(n){var i=t.firstChild;while(i)r.appendChild(vt(e,i,n)),i=i.nextSibling}return r}function mt(e,t,n){var r=new t.constructor;for(var i in t){var s=t[i];typeof s!="object"&&s!=r[i]&&(r[i]=s)}t.childNodes&&(r.childNodes=new j),r.ownerDocument=e;switch(r.nodeType){case u:var o=t.attributes,f=r.attributes=new q,l=o.length;f._ownerElement=r;for(var c=0;c<l;c++)r.setAttributeNode(mt(e,o.item(c),!0));break;case a:n=!0}if(n){var h=t.firstChild;while(h)r.appendChild(mt(e,h,n)),h=h.nextSibling}return r}function gt(e,t,n){e[t]=n}function yt(e){switch(e.nodeType){case 1:case 11:var t=[];e=e.firstChild;while(e)e.nodeType!==7&&e.nodeType!==8&&t.push(yt(e)),e=e.nextSibling;return t.join("");default:return e.nodeValue}}var s="http://www.w3.org/1999/xhtml",o={},u=o.ELEMENT_NODE=1,a=o.ATTRIBUTE_NODE=2,f=o.TEXT_NODE=3,l=o.CDATA_SECTION_NODE=4,c=o.ENTITY_REFERENCE_NODE=5,h=o.ENTITY_NODE=6,p=o.PROCESSING_INSTRUCTION_NODE=7,d=o.COMMENT_NODE=8,v=o.DOCUMENT_NODE=9,m=o.DOCUMENT_TYPE_NODE=10,g=o.DOCUMENT_FRAGMENT_NODE=11,y=o.NOTATION_NODE=12,b={},w={},E=b.INDEX_SIZE_ERR=(w[1]="Index size error",1),S=b.DOMSTRING_SIZE_ERR=(w[2]="DOMString size error",2),x=b.HIERARCHY_REQUEST_ERR=(w[3]="Hierarchy request error",3),T=b.WRONG_DOCUMENT_ERR=(w[4]="Wrong document",4),N=b.INVALID_CHARACTER_ERR=(w[5]="Invalid character",5),C=b.NO_DATA_ALLOWED_ERR=(w[6]="No data allowed",6),k=b.NO_MODIFICATION_ALLOWED_ERR=(w[7]="No modification allowed",7),L=b.NOT_FOUND_ERR=(w[8]="Not found",8),A=b.NOT_SUPPORTED_ERR=(w[9]="Not supported",9),O=b.INUSE_ATTRIBUTE_ERR=(w[10]="Attribute in use",10),M=b.INVALID_STATE_ERR=(w[11]="Invalid state",11),_=b.SYNTAX_ERR=(w[12]="Syntax error",12),D=b.INVALID_MODIFICATION_ERR=(w[13]="Invalid modification",13),P=b.NAMESPACE_ERR=(w[14]="Invalid namespace",14),H=b.INVALID_ACCESS_ERR=(w[15]="Invalid access",15);B.prototype=Error.prototype,r(b,B),j.prototype={length:0,item:function(e){return this[e]||null}},F.prototype.item=function(e){return I(this),this[e]},i(F,j),q.prototype={length:0,item:j.prototype.item,getNamedItem:function(e){var t=this.length;while(t--){var n=this[t];if(n.nodeName==e)return n}},setNamedItem:function(e){var t=e.ownerElement;if(t&&t!=this._ownerElement)throw new B(O);var n=this.getNamedItem(e.nodeName);return U(this._ownerElement,this,e,n),n},setNamedItemNS:function(e){var t=e.ownerElement,n;if(t&&t!=this._ownerElement)throw new B(O);return n=this.getNamedItemNS(e.namespaceURI,e.localName),U(this._ownerElement,this,e,n),n},removeNamedItem:function(e){var t=this.getNamedItem(e);return z(this._ownerElement,this,t),t},removeNamedItemNS:function(e,t){var n=this.getNamedItemNS(e,t);return z(this._ownerElement,this,n),n},getNamedItemNS:function(e,t){var n=this.length;while(n--){var r=this[n];if(r.localName==t&&r.namespaceURI==e)return r}return null}},W.prototype={hasFeature:function(e,t){var n=this._features[e.toLowerCase()];return n&&(!t||t in n)?!0:!1},createDocument:function(e,t,n){var r=new J;r.implementation=this,r.childNodes=new j,r.doctype=n,n&&r.appendChild(n);if(t){var i=r.createElementNS(e,t);r.appendChild(i)}return r},createDocumentType:function(e,t,n){var r=new ut;return r.name=e,r.nodeName=e,r.publicId=t,r.systemId=n,r}},X.prototype={firstChild:null,lastChild:null,previousSibling:null,nextSibling:null,attributes:null,parentNode:null,childNodes:null,ownerDocument:null,nodeValue:null,namespaceURI:null,prefix:null,localName:null,insertBefore:function(e,t){return Z(this,e,t)},replaceChild:function(e,t){this.insertBefore(e,t),t&&this.removeChild(t)},removeChild:function(e){return Y(this,e)},appendChild:function(e){return this.insertBefore(e,null)},hasChildNodes:function(){return this.firstChild!=null},cloneNode:function(e){return mt(this.ownerDocument||this,this,e)},normalize:function(){var e=this.firstChild;while(e){var t=e.nextSibling;t&&t.nodeType==f&&e.nodeType==f?(this.removeChild(t),e.appendData(t.data)):(e.normalize(),e=t)}},isSupported:function(e,t){return this.ownerDocument.implementation.hasFeature(e,t)},hasAttributes:function(){return this.attributes.length>0},lookupPrefix:function(e){var t=this;while(t){var n=t._nsMap;if(n)for(var r in n)if(n[r]==e)return r;t=t.nodeType==2?t.ownerDocument:t.parentNode}return null},lookupNamespaceURI:function(e){var t=this;while(t){var n=t._nsMap;if(n&&e in n)return n[e];t=t.nodeType==2?t.ownerDocument:t.parentNode}return null},isDefaultNamespace:function(e){var t=this.lookupPrefix(e);return t==null}},r(o,X),r(o,X.prototype),J.prototype={nodeName:"#document",nodeType:v,doctype:null,documentElement:null,_inc:1,insertBefore:function(e,t){if(e.nodeType==g){var n=e.firstChild;while(n){var r=n.nextSibling;this.insertBefore(n,t),n=r}return e}return this.documentElement==null&&e.nodeType==1&&(this.documentElement=e),Z(this,e,t),e.ownerDocument=this,e},removeChild:function(e){return this.documentElement==e&&(this.documentElement=null),Y(this,e)},importNode:function(e,t){return vt(this,e,t)},getElementById:function(e){var t=null;return $(this.documentElement,function(n){if(n.nodeType==1&&n.getAttribute("id")==e)return t=n,!0}),t},createElement:function(e){var t=new tt;t.ownerDocument=this,t.nodeName=e,t.tagName=e,t.childNodes=new j;var n=t.attributes=new q;return n._ownerElement=t,t},createDocumentFragment:function(){var e=new ct;return e.ownerDocument=this,e.childNodes=new j,e},createTextNode:function(e){var t=new it;return t.ownerDocument=this,t.appendData(e),t},createComment:function(e){var t=new st;return t.ownerDocument=this,t.appendData(e),t},createCDATASection:function(e){var t=new ot;return t.ownerDocument=this,t.appendData(e),t},createProcessingInstruction:function(e,t){var n=new ht;return n.ownerDocument=this,n.tagName=n.target=e,n.nodeValue=n.data=t,n},createAttribute:function(e){var t=new nt;return t.ownerDocument=this,t.name=e,t.nodeName=e,t.localName=e,t.specified=!0,t},createEntityReference:function(e){var t=new lt;return t.ownerDocument=this,t.nodeName=e,t},createElementNS:function(e,t){var n=new tt,r=t.split(":"),i=n.attributes=new q;return n.childNodes=new j,n.ownerDocument=this,n.nodeName=t,n.tagName=t,n.namespaceURI=e,r.length==2?(n.prefix=r[0],n.localName=r[1]):n.localName=t,i._ownerElement=n,n},createAttributeNS:function(e,t){var n=new nt,r=t.split(":");return n.ownerDocument=this,n.nodeName=t,n.name=t,n.namespaceURI=e,n.specified=!0,r.length==2?(n.prefix=r[0],n.localName=r[1]):n.localName=t,n}},i(J,X),tt.prototype={nodeType:u,hasAttribute:function(e){return this.getAttributeNode(e)!=null},getAttribute:function(e){var t=this.getAttributeNode(e);return t&&t.value||""},getAttributeNode:function(e){return this.attributes.getNamedItem(e)},setAttribute:function(e,t){var n=this.ownerDocument.createAttribute(e);n.value=n.nodeValue=""+t,this.setAttributeNode(n)},removeAttribute:function(e){var t=this.getAttributeNode(e);t&&this.removeAttributeNode(t)},appendChild:function(e){return e.nodeType===g?this.insertBefore(e,null):et(this,e)},setAttributeNode:function(e){return this.attributes.setNamedItem(e)},setAttributeNodeNS:function(e){return this.attributes.setNamedItemNS(e)},removeAttributeNode:function(e){return this.attributes.removeNamedItem(e.nodeName)},removeAttributeNS:function(e,t){var n=this.getAttributeNodeNS(e,t);n&&this.removeAttributeNode(n)},hasAttributeNS:function(e,t){return this.getAttributeNodeNS(e,t)!=null},getAttributeNS:function(e,t){var n=this.getAttributeNodeNS(e,t);return n&&n.value||""},setAttributeNS:function(e,t,n){var r=this.ownerDocument.createAttributeNS(e,t);r.value=r.nodeValue=""+n,this.setAttributeNode(r)},getAttributeNodeNS:function(e,t){return this.attributes.getNamedItemNS(e,t)},getElementsByTagName:function(e){return new F(this,function(t){var n=[];return $(t,function(r){r!==t&&r.nodeType==u&&(e==="*"||r.tagName==e)&&n.push(r)}),n})},getElementsByTagNameNS:function(e,t){return new F(this,function(n){var r=[];return $(n,function(i){i!==n&&i.nodeType===u&&(e==="*"||i.namespaceURI===e)&&(t==="*"||i.localName==t)&&r.push(i)}),r})}},J.prototype.getElementsByTagName=tt.prototype.getElementsByTagName,J.prototype.getElementsByTagNameNS=tt.prototype.getElementsByTagNameNS,i(tt,X),nt.prototype.nodeType=a,i(nt,X),rt.prototype={data:"",substringData:function(e,t){return this.data.substring(e,e+t)},appendData:function(e){e=this.data+e,this.nodeValue=this.data=e,this.length=e.length},insertData:function(e,t){this.replaceData(e,0,t)},appendChild:function(e){throw new Error(w[3])},deleteData:function(e,t){this.replaceData(e,t,"")},replaceData:function(e,t,n){var r=this.data.substring(0,e),i=this.data.substring(e+t);n=r+n+i,this.nodeValue=this.data=n,this.length=n.length}},i(rt,X),it.prototype={nodeName:"#text",nodeType:f,splitText:function(e){var t=this.data,n=t.substring(e);t=t.substring(0,e),this.data=this.nodeValue=t,this.length=t.length;var r=this.ownerDocument.createTextNode(n);return this.parentNode&&this.parentNode.insertBefore(r,this.nextSibling),r}},i(it,rt),st.prototype={nodeName:"#comment",nodeType:d},i(st,rt),ot.prototype={nodeName:"#cdata-section",nodeType:l},i(ot,rt),ut.prototype.nodeType=m,i(ut,X),at.prototype.nodeType=y,i(at,X),ft.prototype.nodeType=h,i(ft,X),lt.prototype.nodeType=c,i(lt,X),ct.prototype.nodeName="#document-fragment",ct.prototype.nodeType=g,i(ct,X),ht.prototype.nodeType=p,i(ht,X),pt.prototype.serializeToString=function(e){var t=[];return dt(e,t),t.join("")},X.prototype.toString=function(){return pt.prototype.serializeToString(this)};try{Object.defineProperty&&(Object.defineProperty(F.prototype,"length",{get:function(){return I(this),this.$$length}}),Object.defineProperty(X.prototype,"textContent",{get:function(){return yt(this)},set:function(e){switch(this.nodeType){case 1:case 11:while(this.firstChild)this.removeChild(this.firstChild);(e||String(e))&&this.appendChild(this.ownerDocument.createTextNode(e));break;default:this.data=e,this.value=value,this.nodeValue=e}}}),gt=function(e,t,n){e["$$"+t]=n})}catch(bt){}return W}),ace.define("ace/mode/xml/dom-parser",[],function(e,t,n){"use strict";function s(e){this.options=e||{locator:{}}}function o(e,t,n){function s(t){var s=e[t];if(!s)if(i)s=e.length==2?function(n){e(t,n)}:e;else{var o=arguments.length;while(--o)if(s=e[arguments[o]])break}r[t]=s&&function(e){s(e+f(n),e,n)}||function(){}}if(!e){if(t instanceof u)return t;e=t}var r={},i=e instanceof Function;return n=n||{},s("warning","warn"),s("error","warn","warning"),s("fatalError","warn","warning","error"),r}function u(){this.cdata=!1}function a(e,t){t.lineNumber=e.lineNumber,t.columnNumber=e.columnNumber}function f(e){if(e)return"\n@"+(e.systemId||"")+"#[line:"+e.lineNumber+",col:"+e.columnNumber+"]"}function l(e,t,n){return typeof e=="string"?e.substr(t,n):e.length>=t+n||t?new java.lang.String(e,t,n)+"":e}function c(e,t){e.currentElement?e.currentElement.appendChild(t):e.document.appendChild(t)}var r=e("./sax"),i=e("./dom");return s.prototype.parseFromString=function(e,t){var n=this.options,i=new r,s=n.domBuilder||new u,a=n.errorHandler,f=n.locator,l=n.xmlns||{},c={lt:"<",gt:">",amp:"&",quot:'"',apos:"'"};return f&&s.setDocumentLocator(f),i.errorHandler=o(a,s,f),i.domBuilder=n.domBuilder||s,/\/x?html?$/.test(t)&&(c.nbsp="\u00a0",c.copy="\u00a9",l[""]="http://www.w3.org/1999/xhtml"),e?i.parse(e,l,c):i.errorHandler.error("invalid document source"),s.document},u.prototype={startDocument:function(){this.document=(new i).createDocument(null,null,null),this.locator&&(this.document.documentURI=this.locator.systemId)},startElement:function(e,t,n,r){var i=this.document,s=i.createElementNS(e,n||t),o=r.length;c(this,s),this.currentElement=s,this.locator&&a(this.locator,s);for(var u=0;u<o;u++){var e=r.getURI(u),f=r.getValue(u),n=r.getQName(u),l=i.createAttributeNS(e,n);l.getOffset&&a(l.getOffset(1),l),l.value=l.nodeValue=f,s.setAttributeNode(l)}},endElement:function(e,t,n){var r=this.currentElement,i=r.tagName;this.currentElement=r.parentNode},startPrefixMapping:function(e,t){},endPrefixMapping:function(e){},processingInstruction:function(e,t){var n=this.document.createProcessingInstruction(e,t);this.locator&&a(this.locator,n),c(this,n)},ignorableWhitespace:function(e,t,n){},characters:function(e,t,n){e=l.apply(this,arguments);if(this.currentElement&&e){if(this.cdata){var r=this.document.createCDATASection(e);this.currentElement.appendChild(r)}else{var r=this.document.createTextNode(e);this.currentElement.appendChild(r)}this.locator&&a(this.locator,r)}},skippedEntity:function(e){},endDocument:function(){this.document.normalize()},setDocumentLocator:function(e){if(this.locator=e)e.lineNumber=0},comment:function(e,t,n){e=l.apply(this,arguments);var r=this.document.createComment(e);this.locator&&a(this.locator,r),c(this,r)},startCDATA:function(){this.cdata=!0},endCDATA:function(){this.cdata=!1},startDTD:function(e,t,n){var r=this.document.implementation;if(r&&r.createDocumentType){var i=r.createDocumentType(e,t,n);this.locator&&a(this.locator,i),c(this,i)}},warning:function(e){console.warn(e,f(this.locator))},error:function(e){console.error(e,f(this.locator))},fatalError:function(e){throw console.error(e,f(this.locator)),e}},"endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(e){u.prototype[e]=function(){return null}}),{DOMParser:s}}),ace.define("ace/mode/xml_worker",[],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("../worker/mirror").Mirror,o=e("./xml/dom-parser").DOMParser,u=t.Worker=function(e){s.call(this,e),this.setTimeout(400),this.context=null};r.inherits(u,s),function(){this.setOptions=function(e){this.context=e.context},this.onUpdate=function(){var e=this.doc.getValue();if(!e)return;var t=new o,n=[];t.options.errorHandler={fatalError:function(e,t,r){n.push({row:r.lineNumber,column:r.columnNumber,text:t,type:"error"})},error:function(e,t,r){n.push({row:r.lineNumber,column:r.columnNumber,text:t,type:"error"})},warning:function(e,t,r){n.push({row:r.lineNumber,column:r.columnNumber,text:t,type:"warning"})}},t.parseFromString(e),this.sender.emit("error",n)}}.call(u.prototype)}),ace.define("ace/lib/es5-shim",[],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)=="[object Array]"});var m=Object("a"),g=m[0]!="a"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _=" \n\x0b\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";if(!String.prototype.trim||_.trim()){_="["+_+"]";var D=new RegExp("^"+_+_+"*"),P=new RegExp(_+_+"*$");String.prototype.trim=function(){return String(this).replace(D,"").replace(P,"")}}var F=function(e){if(e==null)throw new TypeError("can't convert "+e+" to object");return Object(e)}}) \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/d3/d3.v3.min.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/d3/d3.v3.min.js new file mode 100644 index 0000000..2542ced --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/d3/d3.v3.min.js @@ -0,0 +1,4 @@ +(function(){function t(t){return t.target}function n(t){return t.source}function e(t,n){try{for(var e in n)Object.defineProperty(t.prototype,e,{value:n[e],enumerable:!1})}catch(r){t.prototype=n}}function r(t){for(var n=-1,e=t.length,r=[];e>++n;)r.push(t[n]);return r}function i(t){return Array.prototype.slice.call(t)}function u(){}function a(t){return t}function o(){return!0}function c(t){return"function"==typeof t?t:function(){return t}}function l(t,n,e){return function(){var r=e.apply(n,arguments);return arguments.length?t:r}}function s(t){return null!=t&&!isNaN(t)}function f(t){return t.length}function h(t){return t.trim().replace(/\s+/g," ")}function d(t){for(var n=1;t*n%1;)n*=10;return n}function g(t){return 1===t.length?function(n,e){t(null==n?e:null)}:t}function p(t){return t.responseText}function m(t){return JSON.parse(t.responseText)}function v(t){var n=document.createRange();return n.selectNode(document.body),n.createContextualFragment(t.responseText)}function y(t){return t.responseXML}function M(){}function b(t){function n(){for(var n,r=e,i=-1,u=r.length;u>++i;)(n=r[i].on)&&n.apply(this,arguments);return t}var e=[],r=new u;return n.on=function(n,i){var u,a=r.get(n);return 2>arguments.length?a&&a.on:(a&&(a.on=null,e=e.slice(0,u=e.indexOf(a)).concat(e.slice(u+1)),r.remove(n)),i&&e.push(r.set(n,{on:i})),t)},n}function x(t,n){return n-(t?1+Math.floor(Math.log(t+Math.pow(10,1+Math.floor(Math.log(t)/Math.LN10)-n))/Math.LN10):1)}function _(t){return t+""}function w(t,n){var e=Math.pow(10,3*Math.abs(8-n));return{scale:n>8?function(t){return t/e}:function(t){return t*e},symbol:t}}function S(t){return function(n){return 0>=n?0:n>=1?1:t(n)}}function k(t){return function(n){return 1-t(1-n)}}function E(t){return function(n){return.5*(.5>n?t(2*n):2-t(2-2*n))}}function A(t){return t*t}function N(t){return t*t*t}function T(t){if(0>=t)return 0;if(t>=1)return 1;var n=t*t,e=n*t;return 4*(.5>t?e:3*(t-n)+e-.75)}function q(t){return function(n){return Math.pow(n,t)}}function C(t){return 1-Math.cos(t*Ru/2)}function z(t){return Math.pow(2,10*(t-1))}function D(t){return 1-Math.sqrt(1-t*t)}function L(t,n){var e;return 2>arguments.length&&(n=.45),arguments.length?e=n/(2*Ru)*Math.asin(1/t):(t=1,e=n/4),function(r){return 1+t*Math.pow(2,10*-r)*Math.sin(2*(r-e)*Ru/n)}}function F(t){return t||(t=1.70158),function(n){return n*n*((t+1)*n-t)}}function H(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375}function R(){d3.event.stopPropagation(),d3.event.preventDefault()}function P(){for(var t,n=d3.event;t=n.sourceEvent;)n=t;return n}function j(t){for(var n=new M,e=0,r=arguments.length;r>++e;)n[arguments[e]]=b(n);return n.of=function(e,r){return function(i){try{var u=i.sourceEvent=d3.event;i.target=t,d3.event=i,n[i.type].apply(e,r)}finally{d3.event=u}}},n}function O(t){var n=[t.a,t.b],e=[t.c,t.d],r=U(n),i=Y(n,e),u=U(I(e,n,-i))||0;n[0]*e[1]<e[0]*n[1]&&(n[0]*=-1,n[1]*=-1,r*=-1,i*=-1),this.rotate=(r?Math.atan2(n[1],n[0]):Math.atan2(-e[0],e[1]))*Ou,this.translate=[t.e,t.f],this.scale=[r,u],this.skew=u?Math.atan2(i,u)*Ou:0}function Y(t,n){return t[0]*n[0]+t[1]*n[1]}function U(t){var n=Math.sqrt(Y(t,t));return n&&(t[0]/=n,t[1]/=n),n}function I(t,n,e){return t[0]+=e*n[0],t[1]+=e*n[1],t}function V(t){return"transform"==t?d3.interpolateTransform:d3.interpolate}function X(t,n){return n=n-(t=+t)?1/(n-t):0,function(e){return(e-t)*n}}function Z(t,n){return n=n-(t=+t)?1/(n-t):0,function(e){return Math.max(0,Math.min(1,(e-t)*n))}}function B(){}function $(t,n,e){return new J(t,n,e)}function J(t,n,e){this.r=t,this.g=n,this.b=e}function G(t){return 16>t?"0"+Math.max(0,t).toString(16):Math.min(255,t).toString(16)}function K(t,n,e){var r,i,u,a=0,o=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(t))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return n(nn(i[0]),nn(i[1]),nn(i[2]))}return(u=aa.get(t))?n(u.r,u.g,u.b):(null!=t&&"#"===t.charAt(0)&&(4===t.length?(a=t.charAt(1),a+=a,o=t.charAt(2),o+=o,c=t.charAt(3),c+=c):7===t.length&&(a=t.substring(1,3),o=t.substring(3,5),c=t.substring(5,7)),a=parseInt(a,16),o=parseInt(o,16),c=parseInt(c,16)),n(a,o,c))}function W(t,n,e){var r,i,u=Math.min(t/=255,n/=255,e/=255),a=Math.max(t,n,e),o=a-u,c=(a+u)/2;return o?(i=.5>c?o/(a+u):o/(2-a-u),r=t==a?(n-e)/o+(e>n?6:0):n==a?(e-t)/o+2:(t-n)/o+4,r*=60):i=r=0,en(r,i,c)}function Q(t,n,e){t=tn(t),n=tn(n),e=tn(e);var r=gn((.4124564*t+.3575761*n+.1804375*e)/sa),i=gn((.2126729*t+.7151522*n+.072175*e)/fa),u=gn((.0193339*t+.119192*n+.9503041*e)/ha);return ln(116*i-16,500*(r-i),200*(i-u))}function tn(t){return.04045>=(t/=255)?t/12.92:Math.pow((t+.055)/1.055,2.4)}function nn(t){var n=parseFloat(t);return"%"===t.charAt(t.length-1)?Math.round(2.55*n):n}function en(t,n,e){return new rn(t,n,e)}function rn(t,n,e){this.h=t,this.s=n,this.l=e}function un(t,n,e){function r(t){return t>360?t-=360:0>t&&(t+=360),60>t?u+(a-u)*t/60:180>t?a:240>t?u+(a-u)*(240-t)/60:u}function i(t){return Math.round(255*r(t))}var u,a;return t%=360,0>t&&(t+=360),n=0>n?0:n>1?1:n,e=0>e?0:e>1?1:e,a=.5>=e?e*(1+n):e+n-e*n,u=2*e-a,$(i(t+120),i(t),i(t-120))}function an(t,n,e){return new on(t,n,e)}function on(t,n,e){this.h=t,this.c=n,this.l=e}function cn(t,n,e){return ln(e,Math.cos(t*=ju)*n,Math.sin(t)*n)}function ln(t,n,e){return new sn(t,n,e)}function sn(t,n,e){this.l=t,this.a=n,this.b=e}function fn(t,n,e){var r=(t+16)/116,i=r+n/500,u=r-e/200;return i=dn(i)*sa,r=dn(r)*fa,u=dn(u)*ha,$(pn(3.2404542*i-1.5371385*r-.4985314*u),pn(-.969266*i+1.8760108*r+.041556*u),pn(.0556434*i-.2040259*r+1.0572252*u))}function hn(t,n,e){return an(180*(Math.atan2(e,n)/Ru),Math.sqrt(n*n+e*e),t)}function dn(t){return t>.206893034?t*t*t:(t-4/29)/7.787037}function gn(t){return t>.008856?Math.pow(t,1/3):7.787037*t+4/29}function pn(t){return Math.round(255*(.00304>=t?12.92*t:1.055*Math.pow(t,1/2.4)-.055))}function mn(t){return Iu(t,Ma),t}function vn(t){return function(){return ga(t,this)}}function yn(t){return function(){return pa(t,this)}}function Mn(t,n){function e(){this.removeAttribute(t)}function r(){this.removeAttributeNS(t.space,t.local)}function i(){this.setAttribute(t,n)}function u(){this.setAttributeNS(t.space,t.local,n)}function a(){var e=n.apply(this,arguments);null==e?this.removeAttribute(t):this.setAttribute(t,e)}function o(){var e=n.apply(this,arguments);null==e?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,e)}return t=d3.ns.qualify(t),null==n?t.local?r:e:"function"==typeof n?t.local?o:a:t.local?u:i}function bn(t){return RegExp("(?:^|\\s+)"+d3.requote(t)+"(?:\\s+|$)","g")}function xn(t,n){function e(){for(var e=-1;i>++e;)t[e](this,n)}function r(){for(var e=-1,r=n.apply(this,arguments);i>++e;)t[e](this,r)}t=t.trim().split(/\s+/).map(_n);var i=t.length;return"function"==typeof n?r:e}function _n(t){var n=bn(t);return function(e,r){if(i=e.classList)return r?i.add(t):i.remove(t);var i=e.className,u=null!=i.baseVal,a=u?i.baseVal:i;r?(n.lastIndex=0,n.test(a)||(a=h(a+" "+t),u?i.baseVal=a:e.className=a)):a&&(a=h(a.replace(n," ")),u?i.baseVal=a:e.className=a)}}function wn(t,n,e){function r(){this.style.removeProperty(t)}function i(){this.style.setProperty(t,n,e)}function u(){var r=n.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,e)}return null==n?r:"function"==typeof n?u:i}function Sn(t,n){function e(){delete this[t]}function r(){this[t]=n}function i(){var e=n.apply(this,arguments);null==e?delete this[t]:this[t]=e}return null==n?e:"function"==typeof n?i:r}function kn(t){return{__data__:t}}function En(t){return function(){return ya(this,t)}}function An(t){return arguments.length||(t=d3.ascending),function(n,e){return t(n&&n.__data__,e&&e.__data__)}}function Nn(t,n,e){function r(){var n=this[u];n&&(this.removeEventListener(t,n,n.$),delete this[u])}function i(){function i(t){var e=d3.event;d3.event=t,o[0]=a.__data__;try{n.apply(a,o)}finally{d3.event=e}}var a=this,o=Yu(arguments);r.call(this),this.addEventListener(t,this[u]=i,i.$=e),i._=n}var u="__on"+t,a=t.indexOf(".");return a>0&&(t=t.substring(0,a)),n?i:r}function Tn(t,n){for(var e=0,r=t.length;r>e;e++)for(var i,u=t[e],a=0,o=u.length;o>a;a++)(i=u[a])&&n(i,a,e);return t}function qn(t){return Iu(t,xa),t}function Cn(t,n){return Iu(t,wa),t.id=n,t}function zn(t,n,e,r){var i=t.__transition__||(t.__transition__={active:0,count:0}),a=i[e];if(!a){var o=r.time;return a=i[e]={tween:new u,event:d3.dispatch("start","end"),time:o,ease:r.ease,delay:r.delay,duration:r.duration},++i.count,d3.timer(function(r){function u(r){return i.active>e?l():(i.active=e,h.start.call(t,s,n),a.tween.forEach(function(e,r){(r=r.call(t,s,n))&&p.push(r)}),c(r)||d3.timer(c,0,o),1)}function c(r){if(i.active!==e)return l();for(var u=(r-d)/g,a=f(u),o=p.length;o>0;)p[--o].call(t,a);return u>=1?(l(),h.end.call(t,s,n),1):void 0}function l(){return--i.count?delete i[e]:delete t.__transition__,1}var s=t.__data__,f=a.ease,h=a.event,d=a.delay,g=a.duration,p=[];return r>=d?u(r):d3.timer(u,d,o),1},0,o),a}}function Dn(t){return null==t&&(t=""),function(){this.textContent=t}}function Ln(t,n,e,r){var i=t.id;return Tn(t,"function"==typeof e?function(t,u,a){t.__transition__[i].tween.set(n,r(e.call(t,t.__data__,u,a)))}:(e=r(e),function(t){t.__transition__[i].tween.set(n,e)}))}function Fn(){for(var t,n=Date.now(),e=qa;e;)t=n-e.then,t>=e.delay&&(e.flush=e.callback(t)),e=e.next;var r=Hn()-n;r>24?(isFinite(r)&&(clearTimeout(Aa),Aa=setTimeout(Fn,r)),Ea=0):(Ea=1,Ca(Fn))}function Hn(){for(var t=null,n=qa,e=1/0;n;)n.flush?(delete Ta[n.callback.id],n=t?t.next=n.next:qa=n.next):(e=Math.min(e,n.then+n.delay),n=(t=n).next);return e}function Rn(t,n){var e=t.ownerSVGElement||t;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>za&&(window.scrollX||window.scrollY)){e=d3.select(document.body).append("svg").style("position","absolute").style("top",0).style("left",0);var i=e[0][0].getScreenCTM();za=!(i.f||i.e),e.remove()}return za?(r.x=n.pageX,r.y=n.pageY):(r.x=n.clientX,r.y=n.clientY),r=r.matrixTransform(t.getScreenCTM().inverse()),[r.x,r.y]}var u=t.getBoundingClientRect();return[n.clientX-u.left-t.clientLeft,n.clientY-u.top-t.clientTop]}function Pn(){}function jn(t){var n=t[0],e=t[t.length-1];return e>n?[n,e]:[e,n]}function On(t){return t.rangeExtent?t.rangeExtent():jn(t.range())}function Yn(t,n){var e,r=0,i=t.length-1,u=t[r],a=t[i];return u>a&&(e=r,r=i,i=e,e=u,u=a,a=e),(n=n(a-u))&&(t[r]=n.floor(u),t[i]=n.ceil(a)),t}function Un(){return Math}function In(t,n,e,r){function i(){var i=Math.min(t.length,n.length)>2?Gn:Jn,c=r?Z:X;return a=i(t,n,c,e),o=i(n,t,c,d3.interpolate),u}function u(t){return a(t)}var a,o;return u.invert=function(t){return o(t)},u.domain=function(n){return arguments.length?(t=n.map(Number),i()):t},u.range=function(t){return arguments.length?(n=t,i()):n},u.rangeRound=function(t){return u.range(t).interpolate(d3.interpolateRound)},u.clamp=function(t){return arguments.length?(r=t,i()):r},u.interpolate=function(t){return arguments.length?(e=t,i()):e},u.ticks=function(n){return Bn(t,n)},u.tickFormat=function(n){return $n(t,n)},u.nice=function(){return Yn(t,Xn),i()},u.copy=function(){return In(t,n,e,r)},i()}function Vn(t,n){return d3.rebind(t,n,"range","rangeRound","interpolate","clamp")}function Xn(t){return t=Math.pow(10,Math.round(Math.log(t)/Math.LN10)-1),t&&{floor:function(n){return Math.floor(n/t)*t},ceil:function(n){return Math.ceil(n/t)*t}}}function Zn(t,n){var e=jn(t),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/n)/Math.LN10)),u=n/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Bn(t,n){return d3.range.apply(d3,Zn(t,n))}function $n(t,n){return d3.format(",."+Math.max(0,-Math.floor(Math.log(Zn(t,n)[2])/Math.LN10+.01))+"f")}function Jn(t,n,e,r){var i=e(t[0],t[1]),u=r(n[0],n[1]);return function(t){return u(i(t))}}function Gn(t,n,e,r){var i=[],u=[],a=0,o=Math.min(t.length,n.length)-1;for(t[o]<t[0]&&(t=t.slice().reverse(),n=n.slice().reverse());o>=++a;)i.push(e(t[a-1],t[a])),u.push(r(n[a-1],n[a]));return function(n){var e=d3.bisect(t,n,1,o)-1;return u[e](i[e](n))}}function Kn(t,n){function e(e){return t(n(e))}var r=n.pow;return e.invert=function(n){return r(t.invert(n))},e.domain=function(i){return arguments.length?(n=0>i[0]?Qn:Wn,r=n.pow,t.domain(i.map(n)),e):t.domain().map(r)},e.nice=function(){return t.domain(Yn(t.domain(),Un)),e},e.ticks=function(){var e=jn(t.domain()),i=[];if(e.every(isFinite)){var u=Math.floor(e[0]),a=Math.ceil(e[1]),o=r(e[0]),c=r(e[1]);if(n===Qn)for(i.push(r(u));a>u++;)for(var l=9;l>0;l--)i.push(r(u)*l);else{for(;a>u;u++)for(var l=1;10>l;l++)i.push(r(u)*l);i.push(r(u))}for(u=0;o>i[u];u++);for(a=i.length;i[a-1]>c;a--);i=i.slice(u,a)}return i},e.tickFormat=function(t,i){if(2>arguments.length&&(i=Da),!arguments.length)return i;var u,a=Math.max(.1,t/e.ticks().length),o=n===Qn?(u=-1e-12,Math.floor):(u=1e-12,Math.ceil);return function(t){return a>=t/r(o(n(t)+u))?i(t):""}},e.copy=function(){return Kn(t.copy(),n)},Vn(e,t)}function Wn(t){return Math.log(0>t?0:t)/Math.LN10}function Qn(t){return-Math.log(t>0?0:-t)/Math.LN10}function te(t,n){function e(n){return t(r(n))}var r=ne(n),i=ne(1/n);return e.invert=function(n){return i(t.invert(n))},e.domain=function(n){return arguments.length?(t.domain(n.map(r)),e):t.domain().map(i)},e.ticks=function(t){return Bn(e.domain(),t)},e.tickFormat=function(t){return $n(e.domain(),t)},e.nice=function(){return e.domain(Yn(e.domain(),Xn))},e.exponent=function(t){if(!arguments.length)return n;var u=e.domain();return r=ne(n=t),i=ne(1/n),e.domain(u)},e.copy=function(){return te(t.copy(),n)},Vn(e,t)}function ne(t){return function(n){return 0>n?-Math.pow(-n,t):Math.pow(n,t)}}function ee(t,n){function e(n){return a[((i.get(n)||i.set(n,t.push(n)))-1)%a.length]}function r(n,e){return d3.range(t.length).map(function(t){return n+e*t})}var i,a,o;return e.domain=function(r){if(!arguments.length)return t;t=[],i=new u;for(var a,o=-1,c=r.length;c>++o;)i.has(a=r[o])||i.set(a,t.push(a));return e[n.t].apply(e,n.a)},e.range=function(t){return arguments.length?(a=t,o=0,n={t:"range",a:arguments},e):a},e.rangePoints=function(i,u){2>arguments.length&&(u=0);var c=i[0],l=i[1],s=(l-c)/(Math.max(1,t.length-1)+u);return a=r(2>t.length?(c+l)/2:c+s*u/2,s),o=0,n={t:"rangePoints",a:arguments},e},e.rangeBands=function(i,u,c){2>arguments.length&&(u=0),3>arguments.length&&(c=u);var l=i[1]<i[0],s=i[l-0],f=i[1-l],h=(f-s)/(t.length-u+2*c);return a=r(s+h*c,h),l&&a.reverse(),o=h*(1-u),n={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(i,u,c){2>arguments.length&&(u=0),3>arguments.length&&(c=u);var l=i[1]<i[0],s=i[l-0],f=i[1-l],h=Math.floor((f-s)/(t.length-u+2*c)),d=f-s-(t.length-u)*h;return a=r(s+Math.round(d/2),h),l&&a.reverse(),o=Math.round(h*(1-u)),n={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return jn(n.a[0])},e.copy=function(){return ee(t,n)},e.domain(t)}function re(t,n){function e(){var e=0,u=n.length;for(i=[];u>++e;)i[e-1]=d3.quantile(t,e/u);return r}function r(t){return isNaN(t=+t)?0/0:n[d3.bisect(i,t)]}var i;return r.domain=function(n){return arguments.length?(t=n.filter(function(t){return!isNaN(t)}).sort(d3.ascending),e()):t},r.range=function(t){return arguments.length?(n=t,e()):n},r.quantiles=function(){return i},r.copy=function(){return re(t,n)},e()}function ie(t,n,e){function r(n){return e[Math.max(0,Math.min(a,Math.floor(u*(n-t))))]}function i(){return u=e.length/(n-t),a=e.length-1,r}var u,a;return r.domain=function(e){return arguments.length?(t=+e[0],n=+e[e.length-1],i()):[t,n]},r.range=function(t){return arguments.length?(e=t,i()):e},r.copy=function(){return ie(t,n,e)},i()}function ue(t,n){function e(e){return n[d3.bisect(t,e)]}return e.domain=function(n){return arguments.length?(t=n,e):t},e.range=function(t){return arguments.length?(n=t,e):n},e.copy=function(){return ue(t,n)},e}function ae(t){function n(t){return+t}return n.invert=n,n.domain=n.range=function(e){return arguments.length?(t=e.map(n),n):t},n.ticks=function(n){return Bn(t,n)},n.tickFormat=function(n){return $n(t,n)},n.copy=function(){return ae(t)},n}function oe(t){return t.innerRadius}function ce(t){return t.outerRadius}function le(t){return t.startAngle}function se(t){return t.endAngle}function fe(t){function n(n){function a(){s.push("M",u(t(f),l))}for(var o,s=[],f=[],h=-1,d=n.length,g=c(e),p=c(r);d>++h;)i.call(this,o=n[h],h)?f.push([+g.call(this,o,h),+p.call(this,o,h)]):f.length&&(a(),f=[]);return f.length&&a(),s.length?s.join(""):null}var e=he,r=de,i=o,u=ge,a=u.key,l=.7;return n.x=function(t){return arguments.length?(e=t,n):e},n.y=function(t){return arguments.length?(r=t,n):r},n.defined=function(t){return arguments.length?(i=t,n):i},n.interpolate=function(t){return arguments.length?(a="function"==typeof t?u=t:(u=Oa.get(t)||ge).key,n):a},n.tension=function(t){return arguments.length?(l=t,n):l},n}function he(t){return t[0]}function de(t){return t[1]}function ge(t){return t.join("L")}function pe(t){return ge(t)+"Z"}function me(t){for(var n=0,e=t.length,r=t[0],i=[r[0],",",r[1]];e>++n;)i.push("V",(r=t[n])[1],"H",r[0]);return i.join("")}function ve(t){for(var n=0,e=t.length,r=t[0],i=[r[0],",",r[1]];e>++n;)i.push("H",(r=t[n])[0],"V",r[1]);return i.join("")}function ye(t,n){return 4>t.length?ge(t):t[1]+xe(t.slice(1,t.length-1),_e(t,n))}function Me(t,n){return 3>t.length?ge(t):t[0]+xe((t.push(t[0]),t),_e([t[t.length-2]].concat(t,[t[1]]),n))}function be(t,n){return 3>t.length?ge(t):t[0]+xe(t,_e(t,n))}function xe(t,n){if(1>n.length||t.length!=n.length&&t.length!=n.length+2)return ge(t);var e=t.length!=n.length,r="",i=t[0],u=t[1],a=n[0],o=a,c=1;if(e&&(r+="Q"+(u[0]-2*a[0]/3)+","+(u[1]-2*a[1]/3)+","+u[0]+","+u[1],i=t[1],c=2),n.length>1){o=n[1],u=t[c],c++,r+="C"+(i[0]+a[0])+","+(i[1]+a[1])+","+(u[0]-o[0])+","+(u[1]-o[1])+","+u[0]+","+u[1];for(var l=2;n.length>l;l++,c++)u=t[c],o=n[l],r+="S"+(u[0]-o[0])+","+(u[1]-o[1])+","+u[0]+","+u[1]}if(e){var s=t[c];r+="Q"+(u[0]+2*o[0]/3)+","+(u[1]+2*o[1]/3)+","+s[0]+","+s[1]}return r}function _e(t,n){for(var e,r=[],i=(1-n)/2,u=t[0],a=t[1],o=1,c=t.length;c>++o;)e=u,u=a,a=t[o],r.push([i*(a[0]-e[0]),i*(a[1]-e[1])]);return r}function we(t){if(3>t.length)return ge(t);var n=1,e=t.length,r=t[0],i=r[0],u=r[1],a=[i,i,i,(r=t[1])[0]],o=[u,u,u,r[1]],c=[i,",",u];for(Ne(c,a,o);e>++n;)r=t[n],a.shift(),a.push(r[0]),o.shift(),o.push(r[1]),Ne(c,a,o);for(n=-1;2>++n;)a.shift(),a.push(r[0]),o.shift(),o.push(r[1]),Ne(c,a,o);return c.join("")}function Se(t){if(4>t.length)return ge(t);for(var n,e=[],r=-1,i=t.length,u=[0],a=[0];3>++r;)n=t[r],u.push(n[0]),a.push(n[1]);for(e.push(Ae(Ia,u)+","+Ae(Ia,a)),--r;i>++r;)n=t[r],u.shift(),u.push(n[0]),a.shift(),a.push(n[1]),Ne(e,u,a);return e.join("")}function ke(t){for(var n,e,r=-1,i=t.length,u=i+4,a=[],o=[];4>++r;)e=t[r%i],a.push(e[0]),o.push(e[1]);for(n=[Ae(Ia,a),",",Ae(Ia,o)],--r;u>++r;)e=t[r%i],a.shift(),a.push(e[0]),o.shift(),o.push(e[1]),Ne(n,a,o);return n.join("")}function Ee(t,n){var e=t.length-1;if(e)for(var r,i,u=t[0][0],a=t[0][1],o=t[e][0]-u,c=t[e][1]-a,l=-1;e>=++l;)r=t[l],i=l/e,r[0]=n*r[0]+(1-n)*(u+i*o),r[1]=n*r[1]+(1-n)*(a+i*c);return we(t)}function Ae(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]}function Ne(t,n,e){t.push("C",Ae(Ya,n),",",Ae(Ya,e),",",Ae(Ua,n),",",Ae(Ua,e),",",Ae(Ia,n),",",Ae(Ia,e))}function Te(t,n){return(n[1]-t[1])/(n[0]-t[0])}function qe(t){for(var n=0,e=t.length-1,r=[],i=t[0],u=t[1],a=r[0]=Te(i,u);e>++n;)r[n]=(a+(a=Te(i=u,u=t[n+1])))/2;return r[n]=a,r}function Ce(t){for(var n,e,r,i,u=[],a=qe(t),o=-1,c=t.length-1;c>++o;)n=Te(t[o],t[o+1]),1e-6>Math.abs(n)?a[o]=a[o+1]=0:(e=a[o]/n,r=a[o+1]/n,i=e*e+r*r,i>9&&(i=3*n/Math.sqrt(i),a[o]=i*e,a[o+1]=i*r));for(o=-1;c>=++o;)i=(t[Math.min(c,o+1)][0]-t[Math.max(0,o-1)][0])/(6*(1+a[o]*a[o])),u.push([i||0,a[o]*i||0]);return u}function ze(t){return 3>t.length?ge(t):t[0]+xe(t,Ce(t))}function De(t){for(var n,e,r,i=-1,u=t.length;u>++i;)n=t[i],e=n[0],r=n[1]+Pa,n[0]=e*Math.cos(r),n[1]=e*Math.sin(r);return t}function Le(t){function n(n){function o(){m.push("M",l(t(y),d),h,f(t(v.reverse()),d),"Z")}for(var s,g,p,m=[],v=[],y=[],M=-1,b=n.length,x=c(e),_=c(i),w=e===r?function(){return g}:c(r),S=i===u?function(){return p}:c(u);b>++M;)a.call(this,s=n[M],M)?(v.push([g=+x.call(this,s,M),p=+_.call(this,s,M)]),y.push([+w.call(this,s,M),+S.call(this,s,M)])):v.length&&(o(),v=[],y=[]);return v.length&&o(),m.length?m.join(""):null}var e=he,r=he,i=0,u=de,a=o,l=ge,s=l.key,f=l,h="L",d=.7;return n.x=function(t){return arguments.length?(e=r=t,n):r},n.x0=function(t){return arguments.length?(e=t,n):e},n.x1=function(t){return arguments.length?(r=t,n):r},n.y=function(t){return arguments.length?(i=u=t,n):u},n.y0=function(t){return arguments.length?(i=t,n):i},n.y1=function(t){return arguments.length?(u=t,n):u},n.defined=function(t){return arguments.length?(a=t,n):a},n.interpolate=function(t){return arguments.length?(s="function"==typeof t?l=t:(l=Oa.get(t)||ge).key,f=l.reverse||l,h=l.closed?"M":"L",n):s},n.tension=function(t){return arguments.length?(d=t,n):d},n}function Fe(t){return t.radius}function He(t){return[t.x,t.y]}function Re(t){return function(){var n=t.apply(this,arguments),e=n[0],r=n[1]+Pa;return[e*Math.cos(r),e*Math.sin(r)]}}function Pe(){return 64}function je(){return"circle"}function Oe(t){var n=Math.sqrt(t/Ru);return"M0,"+n+"A"+n+","+n+" 0 1,1 0,"+-n+"A"+n+","+n+" 0 1,1 0,"+n+"Z"}function Ye(t,n){t.attr("transform",function(t){return"translate("+n(t)+",0)"})}function Ue(t,n){t.attr("transform",function(t){return"translate(0,"+n(t)+")"})}function Ie(t,n,e){if(r=[],e&&n.length>1){for(var r,i,u,a=jn(t.domain()),o=-1,c=n.length,l=(n[1]-n[0])/++e;c>++o;)for(i=e;--i>0;)(u=+n[o]-i*l)>=a[0]&&r.push(u);for(--o,i=0;e>++i&&(u=+n[o]+i*l)<a[1];)r.push(u)}return r}function Ve(){Ja||(Ja=d3.select("body").append("div").style("visibility","hidden").style("top",0).style("height",0).style("width",0).style("overflow-y","scroll").append("div").style("height","2000px").node().parentNode);var t,n=d3.event;try{Ja.scrollTop=1e3,Ja.dispatchEvent(n),t=1e3-Ja.scrollTop}catch(e){t=n.wheelDelta||5*-n.detail}return t}function Xe(t){for(var n=t.source,e=t.target,r=Be(n,e),i=[n];n!==r;)n=n.parent,i.push(n);for(var u=i.length;e!==r;)i.splice(u,0,e),e=e.parent;return i}function Ze(t){for(var n=[],e=t.parent;null!=e;)n.push(t),t=e,e=e.parent;return n.push(t),n}function Be(t,n){if(t===n)return t;for(var e=Ze(t),r=Ze(n),i=e.pop(),u=r.pop(),a=null;i===u;)a=i,i=e.pop(),u=r.pop();return a}function $e(t){t.fixed|=2}function Je(t){t.fixed&=1}function Ge(t){t.fixed|=4,t.px=t.x,t.py=t.y}function Ke(t){t.fixed&=3}function We(t,n,e){var r=0,i=0;if(t.charge=0,!t.leaf)for(var u,a=t.nodes,o=a.length,c=-1;o>++c;)u=a[c],null!=u&&(We(u,n,e),t.charge+=u.charge,r+=u.charge*u.cx,i+=u.charge*u.cy);if(t.point){t.leaf||(t.point.x+=Math.random()-.5,t.point.y+=Math.random()-.5);var l=n*e[t.point.index];t.charge+=t.pointCharge=l,r+=l*t.point.x,i+=l*t.point.y}t.cx=r/t.charge,t.cy=i/t.charge}function Qe(){return 20}function tr(){return 1}function nr(t){return t.x}function er(t){return t.y}function rr(t,n,e){t.y0=n,t.y=e}function ir(t){return d3.range(t.length)}function ur(t){for(var n=-1,e=t[0].length,r=[];e>++n;)r[n]=0;return r}function ar(t){for(var n,e=1,r=0,i=t[0][1],u=t.length;u>e;++e)(n=t[e][1])>i&&(r=e,i=n);return r}function or(t){return t.reduce(cr,0)}function cr(t,n){return t+n[1]}function lr(t,n){return sr(t,Math.ceil(Math.log(n.length)/Math.LN2+1))}function sr(t,n){for(var e=-1,r=+t[0],i=(t[1]-r)/n,u=[];n>=++e;)u[e]=i*e+r;return u}function fr(t){return[d3.min(t),d3.max(t)]}function hr(t,n){return d3.rebind(t,n,"sort","children","value"),t.nodes=t,t.links=mr,t}function dr(t){return t.children}function gr(t){return t.value}function pr(t,n){return n.value-t.value}function mr(t){return d3.merge(t.map(function(t){return(t.children||[]).map(function(n){return{source:t,target:n}})}))}function vr(t,n){return t.value-n.value}function yr(t,n){var e=t._pack_next;t._pack_next=n,n._pack_prev=t,n._pack_next=e,e._pack_prev=n}function Mr(t,n){t._pack_next=n,n._pack_prev=t}function br(t,n){var e=n.x-t.x,r=n.y-t.y,i=t.r+n.r;return i*i-e*e-r*r>.001}function xr(t){function n(t){s=Math.min(t.x-t.r,s),f=Math.max(t.x+t.r,f),h=Math.min(t.y-t.r,h),d=Math.max(t.y+t.r,d)}if((e=t.children)&&(l=e.length)){var e,r,i,u,a,o,c,l,s=1/0,f=-1/0,h=1/0,d=-1/0;if(e.forEach(_r),r=e[0],r.x=-r.r,r.y=0,n(r),l>1&&(i=e[1],i.x=i.r,i.y=0,n(i),l>2))for(u=e[2],kr(r,i,u),n(u),yr(r,u),r._pack_prev=u,yr(u,i),i=r._pack_next,a=3;l>a;a++){kr(r,i,u=e[a]);var g=0,p=1,m=1;for(o=i._pack_next;o!==i;o=o._pack_next,p++)if(br(o,u)){g=1;break}if(1==g)for(c=r._pack_prev;c!==o._pack_prev&&!br(c,u);c=c._pack_prev,m++);g?(m>p||p==m&&i.r<r.r?Mr(r,i=o):Mr(r=c,i),a--):(yr(r,u),i=u,n(u))}var v=(s+f)/2,y=(h+d)/2,M=0;for(a=0;l>a;a++)u=e[a],u.x-=v,u.y-=y,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));t.r=M,e.forEach(wr)}}function _r(t){t._pack_next=t._pack_prev=t}function wr(t){delete t._pack_next,delete t._pack_prev}function Sr(t,n,e,r){var i=t.children;if(t.x=n+=r*t.x,t.y=e+=r*t.y,t.r*=r,i)for(var u=-1,a=i.length;a>++u;)Sr(i[u],n,e,r)}function kr(t,n,e){var r=t.r+e.r,i=n.x-t.x,u=n.y-t.y;if(r&&(i||u)){var a=n.r+e.r,o=i*i+u*u;a*=a,r*=r;var c=.5+(r-a)/(2*o),l=Math.sqrt(Math.max(0,2*a*(r+o)-(r-=o)*r-a*a))/(2*o);e.x=t.x+c*i+l*u,e.y=t.y+c*u-l*i}else e.x=t.x+r,e.y=t.y}function Er(t){return 1+d3.max(t,function(t){return t.y})}function Ar(t){return t.reduce(function(t,n){return t+n.x},0)/t.length}function Nr(t){var n=t.children;return n&&n.length?Nr(n[0]):t}function Tr(t){var n,e=t.children;return e&&(n=e.length)?Tr(e[n-1]):t}function qr(t,n){return t.parent==n.parent?1:2}function Cr(t){var n=t.children;return n&&n.length?n[0]:t._tree.thread}function zr(t){var n,e=t.children;return e&&(n=e.length)?e[n-1]:t._tree.thread}function Dr(t,n){var e=t.children;if(e&&(i=e.length))for(var r,i,u=-1;i>++u;)n(r=Dr(e[u],n),t)>0&&(t=r);return t}function Lr(t,n){return t.x-n.x}function Fr(t,n){return n.x-t.x}function Hr(t,n){return t.depth-n.depth}function Rr(t,n){function e(t,r){var i=t.children;if(i&&(a=i.length))for(var u,a,o=null,c=-1;a>++c;)u=i[c],e(u,o),o=u;n(t,r)}e(t,null)}function Pr(t){for(var n,e=0,r=0,i=t.children,u=i.length;--u>=0;)n=i[u]._tree,n.prelim+=e,n.mod+=e,e+=n.shift+(r+=n.change)}function jr(t,n,e){t=t._tree,n=n._tree;var r=e/(n.number-t.number);t.change+=r,n.change-=r,n.shift+=e,n.prelim+=e,n.mod+=e}function Or(t,n,e){return t._tree.ancestor.parent==n.parent?t._tree.ancestor:e}function Yr(t){return{x:t.x,y:t.y,dx:t.dx,dy:t.dy}}function Ur(t,n){var e=t.x+n[3],r=t.y+n[0],i=t.dx-n[1]-n[3],u=t.dy-n[0]-n[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Ir(t,n){function e(t,e){return d3.xhr(t,n,e).response(r)}function r(t){return e.parse(t.responseText)}function i(n){return n.map(u).join(t)}function u(t){return a.test(t)?'"'+t.replace(/\"/g,'""')+'"':t}var a=RegExp('["'+t+"\n]"),o=t.charCodeAt(0);return e.parse=function(t){var n;return e.parseRows(t,function(t){return n?n(t):(n=Function("d","return {"+t.map(function(t,n){return JSON.stringify(t)+": d["+n+"]"}).join(",")+"}"),void 0)})},e.parseRows=function(t,n){function e(){if(s>=l)return a;if(i)return i=!1,u;var n=s;if(34===t.charCodeAt(n)){for(var e=n;l>e++;)if(34===t.charCodeAt(e)){if(34!==t.charCodeAt(e+1))break;++e}s=e+2;var r=t.charCodeAt(e+1);return 13===r?(i=!0,10===t.charCodeAt(e+2)&&++s):10===r&&(i=!0),t.substring(n+1,e).replace(/""/g,'"')}for(;l>s;){var r=t.charCodeAt(s++),c=1;if(10===r)i=!0;else if(13===r)i=!0,10===t.charCodeAt(s)&&(++s,++c);else if(r!==o)continue;return t.substring(n,s-c)}return t.substring(n)}for(var r,i,u={},a={},c=[],l=t.length,s=0,f=0;(r=e())!==a;){for(var h=[];r!==u&&r!==a;)h.push(r),r=e();(!n||(h=n(h,f++)))&&c.push(h)}return c},e.format=function(t){return t.map(i).join("\n")},e}function Vr(t,n){no.hasOwnProperty(t.type)&&no[t.type](t,n)}function Xr(t,n,e){var r,i=-1,u=t.length-e;for(n.lineStart();u>++i;)r=t[i],n.point(r[0],r[1]);n.lineEnd()}function Zr(t,n){var e=-1,r=t.length;for(n.polygonStart();r>++e;)Xr(t[e],n,1);n.polygonEnd()}function Br(t){return[Math.atan2(t[1],t[0]),Math.asin(Math.max(-1,Math.min(1,t[2])))]}function $r(t,n){return Pu>Math.abs(t[0]-n[0])&&Pu>Math.abs(t[1]-n[1])}function Jr(t){var n=t[0],e=t[1],r=Math.cos(e);return[r*Math.cos(n),r*Math.sin(n),Math.sin(e)]}function Gr(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]}function Kr(t,n){return[t[1]*n[2]-t[2]*n[1],t[2]*n[0]-t[0]*n[2],t[0]*n[1]-t[1]*n[0]]}function Wr(t,n){t[0]+=n[0],t[1]+=n[1],t[2]+=n[2]}function Qr(t,n){return[t[0]*n,t[1]*n,t[2]*n]}function ti(t){var n=Math.sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=n,t[1]/=n,t[2]/=n}function ni(t){function n(n){function r(e,r){e=t(e,r),n.point(e[0],e[1])}function u(){s=0/0,p.point=a,n.lineStart()}function a(r,u){var a=Jr([r,u]),o=t(r,u);e(s,f,l,h,d,g,s=o[0],f=o[1],l=r,h=a[0],d=a[1],g=a[2],i,n),n.point(s,f)}function o(){p.point=r,n.lineEnd()}function c(){var t,r,c,m,v,y,M;u(),p.point=function(n,e){a(t=n,r=e),c=s,m=f,v=h,y=d,M=g,p.point=a},p.lineEnd=function(){e(s,f,l,h,d,g,c,m,t,v,y,M,i,n),p.lineEnd=o,o()}}var l,s,f,h,d,g,p={point:r,lineStart:u,lineEnd:o,polygonStart:function(){n.polygonStart(),p.lineStart=c},polygonEnd:function(){n.polygonEnd(),p.lineStart=u}};return p}function e(n,i,u,a,o,c,l,s,f,h,d,g,p,m){var v=l-n,y=s-i,M=v*v+y*y;if(M>4*r&&p--){var b=a+h,x=o+d,_=c+g,w=Math.sqrt(b*b+x*x+_*_),S=Math.asin(_/=w),k=Pu>Math.abs(Math.abs(_)-1)?(u+f)/2:Math.atan2(x,b),E=t(k,S),A=E[0],N=E[1],T=A-n,q=N-i,C=y*T-v*q;(C*C/M>r||Math.abs((v*T+y*q)/M-.5)>.3)&&(e(n,i,u,a,o,c,A,N,k,b/=w,x/=w,_,p,m),m.point(A,N),e(A,N,k,b,x,_,l,s,f,h,d,g,p,m))}}var r=.5,i=16;return n.precision=function(t){return arguments.length?(i=(r=t*t)>0&&16,n):Math.sqrt(r)},n}function ei(t,n){function e(t,n){var e=Math.sqrt(u-2*i*Math.sin(n))/i;return[e*Math.sin(t*=i),a-e*Math.cos(t)]}var r=Math.sin(t),i=(r+Math.sin(n))/2,u=1+r*(2*i-r),a=Math.sqrt(u)/i;return e.invert=function(t,n){var e=a-n;return[Math.atan2(t,e)/i,Math.asin((u-(t*t+e*e)*i*i)/(2*i))]},e}function ri(t){function n(t,n){r>t&&(r=t),t>u&&(u=t),i>n&&(i=n),n>a&&(a=n)}function e(){o.point=o.lineEnd=Pn}var r,i,u,a,o={point:n,lineStart:Pn,lineEnd:Pn,polygonStart:function(){o.lineEnd=e},polygonEnd:function(){o.point=n}};return function(n){return a=u=-(r=i=1/0),d3.geo.stream(n,t(o)),[[r,i],[u,a]]}}function ii(t,n){if(!io){++uo,t*=ju;var e=Math.cos(n*=ju);ao+=(e*Math.cos(t)-ao)/uo,oo+=(e*Math.sin(t)-oo)/uo,co+=(Math.sin(n)-co)/uo}}function ui(){var t,n;io=1,ai(),io=2;var e=lo.point;lo.point=function(r,i){e(t=r,n=i)},lo.lineEnd=function(){lo.point(t,n),oi(),lo.lineEnd=oi}}function ai(){function t(t,i){t*=ju;var u=Math.cos(i*=ju),a=u*Math.cos(t),o=u*Math.sin(t),c=Math.sin(i),l=Math.atan2(Math.sqrt((l=e*c-r*o)*l+(l=r*a-n*c)*l+(l=n*o-e*a)*l),n*a+e*o+r*c);uo+=l,ao+=l*(n+(n=a)),oo+=l*(e+(e=o)),co+=l*(r+(r=c))}var n,e,r;io>1||(1>io&&(io=1,uo=ao=oo=co=0),lo.point=function(i,u){i*=ju;var a=Math.cos(u*=ju);n=a*Math.cos(i),e=a*Math.sin(i),r=Math.sin(u),lo.point=t})}function oi(){lo.point=ii}function ci(t,n){var e=Math.cos(t),r=Math.sin(t);return function(i,u,a,o){null!=i?(i=li(e,i),u=li(e,u),(a>0?u>i:i>u)&&(i+=2*a*Ru)):(i=t+2*a*Ru,u=t);for(var c,l=a*n,s=i;a>0?s>u:u>s;s-=l)o.point((c=Br([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],c[1])}}function li(t,n){var e=Jr(n);e[0]-=t,ti(e);var r=Math.acos(Math.max(-1,Math.min(1,-e[1])));return((0>-e[2]?-r:r)+2*Math.PI-Pu)%(2*Math.PI)}function si(t,n,e){return function(r){function i(n,e){t(n,e)&&r.point(n,e)}function u(t,n){m.point(t,n)}function a(){v.point=u,m.lineStart()}function o(){v.point=i,m.lineEnd()}function c(t,n){M.point(t,n),p.push([t,n])}function l(){M.lineStart(),p=[]}function s(){c(p[0][0],p[0][1]),M.lineEnd();var t,n=M.clean(),e=y.buffer(),i=e.length;if(!i)return g=!0,d+=mi(p,-1),p=null,void 0;if(p=null,1&n){t=e[0],h+=mi(t,1);var u,i=t.length-1,a=-1;for(r.lineStart();i>++a;)r.point((u=t[a])[0],u[1]);return r.lineEnd(),void 0}i>1&&2&n&&e.push(e.pop().concat(e.shift())),f.push(e.filter(gi))}var f,h,d,g,p,m=n(r),v={point:i,lineStart:a,lineEnd:o,polygonStart:function(){v.point=c,v.lineStart=l,v.lineEnd=s,g=!1,d=h=0,f=[],r.polygonStart() +},polygonEnd:function(){v.point=i,v.lineStart=a,v.lineEnd=o,f=d3.merge(f),f.length?fi(f,e,r):(-Pu>h||g&&-Pu>d)&&(r.lineStart(),e(null,null,1,r),r.lineEnd()),r.polygonEnd(),f=null},sphere:function(){r.polygonStart(),r.lineStart(),e(null,null,1,r),r.lineEnd(),r.polygonEnd()}},y=pi(),M=n(y);return v}}function fi(t,n,e){var r=[],i=[];if(t.forEach(function(t){var n=t.length;if(!(1>=n)){var e=t[0],u=t[n-1],a={point:e,points:t,other:null,visited:!1,entry:!0,subject:!0},o={point:e,points:[e],other:a,visited:!1,entry:!1,subject:!1};a.other=o,r.push(a),i.push(o),a={point:u,points:[u],other:null,visited:!1,entry:!1,subject:!0},o={point:u,points:[u],other:a,visited:!1,entry:!0,subject:!1},a.other=o,r.push(a),i.push(o)}}),i.sort(di),hi(r),hi(i),r.length)for(var u,a,o,c=r[0];;){for(u=c;u.visited;)if((u=u.next)===c)return;a=u.points,e.lineStart();do{if(u.visited=u.other.visited=!0,u.entry){if(u.subject)for(var l=0;a.length>l;l++)e.point((o=a[l])[0],o[1]);else n(u.point,u.next.point,1,e);u=u.next}else{if(u.subject){a=u.prev.points;for(var l=a.length;--l>=0;)e.point((o=a[l])[0],o[1])}else n(u.point,u.prev.point,-1,e);u=u.prev}u=u.other,a=u.points}while(!u.visited);e.lineEnd()}}function hi(t){if(n=t.length){for(var n,e,r=0,i=t[0];n>++r;)i.next=e=t[r],e.prev=i,i=e;i.next=e=t[0],e.prev=i}}function di(t,n){return(0>(t=t.point)[0]?t[1]-Ru/2-Pu:Ru/2-t[1])-(0>(n=n.point)[0]?n[1]-Ru/2-Pu:Ru/2-n[1])}function gi(t){return t.length>1}function pi(){var t,n=[];return{lineStart:function(){n.push(t=[])},point:function(n,e){t.push([n,e])},lineEnd:Pn,buffer:function(){var e=n;return n=[],t=null,e}}}function mi(t,n){if(!(e=t.length))return 0;for(var e,r,i,u=0,a=0,o=t[0],c=o[0],l=o[1],s=Math.cos(l),f=Math.atan2(n*Math.sin(c)*s,Math.sin(l)),h=1-n*Math.cos(c)*s,d=f;e>++u;)o=t[u],s=Math.cos(l=o[1]),r=Math.atan2(n*Math.sin(c=o[0])*s,Math.sin(l)),i=1-n*Math.cos(c)*s,Pu>Math.abs(h-2)&&Pu>Math.abs(i-2)||(Pu>Math.abs(i)||Pu>Math.abs(h)||(Pu>Math.abs(Math.abs(r-f)-Ru)?i+h>2&&(a+=4*(r-f)):a+=Pu>Math.abs(h-2)?4*(r-d):((3*Ru+r-f)%(2*Ru)-Ru)*(h+i)),d=f,f=r,h=i);return a}function vi(t){var n,e=0/0,r=0/0,i=0/0;return{lineStart:function(){t.lineStart(),n=1},point:function(u,a){var o=u>0?Ru:-Ru,c=Math.abs(u-e);Pu>Math.abs(c-Ru)?(t.point(e,r=(r+a)/2>0?Ru/2:-Ru/2),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(o,r),t.point(u,r),n=0):i!==o&&c>=Ru&&(Pu>Math.abs(e-i)&&(e-=i*Pu),Pu>Math.abs(u-o)&&(u-=o*Pu),r=yi(e,r,u,a),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(o,r),n=0),t.point(e=u,r=a),i=o},lineEnd:function(){t.lineEnd(),e=r=0/0},clean:function(){return 2-n}}}function yi(t,n,e,r){var i,u,a=Math.sin(t-e);return Math.abs(a)>Pu?Math.atan((Math.sin(n)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(n))*Math.sin(t))/(i*u*a)):(n+r)/2}function Mi(t,n,e,r){var i;if(null==t)i=e*Ru/2,r.point(-Ru,i),r.point(0,i),r.point(Ru,i),r.point(Ru,0),r.point(Ru,-i),r.point(0,-i),r.point(-Ru,-i),r.point(-Ru,0),r.point(-Ru,i);else if(Math.abs(t[0]-n[0])>Pu){var u=(t[0]<n[0]?1:-1)*Ru;i=e*u/2,r.point(-u,i),r.point(0,i),r.point(u,i)}else r.point(n[0],n[1])}function bi(t){function n(t,n){return Math.cos(t)*Math.cos(n)>u}function e(t){var e,i,u,a;return{lineStart:function(){u=i=!1,a=1},point:function(o,c){var l,s=[o,c],f=n(o,c);!e&&(u=i=f)&&t.lineStart(),f!==i&&(l=r(e,s),($r(e,l)||$r(s,l))&&(s[0]+=Pu,s[1]+=Pu,f=n(s[0],s[1]))),f!==i&&(a=0,(i=f)?(t.lineStart(),l=r(s,e),t.point(l[0],l[1])):(l=r(e,s),t.point(l[0],l[1]),t.lineEnd()),e=l),!f||e&&$r(e,s)||t.point(s[0],s[1]),e=s},lineEnd:function(){i&&t.lineEnd(),e=null},clean:function(){return a|(u&&i)<<1}}}function r(t,n){var e=Jr(t,0),r=Jr(n,0),i=[1,0,0],a=Kr(e,r),o=Gr(a,a),c=a[0],l=o-c*c;if(!l)return t;var s=u*o/l,f=-u*c/l,h=Kr(i,a),d=Qr(i,s),g=Qr(a,f);Wr(d,g);var p=h,m=Gr(d,p),v=Gr(p,p),y=Math.sqrt(m*m-v*(Gr(d,d)-1)),M=Qr(p,(-m-y)/v);return Wr(M,d),Br(M)}var i=t*ju,u=Math.cos(i),a=ci(i,6*ju);return si(n,e,a)}function xi(t,n){function e(e,r){return e=t(e,r),n(e[0],e[1])}return t.invert&&n.invert&&(e.invert=function(e,r){return e=n.invert(e,r),e&&t.invert(e[0],e[1])}),e}function _i(t,n){return[t,n]}function wi(t,n,e){var r=d3.range(t,n-Pu,e).concat(n);return function(t){return r.map(function(n){return[t,n]})}}function Si(t,n,e){var r=d3.range(t,n-Pu,e).concat(n);return function(t){return r.map(function(n){return[n,t]})}}function ki(t,n,e,r){function i(t){var n=Math.sin(t*=d)*g,e=Math.sin(d-t)*g,r=e*l+n*f,i=e*s+n*h,u=e*a+n*c;return[Math.atan2(i,r)/ju,Math.atan2(u,Math.sqrt(r*r+i*i))/ju]}var u=Math.cos(n),a=Math.sin(n),o=Math.cos(r),c=Math.sin(r),l=u*Math.cos(t),s=u*Math.sin(t),f=o*Math.cos(e),h=o*Math.sin(e),d=Math.acos(Math.max(-1,Math.min(1,a*c+u*o*Math.cos(e-t)))),g=1/Math.sin(d);return i.distance=d,i}function Ei(t,n){return[t/(2*Ru),Math.max(-.5,Math.min(.5,Math.log(Math.tan(Ru/4+n/2))/(2*Ru)))]}function Ai(t){return"m0,"+t+"a"+t+","+t+" 0 1,1 0,"+-2*t+"a"+t+","+t+" 0 1,1 0,"+2*t+"z"}function Ni(t){var n=ni(function(n,e){return t([n*Ou,e*Ou])});return function(t){return t=n(t),{point:function(n,e){t.point(n*ju,e*ju)},sphere:function(){t.sphere()},lineStart:function(){t.lineStart()},lineEnd:function(){t.lineEnd()},polygonStart:function(){t.polygonStart()},polygonEnd:function(){t.polygonEnd()}}}}function Ti(){function t(t,n){a.push("M",t,",",n,u)}function n(t,n){a.push("M",t,",",n),o.point=e}function e(t,n){a.push("L",t,",",n)}function r(){o.point=t}function i(){a.push("Z")}var u=Ai(4.5),a=[],o={point:t,lineStart:function(){o.point=n},lineEnd:r,polygonStart:function(){o.lineEnd=i},polygonEnd:function(){o.lineEnd=r,o.point=t},pointRadius:function(t){return u=Ai(t),o},result:function(){if(a.length){var t=a.join("");return a=[],t}}};return o}function qi(t){function n(n,e){t.moveTo(n,e),t.arc(n,e,a,0,2*Ru)}function e(n,e){t.moveTo(n,e),o.point=r}function r(n,e){t.lineTo(n,e)}function i(){o.point=n}function u(){t.closePath()}var a=4.5,o={point:n,lineStart:function(){o.point=e},lineEnd:i,polygonStart:function(){o.lineEnd=u},polygonEnd:function(){o.lineEnd=i,o.point=n},pointRadius:function(t){return a=t,o},result:Pn};return o}function Ci(){function t(t,n){po+=i*t-r*n,r=t,i=n}var n,e,r,i;mo.point=function(u,a){mo.point=t,n=r=u,e=i=a},mo.lineEnd=function(){t(n,e)}}function zi(t,n){io||(ao+=t,oo+=n,++co)}function Di(){function t(t,r){var i=t-n,u=r-e,a=Math.sqrt(i*i+u*u);ao+=a*(n+t)/2,oo+=a*(e+r)/2,co+=a,n=t,e=r}var n,e;if(1!==io){if(!(1>io))return;io=1,ao=oo=co=0}vo.point=function(r,i){vo.point=t,n=r,e=i}}function Li(){vo.point=zi}function Fi(){function t(t,n){var e=i*t-r*n;ao+=e*(r+t),oo+=e*(i+n),co+=3*e,r=t,i=n}var n,e,r,i;2>io&&(io=2,ao=oo=co=0),vo.point=function(u,a){vo.point=t,n=r=u,e=i=a},vo.lineEnd=function(){t(n,e)}}function Hi(){function t(t,n){if(t*=ju,n*=ju,!(Pu>Math.abs(Math.abs(u)-Ru/2)&&Pu>Math.abs(Math.abs(n)-Ru/2))){var e=Math.cos(n),c=Math.sin(n);if(Pu>Math.abs(u-Ru/2))Mo+=2*(t-r);else{var l=t-i,s=Math.cos(l),f=Math.atan2(Math.sqrt((f=e*Math.sin(l))*f+(f=a*c-o*e*s)*f),o*c+a*e*s),h=(f+Ru+u+n)/4;Mo+=(0>l&&l>-Ru||l>Ru?-4:4)*Math.atan(Math.sqrt(Math.abs(Math.tan(h)*Math.tan(h-f/2)*Math.tan(h-Ru/4-u/2)*Math.tan(h-Ru/4-n/2))))}r=i,i=t,u=n,a=e,o=c}}var n,e,r,i,u,a,o;bo.point=function(c,l){bo.point=t,r=i=(n=c)*ju,u=(e=l)*ju,a=Math.cos(u),o=Math.sin(u)},bo.lineEnd=function(){t(n,e)}}function Ri(t){return Pi(function(){return t})()}function Pi(t){function n(t){return t=a(t[0]*ju,t[1]*ju),[t[0]*s+o,c-t[1]*s]}function e(t){return t=a.invert((t[0]-o)/s,(c-t[1])/s),t&&[t[0]*Ou,t[1]*Ou]}function r(){a=xi(u=Oi(p,m,v),i);var t=i(d,g);return o=f-t[0]*s,c=h+t[1]*s,n}var i,u,a,o,c,l=ni(function(t,n){return t=i(t,n),[t[0]*s+o,c-t[1]*s]}),s=150,f=480,h=250,d=0,g=0,p=0,m=0,v=0,y=so,M=null;return n.stream=function(t){return ji(u,y(l(t)))},n.clipAngle=function(t){return arguments.length?(y=null==t?(M=t,so):bi(M=+t),n):M},n.scale=function(t){return arguments.length?(s=+t,r()):s},n.translate=function(t){return arguments.length?(f=+t[0],h=+t[1],r()):[f,h]},n.center=function(t){return arguments.length?(d=t[0]%360*ju,g=t[1]%360*ju,r()):[d*Ou,g*Ou]},n.rotate=function(t){return arguments.length?(p=t[0]%360*ju,m=t[1]%360*ju,v=t.length>2?t[2]%360*ju:0,r()):[p*Ou,m*Ou,v*Ou]},d3.rebind(n,l,"precision"),function(){return i=t.apply(this,arguments),n.invert=i.invert&&e,r()}}function ji(t,n){return{point:function(e,r){r=t(e*ju,r*ju),e=r[0],n.point(e>Ru?e-2*Ru:-Ru>e?e+2*Ru:e,r[1])},sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function Oi(t,n,e){return t?n||e?xi(Ui(t),Ii(n,e)):Ui(t):n||e?Ii(n,e):_i}function Yi(t){return function(n,e){return n+=t,[n>Ru?n-2*Ru:-Ru>n?n+2*Ru:n,e]}}function Ui(t){var n=Yi(t);return n.invert=Yi(-t),n}function Ii(t,n){function e(t,n){var e=Math.cos(n),o=Math.cos(t)*e,c=Math.sin(t)*e,l=Math.sin(n),s=l*r+o*i;return[Math.atan2(c*u-s*a,o*r-l*i),Math.asin(Math.max(-1,Math.min(1,s*u+c*a)))]}var r=Math.cos(t),i=Math.sin(t),u=Math.cos(n),a=Math.sin(n);return e.invert=function(t,n){var e=Math.cos(n),o=Math.cos(t)*e,c=Math.sin(t)*e,l=Math.sin(n),s=l*u-c*a;return[Math.atan2(c*u+l*a,o*r+s*i),Math.asin(Math.max(-1,Math.min(1,s*r-o*i)))]},e}function Vi(t,n){function e(n,e){var r=Math.cos(n),i=Math.cos(e),u=t(r*i);return[u*i*Math.sin(n),u*Math.sin(e)]}return e.invert=function(t,e){var r=Math.sqrt(t*t+e*e),i=n(r),u=Math.sin(i),a=Math.cos(i);return[Math.atan2(t*u,r*a),Math.asin(r&&e*u/r)]},e}function Xi(t,n,e,r){var i,u,a,o,c,l,s;return i=r[t],u=i[0],a=i[1],i=r[n],o=i[0],c=i[1],i=r[e],l=i[0],s=i[1],(s-a)*(o-u)-(c-a)*(l-u)>0}function Zi(t,n,e){return(e[0]-n[0])*(t[1]-n[1])<(e[1]-n[1])*(t[0]-n[0])}function Bi(t,n,e,r){var i=t[0],u=e[0],a=n[0]-i,o=r[0]-u,c=t[1],l=e[1],s=n[1]-c,f=r[1]-l,h=(o*(c-l)-f*(i-u))/(f*a-o*s);return[i+h*a,c+h*s]}function $i(t,n){var e={list:t.map(function(t,n){return{index:n,x:t[0],y:t[1]}}).sort(function(t,n){return t.y<n.y?-1:t.y>n.y?1:t.x<n.x?-1:t.x>n.x?1:0}),bottomSite:null},r={list:[],leftEnd:null,rightEnd:null,init:function(){r.leftEnd=r.createHalfEdge(null,"l"),r.rightEnd=r.createHalfEdge(null,"l"),r.leftEnd.r=r.rightEnd,r.rightEnd.l=r.leftEnd,r.list.unshift(r.leftEnd,r.rightEnd)},createHalfEdge:function(t,n){return{edge:t,side:n,vertex:null,l:null,r:null}},insert:function(t,n){n.l=t,n.r=t.r,t.r.l=n,t.r=n},leftBound:function(t){var n=r.leftEnd;do n=n.r;while(n!=r.rightEnd&&i.rightOf(n,t));return n=n.l},del:function(t){t.l.r=t.r,t.r.l=t.l,t.edge=null},right:function(t){return t.r},left:function(t){return t.l},leftRegion:function(t){return null==t.edge?e.bottomSite:t.edge.region[t.side]},rightRegion:function(t){return null==t.edge?e.bottomSite:t.edge.region[_o[t.side]]}},i={bisect:function(t,n){var e={region:{l:t,r:n},ep:{l:null,r:null}},r=n.x-t.x,i=n.y-t.y,u=r>0?r:-r,a=i>0?i:-i;return e.c=t.x*r+t.y*i+.5*(r*r+i*i),u>a?(e.a=1,e.b=i/r,e.c/=r):(e.b=1,e.a=r/i,e.c/=i),e},intersect:function(t,n){var e=t.edge,r=n.edge;if(!e||!r||e.region.r==r.region.r)return null;var i=e.a*r.b-e.b*r.a;if(1e-10>Math.abs(i))return null;var u,a,o=(e.c*r.b-r.c*e.b)/i,c=(r.c*e.a-e.c*r.a)/i,l=e.region.r,s=r.region.r;l.y<s.y||l.y==s.y&&l.x<s.x?(u=t,a=e):(u=n,a=r);var f=o>=a.region.r.x;return f&&"l"===u.side||!f&&"r"===u.side?null:{x:o,y:c}},rightOf:function(t,n){var e=t.edge,r=e.region.r,i=n.x>r.x;if(i&&"l"===t.side)return 1;if(!i&&"r"===t.side)return 0;if(1===e.a){var u=n.y-r.y,a=n.x-r.x,o=0,c=0;if(!i&&0>e.b||i&&e.b>=0?c=o=u>=e.b*a:(c=n.x+n.y*e.b>e.c,0>e.b&&(c=!c),c||(o=1)),!o){var l=r.x-e.region.l.x;c=e.b*(a*a-u*u)<l*u*(1+2*a/l+e.b*e.b),0>e.b&&(c=!c)}}else{var s=e.c-e.a*n.x,f=n.y-s,h=n.x-r.x,d=s-r.y;c=f*f>h*h+d*d}return"l"===t.side?c:!c},endPoint:function(t,e,r){t.ep[e]=r,t.ep[_o[e]]&&n(t)},distance:function(t,n){var e=t.x-n.x,r=t.y-n.y;return Math.sqrt(e*e+r*r)}},u={list:[],insert:function(t,n,e){t.vertex=n,t.ystar=n.y+e;for(var r=0,i=u.list,a=i.length;a>r;r++){var o=i[r];if(!(t.ystar>o.ystar||t.ystar==o.ystar&&n.x>o.vertex.x))break}i.splice(r,0,t)},del:function(t){for(var n=0,e=u.list,r=e.length;r>n&&e[n]!=t;++n);e.splice(n,1)},empty:function(){return 0===u.list.length},nextEvent:function(t){for(var n=0,e=u.list,r=e.length;r>n;++n)if(e[n]==t)return e[n+1];return null},min:function(){var t=u.list[0];return{x:t.vertex.x,y:t.ystar}},extractMin:function(){return u.list.shift()}};r.init(),e.bottomSite=e.list.shift();for(var a,o,c,l,s,f,h,d,g,p,m,v,y,M=e.list.shift();;)if(u.empty()||(a=u.min()),M&&(u.empty()||M.y<a.y||M.y==a.y&&M.x<a.x))o=r.leftBound(M),c=r.right(o),h=r.rightRegion(o),v=i.bisect(h,M),f=r.createHalfEdge(v,"l"),r.insert(o,f),p=i.intersect(o,f),p&&(u.del(o),u.insert(o,p,i.distance(p,M))),o=f,f=r.createHalfEdge(v,"r"),r.insert(o,f),p=i.intersect(f,c),p&&u.insert(f,p,i.distance(p,M)),M=e.list.shift();else{if(u.empty())break;o=u.extractMin(),l=r.left(o),c=r.right(o),s=r.right(c),h=r.leftRegion(o),d=r.rightRegion(c),m=o.vertex,i.endPoint(o.edge,o.side,m),i.endPoint(c.edge,c.side,m),r.del(o),u.del(c),r.del(c),y="l",h.y>d.y&&(g=h,h=d,d=g,y="r"),v=i.bisect(h,d),f=r.createHalfEdge(v,y),r.insert(l,f),i.endPoint(v,_o[y],m),p=i.intersect(l,f),p&&(u.del(l),u.insert(l,p,i.distance(p,h))),p=i.intersect(f,s),p&&u.insert(f,p,i.distance(p,h))}for(o=r.right(r.leftEnd);o!=r.rightEnd;o=r.right(o))n(o.edge)}function Ji(){return{leaf:!0,nodes:[],point:null}}function Gi(t,n,e,r,i,u){if(!t(n,e,r,i,u)){var a=.5*(e+i),o=.5*(r+u),c=n.nodes;c[0]&&Gi(t,c[0],e,r,a,o),c[1]&&Gi(t,c[1],a,r,i,o),c[2]&&Gi(t,c[2],e,o,a,u),c[3]&&Gi(t,c[3],a,o,i,u)}}function Ki(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Wi(t,n,e,r){for(var i,u,a=0,o=n.length,c=e.length;o>a;){if(r>=c)return-1;if(i=n.charCodeAt(a++),37===i){if(u=Yo[n.charAt(a++)],!u||0>(r=u(t,e,r)))return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function Qi(t){return RegExp("^(?:"+t.map(d3.requote).join("|")+")","i")}function tu(t){for(var n=new u,e=-1,r=t.length;r>++e;)n.set(t[e].toLowerCase(),e);return n}function nu(t,n,e){t+="";var r=t.length;return e>r?Array(e-r+1).join(n)+t:t}function eu(t,n,e){Lo.lastIndex=0;var r=Lo.exec(n.substring(e));return r?e+=r[0].length:-1}function ru(t,n,e){Do.lastIndex=0;var r=Do.exec(n.substring(e));return r?e+=r[0].length:-1}function iu(t,n,e){Ro.lastIndex=0;var r=Ro.exec(n.substring(e));return r?(t.m=Po.get(r[0].toLowerCase()),e+=r[0].length):-1}function uu(t,n,e){Fo.lastIndex=0;var r=Fo.exec(n.substring(e));return r?(t.m=Ho.get(r[0].toLowerCase()),e+=r[0].length):-1}function au(t,n,e){return Wi(t,""+Oo.c,n,e)}function ou(t,n,e){return Wi(t,""+Oo.x,n,e)}function cu(t,n,e){return Wi(t,""+Oo.X,n,e)}function lu(t,n,e){Uo.lastIndex=0;var r=Uo.exec(n.substring(e,e+4));return r?(t.y=+r[0],e+=r[0].length):-1}function su(t,n,e){Uo.lastIndex=0;var r=Uo.exec(n.substring(e,e+2));return r?(t.y=fu(+r[0]),e+=r[0].length):-1}function fu(t){return t+(t>68?1900:2e3)}function hu(t,n,e){Uo.lastIndex=0;var r=Uo.exec(n.substring(e,e+2));return r?(t.m=r[0]-1,e+=r[0].length):-1}function du(t,n,e){Uo.lastIndex=0;var r=Uo.exec(n.substring(e,e+2));return r?(t.d=+r[0],e+=r[0].length):-1}function gu(t,n,e){Uo.lastIndex=0;var r=Uo.exec(n.substring(e,e+2));return r?(t.H=+r[0],e+=r[0].length):-1}function pu(t,n,e){Uo.lastIndex=0;var r=Uo.exec(n.substring(e,e+2));return r?(t.M=+r[0],e+=r[0].length):-1}function mu(t,n,e){Uo.lastIndex=0;var r=Uo.exec(n.substring(e,e+2));return r?(t.S=+r[0],e+=r[0].length):-1}function vu(t,n,e){Uo.lastIndex=0;var r=Uo.exec(n.substring(e,e+3));return r?(t.L=+r[0],e+=r[0].length):-1}function yu(t,n,e){var r=Io.get(n.substring(e,e+=2).toLowerCase());return null==r?-1:(t.p=r,e)}function Mu(t){var n=t.getTimezoneOffset(),e=n>0?"-":"+",r=~~(Math.abs(n)/60),i=Math.abs(n)%60;return e+nu(r,"0",2)+nu(i,"0",2)}function bu(t){return t.toISOString()}function xu(t,n,e){function r(n){var e=t(n),r=u(e,1);return r-n>n-e?e:r}function i(e){return n(e=t(new wo(e-1)),1),e}function u(t,e){return n(t=new wo(+t),e),t}function a(t,r,u){var a=i(t),o=[];if(u>1)for(;r>a;)e(a)%u||o.push(new Date(+a)),n(a,1);else for(;r>a;)o.push(new Date(+a)),n(a,1);return o}function o(t,n,e){try{wo=Ki;var r=new Ki;return r._=t,a(r,n,e)}finally{wo=Date}}t.floor=t,t.round=r,t.ceil=i,t.offset=u,t.range=a;var c=t.utc=_u(t);return c.floor=c,c.round=_u(r),c.ceil=_u(i),c.offset=_u(u),c.range=o,t}function _u(t){return function(n,e){try{wo=Ki;var r=new Ki;return r._=n,t(r,e)._}finally{wo=Date}}}function wu(t,n,e){function r(n){return t(n)}return r.invert=function(n){return ku(t.invert(n))},r.domain=function(n){return arguments.length?(t.domain(n),r):t.domain().map(ku)},r.nice=function(t){return r.domain(Yn(r.domain(),function(){return t}))},r.ticks=function(e,i){var u=Su(r.domain());if("function"!=typeof e){var a=u[1]-u[0],o=a/e,c=d3.bisect(Xo,o);if(c==Xo.length)return n.year(u,e);if(!c)return t.ticks(e).map(ku);Math.log(o/Xo[c-1])<Math.log(Xo[c]/o)&&--c,e=n[c],i=e[1],e=e[0].range}return e(u[0],new Date(+u[1]+1),i)},r.tickFormat=function(){return e},r.copy=function(){return wu(t.copy(),n,e)},d3.rebind(r,t,"range","rangeRound","interpolate","clamp")}function Su(t){var n=t[0],e=t[t.length-1];return e>n?[n,e]:[e,n]}function ku(t){return new Date(t)}function Eu(t){return function(n){for(var e=t.length-1,r=t[e];!r[1](n);)r=t[--e];return r[0](n)}}function Au(t){var n=new Date(t,0,1);return n.setFullYear(t),n}function Nu(t){var n=t.getFullYear(),e=Au(n),r=Au(n+1);return n+(t-e)/(r-e)}function Tu(t){var n=new Date(Date.UTC(t,0,1));return n.setUTCFullYear(t),n}function qu(t){var n=t.getUTCFullYear(),e=Tu(n),r=Tu(n+1);return n+(t-e)/(r-e)}var Cu=".",zu=",",Du=[3,3];Date.now||(Date.now=function(){return+new Date});try{document.createElement("div").style.setProperty("opacity",0,"")}catch(Lu){var Fu=CSSStyleDeclaration.prototype,Hu=Fu.setProperty;Fu.setProperty=function(t,n,e){Hu.call(this,t,n+"",e)}}d3={version:"3.0.3"};var Ru=Math.PI,Pu=1e-6,ju=Ru/180,Ou=180/Ru,Yu=i;try{Yu(document.documentElement.childNodes)[0].nodeType}catch(Uu){Yu=r}var Iu=[].__proto__?function(t,n){t.__proto__=n}:function(t,n){for(var e in n)t[e]=n[e]};d3.map=function(t){var n=new u;for(var e in t)n.set(e,t[e]);return n},e(u,{has:function(t){return Vu+t in this},get:function(t){return this[Vu+t]},set:function(t,n){return this[Vu+t]=n},remove:function(t){return t=Vu+t,t in this&&delete this[t]},keys:function(){var t=[];return this.forEach(function(n){t.push(n)}),t},values:function(){var t=[];return this.forEach(function(n,e){t.push(e)}),t},entries:function(){var t=[];return this.forEach(function(n,e){t.push({key:n,value:e})}),t},forEach:function(t){for(var n in this)n.charCodeAt(0)===Xu&&t.call(this,n.substring(1),this[n])}});var Vu="\0",Xu=Vu.charCodeAt(0);d3.functor=c,d3.rebind=function(t,n){for(var e,r=1,i=arguments.length;i>++r;)t[e=arguments[r]]=l(t,n,n[e]);return t},d3.ascending=function(t,n){return n>t?-1:t>n?1:t>=n?0:0/0},d3.descending=function(t,n){return t>n?-1:n>t?1:n>=t?0:0/0},d3.mean=function(t,n){var e,r=t.length,i=0,u=-1,a=0;if(1===arguments.length)for(;r>++u;)s(e=t[u])&&(i+=(e-i)/++a);else for(;r>++u;)s(e=n.call(t,t[u],u))&&(i+=(e-i)/++a);return a?i:void 0},d3.median=function(t,n){return arguments.length>1&&(t=t.map(n)),t=t.filter(s),t.length?d3.quantile(t.sort(d3.ascending),.5):void 0},d3.min=function(t,n){var e,r,i=-1,u=t.length;if(1===arguments.length){for(;u>++i&&(null==(e=t[i])||e!=e);)e=void 0;for(;u>++i;)null!=(r=t[i])&&e>r&&(e=r)}else{for(;u>++i&&(null==(e=n.call(t,t[i],i))||e!=e);)e=void 0;for(;u>++i;)null!=(r=n.call(t,t[i],i))&&e>r&&(e=r)}return e},d3.max=function(t,n){var e,r,i=-1,u=t.length;if(1===arguments.length){for(;u>++i&&(null==(e=t[i])||e!=e);)e=void 0;for(;u>++i;)null!=(r=t[i])&&r>e&&(e=r)}else{for(;u>++i&&(null==(e=n.call(t,t[i],i))||e!=e);)e=void 0;for(;u>++i;)null!=(r=n.call(t,t[i],i))&&r>e&&(e=r)}return e},d3.extent=function(t,n){var e,r,i,u=-1,a=t.length;if(1===arguments.length){for(;a>++u&&(null==(e=i=t[u])||e!=e);)e=i=void 0;for(;a>++u;)null!=(r=t[u])&&(e>r&&(e=r),r>i&&(i=r))}else{for(;a>++u&&(null==(e=i=n.call(t,t[u],u))||e!=e);)e=void 0;for(;a>++u;)null!=(r=n.call(t,t[u],u))&&(e>r&&(e=r),r>i&&(i=r))}return[e,i]},d3.random={normal:function(t,n){var e=arguments.length;return 2>e&&(n=1),1>e&&(t=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return t+n*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(t,n){var e=arguments.length;2>e&&(n=1),1>e&&(t=0);var r=d3.random.normal();return function(){return Math.exp(t+n*r())}},irwinHall:function(t){return function(){for(var n=0,e=0;t>e;e++)n+=Math.random();return n/t}}},d3.sum=function(t,n){var e,r=0,i=t.length,u=-1;if(1===arguments.length)for(;i>++u;)isNaN(e=+t[u])||(r+=e);else for(;i>++u;)isNaN(e=+n.call(t,t[u],u))||(r+=e);return r},d3.quantile=function(t,n){var e=(t.length-1)*n+1,r=Math.floor(e),i=+t[r-1],u=e-r;return u?i+u*(t[r]-i):i},d3.shuffle=function(t){for(var n,e,r=t.length;r;)e=0|Math.random()*r--,n=t[r],t[r]=t[e],t[e]=n;return t},d3.transpose=function(t){return d3.zip.apply(d3,t)},d3.zip=function(){if(!(r=arguments.length))return[];for(var t=-1,n=d3.min(arguments,f),e=Array(n);n>++t;)for(var r,i=-1,u=e[t]=Array(r);r>++i;)u[i]=arguments[i][t];return e},d3.bisector=function(t){return{left:function(n,e,r,i){for(3>arguments.length&&(r=0),4>arguments.length&&(i=n.length);i>r;){var u=r+i>>>1;e>t.call(n,n[u],u)?r=u+1:i=u}return r},right:function(n,e,r,i){for(3>arguments.length&&(r=0),4>arguments.length&&(i=n.length);i>r;){var u=r+i>>>1;t.call(n,n[u],u)>e?i=u:r=u+1}return r}}};var Zu=d3.bisector(function(t){return t});d3.bisectLeft=Zu.left,d3.bisect=d3.bisectRight=Zu.right,d3.nest=function(){function t(n,o){if(o>=a.length)return r?r.call(i,n):e?n.sort(e):n;for(var c,l,s,f=-1,h=n.length,d=a[o++],g=new u,p={};h>++f;)(s=g.get(c=d(l=n[f])))?s.push(l):g.set(c,[l]);return g.forEach(function(n,e){p[n]=t(e,o)}),p}function n(t,e){if(e>=a.length)return t;var r,i=[],u=o[e++];for(r in t)i.push({key:r,values:n(t[r],e)});return u&&i.sort(function(t,n){return u(t.key,n.key)}),i}var e,r,i={},a=[],o=[];return i.map=function(n){return t(n,0)},i.entries=function(e){return n(t(e,0),0)},i.key=function(t){return a.push(t),i},i.sortKeys=function(t){return o[a.length-1]=t,i},i.sortValues=function(t){return e=t,i},i.rollup=function(t){return r=t,i},i},d3.keys=function(t){var n=[];for(var e in t)n.push(e);return n},d3.values=function(t){var n=[];for(var e in t)n.push(t[e]);return n},d3.entries=function(t){var n=[];for(var e in t)n.push({key:e,value:t[e]});return n},d3.permute=function(t,n){for(var e=[],r=-1,i=n.length;i>++r;)e[r]=t[n[r]];return e},d3.merge=function(t){return Array.prototype.concat.apply([],t)},d3.range=function(t,n,e){if(3>arguments.length&&(e=1,2>arguments.length&&(n=t,t=0)),1/0===(n-t)/e)throw Error("infinite range");var r,i=[],u=d(Math.abs(e)),a=-1;if(t*=u,n*=u,e*=u,0>e)for(;(r=t+e*++a)>n;)i.push(r/u);else for(;n>(r=t+e*++a);)i.push(r/u);return i},d3.requote=function(t){return t.replace(Bu,"\\$&")};var Bu=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;d3.round=function(t,n){return n?Math.round(t*(n=Math.pow(10,n)))/n:Math.round(t)},d3.xhr=function(t,n,e){function r(){var t=l.status;!t&&l.responseText||t>=200&&300>t||304===t?u.load.call(i,c.call(i,l)):u.error.call(i,l)}var i={},u=d3.dispatch("progress","load","error"),o={},c=a,l=new(window.XDomainRequest&&/^(http(s)?:)?\/\//.test(t)?XDomainRequest:XMLHttpRequest);return"onload"in l?l.onload=l.onerror=r:l.onreadystatechange=function(){l.readyState>3&&r()},l.onprogress=function(t){var n=d3.event;d3.event=t;try{u.progress.call(i,l)}finally{d3.event=n}},i.header=function(t,n){return t=(t+"").toLowerCase(),2>arguments.length?o[t]:(null==n?delete o[t]:o[t]=n+"",i)},i.mimeType=function(t){return arguments.length?(n=null==t?null:t+"",i):n},i.response=function(t){return c=t,i},["get","post"].forEach(function(t){i[t]=function(){return i.send.apply(i,[t].concat(Yu(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),l.open(e,t,!0),null==n||"accept"in o||(o.accept=n+",*/*"),l.setRequestHeader)for(var a in o)l.setRequestHeader(a,o[a]);return null!=n&&l.overrideMimeType&&l.overrideMimeType(n),null!=u&&i.on("error",u).on("load",function(t){u(null,t)}),l.send(null==r?null:r),i},i.abort=function(){return l.abort(),i},d3.rebind(i,u,"on"),2===arguments.length&&"function"==typeof n&&(e=n,n=null),null==e?i:i.get(g(e))},d3.text=function(){return d3.xhr.apply(d3,arguments).response(p)},d3.json=function(t,n){return d3.xhr(t,"application/json",n).response(m)},d3.html=function(t,n){return d3.xhr(t,"text/html",n).response(v)},d3.xml=function(){return d3.xhr.apply(d3,arguments).response(y)};var $u={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};d3.ns={prefix:$u,qualify:function(t){var n=t.indexOf(":"),e=t;return n>=0&&(e=t.substring(0,n),t=t.substring(n+1)),$u.hasOwnProperty(e)?{space:$u[e],local:t}:t}},d3.dispatch=function(){for(var t=new M,n=-1,e=arguments.length;e>++n;)t[arguments[n]]=b(t);return t},M.prototype.on=function(t,n){var e=t.indexOf("."),r="";return e>0&&(r=t.substring(e+1),t=t.substring(0,e)),2>arguments.length?this[t].on(r):this[t].on(r,n)},d3.format=function(t){var n=Ju.exec(t),e=n[1]||" ",r=n[2]||">",i=n[3]||"",u=n[4]||"",a=n[5],o=+n[6],c=n[7],l=n[8],s=n[9],f=1,h="",d=!1;switch(l&&(l=+l.substring(1)),(a||"0"===e&&"="===r)&&(a=e="0",r="=",c&&(o-=Math.floor((o-1)/4))),s){case"n":c=!0,s="g";break;case"%":f=100,h="%",s="f";break;case"p":f=100,h="%",s="r";break;case"b":case"o":case"x":case"X":u&&(u="0"+s.toLowerCase());case"c":case"d":d=!0,l=0;break;case"s":f=-1,s="r"}"#"===u&&(u=""),"r"!=s||l||(s="g"),s=Gu.get(s)||_;var g=a&&c;return function(t){if(d&&t%1)return"";var n=0>t||0===t&&0>1/t?(t=-t,"-"):i;if(0>f){var p=d3.formatPrefix(t,l);t=p.scale(t),h=p.symbol}else t*=f;t=s(t,l),!a&&c&&(t=Ku(t));var m=u.length+t.length+(g?0:n.length),v=o>m?Array(m=o-m+1).join(e):"";return g&&(t=Ku(v+t)),Cu&&t.replace(".",Cu),n+=u,("<"===r?n+t+v:">"===r?v+n+t:"^"===r?v.substring(0,m>>=1)+n+t+v.substring(m):n+(g?t:v+t))+h}};var Ju=/(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/,Gu=d3.map({b:function(t){return t.toString(2)},c:function(t){return String.fromCharCode(t)},o:function(t){return t.toString(8)},x:function(t){return t.toString(16)},X:function(t){return t.toString(16).toUpperCase()},g:function(t,n){return t.toPrecision(n)},e:function(t,n){return t.toExponential(n)},f:function(t,n){return t.toFixed(n)},r:function(t,n){return d3.round(t,n=x(t,n)).toFixed(Math.max(0,Math.min(20,n)))}}),Ku=a;if(Du){var Wu=Du.length;Ku=function(t){for(var n=t.lastIndexOf("."),e=n>=0?"."+t.substring(n+1):(n=t.length,""),r=[],i=0,u=Du[0];n>0&&u>0;)r.push(t.substring(n-=u,n+u)),u=Du[i=(i+1)%Wu];return r.reverse().join(zu||"")+e}}var Qu=["y","z","a","f","p","n","μ","m","","k","M","G","T","P","E","Z","Y"].map(w);d3.formatPrefix=function(t,n){var e=0;return t&&(0>t&&(t*=-1),n&&(t=d3.round(t,x(t,n))),e=1+Math.floor(1e-12+Math.log(t)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),Qu[8+e/3]};var ta=function(){return a},na=d3.map({linear:ta,poly:q,quad:function(){return A},cubic:function(){return N},sin:function(){return C},exp:function(){return z},circle:function(){return D},elastic:L,back:F,bounce:function(){return H}}),ea=d3.map({"in":a,out:k,"in-out":E,"out-in":function(t){return E(k(t))}});d3.ease=function(t){var n=t.indexOf("-"),e=n>=0?t.substring(0,n):t,r=n>=0?t.substring(n+1):"in";return e=na.get(e)||ta,r=ea.get(r)||a,S(r(e.apply(null,Array.prototype.slice.call(arguments,1))))},d3.event=null,d3.transform=function(t){var n=document.createElementNS(d3.ns.prefix.svg,"g");return(d3.transform=function(t){n.setAttribute("transform",t);var e=n.transform.baseVal.consolidate();return new O(e?e.matrix:ra)})(t)},O.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var ra={a:1,b:0,c:0,d:1,e:0,f:0};d3.interpolate=function(t,n){for(var e,r=d3.interpolators.length;--r>=0&&!(e=d3.interpolators[r](t,n)););return e},d3.interpolateNumber=function(t,n){return n-=t,function(e){return t+n*e}},d3.interpolateRound=function(t,n){return n-=t,function(e){return Math.round(t+n*e)}},d3.interpolateString=function(t,n){var e,r,i,u,a,o=0,c=0,l=[],s=[];for(ia.lastIndex=0,r=0;e=ia.exec(n);++r)e.index&&l.push(n.substring(o,c=e.index)),s.push({i:l.length,x:e[0]}),l.push(null),o=ia.lastIndex;for(n.length>o&&l.push(n.substring(o)),r=0,u=s.length;(e=ia.exec(t))&&u>r;++r)if(a=s[r],a.x==e[0]){if(a.i)if(null==l[a.i+1])for(l[a.i-1]+=a.x,l.splice(a.i,1),i=r+1;u>i;++i)s[i].i--;else for(l[a.i-1]+=a.x+l[a.i+1],l.splice(a.i,2),i=r+1;u>i;++i)s[i].i-=2;else if(null==l[a.i+1])l[a.i]=a.x;else for(l[a.i]=a.x+l[a.i+1],l.splice(a.i+1,1),i=r+1;u>i;++i)s[i].i--;s.splice(r,1),u--,r--}else a.x=d3.interpolateNumber(parseFloat(e[0]),parseFloat(a.x));for(;u>r;)a=s.pop(),null==l[a.i+1]?l[a.i]=a.x:(l[a.i]=a.x+l[a.i+1],l.splice(a.i+1,1)),u--;return 1===l.length?null==l[0]?s[0].x:function(){return n}:function(t){for(r=0;u>r;++r)l[(a=s[r]).i]=a.x(t);return l.join("")}},d3.interpolateTransform=function(t,n){var e,r=[],i=[],u=d3.transform(t),a=d3.transform(n),o=u.translate,c=a.translate,l=u.rotate,s=a.rotate,f=u.skew,h=a.skew,d=u.scale,g=a.scale;return o[0]!=c[0]||o[1]!=c[1]?(r.push("translate(",null,",",null,")"),i.push({i:1,x:d3.interpolateNumber(o[0],c[0])},{i:3,x:d3.interpolateNumber(o[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),l!=s?(l-s>180?s+=360:s-l>180&&(l+=360),i.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:d3.interpolateNumber(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?i.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:d3.interpolateNumber(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),d[0]!=g[0]||d[1]!=g[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),i.push({i:e-4,x:d3.interpolateNumber(d[0],g[0])},{i:e-2,x:d3.interpolateNumber(d[1],g[1])})):(1!=g[0]||1!=g[1])&&r.push(r.pop()+"scale("+g+")"),e=i.length,function(t){for(var n,u=-1;e>++u;)r[(n=i[u]).i]=n.x(t);return r.join("")}},d3.interpolateRgb=function(t,n){t=d3.rgb(t),n=d3.rgb(n);var e=t.r,r=t.g,i=t.b,u=n.r-e,a=n.g-r,o=n.b-i;return function(t){return"#"+G(Math.round(e+u*t))+G(Math.round(r+a*t))+G(Math.round(i+o*t))}},d3.interpolateHsl=function(t,n){t=d3.hsl(t),n=d3.hsl(n);var e=t.h,r=t.s,i=t.l,u=n.h-e,a=n.s-r,o=n.l-i;return u>180?u-=360:-180>u&&(u+=360),function(t){return un(e+u*t,r+a*t,i+o*t)+""}},d3.interpolateLab=function(t,n){t=d3.lab(t),n=d3.lab(n);var e=t.l,r=t.a,i=t.b,u=n.l-e,a=n.a-r,o=n.b-i;return function(t){return fn(e+u*t,r+a*t,i+o*t)+""}},d3.interpolateHcl=function(t,n){t=d3.hcl(t),n=d3.hcl(n);var e=t.h,r=t.c,i=t.l,u=n.h-e,a=n.c-r,o=n.l-i;return u>180?u-=360:-180>u&&(u+=360),function(t){return cn(e+u*t,r+a*t,i+o*t)+""}},d3.interpolateArray=function(t,n){var e,r=[],i=[],u=t.length,a=n.length,o=Math.min(t.length,n.length);for(e=0;o>e;++e)r.push(d3.interpolate(t[e],n[e]));for(;u>e;++e)i[e]=t[e];for(;a>e;++e)i[e]=n[e];return function(t){for(e=0;o>e;++e)i[e]=r[e](t);return i}},d3.interpolateObject=function(t,n){var e,r={},i={};for(e in t)e in n?r[e]=V(e)(t[e],n[e]):i[e]=t[e];for(e in n)e in t||(i[e]=n[e]);return function(t){for(e in r)i[e]=r[e](t);return i}};var ia=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;d3.interpolators=[d3.interpolateObject,function(t,n){return n instanceof Array&&d3.interpolateArray(t,n)},function(t,n){return("string"==typeof t||"string"==typeof n)&&d3.interpolateString(t+"",n+"")},function(t,n){return("string"==typeof n?aa.has(n)||/^(#|rgb\(|hsl\()/.test(n):n instanceof B)&&d3.interpolateRgb(t,n)},function(t,n){return!isNaN(t=+t)&&!isNaN(n=+n)&&d3.interpolateNumber(t,n)}],B.prototype.toString=function(){return this.rgb()+""},d3.rgb=function(t,n,e){return 1===arguments.length?t instanceof J?$(t.r,t.g,t.b):K(""+t,$,un):$(~~t,~~n,~~e)};var ua=J.prototype=new B;ua.brighter=function(t){t=Math.pow(.7,arguments.length?t:1);var n=this.r,e=this.g,r=this.b,i=30;return n||e||r?(n&&i>n&&(n=i),e&&i>e&&(e=i),r&&i>r&&(r=i),$(Math.min(255,Math.floor(n/t)),Math.min(255,Math.floor(e/t)),Math.min(255,Math.floor(r/t)))):$(i,i,i)},ua.darker=function(t){return t=Math.pow(.7,arguments.length?t:1),$(Math.floor(t*this.r),Math.floor(t*this.g),Math.floor(t*this.b)) +},ua.hsl=function(){return W(this.r,this.g,this.b)},ua.toString=function(){return"#"+G(this.r)+G(this.g)+G(this.b)};var aa=d3.map({aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"});aa.forEach(function(t,n){aa.set(t,K(n,$,un))}),d3.hsl=function(t,n,e){return 1===arguments.length?t instanceof rn?en(t.h,t.s,t.l):K(""+t,W,en):en(+t,+n,+e)};var oa=rn.prototype=new B;oa.brighter=function(t){return t=Math.pow(.7,arguments.length?t:1),en(this.h,this.s,this.l/t)},oa.darker=function(t){return t=Math.pow(.7,arguments.length?t:1),en(this.h,this.s,t*this.l)},oa.rgb=function(){return un(this.h,this.s,this.l)},d3.hcl=function(t,n,e){return 1===arguments.length?t instanceof on?an(t.h,t.c,t.l):t instanceof sn?hn(t.l,t.a,t.b):hn((t=Q((t=d3.rgb(t)).r,t.g,t.b)).l,t.a,t.b):an(+t,+n,+e)};var ca=on.prototype=new B;ca.brighter=function(t){return an(this.h,this.c,Math.min(100,this.l+la*(arguments.length?t:1)))},ca.darker=function(t){return an(this.h,this.c,Math.max(0,this.l-la*(arguments.length?t:1)))},ca.rgb=function(){return cn(this.h,this.c,this.l).rgb()},d3.lab=function(t,n,e){return 1===arguments.length?t instanceof sn?ln(t.l,t.a,t.b):t instanceof on?cn(t.l,t.c,t.h):Q((t=d3.rgb(t)).r,t.g,t.b):ln(+t,+n,+e)};var la=18,sa=.95047,fa=1,ha=1.08883,da=sn.prototype=new B;da.brighter=function(t){return ln(Math.min(100,this.l+la*(arguments.length?t:1)),this.a,this.b)},da.darker=function(t){return ln(Math.max(0,this.l-la*(arguments.length?t:1)),this.a,this.b)},da.rgb=function(){return fn(this.l,this.a,this.b)};var ga=function(t,n){return n.querySelector(t)},pa=function(t,n){return n.querySelectorAll(t)},ma=document.documentElement,va=ma.matchesSelector||ma.webkitMatchesSelector||ma.mozMatchesSelector||ma.msMatchesSelector||ma.oMatchesSelector,ya=function(t,n){return va.call(t,n)};"function"==typeof Sizzle&&(ga=function(t,n){return Sizzle(t,n)[0]||null},pa=function(t,n){return Sizzle.uniqueSort(Sizzle(t,n))},ya=Sizzle.matchesSelector);var Ma=[];d3.selection=function(){return ba},d3.selection.prototype=Ma,Ma.select=function(t){var n,e,r,i,u=[];"function"!=typeof t&&(t=vn(t));for(var a=-1,o=this.length;o>++a;){u.push(n=[]),n.parentNode=(r=this[a]).parentNode;for(var c=-1,l=r.length;l>++c;)(i=r[c])?(n.push(e=t.call(i,i.__data__,c)),e&&"__data__"in i&&(e.__data__=i.__data__)):n.push(null)}return mn(u)},Ma.selectAll=function(t){var n,e,r=[];"function"!=typeof t&&(t=yn(t));for(var i=-1,u=this.length;u>++i;)for(var a=this[i],o=-1,c=a.length;c>++o;)(e=a[o])&&(r.push(n=Yu(t.call(e,e.__data__,o))),n.parentNode=e);return mn(r)},Ma.attr=function(t,n){if(2>arguments.length){if("string"==typeof t){var e=this.node();return t=d3.ns.qualify(t),t.local?e.getAttributeNS(t.space,t.local):e.getAttribute(t)}for(n in t)this.each(Mn(n,t[n]));return this}return this.each(Mn(t,n))},Ma.classed=function(t,n){if(2>arguments.length){if("string"==typeof t){var e=this.node(),r=(t=t.trim().split(/^|\s+/g)).length,i=-1;if(n=e.classList){for(;r>++i;)if(!n.contains(t[i]))return!1}else for(n=e.className,null!=n.baseVal&&(n=n.baseVal);r>++i;)if(!bn(t[i]).test(n))return!1;return!0}for(n in t)this.each(xn(n,t[n]));return this}return this.each(xn(t,n))},Ma.style=function(t,n,e){var r=arguments.length;if(3>r){if("string"!=typeof t){2>r&&(n="");for(e in t)this.each(wn(e,t[e],n));return this}if(2>r)return getComputedStyle(this.node(),null).getPropertyValue(t);e=""}return this.each(wn(t,n,e))},Ma.property=function(t,n){if(2>arguments.length){if("string"==typeof t)return this.node()[t];for(n in t)this.each(Sn(n,t[n]));return this}return this.each(Sn(t,n))},Ma.text=function(t){return arguments.length?this.each("function"==typeof t?function(){var n=t.apply(this,arguments);this.textContent=null==n?"":n}:null==t?function(){this.textContent=""}:function(){this.textContent=t}):this.node().textContent},Ma.html=function(t){return arguments.length?this.each("function"==typeof t?function(){var n=t.apply(this,arguments);this.innerHTML=null==n?"":n}:null==t?function(){this.innerHTML=""}:function(){this.innerHTML=t}):this.node().innerHTML},Ma.append=function(t){function n(){return this.appendChild(document.createElementNS(this.namespaceURI,t))}function e(){return this.appendChild(document.createElementNS(t.space,t.local))}return t=d3.ns.qualify(t),this.select(t.local?e:n)},Ma.insert=function(t,n){function e(){return this.insertBefore(document.createElementNS(this.namespaceURI,t),ga(n,this))}function r(){return this.insertBefore(document.createElementNS(t.space,t.local),ga(n,this))}return t=d3.ns.qualify(t),this.select(t.local?r:e)},Ma.remove=function(){return this.each(function(){var t=this.parentNode;t&&t.removeChild(this)})},Ma.data=function(t,n){function e(t,e){var r,i,a,o=t.length,f=e.length,h=Math.min(o,f),d=Array(f),g=Array(f),p=Array(o);if(n){var m,v=new u,y=new u,M=[];for(r=-1;o>++r;)m=n.call(i=t[r],i.__data__,r),v.has(m)?p[r]=i:v.set(m,i),M.push(m);for(r=-1;f>++r;)m=n.call(e,a=e[r],r),(i=v.get(m))?(d[r]=i,i.__data__=a):y.has(m)||(g[r]=kn(a)),y.set(m,a),v.remove(m);for(r=-1;o>++r;)v.has(M[r])&&(p[r]=t[r])}else{for(r=-1;h>++r;)i=t[r],a=e[r],i?(i.__data__=a,d[r]=i):g[r]=kn(a);for(;f>r;++r)g[r]=kn(e[r]);for(;o>r;++r)p[r]=t[r]}g.update=d,g.parentNode=d.parentNode=p.parentNode=t.parentNode,c.push(g),l.push(d),s.push(p)}var r,i,a=-1,o=this.length;if(!arguments.length){for(t=Array(o=(r=this[0]).length);o>++a;)(i=r[a])&&(t[a]=i.__data__);return t}var c=qn([]),l=mn([]),s=mn([]);if("function"==typeof t)for(;o>++a;)e(r=this[a],t.call(r,r.parentNode.__data__,a));else for(;o>++a;)e(r=this[a],t);return l.enter=function(){return c},l.exit=function(){return s},l},Ma.datum=function(t){return arguments.length?this.property("__data__",t):this.property("__data__")},Ma.filter=function(t){var n,e,r,i=[];"function"!=typeof t&&(t=En(t));for(var u=0,a=this.length;a>u;u++){i.push(n=[]),n.parentNode=(e=this[u]).parentNode;for(var o=0,c=e.length;c>o;o++)(r=e[o])&&t.call(r,r.__data__,o)&&n.push(r)}return mn(i)},Ma.order=function(){for(var t=-1,n=this.length;n>++t;)for(var e,r=this[t],i=r.length-1,u=r[i];--i>=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Ma.sort=function(t){t=An.apply(this,arguments);for(var n=-1,e=this.length;e>++n;)this[n].sort(t);return this.order()},Ma.on=function(t,n,e){var r=arguments.length;if(3>r){if("string"!=typeof t){2>r&&(n=!1);for(e in t)this.each(Nn(e,t[e],n));return this}if(2>r)return(r=this.node()["__on"+t])&&r._;e=!1}return this.each(Nn(t,n,e))},Ma.each=function(t){return Tn(this,function(n,e,r){t.call(n,n.__data__,e,r)})},Ma.call=function(t){var n=Yu(arguments);return t.apply(n[0]=this,n),this},Ma.empty=function(){return!this.node()},Ma.node=function(){for(var t=0,n=this.length;n>t;t++)for(var e=this[t],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Ma.transition=function(){var t,n,e=_a||++Sa,r=[],i=Object.create(ka);i.time=Date.now();for(var u=-1,a=this.length;a>++u;){r.push(t=[]);for(var o=this[u],c=-1,l=o.length;l>++c;)(n=o[c])&&zn(n,c,e,i),t.push(n)}return Cn(r,e)};var ba=mn([[document]]);ba[0].parentNode=ma,d3.select=function(t){return"string"==typeof t?ba.select(t):mn([[t]])},d3.selectAll=function(t){return"string"==typeof t?ba.selectAll(t):mn([Yu(t)])};var xa=[];d3.selection.enter=qn,d3.selection.enter.prototype=xa,xa.append=Ma.append,xa.insert=Ma.insert,xa.empty=Ma.empty,xa.node=Ma.node,xa.select=function(t){for(var n,e,r,i,u,a=[],o=-1,c=this.length;c>++o;){r=(i=this[o]).update,a.push(n=[]),n.parentNode=i.parentNode;for(var l=-1,s=i.length;s>++l;)(u=i[l])?(n.push(r[l]=e=t.call(i.parentNode,u.__data__,l)),e.__data__=u.__data__):n.push(null)}return mn(a)};var _a,wa=[],Sa=0,ka={ease:T,delay:0,duration:250};wa.call=Ma.call,wa.empty=Ma.empty,wa.node=Ma.node,d3.transition=function(t){return arguments.length?_a?t.transition():t:ba.transition()},d3.transition.prototype=wa,wa.select=function(t){var n,e,r,i=this.id,u=[];"function"!=typeof t&&(t=vn(t));for(var a=-1,o=this.length;o>++a;){u.push(n=[]);for(var c=this[a],l=-1,s=c.length;s>++l;)(r=c[l])&&(e=t.call(r,r.__data__,l))?("__data__"in r&&(e.__data__=r.__data__),zn(e,l,i,r.__transition__[i]),n.push(e)):n.push(null)}return Cn(u,i)},wa.selectAll=function(t){var n,e,r,i,u,a=this.id,o=[];"function"!=typeof t&&(t=yn(t));for(var c=-1,l=this.length;l>++c;)for(var s=this[c],f=-1,h=s.length;h>++f;)if(r=s[f]){u=r.__transition__[a],e=t.call(r,r.__data__,f),o.push(n=[]);for(var d=-1,g=e.length;g>++d;)zn(i=e[d],d,a,u),n.push(i)}return Cn(o,a)},wa.filter=function(t){var n,e,r,i=[];"function"!=typeof t&&(t=En(t));for(var u=0,a=this.length;a>u;u++){i.push(n=[]);for(var e=this[u],o=0,c=e.length;c>o;o++)(r=e[o])&&t.call(r,r.__data__,o)&&n.push(r)}return Cn(i,this.id,this.time).ease(this.ease())},wa.attr=function(t,n){function e(){this.removeAttribute(u)}function r(){this.removeAttributeNS(u.space,u.local)}if(2>arguments.length){for(n in t)this.attr(n,t[n]);return this}var i=V(t),u=d3.ns.qualify(t);return Ln(this,"attr."+t,n,function(t){function n(){var n,e=this.getAttribute(u);return e!==t&&(n=i(e,t),function(t){this.setAttribute(u,n(t))})}function a(){var n,e=this.getAttributeNS(u.space,u.local);return e!==t&&(n=i(e,t),function(t){this.setAttributeNS(u.space,u.local,n(t))})}return null==t?u.local?r:e:(t+="",u.local?a:n)})},wa.attrTween=function(t,n){function e(t,e){var r=n.call(this,t,e,this.getAttribute(i));return r&&function(t){this.setAttribute(i,r(t))}}function r(t,e){var r=n.call(this,t,e,this.getAttributeNS(i.space,i.local));return r&&function(t){this.setAttributeNS(i.space,i.local,r(t))}}var i=d3.ns.qualify(t);return this.tween("attr."+t,i.local?r:e)},wa.style=function(t,n,e){function r(){this.style.removeProperty(t)}var i=arguments.length;if(3>i){if("string"!=typeof t){2>i&&(n="");for(e in t)this.style(e,t[e],n);return this}e=""}var u=V(t);return Ln(this,"style."+t,n,function(n){function i(){var r,i=getComputedStyle(this,null).getPropertyValue(t);return i!==n&&(r=u(i,n),function(n){this.style.setProperty(t,r(n),e)})}return null==n?r:(n+="",i)})},wa.styleTween=function(t,n,e){return 3>arguments.length&&(e=""),this.tween("style."+t,function(r,i){var u=n.call(this,r,i,getComputedStyle(this,null).getPropertyValue(t));return u&&function(n){this.style.setProperty(t,u(n),e)}})},wa.text=function(t){return Ln(this,"text",t,Dn)},wa.remove=function(){return this.each("end.transition",function(){var t;!this.__transition__&&(t=this.parentNode)&&t.removeChild(this)})},wa.ease=function(t){var n=this.id;return 1>arguments.length?this.node().__transition__[n].ease:("function"!=typeof t&&(t=d3.ease.apply(d3,arguments)),Tn(this,function(e){e.__transition__[n].ease=t}))},wa.delay=function(t){var n=this.id;return Tn(this,"function"==typeof t?function(e,r,i){e.__transition__[n].delay=0|t.call(e,e.__data__,r,i)}:(t|=0,function(e){e.__transition__[n].delay=t}))},wa.duration=function(t){var n=this.id;return Tn(this,"function"==typeof t?function(e,r,i){e.__transition__[n].duration=Math.max(1,0|t.call(e,e.__data__,r,i))}:(t=Math.max(1,0|t),function(e){e.__transition__[n].duration=t}))},wa.each=function(t,n){var e=this.id;if(2>arguments.length){var r=ka,i=_a;_a=e,Tn(this,function(n,r,i){ka=n.__transition__[e],t.call(n,n.__data__,r,i)}),ka=r,_a=i}else Tn(this,function(r){r.__transition__[e].event.on(t,n)});return this},wa.transition=function(){for(var t,n,e,r,i=this.id,u=++Sa,a=[],o=0,c=this.length;c>o;o++){a.push(t=[]);for(var n=this[o],l=0,s=n.length;s>l;l++)(e=n[l])&&(r=Object.create(e.__transition__[i]),r.delay+=r.duration,zn(e,l,u,r)),t.push(e)}return Cn(a,u)},wa.tween=function(t,n){var e=this.id;return 2>arguments.length?this.node().__transition__[e].tween.get(t):Tn(this,null==n?function(n){n.__transition__[e].tween.remove(t)}:function(r){r.__transition__[e].tween.set(t,n)})};var Ea,Aa,Na=0,Ta={},qa=null;d3.timer=function(t,n,e){if(3>arguments.length){if(2>arguments.length)n=0;else if(!isFinite(n))return;e=Date.now()}var r=Ta[t.id];r&&r.callback===t?(r.then=e,r.delay=n):Ta[t.id=++Na]=qa={callback:t,then:e,delay:n,next:qa},Ea||(Aa=clearTimeout(Aa),Ea=1,Ca(Fn))},d3.timer.flush=function(){for(var t,n=Date.now(),e=qa;e;)t=n-e.then,e.delay||(e.flush=e.callback(t)),e=e.next;Hn()};var Ca=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){setTimeout(t,17)};d3.mouse=function(t){return Rn(t,P())};var za=/WebKit/.test(navigator.userAgent)?-1:0;d3.touches=function(t,n){return 2>arguments.length&&(n=P().touches),n?Yu(n).map(function(n){var e=Rn(t,n);return e.identifier=n.identifier,e}):[]},d3.scale={},d3.scale.linear=function(){return In([0,1],[0,1],d3.interpolate,!1)},d3.scale.log=function(){return Kn(d3.scale.linear(),Wn)};var Da=d3.format(".0e");Wn.pow=function(t){return Math.pow(10,t)},Qn.pow=function(t){return-Math.pow(10,-t)},d3.scale.pow=function(){return te(d3.scale.linear(),1)},d3.scale.sqrt=function(){return d3.scale.pow().exponent(.5)},d3.scale.ordinal=function(){return ee([],{t:"range",a:[[]]})},d3.scale.category10=function(){return d3.scale.ordinal().range(La)},d3.scale.category20=function(){return d3.scale.ordinal().range(Fa)},d3.scale.category20b=function(){return d3.scale.ordinal().range(Ha)},d3.scale.category20c=function(){return d3.scale.ordinal().range(Ra)};var La=["#1f77b4","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf"],Fa=["#1f77b4","#aec7e8","#ff7f0e","#ffbb78","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5","#8c564b","#c49c94","#e377c2","#f7b6d2","#7f7f7f","#c7c7c7","#bcbd22","#dbdb8d","#17becf","#9edae5"],Ha=["#393b79","#5254a3","#6b6ecf","#9c9ede","#637939","#8ca252","#b5cf6b","#cedb9c","#8c6d31","#bd9e39","#e7ba52","#e7cb94","#843c39","#ad494a","#d6616b","#e7969c","#7b4173","#a55194","#ce6dbd","#de9ed6"],Ra=["#3182bd","#6baed6","#9ecae1","#c6dbef","#e6550d","#fd8d3c","#fdae6b","#fdd0a2","#31a354","#74c476","#a1d99b","#c7e9c0","#756bb1","#9e9ac8","#bcbddc","#dadaeb","#636363","#969696","#bdbdbd","#d9d9d9"];d3.scale.quantile=function(){return re([],[])},d3.scale.quantize=function(){return ie(0,1,[0,1])},d3.scale.threshold=function(){return ue([.5],[0,1])},d3.scale.identity=function(){return ae([0,1])},d3.svg={},d3.svg.arc=function(){function t(){var t=n.apply(this,arguments),u=e.apply(this,arguments),a=r.apply(this,arguments)+Pa,o=i.apply(this,arguments)+Pa,c=(a>o&&(c=a,a=o,o=c),o-a),l=Ru>c?"0":"1",s=Math.cos(a),f=Math.sin(a),h=Math.cos(o),d=Math.sin(o);return c>=ja?t?"M0,"+u+"A"+u+","+u+" 0 1,1 0,"+-u+"A"+u+","+u+" 0 1,1 0,"+u+"M0,"+t+"A"+t+","+t+" 0 1,0 0,"+-t+"A"+t+","+t+" 0 1,0 0,"+t+"Z":"M0,"+u+"A"+u+","+u+" 0 1,1 0,"+-u+"A"+u+","+u+" 0 1,1 0,"+u+"Z":t?"M"+u*s+","+u*f+"A"+u+","+u+" 0 "+l+",1 "+u*h+","+u*d+"L"+t*h+","+t*d+"A"+t+","+t+" 0 "+l+",0 "+t*s+","+t*f+"Z":"M"+u*s+","+u*f+"A"+u+","+u+" 0 "+l+",1 "+u*h+","+u*d+"L0,0"+"Z"}var n=oe,e=ce,r=le,i=se;return t.innerRadius=function(e){return arguments.length?(n=c(e),t):n},t.outerRadius=function(n){return arguments.length?(e=c(n),t):e},t.startAngle=function(n){return arguments.length?(r=c(n),t):r},t.endAngle=function(n){return arguments.length?(i=c(n),t):i},t.centroid=function(){var t=(n.apply(this,arguments)+e.apply(this,arguments))/2,u=(r.apply(this,arguments)+i.apply(this,arguments))/2+Pa;return[Math.cos(u)*t,Math.sin(u)*t]},t};var Pa=-Ru/2,ja=2*Ru-1e-6;d3.svg.line=function(){return fe(a)};var Oa=d3.map({linear:ge,"linear-closed":pe,"step-before":me,"step-after":ve,basis:we,"basis-open":Se,"basis-closed":ke,bundle:Ee,cardinal:be,"cardinal-open":ye,"cardinal-closed":Me,monotone:ze});Oa.forEach(function(t,n){n.key=t,n.closed=/-closed$/.test(t)});var Ya=[0,2/3,1/3,0],Ua=[0,1/3,2/3,0],Ia=[0,1/6,2/3,1/6];d3.svg.line.radial=function(){var t=fe(De);return t.radius=t.x,delete t.x,t.angle=t.y,delete t.y,t},me.reverse=ve,ve.reverse=me,d3.svg.area=function(){return Le(a)},d3.svg.area.radial=function(){var t=Le(De);return t.radius=t.x,delete t.x,t.innerRadius=t.x0,delete t.x0,t.outerRadius=t.x1,delete t.x1,t.angle=t.y,delete t.y,t.startAngle=t.y0,delete t.y0,t.endAngle=t.y1,delete t.y1,t},d3.svg.chord=function(){function e(t,n){var e=r(this,o,t,n),c=r(this,l,t,n);return"M"+e.p0+u(e.r,e.p1,e.a1-e.a0)+(i(e,c)?a(e.r,e.p1,e.r,e.p0):a(e.r,e.p1,c.r,c.p0)+u(c.r,c.p1,c.a1-c.a0)+a(c.r,c.p1,e.r,e.p0))+"Z"}function r(t,n,e,r){var i=n.call(t,e,r),u=s.call(t,i,r),a=f.call(t,i,r)+Pa,o=h.call(t,i,r)+Pa;return{r:u,a0:a,a1:o,p0:[u*Math.cos(a),u*Math.sin(a)],p1:[u*Math.cos(o),u*Math.sin(o)]}}function i(t,n){return t.a0==n.a0&&t.a1==n.a1}function u(t,n,e){return"A"+t+","+t+" 0 "+ +(e>Ru)+",1 "+n}function a(t,n,e,r){return"Q 0,0 "+r}var o=n,l=t,s=Fe,f=le,h=se;return e.radius=function(t){return arguments.length?(s=c(t),e):s},e.source=function(t){return arguments.length?(o=c(t),e):o},e.target=function(t){return arguments.length?(l=c(t),e):l},e.startAngle=function(t){return arguments.length?(f=c(t),e):f},e.endAngle=function(t){return arguments.length?(h=c(t),e):h},e},d3.svg.diagonal=function(){function e(t,n){var e=r.call(this,t,n),a=i.call(this,t,n),o=(e.y+a.y)/2,c=[e,{x:e.x,y:o},{x:a.x,y:o},a];return c=c.map(u),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var r=n,i=t,u=He;return e.source=function(t){return arguments.length?(r=c(t),e):r},e.target=function(t){return arguments.length?(i=c(t),e):i},e.projection=function(t){return arguments.length?(u=t,e):u},e},d3.svg.diagonal.radial=function(){var t=d3.svg.diagonal(),n=He,e=t.projection;return t.projection=function(t){return arguments.length?e(Re(n=t)):n},t},d3.svg.symbol=function(){function t(t,r){return(Va.get(n.call(this,t,r))||Oe)(e.call(this,t,r))}var n=je,e=Pe;return t.type=function(e){return arguments.length?(n=c(e),t):n},t.size=function(n){return arguments.length?(e=c(n),t):e},t};var Va=d3.map({circle:Oe,cross:function(t){var n=Math.sqrt(t/5)/2;return"M"+-3*n+","+-n+"H"+-n+"V"+-3*n+"H"+n+"V"+-n+"H"+3*n+"V"+n+"H"+n+"V"+3*n+"H"+-n+"V"+n+"H"+-3*n+"Z"},diamond:function(t){var n=Math.sqrt(t/(2*Za)),e=n*Za;return"M0,"+-n+"L"+e+",0"+" 0,"+n+" "+-e+",0"+"Z"},square:function(t){var n=Math.sqrt(t)/2;return"M"+-n+","+-n+"L"+n+","+-n+" "+n+","+n+" "+-n+","+n+"Z"},"triangle-down":function(t){var n=Math.sqrt(t/Xa),e=n*Xa/2;return"M0,"+e+"L"+n+","+-e+" "+-n+","+-e+"Z"},"triangle-up":function(t){var n=Math.sqrt(t/Xa),e=n*Xa/2;return"M0,"+-e+"L"+n+","+e+" "+-n+","+e+"Z"}});d3.svg.symbolTypes=Va.keys();var Xa=Math.sqrt(3),Za=Math.tan(30*ju);d3.svg.axis=function(){function t(t){t.each(function(){var t,f=d3.select(this),h=null==l?e.ticks?e.ticks.apply(e,c):e.domain():l,d=null==n?e.tickFormat?e.tickFormat.apply(e,c):String:n,g=Ie(e,h,s),p=f.selectAll(".minor").data(g,String),m=p.enter().insert("line","g").attr("class","tick minor").style("opacity",1e-6),v=d3.transition(p.exit()).style("opacity",1e-6).remove(),y=d3.transition(p).style("opacity",1),M=f.selectAll("g").data(h,String),b=M.enter().insert("g","path").style("opacity",1e-6),x=d3.transition(M.exit()).style("opacity",1e-6).remove(),_=d3.transition(M).style("opacity",1),w=On(e),S=f.selectAll(".domain").data([0]),k=d3.transition(S),E=e.copy(),A=this.__chart__||E;this.__chart__=E,S.enter().append("path").attr("class","domain"),b.append("line").attr("class","tick"),b.append("text");var N=b.select("line"),T=_.select("line"),q=M.select("text").text(d),C=b.select("text"),z=_.select("text");switch(r){case"bottom":t=Ye,m.attr("y2",u),y.attr("x2",0).attr("y2",u),N.attr("y2",i),C.attr("y",Math.max(i,0)+o),T.attr("x2",0).attr("y2",i),z.attr("x",0).attr("y",Math.max(i,0)+o),q.attr("dy",".71em").style("text-anchor","middle"),k.attr("d","M"+w[0]+","+a+"V0H"+w[1]+"V"+a);break;case"top":t=Ye,m.attr("y2",-u),y.attr("x2",0).attr("y2",-u),N.attr("y2",-i),C.attr("y",-(Math.max(i,0)+o)),T.attr("x2",0).attr("y2",-i),z.attr("x",0).attr("y",-(Math.max(i,0)+o)),q.attr("dy","0em").style("text-anchor","middle"),k.attr("d","M"+w[0]+","+-a+"V0H"+w[1]+"V"+-a);break;case"left":t=Ue,m.attr("x2",-u),y.attr("x2",-u).attr("y2",0),N.attr("x2",-i),C.attr("x",-(Math.max(i,0)+o)),T.attr("x2",-i).attr("y2",0),z.attr("x",-(Math.max(i,0)+o)).attr("y",0),q.attr("dy",".32em").style("text-anchor","end"),k.attr("d","M"+-a+","+w[0]+"H0V"+w[1]+"H"+-a);break;case"right":t=Ue,m.attr("x2",u),y.attr("x2",u).attr("y2",0),N.attr("x2",i),C.attr("x",Math.max(i,0)+o),T.attr("x2",i).attr("y2",0),z.attr("x",Math.max(i,0)+o).attr("y",0),q.attr("dy",".32em").style("text-anchor","start"),k.attr("d","M"+a+","+w[0]+"H0V"+w[1]+"H"+a)}if(e.ticks)b.call(t,A),_.call(t,E),x.call(t,E),m.call(t,A),y.call(t,E),v.call(t,E);else{var D=E.rangeBand()/2,L=function(t){return E(t)+D};b.call(t,L),_.call(t,L)}})}var n,e=d3.scale.linear(),r="bottom",i=6,u=6,a=6,o=3,c=[10],l=null,s=0;return t.scale=function(n){return arguments.length?(e=n,t):e},t.orient=function(n){return arguments.length?(r=n,t):r},t.ticks=function(){return arguments.length?(c=arguments,t):c},t.tickValues=function(n){return arguments.length?(l=n,t):l},t.tickFormat=function(e){return arguments.length?(n=e,t):n},t.tickSize=function(n,e){if(!arguments.length)return i;var r=arguments.length-1;return i=+n,u=r>1?+e:i,a=r>0?+arguments[r]:i,t},t.tickPadding=function(n){return arguments.length?(o=+n,t):o},t.tickSubdivide=function(n){return arguments.length?(s=+n,t):s},t},d3.svg.brush=function(){function t(u){u.each(function(){var u,a=d3.select(this),s=a.selectAll(".background").data([0]),f=a.selectAll(".extent").data([0]),h=a.selectAll(".resize").data(l,String);a.style("pointer-events","all").on("mousedown.brush",i).on("touchstart.brush",i),s.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),f.enter().append("rect").attr("class","extent").style("cursor","move"),h.enter().append("g").attr("class",function(t){return"resize "+t}).style("cursor",function(t){return Ba[t]}).append("rect").attr("x",function(t){return/[ew]$/.test(t)?-3:null}).attr("y",function(t){return/^[ns]/.test(t)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),h.style("display",t.empty()?"none":null),h.exit().remove(),o&&(u=On(o),s.attr("x",u[0]).attr("width",u[1]-u[0]),e(a)),c&&(u=On(c),s.attr("y",u[0]).attr("height",u[1]-u[0]),r(a)),n(a)})}function n(t){t.selectAll(".resize").attr("transform",function(t){return"translate("+s[+/e$/.test(t)][0]+","+s[+/^s/.test(t)][1]+")"})}function e(t){t.select(".extent").attr("x",s[0][0]),t.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1][0]-s[0][0])}function r(t){t.select(".extent").attr("y",s[0][1]),t.selectAll(".extent,.e>rect,.w>rect").attr("height",s[1][1]-s[0][1])}function i(){function i(){var t=d3.event.changedTouches;return t?d3.touches(v,t)[0]:d3.mouse(v)}function l(){32==d3.event.keyCode&&(S||(p=null,k[0]-=s[1][0],k[1]-=s[1][1],S=2),R())}function f(){32==d3.event.keyCode&&2==S&&(k[0]+=s[1][0],k[1]+=s[1][1],S=0,R())}function h(){var t=i(),u=!1;m&&(t[0]+=m[0],t[1]+=m[1]),S||(d3.event.altKey?(p||(p=[(s[0][0]+s[1][0])/2,(s[0][1]+s[1][1])/2]),k[0]=s[+(t[0]<p[0])][0],k[1]=s[+(t[1]<p[1])][1]):p=null),_&&d(t,o,0)&&(e(b),u=!0),w&&d(t,c,1)&&(r(b),u=!0),u&&(n(b),M({type:"brush",mode:S?"move":"resize"}))}function d(t,n,e){var r,i,a=On(n),o=a[0],c=a[1],l=k[e],f=s[1][e]-s[0][e];return S&&(o-=l,c-=f+l),r=Math.max(o,Math.min(c,t[e])),S?i=(r+=l)+f:(p&&(l=Math.max(o,Math.min(c,2*p[e]-r))),r>l?(i=r,r=l):i=l),s[0][e]!==r||s[1][e]!==i?(u=null,s[0][e]=r,s[1][e]=i,!0):void 0}function g(){h(),b.style("pointer-events","all").selectAll(".resize").style("display",t.empty()?"none":null),d3.select("body").style("cursor",null),E.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),M({type:"brushend"}),R()}var p,m,v=this,y=d3.select(d3.event.target),M=a.of(v,arguments),b=d3.select(v),x=y.datum(),_=!/^(n|s)$/.test(x)&&o,w=!/^(e|w)$/.test(x)&&c,S=y.classed("extent"),k=i(),E=d3.select(window).on("mousemove.brush",h).on("mouseup.brush",g).on("touchmove.brush",h).on("touchend.brush",g).on("keydown.brush",l).on("keyup.brush",f);if(S)k[0]=s[0][0]-k[0],k[1]=s[0][1]-k[1];else if(x){var A=+/w$/.test(x),N=+/^n/.test(x);m=[s[1-A][0]-k[0],s[1-N][1]-k[1]],k[0]=s[A][0],k[1]=s[N][1]}else d3.event.altKey&&(p=k.slice());b.style("pointer-events","none").selectAll(".resize").style("display",null),d3.select("body").style("cursor",y.style("cursor")),M({type:"brushstart"}),h(),R()}var u,a=j(t,"brushstart","brush","brushend"),o=null,c=null,l=$a[0],s=[[0,0],[0,0]];return t.x=function(n){return arguments.length?(o=n,l=$a[!o<<1|!c],t):o},t.y=function(n){return arguments.length?(c=n,l=$a[!o<<1|!c],t):c},t.extent=function(n){var e,r,i,a,l;return arguments.length?(u=[[0,0],[0,0]],o&&(e=n[0],r=n[1],c&&(e=e[0],r=r[0]),u[0][0]=e,u[1][0]=r,o.invert&&(e=o(e),r=o(r)),e>r&&(l=e,e=r,r=l),s[0][0]=0|e,s[1][0]=0|r),c&&(i=n[0],a=n[1],o&&(i=i[1],a=a[1]),u[0][1]=i,u[1][1]=a,c.invert&&(i=c(i),a=c(a)),i>a&&(l=i,i=a,a=l),s[0][1]=0|i,s[1][1]=0|a),t):(n=u||s,o&&(e=n[0][0],r=n[1][0],u||(e=s[0][0],r=s[1][0],o.invert&&(e=o.invert(e),r=o.invert(r)),e>r&&(l=e,e=r,r=l))),c&&(i=n[0][1],a=n[1][1],u||(i=s[0][1],a=s[1][1],c.invert&&(i=c.invert(i),a=c.invert(a)),i>a&&(l=i,i=a,a=l))),o&&c?[[e,i],[r,a]]:o?[e,r]:c&&[i,a])},t.clear=function(){return u=null,s[0][0]=s[0][1]=s[1][0]=s[1][1]=0,t},t.empty=function(){return o&&s[0][0]===s[1][0]||c&&s[0][1]===s[1][1]},d3.rebind(t,a,"on")};var Ba={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},$a=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]];d3.behavior={},d3.behavior.drag=function(){function t(){this.on("mousedown.drag",n).on("touchstart.drag",n)}function n(){function t(){var t=o.parentNode;return null!=s?d3.touches(t).filter(function(t){return t.identifier===s})[0]:d3.mouse(t)}function n(){if(!o.parentNode)return i();var n=t(),e=n[0]-f[0],r=n[1]-f[1];h|=e|r,f=n,R(),c({type:"drag",x:n[0]+a[0],y:n[1]+a[1],dx:e,dy:r})}function i(){c({type:"dragend"}),h&&(R(),d3.event.target===l&&d.on("click.drag",u,!0)),d.on(null!=s?"touchmove.drag-"+s:"mousemove.drag",null).on(null!=s?"touchend.drag-"+s:"mouseup.drag",null)}function u(){R(),d.on("click.drag",null)}var a,o=this,c=e.of(o,arguments),l=d3.event.target,s=d3.event.touches?d3.event.changedTouches[0].identifier:null,f=t(),h=0,d=d3.select(window).on(null!=s?"touchmove.drag-"+s:"mousemove.drag",n).on(null!=s?"touchend.drag-"+s:"mouseup.drag",i,!0);r?(a=r.apply(o,arguments),a=[a.x-f[0],a.y-f[1]]):a=[0,0],null==s&&R(),c({type:"dragstart"})}var e=j(t,"drag","dragstart","dragend"),r=null;return t.origin=function(n){return arguments.length?(r=n,t):r},d3.rebind(t,e,"on")},d3.behavior.zoom=function(){function t(){this.on("mousedown.zoom",o).on("mousewheel.zoom",c).on("mousemove.zoom",l).on("DOMMouseScroll.zoom",c).on("dblclick.zoom",s).on("touchstart.zoom",f).on("touchmove.zoom",h).on("touchend.zoom",f)}function n(t){return[(t[0]-b[0])/x,(t[1]-b[1])/x]}function e(t){return[t[0]*x+b[0],t[1]*x+b[1]]}function r(t){x=Math.max(_[0],Math.min(_[1],t))}function i(t,n){n=e(n),b[0]+=t[0]-n[0],b[1]+=t[1]-n[1]}function u(){m&&m.domain(p.range().map(function(t){return(t-b[0])/x}).map(p.invert)),y&&y.domain(v.range().map(function(t){return(t-b[1])/x}).map(v.invert))}function a(t){u(),d3.event.preventDefault(),t({type:"zoom",scale:x,translate:b})}function o(){function t(){l=1,i(d3.mouse(u),f),a(o)}function e(){l&&R(),s.on("mousemove.zoom",null).on("mouseup.zoom",null),l&&d3.event.target===c&&s.on("click.zoom",r,!0)}function r(){R(),s.on("click.zoom",null)}var u=this,o=w.of(u,arguments),c=d3.event.target,l=0,s=d3.select(window).on("mousemove.zoom",t).on("mouseup.zoom",e),f=n(d3.mouse(u));window.focus(),R()}function c(){d||(d=n(d3.mouse(this))),r(Math.pow(2,.002*Ve())*x),i(d3.mouse(this),d),a(w.of(this,arguments))}function l(){d=null}function s(){var t=d3.mouse(this),e=n(t),u=Math.log(x)/Math.LN2;r(Math.pow(2,d3.event.shiftKey?Math.ceil(u)-1:Math.floor(u)+1)),i(t,e),a(w.of(this,arguments))}function f(){var t=d3.touches(this),e=Date.now();if(g=x,d={},t.forEach(function(t){d[t.identifier]=n(t)}),R(),1===t.length){if(500>e-M){var u=t[0],o=n(t[0]);r(2*x),i(u,o),a(w.of(this,arguments))}M=e}}function h(){var t=d3.touches(this),n=t[0],e=d[n.identifier];if(u=t[1]){var u,o=d[u.identifier];n=[(n[0]+u[0])/2,(n[1]+u[1])/2],e=[(e[0]+o[0])/2,(e[1]+o[1])/2],r(d3.event.scale*g)}i(n,e),M=null,a(w.of(this,arguments))}var d,g,p,m,v,y,M,b=[0,0],x=1,_=Ga,w=j(t,"zoom");return t.translate=function(n){return arguments.length?(b=n.map(Number),u(),t):b},t.scale=function(n){return arguments.length?(x=+n,u(),t):x},t.scaleExtent=function(n){return arguments.length?(_=null==n?Ga:n.map(Number),t):_},t.x=function(n){return arguments.length?(m=n,p=n.copy(),b=[0,0],x=1,t):m},t.y=function(n){return arguments.length?(y=n,v=n.copy(),b=[0,0],x=1,t):y},d3.rebind(t,w,"on")};var Ja,Ga=[0,1/0];d3.layout={},d3.layout.bundle=function(){return function(t){for(var n=[],e=-1,r=t.length;r>++e;)n.push(Xe(t[e]));return n}},d3.layout.chord=function(){function t(){var t,l,f,h,d,g={},p=[],m=d3.range(u),v=[];for(e=[],r=[],t=0,h=-1;u>++h;){for(l=0,d=-1;u>++d;)l+=i[h][d];p.push(l),v.push(d3.range(u)),t+=l}for(a&&m.sort(function(t,n){return a(p[t],p[n])}),o&&v.forEach(function(t,n){t.sort(function(t,e){return o(i[n][t],i[n][e]) +})}),t=(2*Ru-s*u)/t,l=0,h=-1;u>++h;){for(f=l,d=-1;u>++d;){var y=m[h],M=v[y][d],b=i[y][M],x=l,_=l+=b*t;g[y+"-"+M]={index:y,subindex:M,startAngle:x,endAngle:_,value:b}}r[y]={index:y,startAngle:f,endAngle:l,value:(l-f)/t},l+=s}for(h=-1;u>++h;)for(d=h-1;u>++d;){var w=g[h+"-"+d],S=g[d+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&n()}function n(){e.sort(function(t,n){return c((t.source.value+t.target.value)/2,(n.source.value+n.target.value)/2)})}var e,r,i,u,a,o,c,l={},s=0;return l.matrix=function(t){return arguments.length?(u=(i=t)&&i.length,e=r=null,l):i},l.padding=function(t){return arguments.length?(s=t,e=r=null,l):s},l.sortGroups=function(t){return arguments.length?(a=t,e=r=null,l):a},l.sortSubgroups=function(t){return arguments.length?(o=t,e=null,l):o},l.sortChords=function(t){return arguments.length?(c=t,e&&n(),l):c},l.chords=function(){return e||t(),e},l.groups=function(){return r||t(),r},l},d3.layout.force=function(){function t(t){return function(n,e,r,i){if(n.point!==t){var u=n.cx-t.x,a=n.cy-t.y,o=1/Math.sqrt(u*u+a*a);if(v>(i-e)*o){var c=n.charge*o*o;return t.px-=u*c,t.py-=a*c,!0}if(n.point&&isFinite(o)){var c=n.pointCharge*o*o;t.px-=u*c,t.py-=a*c}}return!n.charge}}function n(t){t.px=d3.event.x,t.py=d3.event.y,l.resume()}var e,r,i,u,o,l={},s=d3.dispatch("start","tick","end"),f=[1,1],h=.9,d=Qe,g=tr,p=-30,m=.1,v=.8,y=[],M=[];return l.tick=function(){if(.005>(r*=.99))return s.end({type:"end",alpha:r=0}),!0;var n,e,a,c,l,d,g,v,b,x=y.length,_=M.length;for(e=0;_>e;++e)a=M[e],c=a.source,l=a.target,v=l.x-c.x,b=l.y-c.y,(d=v*v+b*b)&&(d=r*u[e]*((d=Math.sqrt(d))-i[e])/d,v*=d,b*=d,l.x-=v*(g=c.weight/(l.weight+c.weight)),l.y-=b*g,c.x+=v*(g=1-g),c.y+=b*g);if((g=r*m)&&(v=f[0]/2,b=f[1]/2,e=-1,g))for(;x>++e;)a=y[e],a.x+=(v-a.x)*g,a.y+=(b-a.y)*g;if(p)for(We(n=d3.geom.quadtree(y),r,o),e=-1;x>++e;)(a=y[e]).fixed||n.visit(t(a));for(e=-1;x>++e;)a=y[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*h,a.y-=(a.py-(a.py=a.y))*h);s.tick({type:"tick",alpha:r})},l.nodes=function(t){return arguments.length?(y=t,l):y},l.links=function(t){return arguments.length?(M=t,l):M},l.size=function(t){return arguments.length?(f=t,l):f},l.linkDistance=function(t){return arguments.length?(d=c(t),l):d},l.distance=l.linkDistance,l.linkStrength=function(t){return arguments.length?(g=c(t),l):g},l.friction=function(t){return arguments.length?(h=t,l):h},l.charge=function(t){return arguments.length?(p="function"==typeof t?t:+t,l):p},l.gravity=function(t){return arguments.length?(m=t,l):m},l.theta=function(t){return arguments.length?(v=t,l):v},l.alpha=function(t){return arguments.length?(r?r=t>0?t:0:t>0&&(s.start({type:"start",alpha:r=t}),d3.timer(l.tick)),l):r},l.start=function(){function t(t,r){for(var i,u=n(e),a=-1,o=u.length;o>++a;)if(!isNaN(i=u[a][t]))return i;return Math.random()*r}function n(){if(!a){for(a=[],r=0;s>r;++r)a[r]=[];for(r=0;h>r;++r){var t=M[r];a[t.source.index].push(t.target),a[t.target.index].push(t.source)}}return a[e]}var e,r,a,c,s=y.length,h=M.length,m=f[0],v=f[1];for(e=0;s>e;++e)(c=y[e]).index=e,c.weight=0;for(i=[],u=[],e=0;h>e;++e)c=M[e],"number"==typeof c.source&&(c.source=y[c.source]),"number"==typeof c.target&&(c.target=y[c.target]),i[e]=d.call(this,c,e),u[e]=g.call(this,c,e),++c.source.weight,++c.target.weight;for(e=0;s>e;++e)c=y[e],isNaN(c.x)&&(c.x=t("x",m)),isNaN(c.y)&&(c.y=t("y",v)),isNaN(c.px)&&(c.px=c.x),isNaN(c.py)&&(c.py=c.y);if(o=[],"function"==typeof p)for(e=0;s>e;++e)o[e]=+p.call(this,y[e],e);else for(e=0;s>e;++e)o[e]=p;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){e||(e=d3.behavior.drag().origin(a).on("dragstart",$e).on("drag",n).on("dragend",Je)),this.on("mouseover.force",Ge).on("mouseout.force",Ke).call(e)},d3.rebind(l,s,"on")},d3.layout.partition=function(){function t(n,e,r,i){var u=n.children;if(n.x=e,n.y=n.depth*i,n.dx=r,n.dy=i,u&&(a=u.length)){var a,o,c,l=-1;for(r=n.value?r/n.value:0;a>++l;)t(o=u[l],e,c=o.value*r,i),e+=c}}function n(t){var e=t.children,r=0;if(e&&(i=e.length))for(var i,u=-1;i>++u;)r=Math.max(r,n(e[u]));return 1+r}function e(e,u){var a=r.call(this,e,u);return t(a[0],0,i[0],i[1]/n(a[0])),a}var r=d3.layout.hierarchy(),i=[1,1];return e.size=function(t){return arguments.length?(i=t,e):i},hr(e,r)},d3.layout.pie=function(){function t(u){var a=u.map(function(e,r){return+n.call(t,e,r)}),o=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof i?i.apply(this,arguments):i)-r)/d3.sum(a),l=d3.range(u.length);null!=e&&l.sort(e===Ka?function(t,n){return a[n]-a[t]}:function(t,n){return e(u[t],u[n])});var s=[];return l.forEach(function(t){var n;s[t]={data:u[t],value:n=a[t],startAngle:o,endAngle:o+=n*c}}),s}var n=Number,e=Ka,r=0,i=2*Ru;return t.value=function(e){return arguments.length?(n=e,t):n},t.sort=function(n){return arguments.length?(e=n,t):e},t.startAngle=function(n){return arguments.length?(r=n,t):r},t.endAngle=function(n){return arguments.length?(i=n,t):i},t};var Ka={};d3.layout.stack=function(){function t(a,c){var l=a.map(function(e,r){return n.call(t,e,r)}),s=l.map(function(n){return n.map(function(n,e){return[u.call(t,n,e),o.call(t,n,e)]})}),f=e.call(t,s,c);l=d3.permute(l,f),s=d3.permute(s,f);var h,d,g,p=r.call(t,s,c),m=l.length,v=l[0].length;for(d=0;v>d;++d)for(i.call(t,l[0][d],g=p[d],s[0][d][1]),h=1;m>h;++h)i.call(t,l[h][d],g+=s[h-1][d][1],s[h][d][1]);return a}var n=a,e=ir,r=ur,i=rr,u=nr,o=er;return t.values=function(e){return arguments.length?(n=e,t):n},t.order=function(n){return arguments.length?(e="function"==typeof n?n:Wa.get(n)||ir,t):e},t.offset=function(n){return arguments.length?(r="function"==typeof n?n:Qa.get(n)||ur,t):r},t.x=function(n){return arguments.length?(u=n,t):u},t.y=function(n){return arguments.length?(o=n,t):o},t.out=function(n){return arguments.length?(i=n,t):i},t};var Wa=d3.map({"inside-out":function(t){var n,e,r=t.length,i=t.map(ar),u=t.map(or),a=d3.range(r).sort(function(t,n){return i[t]-i[n]}),o=0,c=0,l=[],s=[];for(n=0;r>n;++n)e=a[n],c>o?(o+=u[e],l.push(e)):(c+=u[e],s.push(e));return s.reverse().concat(l)},reverse:function(t){return d3.range(t.length).reverse()},"default":ir}),Qa=d3.map({silhouette:function(t){var n,e,r,i=t.length,u=t[0].length,a=[],o=0,c=[];for(e=0;u>e;++e){for(n=0,r=0;i>n;n++)r+=t[n][e][1];r>o&&(o=r),a.push(r)}for(e=0;u>e;++e)c[e]=(o-a[e])/2;return c},wiggle:function(t){var n,e,r,i,u,a,o,c,l,s=t.length,f=t[0],h=f.length,d=[];for(d[0]=c=l=0,e=1;h>e;++e){for(n=0,i=0;s>n;++n)i+=t[n][e][1];for(n=0,u=0,o=f[e][0]-f[e-1][0];s>n;++n){for(r=0,a=(t[n][e][1]-t[n][e-1][1])/(2*o);n>r;++r)a+=(t[r][e][1]-t[r][e-1][1])/o;u+=a*t[n][e][1]}d[e]=c-=i?u/i*o:0,l>c&&(l=c)}for(e=0;h>e;++e)d[e]-=l;return d},expand:function(t){var n,e,r,i=t.length,u=t[0].length,a=1/i,o=[];for(e=0;u>e;++e){for(n=0,r=0;i>n;n++)r+=t[n][e][1];if(r)for(n=0;i>n;n++)t[n][e][1]/=r;else for(n=0;i>n;n++)t[n][e][1]=a}for(e=0;u>e;++e)o[e]=0;return o},zero:ur});d3.layout.histogram=function(){function t(t,u){for(var a,o,c=[],l=t.map(e,this),s=r.call(this,l,u),f=i.call(this,s,l,u),u=-1,h=l.length,d=f.length-1,g=n?1:1/h;d>++u;)a=c[u]=[],a.dx=f[u+1]-(a.x=f[u]),a.y=0;if(d>0)for(u=-1;h>++u;)o=l[u],o>=s[0]&&s[1]>=o&&(a=c[d3.bisect(f,o,1,d)-1],a.y+=g,a.push(t[u]));return c}var n=!0,e=Number,r=fr,i=lr;return t.value=function(n){return arguments.length?(e=n,t):e},t.range=function(n){return arguments.length?(r=c(n),t):r},t.bins=function(n){return arguments.length?(i="number"==typeof n?function(t){return sr(t,n)}:c(n),t):i},t.frequency=function(e){return arguments.length?(n=!!e,t):n},t},d3.layout.hierarchy=function(){function t(n,a,o){var c=i.call(e,n,a);if(n.depth=a,o.push(n),c&&(l=c.length)){for(var l,s,f=-1,h=n.children=[],d=0,g=a+1;l>++f;)s=t(c[f],g,o),s.parent=n,h.push(s),d+=s.value;r&&h.sort(r),u&&(n.value=d)}else u&&(n.value=+u.call(e,n,a)||0);return n}function n(t,r){var i=t.children,a=0;if(i&&(o=i.length))for(var o,c=-1,l=r+1;o>++c;)a+=n(i[c],l);else u&&(a=+u.call(e,t,r)||0);return u&&(t.value=a),a}function e(n){var e=[];return t(n,0,e),e}var r=pr,i=dr,u=gr;return e.sort=function(t){return arguments.length?(r=t,e):r},e.children=function(t){return arguments.length?(i=t,e):i},e.value=function(t){return arguments.length?(u=t,e):u},e.revalue=function(t){return n(t,0),t},e},d3.layout.pack=function(){function t(t,i){var u=n.call(this,t,i),a=u[0];a.x=0,a.y=0,Rr(a,function(t){t.r=Math.sqrt(t.value)}),Rr(a,xr);var o=r[0],c=r[1],l=Math.max(2*a.r/o,2*a.r/c);if(e>0){var s=e*l/2;Rr(a,function(t){t.r+=s}),Rr(a,xr),Rr(a,function(t){t.r-=s}),l=Math.max(2*a.r/o,2*a.r/c)}return Sr(a,o/2,c/2,1/l),u}var n=d3.layout.hierarchy().sort(vr),e=0,r=[1,1];return t.size=function(n){return arguments.length?(r=n,t):r},t.padding=function(n){return arguments.length?(e=+n,t):e},hr(t,n)},d3.layout.cluster=function(){function t(t,i){var u,a=n.call(this,t,i),o=a[0],c=0;Rr(o,function(t){var n=t.children;n&&n.length?(t.x=Ar(n),t.y=Er(n)):(t.x=u?c+=e(t,u):0,t.y=0,u=t)});var l=Nr(o),s=Tr(o),f=l.x-e(l,s)/2,h=s.x+e(s,l)/2;return Rr(o,function(t){t.x=(t.x-f)/(h-f)*r[0],t.y=(1-(o.y?t.y/o.y:1))*r[1]}),a}var n=d3.layout.hierarchy().sort(null).value(null),e=qr,r=[1,1];return t.separation=function(n){return arguments.length?(e=n,t):e},t.size=function(n){return arguments.length?(r=n,t):r},hr(t,n)},d3.layout.tree=function(){function t(t,i){function u(t,n){var r=t.children,i=t._tree;if(r&&(a=r.length)){for(var a,c,l,s=r[0],f=s,h=-1;a>++h;)l=r[h],u(l,c),f=o(l,c,f),c=l;Pr(t);var d=.5*(s._tree.prelim+l._tree.prelim);n?(i.prelim=n._tree.prelim+e(t,n),i.mod=i.prelim-d):i.prelim=d}else n&&(i.prelim=n._tree.prelim+e(t,n))}function a(t,n){t.x=t._tree.prelim+n;var e=t.children;if(e&&(r=e.length)){var r,i=-1;for(n+=t._tree.mod;r>++i;)a(e[i],n)}}function o(t,n,r){if(n){for(var i,u=t,a=t,o=n,c=t.parent.children[0],l=u._tree.mod,s=a._tree.mod,f=o._tree.mod,h=c._tree.mod;o=zr(o),u=Cr(u),o&&u;)c=Cr(c),a=zr(a),a._tree.ancestor=t,i=o._tree.prelim+f-u._tree.prelim-l+e(o,u),i>0&&(jr(Or(o,t,r),t,i),l+=i,s+=i),f+=o._tree.mod,l+=u._tree.mod,h+=c._tree.mod,s+=a._tree.mod;o&&!zr(a)&&(a._tree.thread=o,a._tree.mod+=f-s),u&&!Cr(c)&&(c._tree.thread=u,c._tree.mod+=l-h,r=t)}return r}var c=n.call(this,t,i),l=c[0];Rr(l,function(t,n){t._tree={ancestor:t,prelim:0,mod:0,change:0,shift:0,number:n?n._tree.number+1:0}}),u(l),a(l,-l._tree.prelim);var s=Dr(l,Fr),f=Dr(l,Lr),h=Dr(l,Hr),d=s.x-e(s,f)/2,g=f.x+e(f,s)/2,p=h.depth||1;return Rr(l,function(t){t.x=(t.x-d)/(g-d)*r[0],t.y=t.depth/p*r[1],delete t._tree}),c}var n=d3.layout.hierarchy().sort(null).value(null),e=qr,r=[1,1];return t.separation=function(n){return arguments.length?(e=n,t):e},t.size=function(n){return arguments.length?(r=n,t):r},hr(t,n)},d3.layout.treemap=function(){function t(t,n){for(var e,r,i=-1,u=t.length;u>++i;)r=(e=t[i]).value*(0>n?0:n),e.area=isNaN(r)||0>=r?0:r}function n(e){var u=e.children;if(u&&u.length){var a,o,c,l=f(e),s=[],h=u.slice(),g=1/0,p="slice"===d?l.dx:"dice"===d?l.dy:"slice-dice"===d?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(t(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(a=h[c-1]),s.area+=a.area,"squarify"!==d||g>=(o=r(s,p))?(h.pop(),g=o):(s.area-=s.pop().area,i(s,p,l,!1),p=Math.min(l.dx,l.dy),s.length=s.area=0,g=1/0);s.length&&(i(s,p,l,!0),s.length=s.area=0),u.forEach(n)}}function e(n){var r=n.children;if(r&&r.length){var u,a=f(n),o=r.slice(),c=[];for(t(o,a.dx*a.dy/n.value),c.area=0;u=o.pop();)c.push(u),c.area+=u.area,null!=u.z&&(i(c,u.z?a.dx:a.dy,a,!o.length),c.length=c.area=0);r.forEach(e)}}function r(t,n){for(var e,r=t.area,i=0,u=1/0,a=-1,o=t.length;o>++a;)(e=t[a].area)&&(u>e&&(u=e),e>i&&(i=e));return r*=r,n*=n,r?Math.max(n*i*g/r,r/(n*u*g)):1/0}function i(t,n,e,r){var i,u=-1,a=t.length,o=e.x,l=e.y,s=n?c(t.area/n):0;if(n==e.dx){for((r||s>e.dy)&&(s=e.dy);a>++u;)i=t[u],i.x=o,i.y=l,i.dy=s,o+=i.dx=Math.min(e.x+e.dx-o,s?c(i.area/s):0);i.z=!0,i.dx+=e.x+e.dx-o,e.y+=s,e.dy-=s}else{for((r||s>e.dx)&&(s=e.dx);a>++u;)i=t[u],i.x=o,i.y=l,i.dx=s,l+=i.dy=Math.min(e.y+e.dy-l,s?c(i.area/s):0);i.z=!1,i.dy+=e.y+e.dy-l,e.x+=s,e.dx-=s}}function u(r){var i=a||o(r),u=i[0];return u.x=0,u.y=0,u.dx=l[0],u.dy=l[1],a&&o.revalue(u),t([u],u.dx*u.dy/u.value),(a?e:n)(u),h&&(a=i),i}var a,o=d3.layout.hierarchy(),c=Math.round,l=[1,1],s=null,f=Yr,h=!1,d="squarify",g=.5*(1+Math.sqrt(5));return u.size=function(t){return arguments.length?(l=t,u):l},u.padding=function(t){function n(n){var e=t.call(u,n,n.depth);return null==e?Yr(n):Ur(n,"number"==typeof e?[e,e,e,e]:e)}function e(n){return Ur(n,t)}if(!arguments.length)return s;var r;return f=null==(s=t)?Yr:"function"==(r=typeof t)?n:"number"===r?(t=[t,t,t,t],e):e,u},u.round=function(t){return arguments.length?(c=t?Math.round:Number,u):c!=Number},u.sticky=function(t){return arguments.length?(h=t,a=null,u):h},u.ratio=function(t){return arguments.length?(g=t,u):g},u.mode=function(t){return arguments.length?(d=t+"",u):d},hr(u,o)},d3.csv=Ir(",","text/csv"),d3.tsv=Ir(" ","text/tab-separated-values"),d3.geo={},d3.geo.stream=function(t,n){to.hasOwnProperty(t.type)?to[t.type](t,n):Vr(t,n)};var to={Feature:function(t,n){Vr(t.geometry,n)},FeatureCollection:function(t,n){for(var e=t.features,r=-1,i=e.length;i>++r;)Vr(e[r].geometry,n)}},no={Sphere:function(t,n){n.sphere()},Point:function(t,n){var e=t.coordinates;n.point(e[0],e[1])},MultiPoint:function(t,n){for(var e,r=t.coordinates,i=-1,u=r.length;u>++i;)e=r[i],n.point(e[0],e[1])},LineString:function(t,n){Xr(t.coordinates,n,0)},MultiLineString:function(t,n){for(var e=t.coordinates,r=-1,i=e.length;i>++r;)Xr(e[r],n,0)},Polygon:function(t,n){Zr(t.coordinates,n)},MultiPolygon:function(t,n){for(var e=t.coordinates,r=-1,i=e.length;i>++r;)Zr(e[r],n)},GeometryCollection:function(t,n){for(var e=t.geometries,r=-1,i=e.length;i>++r;)Vr(e[r],n)}};d3.geo.albersUsa=function(){function t(t){return n(t)(t)}function n(t){var n=t[0],a=t[1];return a>50?r:-140>n?i:21>a?u:e}var e=d3.geo.albers(),r=d3.geo.albers().rotate([160,0]).center([0,60]).parallels([55,65]),i=d3.geo.albers().rotate([160,0]).center([0,20]).parallels([8,18]),u=d3.geo.albers().rotate([60,0]).center([0,10]).parallels([8,18]);return t.scale=function(n){return arguments.length?(e.scale(n),r.scale(.6*n),i.scale(n),u.scale(1.5*n),t.translate(e.translate())):e.scale()},t.translate=function(n){if(!arguments.length)return e.translate();var a=e.scale(),o=n[0],c=n[1];return e.translate(n),r.translate([o-.4*a,c+.17*a]),i.translate([o-.19*a,c+.2*a]),u.translate([o+.58*a,c+.43*a]),t},t.scale(e.scale())},(d3.geo.albers=function(){var t=29.5*ju,n=45.5*ju,e=Pi(ei),r=e(t,n);return r.parallels=function(r){return arguments.length?e(t=r[0]*ju,n=r[1]*ju):[t*Ou,n*Ou]},r.rotate([98,0]).center([0,38]).scale(1e3)}).raw=ei;var eo=Vi(function(t){return Math.sqrt(2/(1+t))},function(t){return 2*Math.asin(t/2)});(d3.geo.azimuthalEqualArea=function(){return Ri(eo)}).raw=eo;var ro=Vi(function(t){var n=Math.acos(t);return n&&n/Math.sin(n)},a);(d3.geo.azimuthalEquidistant=function(){return Ri(ro)}).raw=ro,d3.geo.bounds=ri(a),d3.geo.centroid=function(t){io=uo=ao=oo=co=0,d3.geo.stream(t,lo);var n;return uo&&Math.abs(n=Math.sqrt(ao*ao+oo*oo+co*co))>Pu?[Math.atan2(oo,ao)*Ou,Math.asin(Math.max(-1,Math.min(1,co/n)))*Ou]:void 0};var io,uo,ao,oo,co,lo={sphere:function(){2>io&&(io=2,uo=ao=oo=co=0)},point:ii,lineStart:ai,lineEnd:oi,polygonStart:function(){2>io&&(io=2,uo=ao=oo=co=0),lo.lineStart=ui},polygonEnd:function(){lo.lineStart=ai}};d3.geo.circle=function(){function t(){var t="function"==typeof r?r.apply(this,arguments):r,n=Oi(-t[0]*ju,-t[1]*ju,0).invert,i=[];return e(null,null,1,{point:function(t,e){i.push(t=n(t,e)),t[0]*=Ou,t[1]*=Ou}}),{type:"Polygon",coordinates:[i]}}var n,e,r=[0,0],i=6;return t.origin=function(n){return arguments.length?(r=n,t):r},t.angle=function(r){return arguments.length?(e=ci((n=+r)*ju,i*ju),t):n},t.precision=function(r){return arguments.length?(e=ci(n*ju,(i=+r)*ju),t):i},t.angle(90)};var so=si(o,vi,Mi);(d3.geo.equirectangular=function(){return Ri(_i).scale(250/Ru)}).raw=_i.invert=_i;var fo=Vi(function(t){return 1/t},Math.atan);(d3.geo.gnomonic=function(){return Ri(fo)}).raw=fo,d3.geo.graticule=function(){function t(){return{type:"MultiLineString",coordinates:n()}}function n(){return d3.range(Math.ceil(r/c)*c,e,c).map(a).concat(d3.range(Math.ceil(u/l)*l,i,l).map(o))}var e,r,i,u,a,o,c=22.5,l=c,s=2.5;return t.lines=function(){return n().map(function(t){return{type:"LineString",coordinates:t}})},t.outline=function(){return{type:"Polygon",coordinates:[a(r).concat(o(i).slice(1),a(e).reverse().slice(1),o(u).reverse().slice(1))]}},t.extent=function(n){return arguments.length?(r=+n[0][0],e=+n[1][0],u=+n[0][1],i=+n[1][1],r>e&&(n=r,r=e,e=n),u>i&&(n=u,u=i,i=n),t.precision(s)):[[r,u],[e,i]]},t.step=function(n){return arguments.length?(c=+n[0],l=+n[1],t):[c,l]},t.precision=function(n){return arguments.length?(s=+n,a=wi(u,i,s),o=Si(r,e,s),t):s},t.extent([[-180+Pu,-90+Pu],[180-Pu,90-Pu]])},d3.geo.interpolate=function(t,n){return ki(t[0]*ju,t[1]*ju,n[0]*ju,n[1]*ju)},d3.geo.greatArc=function(){function e(){for(var t=r||a.apply(this,arguments),n=i||o.apply(this,arguments),e=u||d3.geo.interpolate(t,n),i=0,l=c/e.distance,s=[t];1>(i+=l);)s.push(e(i));return s.push(n),{type:"LineString",coordinates:s}}var r,i,u,a=n,o=t,c=6*ju;return e.distance=function(){return(u||d3.geo.interpolate(r||a.apply(this,arguments),i||o.apply(this,arguments))).distance},e.source=function(t){return arguments.length?(a=t,r="function"==typeof t?null:t,u=r&&i?d3.geo.interpolate(r,i):null,e):a},e.target=function(t){return arguments.length?(o=t,i="function"==typeof t?null:t,u=r&&i?d3.geo.interpolate(r,i):null,e):o},e.precision=function(t){return arguments.length?(c=t*ju,e):c/ju},e},Ei.invert=function(t,n){return[2*Ru*t,2*Math.atan(Math.exp(2*Ru*n))-Ru/2]},(d3.geo.mercator=function(){return Ri(Ei).scale(500)}).raw=Ei;var ho=Vi(function(){return 1},Math.asin);(d3.geo.orthographic=function(){return Ri(ho)}).raw=ho,d3.geo.path=function(){function t(t){return t&&d3.geo.stream(t,r(i.pointRadius("function"==typeof u?+u.apply(this,arguments):u))),i.result()}var n,e,r,i,u=4.5;return t.area=function(t){return go=0,d3.geo.stream(t,r(mo)),go},t.centroid=function(t){return io=ao=oo=co=0,d3.geo.stream(t,r(vo)),co?[ao/co,oo/co]:void 0},t.bounds=function(t){return ri(r)(t)},t.projection=function(e){return arguments.length?(r=(n=e)?e.stream||Ni(e):a,t):n},t.context=function(n){return arguments.length?(i=null==(e=n)?new Ti:new qi(n),t):e},t.pointRadius=function(n){return arguments.length?(u="function"==typeof n?n:+n,t):u},t.projection(d3.geo.albersUsa()).context(null)};var go,po,mo={point:Pn,lineStart:Pn,lineEnd:Pn,polygonStart:function(){po=0,mo.lineStart=Ci},polygonEnd:function(){mo.lineStart=mo.lineEnd=mo.point=Pn,go+=Math.abs(po/2)}},vo={point:zi,lineStart:Di,lineEnd:Li,polygonStart:function(){vo.lineStart=Fi},polygonEnd:function(){vo.point=zi,vo.lineStart=Di,vo.lineEnd=Li}};d3.geo.area=function(t){return yo=0,d3.geo.stream(t,bo),yo};var yo,Mo,bo={sphere:function(){yo+=4*Ru},point:Pn,lineStart:Pn,lineEnd:Pn,polygonStart:function(){Mo=0,bo.lineStart=Hi},polygonEnd:function(){yo+=0>Mo?4*Ru+Mo:Mo,bo.lineStart=bo.lineEnd=bo.point=Pn}};d3.geo.projection=Ri,d3.geo.projectionMutator=Pi;var xo=Vi(function(t){return 1/(1+t)},function(t){return 2*Math.atan(t)});(d3.geo.stereographic=function(){return Ri(xo)}).raw=xo,d3.geom={},d3.geom.hull=function(t){if(3>t.length)return[];var n,e,r,i,u,a,o,c,l,s,f=t.length,h=f-1,d=[],g=[],p=0;for(n=1;f>n;++n)t[n][1]<t[p][1]?p=n:t[n][1]==t[p][1]&&(p=t[n][0]<t[p][0]?n:p);for(n=0;f>n;++n)n!==p&&(i=t[n][1]-t[p][1],r=t[n][0]-t[p][0],d.push({angle:Math.atan2(i,r),index:n}));for(d.sort(function(t,n){return t.angle-n.angle}),l=d[0].angle,c=d[0].index,o=0,n=1;h>n;++n)e=d[n].index,l==d[n].angle?(r=t[c][0]-t[p][0],i=t[c][1]-t[p][1],u=t[e][0]-t[p][0],a=t[e][1]-t[p][1],r*r+i*i>=u*u+a*a?d[n].index=-1:(d[o].index=-1,l=d[n].angle,o=n,c=e)):(l=d[n].angle,o=n,c=e);for(g.push(p),n=0,e=0;2>n;++e)-1!==d[e].index&&(g.push(d[e].index),n++);for(s=g.length;h>e;++e)if(-1!==d[e].index){for(;!Xi(g[s-2],g[s-1],d[e].index,t);)--s;g[s++]=d[e].index}var m=[];for(n=0;s>n;++n)m.push(t[g[n]]);return m},d3.geom.polygon=function(t){return t.area=function(){for(var n=0,e=t.length,r=t[e-1][1]*t[0][0]-t[e-1][0]*t[0][1];e>++n;)r+=t[n-1][1]*t[n][0]-t[n-1][0]*t[n][1];return.5*r},t.centroid=function(n){var e,r,i=-1,u=t.length,a=0,o=0,c=t[u-1];for(arguments.length||(n=-1/(6*t.area()));u>++i;)e=c,c=t[i],r=e[0]*c[1]-c[0]*e[1],a+=(e[0]+c[0])*r,o+=(e[1]+c[1])*r;return[a*n,o*n]},t.clip=function(n){for(var e,r,i,u,a,o,c=-1,l=t.length,s=t[l-1];l>++c;){for(e=n.slice(),n.length=0,u=t[c],a=e[(i=e.length)-1],r=-1;i>++r;)o=e[r],Zi(o,s,u)?(Zi(a,s,u)||n.push(Bi(a,o,s,u)),n.push(o)):Zi(a,s,u)&&n.push(Bi(a,o,s,u)),a=o;s=u}return n},t},d3.geom.voronoi=function(t){var n=t.map(function(){return[]}),e=1e6;return $i(t,function(t){var r,i,u,a,o,c;1===t.a&&t.b>=0?(r=t.ep.r,i=t.ep.l):(r=t.ep.l,i=t.ep.r),1===t.a?(o=r?r.y:-e,u=t.c-t.b*o,c=i?i.y:e,a=t.c-t.b*c):(u=r?r.x:-e,o=t.c-t.a*u,a=i?i.x:e,c=t.c-t.a*a);var l=[u,o],s=[a,c];n[t.region.l.index].push(l,s),n[t.region.r.index].push(l,s)}),n=n.map(function(n,e){var r=t[e][0],i=t[e][1],u=n.map(function(t){return Math.atan2(t[0]-r,t[1]-i)});return d3.range(n.length).sort(function(t,n){return u[t]-u[n]}).filter(function(t,n,e){return!n||u[t]-u[e[n-1]]>Pu}).map(function(t){return n[t]})}),n.forEach(function(n,r){var i=n.length;if(!i)return n.push([-e,-e],[-e,e],[e,e],[e,-e]);if(!(i>2)){var u=t[r],a=n[0],o=n[1],c=u[0],l=u[1],s=a[0],f=a[1],h=o[0],d=o[1],g=Math.abs(h-s),p=d-f;if(Pu>Math.abs(p)){var m=f>l?-e:e;n.push([-e,m],[e,m])}else if(Pu>g){var v=s>c?-e:e;n.push([v,-e],[v,e])}else{var m=(s-c)*(d-f)>(h-s)*(f-l)?e:-e,y=Math.abs(p)-g;Pu>Math.abs(y)?n.push([0>p?m:-m,m]):(y>0&&(m*=-1),n.push([-e,m],[e,m]))}}}),n};var _o={l:"r",r:"l"};d3.geom.delaunay=function(t){var n=t.map(function(){return[]}),e=[];return $i(t,function(e){n[e.region.l.index].push(t[e.region.r.index])}),n.forEach(function(n,r){var i=t[r],u=i[0],a=i[1];n.forEach(function(t){t.angle=Math.atan2(t[0]-u,t[1]-a)}),n.sort(function(t,n){return t.angle-n.angle});for(var o=0,c=n.length-1;c>o;o++)e.push([i,n[o],n[o+1]])}),e},d3.geom.quadtree=function(t,n,e,r,i){function u(t,n,e,r,i,u){if(!isNaN(n.x)&&!isNaN(n.y))if(t.leaf){var o=t.point;o?.01>Math.abs(o.x-n.x)+Math.abs(o.y-n.y)?a(t,n,e,r,i,u):(t.point=null,a(t,o,e,r,i,u),a(t,n,e,r,i,u)):t.point=n}else a(t,n,e,r,i,u)}function a(t,n,e,r,i,a){var o=.5*(e+i),c=.5*(r+a),l=n.x>=o,s=n.y>=c,f=(s<<1)+l;t.leaf=!1,t=t.nodes[f]||(t.nodes[f]=Ji()),l?e=o:i=o,s?r=c:a=c,u(t,n,e,r,i,a)}var o,c=-1,l=t.length;if(5>arguments.length)if(3===arguments.length)i=e,r=n,e=n=0;else for(n=e=1/0,r=i=-1/0;l>++c;)o=t[c],n>o.x&&(n=o.x),e>o.y&&(e=o.y),o.x>r&&(r=o.x),o.y>i&&(i=o.y);var s=r-n,f=i-e;s>f?i=e+s:r=n+f;var h=Ji();return h.add=function(t){u(h,t,n,e,r,i)},h.visit=function(t){Gi(t,h,n,e,r,i)},t.forEach(h.add),h},d3.time={};var wo=Date,So=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];Ki.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){ko.setUTCDate.apply(this._,arguments)},setDay:function(){ko.setUTCDay.apply(this._,arguments)},setFullYear:function(){ko.setUTCFullYear.apply(this._,arguments)},setHours:function(){ko.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){ko.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){ko.setUTCMinutes.apply(this._,arguments)},setMonth:function(){ko.setUTCMonth.apply(this._,arguments)},setSeconds:function(){ko.setUTCSeconds.apply(this._,arguments)},setTime:function(){ko.setTime.apply(this._,arguments)}};var ko=Date.prototype,Eo="%a %b %e %X %Y",Ao="%m/%d/%Y",No="%H:%M:%S",To=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],qo=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],Co=["January","February","March","April","May","June","July","August","September","October","November","December"],zo=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];d3.time.format=function(t){function n(n){for(var r,i,u,a=[],o=-1,c=0;e>++o;)37===t.charCodeAt(o)&&(a.push(t.substring(c,o)),null!=(i=jo[r=t.charAt(++o)])&&(r=t.charAt(++o)),(u=Oo[r])&&(r=u(n,null==i?"e"===r?" ":"0":i)),a.push(r),c=o+1);return a.push(t.substring(c,o)),a.join("")}var e=t.length;return n.parse=function(n){var e={y:1900,m:0,d:1,H:0,M:0,S:0,L:0},r=Wi(e,t,n,0);if(r!=n.length)return null;"p"in e&&(e.H=e.H%12+12*e.p);var i=new wo;return i.setFullYear(e.y,e.m,e.d),i.setHours(e.H,e.M,e.S,e.L),i},n.toString=function(){return t},n};var Do=Qi(To),Lo=Qi(qo),Fo=Qi(Co),Ho=tu(Co),Ro=Qi(zo),Po=tu(zo),jo={"-":"",_:" ",0:"0"},Oo={a:function(t){return qo[t.getDay()]},A:function(t){return To[t.getDay()]},b:function(t){return zo[t.getMonth()]},B:function(t){return Co[t.getMonth()]},c:d3.time.format(Eo),d:function(t,n){return nu(t.getDate(),n,2)},e:function(t,n){return nu(t.getDate(),n,2)},H:function(t,n){return nu(t.getHours(),n,2)},I:function(t,n){return nu(t.getHours()%12||12,n,2)},j:function(t,n){return nu(1+d3.time.dayOfYear(t),n,3)},L:function(t,n){return nu(t.getMilliseconds(),n,3)},m:function(t,n){return nu(t.getMonth()+1,n,2)},M:function(t,n){return nu(t.getMinutes(),n,2)},p:function(t){return t.getHours()>=12?"PM":"AM"},S:function(t,n){return nu(t.getSeconds(),n,2)},U:function(t,n){return nu(d3.time.sundayOfYear(t),n,2)},w:function(t){return t.getDay()},W:function(t,n){return nu(d3.time.mondayOfYear(t),n,2)},x:d3.time.format(Ao),X:d3.time.format(No),y:function(t,n){return nu(t.getFullYear()%100,n,2)},Y:function(t,n){return nu(t.getFullYear()%1e4,n,4)},Z:Mu,"%":function(){return"%"}},Yo={a:eu,A:ru,b:iu,B:uu,c:au,d:du,e:du,H:gu,I:gu,L:vu,m:hu,M:pu,p:yu,S:mu,x:ou,X:cu,y:su,Y:lu},Uo=/^\s*\d+/,Io=d3.map({am:0,pm:1});d3.time.format.utc=function(t){function n(t){try{wo=Ki;var n=new wo;return n._=t,e(n)}finally{wo=Date}}var e=d3.time.format(t);return n.parse=function(t){try{wo=Ki;var n=e.parse(t);return n&&n._}finally{wo=Date}},n.toString=e.toString,n};var Vo=d3.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ");d3.time.format.iso=Date.prototype.toISOString?bu:Vo,bu.parse=function(t){var n=new Date(t);return isNaN(n)?null:n},bu.toString=Vo.toString,d3.time.second=xu(function(t){return new wo(1e3*Math.floor(t/1e3))},function(t,n){t.setTime(t.getTime()+1e3*Math.floor(n))},function(t){return t.getSeconds()}),d3.time.seconds=d3.time.second.range,d3.time.seconds.utc=d3.time.second.utc.range,d3.time.minute=xu(function(t){return new wo(6e4*Math.floor(t/6e4))},function(t,n){t.setTime(t.getTime()+6e4*Math.floor(n))},function(t){return t.getMinutes()}),d3.time.minutes=d3.time.minute.range,d3.time.minutes.utc=d3.time.minute.utc.range,d3.time.hour=xu(function(t){var n=t.getTimezoneOffset()/60;return new wo(36e5*(Math.floor(t/36e5-n)+n))},function(t,n){t.setTime(t.getTime()+36e5*Math.floor(n))},function(t){return t.getHours()}),d3.time.hours=d3.time.hour.range,d3.time.hours.utc=d3.time.hour.utc.range,d3.time.day=xu(function(t){var n=new wo(1970,0);return n.setFullYear(t.getFullYear(),t.getMonth(),t.getDate()),n},function(t,n){t.setDate(t.getDate()+n)},function(t){return t.getDate()-1}),d3.time.days=d3.time.day.range,d3.time.days.utc=d3.time.day.utc.range,d3.time.dayOfYear=function(t){var n=d3.time.year(t);return Math.floor((t-n-6e4*(t.getTimezoneOffset()-n.getTimezoneOffset()))/864e5)},So.forEach(function(t,n){t=t.toLowerCase(),n=7-n;var e=d3.time[t]=xu(function(t){return(t=d3.time.day(t)).setDate(t.getDate()-(t.getDay()+n)%7),t},function(t,n){t.setDate(t.getDate()+7*Math.floor(n))},function(t){var e=d3.time.year(t).getDay();return Math.floor((d3.time.dayOfYear(t)+(e+n)%7)/7)-(e!==n)});d3.time[t+"s"]=e.range,d3.time[t+"s"].utc=e.utc.range,d3.time[t+"OfYear"]=function(t){var e=d3.time.year(t).getDay();return Math.floor((d3.time.dayOfYear(t)+(e+n)%7)/7)}}),d3.time.week=d3.time.sunday,d3.time.weeks=d3.time.sunday.range,d3.time.weeks.utc=d3.time.sunday.utc.range,d3.time.weekOfYear=d3.time.sundayOfYear,d3.time.month=xu(function(t){return t=d3.time.day(t),t.setDate(1),t},function(t,n){t.setMonth(t.getMonth()+n)},function(t){return t.getMonth()}),d3.time.months=d3.time.month.range,d3.time.months.utc=d3.time.month.utc.range,d3.time.year=xu(function(t){return t=d3.time.day(t),t.setMonth(0,1),t},function(t,n){t.setFullYear(t.getFullYear()+n)},function(t){return t.getFullYear()}),d3.time.years=d3.time.year.range,d3.time.years.utc=d3.time.year.utc.range;var Xo=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Zo=[[d3.time.second,1],[d3.time.second,5],[d3.time.second,15],[d3.time.second,30],[d3.time.minute,1],[d3.time.minute,5],[d3.time.minute,15],[d3.time.minute,30],[d3.time.hour,1],[d3.time.hour,3],[d3.time.hour,6],[d3.time.hour,12],[d3.time.day,1],[d3.time.day,2],[d3.time.week,1],[d3.time.month,1],[d3.time.month,3],[d3.time.year,1]],Bo=[[d3.time.format("%Y"),o],[d3.time.format("%B"),function(t){return t.getMonth()}],[d3.time.format("%b %d"),function(t){return 1!=t.getDate()}],[d3.time.format("%a %d"),function(t){return t.getDay()&&1!=t.getDate()}],[d3.time.format("%I %p"),function(t){return t.getHours()}],[d3.time.format("%I:%M"),function(t){return t.getMinutes()}],[d3.time.format(":%S"),function(t){return t.getSeconds()}],[d3.time.format(".%L"),function(t){return t.getMilliseconds()}]],$o=d3.scale.linear(),Jo=Eu(Bo);Zo.year=function(t,n){return $o.domain(t.map(Nu)).ticks(n).map(Au)},d3.time.scale=function(){return wu(d3.scale.linear(),Zo,Jo)};var Go=Zo.map(function(t){return[t[0].utc,t[1]]}),Ko=[[d3.time.format.utc("%Y"),o],[d3.time.format.utc("%B"),function(t){return t.getUTCMonth()}],[d3.time.format.utc("%b %d"),function(t){return 1!=t.getUTCDate()}],[d3.time.format.utc("%a %d"),function(t){return t.getUTCDay()&&1!=t.getUTCDate()}],[d3.time.format.utc("%I %p"),function(t){return t.getUTCHours()}],[d3.time.format.utc("%I:%M"),function(t){return t.getUTCMinutes()}],[d3.time.format.utc(":%S"),function(t){return t.getUTCSeconds()}],[d3.time.format.utc(".%L"),function(t){return t.getUTCMilliseconds()}]],Wo=Eu(Ko);Go.year=function(t,n){return $o.domain(t.map(qu)).ticks(n).map(Tu)},d3.time.scale.utc=function(){return wu(d3.scale.linear(),Go,Wo)}})(); \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/css/font-awesome.min.css b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/css/font-awesome.min.css new file mode 100644 index 0000000..540440c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.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} diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/FontAwesome.otf b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/FontAwesome.otf new file mode 100644 index 0000000..401ec0f Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/FontAwesome.otf differ diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.eot b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.eot differ diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.svg b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ +<?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> +<metadata> +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. +</metadata> +<defs> +<font id="FontAwesome" horiz-adv-x="1536" > + <font-face + font-family="FontAwesome" + font-weight="400" + font-stretch="normal" + units-per-em="1792" + panose-1="0 0 0 0 0 0 0 0 0 0" + ascent="1536" + descent="-256" + bbox="-1.02083 -256.962 2304.6 1537.02" + underline-thickness="0" + underline-position="0" + unicode-range="U+0020-F500" + /> +<missing-glyph horiz-adv-x="896" +d="M224 112h448v1312h-448v-1312zM112 0v1536h672v-1536h-672z" /> + <glyph glyph-name=".notdef" horiz-adv-x="896" +d="M224 112h448v1312h-448v-1312zM112 0v1536h672v-1536h-672z" /> + <glyph glyph-name=".null" horiz-adv-x="0" + /> + <glyph glyph-name="nonmarkingreturn" horiz-adv-x="597" + /> + <glyph glyph-name="space" unicode=" " horiz-adv-x="448" + /> + <glyph glyph-name="dieresis" unicode="&#xa8;" horiz-adv-x="1792" + /> + <glyph glyph-name="copyright" unicode="&#xa9;" horiz-adv-x="1792" + /> + <glyph glyph-name="registered" unicode="&#xae;" horiz-adv-x="1792" + /> + <glyph glyph-name="acute" unicode="&#xb4;" horiz-adv-x="1792" + /> + <glyph glyph-name="AE" unicode="&#xc6;" horiz-adv-x="1792" + /> + <glyph glyph-name="Oslash" unicode="&#xd8;" horiz-adv-x="1792" + /> + <glyph glyph-name="trademark" unicode="&#x2122;" horiz-adv-x="1792" + /> + <glyph glyph-name="infinity" unicode="&#x221e;" horiz-adv-x="1792" + /> + <glyph glyph-name="notequal" unicode="&#x2260;" horiz-adv-x="1792" + /> + <glyph glyph-name="glass" unicode="&#xf000;" horiz-adv-x="1792" +d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" /> + <glyph glyph-name="music" unicode="&#xf001;" +d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89 +t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" /> + <glyph glyph-name="search" unicode="&#xf002;" horiz-adv-x="1664" +d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5 +t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" /> + <glyph glyph-name="envelope" unicode="&#xf003;" horiz-adv-x="1792" +d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13 +t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z +M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> + <glyph glyph-name="heart" unicode="&#xf004;" horiz-adv-x="1792" +d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600 +q-18 -18 -44 -18z" /> + <glyph glyph-name="star" unicode="&#xf005;" horiz-adv-x="1664" +d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455 +l502 -73q56 -9 56 -46z" /> + <glyph glyph-name="star_empty" unicode="&#xf006;" horiz-adv-x="1664" +d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 +l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" /> + <glyph glyph-name="user" unicode="&#xf007;" horiz-adv-x="1280" +d="M1280 137q0 -109 -62.5 -187t-150.5 -78h-854q-88 0 -150.5 78t-62.5 187q0 85 8.5 160.5t31.5 152t58.5 131t94 89t134.5 34.5q131 -128 313 -128t313 128q76 0 134.5 -34.5t94 -89t58.5 -131t31.5 -152t8.5 -160.5zM1024 1024q0 -159 -112.5 -271.5t-271.5 -112.5 +t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" /> + <glyph glyph-name="film" unicode="&#xf008;" horiz-adv-x="1920" +d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128 +q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45 +t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128 +q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19 +t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> + <glyph glyph-name="th_large" unicode="&#xf009;" horiz-adv-x="1664" +d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38 +h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" /> + <glyph glyph-name="th" unicode="&#xf00a;" horiz-adv-x="1792" +d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320 +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 +h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192 +q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68z" /> + <glyph glyph-name="th_list" unicode="&#xf00b;" horiz-adv-x="1792" +d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960 +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 +h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" /> + <glyph glyph-name="ok" unicode="&#xf00c;" horiz-adv-x="1792" +d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" /> + <glyph glyph-name="remove" unicode="&#xf00d;" horiz-adv-x="1408" +d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68 +t-28 -68l-294 -294l294 -294q28 -28 28 -68z" /> + <glyph glyph-name="zoom_in" unicode="&#xf00e;" horiz-adv-x="1664" +d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224 +q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5 +t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" /> + <glyph glyph-name="zoom_out" unicode="&#xf010;" horiz-adv-x="1664" +d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z +M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z +" /> + <glyph glyph-name="off" unicode="&#xf011;" +d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5 +t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" /> + <glyph glyph-name="signal" unicode="&#xf012;" horiz-adv-x="1792" +d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 +v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" /> + <glyph glyph-name="cog" unicode="&#xf013;" +d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38 +q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13 +l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22 +q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" /> + <glyph glyph-name="trash" unicode="&#xf014;" horiz-adv-x="1408" +d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576 +q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832 +q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" /> + <glyph glyph-name="home" unicode="&#xf015;" horiz-adv-x="1664" +d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5 +l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" /> + <glyph glyph-name="file_alt" unicode="&#xf016;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +" /> + <glyph glyph-name="time" unicode="&#xf017;" +d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="road" unicode="&#xf018;" horiz-adv-x="1920" +d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256 +q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" /> + <glyph glyph-name="download_alt" unicode="&#xf019;" horiz-adv-x="1664" +d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136 +q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" /> + <glyph glyph-name="download" unicode="&#xf01a;" +d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273 +t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="upload" unicode="&#xf01b;" +d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198 +t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="inbox" unicode="&#xf01c;" +d="M1023 576h316q-1 3 -2.5 8.5t-2.5 7.5l-212 496h-708l-212 -496q-1 -3 -2.5 -8.5t-2.5 -7.5h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552 +q25 -61 25 -123z" /> + <glyph glyph-name="play_circle" unicode="&#xf01d;" +d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="repeat" unicode="&#xf01e;" +d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q15 0 25 -9 +l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" /> + <glyph glyph-name="refresh" unicode="&#xf021;" +d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117 +q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5 +q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" /> + <glyph glyph-name="list_alt" unicode="&#xf022;" horiz-adv-x="1792" +d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z +M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5 +t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47 +t47 -113z" /> + <glyph glyph-name="lock" unicode="&#xf023;" horiz-adv-x="1152" +d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" /> + <glyph glyph-name="flag" unicode="&#xf024;" horiz-adv-x="1792" +d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48 +t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" /> + <glyph glyph-name="headphones" unicode="&#xf025;" horiz-adv-x="1664" +d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78 +t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5 +t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" /> + <glyph glyph-name="volume_off" unicode="&#xf026;" horiz-adv-x="768" +d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" /> + <glyph glyph-name="volume_down" unicode="&#xf027;" horiz-adv-x="1152" +d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 36 +t12 56.5t-12 56.5t-29 36t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" /> + <glyph glyph-name="volume_up" unicode="&#xf028;" horiz-adv-x="1664" +d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 36 +t12 56.5t-12 56.5t-29 36t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5 +t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289 +t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" /> + <glyph glyph-name="qrcode" unicode="&#xf029;" horiz-adv-x="1408" +d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z +M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" /> + <glyph glyph-name="barcode" unicode="&#xf02a;" horiz-adv-x="1792" +d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z +M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" /> + <glyph glyph-name="tag" unicode="&#xf02b;" +d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 +l715 -714q37 -39 37 -91z" /> + <glyph glyph-name="tags" unicode="&#xf02c;" horiz-adv-x="1920" +d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 +l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" /> + <glyph glyph-name="book" unicode="&#xf02d;" horiz-adv-x="1664" +d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23 +q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906 +q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5 +t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" /> + <glyph glyph-name="bookmark" unicode="&#xf02e;" horiz-adv-x="1280" +d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" /> + <glyph glyph-name="print" unicode="&#xf02f;" horiz-adv-x="1664" +d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68 +v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" /> + <glyph glyph-name="camera" unicode="&#xf030;" horiz-adv-x="1920" +d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136 +q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="font" unicode="&#xf031;" horiz-adv-x="1664" +d="M725 977l-170 -450q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452zM0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57 +q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -5 -0.5 -13.5t-0.5 -12.5q-63 0 -190 8t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5 +q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14z" /> + <glyph glyph-name="bold" unicode="&#xf032;" horiz-adv-x="1408" +d="M555 15q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5t4.5 -83.5t12 -66.5zM541 761q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142 +q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13q0 -50 4 -151t4 -152q0 -27 -0.5 -80t-0.5 -79q0 -46 1 -69zM0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5 +t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68 -0.5t68 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5 +t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12z" /> + <glyph glyph-name="italic" unicode="&#xf033;" horiz-adv-x="1024" +d="M0 -126l17 85q22 7 61.5 16.5t72 19t59.5 23.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5 +q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" /> + <glyph glyph-name="text_height" unicode="&#xf034;" horiz-adv-x="1792" +d="M1744 128q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80zM81 1407l54 -27q12 -5 211 -5q44 0 132 2 +t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5 +q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 +q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44v383z" /> + <glyph glyph-name="text_width" unicode="&#xf035;" +d="M81 1407l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1t-103 1 +t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 +q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44v383zM1310 125q12 0 42 -19.5t57.5 -41.5 +t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41.5t-59.5 49t-36 30q-26 21 -26 49 +t26 49q4 3 36 30t59.5 49t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5z" /> + <glyph glyph-name="align_left" unicode="&#xf036;" horiz-adv-x="1792" +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45 +t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> + <glyph glyph-name="align_center" unicode="&#xf037;" horiz-adv-x="1792" +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19 +h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" /> + <glyph glyph-name="align_right" unicode="&#xf038;" horiz-adv-x="1792" +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 +t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> + <glyph glyph-name="align_justify" unicode="&#xf039;" horiz-adv-x="1792" +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 +t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" /> + <glyph glyph-name="list" unicode="&#xf03a;" horiz-adv-x="1792" +d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5 +t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344 +q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 +t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192 +q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" /> + <glyph glyph-name="indent_left" unicode="&#xf03b;" horiz-adv-x="1792" +d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 +t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 +q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" /> + <glyph glyph-name="indent_right" unicode="&#xf03c;" horiz-adv-x="1792" +d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 +t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 +q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" /> + <glyph glyph-name="facetime_video" unicode="&#xf03d;" horiz-adv-x="1792" +d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5 +q39 -17 39 -59z" /> + <glyph glyph-name="picture" unicode="&#xf03e;" horiz-adv-x="1920" +d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216 +q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> + <glyph glyph-name="pencil" unicode="&#xf040;" +d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38 +q53 0 91 -38l235 -234q37 -39 37 -91z" /> + <glyph glyph-name="map_marker" unicode="&#xf041;" horiz-adv-x="1024" +d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" /> + <glyph glyph-name="adjust" unicode="&#xf042;" +d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="tint" unicode="&#xf043;" horiz-adv-x="1024" +d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362 +q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" /> + <glyph glyph-name="edit" unicode="&#xf044;" horiz-adv-x="1792" +d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 +q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92 +l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" /> + <glyph glyph-name="share" unicode="&#xf045;" horiz-adv-x="1664" +d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832 +q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5 +t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" /> + <glyph glyph-name="check" unicode="&#xf046;" horiz-adv-x="1664" +d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832 +q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110 +q24 -24 24 -57t-24 -57z" /> + <glyph glyph-name="move" unicode="&#xf047;" horiz-adv-x="1792" +d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45 +t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" /> + <glyph glyph-name="step_backward" unicode="&#xf048;" horiz-adv-x="1024" +d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 10 13 19z" /> + <glyph glyph-name="fast_backward" unicode="&#xf049;" horiz-adv-x="1792" +d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 10 13 19l710 710 +q19 19 32 13t13 -32v-710q4 10 13 19z" /> + <glyph glyph-name="backward" unicode="&#xf04a;" horiz-adv-x="1664" +d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q4 10 13 19z" /> + <glyph glyph-name="play" unicode="&#xf04b;" horiz-adv-x="1408" +d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" /> + <glyph glyph-name="pause" unicode="&#xf04c;" +d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" /> + <glyph glyph-name="stop" unicode="&#xf04d;" +d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> + <glyph glyph-name="forward" unicode="&#xf04e;" horiz-adv-x="1664" +d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-4 -10 -13 -19z" /> + <glyph glyph-name="fast_forward" unicode="&#xf050;" horiz-adv-x="1792" +d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v710q0 26 13 32t32 -13l710 -710q9 -9 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-4 -10 -13 -19l-710 -710 +q-19 -19 -32 -13t-13 32v710q-4 -10 -13 -19z" /> + <glyph glyph-name="step_forward" unicode="&#xf051;" horiz-adv-x="1024" +d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-4 -10 -13 -19z" /> + <glyph glyph-name="eject" unicode="&#xf052;" horiz-adv-x="1538" +d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" /> + <glyph glyph-name="chevron_left" unicode="&#xf053;" horiz-adv-x="1280" +d="M1171 1235l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45t19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45z" /> + <glyph glyph-name="chevron_right" unicode="&#xf054;" horiz-adv-x="1280" +d="M1107 659l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45t19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45z" /> + <glyph glyph-name="plus_sign" unicode="&#xf055;" +d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5 +t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="minus_sign" unicode="&#xf056;" +d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 +t103 -385.5z" /> + <glyph glyph-name="remove_sign" unicode="&#xf057;" +d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19 +q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="ok_sign" unicode="&#xf058;" +d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="question_sign" unicode="&#xf059;" +d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59 +q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="info_sign" unicode="&#xf05a;" +d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23 +t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="screenshot" unicode="&#xf05b;" +d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109 +q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143 +q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" /> + <glyph glyph-name="remove_circle" unicode="&#xf05c;" +d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23 +l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5 +t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="ok_circle" unicode="&#xf05d;" +d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198 +t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="ban_circle" unicode="&#xf05e;" +d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61 +t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" /> + <glyph glyph-name="arrow_left" unicode="&#xf060;" +d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5 +t32.5 -90.5z" /> + <glyph glyph-name="arrow_right" unicode="&#xf061;" +d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" /> + <glyph glyph-name="arrow_up" unicode="&#xf062;" horiz-adv-x="1664" +d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651 +q37 -39 37 -91z" /> + <glyph glyph-name="arrow_down" unicode="&#xf063;" horiz-adv-x="1664" +d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" /> + <glyph glyph-name="share_alt" unicode="&#xf064;" horiz-adv-x="1792" +d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22 +t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" /> + <glyph glyph-name="resize_full" unicode="&#xf065;" +d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332 +q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" /> + <glyph glyph-name="resize_small" unicode="&#xf066;" +d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45 +t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" /> + <glyph glyph-name="plus" unicode="&#xf067;" horiz-adv-x="1408" +d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" /> + <glyph glyph-name="minus" unicode="&#xf068;" horiz-adv-x="1408" +d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" /> + <glyph glyph-name="asterisk" unicode="&#xf069;" horiz-adv-x="1664" +d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154 +q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" /> + <glyph glyph-name="exclamation_sign" unicode="&#xf06a;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192 +q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" /> + <glyph glyph-name="gift" unicode="&#xf06b;" +d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320 +q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5 +t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" /> + <glyph glyph-name="leaf" unicode="&#xf06c;" horiz-adv-x="1792" +d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268 +q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-43 0 -63.5 17.5t-45.5 59.5q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5 +t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" /> + <glyph glyph-name="fire" unicode="&#xf06d;" horiz-adv-x="1408" +d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1 +q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" /> + <glyph glyph-name="eye_open" unicode="&#xf06e;" horiz-adv-x="1792" +d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5 +t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" /> + <glyph glyph-name="eye_close" unicode="&#xf070;" horiz-adv-x="1792" +d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9 +q-106 -189 -316 -567t-315 -566l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5 +q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z +" /> + <glyph glyph-name="warning_sign" unicode="&#xf071;" horiz-adv-x="1792" +d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185 +q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" /> + <glyph glyph-name="plane" unicode="&#xf072;" horiz-adv-x="1408" +d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9 +q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" /> + <glyph glyph-name="calendar" unicode="&#xf073;" horiz-adv-x="1664" +d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z +M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64 +q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47 +h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> + <glyph glyph-name="random" unicode="&#xf074;" horiz-adv-x="1792" +d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1 +t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5 +v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111 +t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" /> + <glyph glyph-name="comment" unicode="&#xf075;" horiz-adv-x="1792" +d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281 +q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" /> + <glyph glyph-name="magnet" unicode="&#xf076;" +d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384 +q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" /> + <glyph glyph-name="chevron_up" unicode="&#xf077;" horiz-adv-x="1792" +d="M1683 205l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5t19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5z" /> + <glyph glyph-name="chevron_down" unicode="&#xf078;" horiz-adv-x="1792" +d="M1683 728l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5t19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5z" /> + <glyph glyph-name="retweet" unicode="&#xf079;" horiz-adv-x="1920" +d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -10 7 -21 +zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z +" /> + <glyph glyph-name="shopping_cart" unicode="&#xf07a;" horiz-adv-x="1664" +d="M640 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1536 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1664 1088v-512q0 -24 -16.5 -42.5t-40.5 -21.5l-1044 -122q13 -60 13 -70q0 -16 -24 -64h920q26 0 45 -19t19 -45 +t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 11 8 31.5t16 36t21.5 40t15.5 29.5l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t19.5 -15.5t13 -24.5t8 -26t5.5 -29.5t4.5 -26h1201q26 0 45 -19t19 -45z" /> + <glyph glyph-name="folder_close" unicode="&#xf07b;" horiz-adv-x="1664" +d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" /> + <glyph glyph-name="folder_open" unicode="&#xf07c;" horiz-adv-x="1920" +d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 +t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" /> + <glyph glyph-name="resize_vertical" unicode="&#xf07d;" horiz-adv-x="768" +d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" /> + <glyph glyph-name="resize_horizontal" unicode="&#xf07e;" horiz-adv-x="1792" +d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" /> + <glyph glyph-name="bar_chart" unicode="&#xf080;" horiz-adv-x="2048" +d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" /> + <glyph glyph-name="twitter_sign" unicode="&#xf081;" +d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4 +q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5 +t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="facebook_sign" unicode="&#xf082;" +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-188v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-532q-119 0 -203.5 84.5t-84.5 203.5v960 +q0 119 84.5 203.5t203.5 84.5h960z" /> + <glyph glyph-name="camera_retro" unicode="&#xf083;" horiz-adv-x="1792" +d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5 +t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280 +q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" /> + <glyph glyph-name="key" unicode="&#xf084;" horiz-adv-x="1792" +d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26 +l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5 +t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" /> + <glyph glyph-name="cogs" unicode="&#xf085;" horiz-adv-x="1920" +d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 +t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -11 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 +l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7 +l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -8 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 +q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 +t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 +q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70 +q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" /> + <glyph glyph-name="comments" unicode="&#xf086;" horiz-adv-x="1792" +d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224 +q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7 +q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" /> + <glyph glyph-name="thumbs_up_alt" unicode="&#xf087;" +d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5 +t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769 +q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128 +q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" /> + <glyph glyph-name="thumbs_down_alt" unicode="&#xf088;" +d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 31 18 69q0 37 -17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5 +t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z +M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5 +h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -73 49 -163z" /> + <glyph glyph-name="star_half" unicode="&#xf089;" horiz-adv-x="896" +d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" /> + <glyph glyph-name="heart_empty" unicode="&#xf08a;" horiz-adv-x="1792" +d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559 +q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5 +q224 0 351 -124t127 -344z" /> + <glyph glyph-name="signout" unicode="&#xf08b;" horiz-adv-x="1664" +d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704 +q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" /> + <glyph glyph-name="linkedin_sign" unicode="&#xf08c;" +d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5 +q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="pushpin" unicode="&#xf08d;" horiz-adv-x="1152" +d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38 +t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" /> + <glyph glyph-name="external_link" unicode="&#xf08e;" horiz-adv-x="1792" +d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320 +q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" /> + <glyph glyph-name="signin" unicode="&#xf090;" +d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5 +q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="trophy" unicode="&#xf091;" horiz-adv-x="1664" +d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91 +t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96 +q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" /> + <glyph glyph-name="github_sign" unicode="&#xf092;" +d="M519 336q4 6 -3 13q-9 7 -14 2q-4 -6 3 -13q9 -7 14 -2zM491 377q-5 7 -12 4q-6 -4 0 -12q7 -8 12 -5q6 4 0 13zM450 417q2 4 -5 8q-7 2 -8 -2q-3 -5 4 -8q8 -2 9 2zM471 394q2 1 1.5 4.5t-3.5 5.5q-6 7 -10 3t1 -11q6 -6 11 -2zM557 319q2 7 -9 11q-9 3 -13 -4 +q-2 -7 9 -11q9 -3 13 4zM599 316q0 8 -12 8q-10 0 -10 -8t11 -8t11 8zM638 323q-2 7 -13 5t-9 -9q2 -8 12 -6t10 10zM1280 640q0 212 -150 362t-362 150t-362 -150t-150 -362q0 -167 98 -300.5t252 -185.5q18 -3 26.5 5t8.5 20q0 52 -1 95q-6 -1 -15.5 -2.5t-35.5 -2t-48 4 +t-43.5 20t-29.5 41.5q-23 59 -57 74q-2 1 -4.5 3.5l-8 8t-7 9.5t4 7.5t19.5 3.5q6 0 15 -2t30 -15.5t33 -35.5q16 -28 37.5 -42t43.5 -14t38 3.5t30 9.5q7 47 33 69q-49 6 -86 18.5t-73 39t-55.5 76t-19.5 119.5q0 79 53 137q-24 62 5 136q19 6 54.5 -7.5t60.5 -29.5l26 -16 +q58 17 128 17t128 -17q11 7 28.5 18t55.5 26t57 9q29 -74 5 -136q53 -58 53 -137q0 -57 -14 -100.5t-35.5 -70t-53.5 -44.5t-62.5 -26t-68.5 -12q35 -31 35 -95q0 -40 -0.5 -89t-0.5 -51q0 -12 8.5 -20t26.5 -5q154 52 252 185.5t98 300.5zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="upload_alt" unicode="&#xf093;" horiz-adv-x="1664" +d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92 +t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" /> + <glyph glyph-name="lemon" unicode="&#xf094;" +d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5 +q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44 +q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5 +q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -13 2 -25t3.5 -16.5t7.5 -20.5t8 -20q16 -40 25 -118.5t9 -136.5z" /> + <glyph glyph-name="phone" unicode="&#xf095;" horiz-adv-x="1408" +d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -53 3.5t-57.5 12.5t-47 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-127 79 -264 216t-216 264q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47t-12.5 57.5t-3.5 53q0 92 51 186 +q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174q2 -1 19 -11.5t24 -14 +t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" /> + <glyph glyph-name="check_empty" unicode="&#xf096;" horiz-adv-x="1408" +d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 +q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="bookmark_empty" unicode="&#xf097;" horiz-adv-x="1280" +d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289 +q0 34 19.5 62t52.5 41q21 9 44 9h1048z" /> + <glyph glyph-name="phone_sign" unicode="&#xf098;" +d="M1280 343q0 11 -2 16t-18 16.5t-40.5 25t-47.5 26.5t-45.5 25t-28.5 15q-5 3 -19 13t-25 15t-21 5q-15 0 -36.5 -20.5t-39.5 -45t-38.5 -45t-33.5 -20.5q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170 126.5t-127 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5 +t-3.5 16.5q0 13 20.5 33.5t45 38.5t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5 +t320.5 -216.5q6 -2 30 -11t33 -12.5t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z +" /> + <glyph glyph-name="twitter" unicode="&#xf099;" horiz-adv-x="1664" +d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41 +q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" /> + <glyph glyph-name="facebook" unicode="&#xf09a;" horiz-adv-x="1024" +d="M959 1524v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12z" /> + <glyph glyph-name="github" unicode="&#xf09b;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -40 7t-13 30q0 3 0.5 76.5t0.5 134.5q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 119 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24 +q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-85 13.5q-45 -113 -8 -204q-79 -87 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-39 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5 +t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -88.5t0.5 -54.5q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103zM291 305q3 7 -7 12 +q-10 3 -13 -2q-3 -7 7 -12q9 -6 13 2zM322 271q7 5 -2 16q-10 9 -16 3q-7 -5 2 -16q10 -10 16 -3zM352 226q9 7 0 19q-8 13 -17 6q-9 -5 0 -18t17 -7zM394 184q8 8 -4 19q-12 12 -20 3q-9 -8 4 -19q12 -12 20 -3zM451 159q3 11 -13 16q-15 4 -19 -7t13 -15q15 -6 19 6z +M514 154q0 13 -17 11q-16 0 -16 -11q0 -13 17 -11q16 0 16 11zM572 164q-2 11 -18 9q-16 -3 -14 -15t18 -8t14 14z" /> + <glyph glyph-name="unlock" unicode="&#xf09c;" horiz-adv-x="1664" +d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5 +t316.5 -131.5t131.5 -316.5z" /> + <glyph glyph-name="credit_card" unicode="&#xf09d;" horiz-adv-x="1920" +d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608 +q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" /> + <glyph glyph-name="rss" unicode="&#xf09e;" horiz-adv-x="1408" +d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5 +t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294 +q187 -186 294 -425.5t120 -501.5z" /> + <glyph glyph-name="hdd" unicode="&#xf0a0;" +d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5 +h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75 +l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" /> + <glyph glyph-name="bullhorn" unicode="&#xf0a1;" horiz-adv-x="1792" +d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5 +t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" /> + <glyph glyph-name="bell" unicode="&#xf0a2;" horiz-adv-x="1792" +d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM246 128h1300q-266 300 -266 832q0 51 -24 105t-69 103t-121.5 80.5t-169.5 31.5t-169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -532 -266 -832z +M1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5 +t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" /> + <glyph glyph-name="certificate" unicode="&#xf0a3;" +d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70 +l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70 +l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" /> + <glyph glyph-name="hand_right" unicode="&#xf0a4;" horiz-adv-x="1792" +d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106 +q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43 +q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5 +t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" /> + <glyph glyph-name="hand_left" unicode="&#xf0a5;" horiz-adv-x="1792" +d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-8 9 -12 14q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576q-50 0 -89 -38.5 +t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45z +M1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128q0 122 81.5 189t206.5 67 +q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" /> + <glyph glyph-name="hand_up" unicode="&#xf0a6;" +d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576 +q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5 +t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76 +q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" /> + <glyph glyph-name="hand_down" unicode="&#xf0a7;" +d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33 +t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580 +q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100 +q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" /> + <glyph glyph-name="circle_arrow_left" unicode="&#xf0a8;" +d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="circle_arrow_right" unicode="&#xf0a9;" +d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="circle_arrow_up" unicode="&#xf0aa;" +d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="circle_arrow_down" unicode="&#xf0ab;" +d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="globe" unicode="&#xf0ac;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11 +q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 11t-9.5 10q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5 +q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5 +q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5 +t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-4 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3 +q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25 +q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5 +t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5 +t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10.5t17 -19.5q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21 +q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5 +q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3 +q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5 +t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q8 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5 +q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7 +q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5q0 -6 2 -16z" /> + <glyph glyph-name="wrench" unicode="&#xf0ad;" horiz-adv-x="1664" +d="M384 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1028 484l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5zM1662 919q0 -39 -23 -106q-47 -134 -164.5 -217.5 +t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q58 0 121.5 -16.5t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25z" /> + <glyph glyph-name="tasks" unicode="&#xf0ae;" horiz-adv-x="1792" +d="M1024 128h640v128h-640v-128zM640 640h1024v128h-1024v-128zM1280 1152h384v128h-384v-128zM1792 320v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 832v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19 +t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" /> + <glyph glyph-name="filter" unicode="&#xf0b0;" horiz-adv-x="1408" +d="M1403 1241q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70q17 39 59 39h1280q42 0 59 -39z" /> + <glyph glyph-name="briefcase" unicode="&#xf0b1;" horiz-adv-x="1792" +d="M640 1280h512v128h-512v-128zM1792 640v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672zM1024 640v-128h-256v128h256zM1792 1120v-384h-1792v384q0 66 47 113t113 47h352v160q0 40 28 68 +t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113z" /> + <glyph glyph-name="fullscreen" unicode="&#xf0b2;" +d="M1283 995l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l144 -144 +l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19z +" /> + <glyph glyph-name="group" unicode="&#xf0c0;" horiz-adv-x="1920" +d="M593 640q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256zM1664 3q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5 +t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM640 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75 +t75 -181zM1344 896q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5zM1920 671q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128q81 117 81 256q0 29 -5 66q66 -23 133 -23q59 0 119 21.5t97.5 42.5 +t43.5 21q124 0 124 -353zM1792 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181z" /> + <glyph glyph-name="link" unicode="&#xf0c1;" horiz-adv-x="1664" +d="M1456 320q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26 +l147 146q28 28 28 67zM753 1025q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15 +t21.5 -21.5t18.5 -19q33 31 33 73zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204t85 203l147 146q83 83 203 83q121 0 204 -85l206 -207 +q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204z" /> + <glyph glyph-name="cloud" unicode="&#xf0c2;" horiz-adv-x="1920" +d="M1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5z +" /> + <glyph glyph-name="beaker" unicode="&#xf0c3;" horiz-adv-x="1664" +d="M1527 88q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5t21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399zM748 813l-272 -429h712l-272 429l-20 31v37v399h-128v-399v-37z" /> + <glyph glyph-name="cut" unicode="&#xf0c4;" horiz-adv-x="1792" +d="M960 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1260 576l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84 +q-136 0 -222 78q-90 84 -79 207q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148 +q4 -48 -10 -97q4 -1 12 -5l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56zM579 836q46 42 21 108t-106 117q-92 59 -192 59q-74 0 -113 -36q-46 -42 -21 -108t106 -117q92 -59 192 -59q74 0 113 36zM494 91q81 51 106 117t-21 108 +q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117t21 -108q39 -36 113 -36q100 0 192 59zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 480l96 -32l736 576l-128 64l-768 -431v-113l-160 -96l9 -8q2 -2 7 -6 +q4 -4 11 -12t11 -12l26 -26zM1600 64l128 64l-520 408l-177 -138q-2 -3 -13 -7z" /> + <glyph glyph-name="copy" unicode="&#xf0c5;" horiz-adv-x="1792" +d="M1696 1152q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323l-299 -299 +h299v299zM708 676l316 316v416h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h512v256q0 40 20 88t48 76zM1664 -128v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h896z" /> + <glyph glyph-name="paper_clip" unicode="&#xf0c6;" horiz-adv-x="1408" +d="M1404 151q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776q-113 115 -113 271q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181 +l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235 +z" /> + <glyph glyph-name="save" unicode="&#xf0c7;" +d="M384 0h768v384h-768v-384zM1280 0h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416zM896 928v320q0 13 -9.5 22.5t-22.5 9.5 +h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5zM1536 896v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88z" /> + <glyph glyph-name="sign_blank" unicode="&#xf0c8;" +d="M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="reorder" unicode="&#xf0c9;" +d="M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45 +t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> + <glyph glyph-name="ul" unicode="&#xf0ca;" horiz-adv-x="1792" +d="M384 128q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 640q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 +t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1152q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z +M1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" /> + <glyph glyph-name="ol" unicode="&#xf0cb;" horiz-adv-x="1792" +d="M381 -84q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88zM383 543v-159h-362 +q-6 36 -6 54q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105zM1792 224v-192q0 -13 -9.5 -22.5 +t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1123v-99h-335v99h107q0 41 0.5 121.5t0.5 121.5v12h-2q-8 -17 -50 -54l-71 76l136 127h106v-404h108zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216 +q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" /> + <glyph glyph-name="strikethrough" unicode="&#xf0cc;" horiz-adv-x="1792" +d="M1760 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h1728zM483 704q-28 35 -51 80q-48 98 -48 188q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6 +l-14 2q-50 149 -103 205q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743zM990 448h411q7 -39 7 -92q0 -111 -41 -212q-23 -56 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23 +l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71z" /> + <glyph glyph-name="underline" unicode="&#xf0cd;" +d="M48 1313q-37 2 -45 4l-3 88q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47 +q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41 +q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39zM1536 -96v64q0 14 -9 23t-23 9h-1472 +q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23z" /> + <glyph glyph-name="table" unicode="&#xf0ce;" horiz-adv-x="1664" +d="M512 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23 +v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 160v192 +q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192 +q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1664 1248v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113 +z" /> + <glyph glyph-name="magic" unicode="&#xf0d0;" horiz-adv-x="1664" +d="M1190 955l293 293l-107 107l-293 -293zM1637 1248q0 -27 -18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45t18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45zM286 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM636 1276 +l196 -60l-196 -60l-60 -196l-60 196l-196 60l196 60l60 196zM1566 798l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM926 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98z" /> + <glyph glyph-name="truck" unicode="&#xf0d1;" horiz-adv-x="1792" +d="M640 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM1536 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1792 1216v-1024q0 -15 -4 -26.5t-13.5 -18.5 +t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5q0 26 19 45t45 19v320q0 8 -0.5 35t0 38 +t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45z" /> + <glyph glyph-name="pinterest" unicode="&#xf0d2;" +d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134 +q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33 +q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="pinterest_sign" unicode="&#xf0d3;" +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5q-104 0 -194.5 -28.5t-153 -76.5 +t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5 +t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960z" /> + <glyph glyph-name="google_plus_sign" unicode="&#xf0d4;" +d="M917 631q0 26 -6 64h-362v-132h217q-3 -24 -16.5 -50t-37.5 -53t-66.5 -44.5t-96.5 -17.5q-99 0 -169 71t-70 171t70 171t169 71q92 0 153 -59l104 101q-108 100 -257 100q-160 0 -272 -112.5t-112 -271.5t112 -271.5t272 -112.5q165 0 266.5 105t101.5 270zM1262 585 +h109v110h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="google_plus" unicode="&#xf0d5;" horiz-adv-x="2304" +d="M1437 623q0 -208 -87 -370.5t-248 -254t-369 -91.5q-149 0 -285 58t-234 156t-156 234t-58 285t58 285t156 234t234 156t285 58q286 0 491 -192l-199 -191q-117 113 -292 113q-123 0 -227.5 -62t-165.5 -168.5t-61 -232.5t61 -232.5t165.5 -168.5t227.5 -62 +q83 0 152.5 23t114.5 57.5t78.5 78.5t49 83t21.5 74h-416v252h692q12 -63 12 -122zM2304 745v-210h-209v-209h-210v209h-209v210h209v209h210v-209h209z" /> + <glyph glyph-name="money" unicode="&#xf0d6;" horiz-adv-x="1920" +d="M768 384h384v96h-128v448h-114l-148 -137l77 -80q42 37 55 57h2v-288h-128v-96zM1280 640q0 -70 -21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142t21 142t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142zM1792 384 +v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512q106 0 181 -75t75 -181h1152q0 106 75 181t181 75zM1920 1216v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45z" /> + <glyph glyph-name="caret_down" unicode="&#xf0d7;" horiz-adv-x="1024" +d="M1024 832q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" /> + <glyph glyph-name="caret_up" unicode="&#xf0d8;" horiz-adv-x="1024" +d="M1024 320q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> + <glyph glyph-name="caret_left" unicode="&#xf0d9;" horiz-adv-x="640" +d="M640 1088v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45t19 45l448 448q19 19 45 19t45 -19t19 -45z" /> + <glyph glyph-name="caret_right" unicode="&#xf0da;" horiz-adv-x="640" +d="M576 640q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45z" /> + <glyph glyph-name="columns" unicode="&#xf0db;" horiz-adv-x="1664" +d="M160 0h608v1152h-640v-1120q0 -13 9.5 -22.5t22.5 -9.5zM1536 32v1120h-640v-1152h608q13 0 22.5 9.5t9.5 22.5zM1664 1248v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113z" /> + <glyph glyph-name="sort" unicode="&#xf0dc;" horiz-adv-x="1024" +d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45zM1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> + <glyph glyph-name="sort_down" unicode="&#xf0dd;" horiz-adv-x="1024" +d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" /> + <glyph glyph-name="sort_up" unicode="&#xf0de;" horiz-adv-x="1024" +d="M1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> + <glyph glyph-name="envelope_alt" unicode="&#xf0e0;" horiz-adv-x="1792" +d="M1792 826v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87zM1792 1120q0 -79 -49 -151t-122 -123 +q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5q0 78 41.5 130t118.5 52h1472q65 0 112.5 -47t47.5 -113z" /> + <glyph glyph-name="linkedin" unicode="&#xf0e1;" +d="M349 911v-991h-330v991h330zM370 1217q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5zM1536 488v-568h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329 +q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5z" /> + <glyph glyph-name="undo" unicode="&#xf0e2;" +d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5 +t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298z" /> + <glyph glyph-name="legal" unicode="&#xf0e3;" horiz-adv-x="1792" +d="M1771 0q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5 +t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14 +q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28 +q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91z" /> + <glyph glyph-name="dashboard" unicode="&#xf0e4;" horiz-adv-x="1792" +d="M384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM576 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1004 351l101 382q6 26 -7.5 48.5t-38.5 29.5 +t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5t-63 -98.5q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91zM1664 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 1024q0 53 -37.5 90.5 +t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1472 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 384q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29 +q-141 221 -141 483q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="comment_alt" unicode="&#xf0e5;" horiz-adv-x="1792" +d="M896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640 +q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 174 120 321.5 +t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" /> + <glyph glyph-name="comments_alt" unicode="&#xf0e6;" horiz-adv-x="1792" +d="M704 1152q-153 0 -286 -52t-211.5 -141t-78.5 -191q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52zM704 1280q191 0 353.5 -68.5t256.5 -186.5t94 -257t-94 -257 +t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224q0 139 94 257t256.5 186.5 +t353.5 68.5zM1526 111q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129 +q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5z" /> + <glyph glyph-name="bolt" unicode="&#xf0e7;" horiz-adv-x="896" +d="M885 970q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15z" /> + <glyph glyph-name="sitemap" unicode="&#xf0e8;" horiz-adv-x="1792" +d="M1792 288v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320 +q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68 +z" /> + <glyph glyph-name="umbrella" unicode="&#xf0e9;" horiz-adv-x="1664" +d="M896 708v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11zM1664 681q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97 +q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69 +q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7zM896 1408v-98q-42 2 -64 2t-64 -2v98q0 26 19 45t45 19t45 -19t19 -45z" /> + <glyph glyph-name="paste" unicode="&#xf0ea;" horiz-adv-x="1792" +d="M768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1024 1312v64q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5zM1280 640h299l-299 299v-299zM1792 512v-672q0 -40 -28 -68t-68 -28 +h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88z" /> + <glyph glyph-name="light_bulb" unicode="&#xf0eb;" horiz-adv-x="1024" +d="M736 960q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5t9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90zM896 960q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134 +q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180zM1024 960q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47 +q0 -46 -31.5 -71t-77.5 -25q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268q0 99 44.5 184.5t117 142t164 89t186.5 32.5 +t186.5 -32.5t164 -89t117 -142t44.5 -184.5z" /> + <glyph glyph-name="exchange" unicode="&#xf0ec;" horiz-adv-x="1792" +d="M1792 352v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5zM1792 896q0 -14 -9 -23l-320 -320q-9 -9 -23 -9 +q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" /> + <glyph glyph-name="cloud_download" unicode="&#xf0ed;" horiz-adv-x="1920" +d="M1280 608q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 +q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" /> + <glyph glyph-name="cloud_upload" unicode="&#xf0ee;" horiz-adv-x="1920" +d="M1280 672q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 +q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" /> + <glyph glyph-name="user_md" unicode="&#xf0f0;" horiz-adv-x="1408" +d="M384 192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56 +t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68 +t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5t81 -103t47.5 -132.5t24 -138t5.5 -131zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5 +t271.5 -112.5t112.5 -271.5z" /> + <glyph glyph-name="stethoscope" unicode="&#xf0f1;" horiz-adv-x="1408" +d="M1280 832q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 832q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5t-131.5 271.5v132q-164 20 -274 128t-110 252v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48 +t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252 +t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136z" /> + <glyph glyph-name="suitcase" unicode="&#xf0f2;" horiz-adv-x="1792" +d="M640 1152h512v128h-512v-128zM288 1152v-1280h-64q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h64zM1408 1152v-1280h-1024v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128zM1792 928v-832q0 -92 -66 -158t-158 -66h-64v1280h64q92 0 158 -66 +t66 -158z" /> + <glyph glyph-name="bell_alt" unicode="&#xf0f3;" horiz-adv-x="1792" +d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5 +t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" /> + <glyph glyph-name="coffee" unicode="&#xf0f4;" horiz-adv-x="1920" +d="M1664 896q0 80 -56 136t-136 56h-64v-384h64q80 0 136 56t56 136zM0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM1856 896q0 -159 -112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158v736q0 26 19 45 +t45 19h1152q159 0 271.5 -112.5t112.5 -271.5z" /> + <glyph glyph-name="food" unicode="&#xf0f5;" horiz-adv-x="1408" +d="M640 1472v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45 +t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45zM1408 1472v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45z" /> + <glyph glyph-name="file_text_alt" unicode="&#xf0f6;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M384 736q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64zM1120 512q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704zM1120 256q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704 +q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704z" /> + <glyph glyph-name="building" unicode="&#xf0f7;" horiz-adv-x="1408" +d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M896 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M896 -128h384v1536h-1152v-1536h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM1408 1472v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45z" /> + <glyph glyph-name="hospital" unicode="&#xf0f8;" horiz-adv-x="1408" +d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M896 -128h384v1152h-256v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM896 1056v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5 +t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1408 1088v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1280q0 26 19 45t45 19h320 +v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45z" /> + <glyph glyph-name="ambulance" unicode="&#xf0f9;" horiz-adv-x="1920" +d="M640 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM1536 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5 +t90.5 37.5t37.5 90.5zM1664 800v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM1920 1344v-1152 +q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128q-26 0 -45 19t-19 45t19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> + <glyph glyph-name="medkit" unicode="&#xf0fa;" horiz-adv-x="1792" +d="M1280 416v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM640 1152h512v128h-512v-128zM256 1152v-1280h-32 +q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h32zM1440 1152v-1280h-1088v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160zM1792 928v-832q0 -92 -66 -158t-158 -66h-32v1280h32q92 0 158 -66t66 -158z" /> + <glyph glyph-name="fighter_jet" unicode="&#xf0fb;" horiz-adv-x="1920" +d="M1920 576q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8l-192 24v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96 +q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q128 -28 200 -52t80 -34z" /> + <glyph glyph-name="beer" unicode="&#xf0fc;" horiz-adv-x="1664" +d="M640 640v384h-256v-256q0 -53 37.5 -90.5t90.5 -37.5h128zM1664 192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320l-64 64l32 128h480l32 128h960l32 -192l-64 -32v-800z" /> + <glyph glyph-name="h_sign" unicode="&#xf0fd;" +d="M1280 192v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="f0fe" unicode="&#xf0fe;" +d="M1280 576v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="double_angle_left" unicode="&#xf100;" horiz-adv-x="1024" +d="M627 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23zM1011 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 +t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23z" /> + <glyph glyph-name="double_angle_right" unicode="&#xf101;" horiz-adv-x="1024" +d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM979 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23 +l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> + <glyph glyph-name="double_angle_up" unicode="&#xf102;" horiz-adv-x="1152" +d="M1075 224q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM1075 608q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393 +q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> + <glyph glyph-name="double_angle_down" unicode="&#xf103;" horiz-adv-x="1152" +d="M1075 672q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23zM1075 1056q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 +t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> + <glyph glyph-name="angle_left" unicode="&#xf104;" horiz-adv-x="640" +d="M627 992q0 -13 -10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> + <glyph glyph-name="angle_right" unicode="&#xf105;" horiz-adv-x="640" +d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> + <glyph glyph-name="angle_up" unicode="&#xf106;" horiz-adv-x="1152" +d="M1075 352q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> + <glyph glyph-name="angle_down" unicode="&#xf107;" horiz-adv-x="1152" +d="M1075 800q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> + <glyph glyph-name="desktop" unicode="&#xf108;" horiz-adv-x="1920" +d="M1792 544v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1376v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19 +t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> + <glyph glyph-name="laptop" unicode="&#xf109;" horiz-adv-x="1920" +d="M416 256q-66 0 -113 47t-47 113v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088zM384 1120v-704q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5z +M1760 192h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68v96h160h1600zM1040 96q16 0 16 16t-16 16h-160q-16 0 -16 -16t16 -16h160z" /> + <glyph glyph-name="tablet" unicode="&#xf10a;" horiz-adv-x="1152" +d="M640 128q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1024 288v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5zM1152 1248v-1088q0 -66 -47 -113t-113 -47h-832 +q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113z" /> + <glyph glyph-name="mobile_phone" unicode="&#xf10b;" horiz-adv-x="768" +d="M464 128q0 33 -23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5zM672 288v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5zM480 1136 +q0 16 -16 16h-160q-16 0 -16 -16t16 -16h160q16 0 16 16zM768 1152v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" /> + <glyph glyph-name="circle_blank" unicode="&#xf10c;" +d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103 +t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="quote_left" unicode="&#xf10d;" horiz-adv-x="1664" +d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z +M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z" /> + <glyph glyph-name="quote_right" unicode="&#xf10e;" horiz-adv-x="1664" +d="M768 1216v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216 +v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" /> + <glyph glyph-name="spinner" unicode="&#xf110;" horiz-adv-x="1792" +d="M526 142q0 -53 -37.5 -90.5t-90.5 -37.5q-52 0 -90 38t-38 90q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 -64q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -53 -37.5 -90.5t-90.5 -37.5 +t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1522 142q0 -52 -38 -90t-90 -38q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM558 1138q0 -66 -47 -113t-113 -47t-113 47t-47 113t47 113t113 47t113 -47t47 -113z +M1728 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1088 1344q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1618 1138q0 -93 -66 -158.5t-158 -65.5q-93 0 -158.5 65.5t-65.5 158.5 +q0 92 65.5 158t158.5 66q92 0 158 -66t66 -158z" /> + <glyph glyph-name="circle" unicode="&#xf111;" +d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="reply" unicode="&#xf112;" horiz-adv-x="1792" +d="M1792 416q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19 +l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" /> + <glyph glyph-name="github_alt" unicode="&#xf113;" horiz-adv-x="1664" +d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320 +q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86 +t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218 +q0 -87 -27 -168q136 -160 136 -398z" /> + <glyph glyph-name="folder_close_alt" unicode="&#xf114;" horiz-adv-x="1664" +d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320 +q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" /> + <glyph glyph-name="folder_open_alt" unicode="&#xf115;" horiz-adv-x="1920" +d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68 +v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z +" /> + <glyph glyph-name="expand_alt" unicode="&#xf116;" horiz-adv-x="1792" + /> + <glyph glyph-name="collapse_alt" unicode="&#xf117;" horiz-adv-x="1792" + /> + <glyph glyph-name="smile" unicode="&#xf118;" +d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 +t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5 +t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="frown" unicode="&#xf119;" +d="M1134 307q8 -25 -4 -48.5t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 +t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204 +t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="meh" unicode="&#xf11a;" +d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 +t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="gamepad" unicode="&#xf11b;" horiz-adv-x="1920" +d="M832 448v128q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23zM1408 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 +t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1920 512q0 -212 -150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150 +t-150 362t150 362t362 150h896q212 0 362 -150t150 -362z" /> + <glyph glyph-name="keyboard" unicode="&#xf11c;" horiz-adv-x="1920" +d="M384 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM512 624v-96q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h224q16 0 16 -16zM384 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 368v-96q0 -16 -16 -16 +h-864q-16 0 -16 16v96q0 16 16 16h864q16 0 16 -16zM768 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM640 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1024 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16 +h96q16 0 16 -16zM896 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1280 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1152 880v-96 +q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 880v-352q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h112v240q0 16 16 16h96q16 0 16 -16zM1792 128v896h-1664v-896 +h1664zM1920 1024v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5z" /> + <glyph glyph-name="flag_alt" unicode="&#xf11d;" horiz-adv-x="1792" +d="M1664 491v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9 +h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102 +q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" /> + <glyph glyph-name="flag_checkered" unicode="&#xf11e;" horiz-adv-x="1792" +d="M832 536v192q-181 -16 -384 -117v-185q205 96 384 110zM832 954v197q-172 -8 -384 -126v-189q215 111 384 118zM1664 491v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2 +q-23 0 -49 -3v-222h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92zM1664 918v189q-169 -91 -306 -91q-45 0 -78 8v-196q148 -42 384 90zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266 +q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8 +q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" /> + <glyph glyph-name="terminal" unicode="&#xf120;" horiz-adv-x="1664" +d="M585 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23zM1664 96v-64q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h960q14 0 23 -9 +t9 -23z" /> + <glyph glyph-name="code" unicode="&#xf121;" horiz-adv-x="1920" +d="M617 137l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23zM1208 1204l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5 +l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5zM1865 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23z" /> + <glyph glyph-name="reply_all" unicode="&#xf122;" horiz-adv-x="1792" +d="M640 454v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45zM1792 416q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1 +q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221q169 -173 169 -509z" /> + <glyph glyph-name="star_half_empty" unicode="&#xf123;" horiz-adv-x="1664" +d="M1186 579l257 250l-356 52l-66 10l-30 60l-159 322v-963l59 -31l318 -168l-60 355l-12 66zM1638 841l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5t54 34.5 +l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5z" /> + <glyph glyph-name="location_arrow" unicode="&#xf124;" horiz-adv-x="1408" +d="M1401 1187l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5t4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5z" /> + <glyph glyph-name="crop" unicode="&#xf125;" horiz-adv-x="1664" +d="M557 256h595v595zM512 301l595 595h-595v-595zM1664 224v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23 +v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23z" /> + <glyph glyph-name="code_fork" unicode="&#xf126;" horiz-adv-x="1024" +d="M288 64q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM288 1216q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM928 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1024 1088q0 -52 -26 -96.5t-70 -69.5 +q-2 -287 -226 -414q-67 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497 +q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136z" /> + <glyph glyph-name="unlink" unicode="&#xf127;" horiz-adv-x="1664" +d="M439 265l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23zM608 224v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM384 448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23t9 23t23 9h320 +q14 0 23 -9t9 -23zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204zM1031 1044l-239 -18 +l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56zM1664 960q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9 +t-9 23t9 23t23 9h320q14 0 23 -9t9 -23zM1120 1504v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM1527 1353l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" /> + <glyph glyph-name="question" unicode="&#xf128;" horiz-adv-x="1024" +d="M704 280v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28zM1020 880q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5 +t-10.5 37.5v45q0 83 65 156.5t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25t5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5z" /> + <glyph glyph-name="_279" unicode="&#xf129;" horiz-adv-x="640" +d="M640 192v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45zM512 1344v-192q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v192 +q0 26 19 45t45 19h256q26 0 45 -19t19 -45z" /> + <glyph glyph-name="exclamation" unicode="&#xf12a;" horiz-adv-x="640" +d="M512 288v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45zM542 1344l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45l-28 768q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45z" /> + <glyph glyph-name="superscript" unicode="&#xf12b;" +d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3q-1 -3 -2.5 -6.5t-3.5 -8t-3 -6.5q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109z +M1534 846v-206h-514l-3 27q-4 28 -4 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5 +t-65.5 -51.5t-30.5 -63h232v80h126z" /> + <glyph glyph-name="subscript" unicode="&#xf12c;" +d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3q-1 -3 -2.5 -6.5t-3.5 -8t-3 -6.5q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109z +M1536 -50v-206h-514l-4 27q-3 45 -3 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73 +h232v80h126z" /> + <glyph glyph-name="_283" unicode="&#xf12d;" horiz-adv-x="1920" +d="M896 128l336 384h-768l-336 -384h768zM1909 1205q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5t30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5z" /> + <glyph glyph-name="puzzle_piece" unicode="&#xf12e;" horiz-adv-x="1664" +d="M1664 438q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5 +t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89 +q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117 +q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143z" /> + <glyph glyph-name="microphone" unicode="&#xf130;" horiz-adv-x="1152" +d="M1152 832v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5 +t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45zM896 1216v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226v512q0 132 94 226t226 94t226 -94t94 -226z" /> + <glyph glyph-name="microphone_off" unicode="&#xf131;" horiz-adv-x="1408" +d="M271 591l-101 -101q-42 103 -42 214v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113zM1385 1193l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128 +q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23 +t-10 -23zM1005 1325l-621 -621v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" /> + <glyph glyph-name="shield" unicode="&#xf132;" horiz-adv-x="1280" +d="M1088 576v640h-448v-1137q119 63 213 137q235 184 235 360zM1280 1344v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150 +t-33.5 170.5v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> + <glyph glyph-name="calendar_empty" unicode="&#xf133;" horiz-adv-x="1664" +d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280 +q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> + <glyph glyph-name="fire_extinguisher" unicode="&#xf134;" horiz-adv-x="1408" +d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800 +q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113 +q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" /> + <glyph glyph-name="rocket" unicode="&#xf135;" horiz-adv-x="1664" +d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1 +q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" /> + <glyph glyph-name="maxcdn" unicode="&#xf136;" horiz-adv-x="1792" +d="M1745 763l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5z" /> + <glyph glyph-name="chevron_sign_left" unicode="&#xf137;" +d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="chevron_sign_right" unicode="&#xf138;" +d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="chevron_sign_up" unicode="&#xf139;" +d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="chevron_sign_down" unicode="&#xf13a;" +d="M813 237l454 454q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="html5" unicode="&#xf13b;" horiz-adv-x="1408" +d="M1130 939l16 175h-884l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674zM0 1408h1408l-128 -1438l-578 -162l-574 162z" /> + <glyph glyph-name="css3" unicode="&#xf13c;" horiz-adv-x="1792" +d="M275 1408h1505l-266 -1333l-804 -267l-698 267l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208z" /> + <glyph glyph-name="anchor" unicode="&#xf13d;" horiz-adv-x="1792" +d="M960 1280q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1792 352v-352q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30v352 +q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192q26 0 45 -19 +t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23z" /> + <glyph glyph-name="unlock_alt" unicode="&#xf13e;" horiz-adv-x="1152" +d="M1056 768q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181 +v-320h736z" /> + <glyph glyph-name="bullseye" unicode="&#xf140;" +d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM1152 640q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1280 640q0 -212 -150 -362t-362 -150t-362 150 +t-150 362t150 362t362 150t362 -150t150 -362zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="ellipsis_horizontal" unicode="&#xf141;" horiz-adv-x="1408" +d="M384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM896 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM1408 800v-192q0 -40 -28 -68t-68 -28h-192 +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" /> + <glyph glyph-name="ellipsis_vertical" unicode="&#xf142;" horiz-adv-x="384" +d="M384 288v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 1312v-192q0 -40 -28 -68t-68 -28h-192 +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" /> + <glyph glyph-name="_303" unicode="&#xf143;" +d="M512 256q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM863 162q-13 233 -176.5 396.5t-396.5 176.5q-14 1 -24 -9t-10 -23v-128q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128 +q13 0 23 10t9 24zM1247 161q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128q13 0 23 10q11 9 9 23zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="play_sign" unicode="&#xf144;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1152 585q32 18 32 55t-32 55l-544 320q-31 19 -64 1q-32 -19 -32 -56v-640q0 -37 32 -56 +q16 -8 32 -8q17 0 32 9z" /> + <glyph glyph-name="ticket" unicode="&#xf145;" horiz-adv-x="1792" +d="M1024 1084l316 -316l-572 -572l-316 316zM813 105l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45t19 -45l362 -362q18 -18 45 -18t45 18zM1702 742l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136 +t-136 56t-136 -56l-125 126q-37 37 -37 90.5t37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5z" /> + <glyph glyph-name="minus_sign_alt" unicode="&#xf146;" +d="M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 +t84.5 -203.5z" /> + <glyph glyph-name="check_minus" unicode="&#xf147;" horiz-adv-x="1408" +d="M1152 736v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5 +t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="level_up" unicode="&#xf148;" horiz-adv-x="1024" +d="M1018 933q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68z" /> + <glyph glyph-name="level_down" unicode="&#xf149;" horiz-adv-x="1024" +d="M32 1280h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34q9 19 29 19z" /> + <glyph glyph-name="check_sign" unicode="&#xf14a;" +d="M685 237l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l358 -358q19 -19 45 -19t45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5 +t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="edit_sign" unicode="&#xf14b;" +d="M404 428l152 -152l-52 -52h-56v96h-96v56zM818 818q14 -13 -3 -30l-291 -291q-17 -17 -30 -3q-14 13 3 30l291 291q17 17 30 3zM544 128l544 544l-288 288l-544 -544v-288h288zM1152 736l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28l-92 -92zM1536 1120 +v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_312" unicode="&#xf14c;" +d="M1280 608v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 +q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="share_sign" unicode="&#xf14d;" +d="M1005 435l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5q0 -181 167 -404q11 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5 +t224 23.5v-160q0 -42 40 -59q12 -5 24 -5q26 0 45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="compass" unicode="&#xf14e;" +d="M640 448l256 128l-256 128v-256zM1024 1039v-542l-512 -256v542zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="collapse" unicode="&#xf150;" +d="M1145 861q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66q17 35 57 35h640q40 0 57 -35zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120 +v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="collapse_top" unicode="&#xf151;" +d="M1145 419q-17 -35 -57 -35h-640q-40 0 -57 35q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_317" unicode="&#xf152;" +d="M1088 640q0 -33 -27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52zM1280 160v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h960q14 0 23 9t9 23zM1536 1120v-960q0 -119 -84.5 -203.5 +t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="eur" unicode="&#xf153;" horiz-adv-x="1024" +d="M976 229l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9 +t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26 +l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5l12 3l5 2q13 5 26 -2q12 -7 15 -21z" /> + <glyph glyph-name="gbp" unicode="&#xf154;" horiz-adv-x="1024" +d="M1020 399v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7 +q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5z" /> + <glyph glyph-name="usd" unicode="&#xf155;" horiz-adv-x="1024" +d="M978 351q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43 +t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5 +t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50 +t53 -63.5t31.5 -76.5t13 -94z" /> + <glyph glyph-name="inr" unicode="&#xf156;" horiz-adv-x="898" +d="M898 1066v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102 +q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171q14 0 23 -9t9 -23z" /> + <glyph glyph-name="jpy" unicode="&#xf157;" horiz-adv-x="1027" +d="M603 0h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61 +l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" /> + <glyph glyph-name="rub" unicode="&#xf158;" horiz-adv-x="1280" +d="M1043 971q0 100 -65 162t-171 62h-320v-448h320q106 0 171 62t65 162zM1280 971q0 -193 -126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23v128 +q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315z" /> + <glyph glyph-name="krw" unicode="&#xf159;" horiz-adv-x="1792" +d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23 +t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28 +q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" /> + <glyph glyph-name="btc" unicode="&#xf15a;" horiz-adv-x="1280" +d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164 +l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30 +t24.5 40t9.5 51zM881 827q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" /> + <glyph glyph-name="file" unicode="&#xf15b;" +d="M1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472zM896 992q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544z" /> + <glyph glyph-name="file_text" unicode="&#xf15c;" +d="M1468 1060q14 -14 28 -36h-472v472q22 -14 36 -28zM992 896h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28zM1152 160v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704 +q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23z" /> + <glyph glyph-name="sort_by_alphabet" unicode="&#xf15d;" horiz-adv-x="1664" +d="M1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1572 -23 +v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121zM1661 874v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162 +l230 -662h70z" /> + <glyph glyph-name="_329" unicode="&#xf15e;" horiz-adv-x="1664" +d="M1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1661 -150 +v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70zM1572 1001v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248 +v119h121z" /> + <glyph glyph-name="sort_by_attributes" unicode="&#xf160;" horiz-adv-x="1792" +d="M736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1792 -32v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832 +q14 0 23 -9t9 -23zM1600 480v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1408 992v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1216 1504v-192q0 -14 -9 -23t-23 -9h-256 +q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23z" /> + <glyph glyph-name="sort_by_attributes_alt" unicode="&#xf161;" horiz-adv-x="1792" +d="M1216 -32v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192 +q14 0 23 -9t9 -23zM1408 480v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1600 992v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1792 1504v-192q0 -14 -9 -23t-23 -9h-832 +q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23z" /> + <glyph glyph-name="sort_by_order" unicode="&#xf162;" +d="M1346 223q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23 +zM1486 165q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5 +t82 -252.5zM1456 882v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165z" /> + <glyph glyph-name="sort_by_order_alt" unicode="&#xf163;" +d="M1346 1247q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9 +t9 -23zM1456 -142v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165zM1486 1189q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13 +q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5z" /> + <glyph glyph-name="_334" unicode="&#xf164;" horiz-adv-x="1664" +d="M256 192q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5zM416 704v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45zM1600 704q0 -86 -55 -149q15 -44 15 -76 +q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5v641q0 25 18 43.5t43 20.5q24 2 76 59t101 121q68 87 101 120q18 18 31 48t17.5 48.5 +t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135z" /> + <glyph glyph-name="_335" unicode="&#xf165;" horiz-adv-x="1664" +d="M256 960q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5zM416 448v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640q0 -26 19 -45t45 -19h288q26 0 45 19t19 45zM1545 597q55 -61 55 -149q-1 -78 -57.5 -135 +t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121 +t-76 59q-25 2 -43 20.5t-18 43.5v641q0 26 19 44.5t45 19.5q35 1 158 44q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76z" /> + <glyph glyph-name="youtube_sign" unicode="&#xf166;" +d="M919 233v157q0 50 -29 50q-17 0 -33 -16v-224q16 -16 33 -16q29 0 29 49zM1103 355h66v34q0 51 -33 51t-33 -51v-34zM532 621v-70h-80v-423h-74v423h-78v70h232zM733 495v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 17 -6 54v290h66v-270q0 -24 1 -26q1 -15 15 -15 +q20 0 42 31v280h67zM985 384v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74zM1236 255v-9q0 -29 -2 -43q-3 -22 -15 -40q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86v129q0 59 20 86q29 38 80 38t78 -38 +q21 -29 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68zM785 1079v-156q0 -51 -32 -51t-32 51v156q0 52 32 52t32 -52zM1318 366q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5 +q-20 -87 -20 -260q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73q20 84 20 260zM563 1017l90 296h-75l-51 -195l-53 195h-78q7 -23 23 -69l24 -69q35 -103 46 -158v-201h74v201zM852 936v130q0 58 -21 87q-29 38 -78 38 +q-51 0 -78 -38q-21 -29 -21 -87v-130q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87zM1033 816h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293q0 -37 6 -55q11 -27 43 -27q36 0 77 45v-40zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5 +h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="youtube" unicode="&#xf167;" +d="M971 292v-211q0 -67 -39 -67q-23 0 -45 22v301q22 22 45 22q39 0 39 -67zM1309 291v-46h-90v46q0 68 45 68t45 -68zM343 509h107v94h-312v-94h105v-569h100v569zM631 -60h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391q0 -49 8 -73 +q12 -37 58 -37q48 0 102 61v-54zM1060 88v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89v-663h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100zM1398 98v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51 +q-28 -37 -28 -116v-173q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54q2 9 2 58zM790 1011v210q0 69 -43 69t-43 -69v-210q0 -70 43 -70t43 70zM1509 260q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99 +q-26 112 -26 350q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350zM511 1536h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187h106l71 -263zM881 1203v-175q0 -81 -28 -118q-38 -51 -106 -51q-67 0 -105 51 +q-28 38 -28 118v175q0 80 28 117q38 51 105 51q68 0 106 -51q28 -37 28 -117zM1216 1365v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91z" /> + <glyph glyph-name="xing" unicode="&#xf168;" horiz-adv-x="1408" +d="M597 869q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17t0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45zM1403 1511q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37q-10 -15 -32 -15h-239q-42 0 -66 45l-339 622q18 32 531 942 +q25 45 64 45h241q22 0 31 -15z" /> + <glyph glyph-name="xing_sign" unicode="&#xf169;" +d="M685 771q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29l125 -216v-1l-196 -346q-9 -14 0 -28q8 -13 24 -13h185q31 0 50 36zM1309 1268q-7 12 -24 12h-187q-30 0 -49 -35l-411 -729q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1 +l409 723q8 16 0 28zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="youtube_play" unicode="&#xf16a;" horiz-adv-x="1792" +d="M711 408l484 250l-484 253v-503zM896 1270q168 0 324.5 -4.5t229.5 -9.5l73 -4q1 0 17 -1.5t23 -3t23.5 -4.5t28.5 -8t28 -13t31 -19.5t29 -26.5q6 -6 15.5 -18.5t29 -58.5t26.5 -101q8 -64 12.5 -136.5t5.5 -113.5v-40v-136q1 -145 -18 -290q-7 -55 -25 -99.5t-32 -61.5 +l-14 -17q-14 -15 -29 -26.5t-31 -19t-28 -12.5t-28.5 -8t-24 -4.5t-23 -3t-16.5 -1.5q-251 -19 -627 -19q-207 2 -359.5 6.5t-200.5 7.5l-49 4l-36 4q-36 5 -54.5 10t-51 21t-56.5 41q-6 6 -15.5 18.5t-29 58.5t-26.5 101q-8 64 -12.5 136.5t-5.5 113.5v40v136 +q-1 145 18 290q7 55 25 99.5t32 61.5l14 17q14 15 29 26.5t31 19.5t28 13t28.5 8t23.5 4.5t23 3t17 1.5q251 18 627 18z" /> + <glyph glyph-name="dropbox" unicode="&#xf16b;" horiz-adv-x="1792" +d="M402 829l494 -305l-342 -285l-490 319zM1388 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM554 1418l342 -285l-494 -304l-338 270zM1390 829l338 -271l-489 -319l-343 285zM1239 1418l489 -319l-338 -270l-494 304z" /> + <glyph glyph-name="stackexchange" unicode="&#xf16c;" +d="M1289 -96h-1118v480h-160v-640h1438v640h-160v-480zM347 428l33 157l783 -165l-33 -156zM450 802l67 146l725 -339l-67 -145zM651 1158l102 123l614 -513l-102 -123zM1048 1536l477 -641l-128 -96l-477 641zM330 65v159h800v-159h-800z" /> + <glyph glyph-name="instagram" unicode="&#xf16d;" +d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1162 640q0 -164 -115 -279t-279 -115t-279 115t-115 279t115 279t279 115t279 -115t115 -279zM1270 1050q0 -38 -27 -65t-65 -27t-65 27t-27 65t27 65t65 27t65 -27t27 -65zM768 1270 +q-7 0 -76.5 0.5t-105.5 0t-96.5 -3t-103 -10t-71.5 -18.5q-50 -20 -88 -58t-58 -88q-11 -29 -18.5 -71.5t-10 -103t-3 -96.5t0 -105.5t0.5 -76.5t-0.5 -76.5t0 -105.5t3 -96.5t10 -103t18.5 -71.5q20 -50 58 -88t88 -58q29 -11 71.5 -18.5t103 -10t96.5 -3t105.5 0t76.5 0.5 +t76.5 -0.5t105.5 0t96.5 3t103 10t71.5 18.5q50 20 88 58t58 88q11 29 18.5 71.5t10 103t3 96.5t0 105.5t-0.5 76.5t0.5 76.5t0 105.5t-3 96.5t-10 103t-18.5 71.5q-20 50 -58 88t-88 58q-29 11 -71.5 18.5t-103 10t-96.5 3t-105.5 0t-76.5 -0.5zM1536 640q0 -229 -5 -317 +q-10 -208 -124 -322t-322 -124q-88 -5 -317 -5t-317 5q-208 10 -322 124t-124 322q-5 88 -5 317t5 317q10 208 124 322t322 124q88 5 317 5t317 -5q208 -10 322 -124t124 -322q5 -88 5 -317z" /> + <glyph glyph-name="flickr" unicode="&#xf16e;" +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM698 640q0 88 -62 150t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150zM1262 640q0 88 -62 150 +t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150z" /> + <glyph glyph-name="adn" unicode="&#xf170;" +d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="f171" unicode="&#xf171;" horiz-adv-x="1408" +d="M815 677q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82t52 58q36 18 72.5 12t64 -35.5t27.5 -67.5zM926 698q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5q4 -91 77.5 -155t165.5 -56q91 8 152 84t50 168zM1165 1240q-20 27 -56 44.5t-58 22 +t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5zM1222 205q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18 +t-76.5 27t-73 43.5t-52 61.5q-25 96 -57 292l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37zM1403 1166q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34t-6 39.5 +t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54z" /> + <glyph glyph-name="bitbucket_sign" unicode="&#xf172;" +d="M848 666q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5t43.5 -70.5q39 -23 81 4t36 72zM928 682q8 -66 -36 -121t-110 -61t-119 40t-56 113q-2 49 25.5 93t72.5 64q70 31 141.5 -10t81.5 -118zM1100 1073q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5 +t-52.5 16t-54.5 32.5q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5zM1142 327q0 7 5.5 26.5t3 32t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6l-5 -12q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71z +M1272 1020q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63q24 13 39.5 23t31 29t19.5 40q48 267 80 473zM1536 1120 +v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="tumblr" unicode="&#xf173;" horiz-adv-x="1024" +d="M944 207l80 -237q-23 -35 -111 -66t-177 -32q-104 -2 -190.5 26t-142.5 74t-95 106t-55.5 120t-16.5 118v544h-168v215q72 26 129 69.5t91 90t58 102t34 99t15 88.5q1 5 4.5 8.5t7.5 3.5h244v-424h333v-252h-334v-518q0 -30 6.5 -56t22.5 -52.5t49.5 -41.5t81.5 -14 +q78 2 134 29z" /> + <glyph glyph-name="tumblr_sign" unicode="&#xf174;" +d="M1136 75l-62 183q-44 -22 -103 -22q-36 -1 -62 10.5t-38.5 31.5t-17.5 40.5t-5 43.5v398h257v194h-256v326h-188q-8 0 -9 -10q-5 -44 -17.5 -87t-39 -95t-77 -95t-118.5 -68v-165h130v-418q0 -57 21.5 -115t65 -111t121 -85.5t176.5 -30.5q69 1 136.5 25t85.5 50z +M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="long_arrow_down" unicode="&#xf175;" horiz-adv-x="768" +d="M765 237q8 -19 -5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19z" /> + <glyph glyph-name="long_arrow_up" unicode="&#xf176;" horiz-adv-x="768" +d="M765 1043q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19t5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35z" /> + <glyph glyph-name="long_arrow_left" unicode="&#xf177;" horiz-adv-x="1792" +d="M1792 736v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23z" /> + <glyph glyph-name="long_arrow_right" unicode="&#xf178;" horiz-adv-x="1792" +d="M1728 643q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23z" /> + <glyph glyph-name="apple" unicode="&#xf179;" horiz-adv-x="1408" +d="M1393 321q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503q0 228 113 374q113 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65 +q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126zM1017 1494q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10z" /> + <glyph glyph-name="windows" unicode="&#xf17a;" horiz-adv-x="1664" +d="M682 530v-651l-682 94v557h682zM682 1273v-659h-682v565zM1664 530v-786l-907 125v661h907zM1664 1408v-794h-907v669z" /> + <glyph glyph-name="android" unicode="&#xf17b;" horiz-adv-x="1408" +d="M493 1053q16 0 27.5 11.5t11.5 27.5t-11.5 27.5t-27.5 11.5t-27 -11.5t-11 -27.5t11 -27.5t27 -11.5zM915 1053q16 0 27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5t11.5 -27.5t27.5 -11.5zM103 869q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30 +t-73 30t-30 73v430q0 42 30 72t73 30zM1163 850v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78v666h918zM931 1255q107 -55 171 -153.5t64 -215.5 +h-925q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20zM1408 767v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5z" /> + <glyph glyph-name="linux" unicode="&#xf17c;" +d="M663 1125q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5q0 12 19 15h10zM750 1111q-4 -1 -11.5 6.5t-17.5 4.5q24 11 32 -2q3 -6 -3 -9zM399 684q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-10 -11 -1 -12q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2z +M1254 325q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7 +q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15 +q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5 +t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19 +q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63 +q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18q-2 -1 -4 -5q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54t7 -70.5q46 24 7 92 +q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5t60 -22.5zM626 1152 +q3 17 -2.5 30t-11.5 15q-9 2 -9 -7q2 -5 5 -6q10 0 7 -15q-3 -20 8 -20q3 0 3 3zM1045 955q-2 8 -6.5 11.5t-13 5t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20zM867 1168q0 11 -5 19.5t-11 12.5t-9 3q-6 0 -8 -2t0 -4 +t5 -3q14 -4 18 -31q0 -3 8 2q2 2 2 3zM921 1401q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9t3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7zM1486 60q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5 +t-30 -18.5t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43 +q-19 4 -51 9.5t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49 +t-14 -48q3 -17 37 -26q20 -6 84.5 -18.5t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54 +q110 143 124 195q-12 112 -16 310q-2 90 24 151.5t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5 +t-40.5 -33.5t-61 -14q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5 +t15.5 47.5q1 -31 8 -56.5t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13t16.5 -9.5z" /> + <glyph glyph-name="dribble" unicode="&#xf17d;" +d="M1024 36q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5t-103 -148l-15 11q184 -150 418 -150q132 0 256 52zM839 643q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81 +t99.5 48l37 13q4 1 13 3.5t13 4.5zM732 855q-120 213 -244 378q-138 -65 -234 -186t-128 -272q302 0 606 80zM1416 536q-210 60 -409 29q87 -239 128 -469q111 75 185 189.5t96 250.5zM611 1277q-1 0 -2 -1q1 1 2 1zM1201 1132q-185 164 -433 164q-76 0 -155 -19 +q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5zM1424 647q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5q25 -53 44 -95q2 -5 6.5 -17t7.5 -17q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5t36.5 -6 +t25 -4.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="skype" unicode="&#xf17e;" +d="M1173 473q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5 +t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75q0 -92 122 -157.5t291 -65.5 +q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5q0 73 16 150q-80 104 -80 234q0 159 112.5 271.5t271.5 112.5q130 0 234 -80 +q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234z" /> + <glyph glyph-name="foursquare" unicode="&#xf180;" horiz-adv-x="1280" +d="M1000 1102l37 194q5 23 -9 40t-35 17h-712q-23 0 -38.5 -17t-15.5 -37v-1101q0 -7 6 -1l291 352q23 26 38 33.5t48 7.5h239q22 0 37 14.5t18 29.5q24 130 37 191q4 21 -11.5 40t-36.5 19h-294q-29 0 -48 19t-19 48v42q0 29 19 47.5t48 18.5h346q18 0 35 13.5t20 29.5z +M1227 1324q-15 -73 -53.5 -266.5t-69.5 -350t-35 -173.5q-6 -22 -9 -32.5t-14 -32.5t-24.5 -33t-38.5 -21t-58 -10h-271q-13 0 -22 -10q-8 -9 -426 -494q-22 -25 -58.5 -28.5t-48.5 5.5q-55 22 -55 98v1410q0 55 38 102.5t120 47.5h888q95 0 127 -53t10 -159zM1227 1324 +l-158 -790q4 17 35 173.5t69.5 350t53.5 266.5z" /> + <glyph glyph-name="trello" unicode="&#xf181;" +d="M704 192v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1376 576v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408 +q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> + <glyph glyph-name="female" unicode="&#xf182;" horiz-adv-x="1280" +d="M1280 480q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43 +q-40 0 -68 28t-28 68q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53zM864 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> + <glyph glyph-name="male" unicode="&#xf183;" horiz-adv-x="1024" +d="M1024 832v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136z +M736 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> + <glyph glyph-name="gittip" unicode="&#xf184;" +d="M773 234l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85t24.5 -59zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="sun" unicode="&#xf185;" horiz-adv-x="1792" +d="M1472 640q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5zM1748 363q-4 -15 -20 -20l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4 +l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94 +q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29z" /> + <glyph glyph-name="_366" unicode="&#xf186;" +d="M1262 233q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5zM1465 318q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61 +t-245 164t-164 245t-61 298q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38z" /> + <glyph glyph-name="archive" unicode="&#xf187;" horiz-adv-x="1792" +d="M1088 704q0 26 -19 45t-45 19h-256q-26 0 -45 -19t-19 -45t19 -45t45 -19h256q26 0 45 19t19 45zM1664 896v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1728 1344v-256q0 -26 -19 -45t-45 -19h-1536 +q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45z" /> + <glyph glyph-name="bug" unicode="&#xf188;" horiz-adv-x="1664" +d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207 +q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45t19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19 +t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" /> + <glyph glyph-name="vk" unicode="&#xf189;" horiz-adv-x="1920" +d="M1917 1016q23 -64 -150 -294q-24 -32 -65 -85q-40 -51 -55 -72t-30.5 -49.5t-12 -42t13 -34.5t32.5 -43t57 -53q4 -2 5 -4q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12q-30 21 -70 64t-68.5 77.5t-61 58 +t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211t-130.5 272q-6 16 -6 27t3 16l4 6 +q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24q16 19 38 30q53 26 239 24 +q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5t13 3t20 0.5l288 2 +q39 5 64 -2.5t31 -16.5z" /> + <glyph glyph-name="weibo" unicode="&#xf18a;" horiz-adv-x="1792" +d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12 +q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422 +q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178 +q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z +M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" /> + <glyph glyph-name="renren" unicode="&#xf18b;" +d="M1133 -34q-171 -94 -368 -94q-196 0 -367 94q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211zM638 1394v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495q0 187 83.5 349.5t229.5 269.5t325 137zM1536 638q0 -280 -181 -495 +q-204 99 -330.5 306.5t-126.5 459.5v485q179 -30 325 -137t229.5 -269.5t83.5 -349.5z" /> + <glyph glyph-name="_372" unicode="&#xf18c;" horiz-adv-x="1408" +d="M1402 433q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32t13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5 +t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56 +t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -4 1 -50t-1 -72q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5 +t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5z" /> + <glyph glyph-name="stack_exchange" unicode="&#xf18d;" horiz-adv-x="1280" +d="M1259 283v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5v66h1238zM1259 609v-255h-1238v255h1238zM1259 937v-255h-1238v255h1238zM1259 1077v-67h-1238v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5z +" /> + <glyph glyph-name="_374" unicode="&#xf18e;" +d="M1152 640q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 +t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="arrow_circle_alt_left" unicode="&#xf190;" +d="M1152 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23t9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 +t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_376" unicode="&#xf191;" +d="M1024 960v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52t27 52l448 320q17 12 37 12q26 0 45 -19t19 -45zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5z +M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="dot_circle_alt" unicode="&#xf192;" +d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5 +t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_378" unicode="&#xf193;" horiz-adv-x="1664" +d="M1023 349l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5zM1571 249l58 -114l-256 -128 +q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5l-96 779q-2 17 6 42q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455z" /> + <glyph glyph-name="vimeo_square" unicode="&#xf194;" +d="M1292 898q10 216 -161 222q-231 8 -312 -261q44 19 82 19q85 0 74 -96q-4 -57 -74 -167t-105 -110q-43 0 -82 169q-13 54 -45 255q-30 189 -160 177q-59 -7 -164 -100l-81 -72l-81 -72l52 -67q76 52 87 52q57 0 107 -179q15 -55 45 -164.5t45 -164.5q68 -179 164 -179 +q157 0 383 294q220 283 226 444zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_380" unicode="&#xf195;" horiz-adv-x="1152" +d="M1152 704q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160 +q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" /> + <glyph glyph-name="plus_square_o" unicode="&#xf196;" horiz-adv-x="1408" +d="M1152 736v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832 +q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_382" unicode="&#xf197;" horiz-adv-x="2176" +d="M620 416q-110 -64 -268 -64h-128v64h-64q-13 0 -22.5 23.5t-9.5 56.5q0 24 7 49q-58 2 -96.5 10.5t-38.5 20.5t38.5 20.5t96.5 10.5q-7 25 -7 49q0 33 9.5 56.5t22.5 23.5h64v64h128q158 0 268 -64h1113q42 -7 106.5 -18t80.5 -14q89 -15 150 -40.5t83.5 -47.5t22.5 -40 +t-22.5 -40t-83.5 -47.5t-150 -40.5q-16 -3 -80.5 -14t-106.5 -18h-1113zM1739 668q53 -36 53 -92t-53 -92l81 -30q68 48 68 122t-68 122zM625 400h1015q-217 -38 -456 -80q-57 0 -113 -24t-83 -48l-28 -24l-288 -288q-26 -26 -70.5 -45t-89.5 -19h-96l-93 464h29 +q157 0 273 64zM352 816h-29l93 464h96q46 0 90 -19t70 -45l288 -288q4 -4 11 -10.5t30.5 -23t48.5 -29t61.5 -23t72.5 -10.5l456 -80h-1015q-116 64 -273 64z" /> + <glyph glyph-name="_383" unicode="&#xf198;" horiz-adv-x="1664" +d="M1519 760q62 0 103.5 -40.5t41.5 -101.5q0 -97 -93 -130l-172 -59l56 -167q7 -21 7 -47q0 -59 -42 -102t-101 -43q-47 0 -85.5 27t-53.5 72l-55 165l-310 -106l55 -164q8 -24 8 -47q0 -59 -42 -102t-102 -43q-47 0 -85 27t-53 72l-55 163l-153 -53q-29 -9 -50 -9 +q-61 0 -101.5 40t-40.5 101q0 47 27.5 85t71.5 53l156 53l-105 313l-156 -54q-26 -8 -48 -8q-60 0 -101 40.5t-41 100.5q0 47 27.5 85t71.5 53l157 53l-53 159q-8 24 -8 47q0 60 42 102.5t102 42.5q47 0 85 -27t53 -72l54 -160l310 105l-54 160q-8 24 -8 47q0 59 42.5 102 +t101.5 43q47 0 85.5 -27.5t53.5 -71.5l53 -161l162 55q21 6 43 6q60 0 102.5 -39.5t42.5 -98.5q0 -45 -30 -81.5t-74 -51.5l-157 -54l105 -316l164 56q24 8 46 8zM725 498l310 105l-105 315l-310 -107z" /> + <glyph glyph-name="_384" unicode="&#xf199;" +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM1280 352v436q-31 -35 -64 -55q-34 -22 -132.5 -85t-151.5 -99q-98 -69 -164 -69v0v0q-66 0 -164 69 +q-47 32 -142 92.5t-142 92.5q-12 8 -33 27t-31 27v-436q0 -40 28 -68t68 -28h832q40 0 68 28t28 68zM1280 925q0 41 -27.5 70t-68.5 29h-832q-40 0 -68 -28t-28 -68q0 -37 30.5 -76.5t67.5 -64.5q47 -32 137.5 -89t129.5 -83q3 -2 17 -11.5t21 -14t21 -13t23.5 -13 +t21.5 -9.5t22.5 -7.5t20.5 -2.5t20.5 2.5t22.5 7.5t21.5 9.5t23.5 13t21 13t21 14t17 11.5l267 174q35 23 66.5 62.5t31.5 73.5z" /> + <glyph glyph-name="_385" unicode="&#xf19a;" horiz-adv-x="1792" +d="M127 640q0 163 67 313l367 -1005q-196 95 -315 281t-119 411zM1415 679q0 -19 -2.5 -38.5t-10 -49.5t-11.5 -44t-17.5 -59t-17.5 -58l-76 -256l-278 826q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-75 1 -202 10q-12 1 -20.5 -5t-11.5 -15t-1.5 -18.5t9 -16.5 +t19.5 -8l80 -8l120 -328l-168 -504l-280 832q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-7 0 -23 0.5t-26 0.5q105 160 274.5 253.5t367.5 93.5q147 0 280.5 -53t238.5 -149h-10q-55 0 -92 -40.5t-37 -95.5q0 -12 2 -24t4 -21.5t8 -23t9 -21t12 -22.5t12.5 -21 +t14.5 -24t14 -23q63 -107 63 -212zM909 573l237 -647q1 -6 5 -11q-126 -44 -255 -44q-112 0 -217 32zM1570 1009q95 -174 95 -369q0 -209 -104 -385.5t-279 -278.5l235 678q59 169 59 276q0 42 -6 79zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286 +t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 -215q173 0 331.5 68t273 182.5t182.5 273t68 331.5t-68 331.5t-182.5 273t-273 182.5t-331.5 68t-331.5 -68t-273 -182.5t-182.5 -273t-68 -331.5t68 -331.5t182.5 -273 +t273 -182.5t331.5 -68z" /> + <glyph glyph-name="_386" unicode="&#xf19b;" horiz-adv-x="1792" +d="M1086 1536v-1536l-272 -128q-228 20 -414 102t-293 208.5t-107 272.5q0 140 100.5 263.5t275 205.5t391.5 108v-172q-217 -38 -356.5 -150t-139.5 -255q0 -152 154.5 -267t388.5 -145v1360zM1755 954l37 -390l-525 114l147 83q-119 70 -280 99v172q277 -33 481 -157z" /> + <glyph glyph-name="_387" unicode="&#xf19c;" horiz-adv-x="2048" +d="M960 1536l960 -384v-128h-128q0 -26 -20.5 -45t-48.5 -19h-1526q-28 0 -48.5 19t-20.5 45h-128v128zM256 896h256v-768h128v768h256v-768h128v768h256v-768h128v768h256v-768h59q28 0 48.5 -19t20.5 -45v-64h-1664v64q0 26 20.5 45t48.5 19h59v768zM1851 -64 +q28 0 48.5 -19t20.5 -45v-128h-1920v128q0 26 20.5 45t48.5 19h1782z" /> + <glyph glyph-name="_388" unicode="&#xf19d;" horiz-adv-x="2304" +d="M1774 700l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128l18 316l574 -181q22 -7 48 -7t48 7zM2304 1024q0 -23 -22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433 +q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31t22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31z" /> + <glyph glyph-name="_389" unicode="&#xf19e;" +d="M859 579l13 -707q-62 11 -105 11q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287q58 -15 108 -15q44 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14v0 +q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610z" /> + <glyph glyph-name="uniF1A0" unicode="&#xf1a0;" +d="M768 750h725q12 -67 12 -128q0 -217 -91 -387.5t-259.5 -266.5t-386.5 -96q-157 0 -299 60.5t-245 163.5t-163.5 245t-60.5 299t60.5 299t163.5 245t245 163.5t299 60.5q300 0 515 -201l-209 -201q-123 119 -306 119q-129 0 -238.5 -65t-173.5 -176.5t-64 -243.5 +t64 -243.5t173.5 -176.5t238.5 -65q87 0 160 24t120 60t82 82t51.5 87t22.5 78h-436v264z" /> + <glyph glyph-name="f1a1" unicode="&#xf1a1;" horiz-adv-x="1792" +d="M1095 369q16 -16 0 -31q-62 -62 -199 -62t-199 62q-16 15 0 31q6 6 15 6t15 -6q48 -49 169 -49q120 0 169 49q6 6 15 6t15 -6zM788 550q0 -37 -26 -63t-63 -26t-63.5 26t-26.5 63q0 38 26.5 64t63.5 26t63 -26.5t26 -63.5zM1183 550q0 -37 -26.5 -63t-63.5 -26t-63 26 +t-26 63t26 63.5t63 26.5t63.5 -26t26.5 -64zM1434 670q0 49 -35 84t-85 35t-86 -36q-130 90 -311 96l63 283l200 -45q0 -37 26 -63t63 -26t63.5 26.5t26.5 63.5t-26.5 63.5t-63.5 26.5q-54 0 -80 -50l-221 49q-19 5 -25 -16l-69 -312q-180 -7 -309 -97q-35 37 -87 37 +q-50 0 -85 -35t-35 -84q0 -35 18.5 -64t49.5 -44q-6 -27 -6 -56q0 -142 140 -243t337 -101q198 0 338 101t140 243q0 32 -7 57q30 15 48 43.5t18 63.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191 +t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="_392" unicode="&#xf1a2;" +d="M939 407q13 -13 0 -26q-53 -53 -171 -53t-171 53q-13 13 0 26q5 6 13 6t13 -6q42 -42 145 -42t145 42q5 6 13 6t13 -6zM676 563q0 -31 -23 -54t-54 -23t-54 23t-23 54q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1014 563q0 -31 -23 -54t-54 -23t-54 23t-23 54 +q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1229 666q0 42 -30 72t-73 30q-42 0 -73 -31q-113 78 -267 82l54 243l171 -39q1 -32 23.5 -54t53.5 -22q32 0 54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5q-48 0 -69 -43l-189 42q-17 5 -21 -13l-60 -268q-154 -6 -265 -83 +q-30 32 -74 32q-43 0 -73 -30t-30 -72q0 -30 16 -55t42 -38q-5 -25 -5 -48q0 -122 120 -208.5t289 -86.5q170 0 290 86.5t120 208.5q0 25 -6 49q25 13 40.5 37.5t15.5 54.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960 +q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_393" unicode="&#xf1a3;" +d="M866 697l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14q19 0 32.5 -14t13.5 -33v-54zM1199 502v122h-150 +v-126q0 -20 -13.5 -33.5t-33.5 -13.5q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123q0 -80 58 -137t139 -57t138.5 57t57.5 139zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103 +t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="f1a4" unicode="&#xf1a4;" horiz-adv-x="1920" +d="M1062 824v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58zM1592 602h328 +v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275z" /> + <glyph glyph-name="_395" unicode="&#xf1a5;" +d="M1472 160v480h-704v704h-480q-93 0 -158.5 -65.5t-65.5 -158.5v-480h704v-704h480q93 0 158.5 65.5t65.5 158.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 +t84.5 -203.5z" /> + <glyph glyph-name="_396" unicode="&#xf1a6;" horiz-adv-x="2048" +d="M328 1254h204v-983h-532v697h328v286zM328 435v369h-123v-369h123zM614 968v-697h205v697h-205zM614 1254v-204h205v204h-205zM901 968h533v-942h-533v163h328v82h-328v697zM1229 435v369h-123v-369h123zM1516 968h532v-942h-532v163h327v82h-327v697zM1843 435v369h-123 +v-369h123z" /> + <glyph glyph-name="_397" unicode="&#xf1a7;" +d="M1046 516q0 -64 -38 -109t-91 -45q-43 0 -70 15v277q28 17 70 17q53 0 91 -45.5t38 -109.5zM703 944q0 -64 -38 -109.5t-91 -45.5q-43 0 -70 15v277q28 17 70 17q53 0 91 -45t38 -109zM1265 513q0 134 -88 229t-213 95q-20 0 -39 -3q-23 -78 -78 -136q-87 -95 -211 -101 +v-636l211 41v206q51 -19 117 -19q125 0 213 95t88 229zM922 940q0 134 -88.5 229t-213.5 95q-74 0 -141 -36h-186v-840l211 41v206q55 -19 116 -19q125 0 213.5 95t88.5 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960 +q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_398" unicode="&#xf1a8;" horiz-adv-x="2038" +d="M1222 607q75 3 143.5 -20.5t118 -58.5t101 -94.5t84 -108t75.5 -120.5q33 -56 78.5 -109t75.5 -80.5t99 -88.5q-48 -30 -108.5 -57.5t-138.5 -59t-114 -47.5q-44 37 -74 115t-43.5 164.5t-33 180.5t-42.5 168.5t-72.5 123t-122.5 48.5l-10 -2l-6 -4q4 -5 13 -14 +q6 -5 28 -23.5t25.5 -22t19 -18t18 -20.5t11.5 -21t10.5 -27.5t4.5 -31t4 -40.5l1 -33q1 -26 -2.5 -57.5t-7.5 -52t-12.5 -58.5t-11.5 -53q-35 1 -101 -9.5t-98 -10.5q-39 0 -72 10q-2 16 -2 47q0 74 3 96q2 13 31.5 41.5t57 59t26.5 51.5q-24 2 -43 -24 +q-36 -53 -111.5 -99.5t-136.5 -46.5q-25 0 -75.5 63t-106.5 139.5t-84 96.5q-6 4 -27 30q-482 -112 -513 -112q-16 0 -28 11t-12 27q0 15 8.5 26.5t22.5 14.5l486 106q-8 14 -8 25t5.5 17.5t16 11.5t20 7t23 4.5t18.5 4.5q4 1 15.5 7.5t17.5 6.5q15 0 28 -16t20 -33 +q163 37 172 37q17 0 29.5 -11t12.5 -28q0 -15 -8.5 -26t-23.5 -14l-182 -40l-1 -16q-1 -26 81.5 -117.5t104.5 -91.5q47 0 119 80t72 129q0 36 -23.5 53t-51 18.5t-51 11.5t-23.5 34q0 16 10 34l-68 19q43 44 43 117q0 26 -5 58q82 16 144 16q44 0 71.5 -1.5t48.5 -8.5 +t31 -13.5t20.5 -24.5t15.5 -33.5t17 -47.5t24 -60l50 25q-3 -40 -23 -60t-42.5 -21t-40 -6.5t-16.5 -20.5zM1282 842q-5 5 -13.5 15.5t-12 14.5t-10.5 11.5t-10 10.5l-8 8t-8.5 7.5t-8 5t-8.5 4.5q-7 3 -14.5 5t-20.5 2.5t-22 0.5h-32.5h-37.5q-126 0 -217 -43 +q16 30 36 46.5t54 29.5t65.5 36t46 36.5t50 55t43.5 50.5q12 -9 28 -31.5t32 -36.5t38 -13l12 1v-76l22 -1q247 95 371 190q28 21 50 39t42.5 37.5t33 31t29.5 34t24 31t24.5 37t23 38t27 47.5t29.5 53l7 9q-2 -53 -43 -139q-79 -165 -205 -264t-306 -142q-14 -3 -42 -7.5 +t-50 -9.5t-39 -14q3 -19 24.5 -46t21.5 -34q0 -11 -26 -30zM1061 -79q39 26 131.5 47.5t146.5 21.5q9 0 22.5 -15.5t28 -42.5t26 -50t24 -51t14.5 -33q-121 -45 -244 -45q-61 0 -125 11zM822 568l48 12l109 -177l-73 -48zM1323 51q3 -15 3 -16q0 -7 -17.5 -14.5t-46 -13 +t-54 -9.5t-53.5 -7.5t-32 -4.5l-7 43q21 2 60.5 8.5t72 10t60.5 3.5h14zM866 679l-96 -20l-6 17q10 1 32.5 7t34.5 6q19 0 35 -10zM1061 45h31l10 -83l-41 -12v95zM1950 1535v1v-1zM1950 1535l-1 -5l-2 -2l1 3zM1950 1535l1 1z" /> + <glyph glyph-name="_399" unicode="&#xf1a9;" +d="M1167 -50q-5 19 -24 5q-30 -22 -87 -39t-131 -17q-129 0 -193 49q-5 4 -13 4q-11 0 -26 -12q-7 -6 -7.5 -16t7.5 -20q34 -32 87.5 -46t102.5 -12.5t99 4.5q41 4 84.5 20.5t65 30t28.5 20.5q12 12 7 29zM1128 65q-19 47 -39 61q-23 15 -76 15q-47 0 -71 -10 +q-29 -12 -78 -56q-26 -24 -12 -44q9 -8 17.5 -4.5t31.5 23.5q3 2 10.5 8.5t10.5 8.5t10 7t11.5 7t12.5 5t15 4.5t16.5 2.5t20.5 1q27 0 44.5 -7.5t23 -14.5t13.5 -22q10 -17 12.5 -20t12.5 1q23 12 14 34zM1483 346q0 22 -5 44.5t-16.5 45t-34 36.5t-52.5 14 +q-33 0 -97 -41.5t-129 -83.5t-101 -42q-27 -1 -63.5 19t-76 49t-83.5 58t-100 49t-111 19q-115 -1 -197 -78.5t-84 -178.5q-2 -112 74 -164q29 -20 62.5 -28.5t103.5 -8.5q57 0 132 32.5t134 71t120 70.5t93 31q26 -1 65 -31.5t71.5 -67t68 -67.5t55.5 -32q35 -3 58.5 14 +t55.5 63q28 41 42.5 101t14.5 106zM1536 506q0 -164 -62 -304.5t-166 -236t-242.5 -149.5t-290.5 -54t-293 57.5t-247.5 157t-170.5 241.5t-64 302q0 89 19.5 172.5t49 145.5t70.5 118.5t78.5 94t78.5 69.5t64.5 46.5t42.5 24.5q14 8 51 26.5t54.5 28.5t48 30t60.5 44 +q36 28 58 72.5t30 125.5q129 -155 186 -193q44 -29 130 -68t129 -66q21 -13 39 -25t60.5 -46.5t76 -70.5t75 -95t69 -122t47 -148.5t19.5 -177.5z" /> + <glyph glyph-name="_400" unicode="&#xf1aa;" +d="M1070 463l-160 -160l-151 -152l-30 -30q-65 -64 -151.5 -87t-171.5 -2q-16 -70 -72 -115t-129 -45q-85 0 -145 60.5t-60 145.5q0 72 44.5 128t113.5 72q-22 86 1 173t88 152l12 12l151 -152l-11 -11q-37 -37 -37 -89t37 -90q37 -37 89 -37t89 37l30 30l151 152l161 160z +M729 1145l12 -12l-152 -152l-12 12q-37 37 -89 37t-89 -37t-37 -89.5t37 -89.5l29 -29l152 -152l160 -160l-151 -152l-161 160l-151 152l-30 30q-68 67 -90 159.5t5 179.5q-70 15 -115 71t-45 129q0 85 60 145.5t145 60.5q76 0 133.5 -49t69.5 -123q84 20 169.5 -3.5 +t149.5 -87.5zM1536 78q0 -85 -60 -145.5t-145 -60.5q-74 0 -131 47t-71 118q-86 -28 -179.5 -6t-161.5 90l-11 12l151 152l12 -12q37 -37 89 -37t89 37t37 89t-37 89l-30 30l-152 152l-160 160l152 152l160 -160l152 -152l29 -30q64 -64 87.5 -150.5t2.5 -171.5 +q76 -11 126.5 -68.5t50.5 -134.5zM1534 1202q0 -77 -51 -135t-127 -69q26 -85 3 -176.5t-90 -158.5l-12 -12l-151 152l12 12q37 37 37 89t-37 89t-89 37t-89 -37l-30 -30l-152 -152l-160 -160l-152 152l161 160l152 152l29 30q67 67 159 89.5t178 -3.5q11 75 68.5 126 +t135.5 51q85 0 145 -60.5t60 -145.5z" /> + <glyph glyph-name="f1ab" unicode="&#xf1ab;" +d="M654 458q-1 -3 -12.5 0.5t-31.5 11.5l-20 9q-44 20 -87 49q-7 5 -41 31.5t-38 28.5q-67 -103 -134 -181q-81 -95 -105 -110q-4 -2 -19.5 -4t-18.5 0q6 4 82 92q21 24 85.5 115t78.5 118q17 30 51 98.5t36 77.5q-8 1 -110 -33q-8 -2 -27.5 -7.5t-34.5 -9.5t-17 -5 +q-2 -2 -2 -10.5t-1 -9.5q-5 -10 -31 -15q-23 -7 -47 0q-18 4 -28 21q-4 6 -5 23q6 2 24.5 5t29.5 6q58 16 105 32q100 35 102 35q10 2 43 19.5t44 21.5q9 3 21.5 8t14.5 5.5t6 -0.5q2 -12 -1 -33q0 -2 -12.5 -27t-26.5 -53.5t-17 -33.5q-25 -50 -77 -131l64 -28 +q12 -6 74.5 -32t67.5 -28q4 -1 10.5 -25.5t4.5 -30.5zM449 944q3 -15 -4 -28q-12 -23 -50 -38q-30 -12 -60 -12q-26 3 -49 26q-14 15 -18 41l1 3q3 -3 19.5 -5t26.5 0t58 16q36 12 55 14q17 0 21 -17zM1147 815l63 -227l-139 42zM39 15l694 232v1032l-694 -233v-1031z +M1280 332l102 -31l-181 657l-100 31l-216 -536l102 -31l45 110l211 -65zM777 1294l573 -184v380zM1088 -29l158 -13l-54 -160l-40 66q-130 -83 -276 -108q-58 -12 -91 -12h-84q-79 0 -199.5 39t-183.5 85q-8 7 -8 16q0 8 5 13.5t13 5.5q4 0 18 -7.5t30.5 -16.5t20.5 -11 +q73 -37 159.5 -61.5t157.5 -24.5q95 0 167 14.5t157 50.5q15 7 30.5 15.5t34 19t28.5 16.5zM1536 1050v-1079l-774 246q-14 -6 -375 -127.5t-368 -121.5q-13 0 -18 13q0 1 -1 3v1078q3 9 4 10q5 6 20 11q107 36 149 50v384l558 -198q2 0 160.5 55t316 108.5t161.5 53.5 +q20 0 20 -21v-418z" /> + <glyph glyph-name="_402" unicode="&#xf1ac;" horiz-adv-x="1792" +d="M288 1152q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-128q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h128zM1664 989q58 -34 93 -93t35 -128v-768q0 -106 -75 -181t-181 -75h-864q-66 0 -113 47t-47 113v1536q0 40 28 68t68 28h672q40 0 88 -20t76 -48 +l152 -152q28 -28 48 -76t20 -88v-163zM928 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 512v128q0 14 -9 23 +t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128 +q14 0 23 9t9 23zM1184 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 256v128q0 14 -9 23t-23 9h-128 +q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1536 896v256h-160q-40 0 -68 28t-28 68v160h-640v-512h896z" /> + <glyph glyph-name="_403" unicode="&#xf1ad;" +d="M1344 1536q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280zM512 1248v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 992v-64q0 -14 9 -23t23 -9h64q14 0 23 9 +t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 736v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 480v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 160v64 +q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64 +q14 0 23 9t9 23zM384 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 -96v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9 +t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM896 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 928v64 +q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 160v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64 +q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9 +t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23z" /> + <glyph glyph-name="_404" unicode="&#xf1ae;" horiz-adv-x="1280" +d="M1188 988l-292 -292v-824q0 -46 -33 -79t-79 -33t-79 33t-33 79v384h-64v-384q0 -46 -33 -79t-79 -33t-79 33t-33 79v824l-292 292q-28 28 -28 68t28 68q29 28 68.5 28t67.5 -28l228 -228h368l228 228q28 28 68 28t68 -28q28 -29 28 -68.5t-28 -67.5zM864 1152 +q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> + <glyph glyph-name="uniF1B1" unicode="&#xf1b0;" horiz-adv-x="1664" +d="M780 1064q0 -60 -19 -113.5t-63 -92.5t-105 -39q-76 0 -138 57.5t-92 135.5t-30 151q0 60 19 113.5t63 92.5t105 39q77 0 138.5 -57.5t91.5 -135t30 -151.5zM438 581q0 -80 -42 -139t-119 -59q-76 0 -141.5 55.5t-100.5 133.5t-35 152q0 80 42 139.5t119 59.5 +q76 0 141.5 -55.5t100.5 -134t35 -152.5zM832 608q118 0 255 -97.5t229 -237t92 -254.5q0 -46 -17 -76.5t-48.5 -45t-64.5 -20t-76 -5.5q-68 0 -187.5 45t-182.5 45q-66 0 -192.5 -44.5t-200.5 -44.5q-183 0 -183 146q0 86 56 191.5t139.5 192.5t187.5 146t193 59zM1071 819 +q-61 0 -105 39t-63 92.5t-19 113.5q0 74 30 151.5t91.5 135t138.5 57.5q61 0 105 -39t63 -92.5t19 -113.5q0 -73 -30 -151t-92 -135.5t-138 -57.5zM1503 923q77 0 119 -59.5t42 -139.5q0 -74 -35 -152t-100.5 -133.5t-141.5 -55.5q-77 0 -119 59t-42 139q0 74 35 152.5 +t100.5 134t141.5 55.5z" /> + <glyph glyph-name="_406" unicode="&#xf1b1;" horiz-adv-x="768" +d="M704 1008q0 -145 -57 -243.5t-152 -135.5l45 -821q2 -26 -16 -45t-44 -19h-192q-26 0 -44 19t-16 45l45 821q-95 37 -152 135.5t-57 243.5q0 128 42.5 249.5t117.5 200t160 78.5t160 -78.5t117.5 -200t42.5 -249.5z" /> + <glyph glyph-name="_407" unicode="&#xf1b2;" horiz-adv-x="1792" +d="M896 -93l640 349v636l-640 -233v-752zM832 772l698 254l-698 254l-698 -254zM1664 1024v-768q0 -35 -18 -65t-49 -47l-704 -384q-28 -16 -61 -16t-61 16l-704 384q-31 17 -49 47t-18 65v768q0 40 23 73t61 47l704 256q22 8 44 8t44 -8l704 -256q38 -14 61 -47t23 -73z +" /> + <glyph glyph-name="_408" unicode="&#xf1b3;" horiz-adv-x="2304" +d="M640 -96l384 192v314l-384 -164v-342zM576 358l404 173l-404 173l-404 -173zM1664 -96l384 192v314l-384 -164v-342zM1600 358l404 173l-404 173l-404 -173zM1152 651l384 165v266l-384 -164v-267zM1088 1030l441 189l-441 189l-441 -189zM2176 512v-416q0 -36 -19 -67 +t-52 -47l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-4 2 -7 4q-2 -2 -7 -4l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-33 16 -52 47t-19 67v416q0 38 21.5 70t56.5 48l434 186v400q0 38 21.5 70t56.5 48l448 192q23 10 50 10t50 -10l448 -192q35 -16 56.5 -48t21.5 -70 +v-400l434 -186q36 -16 57 -48t21 -70z" /> + <glyph glyph-name="_409" unicode="&#xf1b4;" horiz-adv-x="2048" +d="M1848 1197h-511v-124h511v124zM1596 771q-90 0 -146 -52.5t-62 -142.5h408q-18 195 -200 195zM1612 186q63 0 122 32t76 87h221q-100 -307 -427 -307q-214 0 -340.5 132t-126.5 347q0 208 130.5 345.5t336.5 137.5q138 0 240.5 -68t153 -179t50.5 -248q0 -17 -2 -47h-658 +q0 -111 57.5 -171.5t166.5 -60.5zM277 236h296q205 0 205 167q0 180 -199 180h-302v-347zM277 773h281q78 0 123.5 36.5t45.5 113.5q0 144 -190 144h-260v-294zM0 1282h594q87 0 155 -14t126.5 -47.5t90 -96.5t31.5 -154q0 -181 -172 -263q114 -32 172 -115t58 -204 +q0 -75 -24.5 -136.5t-66 -103.5t-98.5 -71t-121 -42t-134 -13h-611v1260z" /> + <glyph glyph-name="_410" unicode="&#xf1b5;" +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM499 1041h-371v-787h382q117 0 197 57.5t80 170.5q0 158 -143 200q107 52 107 164q0 57 -19.5 96.5 +t-56.5 60.5t-79 29.5t-97 8.5zM477 723h-176v184h163q119 0 119 -90q0 -94 -106 -94zM486 388h-185v217h189q124 0 124 -113q0 -104 -128 -104zM1136 356q-68 0 -104 38t-36 107h411q1 10 1 30q0 132 -74.5 220.5t-203.5 88.5q-128 0 -210 -86t-82 -216q0 -135 79 -217 +t213 -82q205 0 267 191h-138q-11 -34 -47.5 -54t-75.5 -20zM1126 722q113 0 124 -122h-254q4 56 39 89t91 33zM964 988h319v-77h-319v77z" /> + <glyph glyph-name="_411" unicode="&#xf1b6;" horiz-adv-x="1792" +d="M1582 954q0 -101 -71.5 -172.5t-172.5 -71.5t-172.5 71.5t-71.5 172.5t71.5 172.5t172.5 71.5t172.5 -71.5t71.5 -172.5zM812 212q0 104 -73 177t-177 73q-27 0 -54 -6l104 -42q77 -31 109.5 -106.5t1.5 -151.5q-31 -77 -107 -109t-152 -1q-21 8 -62 24.5t-61 24.5 +q32 -60 91 -96.5t130 -36.5q104 0 177 73t73 177zM1642 953q0 126 -89.5 215.5t-215.5 89.5q-127 0 -216.5 -89.5t-89.5 -215.5q0 -127 89.5 -216t216.5 -89q126 0 215.5 89t89.5 216zM1792 953q0 -189 -133.5 -322t-321.5 -133l-437 -319q-12 -129 -109 -218t-229 -89 +q-121 0 -214 76t-118 192l-230 92v429l389 -157q79 48 173 48q13 0 35 -2l284 407q2 187 135.5 319t320.5 132q188 0 321.5 -133.5t133.5 -321.5z" /> + <glyph glyph-name="_412" unicode="&#xf1b7;" +d="M1242 889q0 80 -57 136.5t-137 56.5t-136.5 -57t-56.5 -136q0 -80 56.5 -136.5t136.5 -56.5t137 56.5t57 136.5zM632 301q0 -83 -58 -140.5t-140 -57.5q-56 0 -103 29t-72 77q52 -20 98 -40q60 -24 120 1.5t85 86.5q24 60 -1.5 120t-86.5 84l-82 33q22 5 42 5 +q82 0 140 -57.5t58 -140.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v153l172 -69q20 -92 93.5 -152t168.5 -60q104 0 181 70t87 173l345 252q150 0 255.5 105.5t105.5 254.5q0 150 -105.5 255.5t-255.5 105.5 +q-148 0 -253 -104.5t-107 -252.5l-225 -322q-9 1 -28 1q-75 0 -137 -37l-297 119v468q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5zM1289 887q0 -100 -71 -170.5t-171 -70.5t-170.5 70.5t-70.5 170.5t70.5 171t170.5 71q101 0 171.5 -70.5t70.5 -171.5z +" /> + <glyph glyph-name="_413" unicode="&#xf1b8;" horiz-adv-x="1792" +d="M836 367l-15 -368l-2 -22l-420 29q-36 3 -67 31.5t-47 65.5q-11 27 -14.5 55t4 65t12 55t21.5 64t19 53q78 -12 509 -28zM449 953l180 -379l-147 92q-63 -72 -111.5 -144.5t-72.5 -125t-39.5 -94.5t-18.5 -63l-4 -21l-190 357q-17 26 -18 56t6 47l8 18q35 63 114 188 +l-140 86zM1680 436l-188 -359q-12 -29 -36.5 -46.5t-43.5 -20.5l-18 -4q-71 -7 -219 -12l8 -164l-230 367l211 362l7 -173q170 -16 283 -5t170 33zM895 1360q-47 -63 -265 -435l-317 187l-19 12l225 356q20 31 60 45t80 10q24 -2 48.5 -12t42 -21t41.5 -33t36 -34.5 +t36 -39.5t32 -35zM1550 1053l212 -363q18 -37 12.5 -76t-27.5 -74q-13 -20 -33 -37t-38 -28t-48.5 -22t-47 -16t-51.5 -14t-46 -12q-34 72 -265 436l313 195zM1407 1279l142 83l-220 -373l-419 20l151 86q-34 89 -75 166t-75.5 123.5t-64.5 80t-47 46.5l-17 13l405 -1 +q31 3 58 -10.5t39 -28.5l11 -15q39 -61 112 -190z" /> + <glyph glyph-name="_414" unicode="&#xf1b9;" horiz-adv-x="2048" +d="M480 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM516 768h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5zM1888 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM2048 544v-384 +q0 -14 -9 -23t-23 -9h-96v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-1024v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h768q98 0 179 -63.5t104 -157.5 +l105 -419h28q93 0 158.5 -65.5t65.5 -158.5z" /> + <glyph glyph-name="_415" unicode="&#xf1ba;" horiz-adv-x="2048" +d="M1824 640q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-96v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-1024v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5 +t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h128q98 0 179 -63.5t104 -157.5l105 -419h28zM320 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM516 640h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5z +M1728 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47z" /> + <glyph glyph-name="_416" unicode="&#xf1bb;" +d="M1504 64q0 -26 -19 -45t-45 -19h-462q1 -17 6 -87.5t5 -108.5q0 -25 -18 -42.5t-43 -17.5h-320q-25 0 -43 17.5t-18 42.5q0 38 5 108.5t6 87.5h-462q-26 0 -45 19t-19 45t19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384 +q19 19 45 19t45 -19l384 -384q19 -19 19 -45t-19 -45t-45 -19h-197l402 -403q19 -19 19 -45t-19 -45t-45 -19h-229l402 -403q19 -19 19 -45z" /> + <glyph glyph-name="_417" unicode="&#xf1bc;" +d="M1127 326q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52q0 -20 13.5 -34.5t35.5 -14.5q5 0 37 8q132 27 243 27q226 0 397 -103q19 -11 33 -11q19 0 33 13.5t14 34.5zM1223 541q0 40 -35 61q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64 +q0 -25 17.5 -42.5t42.5 -17.5q7 0 37 8q122 33 251 33q279 0 488 -124q24 -13 38 -13q25 0 42.5 17.5t17.5 42.5zM1331 789q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37 +q159 0 309.5 -34t253.5 -95q21 -12 40 -12q29 0 50.5 20.5t21.5 51.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_418" unicode="&#xf1bd;" horiz-adv-x="1024" +d="M1024 1233l-303 -582l24 -31h279v-415h-507l-44 -30l-142 -273l-30 -30h-301v303l303 583l-24 30h-279v415h507l44 30l142 273l30 30h301v-303z" /> + <glyph glyph-name="_419" unicode="&#xf1be;" horiz-adv-x="2304" +d="M784 164l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17l-14 -523l14 -241q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23zM1080 193l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6l-10 -579q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11 +q11 0 20 9q9 7 9 20zM35 533l20 -128l-20 -126q-2 -9 -9 -9t-9 9l-17 126l17 128q2 9 9 9t9 -9zM121 612l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10l-23 202l23 207q0 9 9 9q8 0 10 -9zM401 159zM213 650l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11l-21 237l21 245 +q2 12 12 12q11 0 11 -12zM307 657l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13l-21 244l21 252q0 13 13 13q12 0 14 -13zM401 639l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5l-20 246l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15zM784 164zM495 785 +l21 -380l-21 -246q0 -7 -5 -12.5t-12 -5.5q-16 0 -18 18l-18 246l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5zM589 871l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19l-16 244l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5zM687 911l18 -506l-18 -242 +q-2 -21 -22 -21q-19 0 -21 21l-16 242l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5zM1079 169v0v0v0zM881 915l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18l-14 239l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18zM980 896l14 -492l-14 -236 +q0 -11 -8 -19t-19 -8t-19 8t-9 19l-12 236l12 492q1 12 9 20t19 8t18.5 -8t8.5 -20zM1192 404l-14 -231v0q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114l-6 117l12 636v3q2 15 12 24q9 7 20 7q8 0 15 -5q14 -8 16 -26zM2304 423q0 -117 -83 -199.5t-200 -82.5h-786 +q-13 2 -22 11t-9 22v899q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201z" /> + <glyph glyph-name="uniF1C0" unicode="&#xf1c0;" +d="M768 768q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 0q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127 +t443 -43zM768 384q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 1536q208 0 385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5 +t-103 128v128q0 69 103 128t280 93.5t385 34.5z" /> + <glyph glyph-name="uniF1C1" unicode="&#xf1c1;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M894 465q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38q-48 0 -115 20t-130 53q-221 -24 -392 -83q-153 -262 -242 -262q-15 0 -28 7l-24 12q-1 1 -6 5q-10 10 -6 36q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4q52 85 107 197 +q68 136 104 262q-24 82 -30.5 159.5t6.5 127.5q11 40 42 40h21h1q23 0 35 -15q18 -21 9 -68q-2 -6 -4 -8q1 -3 1 -8v-30q-2 -123 -14 -192q55 -164 146 -238zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM716 974q-15 -42 -2 -132q1 7 7 44q0 3 7 43q1 4 4 8 +q-1 1 -1 2q-1 2 -1 3q-1 22 -13 36q0 -1 -1 -2v-2zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83zM1238 329q-24 24 -140 24q76 -28 124 -28q14 0 18 1q0 1 -2 3z" /> + <glyph glyph-name="_422" unicode="&#xf1c2;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M233 768v-107h70l164 -661h159l128 485q7 20 10 46q2 16 2 24h4l3 -24q1 -3 3.5 -20t5.5 -26l128 -485h159l164 661h70v107h-300v-107h90l-99 -438q-5 -20 -7 -46l-2 -21h-4q0 3 -0.5 6.5t-1.5 8t-1 6.5q-1 5 -4 21t-5 25l-144 545h-114l-144 -545q-2 -9 -4.5 -24.5 +t-3.5 -21.5l-4 -21h-4l-2 21q-2 26 -7 46l-99 438h90v107h-300z" /> + <glyph glyph-name="_423" unicode="&#xf1c3;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M429 106v-106h281v106h-75l103 161q5 7 10 16.5t7.5 13.5t3.5 4h2q1 -4 5 -10q2 -4 4.5 -7.5t6 -8t6.5 -8.5l107 -161h-76v-106h291v106h-68l-192 273l195 282h67v107h-279v-107h74l-103 -159q-4 -7 -10 -16.5t-9 -13.5l-2 -3h-2q-1 4 -5 10q-6 11 -17 23l-106 159h76v107 +h-290v-107h68l189 -272l-194 -283h-68z" /> + <glyph glyph-name="_424" unicode="&#xf1c4;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M416 106v-106h327v106h-93v167h137q76 0 118 15q67 23 106.5 87t39.5 146q0 81 -37 141t-100 87q-48 19 -130 19h-368v-107h92v-555h-92zM769 386h-119v268h120q52 0 83 -18q56 -33 56 -115q0 -89 -62 -120q-31 -15 -78 -15z" /> + <glyph glyph-name="_425" unicode="&#xf1c5;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M1280 320v-320h-1024v192l192 192l128 -128l384 384zM448 512q-80 0 -136 56t-56 136t56 136t136 56t136 -56t56 -136t-56 -136t-136 -56z" /> + <glyph glyph-name="_426" unicode="&#xf1c6;" +d="M640 1152v128h-128v-128h128zM768 1024v128h-128v-128h128zM640 896v128h-128v-128h128zM768 768v128h-128v-128h128zM1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400 +v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-128v-128h-128v128h-512v-1536h1280zM781 593l107 -349q8 -27 8 -52q0 -83 -72.5 -137.5t-183.5 -54.5t-183.5 54.5t-72.5 137.5q0 25 8 52q21 63 120 396v128h128v-128h79 +q22 0 39 -13t23 -34zM640 128q53 0 90.5 19t37.5 45t-37.5 45t-90.5 19t-90.5 -19t-37.5 -45t37.5 -45t90.5 -19z" /> + <glyph glyph-name="_427" unicode="&#xf1c7;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M620 686q20 -8 20 -30v-544q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-166 167h-131q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h131l166 167q16 15 35 7zM1037 -3q31 0 50 24q129 159 129 363t-129 363q-16 21 -43 24t-47 -14q-21 -17 -23.5 -43.5t14.5 -47.5 +q100 -123 100 -282t-100 -282q-17 -21 -14.5 -47.5t23.5 -42.5q18 -15 40 -15zM826 145q27 0 47 20q87 93 87 219t-87 219q-18 19 -45 20t-46 -17t-20 -44.5t18 -46.5q52 -57 52 -131t-52 -131q-19 -20 -18 -46.5t20 -44.5q20 -17 44 -17z" /> + <glyph glyph-name="_428" unicode="&#xf1c8;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M768 768q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-384q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h384zM1260 766q20 -8 20 -30v-576q0 -22 -20 -30q-8 -2 -12 -2q-14 0 -23 9l-265 266v90l265 266q9 9 23 9q4 0 12 -2z" /> + <glyph glyph-name="_429" unicode="&#xf1c9;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M480 768q8 11 21 12.5t24 -6.5l51 -38q11 -8 12.5 -21t-6.5 -24l-182 -243l182 -243q8 -11 6.5 -24t-12.5 -21l-51 -38q-11 -8 -24 -6.5t-21 12.5l-226 301q-14 19 0 38zM1282 467q14 -19 0 -38l-226 -301q-8 -11 -21 -12.5t-24 6.5l-51 38q-11 8 -12.5 21t6.5 24l182 243 +l-182 243q-8 11 -6.5 24t12.5 21l51 38q11 8 24 6.5t21 -12.5zM662 6q-13 2 -20.5 13t-5.5 24l138 831q2 13 13 20.5t24 5.5l63 -10q13 -2 20.5 -13t5.5 -24l-138 -831q-2 -13 -13 -20.5t-24 -5.5z" /> + <glyph glyph-name="_430" unicode="&#xf1ca;" +d="M1497 709v-198q-101 -23 -198 -23q-65 -136 -165.5 -271t-181.5 -215.5t-128 -106.5q-80 -45 -162 3q-28 17 -60.5 43.5t-85 83.5t-102.5 128.5t-107.5 184t-105.5 244t-91.5 314.5t-70.5 390h283q26 -218 70 -398.5t104.5 -317t121.5 -235.5t140 -195q169 169 287 406 +q-142 72 -223 220t-81 333q0 192 104 314.5t284 122.5q178 0 273 -105.5t95 -297.5q0 -159 -58 -286q-7 -1 -19.5 -3t-46 -2t-63 6t-62 25.5t-50.5 51.5q31 103 31 184q0 87 -29 132t-79 45q-53 0 -85 -49.5t-32 -140.5q0 -186 105 -293.5t267 -107.5q62 0 121 14z" /> + <glyph glyph-name="_431" unicode="&#xf1cb;" horiz-adv-x="1792" +d="M216 367l603 -402v359l-334 223zM154 511l193 129l-193 129v-258zM973 -35l603 402l-269 180l-334 -223v-359zM896 458l272 182l-272 182l-272 -182zM485 733l334 223v359l-603 -402zM1445 640l193 -129v258zM1307 733l269 180l-603 402v-359zM1792 913v-546 +q0 -41 -34 -64l-819 -546q-21 -13 -43 -13t-43 13l-819 546q-34 23 -34 64v546q0 41 34 64l819 546q21 13 43 13t43 -13l819 -546q34 -23 34 -64z" /> + <glyph glyph-name="_432" unicode="&#xf1cc;" horiz-adv-x="2048" +d="M1800 764q111 -46 179.5 -145.5t68.5 -221.5q0 -164 -118 -280.5t-285 -116.5q-4 0 -11.5 0.5t-10.5 0.5h-1209h-1h-2h-5q-170 10 -288 125.5t-118 280.5q0 110 55 203t147 147q-12 39 -12 82q0 115 82 196t199 81q95 0 172 -58q75 154 222.5 248t326.5 94 +q166 0 306 -80.5t221.5 -218.5t81.5 -301q0 -6 -0.5 -18t-0.5 -18zM468 498q0 -122 84 -193t208 -71q137 0 240 99q-16 20 -47.5 56.5t-43.5 50.5q-67 -65 -144 -65q-55 0 -93.5 33.5t-38.5 87.5q0 53 38.5 87t91.5 34q44 0 84.5 -21t73 -55t65 -75t69 -82t77 -75t97 -55 +t121.5 -21q121 0 204.5 71.5t83.5 190.5q0 121 -84 192t-207 71q-143 0 -241 -97l93 -108q66 64 142 64q52 0 92 -33t40 -84q0 -57 -37 -91.5t-94 -34.5q-43 0 -82.5 21t-72 55t-65.5 75t-69.5 82t-77.5 75t-96.5 55t-118.5 21q-122 0 -207 -70.5t-85 -189.5z" /> + <glyph glyph-name="_433" unicode="&#xf1cd;" horiz-adv-x="1792" +d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 1408q-190 0 -361 -90l194 -194q82 28 167 28t167 -28l194 194q-171 90 -361 90zM218 279l194 194 +q-28 82 -28 167t28 167l-194 194q-90 -171 -90 -361t90 -361zM896 -128q190 0 361 90l-194 194q-82 -28 -167 -28t-167 28l-194 -194q171 -90 361 -90zM896 256q159 0 271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5 +t271.5 -112.5zM1380 473l194 -194q90 171 90 361t-90 361l-194 -194q28 -82 28 -167t-28 -167z" /> + <glyph glyph-name="_434" unicode="&#xf1ce;" horiz-adv-x="1792" +d="M1760 640q0 -176 -68.5 -336t-184 -275.5t-275.5 -184t-336 -68.5t-336 68.5t-275.5 184t-184 275.5t-68.5 336q0 213 97 398.5t265 305.5t374 151v-228q-221 -45 -366.5 -221t-145.5 -406q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5 +t136.5 204t51 248.5q0 230 -145.5 406t-366.5 221v228q206 -31 374 -151t265 -305.5t97 -398.5z" /> + <glyph glyph-name="uniF1D0" unicode="&#xf1d0;" horiz-adv-x="1792" +d="M19 662q8 217 116 406t305 318h5q0 -1 -1 -3q-8 -8 -28 -33.5t-52 -76.5t-60 -110.5t-44.5 -135.5t-14 -150.5t39 -157.5t108.5 -154q50 -50 102 -69.5t90.5 -11.5t69.5 23.5t47 32.5l16 16q39 51 53 116.5t6.5 122.5t-21 107t-26.5 80l-14 29q-10 25 -30.5 49.5t-43 41 +t-43.5 29.5t-35 19l-13 6l104 115q39 -17 78 -52t59 -61l19 -27q1 48 -18.5 103.5t-40.5 87.5l-20 31l161 183l160 -181q-33 -46 -52.5 -102.5t-22.5 -90.5l-4 -33q22 37 61.5 72.5t67.5 52.5l28 17l103 -115q-44 -14 -85 -50t-60 -65l-19 -29q-31 -56 -48 -133.5t-7 -170 +t57 -156.5q33 -45 77.5 -60.5t85 -5.5t76 26.5t57.5 33.5l21 16q60 53 96.5 115t48.5 121.5t10 121.5t-18 118t-37 107.5t-45.5 93t-45 72t-34.5 47.5l-13 17q-14 13 -7 13l10 -3q40 -29 62.5 -46t62 -50t64 -58t58.5 -65t55.5 -77t45.5 -88t38 -103t23.5 -117t10.5 -136 +q3 -259 -108 -465t-312 -321t-456 -115q-185 0 -351 74t-283.5 198t-184 293t-60.5 353z" /> + <glyph glyph-name="uniF1D1" unicode="&#xf1d1;" horiz-adv-x="1792" +d="M874 -102v-66q-208 6 -385 109.5t-283 275.5l58 34q29 -49 73 -99l65 57q148 -168 368 -212l-17 -86q65 -12 121 -13zM276 428l-83 -28q22 -60 49 -112l-57 -33q-98 180 -98 385t98 385l57 -33q-30 -56 -49 -112l82 -28q-35 -100 -35 -212q0 -109 36 -212zM1528 251 +l58 -34q-106 -172 -283 -275.5t-385 -109.5v66q56 1 121 13l-17 86q220 44 368 212l65 -57q44 50 73 99zM1377 805l-233 -80q14 -42 14 -85t-14 -85l232 -80q-31 -92 -98 -169l-185 162q-57 -67 -147 -85l48 -241q-52 -10 -98 -10t-98 10l48 241q-90 18 -147 85l-185 -162 +q-67 77 -98 169l232 80q-14 42 -14 85t14 85l-233 80q33 93 99 169l185 -162q59 68 147 86l-48 240q44 10 98 10t98 -10l-48 -240q88 -18 147 -86l185 162q66 -76 99 -169zM874 1448v-66q-65 -2 -121 -13l17 -86q-220 -42 -368 -211l-65 56q-38 -42 -73 -98l-57 33 +q106 172 282 275.5t385 109.5zM1705 640q0 -205 -98 -385l-57 33q27 52 49 112l-83 28q36 103 36 212q0 112 -35 212l82 28q-19 56 -49 112l57 33q98 -180 98 -385zM1585 1063l-57 -33q-35 56 -73 98l-65 -56q-148 169 -368 211l17 86q-56 11 -121 13v66q209 -6 385 -109.5 +t282 -275.5zM1748 640q0 173 -67.5 331t-181.5 272t-272 181.5t-331 67.5t-331 -67.5t-272 -181.5t-181.5 -272t-67.5 -331t67.5 -331t181.5 -272t272 -181.5t331 -67.5t331 67.5t272 181.5t181.5 272t67.5 331zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71 +t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF1D2" unicode="&#xf1d2;" +d="M582 228q0 -66 -93 -66q-107 0 -107 63q0 64 98 64q102 0 102 -61zM546 694q0 -85 -74 -85q-77 0 -77 84q0 90 77 90q36 0 55 -25.5t19 -63.5zM712 769v125q-78 -29 -135 -29q-50 29 -110 29q-86 0 -145 -57t-59 -143q0 -50 29.5 -102t73.5 -67v-3q-38 -17 -38 -85 +q0 -53 41 -77v-3q-113 -37 -113 -139q0 -45 20 -78.5t54 -51t72 -25.5t81 -8q224 0 224 188q0 67 -48 99t-126 46q-27 5 -51.5 20.5t-24.5 39.5q0 44 49 52q77 15 122 70t45 134q0 24 -10 52q37 9 49 13zM771 350h137q-2 27 -2 82v387q0 46 2 69h-137q3 -23 3 -71v-392 +q0 -50 -3 -75zM1280 366v121q-30 -21 -68 -21q-53 0 -53 82v225h52q9 0 26.5 -1t26.5 -1v117h-105q0 82 3 102h-140q4 -24 4 -55v-47h-60v-117q36 3 37 3q3 0 11 -0.5t12 -0.5v-2h-2v-217q0 -37 2.5 -64t11.5 -56.5t24.5 -48.5t43.5 -31t66 -12q64 0 108 24zM924 1072 +q0 36 -24 63.5t-60 27.5t-60.5 -27t-24.5 -64q0 -36 25 -62.5t60 -26.5t59.5 27t24.5 62zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_438" unicode="&#xf1d3;" horiz-adv-x="1792" +d="M595 22q0 100 -165 100q-158 0 -158 -104q0 -101 172 -101q151 0 151 105zM536 777q0 61 -30 102t-89 41q-124 0 -124 -145q0 -135 124 -135q119 0 119 137zM805 1101v-202q-36 -12 -79 -22q16 -43 16 -84q0 -127 -73 -216.5t-197 -112.5q-40 -8 -59.5 -27t-19.5 -58 +q0 -31 22.5 -51.5t58 -32t78.5 -22t86 -25.5t78.5 -37.5t58 -64t22.5 -98.5q0 -304 -363 -304q-69 0 -130 12.5t-116 41t-87.5 82t-32.5 127.5q0 165 182 225v4q-67 41 -67 126q0 109 63 137v4q-72 24 -119.5 108.5t-47.5 165.5q0 139 95 231.5t235 92.5q96 0 178 -47 +q98 0 218 47zM1123 220h-222q4 45 4 134v609q0 94 -4 128h222q-4 -33 -4 -124v-613q0 -89 4 -134zM1724 442v-196q-71 -39 -174 -39q-62 0 -107 20t-70 50t-39.5 78t-18.5 92t-4 103v351h2v4q-7 0 -19 1t-18 1q-21 0 -59 -6v190h96v76q0 54 -6 89h227q-6 -41 -6 -165h171 +v-190q-15 0 -43.5 2t-42.5 2h-85v-365q0 -131 87 -131q61 0 109 33zM1148 1389q0 -58 -39 -101.5t-96 -43.5q-58 0 -98 43.5t-40 101.5q0 59 39.5 103t98.5 44q58 0 96.5 -44.5t38.5 -102.5z" /> + <glyph glyph-name="_439" unicode="&#xf1d4;" +d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="uniF1D5" unicode="&#xf1d5;" horiz-adv-x="1280" +d="M842 964q0 -80 -57 -136.5t-136 -56.5q-60 0 -111 35q-62 -67 -115 -146q-247 -371 -202 -859q1 -22 -12.5 -38.5t-34.5 -18.5h-5q-20 0 -35 13.5t-17 33.5q-14 126 -3.5 247.5t29.5 217t54 186t69 155.5t74 125q61 90 132 165q-16 35 -16 77q0 80 56.5 136.5t136.5 56.5 +t136.5 -56.5t56.5 -136.5zM1223 953q0 -158 -78 -292t-212.5 -212t-292.5 -78q-64 0 -131 14q-21 5 -32.5 23.5t-6.5 39.5q5 20 23 31.5t39 7.5q51 -13 108 -13q97 0 186 38t153 102t102 153t38 186t-38 186t-102 153t-153 102t-186 38t-186 -38t-153 -102t-102 -153 +t-38 -186q0 -114 52 -218q10 -20 3.5 -40t-25.5 -30t-39.5 -3t-30.5 26q-64 123 -64 265q0 119 46.5 227t124.5 186t186 124t226 46q158 0 292.5 -78t212.5 -212.5t78 -292.5z" /> + <glyph glyph-name="uniF1D6" unicode="&#xf1d6;" horiz-adv-x="1792" +d="M270 730q-8 19 -8 52q0 20 11 49t24 45q-1 22 7.5 53t22.5 43q0 139 92.5 288.5t217.5 209.5q139 66 324 66q133 0 266 -55q49 -21 90 -48t71 -56t55 -68t42 -74t32.5 -84.5t25.5 -89.5t22 -98l1 -5q55 -83 55 -150q0 -14 -9 -40t-9 -38q0 -1 1.5 -3.5t3.5 -5t2 -3.5 +q77 -114 120.5 -214.5t43.5 -208.5q0 -43 -19.5 -100t-55.5 -57q-9 0 -19.5 7.5t-19 17.5t-19 26t-16 26.5t-13.5 26t-9 17.5q-1 1 -3 1l-5 -4q-59 -154 -132 -223q20 -20 61.5 -38.5t69 -41.5t35.5 -65q-2 -4 -4 -16t-7 -18q-64 -97 -302 -97q-53 0 -110.5 9t-98 20 +t-104.5 30q-15 5 -23 7q-14 4 -46 4.5t-40 1.5q-41 -45 -127.5 -65t-168.5 -20q-35 0 -69 1.5t-93 9t-101 20.5t-74.5 40t-32.5 64q0 40 10 59.5t41 48.5q11 2 40.5 13t49.5 12q4 0 14 2q2 2 2 4l-2 3q-48 11 -108 105.5t-73 156.5l-5 3q-4 0 -12 -20q-18 -41 -54.5 -74.5 +t-77.5 -37.5h-1q-4 0 -6 4.5t-5 5.5q-23 54 -23 100q0 275 252 466z" /> + <glyph glyph-name="uniF1D7" unicode="&#xf1d7;" horiz-adv-x="2048" +d="M580 1075q0 41 -25 66t-66 25q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 66 24.5t25 65.5zM1323 568q0 28 -25.5 50t-65.5 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q40 0 65.5 22t25.5 51zM1087 1075q0 41 -24.5 66t-65.5 25 +q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 65.5 24.5t24.5 65.5zM1722 568q0 28 -26 50t-65 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q39 0 65 22t26 51zM1456 965q-31 4 -70 4q-169 0 -311 -77t-223.5 -208.5t-81.5 -287.5 +q0 -78 23 -152q-35 -3 -68 -3q-26 0 -50 1.5t-55 6.5t-44.5 7t-54.5 10.5t-50 10.5l-253 -127l72 218q-290 203 -290 490q0 169 97.5 311t264 223.5t363.5 81.5q176 0 332.5 -66t262 -182.5t136.5 -260.5zM2048 404q0 -117 -68.5 -223.5t-185.5 -193.5l55 -181l-199 109 +q-150 -37 -218 -37q-169 0 -311 70.5t-223.5 191.5t-81.5 264t81.5 264t223.5 191.5t311 70.5q161 0 303 -70.5t227.5 -192t85.5 -263.5z" /> + <glyph glyph-name="_443" unicode="&#xf1d8;" horiz-adv-x="1792" +d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-453 185l-242 -295q-18 -23 -49 -23q-13 0 -22 4q-19 7 -30.5 23.5t-11.5 36.5v349l864 1059l-1069 -925l-395 162q-37 14 -40 55q-2 40 32 59l1664 960q15 9 32 9q20 0 36 -11z" /> + <glyph glyph-name="_444" unicode="&#xf1d9;" horiz-adv-x="1792" +d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-527 215l-298 -327q-18 -21 -47 -21q-14 0 -23 4q-19 7 -30 23.5t-11 36.5v452l-472 193q-37 14 -40 55q-3 39 32 59l1664 960q35 21 68 -2zM1422 26l221 1323l-1434 -827l336 -137 +l863 639l-478 -797z" /> + <glyph glyph-name="_445" unicode="&#xf1da;" +d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5 +t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298zM896 928v-448q0 -14 -9 -23 +t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23z" /> + <glyph glyph-name="_446" unicode="&#xf1db;" +d="M768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_447" unicode="&#xf1dc;" horiz-adv-x="1792" +d="M1682 -128q-44 0 -132.5 3.5t-133.5 3.5q-44 0 -132 -3.5t-132 -3.5q-24 0 -37 20.5t-13 45.5q0 31 17 46t39 17t51 7t45 15q33 21 33 140l-1 391q0 21 -1 31q-13 4 -50 4h-675q-38 0 -51 -4q-1 -10 -1 -31l-1 -371q0 -142 37 -164q16 -10 48 -13t57 -3.5t45 -15 +t20 -45.5q0 -26 -12.5 -48t-36.5 -22q-47 0 -139.5 3.5t-138.5 3.5q-43 0 -128 -3.5t-127 -3.5q-23 0 -35.5 21t-12.5 45q0 30 15.5 45t36 17.5t47.5 7.5t42 15q33 23 33 143l-1 57v813q0 3 0.5 26t0 36.5t-1.5 38.5t-3.5 42t-6.5 36.5t-11 31.5t-16 18q-15 10 -45 12t-53 2 +t-41 14t-18 45q0 26 12 48t36 22q46 0 138.5 -3.5t138.5 -3.5q42 0 126.5 3.5t126.5 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17 -43.5t-38.5 -14.5t-49.5 -4t-43 -13q-35 -21 -35 -160l1 -320q0 -21 1 -32q13 -3 39 -3h699q25 0 38 3q1 11 1 32l1 320q0 139 -35 160 +q-18 11 -58.5 12.5t-66 13t-25.5 49.5q0 26 12.5 48t37.5 22q44 0 132 -3.5t132 -3.5q43 0 129 3.5t129 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17.5 -44t-40 -14.5t-51.5 -3t-44 -12.5q-35 -23 -35 -161l1 -943q0 -119 34 -140q16 -10 46 -13.5t53.5 -4.5t41.5 -15.5t18 -44.5 +q0 -26 -12 -48t-36 -22z" /> + <glyph glyph-name="_448" unicode="&#xf1dd;" horiz-adv-x="1280" +d="M1278 1347v-73q0 -29 -18.5 -61t-42.5 -32q-50 0 -54 -1q-26 -6 -32 -31q-3 -11 -3 -64v-1152q0 -25 -18 -43t-43 -18h-108q-25 0 -43 18t-18 43v1218h-143v-1218q0 -25 -17.5 -43t-43.5 -18h-108q-26 0 -43.5 18t-17.5 43v496q-147 12 -245 59q-126 58 -192 179 +q-64 117 -64 259q0 166 88 286q88 118 209 159q111 37 417 37h479q25 0 43 -18t18 -43z" /> + <glyph glyph-name="_449" unicode="&#xf1de;" +d="M352 128v-128h-352v128h352zM704 256q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM864 640v-128h-864v128h864zM224 1152v-128h-224v128h224zM1536 128v-128h-736v128h736zM576 1280q26 0 45 -19t19 -45v-256 +q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1216 768q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1536 640v-128h-224v128h224zM1536 1152v-128h-864v128h864z" /> + <glyph glyph-name="uniF1E0" unicode="&#xf1e0;" +d="M1216 512q133 0 226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5t-226.5 93.5t-93.5 226.5q0 12 2 34l-360 180q-92 -86 -218 -86q-133 0 -226.5 93.5t-93.5 226.5t93.5 226.5t226.5 93.5q126 0 218 -86l360 180q-2 22 -2 34q0 133 93.5 226.5t226.5 93.5 +t226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5q-126 0 -218 86l-360 -180q2 -22 2 -34t-2 -34l360 -180q92 86 218 86z" /> + <glyph glyph-name="_451" unicode="&#xf1e1;" +d="M1280 341q0 88 -62.5 151t-150.5 63q-84 0 -145 -58l-241 120q2 16 2 23t-2 23l241 120q61 -58 145 -58q88 0 150.5 63t62.5 151t-62.5 150.5t-150.5 62.5t-151 -62.5t-63 -150.5q0 -7 2 -23l-241 -120q-62 57 -145 57q-88 0 -150.5 -62.5t-62.5 -150.5t62.5 -150.5 +t150.5 -62.5q83 0 145 57l241 -120q-2 -16 -2 -23q0 -88 63 -150.5t151 -62.5t150.5 62.5t62.5 150.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_452" unicode="&#xf1e2;" horiz-adv-x="1792" +d="M571 947q-10 25 -34 35t-49 0q-108 -44 -191 -127t-127 -191q-10 -25 0 -49t35 -34q13 -5 24 -5q42 0 60 40q34 84 98.5 148.5t148.5 98.5q25 11 35 35t0 49zM1513 1303l46 -46l-244 -243l68 -68q19 -19 19 -45.5t-19 -45.5l-64 -64q89 -161 89 -343q0 -143 -55.5 -273.5 +t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5q182 0 343 -89l64 64q19 19 45.5 19t45.5 -19l68 -68zM1521 1359q-10 -10 -22 -10q-13 0 -23 10l-91 90q-9 10 -9 23t9 23q10 9 23 9t23 -9l90 -91 +q10 -9 10 -22.5t-10 -22.5zM1751 1129q-11 -9 -23 -9t-23 9l-90 91q-10 9 -10 22.5t10 22.5q9 10 22.5 10t22.5 -10l91 -90q9 -10 9 -23t-9 -23zM1792 1312q0 -14 -9 -23t-23 -9h-96q-14 0 -23 9t-9 23t9 23t23 9h96q14 0 23 -9t9 -23zM1600 1504v-96q0 -14 -9 -23t-23 -9 +t-23 9t-9 23v96q0 14 9 23t23 9t23 -9t9 -23zM1751 1449l-91 -90q-10 -10 -22 -10q-13 0 -23 10q-10 9 -10 22.5t10 22.5l90 91q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" /> + <glyph glyph-name="_453" unicode="&#xf1e3;" horiz-adv-x="1792" +d="M609 720l287 208l287 -208l-109 -336h-355zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM1515 186q149 203 149 454v3l-102 -89l-240 224l63 323 +l134 -12q-150 206 -389 282l53 -124l-287 -159l-287 159l53 124q-239 -76 -389 -282l135 12l62 -323l-240 -224l-102 89v-3q0 -251 149 -454l30 132l326 -40l139 -298l-116 -69q117 -39 240 -39t240 39l-116 69l139 298l326 40z" /> + <glyph glyph-name="_454" unicode="&#xf1e4;" horiz-adv-x="1792" +d="M448 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM256 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM832 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 +v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM66 768q-28 0 -47 19t-19 46v129h514v-129q0 -27 -19 -46t-46 -19h-383zM1216 224v-192q0 -14 -9 -23t-23 -9h-192 +q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1600 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23 +zM1408 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1016v-13h-514v10q0 104 -382 102q-382 -1 -382 -102v-10h-514v13q0 17 8.5 43t34 64t65.5 75.5t110.5 76t160 67.5t224 47.5t293.5 18.5t293 -18.5t224 -47.5 +t160.5 -67.5t110.5 -76t65.5 -75.5t34 -64t8.5 -43zM1792 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 962v-129q0 -27 -19 -46t-46 -19h-384q-27 0 -46 19t-19 46v129h514z" /> + <glyph glyph-name="_455" unicode="&#xf1e5;" horiz-adv-x="1792" +d="M704 1216v-768q0 -26 -19 -45t-45 -19v-576q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v512l249 873q7 23 31 23h424zM1024 1216v-704h-256v704h256zM1792 320v-512q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v576q-26 0 -45 19t-19 45v768h424q24 0 31 -23z +M736 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23zM1408 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23z" /> + <glyph glyph-name="_456" unicode="&#xf1e6;" horiz-adv-x="1792" +d="M1755 1083q37 -38 37 -90.5t-37 -90.5l-401 -400l150 -150l-160 -160q-163 -163 -389.5 -186.5t-411.5 100.5l-362 -362h-181v181l362 362q-124 185 -100.5 411.5t186.5 389.5l160 160l150 -150l400 401q38 37 91 37t90 -37t37 -90.5t-37 -90.5l-400 -401l234 -234 +l401 400q38 37 91 37t90 -37z" /> + <glyph glyph-name="_457" unicode="&#xf1e7;" horiz-adv-x="1792" +d="M873 796q0 -83 -63.5 -142.5t-152.5 -59.5t-152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59t152.5 -59t63.5 -143zM1375 796q0 -83 -63 -142.5t-153 -59.5q-89 0 -152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59q90 0 153 -59t63 -143zM1600 616v667q0 87 -32 123.5 +t-111 36.5h-1112q-83 0 -112.5 -34t-29.5 -126v-673q43 -23 88.5 -40t81 -28t81 -18.5t71 -11t70 -4t58.5 -0.5t56.5 2t44.5 2q68 1 95 -27q6 -6 10 -9q26 -25 61 -51q7 91 118 87q5 0 36.5 -1.5t43 -2t45.5 -1t53 1t54.5 4.5t61 8.5t62 13.5t67 19.5t67.5 27t72 34.5z +M1763 621q-121 -149 -372 -252q84 -285 -23 -465q-66 -113 -183 -148q-104 -32 -182 15q-86 51 -82 164l-1 326v1q-8 2 -24.5 6t-23.5 5l-1 -338q4 -114 -83 -164q-79 -47 -183 -15q-117 36 -182 150q-105 180 -22 463q-251 103 -372 252q-25 37 -4 63t60 -1q4 -2 11.5 -7 +t10.5 -8v694q0 72 47 123t114 51h1257q67 0 114 -51t47 -123v-694l21 15q39 27 60 1t-4 -63z" /> + <glyph glyph-name="_458" unicode="&#xf1e8;" horiz-adv-x="1792" +d="M896 1102v-434h-145v434h145zM1294 1102v-434h-145v434h145zM1294 342l253 254v795h-1194v-1049h326v-217l217 217h398zM1692 1536v-1013l-434 -434h-326l-217 -217h-217v217h-398v1158l109 289h1483z" /> + <glyph glyph-name="_459" unicode="&#xf1e9;" +d="M773 217v-127q-1 -292 -6 -305q-12 -32 -51 -40q-54 -9 -181.5 38t-162.5 89q-13 15 -17 36q-1 12 4 26q4 10 34 47t181 216q1 0 60 70q15 19 39.5 24.5t49.5 -3.5q24 -10 37.5 -29t12.5 -42zM624 468q-3 -55 -52 -70l-120 -39q-275 -88 -292 -88q-35 2 -54 36 +q-12 25 -17 75q-8 76 1 166.5t30 124.5t56 32q13 0 202 -77q71 -29 115 -47l84 -34q23 -9 35.5 -30.5t11.5 -48.5zM1450 171q-7 -54 -91.5 -161t-135.5 -127q-37 -14 -63 7q-14 10 -184 287l-47 77q-14 21 -11.5 46t19.5 46q35 43 83 26q1 -1 119 -40q203 -66 242 -79.5 +t47 -20.5q28 -22 22 -61zM778 803q5 -102 -54 -122q-58 -17 -114 71l-378 598q-8 35 19 62q41 43 207.5 89.5t224.5 31.5q40 -10 49 -45q3 -18 22 -305.5t24 -379.5zM1440 695q3 -39 -26 -59q-15 -10 -329 -86q-67 -15 -91 -23l1 2q-23 -6 -46 4t-37 32q-30 47 0 87 +q1 1 75 102q125 171 150 204t34 39q28 19 65 2q48 -23 123 -133.5t81 -167.5v-3z" /> + <glyph glyph-name="_460" unicode="&#xf1ea;" horiz-adv-x="2048" +d="M1024 1024h-384v-384h384v384zM1152 384v-128h-640v128h640zM1152 1152v-640h-640v640h640zM1792 384v-128h-512v128h512zM1792 640v-128h-512v128h512zM1792 896v-128h-512v128h512zM1792 1152v-128h-512v128h512zM256 192v960h-128v-960q0 -26 19 -45t45 -19t45 19 +t19 45zM1920 192v1088h-1536v-1088q0 -33 -11 -64h1483q26 0 45 19t19 45zM2048 1408v-1216q0 -80 -56 -136t-136 -56h-1664q-80 0 -136 56t-56 136v1088h256v128h1792z" /> + <glyph glyph-name="_461" unicode="&#xf1eb;" horiz-adv-x="2048" +d="M1024 13q-20 0 -93 73.5t-73 93.5q0 32 62.5 54t103.5 22t103.5 -22t62.5 -54q0 -20 -73 -93.5t-93 -73.5zM1294 284q-2 0 -40 25t-101.5 50t-128.5 25t-128.5 -25t-101 -50t-40.5 -25q-18 0 -93.5 75t-75.5 93q0 13 10 23q78 77 196 121t233 44t233 -44t196 -121 +q10 -10 10 -23q0 -18 -75.5 -93t-93.5 -75zM1567 556q-11 0 -23 8q-136 105 -252 154.5t-268 49.5q-85 0 -170.5 -22t-149 -53t-113.5 -62t-79 -53t-31 -22q-17 0 -92 75t-75 93q0 12 10 22q132 132 320 205t380 73t380 -73t320 -205q10 -10 10 -22q0 -18 -75 -93t-92 -75z +M1838 827q-11 0 -22 9q-179 157 -371.5 236.5t-420.5 79.5t-420.5 -79.5t-371.5 -236.5q-11 -9 -22 -9q-17 0 -92.5 75t-75.5 93q0 13 10 23q187 186 445 288t527 102t527 -102t445 -288q10 -10 10 -23q0 -18 -75.5 -93t-92.5 -75z" /> + <glyph glyph-name="_462" unicode="&#xf1ec;" horiz-adv-x="1792" +d="M384 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 +t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5 +t37.5 90.5zM384 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 768q0 53 -37.5 90.5t-90.5 37.5 +t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1536 0v384q0 52 -38 90t-90 38t-90 -38t-38 -90v-384q0 -52 38 -90t90 -38t90 38t38 90zM1152 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z +M1536 1088v256q0 26 -19 45t-45 19h-1280q-26 0 -45 -19t-19 -45v-256q0 -26 19 -45t45 -19h1280q26 0 45 19t19 45zM1536 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1408v-1536q0 -52 -38 -90t-90 -38 +h-1408q-52 0 -90 38t-38 90v1536q0 52 38 90t90 38h1408q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_463" unicode="&#xf1ed;" +d="M1519 890q18 -84 -4 -204q-87 -444 -565 -444h-44q-25 0 -44 -16.5t-24 -42.5l-4 -19l-55 -346l-2 -15q-5 -26 -24.5 -42.5t-44.5 -16.5h-251q-21 0 -33 15t-9 36q9 56 26.5 168t26.5 168t27 167.5t27 167.5q5 37 43 37h131q133 -2 236 21q175 39 287 144q102 95 155 246 +q24 70 35 133q1 6 2.5 7.5t3.5 1t6 -3.5q79 -59 98 -162zM1347 1172q0 -107 -46 -236q-80 -233 -302 -315q-113 -40 -252 -42q0 -1 -90 -1l-90 1q-100 0 -118 -96q-2 -8 -85 -530q-1 -10 -12 -10h-295q-22 0 -36.5 16.5t-11.5 38.5l232 1471q5 29 27.5 48t51.5 19h598 +q34 0 97.5 -13t111.5 -32q107 -41 163.5 -123t56.5 -196z" /> + <glyph glyph-name="_464" unicode="&#xf1ee;" horiz-adv-x="1792" +d="M441 864q33 0 52 -26q266 -364 362 -774h-446q-127 441 -367 749q-12 16 -3 33.5t29 17.5h373zM1000 507q-49 -199 -125 -393q-79 310 -256 594q40 221 44 449q211 -340 337 -650zM1099 1216q235 -324 384.5 -698.5t184.5 -773.5h-451q-41 665 -553 1472h435zM1792 640 +q0 -424 -101 -812q-67 560 -359 1083q-25 301 -106 584q-4 16 5.5 28.5t25.5 12.5h359q21 0 38.5 -13t22.5 -33q115 -409 115 -850z" /> + <glyph glyph-name="uniF1F0" unicode="&#xf1f0;" horiz-adv-x="2304" +d="M1975 546h-138q14 37 66 179l3 9q4 10 10 26t9 26l12 -55zM531 611l-58 295q-11 54 -75 54h-268l-2 -13q311 -79 403 -336zM710 960l-162 -438l-17 89q-26 70 -85 129.5t-131 88.5l135 -510h175l261 641h-176zM849 318h166l104 642h-166zM1617 944q-69 27 -149 27 +q-123 0 -201 -59t-79 -153q-1 -102 145 -174q48 -23 67 -41t19 -39q0 -30 -30 -46t-69 -16q-86 0 -156 33l-22 11l-23 -144q74 -34 185 -34q130 -1 208.5 59t80.5 160q0 106 -140 174q-49 25 -71 42t-22 38q0 22 24.5 38.5t70.5 16.5q70 1 124 -24l15 -8zM2042 960h-128 +q-65 0 -87 -54l-246 -588h174l35 96h212q5 -22 20 -96h154zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_466" unicode="&#xf1f1;" horiz-adv-x="2304" +d="M1119 1195q-128 85 -281 85q-103 0 -197.5 -40.5t-162.5 -108.5t-108.5 -162t-40.5 -197q0 -104 40.5 -198t108.5 -162t162 -108.5t198 -40.5q153 0 281 85q-131 107 -178 265.5t0.5 316.5t177.5 265zM1152 1171q-126 -99 -172 -249.5t-0.5 -300.5t172.5 -249 +q127 99 172.5 249t-0.5 300.5t-172 249.5zM1185 1195q130 -107 177.5 -265.5t0.5 -317t-178 -264.5q128 -85 281 -85q104 0 198 40.5t162 108.5t108.5 162t40.5 198q0 103 -40.5 197t-108.5 162t-162.5 108.5t-197.5 40.5q-153 0 -281 -85zM1926 473h7v3h-17v-3h7v-17h3v17z +M1955 456h4v20h-5l-6 -13l-6 13h-5v-20h3v15l6 -13h4l5 13v-15zM1947 16v-2h-2h-3v3h3h2v-1zM1947 7h3l-4 5h2l1 1q1 1 1 3t-1 3l-1 1h-3h-6v-13h3v5h1zM685 75q0 19 11 31t30 12q18 0 29 -12.5t11 -30.5q0 -19 -11 -31t-29 -12q-19 0 -30 12t-11 31zM1158 119q30 0 35 -32 +h-70q5 32 35 32zM1514 75q0 19 11 31t29 12t29.5 -12.5t11.5 -30.5q0 -19 -11 -31t-30 -12q-18 0 -29 12t-11 31zM1786 75q0 18 11.5 30.5t29.5 12.5t29.5 -12.5t11.5 -30.5q0 -19 -11.5 -31t-29.5 -12t-29.5 12.5t-11.5 30.5zM1944 3q-2 0 -4 1q-1 0 -3 2t-2 3q-1 2 -1 4 +q0 3 1 4q0 2 2 4l1 1q2 0 2 1q2 1 4 1q3 0 4 -1l4 -2l2 -4v-1q1 -2 1 -3l-1 -1v-3t-1 -1l-1 -2q-2 -2 -4 -2q-1 -1 -4 -1zM599 7h30v85q0 24 -14.5 38.5t-39.5 15.5q-32 0 -47 -24q-14 24 -45 24q-24 0 -39 -20v16h-30v-135h30v75q0 36 33 36q30 0 30 -36v-75h29v75 +q0 36 33 36q30 0 30 -36v-75zM765 7h29v68v67h-29v-16q-17 20 -43 20q-29 0 -48 -20t-19 -51t19 -51t48 -20q28 0 43 20v-17zM943 48q0 34 -47 40l-14 2q-23 4 -23 14q0 15 25 15q23 0 43 -11l12 24q-22 14 -55 14q-26 0 -41 -12t-15 -32q0 -33 47 -39l13 -2q24 -4 24 -14 +q0 -17 -31 -17q-25 0 -45 14l-13 -23q25 -17 58 -17q29 0 45.5 12t16.5 32zM1073 14l-8 25q-13 -7 -26 -7q-19 0 -19 22v61h48v27h-48v41h-30v-41h-28v-27h28v-61q0 -50 47 -50q21 0 36 10zM1159 146q-29 0 -48 -20t-19 -51q0 -32 19.5 -51.5t49.5 -19.5q33 0 55 19l-14 22 +q-18 -15 -39 -15q-34 0 -41 33h101v12q0 32 -18 51.5t-46 19.5zM1318 146q-23 0 -35 -20v16h-30v-135h30v76q0 35 29 35q10 0 18 -4l9 28q-9 4 -21 4zM1348 75q0 -31 19.5 -51t52.5 -20q29 0 48 16l-14 24q-18 -13 -35 -12q-18 0 -29.5 12t-11.5 31t11.5 31t29.5 12 +q19 0 35 -12l14 24q-20 16 -48 16q-33 0 -52.5 -20t-19.5 -51zM1593 7h30v68v67h-30v-16q-15 20 -42 20q-29 0 -48.5 -20t-19.5 -51t19.5 -51t48.5 -20q28 0 42 20v-17zM1726 146q-23 0 -35 -20v16h-29v-135h29v76q0 35 29 35q10 0 18 -4l9 28q-8 4 -21 4zM1866 7h29v68v122 +h-29v-71q-15 20 -43 20t-47.5 -20.5t-19.5 -50.5t19.5 -50.5t47.5 -20.5q29 0 43 20v-17zM1944 27l-2 -1h-3q-2 -1 -4 -3q-3 -1 -3 -4q-1 -2 -1 -6q0 -3 1 -5q0 -2 3 -4q2 -2 4 -3t5 -1q4 0 6 1q0 1 2 2l2 1q1 1 3 4q1 2 1 5q0 4 -1 6q-1 1 -3 4q0 1 -2 2l-2 1q-1 0 -3 0.5 +t-3 0.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_467" unicode="&#xf1f2;" horiz-adv-x="2304" +d="M313 759q0 -51 -36 -84q-29 -26 -89 -26h-17v220h17q61 0 89 -27q36 -31 36 -83zM2089 824q0 -52 -64 -52h-19v101h20q63 0 63 -49zM380 759q0 74 -50 120.5t-129 46.5h-95v-333h95q74 0 119 38q60 51 60 128zM410 593h65v333h-65v-333zM730 694q0 40 -20.5 62t-75.5 42 +q-29 10 -39.5 19t-10.5 23q0 16 13.5 26.5t34.5 10.5q29 0 53 -27l34 44q-41 37 -98 37q-44 0 -74 -27.5t-30 -67.5q0 -35 18 -55.5t64 -36.5q37 -13 45 -19q19 -12 19 -34q0 -20 -14 -33.5t-36 -13.5q-48 0 -71 44l-42 -40q44 -64 115 -64q51 0 83 30.5t32 79.5zM1008 604 +v77q-37 -37 -78 -37q-49 0 -80.5 32.5t-31.5 82.5q0 48 31.5 81.5t77.5 33.5q43 0 81 -38v77q-40 20 -80 20q-74 0 -125.5 -50.5t-51.5 -123.5t51 -123.5t125 -50.5q42 0 81 19zM2240 0v527q-65 -40 -144.5 -84t-237.5 -117t-329.5 -137.5t-417.5 -134.5t-504 -118h1569 +q26 0 45 19t19 45zM1389 757q0 75 -53 128t-128 53t-128 -53t-53 -128t53 -128t128 -53t128 53t53 128zM1541 584l144 342h-71l-90 -224l-89 224h-71l142 -342h35zM1714 593h184v56h-119v90h115v56h-115v74h119v57h-184v-333zM2105 593h80l-105 140q76 16 76 94q0 47 -31 73 +t-87 26h-97v-333h65v133h9zM2304 1274v-1268q0 -56 -38.5 -95t-93.5 -39h-2040q-55 0 -93.5 39t-38.5 95v1268q0 56 38.5 95t93.5 39h2040q55 0 93.5 -39t38.5 -95z" /> + <glyph glyph-name="f1f3" unicode="&#xf1f3;" horiz-adv-x="2304" +d="M119 854h89l-45 108zM740 328l74 79l-70 79h-163v-49h142v-55h-142v-54h159zM898 406l99 -110v217zM1186 453q0 33 -40 33h-84v-69h83q41 0 41 36zM1475 457q0 29 -42 29h-82v-61h81q43 0 43 32zM1197 923q0 29 -42 29h-82v-60h81q43 0 43 31zM1656 854h89l-44 108z +M699 1009v-271h-66v212l-94 -212h-57l-94 212v-212h-132l-25 60h-135l-25 -60h-70l116 271h96l110 -257v257h106l85 -184l77 184h108zM1255 453q0 -20 -5.5 -35t-14 -25t-22.5 -16.5t-26 -10t-31.5 -4.5t-31.5 -1t-32.5 0.5t-29.5 0.5v-91h-126l-80 90l-83 -90h-256v271h260 +l80 -89l82 89h207q109 0 109 -89zM964 794v-56h-217v271h217v-57h-152v-49h148v-55h-148v-54h152zM2304 235v-229q0 -55 -38.5 -94.5t-93.5 -39.5h-2040q-55 0 -93.5 39.5t-38.5 94.5v678h111l25 61h55l25 -61h218v46l19 -46h113l20 47v-47h541v99l10 1q10 0 10 -14v-86h279 +v23q23 -12 55 -18t52.5 -6.5t63 0.5t51.5 1l25 61h56l25 -61h227v58l34 -58h182v378h-180v-44l-25 44h-185v-44l-23 44h-249q-69 0 -109 -22v22h-172v-22q-24 22 -73 22h-628l-43 -97l-43 97h-198v-44l-22 44h-169l-78 -179v391q0 55 38.5 94.5t93.5 39.5h2040 +q55 0 93.5 -39.5t38.5 -94.5v-678h-120q-51 0 -81 -22v22h-177q-55 0 -78 -22v22h-316v-22q-31 22 -87 22h-209v-22q-23 22 -91 22h-234l-54 -58l-50 58h-349v-378h343l55 59l52 -59h211v89h21q59 0 90 13v-102h174v99h8q8 0 10 -2t2 -10v-87h529q57 0 88 24v-24h168 +q60 0 95 17zM1546 469q0 -23 -12 -43t-34 -29q25 -9 34 -26t9 -46v-54h-65v45q0 33 -12 43.5t-46 10.5h-69v-99h-65v271h154q48 0 77 -15t29 -58zM1269 936q0 -24 -12.5 -44t-33.5 -29q26 -9 34.5 -25.5t8.5 -46.5v-53h-65q0 9 0.5 26.5t0 25t-3 18.5t-8.5 16t-17.5 8.5 +t-29.5 3.5h-70v-98h-64v271l153 -1q49 0 78 -14.5t29 -57.5zM1798 327v-56h-216v271h216v-56h-151v-49h148v-55h-148v-54zM1372 1009v-271h-66v271h66zM2065 357q0 -86 -102 -86h-126v58h126q34 0 34 25q0 16 -17 21t-41.5 5t-49.5 3.5t-42 22.5t-17 55q0 39 26 60t66 21 +h130v-57h-119q-36 0 -36 -25q0 -16 17.5 -20.5t42 -4t49 -2.5t42 -21.5t17.5 -54.5zM2304 407v-101q-24 -35 -88 -35h-125v58h125q33 0 33 25q0 13 -12.5 19t-31 5.5t-40 2t-40 8t-31 24t-12.5 48.5q0 39 26.5 60t66.5 21h129v-57h-118q-36 0 -36 -25q0 -20 29 -22t68.5 -5 +t56.5 -26zM2139 1008v-270h-92l-122 203v-203h-132l-26 60h-134l-25 -60h-75q-129 0 -129 133q0 138 133 138h63v-59q-7 0 -28 1t-28.5 0.5t-23 -2t-21.5 -6.5t-14.5 -13.5t-11.5 -23t-3 -33.5q0 -38 13.5 -58t49.5 -20h29l92 213h97l109 -256v256h99l114 -188v188h66z" /> + <glyph glyph-name="_469" unicode="&#xf1f4;" horiz-adv-x="2304" +d="M745 630q0 -37 -25.5 -61.5t-62.5 -24.5q-29 0 -46.5 16t-17.5 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM1530 779q0 -42 -22 -57t-66 -15l-32 -1l17 107q2 11 13 11h18q22 0 35 -2t25 -12.5t12 -30.5zM1881 630q0 -36 -25.5 -61t-61.5 -25q-29 0 -47 16 +t-18 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM513 801q0 59 -38.5 85.5t-100.5 26.5h-160q-19 0 -21 -19l-65 -408q-1 -6 3 -11t10 -5h76q20 0 22 19l18 110q1 8 7 13t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM822 489l41 261q1 6 -3 11t-10 5h-76 +q-14 0 -17 -33q-27 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q28 0 58 12t48 32q-4 -12 -4 -21q0 -16 13 -16h69q19 0 22 19zM1269 752q0 5 -4 9.5t-9 4.5h-77q-11 0 -18 -10l-106 -156l-44 150q-5 16 -22 16h-75q-5 0 -9 -4.5t-4 -9.5q0 -2 19.5 -59 +t42 -123t23.5 -70q-82 -112 -82 -120q0 -13 13 -13h77q11 0 18 10l255 368q2 2 2 7zM1649 801q0 59 -38.5 85.5t-100.5 26.5h-159q-20 0 -22 -19l-65 -408q-1 -6 3 -11t10 -5h82q12 0 16 13l18 116q1 8 7 13t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM1958 489 +l41 261q1 6 -3 11t-10 5h-76q-14 0 -17 -33q-26 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q29 0 59 12t47 32q0 -1 -2 -9t-2 -12q0 -16 13 -16h69q19 0 22 19zM2176 898v1q0 14 -13 14h-74q-11 0 -13 -11l-65 -416l-1 -2q0 -5 4 -9.5t10 -4.5h66 +q19 0 21 19zM392 764q-5 -35 -26 -46t-60 -11l-33 -1l17 107q2 11 13 11h19q40 0 58 -11.5t12 -48.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_470" unicode="&#xf1f5;" horiz-adv-x="2304" +d="M1597 633q0 -69 -21 -106q-19 -35 -52 -35q-23 0 -41 9v224q29 30 57 30q57 0 57 -122zM2035 669h-110q6 98 56 98q51 0 54 -98zM476 534q0 59 -33 91.5t-101 57.5q-36 13 -52 24t-16 25q0 26 38 26q58 0 124 -33l18 112q-67 32 -149 32q-77 0 -123 -38q-48 -39 -48 -109 +q0 -58 32.5 -90.5t99.5 -56.5q39 -14 54.5 -25.5t15.5 -27.5q0 -31 -48 -31q-29 0 -70 12.5t-72 30.5l-18 -113q72 -41 168 -41q81 0 129 37q51 41 51 117zM771 749l19 111h-96v135l-129 -21l-18 -114l-46 -8l-17 -103h62v-219q0 -84 44 -120q38 -30 111 -30q32 0 79 11v118 +q-32 -7 -44 -7q-42 0 -42 50v197h77zM1087 724v139q-15 3 -28 3q-32 0 -55.5 -16t-33.5 -46l-10 56h-131v-471h150v306q26 31 82 31q16 0 26 -2zM1124 389h150v471h-150v-471zM1746 638q0 122 -45 179q-40 52 -111 52q-64 0 -117 -56l-8 47h-132v-645l150 25v151 +q36 -11 68 -11q83 0 134 56q61 65 61 202zM1278 986q0 33 -23 56t-56 23t-56 -23t-23 -56t23 -56.5t56 -23.5t56 23.5t23 56.5zM2176 629q0 113 -48 176q-50 64 -144 64q-96 0 -151.5 -66t-55.5 -180q0 -128 63 -188q55 -55 161 -55q101 0 160 40l-16 103q-57 -31 -128 -31 +q-43 0 -63 19q-23 19 -28 66h248q2 14 2 52zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_471" unicode="&#xf1f6;" horiz-adv-x="2048" +d="M1558 684q61 -356 298 -556q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5zM1024 -176q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5zM2026 1424q8 -10 7.5 -23.5t-10.5 -22.5 +l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5 +l418 363q10 8 23.5 7t21.5 -11z" /> + <glyph glyph-name="_472" unicode="&#xf1f7;" horiz-adv-x="2048" +d="M1040 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM503 315l877 760q-42 88 -132.5 146.5t-223.5 58.5q-93 0 -169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -384 -137 -645zM1856 128 +q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5l149 129h757q-166 187 -227 459l111 97q61 -356 298 -556zM1942 1520l84 -96q8 -10 7.5 -23.5t-10.5 -22.5l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161 +q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5l418 363q10 8 23.5 7t21.5 -11z" /> + <glyph glyph-name="_473" unicode="&#xf1f8;" horiz-adv-x="1408" +d="M512 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM768 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1024 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704 +q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167 +q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" /> + <glyph glyph-name="_474" unicode="&#xf1f9;" +d="M1150 462v-109q0 -50 -36.5 -89t-94 -60.5t-118 -32.5t-117.5 -11q-205 0 -342.5 139t-137.5 346q0 203 136 339t339 136q34 0 75.5 -4.5t93 -18t92.5 -34t69 -56.5t28 -81v-109q0 -16 -16 -16h-118q-16 0 -16 16v70q0 43 -65.5 67.5t-137.5 24.5q-140 0 -228.5 -91.5 +t-88.5 -237.5q0 -151 91.5 -249.5t233.5 -98.5q68 0 138 24t70 66v70q0 7 4.5 11.5t10.5 4.5h119q6 0 11 -4.5t5 -11.5zM768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 +t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_475" unicode="&#xf1fa;" +d="M972 761q0 108 -53.5 169t-147.5 61q-63 0 -124 -30.5t-110 -84.5t-79.5 -137t-30.5 -180q0 -112 53.5 -173t150.5 -61q96 0 176 66.5t122.5 166t42.5 203.5zM1536 640q0 -111 -37 -197t-98.5 -135t-131.5 -74.5t-145 -27.5q-6 0 -15.5 -0.5t-16.5 -0.5q-95 0 -142 53 +q-28 33 -33 83q-52 -66 -131.5 -110t-173.5 -44q-161 0 -249.5 95.5t-88.5 269.5q0 157 66 290t179 210.5t246 77.5q87 0 155 -35.5t106 -99.5l2 19l11 56q1 6 5.5 12t9.5 6h118q5 0 13 -11q5 -5 3 -16l-120 -614q-5 -24 -5 -48q0 -39 12.5 -52t44.5 -13q28 1 57 5.5t73 24 +t77 50t57 89.5t24 137q0 292 -174 466t-466 174q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51q228 0 405 144q11 9 24 8t21 -12l41 -49q8 -12 7 -24q-2 -13 -12 -22q-102 -83 -227.5 -128t-258.5 -45q-156 0 -298 61 +t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q344 0 556 -212t212 -556z" /> + <glyph glyph-name="_476" unicode="&#xf1fb;" horiz-adv-x="1792" +d="M1698 1442q94 -94 94 -226.5t-94 -225.5l-225 -223l104 -104q10 -10 10 -23t-10 -23l-210 -210q-10 -10 -23 -10t-23 10l-105 105l-603 -603q-37 -37 -90 -37h-203l-256 -128l-64 64l128 256v203q0 53 37 90l603 603l-105 105q-10 10 -10 23t10 23l210 210q10 10 23 10 +t23 -10l104 -104l223 225q93 94 225.5 94t226.5 -94zM512 64l576 576l-192 192l-576 -576v-192h192z" /> + <glyph glyph-name="f1fc" unicode="&#xf1fc;" horiz-adv-x="1792" +d="M1615 1536q70 0 122.5 -46.5t52.5 -116.5q0 -63 -45 -151q-332 -629 -465 -752q-97 -91 -218 -91q-126 0 -216.5 92.5t-90.5 219.5q0 128 92 212l638 579q59 54 130 54zM706 502q39 -76 106.5 -130t150.5 -76l1 -71q4 -213 -129.5 -347t-348.5 -134q-123 0 -218 46.5 +t-152.5 127.5t-86.5 183t-29 220q7 -5 41 -30t62 -44.5t59 -36.5t46 -17q41 0 55 37q25 66 57.5 112.5t69.5 76t88 47.5t103 25.5t125 10.5z" /> + <glyph glyph-name="_478" unicode="&#xf1fd;" horiz-adv-x="1792" +d="M1792 128v-384h-1792v384q45 0 85 14t59 27.5t47 37.5q30 27 51.5 38t56.5 11q24 0 44 -7t31 -15t33 -27q29 -25 47 -38t58 -27t86 -14q45 0 85 14.5t58 27t48 37.5q21 19 32.5 27t31 15t43.5 7q35 0 56.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14t85 14t59 27.5 +t47 37.5q30 27 51.5 38t56.5 11q34 0 55.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14zM1792 448v-192q-24 0 -44 7t-31 15t-33 27q-29 25 -47 38t-58 27t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-22 -19 -33 -27t-31 -15t-44 -7q-35 0 -56.5 11t-51.5 38q-29 25 -47 38 +t-58 27t-86 14q-45 0 -85 -14.5t-58 -27t-48 -37.5q-21 -19 -32.5 -27t-31 -15t-43.5 -7q-35 0 -56.5 11t-51.5 38q-28 24 -47 37.5t-59 27.5t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-30 -27 -51.5 -38t-56.5 -11v192q0 80 56 136t136 56h64v448h256v-448h256v448h256v-448 +h256v448h256v-448h64q80 0 136 -56t56 -136zM512 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1024 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5 +q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1536 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150z" /> + <glyph glyph-name="_479" unicode="&#xf1fe;" horiz-adv-x="2048" +d="M2048 0v-128h-2048v1536h128v-1408h1920zM1664 1024l256 -896h-1664v576l448 576l576 -576z" /> + <glyph glyph-name="_480" unicode="&#xf200;" horiz-adv-x="1792" +d="M768 646l546 -546q-106 -108 -247.5 -168t-298.5 -60q-209 0 -385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103v-762zM955 640h773q0 -157 -60 -298.5t-168 -247.5zM1664 768h-768v768q209 0 385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_481" unicode="&#xf201;" horiz-adv-x="2048" +d="M2048 0v-128h-2048v1536h128v-1408h1920zM1920 1248v-435q0 -21 -19.5 -29.5t-35.5 7.5l-121 121l-633 -633q-10 -10 -23 -10t-23 10l-233 233l-416 -416l-192 192l585 585q10 10 23 10t23 -10l233 -233l464 464l-121 121q-16 16 -7.5 35.5t29.5 19.5h435q14 0 23 -9 +t9 -23z" /> + <glyph glyph-name="_482" unicode="&#xf202;" horiz-adv-x="1792" +d="M1292 832q0 -6 10 -41q10 -29 25 -49.5t41 -34t44 -20t55 -16.5q325 -91 325 -332q0 -146 -105.5 -242.5t-254.5 -96.5q-59 0 -111.5 18.5t-91.5 45.5t-77 74.5t-63 87.5t-53.5 103.5t-43.5 103t-39.5 106.5t-35.5 95q-32 81 -61.5 133.5t-73.5 96.5t-104 64t-142 20 +q-96 0 -183 -55.5t-138 -144.5t-51 -185q0 -160 106.5 -279.5t263.5 -119.5q177 0 258 95q56 63 83 116l84 -152q-15 -34 -44 -70l1 -1q-131 -152 -388 -152q-147 0 -269.5 79t-190.5 207.5t-68 274.5q0 105 43.5 206t116 176.5t172 121.5t204.5 46q87 0 159 -19t123.5 -50 +t95 -80t72.5 -99t58.5 -117t50.5 -124.5t50 -130.5t55 -127q96 -200 233 -200q81 0 138.5 48.5t57.5 128.5q0 42 -19 72t-50.5 46t-72.5 31.5t-84.5 27t-87.5 34t-81 52t-65 82t-39 122.5q-3 16 -3 33q0 110 87.5 192t198.5 78q78 -3 120.5 -14.5t90.5 -53.5h-1 +q12 -11 23 -24.5t26 -36t19 -27.5l-129 -99q-26 49 -54 70v1q-23 21 -97 21q-49 0 -84 -33t-35 -83z" /> + <glyph glyph-name="_483" unicode="&#xf203;" +d="M1432 484q0 173 -234 239q-35 10 -53 16.5t-38 25t-29 46.5q0 2 -2 8.5t-3 12t-1 7.5q0 36 24.5 59.5t60.5 23.5q54 0 71 -15h-1q20 -15 39 -51l93 71q-39 54 -49 64q-33 29 -67.5 39t-85.5 10q-80 0 -142 -57.5t-62 -137.5q0 -7 2 -23q16 -96 64.5 -140t148.5 -73 +q29 -8 49 -15.5t45 -21.5t38.5 -34.5t13.5 -46.5v-5q1 -58 -40.5 -93t-100.5 -35q-97 0 -167 144q-23 47 -51.5 121.5t-48 125.5t-54 110.5t-74 95.5t-103.5 60.5t-147 24.5q-101 0 -192 -56t-144 -148t-50 -192v-1q4 -108 50.5 -199t133.5 -147.5t196 -56.5q186 0 279 110 +q20 27 31 51l-60 109q-42 -80 -99 -116t-146 -36q-115 0 -191 87t-76 204q0 105 82 189t186 84q112 0 170 -53.5t104 -172.5q8 -21 25.5 -68.5t28.5 -76.5t31.5 -74.5t38.5 -74t45.5 -62.5t55.5 -53.5t66 -33t80 -13.5q107 0 183 69.5t76 174.5zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_484" unicode="&#xf204;" horiz-adv-x="2048" +d="M1152 640q0 104 -40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM1920 640q0 104 -40.5 198.5 +t-109.5 163.5t-163.5 109.5t-198.5 40.5h-386q119 -90 188.5 -224t69.5 -288t-69.5 -288t-188.5 -224h386q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM2048 640q0 -130 -51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5 +t-136.5 204t-51 248.5t51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5z" /> + <glyph glyph-name="_485" unicode="&#xf205;" horiz-adv-x="2048" +d="M0 640q0 130 51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5t-51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5t-136.5 204t-51 248.5zM1408 128q104 0 198.5 40.5t163.5 109.5 +t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5z" /> + <glyph glyph-name="_486" unicode="&#xf206;" horiz-adv-x="2304" +d="M762 384h-314q-40 0 -57.5 35t6.5 67l188 251q-65 31 -137 31q-132 0 -226 -94t-94 -226t94 -226t226 -94q115 0 203 72.5t111 183.5zM576 512h186q-18 85 -75 148zM1056 512l288 384h-480l-99 -132q105 -103 126 -252h165zM2176 448q0 132 -94 226t-226 94 +q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94t226 94t94 226zM2304 448q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 97 39.5 183.5t109.5 149.5l-65 98l-353 -469 +q-18 -26 -51 -26h-197q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q114 0 215 -55l137 183h-224q-26 0 -45 19t-19 45t19 45t45 19h384v-128h435l-85 128h-222q-26 0 -45 19t-19 45t19 45t45 19h256q33 0 53 -28l267 -400 +q91 44 192 44q185 0 316.5 -131.5t131.5 -316.5z" /> + <glyph glyph-name="_487" unicode="&#xf207;" +d="M384 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1362 716l-72 384q-5 23 -22.5 37.5t-40.5 14.5 +h-918q-23 0 -40.5 -14.5t-22.5 -37.5l-72 -384q-5 -30 14 -53t49 -23h1062q30 0 49 23t14 53zM1136 1328q0 20 -14 34t-34 14h-640q-20 0 -34 -14t-14 -34t14 -34t34 -14h640q20 0 34 14t14 34zM1536 603v-603h-128v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 +t-37.5 90.5v128h-768v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5v128h-128v603q0 112 25 223l103 454q9 78 97.5 137t230 89t312.5 30t312.5 -30t230 -89t97.5 -137l105 -454q23 -102 23 -223z" /> + <glyph glyph-name="_488" unicode="&#xf208;" horiz-adv-x="2048" +d="M1463 704q0 -35 -25 -60.5t-61 -25.5h-702q-36 0 -61 25.5t-25 60.5t25 60.5t61 25.5h702q36 0 61 -25.5t25 -60.5zM1677 704q0 86 -23 170h-982q-36 0 -61 25t-25 60q0 36 25 61t61 25h908q-88 143 -235 227t-320 84q-177 0 -327.5 -87.5t-238 -237.5t-87.5 -327 +q0 -86 23 -170h982q36 0 61 -25t25 -60q0 -36 -25 -61t-61 -25h-908q88 -143 235.5 -227t320.5 -84q132 0 253 51.5t208 139t139 208t52 253.5zM2048 959q0 -35 -25 -60t-61 -25h-131q17 -85 17 -170q0 -167 -65.5 -319.5t-175.5 -263t-262.5 -176t-319.5 -65.5 +q-246 0 -448.5 133t-301.5 350h-189q-36 0 -61 25t-25 61q0 35 25 60t61 25h132q-17 85 -17 170q0 167 65.5 319.5t175.5 263t262.5 176t320.5 65.5q245 0 447.5 -133t301.5 -350h188q36 0 61 -25t25 -61z" /> + <glyph glyph-name="_489" unicode="&#xf209;" horiz-adv-x="1280" +d="M953 1158l-114 -328l117 -21q165 451 165 518q0 56 -38 56q-57 0 -130 -225zM654 471l33 -88q37 42 71 67l-33 5.5t-38.5 7t-32.5 8.5zM362 1367q0 -98 159 -521q17 10 49 10q15 0 75 -5l-121 351q-75 220 -123 220q-19 0 -29 -17.5t-10 -37.5zM283 608q0 -36 51.5 -119 +t117.5 -153t100 -70q14 0 25.5 13t11.5 27q0 24 -32 102q-13 32 -32 72t-47.5 89t-61.5 81t-62 32q-20 0 -45.5 -27t-25.5 -47zM125 273q0 -41 25 -104q59 -145 183.5 -227t281.5 -82q227 0 382 170q152 169 152 427q0 43 -1 67t-11.5 62t-30.5 56q-56 49 -211.5 75.5 +t-270.5 26.5q-37 0 -49 -11q-12 -5 -12 -35q0 -34 21.5 -60t55.5 -40t77.5 -23.5t87.5 -11.5t85 -4t70 0h23q24 0 40 -19q15 -19 19 -55q-28 -28 -96 -54q-61 -22 -93 -46q-64 -46 -108.5 -114t-44.5 -137q0 -31 18.5 -88.5t18.5 -87.5l-3 -12q-4 -12 -4 -14 +q-137 10 -146 216q-8 -2 -41 -2q2 -7 2 -21q0 -53 -40.5 -89.5t-94.5 -36.5q-82 0 -166.5 78t-84.5 159q0 34 33 67q52 -64 60 -76q77 -104 133 -104q12 0 26.5 8.5t14.5 20.5q0 34 -87.5 145t-116.5 111q-43 0 -70 -44.5t-27 -90.5zM11 264q0 101 42.5 163t136.5 88 +q-28 74 -28 104q0 62 61 123t122 61q29 0 70 -15q-163 462 -163 567q0 80 41 130.5t119 50.5q131 0 325 -581q6 -17 8 -23q6 16 29 79.5t43.5 118.5t54 127.5t64.5 123t70.5 86.5t76.5 36q71 0 112 -49t41 -122q0 -108 -159 -550q61 -15 100.5 -46t58.5 -78t26 -93.5 +t7 -110.5q0 -150 -47 -280t-132 -225t-211 -150t-278 -55q-111 0 -223 42q-149 57 -258 191.5t-109 286.5z" /> + <glyph glyph-name="_490" unicode="&#xf20a;" horiz-adv-x="2048" +d="M785 528h207q-14 -158 -98.5 -248.5t-214.5 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-203q-5 64 -35.5 99t-81.5 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t40 -51.5t66 -18q95 0 109 139zM1497 528h206 +q-14 -158 -98 -248.5t-214 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-204q-4 64 -35 99t-81 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t39.5 -51.5t65.5 -18q49 0 76.5 38t33.5 101zM1856 647q0 207 -15.5 307 +t-60.5 161q-6 8 -13.5 14t-21.5 15t-16 11q-86 63 -697 63q-625 0 -710 -63q-5 -4 -17.5 -11.5t-21 -14t-14.5 -14.5q-45 -60 -60 -159.5t-15 -308.5q0 -208 15 -307.5t60 -160.5q6 -8 15 -15t20.5 -14t17.5 -12q44 -33 239.5 -49t470.5 -16q610 0 697 65q5 4 17 11t20.5 14 +t13.5 16q46 60 61 159t15 309zM2048 1408v-1536h-2048v1536h2048z" /> + <glyph glyph-name="_491" unicode="&#xf20b;" +d="M992 912v-496q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v496q0 112 -80 192t-192 80h-272v-1152q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v1344q0 14 9 23t23 9h464q135 0 249 -66.5t180.5 -180.5t66.5 -249zM1376 1376v-880q0 -135 -66.5 -249t-180.5 -180.5 +t-249 -66.5h-464q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-768h272q112 0 192 80t80 192v880q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" /> + <glyph glyph-name="_492" unicode="&#xf20c;" +d="M1311 694v-114q0 -24 -13.5 -38t-37.5 -14h-202q-24 0 -38 14t-14 38v114q0 24 14 38t38 14h202q24 0 37.5 -14t13.5 -38zM821 464v250q0 53 -32.5 85.5t-85.5 32.5h-133q-68 0 -96 -52q-28 52 -96 52h-130q-53 0 -85.5 -32.5t-32.5 -85.5v-250q0 -22 21 -22h55 +q22 0 22 22v230q0 24 13.5 38t38.5 14h94q24 0 38 -14t14 -38v-230q0 -22 21 -22h54q22 0 22 22v230q0 24 14 38t38 14h97q24 0 37.5 -14t13.5 -38v-230q0 -22 22 -22h55q21 0 21 22zM1410 560v154q0 53 -33 85.5t-86 32.5h-264q-53 0 -86 -32.5t-33 -85.5v-410 +q0 -21 22 -21h55q21 0 21 21v180q31 -42 94 -42h191q53 0 86 32.5t33 85.5zM1536 1176v-1072q0 -96 -68 -164t-164 -68h-1072q-96 0 -164 68t-68 164v1072q0 96 68 164t164 68h1072q96 0 164 -68t68 -164z" /> + <glyph glyph-name="_493" unicode="&#xf20d;" +d="M915 450h-294l147 551zM1001 128h311l-324 1024h-440l-324 -1024h311l383 314zM1536 1120v-960q0 -118 -85 -203t-203 -85h-960q-118 0 -203 85t-85 203v960q0 118 85 203t203 85h960q118 0 203 -85t85 -203z" /> + <glyph glyph-name="_494" unicode="&#xf20e;" horiz-adv-x="2048" +d="M2048 641q0 -21 -13 -36.5t-33 -19.5l-205 -356q3 -9 3 -18q0 -20 -12.5 -35.5t-32.5 -19.5l-193 -337q3 -8 3 -16q0 -23 -16.5 -40t-40.5 -17q-25 0 -41 18h-400q-17 -20 -43 -20t-43 20h-399q-17 -20 -43 -20q-23 0 -40 16.5t-17 40.5q0 8 4 20l-193 335 +q-20 4 -32.5 19.5t-12.5 35.5q0 9 3 18l-206 356q-20 5 -32.5 20.5t-12.5 35.5q0 21 13.5 36.5t33.5 19.5l199 344q0 1 -0.5 3t-0.5 3q0 36 34 51l209 363q-4 10 -4 18q0 24 17 40.5t40 16.5q26 0 44 -21h396q16 21 43 21t43 -21h398q18 21 44 21q23 0 40 -16.5t17 -40.5 +q0 -6 -4 -18l207 -358q23 -1 39 -17.5t16 -38.5q0 -13 -7 -27l187 -324q19 -4 31.5 -19.5t12.5 -35.5zM1063 -158h389l-342 354h-143l-342 -354h360q18 16 39 16t39 -16zM112 654q1 -4 1 -13q0 -10 -2 -15l208 -360l15 -6l188 199v347l-187 194q-13 -8 -29 -10zM986 1438 +h-388l190 -200l554 200h-280q-16 -16 -38 -16t-38 16zM1689 226q1 6 5 11l-64 68l-17 -79h76zM1583 226l22 105l-252 266l-296 -307l63 -64h463zM1495 -142l16 28l65 310h-427l333 -343q8 4 13 5zM578 -158h5l342 354h-373v-335l4 -6q14 -5 22 -13zM552 226h402l64 66 +l-309 321l-157 -166v-221zM359 226h163v189l-168 -177q4 -8 5 -12zM358 1051q0 -1 0.5 -2t0.5 -2q0 -16 -8 -29l171 -177v269zM552 1121v-311l153 -157l297 314l-223 236zM556 1425l-4 -8v-264l205 74l-191 201q-6 -2 -10 -3zM1447 1438h-16l-621 -224l213 -225zM1023 946 +l-297 -315l311 -319l296 307zM688 634l-136 141v-284zM1038 270l-42 -44h85zM1374 618l238 -251l132 624l-3 5l-1 1zM1718 1018q-8 13 -8 29v2l-216 376q-5 1 -13 5l-437 -463l310 -327zM522 1142v223l-163 -282zM522 196h-163l163 -283v283zM1607 196l-48 -227l130 227h-82 +zM1729 266l207 361q-2 10 -2 14q0 1 3 16l-171 296l-129 -612l77 -82q5 3 15 7z" /> + <glyph glyph-name="f210" unicode="&#xf210;" +d="M0 856q0 131 91.5 226.5t222.5 95.5h742l352 358v-1470q0 -132 -91.5 -227t-222.5 -95h-780q-131 0 -222.5 95t-91.5 227v790zM1232 102l-176 180v425q0 46 -32 79t-78 33h-484q-46 0 -78 -33t-32 -79v-492q0 -46 32.5 -79.5t77.5 -33.5h770z" /> + <glyph glyph-name="_496" unicode="&#xf211;" +d="M934 1386q-317 -121 -556 -362.5t-358 -560.5q-20 89 -20 176q0 208 102.5 384.5t278.5 279t384 102.5q82 0 169 -19zM1203 1267q93 -65 164 -155q-389 -113 -674.5 -400.5t-396.5 -676.5q-93 72 -155 162q112 386 395 671t667 399zM470 -67q115 356 379.5 622t619.5 384 +q40 -92 54 -195q-292 -120 -516 -345t-343 -518q-103 14 -194 52zM1536 -125q-193 50 -367 115q-135 -84 -290 -107q109 205 274 370.5t369 275.5q-21 -152 -101 -284q65 -175 115 -370z" /> + <glyph glyph-name="f212" unicode="&#xf212;" horiz-adv-x="2048" +d="M1893 1144l155 -1272q-131 0 -257 57q-200 91 -393 91q-226 0 -374 -148q-148 148 -374 148q-193 0 -393 -91q-128 -57 -252 -57h-5l155 1272q224 127 482 127q233 0 387 -106q154 106 387 106q258 0 482 -127zM1398 157q129 0 232 -28.5t260 -93.5l-124 1021 +q-171 78 -368 78q-224 0 -374 -141q-150 141 -374 141q-197 0 -368 -78l-124 -1021q105 43 165.5 65t148.5 39.5t178 17.5q202 0 374 -108q172 108 374 108zM1438 191l-55 907q-211 -4 -359 -155q-152 155 -374 155q-176 0 -336 -66l-114 -941q124 51 228.5 76t221.5 25 +q209 0 374 -102q172 107 374 102z" /> + <glyph glyph-name="_498" unicode="&#xf213;" horiz-adv-x="2048" +d="M1500 165v733q0 21 -15 36t-35 15h-93q-20 0 -35 -15t-15 -36v-733q0 -20 15 -35t35 -15h93q20 0 35 15t15 35zM1216 165v531q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-531q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM924 165v429q0 20 -15 35t-35 15h-101 +q-20 0 -35 -15t-15 -35v-429q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM632 165v362q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-362q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM2048 311q0 -166 -118 -284t-284 -118h-1244q-166 0 -284 118t-118 284 +q0 116 63 214.5t168 148.5q-10 34 -10 73q0 113 80.5 193.5t193.5 80.5q102 0 180 -67q45 183 194 300t338 117q149 0 275 -73.5t199.5 -199.5t73.5 -275q0 -66 -14 -122q135 -33 221 -142.5t86 -247.5z" /> + <glyph glyph-name="_499" unicode="&#xf214;" +d="M0 1536h1536v-1392l-776 -338l-760 338v1392zM1436 209v926h-1336v-926l661 -294zM1436 1235v201h-1336v-201h1336zM181 937v-115h-37v115h37zM181 789v-115h-37v115h37zM181 641v-115h-37v115h37zM181 493v-115h-37v115h37zM181 345v-115h-37v115h37zM207 202l15 34 +l105 -47l-15 -33zM343 142l15 34l105 -46l-15 -34zM478 82l15 34l105 -46l-15 -34zM614 23l15 33l104 -46l-15 -34zM797 10l105 46l15 -33l-105 -47zM932 70l105 46l15 -34l-105 -46zM1068 130l105 46l15 -34l-105 -46zM1203 189l105 47l15 -34l-105 -46zM259 1389v-36h-114 +v36h114zM421 1389v-36h-115v36h115zM583 1389v-36h-115v36h115zM744 1389v-36h-114v36h114zM906 1389v-36h-114v36h114zM1068 1389v-36h-115v36h115zM1230 1389v-36h-115v36h115zM1391 1389v-36h-114v36h114zM181 1049v-79h-37v115h115v-36h-78zM421 1085v-36h-115v36h115z +M583 1085v-36h-115v36h115zM744 1085v-36h-114v36h114zM906 1085v-36h-114v36h114zM1068 1085v-36h-115v36h115zM1230 1085v-36h-115v36h115zM1355 970v79h-78v36h115v-115h-37zM1355 822v115h37v-115h-37zM1355 674v115h37v-115h-37zM1355 526v115h37v-115h-37zM1355 378 +v115h37v-115h-37zM1355 230v115h37v-115h-37zM760 265q-129 0 -221 91.5t-92 221.5q0 129 92 221t221 92q130 0 221.5 -92t91.5 -221q0 -130 -91.5 -221.5t-221.5 -91.5zM595 646q0 -36 19.5 -56.5t49.5 -25t64 -7t64 -2t49.5 -9t19.5 -30.5q0 -49 -112 -49q-97 0 -123 51 +h-3l-31 -63q67 -42 162 -42q29 0 56.5 5t55.5 16t45.5 33t17.5 53q0 46 -27.5 69.5t-67.5 27t-79.5 3t-67 5t-27.5 25.5q0 21 20.5 33t40.5 15t41 3q34 0 70.5 -11t51.5 -34h3l30 58q-3 1 -21 8.5t-22.5 9t-19.5 7t-22 7t-20 4.5t-24 4t-23 1q-29 0 -56.5 -5t-54 -16.5 +t-43 -34t-16.5 -53.5z" /> + <glyph glyph-name="_500" unicode="&#xf215;" horiz-adv-x="2048" +d="M863 504q0 112 -79.5 191.5t-191.5 79.5t-191 -79.5t-79 -191.5t79 -191t191 -79t191.5 79t79.5 191zM1726 505q0 112 -79 191t-191 79t-191.5 -79t-79.5 -191q0 -113 79.5 -192t191.5 -79t191 79.5t79 191.5zM2048 1314v-1348q0 -44 -31.5 -75.5t-76.5 -31.5h-1832 +q-45 0 -76.5 31.5t-31.5 75.5v1348q0 44 31.5 75.5t76.5 31.5h431q44 0 76 -31.5t32 -75.5v-161h754v161q0 44 32 75.5t76 31.5h431q45 0 76.5 -31.5t31.5 -75.5z" /> + <glyph glyph-name="_501" unicode="&#xf216;" horiz-adv-x="2048" +d="M1430 953zM1690 749q148 0 253 -98.5t105 -244.5q0 -157 -109 -261.5t-267 -104.5q-85 0 -162 27.5t-138 73.5t-118 106t-109 126t-103.5 132.5t-108.5 126.5t-117 106t-136 73.5t-159 27.5q-154 0 -251.5 -91.5t-97.5 -244.5q0 -157 104 -250t263 -93q100 0 208 37.5 +t193 98.5q5 4 21 18.5t30 24t22 9.5q14 0 24.5 -10.5t10.5 -24.5q0 -24 -60 -77q-101 -88 -234.5 -142t-260.5 -54q-133 0 -245.5 58t-180 165t-67.5 241q0 205 141.5 341t347.5 136q120 0 226.5 -43.5t185.5 -113t151.5 -153t139 -167.5t133.5 -153.5t149.5 -113 +t172.5 -43.5q102 0 168.5 61.5t66.5 162.5q0 95 -64.5 159t-159.5 64q-30 0 -81.5 -18.5t-68.5 -18.5q-20 0 -35.5 15t-15.5 35q0 18 8.5 57t8.5 59q0 159 -107.5 263t-266.5 104q-58 0 -111.5 -18.5t-84 -40.5t-55.5 -40.5t-33 -18.5q-15 0 -25.5 10.5t-10.5 25.5 +q0 19 25 46q59 67 147 103.5t182 36.5q191 0 318 -125.5t127 -315.5q0 -37 -4 -66q57 15 115 15z" /> + <glyph glyph-name="_502" unicode="&#xf217;" horiz-adv-x="1664" +d="M1216 832q0 26 -19 45t-45 19h-128v128q0 26 -19 45t-45 19t-45 -19t-19 -45v-128h-128q-26 0 -45 -19t-19 -45t19 -45t45 -19h128v-128q0 -26 19 -45t45 -19t45 19t19 45v128h128q26 0 45 19t19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 +t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920 +q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" /> + <glyph glyph-name="_503" unicode="&#xf218;" horiz-adv-x="1664" +d="M1280 832q0 26 -19 45t-45 19t-45 -19l-147 -146v293q0 26 -19 45t-45 19t-45 -19t-19 -45v-293l-147 146q-19 19 -45 19t-45 -19t-19 -45t19 -45l256 -256q19 -19 45 -19t45 19l256 256q19 19 19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 +t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920 +q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" /> + <glyph glyph-name="_504" unicode="&#xf219;" horiz-adv-x="2048" +d="M212 768l623 -665l-300 665h-323zM1024 -4l349 772h-698zM538 896l204 384h-262l-288 -384h346zM1213 103l623 665h-323zM683 896h682l-204 384h-274zM1510 896h346l-288 384h-262zM1651 1382l384 -512q14 -18 13 -41.5t-17 -40.5l-960 -1024q-18 -20 -47 -20t-47 20 +l-960 1024q-16 17 -17 40.5t13 41.5l384 512q18 26 51 26h1152q33 0 51 -26z" /> + <glyph glyph-name="_505" unicode="&#xf21a;" horiz-adv-x="2048" +d="M1811 -19q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83 +q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83 +q19 19 45 19t45 -19l83 -83zM237 19q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -82l83 82q19 19 45 19t45 -19l83 -82l64 64v293l-210 314q-17 26 -7 56.5t40 40.5l177 58v299h128v128h256v128h256v-128h256v-128h128v-299l177 -58q30 -10 40 -40.5t-7 -56.5l-210 -314 +v-293l19 18q19 19 45 19t45 -19l83 -82l83 82q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83 +q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83zM640 1152v-128l384 128l384 -128v128h-128v128h-512v-128h-128z" /> + <glyph glyph-name="_506" unicode="&#xf21b;" +d="M576 0l96 448l-96 128l-128 64zM832 0l128 640l-128 -64l-96 -128zM992 1010q-2 4 -4 6q-10 8 -96 8q-70 0 -167 -19q-7 -2 -21 -2t-21 2q-97 19 -167 19q-86 0 -96 -8q-2 -2 -4 -6q2 -18 4 -27q2 -3 7.5 -6.5t7.5 -10.5q2 -4 7.5 -20.5t7 -20.5t7.5 -17t8.5 -17t9 -14 +t12 -13.5t14 -9.5t17.5 -8t20.5 -4t24.5 -2q36 0 59 12.5t32.5 30t14.5 34.5t11.5 29.5t17.5 12.5h12q11 0 17.5 -12.5t11.5 -29.5t14.5 -34.5t32.5 -30t59 -12.5q13 0 24.5 2t20.5 4t17.5 8t14 9.5t12 13.5t9 14t8.5 17t7.5 17t7 20.5t7.5 20.5q2 7 7.5 10.5t7.5 6.5 +q2 9 4 27zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 61 4.5 118t19 125.5t37.5 123.5t63.5 103.5t93.5 74.5l-90 220h214q-22 64 -22 128q0 12 2 32q-194 40 -194 96q0 57 210 99q17 62 51.5 134t70.5 114q32 37 76 37q30 0 84 -31t84 -31t84 31 +t84 31q44 0 76 -37q36 -42 70.5 -114t51.5 -134q210 -42 210 -99q0 -56 -194 -96q7 -81 -20 -160h214l-82 -225q63 -33 107.5 -96.5t65.5 -143.5t29 -151.5t8 -148.5z" /> + <glyph glyph-name="_507" unicode="&#xf21c;" horiz-adv-x="2304" +d="M2301 500q12 -103 -22 -198.5t-99 -163.5t-158.5 -106t-196.5 -31q-161 11 -279.5 125t-134.5 274q-12 111 27.5 210.5t118.5 170.5l-71 107q-96 -80 -151 -194t-55 -244q0 -27 -18.5 -46.5t-45.5 -19.5h-256h-69q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5 +t-131.5 316.5t131.5 316.5t316.5 131.5q76 0 152 -27l24 45q-123 110 -304 110h-64q-26 0 -45 19t-19 45t19 45t45 19h128q78 0 145 -13.5t116.5 -38.5t71.5 -39.5t51 -36.5h512h115l-85 128h-222q-30 0 -49 22.5t-14 52.5q4 23 23 38t43 15h253q33 0 53 -28l70 -105 +l114 114q19 19 46 19h101q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-179l115 -172q131 63 275 36q143 -26 244 -134.5t118 -253.5zM448 128q115 0 203 72.5t111 183.5h-314q-35 0 -55 31q-18 32 -1 63l147 277q-47 13 -91 13q-132 0 -226 -94t-94 -226t94 -226 +t226 -94zM1856 128q132 0 226 94t94 226t-94 226t-226 94q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94z" /> + <glyph glyph-name="_508" unicode="&#xf21d;" +d="M1408 0q0 -63 -61.5 -113.5t-164 -81t-225 -46t-253.5 -15.5t-253.5 15.5t-225 46t-164 81t-61.5 113.5q0 49 33 88.5t91 66.5t118 44.5t131 29.5q26 5 48 -10.5t26 -41.5q5 -26 -10.5 -48t-41.5 -26q-58 -10 -106 -23.5t-76.5 -25.5t-48.5 -23.5t-27.5 -19.5t-8.5 -12 +q3 -11 27 -26.5t73 -33t114 -32.5t160.5 -25t201.5 -10t201.5 10t160.5 25t114 33t73 33.5t27 27.5q-1 4 -8.5 11t-27.5 19t-48.5 23.5t-76.5 25t-106 23.5q-26 4 -41.5 26t-10.5 48q4 26 26 41.5t48 10.5q71 -12 131 -29.5t118 -44.5t91 -66.5t33 -88.5zM1024 896v-384 +q0 -26 -19 -45t-45 -19h-64v-384q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v384h-64q-26 0 -45 19t-19 45v384q0 53 37.5 90.5t90.5 37.5h384q53 0 90.5 -37.5t37.5 -90.5zM928 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5 +t158.5 -65.5t65.5 -158.5z" /> + <glyph glyph-name="_509" unicode="&#xf21e;" horiz-adv-x="1792" +d="M1280 512h305q-5 -6 -10 -10.5t-9 -7.5l-3 -4l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-5 2 -21 20h369q22 0 39.5 13.5t22.5 34.5l70 281l190 -667q6 -20 23 -33t39 -13q21 0 38 13t23 33l146 485l56 -112q18 -35 57 -35zM1792 940q0 -145 -103 -300h-369l-111 221 +q-8 17 -25.5 27t-36.5 8q-45 -5 -56 -46l-129 -430l-196 686q-6 20 -23.5 33t-39.5 13t-39 -13.5t-22 -34.5l-116 -464h-423q-103 155 -103 300q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124 +t127 -344z" /> + <glyph glyph-name="venus" unicode="&#xf221;" horiz-adv-x="1280" +d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292 +q11 134 80.5 249t182 188t245.5 88q170 19 319 -54t236 -212t87 -306zM128 960q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5z" /> + <glyph glyph-name="_511" unicode="&#xf222;" +d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-382 -383q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5 +q203 0 359 -126l382 382h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_512" unicode="&#xf223;" horiz-adv-x="1280" +d="M830 1220q145 -72 233.5 -210.5t88.5 -305.5q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5 +t-147.5 384.5q0 167 88.5 305.5t233.5 210.5q-165 96 -228 273q-6 16 3.5 29.5t26.5 13.5h69q21 0 29 -20q44 -106 140 -171t214 -65t214 65t140 171q8 20 37 20h61q17 0 26.5 -13.5t3.5 -29.5q-63 -177 -228 -273zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 +t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_513" unicode="&#xf224;" +d="M1024 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64 +q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-149 16 -270.5 103t-186.5 223.5t-53 291.5q16 204 160 353.5t347 172.5q118 14 228 -19t198 -103l255 254h-134q-14 0 -23 9t-9 23v64zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 +t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_514" unicode="&#xf225;" horiz-adv-x="1792" +d="M1280 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64 +q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5t-147.5 384.5q0 201 126 359l-52 53l-101 -111q-9 -10 -22 -10.5t-23 7.5l-48 44q-10 8 -10.5 21.5t8.5 23.5l105 115l-111 112v-134q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9 +t-9 23v288q0 26 19 45t45 19h288q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-133l106 -107l86 94q9 10 22 10.5t23 -7.5l48 -44q10 -8 10.5 -21.5t-8.5 -23.5l-90 -99l57 -56q158 126 359 126t359 -126l255 254h-134q-14 0 -23 9t-9 23v64zM832 256q185 0 316.5 131.5 +t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_515" unicode="&#xf226;" horiz-adv-x="1792" +d="M1790 1007q12 -155 -52.5 -292t-186 -224t-271.5 -103v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-512v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23 +t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292q17 206 164.5 356.5t352.5 169.5q206 21 377 -94q171 115 377 94q205 -19 352.5 -169.5t164.5 -356.5zM896 647q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM576 512q115 0 218 57q-154 165 -154 391 +q0 224 154 391q-103 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5zM1152 128v260q-137 15 -256 94q-119 -79 -256 -94v-260h512zM1216 512q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5q-115 0 -218 -57q154 -167 154 -391 +q0 -226 -154 -391q103 -57 218 -57z" /> + <glyph glyph-name="_516" unicode="&#xf227;" horiz-adv-x="1920" +d="M1536 1120q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-31 -182 -166 -312t-318 -156q-210 -29 -384.5 80t-241.5 300q-117 6 -221 57.5t-177.5 133t-113.5 192.5t-32 230 +q9 135 78 252t182 191.5t248 89.5q118 14 227.5 -19t198.5 -103l255 254h-134q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q59 -74 93 -169q182 -9 328 -124l255 254h-134q-14 0 -23 9 +t-9 23v64zM1024 704q0 20 -4 58q-162 -25 -271 -150t-109 -292q0 -20 4 -58q162 25 271 150t109 292zM128 704q0 -168 111 -294t276 -149q-3 29 -3 59q0 210 135 369.5t338 196.5q-53 120 -163.5 193t-245.5 73q-185 0 -316.5 -131.5t-131.5 -316.5zM1088 -128 +q185 0 316.5 131.5t131.5 316.5q0 168 -111 294t-276 149q3 -28 3 -59q0 -210 -135 -369.5t-338 -196.5q53 -120 163.5 -193t245.5 -73z" /> + <glyph glyph-name="_517" unicode="&#xf228;" horiz-adv-x="2048" +d="M1664 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-32 -180 -164.5 -310t-313.5 -157q-223 -34 -409 90q-117 -78 -256 -93v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23 +t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-155 17 -279.5 109.5t-187 237.5t-39.5 307q25 187 159.5 322.5t320.5 164.5q224 34 410 -90q146 97 320 97q201 0 359 -126l255 254h-134q-14 0 -23 9 +t-9 23v64zM896 391q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM128 704q0 -185 131.5 -316.5t316.5 -131.5q117 0 218 57q-154 167 -154 391t154 391q-101 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5zM1216 256q185 0 316.5 131.5t131.5 316.5 +t-131.5 316.5t-316.5 131.5q-117 0 -218 -57q154 -167 154 -391t-154 -391q101 -57 218 -57z" /> + <glyph glyph-name="_518" unicode="&#xf229;" +d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-213 -214l140 -140q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-140 141l-78 -79q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5 +t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5q203 0 359 -126l78 78l-172 172q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l172 -172l213 213h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 +t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_519" unicode="&#xf22a;" horiz-adv-x="1280" +d="M640 892q217 -24 364.5 -187.5t147.5 -384.5q0 -167 -87 -306t-236 -212t-319 -54q-133 15 -245.5 88t-182 188t-80.5 249q-12 155 52.5 292t186 224t271.5 103v132h-160q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h160v165l-92 -92q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22 +t9 23l202 201q19 19 45 19t45 -19l202 -201q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-92 92v-165h160q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-160v-132zM576 -128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5 +t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_520" unicode="&#xf22b;" horiz-adv-x="2048" +d="M1901 621q19 -19 19 -45t-19 -45l-294 -294q-9 -10 -22.5 -10t-22.5 10l-45 45q-10 9 -10 22.5t10 22.5l185 185h-294v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-132q-24 -217 -187.5 -364.5t-384.5 -147.5q-167 0 -306 87t-212 236t-54 319q15 133 88 245.5 +t188 182t249 80.5q155 12 292 -52.5t224 -186t103 -271.5h132v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h294l-185 185q-10 9 -10 22.5t10 22.5l45 45q9 10 22.5 10t22.5 -10zM576 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5 +t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_521" unicode="&#xf22c;" horiz-adv-x="1280" +d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-612q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v612q-217 24 -364.5 187.5t-147.5 384.5q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM576 512q185 0 316.5 131.5 +t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_522" unicode="&#xf22d;" horiz-adv-x="1280" +d="M1024 576q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1152 576q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123 +t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5z" /> + <glyph glyph-name="_523" unicode="&#xf22e;" horiz-adv-x="1792" + /> + <glyph glyph-name="_524" unicode="&#xf22f;" horiz-adv-x="1792" + /> + <glyph glyph-name="_525" unicode="&#xf230;" +d="M1451 1408q35 0 60 -25t25 -60v-1366q0 -35 -25 -60t-60 -25h-391v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-735q-35 0 -60 25t-25 60v1366q0 35 25 60t60 25h1366z" /> + <glyph glyph-name="_526" unicode="&#xf231;" horiz-adv-x="1280" +d="M0 939q0 108 37.5 203.5t103.5 166.5t152 123t185 78t202 26q158 0 294 -66.5t221 -193.5t85 -287q0 -96 -19 -188t-60 -177t-100 -149.5t-145 -103t-189 -38.5q-68 0 -135 32t-96 88q-10 -39 -28 -112.5t-23.5 -95t-20.5 -71t-26 -71t-32 -62.5t-46 -77.5t-62 -86.5 +l-14 -5l-9 10q-15 157 -15 188q0 92 21.5 206.5t66.5 287.5t52 203q-32 65 -32 169q0 83 52 156t132 73q61 0 95 -40.5t34 -102.5q0 -66 -44 -191t-44 -187q0 -63 45 -104.5t109 -41.5q55 0 102 25t78.5 68t56 95t38 110.5t20 111t6.5 99.5q0 173 -109.5 269.5t-285.5 96.5 +q-200 0 -334 -129.5t-134 -328.5q0 -44 12.5 -85t27 -65t27 -45.5t12.5 -30.5q0 -28 -15 -73t-37 -45q-2 0 -17 3q-51 15 -90.5 56t-61 94.5t-32.5 108t-11 106.5z" /> + <glyph glyph-name="_527" unicode="&#xf232;" +d="M985 562q13 0 97.5 -44t89.5 -53q2 -5 2 -15q0 -33 -17 -76q-16 -39 -71 -65.5t-102 -26.5q-57 0 -190 62q-98 45 -170 118t-148 185q-72 107 -71 194v8q3 91 74 158q24 22 52 22q6 0 18 -1.5t19 -1.5q19 0 26.5 -6.5t15.5 -27.5q8 -20 33 -88t25 -75q0 -21 -34.5 -57.5 +t-34.5 -46.5q0 -7 5 -15q34 -73 102 -137q56 -53 151 -101q12 -7 22 -7q15 0 54 48.5t52 48.5zM782 32q127 0 243.5 50t200.5 134t134 200.5t50 243.5t-50 243.5t-134 200.5t-200.5 134t-243.5 50t-243.5 -50t-200.5 -134t-134 -200.5t-50 -243.5q0 -203 120 -368l-79 -233 +l242 77q158 -104 345 -104zM782 1414q153 0 292.5 -60t240.5 -161t161 -240.5t60 -292.5t-60 -292.5t-161 -240.5t-240.5 -161t-292.5 -60q-195 0 -365 94l-417 -134l136 405q-108 178 -108 389q0 153 60 292.5t161 240.5t240.5 161t292.5 60z" /> + <glyph glyph-name="_528" unicode="&#xf233;" horiz-adv-x="1792" +d="M128 128h1024v128h-1024v-128zM128 640h1024v128h-1024v-128zM1696 192q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM128 1152h1024v128h-1024v-128zM1696 704q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1696 1216 +q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1792 384v-384h-1792v384h1792zM1792 896v-384h-1792v384h1792zM1792 1408v-384h-1792v384h1792z" /> + <glyph glyph-name="_529" unicode="&#xf234;" horiz-adv-x="2048" +d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1664 512h352q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-352q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5 +t-9.5 22.5v352h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v352q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-352zM928 288q0 -52 38 -90t90 -38h256v-238q-68 -50 -171 -50h-874q-121 0 -194 69t-73 190q0 53 3.5 103.5t14 109t26.5 108.5 +t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q79 -61 154.5 -91.5t164.5 -30.5t164.5 30.5t154.5 91.5q20 17 39 17q132 0 217 -96h-223q-52 0 -90 -38t-38 -90v-192z" /> + <glyph glyph-name="_530" unicode="&#xf235;" horiz-adv-x="2048" +d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1781 320l249 -249q9 -9 9 -23q0 -13 -9 -22l-136 -136q-9 -9 -22 -9q-14 0 -23 9l-249 249l-249 -249q-9 -9 -23 -9q-13 0 -22 9l-136 136 +q-9 9 -9 22q0 14 9 23l249 249l-249 249q-9 9 -9 23q0 13 9 22l136 136q9 9 22 9q14 0 23 -9l249 -249l249 249q9 9 23 9q13 0 22 -9l136 -136q9 -9 9 -22q0 -14 -9 -23zM1283 320l-181 -181q-37 -37 -37 -91q0 -53 37 -90l83 -83q-21 -3 -44 -3h-874q-121 0 -194 69 +t-73 190q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q154 -122 319 -122t319 122q20 17 39 17q28 0 57 -6q-28 -27 -41 -50t-13 -56q0 -54 37 -91z" /> + <glyph glyph-name="_531" unicode="&#xf236;" horiz-adv-x="2048" +d="M256 512h1728q26 0 45 -19t19 -45v-448h-256v256h-1536v-256h-256v1216q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-704zM832 832q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM2048 576v64q0 159 -112.5 271.5t-271.5 112.5h-704 +q-26 0 -45 -19t-19 -45v-384h1152z" /> + <glyph glyph-name="_532" unicode="&#xf237;" +d="M1536 1536l-192 -448h192v-192h-274l-55 -128h329v-192h-411l-357 -832l-357 832h-411v192h329l-55 128h-274v192h192l-192 448h256l323 -768h378l323 768h256zM768 320l108 256h-216z" /> + <glyph glyph-name="_533" unicode="&#xf238;" +d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM768 192q80 0 136 56t56 136t-56 136t-136 56 +t-136 -56t-56 -136t56 -136t136 -56zM1344 768v512h-1152v-512h1152z" /> + <glyph glyph-name="_534" unicode="&#xf239;" +d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM288 224q66 0 113 47t47 113t-47 113t-113 47 +t-113 -47t-47 -113t47 -113t113 -47zM704 768v512h-544v-512h544zM1248 224q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM1408 768v512h-576v-512h576z" /> + <glyph glyph-name="_535" unicode="&#xf23a;" horiz-adv-x="1792" +d="M597 1115v-1173q0 -25 -12.5 -42.5t-36.5 -17.5q-17 0 -33 8l-465 233q-21 10 -35.5 33.5t-14.5 46.5v1140q0 20 10 34t29 14q14 0 44 -15l511 -256q3 -3 3 -5zM661 1014l534 -866l-534 266v600zM1792 996v-1054q0 -25 -14 -40.5t-38 -15.5t-47 13l-441 220zM1789 1116 +q0 -3 -256.5 -419.5t-300.5 -487.5l-390 634l324 527q17 28 52 28q14 0 26 -6l541 -270q4 -2 4 -6z" /> + <glyph glyph-name="_536" unicode="&#xf23b;" +d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1408v-1536h-1536v1536h1536z" /> + <glyph glyph-name="_537" unicode="&#xf23c;" horiz-adv-x="2296" +d="M478 -139q-8 -16 -27 -34.5t-37 -25.5q-25 -9 -51.5 3.5t-28.5 31.5q-1 22 40 55t68 38q23 4 34 -21.5t2 -46.5zM1819 -139q7 -16 26 -34.5t38 -25.5q25 -9 51.5 3.5t27.5 31.5q2 22 -39.5 55t-68.5 38q-22 4 -33 -21.5t-2 -46.5zM1867 -30q13 -27 56.5 -59.5t77.5 -41.5 +q45 -13 82 4.5t37 50.5q0 46 -67.5 100.5t-115.5 59.5q-40 5 -63.5 -37.5t-6.5 -76.5zM428 -30q-13 -27 -56 -59.5t-77 -41.5q-45 -13 -82 4.5t-37 50.5q0 46 67.5 100.5t115.5 59.5q40 5 63 -37.5t6 -76.5zM1158 1094h1q-41 0 -76 -15q27 -8 44 -30.5t17 -49.5 +q0 -35 -27 -60t-65 -25q-52 0 -80 43q-5 -23 -5 -42q0 -74 56 -126.5t135 -52.5q80 0 136 52.5t56 126.5t-56 126.5t-136 52.5zM1462 1312q-99 109 -220.5 131.5t-245.5 -44.5q27 60 82.5 96.5t118 39.5t121.5 -17t99.5 -74.5t44.5 -131.5zM2212 73q8 -11 -11 -42 +q7 -23 7 -40q1 -56 -44.5 -112.5t-109.5 -91.5t-118 -37q-48 -2 -92 21.5t-66 65.5q-687 -25 -1259 0q-23 -41 -66.5 -65t-92.5 -22q-86 3 -179.5 80.5t-92.5 160.5q2 22 7 40q-19 31 -11 42q6 10 31 1q14 22 41 51q-7 29 2 38q11 10 39 -4q29 20 59 34q0 29 13 37 +q23 12 51 -16q35 5 61 -2q18 -4 38 -19v73q-11 0 -18 2q-53 10 -97 44.5t-55 87.5q-9 38 0 81q15 62 93 95q2 17 19 35.5t36 23.5t33 -7.5t19 -30.5h13q46 -5 60 -23q3 -3 5 -7q10 1 30.5 3.5t30.5 3.5q-15 11 -30 17q-23 40 -91 43q0 6 1 10q-62 2 -118.5 18.5t-84.5 47.5 +q-32 36 -42.5 92t-2.5 112q16 126 90 179q23 16 52 4.5t32 -40.5q0 -1 1.5 -14t2.5 -21t3 -20t5.5 -19t8.5 -10q27 -14 76 -12q48 46 98 74q-40 4 -162 -14l47 46q61 58 163 111q145 73 282 86q-20 8 -41 15.5t-47 14t-42.5 10.5t-47.5 11t-43 10q595 126 904 -139 +q98 -84 158 -222q85 -10 121 9h1q5 3 8.5 10t5.5 19t3 19.5t3 21.5l1 14q3 28 32 40t52 -5q73 -52 91 -178q7 -57 -3.5 -113t-42.5 -91q-28 -32 -83.5 -48.5t-115.5 -18.5v-10q-71 -2 -95 -43q-14 -5 -31 -17q11 -1 32 -3.5t30 -3.5q1 5 5 8q16 18 60 23h13q5 18 19 30t33 8 +t36 -23t19 -36q79 -32 93 -95q9 -40 1 -81q-12 -53 -56 -88t-97 -44q-10 -2 -17 -2q0 -49 -1 -73q20 15 38 19q26 7 61 2q28 28 51 16q14 -9 14 -37q33 -16 59 -34q27 13 38 4q10 -10 2 -38q28 -30 41 -51q23 8 31 -1zM1937 1025q0 -29 -9 -54q82 -32 112 -132 +q4 37 -9.5 98.5t-41.5 90.5q-20 19 -36 17t-16 -20zM1859 925q35 -42 47.5 -108.5t-0.5 -124.5q67 13 97 45q13 14 18 28q-3 64 -31 114.5t-79 66.5q-15 -15 -52 -21zM1822 921q-30 0 -44 1q42 -115 53 -239q21 0 43 3q16 68 1 135t-53 100zM258 839q30 100 112 132 +q-9 25 -9 54q0 18 -16.5 20t-35.5 -17q-28 -29 -41.5 -90.5t-9.5 -98.5zM294 737q29 -31 97 -45q-13 58 -0.5 124.5t47.5 108.5v0q-37 6 -52 21q-51 -16 -78.5 -66t-31.5 -115q9 -17 18 -28zM471 683q14 124 73 235q-19 -4 -55 -18l-45 -19v1q-46 -89 -20 -196q25 -3 47 -3z +M1434 644q8 -38 16.5 -108.5t11.5 -89.5q3 -18 9.5 -21.5t23.5 4.5q40 20 62 85.5t23 125.5q-24 2 -146 4zM1152 1285q-116 0 -199 -82.5t-83 -198.5q0 -117 83 -199.5t199 -82.5t199 82.5t83 199.5q0 116 -83 198.5t-199 82.5zM1380 646q-105 2 -211 0v1q-1 -27 2.5 -86 +t13.5 -66q29 -14 93.5 -14.5t95.5 10.5q9 3 11 39t-0.5 69.5t-4.5 46.5zM1112 447q8 4 9.5 48t-0.5 88t-4 63v1q-212 -3 -214 -3q-4 -20 -7 -62t0 -83t14 -46q34 -15 101 -16t101 10zM718 636q-16 -59 4.5 -118.5t77.5 -84.5q15 -8 24 -5t12 21q3 16 8 90t10 103 +q-69 -2 -136 -6zM591 510q3 -23 -34 -36q132 -141 271.5 -240t305.5 -154q172 49 310.5 146t293.5 250q-33 13 -30 34q0 2 0.5 3.5t1.5 3t1 2.5v1v-1q-17 2 -50 5.5t-48 4.5q-26 -90 -82 -132q-51 -38 -82 1q-5 6 -9 14q-7 13 -17 62q-2 -5 -5 -9t-7.5 -7t-8 -5.5t-9.5 -4 +l-10 -2.5t-12 -2l-12 -1.5t-13.5 -1t-13.5 -0.5q-106 -9 -163 11q-4 -17 -10 -26.5t-21 -15t-23 -7t-36 -3.5q-6 -1 -9 -1q-179 -17 -203 40q-2 -63 -56 -54q-47 8 -91 54q-12 13 -20 26q-17 29 -26 65q-58 -6 -87 -10q1 -2 4 -10zM507 -118q3 14 3 30q-17 71 -51 130 +t-73 70q-41 12 -101.5 -14.5t-104.5 -80t-39 -107.5q35 -53 100 -93t119 -42q51 -2 94 28t53 79zM510 53q23 -63 27 -119q195 113 392 174q-98 52 -180.5 120t-179.5 165q-6 -4 -29 -13q0 -1 -1 -4t-1 -5q31 -18 22 -37q-12 -23 -56 -34q-10 -13 -29 -24h-1q-2 -83 1 -150 +q19 -34 35 -73zM579 -113q532 -21 1145 0q-254 147 -428 196q-76 -35 -156 -57q-8 -3 -16 0q-65 21 -129 49q-208 -60 -416 -188h-1v-1q1 0 1 1zM1763 -67q4 54 28 120q14 38 33 71l-1 -1q3 77 3 153q-15 8 -30 25q-42 9 -56 33q-9 20 22 38q-2 4 -2 9q-16 4 -28 12 +q-204 -190 -383 -284q198 -59 414 -176zM2155 -90q5 54 -39 107.5t-104 80t-102 14.5q-38 -11 -72.5 -70.5t-51.5 -129.5q0 -16 3 -30q10 -49 53 -79t94 -28q54 2 119 42t100 93z" /> + <glyph glyph-name="_538" unicode="&#xf23d;" horiz-adv-x="2304" +d="M1524 -25q0 -68 -48 -116t-116 -48t-116.5 48t-48.5 116t48.5 116.5t116.5 48.5t116 -48.5t48 -116.5zM775 -25q0 -68 -48.5 -116t-116.5 -48t-116 48t-48 116t48 116.5t116 48.5t116.5 -48.5t48.5 -116.5zM0 1469q57 -60 110.5 -104.5t121 -82t136 -63t166 -45.5 +t200 -31.5t250 -18.5t304 -9.5t372.5 -2.5q139 0 244.5 -5t181 -16.5t124 -27.5t71 -39.5t24 -51.5t-19.5 -64t-56.5 -76.5t-89.5 -91t-116 -104.5t-139 -119q-185 -157 -286 -247q29 51 76.5 109t94 105.5t94.5 98.5t83 91.5t54 80.5t13 70t-45.5 55.5t-116.5 41t-204 23.5 +t-304 5q-168 -2 -314 6t-256 23t-204.5 41t-159.5 51.5t-122.5 62.5t-91.5 66.5t-68 71.5t-50.5 69.5t-40 68t-36.5 59.5z" /> + <glyph glyph-name="_539" unicode="&#xf23e;" horiz-adv-x="1792" +d="M896 1472q-169 0 -323 -66t-265.5 -177.5t-177.5 -265.5t-66 -323t66 -323t177.5 -265.5t265.5 -177.5t323 -66t323 66t265.5 177.5t177.5 265.5t66 323t-66 323t-177.5 265.5t-265.5 177.5t-323 66zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348 +t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM496 704q16 0 16 -16v-480q0 -16 -16 -16h-32q-16 0 -16 16v480q0 16 16 16h32zM896 640q53 0 90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-114q0 -14 -9 -23 +t-23 -9h-64q-14 0 -23 9t-9 23v114q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5zM896 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM544 928v-96 +q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5v-96q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 146 -103 249t-249 103t-249 -103t-103 -249zM1408 192v512q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-512 +q0 -26 19 -45t45 -19h896q26 0 45 19t19 45z" /> + <glyph glyph-name="_540" unicode="&#xf240;" horiz-adv-x="2304" +d="M1920 1024v-768h-1664v768h1664zM2048 448h128v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288zM2304 832v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113 +v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160q53 0 90.5 -37.5t37.5 -90.5z" /> + <glyph glyph-name="_541" unicode="&#xf241;" horiz-adv-x="2304" +d="M256 256v768h1280v-768h-1280zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9 +h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" /> + <glyph glyph-name="_542" unicode="&#xf242;" horiz-adv-x="2304" +d="M256 256v768h896v-768h-896zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9 +h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" /> + <glyph glyph-name="_543" unicode="&#xf243;" horiz-adv-x="2304" +d="M256 256v768h512v-768h-512zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9 +h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" /> + <glyph glyph-name="_544" unicode="&#xf244;" horiz-adv-x="2304" +d="M2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23 +v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" /> + <glyph glyph-name="_545" unicode="&#xf245;" horiz-adv-x="1280" +d="M1133 493q31 -30 14 -69q-17 -40 -59 -40h-382l201 -476q10 -25 0 -49t-34 -35l-177 -75q-25 -10 -49 0t-35 34l-191 452l-312 -312q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v1504q0 42 40 59q12 5 24 5q27 0 45 -19z" /> + <glyph glyph-name="_546" unicode="&#xf246;" horiz-adv-x="1024" +d="M832 1408q-320 0 -320 -224v-416h128v-128h-128v-544q0 -224 320 -224h64v-128h-64q-272 0 -384 146q-112 -146 -384 -146h-64v128h64q320 0 320 224v544h-128v128h128v416q0 224 -320 224h-64v128h64q272 0 384 -146q112 146 384 146h64v-128h-64z" /> + <glyph glyph-name="_547" unicode="&#xf247;" horiz-adv-x="2048" +d="M2048 1152h-128v-1024h128v-384h-384v128h-1280v-128h-384v384h128v1024h-128v384h384v-128h1280v128h384v-384zM1792 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 -128v128h-128v-128h128zM1664 0v128h128v1024h-128v128h-1280v-128h-128v-1024h128v-128 +h1280zM1920 -128v128h-128v-128h128zM1280 896h384v-768h-896v256h-384v768h896v-256zM512 512h640v512h-640v-512zM1536 256v512h-256v-384h-384v-128h640z" /> + <glyph glyph-name="_548" unicode="&#xf248;" horiz-adv-x="2304" +d="M2304 768h-128v-640h128v-384h-384v128h-896v-128h-384v384h128v128h-384v-128h-384v384h128v640h-128v384h384v-128h896v128h384v-384h-128v-128h384v128h384v-384zM2048 1024v-128h128v128h-128zM1408 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 256 +v128h-128v-128h128zM1536 384h-128v-128h128v128zM384 384h896v128h128v640h-128v128h-896v-128h-128v-640h128v-128zM896 -128v128h-128v-128h128zM2176 -128v128h-128v-128h128zM2048 128v640h-128v128h-384v-384h128v-384h-384v128h-384v-128h128v-128h896v128h128z" /> + <glyph glyph-name="_549" unicode="&#xf249;" +d="M1024 288v-416h-928q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68v-928h-416q-40 0 -68 -28t-28 -68zM1152 256h381q-15 -82 -65 -132l-184 -184q-50 -50 -132 -65v381z" /> + <glyph glyph-name="_550" unicode="&#xf24a;" +d="M1400 256h-248v-248q29 10 41 22l185 185q12 12 22 41zM1120 384h288v896h-1280v-1280h896v288q0 40 28 68t68 28zM1536 1312v-1024q0 -40 -20 -88t-48 -76l-184 -184q-28 -28 -76 -48t-88 -20h-1024q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68 +z" /> + <glyph glyph-name="_551" unicode="&#xf24b;" horiz-adv-x="2304" +d="M1951 538q0 -26 -15.5 -44.5t-38.5 -23.5q-8 -2 -18 -2h-153v140h153q10 0 18 -2q23 -5 38.5 -23.5t15.5 -44.5zM1933 751q0 -25 -15 -42t-38 -21q-3 -1 -15 -1h-139v129h139q3 0 8.5 -0.5t6.5 -0.5q23 -4 38 -21.5t15 -42.5zM728 587v308h-228v-308q0 -58 -38 -94.5 +t-105 -36.5q-108 0 -229 59v-112q53 -15 121 -23t109 -9l42 -1q328 0 328 217zM1442 403v113q-99 -52 -200 -59q-108 -8 -169 41t-61 142t61 142t169 41q101 -7 200 -58v112q-48 12 -100 19.5t-80 9.5l-28 2q-127 6 -218.5 -14t-140.5 -60t-71 -88t-22 -106t22 -106t71 -88 +t140.5 -60t218.5 -14q101 4 208 31zM2176 518q0 54 -43 88.5t-109 39.5v3q57 8 89 41.5t32 79.5q0 55 -41 88t-107 36q-3 0 -12 0.5t-14 0.5h-455v-510h491q74 0 121.5 36.5t47.5 96.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90 +t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_552" unicode="&#xf24c;" horiz-adv-x="2304" +d="M858 295v693q-106 -41 -172 -135.5t-66 -211.5t66 -211.5t172 -134.5zM1362 641q0 117 -66 211.5t-172 135.5v-694q106 41 172 135.5t66 211.5zM1577 641q0 -159 -78.5 -294t-213.5 -213.5t-294 -78.5q-119 0 -227.5 46.5t-187 125t-125 187t-46.5 227.5q0 159 78.5 294 +t213.5 213.5t294 78.5t294 -78.5t213.5 -213.5t78.5 -294zM1960 634q0 139 -55.5 261.5t-147.5 205.5t-213.5 131t-252.5 48h-301q-176 0 -323.5 -81t-235 -230t-87.5 -335q0 -171 87 -317.5t236 -231.5t323 -85h301q129 0 251.5 50.5t214.5 135t147.5 202.5t55.5 246z +M2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_553" unicode="&#xf24d;" horiz-adv-x="1792" +d="M1664 -96v1088q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5zM1792 992v-1088q0 -66 -47 -113t-113 -47h-1088q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113 +zM1408 1376v-160h-128v160q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h160v-128h-160q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113z" /> + <glyph glyph-name="_554" unicode="&#xf24e;" horiz-adv-x="2304" +d="M1728 1088l-384 -704h768zM448 1088l-384 -704h768zM1269 1280q-14 -40 -45.5 -71.5t-71.5 -45.5v-1291h608q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1344q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h608v1291q-40 14 -71.5 45.5t-45.5 71.5h-491q-14 0 -23 9t-9 23v64 +q0 14 9 23t23 9h491q21 57 70 92.5t111 35.5t111 -35.5t70 -92.5h491q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-491zM1088 1264q33 0 56.5 23.5t23.5 56.5t-23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5zM2176 384q0 -73 -46.5 -131t-117.5 -91 +t-144.5 -49.5t-139.5 -16.5t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81zM896 384q0 -73 -46.5 -131t-117.5 -91t-144.5 -49.5t-139.5 -16.5 +t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81z" /> + <glyph glyph-name="_555" unicode="&#xf250;" +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-77 -29 -149 -92.5 +t-129.5 -152.5t-92.5 -210t-35 -253h1024q0 132 -35 253t-92.5 210t-129.5 152.5t-149 92.5q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" /> + <glyph glyph-name="_556" unicode="&#xf251;" +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -66 9 -128h1006q9 61 9 128zM1280 -128q0 130 -34 249.5t-90.5 208t-126.5 152t-146 94.5h-230q-76 -31 -146 -94.5t-126.5 -152t-90.5 -208t-34 -249.5h1024z" /> + <glyph glyph-name="_557" unicode="&#xf252;" +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -206 85 -384h854q85 178 85 384zM1223 192q-54 141 -145.5 241.5t-194.5 142.5h-230q-103 -42 -194.5 -142.5t-145.5 -241.5h910z" /> + <glyph glyph-name="_558" unicode="&#xf253;" +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-137 -51 -244 -196 +h700q-107 145 -244 196q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" /> + <glyph glyph-name="_559" unicode="&#xf254;" +d="M1504 -64q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472zM130 0q3 55 16 107t30 95t46 87t53.5 76t64.5 69.5t66 60t70.5 55t66.5 47.5t65 43q-43 28 -65 43t-66.5 47.5t-70.5 55t-66 60t-64.5 69.5t-53.5 76t-46 87 +t-30 95t-16 107h1276q-3 -55 -16 -107t-30 -95t-46 -87t-53.5 -76t-64.5 -69.5t-66 -60t-70.5 -55t-66.5 -47.5t-65 -43q43 -28 65 -43t66.5 -47.5t70.5 -55t66 -60t64.5 -69.5t53.5 -76t46 -87t30 -95t16 -107h-1276zM1504 1536q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9 +h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472z" /> + <glyph glyph-name="_560" unicode="&#xf255;" +d="M768 1152q-53 0 -90.5 -37.5t-37.5 -90.5v-128h-32v93q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-429l-32 30v172q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-224q0 -47 35 -82l310 -296q39 -39 39 -102q0 -26 19 -45t45 -19h640q26 0 45 19t19 45v25 +q0 41 10 77l108 436q10 36 10 77v246q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-32h-32v125q0 40 -25 72.5t-64 40.5q-14 2 -23 2q-46 0 -79 -33t-33 -79v-128h-32v122q0 51 -32.5 89.5t-82.5 43.5q-5 1 -13 1zM768 1280q84 0 149 -50q57 34 123 34q59 0 111 -27 +t86 -76q27 7 59 7q100 0 170 -71.5t70 -171.5v-246q0 -51 -13 -108l-109 -436q-6 -24 -6 -71q0 -80 -56 -136t-136 -56h-640q-84 0 -138 58.5t-54 142.5l-308 296q-76 73 -76 175v224q0 99 70.5 169.5t169.5 70.5q11 0 16 -1q6 95 75.5 160t164.5 65q52 0 98 -21 +q72 69 174 69z" /> + <glyph glyph-name="_561" unicode="&#xf256;" horiz-adv-x="1792" +d="M880 1408q-46 0 -79 -33t-33 -79v-656h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528v-256l-154 205q-38 51 -102 51q-53 0 -90.5 -37.5t-37.5 -90.5q0 -43 26 -77l384 -512q38 -51 102 -51h688q34 0 61 22t34 56l76 405q5 32 5 59v498q0 46 -33 79t-79 33t-79 -33 +t-33 -79v-272h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528h-32v656q0 46 -33 79t-79 33zM880 1536q68 0 125.5 -35.5t88.5 -96.5q19 4 42 4q99 0 169.5 -70.5t70.5 -169.5v-17q105 6 180.5 -64t75.5 -175v-498q0 -40 -8 -83l-76 -404q-14 -79 -76.5 -131t-143.5 -52 +h-688q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 106 75 181t181 75q78 0 128 -34v434q0 99 70.5 169.5t169.5 70.5q23 0 42 -4q31 61 88.5 96.5t125.5 35.5z" /> + <glyph glyph-name="_562" unicode="&#xf257;" horiz-adv-x="1792" +d="M1073 -128h-177q-163 0 -226 141q-23 49 -23 102v5q-62 30 -98.5 88.5t-36.5 127.5q0 38 5 48h-261q-106 0 -181 75t-75 181t75 181t181 75h113l-44 17q-74 28 -119.5 93.5t-45.5 145.5q0 106 75 181t181 75q46 0 91 -17l628 -239h401q106 0 181 -75t75 -181v-668 +q0 -88 -54 -157.5t-140 -90.5l-339 -85q-92 -23 -186 -23zM1024 583l-155 -71l-163 -74q-30 -14 -48 -41.5t-18 -60.5q0 -46 33 -79t79 -33q26 0 46 10l338 154q-49 10 -80.5 50t-31.5 90v55zM1344 272q0 46 -33 79t-79 33q-26 0 -46 -10l-290 -132q-28 -13 -37 -17 +t-30.5 -17t-29.5 -23.5t-16 -29t-8 -40.5q0 -50 31.5 -82t81.5 -32q20 0 38 9l352 160q30 14 48 41.5t18 60.5zM1112 1024l-650 248q-24 8 -46 8q-53 0 -90.5 -37.5t-37.5 -90.5q0 -40 22.5 -73t59.5 -47l526 -200v-64h-640q-53 0 -90.5 -37.5t-37.5 -90.5t37.5 -90.5 +t90.5 -37.5h535l233 106v198q0 63 46 106l111 102h-69zM1073 0q82 0 155 19l339 85q43 11 70 45.5t27 78.5v668q0 53 -37.5 90.5t-90.5 37.5h-308l-136 -126q-36 -33 -36 -82v-296q0 -46 33 -77t79 -31t79 35t33 81v208h32v-208q0 -70 -57 -114q52 -8 86.5 -48.5t34.5 -93.5 +q0 -42 -23 -78t-61 -53l-310 -141h91z" /> + <glyph glyph-name="_563" unicode="&#xf258;" horiz-adv-x="2048" +d="M1151 1536q61 0 116 -28t91 -77l572 -781q118 -159 118 -359v-355q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v177l-286 143h-546q-80 0 -136 56t-56 136v32q0 119 84.5 203.5t203.5 84.5h420l42 128h-686q-100 0 -173.5 67.5t-81.5 166.5q-65 79 -65 182v32 +q0 80 56 136t136 56h959zM1920 -64v355q0 157 -93 284l-573 781q-39 52 -103 52h-959q-26 0 -45 -19t-19 -45q0 -32 1.5 -49.5t9.5 -40.5t25 -43q10 31 35.5 50t56.5 19h832v-32h-832q-26 0 -45 -19t-19 -45q0 -44 3 -58q8 -44 44 -73t81 -29h640h91q40 0 68 -28t28 -68 +q0 -15 -5 -30l-64 -192q-10 -29 -35 -47.5t-56 -18.5h-443q-66 0 -113 -47t-47 -113v-32q0 -26 19 -45t45 -19h561q16 0 29 -7l317 -158q24 -13 38.5 -36t14.5 -50v-197q0 -26 19 -45t45 -19h384q26 0 45 19t19 45z" /> + <glyph glyph-name="_564" unicode="&#xf259;" horiz-adv-x="2048" +d="M459 -256q-77 0 -137.5 47.5t-79.5 122.5l-101 401q-13 57 -13 108q0 45 -5 67l-116 477q-7 27 -7 57q0 93 62 161t155 78q17 85 82.5 139t152.5 54q83 0 148 -51.5t85 -132.5l83 -348l103 428q20 81 85 132.5t148 51.5q89 0 155.5 -57.5t80.5 -144.5q92 -10 152 -79 +t60 -162q0 -24 -7 -59l-123 -512q10 7 37.5 28.5t38.5 29.5t35 23t41 20.5t41.5 11t49.5 5.5q105 0 180 -74t75 -179q0 -62 -28.5 -118t-78.5 -94l-507 -380q-68 -51 -153 -51h-694zM1104 1408q-38 0 -68.5 -24t-39.5 -62l-164 -682h-127l-145 602q-9 38 -39.5 62t-68.5 24 +q-48 0 -80 -33t-32 -80q0 -15 3 -28l132 -547h-26l-99 408q-9 37 -40 62.5t-69 25.5q-47 0 -80 -33t-33 -79q0 -14 3 -26l116 -478q7 -28 9 -86t10 -88l100 -401q8 -32 34 -52.5t59 -20.5h694q42 0 76 26l507 379q56 43 56 110q0 52 -37.5 88.5t-89.5 36.5q-43 0 -77 -26 +l-307 -230v227q0 4 32 138t68 282t39 161q4 18 4 29q0 47 -32 81t-79 34q-39 0 -69.5 -24t-39.5 -62l-116 -482h-26l150 624q3 14 3 28q0 48 -31.5 82t-79.5 34z" /> + <glyph glyph-name="_565" unicode="&#xf25a;" horiz-adv-x="1792" +d="M640 1408q-53 0 -90.5 -37.5t-37.5 -90.5v-512v-384l-151 202q-41 54 -107 54q-52 0 -89 -38t-37 -90q0 -43 26 -77l384 -512q38 -51 102 -51h718q22 0 39.5 13.5t22.5 34.5l92 368q24 96 24 194v217q0 41 -28 71t-68 30t-68 -28t-28 -68h-32v61q0 48 -32 81.5t-80 33.5 +q-46 0 -79 -33t-33 -79v-64h-32v90q0 55 -37 94.5t-91 39.5q-53 0 -90.5 -37.5t-37.5 -90.5v-96h-32v570q0 55 -37 94.5t-91 39.5zM640 1536q107 0 181.5 -77.5t74.5 -184.5v-220q22 2 32 2q99 0 173 -69q47 21 99 21q113 0 184 -87q27 7 56 7q94 0 159 -67.5t65 -161.5 +v-217q0 -116 -28 -225l-92 -368q-16 -64 -68 -104.5t-118 -40.5h-718q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 105 74.5 180.5t179.5 75.5q71 0 130 -35v547q0 106 75 181t181 75zM768 128v384h-32v-384h32zM1024 128v384h-32v-384h32zM1280 128v384h-32 +v-384h32z" /> + <glyph glyph-name="_566" unicode="&#xf25b;" +d="M1288 889q60 0 107 -23q141 -63 141 -226v-177q0 -94 -23 -186l-85 -339q-21 -86 -90.5 -140t-157.5 -54h-668q-106 0 -181 75t-75 181v401l-239 628q-17 45 -17 91q0 106 75 181t181 75q80 0 145.5 -45.5t93.5 -119.5l17 -44v113q0 106 75 181t181 75t181 -75t75 -181 +v-261q27 5 48 5q69 0 127.5 -36.5t88.5 -98.5zM1072 896q-33 0 -60.5 -18t-41.5 -48l-74 -163l-71 -155h55q50 0 90 -31.5t50 -80.5l154 338q10 20 10 46q0 46 -33 79t-79 33zM1293 761q-22 0 -40.5 -8t-29 -16t-23.5 -29.5t-17 -30.5t-17 -37l-132 -290q-10 -20 -10 -46 +q0 -46 33 -79t79 -33q33 0 60.5 18t41.5 48l160 352q9 18 9 38q0 50 -32 81.5t-82 31.5zM128 1120q0 -22 8 -46l248 -650v-69l102 111q43 46 106 46h198l106 233v535q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5v-640h-64l-200 526q-14 37 -47 59.5t-73 22.5 +q-53 0 -90.5 -37.5t-37.5 -90.5zM1180 -128q44 0 78.5 27t45.5 70l85 339q19 73 19 155v91l-141 -310q-17 -38 -53 -61t-78 -23q-53 0 -93.5 34.5t-48.5 86.5q-44 -57 -114 -57h-208v32h208q46 0 81 33t35 79t-31 79t-77 33h-296q-49 0 -82 -36l-126 -136v-308 +q0 -53 37.5 -90.5t90.5 -37.5h668z" /> + <glyph glyph-name="_567" unicode="&#xf25c;" horiz-adv-x="1973" +d="M857 992v-117q0 -13 -9.5 -22t-22.5 -9h-298v-812q0 -13 -9 -22.5t-22 -9.5h-135q-13 0 -22.5 9t-9.5 23v812h-297q-13 0 -22.5 9t-9.5 22v117q0 14 9 23t23 9h793q13 0 22.5 -9.5t9.5 -22.5zM1895 995l77 -961q1 -13 -8 -24q-10 -10 -23 -10h-134q-12 0 -21 8.5 +t-10 20.5l-46 588l-189 -425q-8 -19 -29 -19h-120q-20 0 -29 19l-188 427l-45 -590q-1 -12 -10 -20.5t-21 -8.5h-135q-13 0 -23 10q-9 10 -9 24l78 961q1 12 10 20.5t21 8.5h142q20 0 29 -19l220 -520q10 -24 20 -51q3 7 9.5 24.5t10.5 26.5l221 520q9 19 29 19h141 +q13 0 22 -8.5t10 -20.5z" /> + <glyph glyph-name="_568" unicode="&#xf25d;" horiz-adv-x="1792" +d="M1042 833q0 88 -60 121q-33 18 -117 18h-123v-281h162q66 0 102 37t36 105zM1094 548l205 -373q8 -17 -1 -31q-8 -16 -27 -16h-152q-20 0 -28 17l-194 365h-155v-350q0 -14 -9 -23t-23 -9h-134q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h294q128 0 190 -24q85 -31 134 -109 +t49 -180q0 -92 -42.5 -165.5t-115.5 -109.5q6 -10 9 -16zM896 1376q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM1792 640 +q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="_569" unicode="&#xf25e;" horiz-adv-x="1792" +d="M605 303q153 0 257 104q14 18 3 36l-45 82q-6 13 -24 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13.5t-23.5 -14.5t-28.5 -13t-33.5 -9.5t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78 +q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-148 0 -246 -96.5t-98 -240.5q0 -146 97 -241.5t247 -95.5zM1235 303q153 0 257 104q14 18 4 36l-45 82q-8 14 -25 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13.5t-23.5 -14.5t-28.5 -13t-33.5 -9.5 +t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-147 0 -245.5 -96.5t-98.5 -240.5q0 -146 97 -241.5t247 -95.5zM896 1376 +q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191 +t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71z" /> + <glyph glyph-name="f260" unicode="&#xf260;" horiz-adv-x="2048" +d="M736 736l384 -384l-384 -384l-672 672l672 672l168 -168l-96 -96l-72 72l-480 -480l480 -480l193 193l-289 287zM1312 1312l672 -672l-672 -672l-168 168l96 96l72 -72l480 480l-480 480l-193 -193l289 -287l-96 -96l-384 384z" /> + <glyph glyph-name="f261" unicode="&#xf261;" horiz-adv-x="1792" +d="M717 182l271 271l-279 279l-88 -88l192 -191l-96 -96l-279 279l279 279l40 -40l87 87l-127 128l-454 -454zM1075 190l454 454l-454 454l-271 -271l279 -279l88 88l-192 191l96 96l279 -279l-279 -279l-40 40l-87 -88zM1792 640q0 -182 -71 -348t-191 -286t-286 -191 +t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="_572" unicode="&#xf262;" horiz-adv-x="2304" +d="M651 539q0 -39 -27.5 -66.5t-65.5 -27.5q-39 0 -66.5 27.5t-27.5 66.5q0 38 27.5 65.5t66.5 27.5q38 0 65.5 -27.5t27.5 -65.5zM1805 540q0 -39 -27.5 -66.5t-66.5 -27.5t-66.5 27.5t-27.5 66.5t27.5 66t66.5 27t66.5 -27t27.5 -66zM765 539q0 79 -56.5 136t-136.5 57 +t-136.5 -56.5t-56.5 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM1918 540q0 80 -56.5 136.5t-136.5 56.5q-79 0 -136 -56.5t-57 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM850 539q0 -116 -81.5 -197.5t-196.5 -81.5q-116 0 -197.5 82t-81.5 197 +t82 196.5t197 81.5t196.5 -81.5t81.5 -196.5zM2004 540q0 -115 -81.5 -196.5t-197.5 -81.5q-115 0 -196.5 81.5t-81.5 196.5t81.5 196.5t196.5 81.5q116 0 197.5 -81.5t81.5 -196.5zM1040 537q0 191 -135.5 326.5t-326.5 135.5q-125 0 -231 -62t-168 -168.5t-62 -231.5 +t62 -231.5t168 -168.5t231 -62q191 0 326.5 135.5t135.5 326.5zM1708 1110q-254 111 -556 111q-319 0 -573 -110q117 0 223 -45.5t182.5 -122.5t122 -183t45.5 -223q0 115 43.5 219.5t118 180.5t177.5 123t217 50zM2187 537q0 191 -135 326.5t-326 135.5t-326.5 -135.5 +t-135.5 -326.5t135.5 -326.5t326.5 -135.5t326 135.5t135 326.5zM1921 1103h383q-44 -51 -75 -114.5t-40 -114.5q110 -151 110 -337q0 -156 -77 -288t-209 -208.5t-287 -76.5q-133 0 -249 56t-196 155q-47 -56 -129 -179q-11 22 -53.5 82.5t-74.5 97.5 +q-80 -99 -196.5 -155.5t-249.5 -56.5q-155 0 -287 76.5t-209 208.5t-77 288q0 186 110 337q-9 51 -40 114.5t-75 114.5h365q149 100 355 156.5t432 56.5q224 0 421 -56t348 -157z" /> + <glyph glyph-name="f263" unicode="&#xf263;" horiz-adv-x="1280" +d="M640 629q-188 0 -321 133t-133 320q0 188 133 321t321 133t321 -133t133 -321q0 -187 -133 -320t-321 -133zM640 1306q-92 0 -157.5 -65.5t-65.5 -158.5q0 -92 65.5 -157.5t157.5 -65.5t157.5 65.5t65.5 157.5q0 93 -65.5 158.5t-157.5 65.5zM1163 574q13 -27 15 -49.5 +t-4.5 -40.5t-26.5 -38.5t-42.5 -37t-61.5 -41.5q-115 -73 -315 -94l73 -72l267 -267q30 -31 30 -74t-30 -73l-12 -13q-31 -30 -74 -30t-74 30q-67 68 -267 268l-267 -268q-31 -30 -74 -30t-73 30l-12 13q-31 30 -31 73t31 74l267 267l72 72q-203 21 -317 94 +q-39 25 -61.5 41.5t-42.5 37t-26.5 38.5t-4.5 40.5t15 49.5q10 20 28 35t42 22t56 -2t65 -35q5 -4 15 -11t43 -24.5t69 -30.5t92 -24t113 -11q91 0 174 25.5t120 50.5l38 25q33 26 65 35t56 2t42 -22t28 -35z" /> + <glyph glyph-name="_574" unicode="&#xf264;" +d="M927 956q0 -66 -46.5 -112.5t-112.5 -46.5t-112.5 46.5t-46.5 112.5t46.5 112.5t112.5 46.5t112.5 -46.5t46.5 -112.5zM1141 593q-10 20 -28 32t-47.5 9.5t-60.5 -27.5q-10 -8 -29 -20t-81 -32t-127 -20t-124 18t-86 36l-27 18q-31 25 -60.5 27.5t-47.5 -9.5t-28 -32 +q-22 -45 -2 -74.5t87 -73.5q83 -53 226 -67l-51 -52q-142 -142 -191 -190q-22 -22 -22 -52.5t22 -52.5l9 -9q22 -22 52.5 -22t52.5 22l191 191q114 -115 191 -191q22 -22 52.5 -22t52.5 22l9 9q22 22 22 52.5t-22 52.5l-191 190l-52 52q141 14 225 67q67 44 87 73.5t-2 74.5 +zM1092 956q0 134 -95 229t-229 95t-229 -95t-95 -229t95 -229t229 -95t229 95t95 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_575" unicode="&#xf265;" horiz-adv-x="1720" +d="M1565 1408q65 0 110 -45.5t45 -110.5v-519q0 -176 -68 -336t-182.5 -275t-274 -182.5t-334.5 -67.5q-176 0 -335.5 67.5t-274.5 182.5t-183 275t-68 336v519q0 64 46 110t110 46h1409zM861 344q47 0 82 33l404 388q37 35 37 85q0 49 -34.5 83.5t-83.5 34.5q-47 0 -82 -33 +l-323 -310l-323 310q-35 33 -81 33q-49 0 -83.5 -34.5t-34.5 -83.5q0 -51 36 -85l405 -388q33 -33 81 -33z" /> + <glyph glyph-name="_576" unicode="&#xf266;" horiz-adv-x="2304" +d="M1494 -103l-295 695q-25 -49 -158.5 -305.5t-198.5 -389.5q-1 -1 -27.5 -0.5t-26.5 1.5q-82 193 -255.5 587t-259.5 596q-21 50 -66.5 107.5t-103.5 100.5t-102 43q0 5 -0.5 24t-0.5 27h583v-50q-39 -2 -79.5 -16t-66.5 -43t-10 -64q26 -59 216.5 -499t235.5 -540 +q31 61 140 266.5t131 247.5q-19 39 -126 281t-136 295q-38 69 -201 71v50l513 -1v-47q-60 -2 -93.5 -25t-12.5 -69q33 -70 87 -189.5t86 -187.5q110 214 173 363q24 55 -10 79.5t-129 26.5q1 7 1 25v24q64 0 170.5 0.5t180 1t92.5 0.5v-49q-62 -2 -119 -33t-90 -81 +l-213 -442q13 -33 127.5 -290t121.5 -274l441 1017q-14 38 -49.5 62.5t-65 31.5t-55.5 8v50l460 -4l1 -2l-1 -44q-139 -4 -201 -145q-526 -1216 -559 -1291h-49z" /> + <glyph glyph-name="_577" unicode="&#xf267;" horiz-adv-x="1792" +d="M949 643q0 -26 -16.5 -45t-41.5 -19q-26 0 -45 16.5t-19 41.5q0 26 17 45t42 19t44 -16.5t19 -41.5zM964 585l350 581q-9 -8 -67.5 -62.5t-125.5 -116.5t-136.5 -127t-117 -110.5t-50.5 -51.5l-349 -580q7 7 67 62t126 116.5t136 127t117 111t50 50.5zM1611 640 +q0 -201 -104 -371q-3 2 -17 11t-26.5 16.5t-16.5 7.5q-13 0 -13 -13q0 -10 59 -44q-74 -112 -184.5 -190.5t-241.5 -110.5l-16 67q-1 10 -15 10q-5 0 -8 -5.5t-2 -9.5l16 -68q-72 -15 -146 -15q-199 0 -372 105q1 2 13 20.5t21.5 33.5t9.5 19q0 13 -13 13q-6 0 -17 -14.5 +t-22.5 -34.5t-13.5 -23q-113 75 -192 187.5t-110 244.5l69 15q10 3 10 15q0 5 -5.5 8t-10.5 2l-68 -15q-14 72 -14 139q0 206 109 379q2 -1 18.5 -12t30 -19t17.5 -8q13 0 13 12q0 6 -12.5 15.5t-32.5 21.5l-20 12q77 112 189 189t244 107l15 -67q2 -10 15 -10q5 0 8 5.5 +t2 10.5l-15 66q71 13 134 13q204 0 379 -109q-39 -56 -39 -65q0 -13 12 -13q11 0 48 64q111 -75 187.5 -186t107.5 -241l-56 -12q-10 -2 -10 -16q0 -5 5.5 -8t9.5 -2l57 13q14 -72 14 -140zM1696 640q0 163 -63.5 311t-170.5 255t-255 170.5t-311 63.5t-311 -63.5 +t-255 -170.5t-170.5 -255t-63.5 -311t63.5 -311t170.5 -255t255 -170.5t311 -63.5t311 63.5t255 170.5t170.5 255t63.5 311zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191 +t191 -286t71 -348z" /> + <glyph glyph-name="_578" unicode="&#xf268;" horiz-adv-x="1792" +d="M893 1536q240 2 451 -120q232 -134 352 -372l-742 39q-160 9 -294 -74.5t-185 -229.5l-276 424q128 159 311 245.5t383 87.5zM146 1131l337 -663q72 -143 211 -217t293 -45l-230 -451q-212 33 -385 157.5t-272.5 316t-99.5 411.5q0 267 146 491zM1732 962 +q58 -150 59.5 -310.5t-48.5 -306t-153 -272t-246 -209.5q-230 -133 -498 -119l405 623q88 131 82.5 290.5t-106.5 277.5zM896 942q125 0 213.5 -88.5t88.5 -213.5t-88.5 -213.5t-213.5 -88.5t-213.5 88.5t-88.5 213.5t88.5 213.5t213.5 88.5z" /> + <glyph glyph-name="_579" unicode="&#xf269;" horiz-adv-x="1792" +d="M903 -256q-283 0 -504.5 150.5t-329.5 398.5q-58 131 -67 301t26 332.5t111 312t179 242.5l-11 -281q11 14 68 15.5t70 -15.5q42 81 160.5 138t234.5 59q-54 -45 -119.5 -148.5t-58.5 -163.5q25 -8 62.5 -13.5t63 -7.5t68 -4t50.5 -3q15 -5 9.5 -45.5t-30.5 -75.5 +q-5 -7 -16.5 -18.5t-56.5 -35.5t-101 -34l15 -189l-139 67q-18 -43 -7.5 -81.5t36 -66.5t65.5 -41.5t81 -6.5q51 9 98 34.5t83.5 45t73.5 17.5q61 -4 89.5 -33t19.5 -65q-1 -2 -2.5 -5.5t-8.5 -12.5t-18 -15.5t-31.5 -10.5t-46.5 -1q-60 -95 -144.5 -135.5t-209.5 -29.5 +q74 -61 162.5 -82.5t168.5 -6t154.5 52t128 87.5t80.5 104q43 91 39 192.5t-37.5 188.5t-78.5 125q87 -38 137 -79.5t77 -112.5q15 170 -57.5 343t-209.5 284q265 -77 412 -279.5t151 -517.5q2 -127 -40.5 -255t-123.5 -238t-189 -196t-247.5 -135.5t-288.5 -49.5z" /> + <glyph glyph-name="_580" unicode="&#xf26a;" horiz-adv-x="1792" +d="M1493 1308q-165 110 -359 110q-155 0 -293 -73t-240 -200q-75 -93 -119.5 -218t-48.5 -266v-42q4 -141 48.5 -266t119.5 -218q102 -127 240 -200t293 -73q194 0 359 110q-121 -108 -274.5 -168t-322.5 -60q-29 0 -43 1q-175 8 -333 82t-272 193t-181 281t-67 339 +q0 182 71 348t191 286t286 191t348 71h3q168 -1 320.5 -60.5t273.5 -167.5zM1792 640q0 -192 -77 -362.5t-213 -296.5q-104 -63 -222 -63q-137 0 -255 84q154 56 253.5 233t99.5 405q0 227 -99 404t-253 234q119 83 254 83q119 0 226 -65q135 -125 210.5 -295t75.5 -361z +" /> + <glyph glyph-name="_581" unicode="&#xf26b;" horiz-adv-x="1792" +d="M1792 599q0 -56 -7 -104h-1151q0 -146 109.5 -244.5t257.5 -98.5q99 0 185.5 46.5t136.5 130.5h423q-56 -159 -170.5 -281t-267.5 -188.5t-321 -66.5q-187 0 -356 83q-228 -116 -394 -116q-237 0 -237 263q0 115 45 275q17 60 109 229q199 360 475 606 +q-184 -79 -427 -354q63 274 283.5 449.5t501.5 175.5q30 0 45 -1q255 117 433 117q64 0 116 -13t94.5 -40.5t66.5 -76.5t24 -115q0 -116 -75 -286q101 -182 101 -390zM1722 1239q0 83 -53 132t-137 49q-108 0 -254 -70q121 -47 222.5 -131.5t170.5 -195.5q51 135 51 216z +M128 2q0 -86 48.5 -132.5t134.5 -46.5q115 0 266 83q-122 72 -213.5 183t-137.5 245q-98 -205 -98 -332zM632 715h728q-5 142 -113 237t-251 95q-144 0 -251.5 -95t-112.5 -237z" /> + <glyph glyph-name="_582" unicode="&#xf26c;" horiz-adv-x="2048" +d="M1792 288v960q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1248v-960q0 -66 -47 -113t-113 -47h-736v-128h352q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23 +v64q0 14 9 23t23 9h352v128h-736q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> + <glyph glyph-name="_583" unicode="&#xf26d;" horiz-adv-x="1792" +d="M138 1408h197q-70 -64 -126 -149q-36 -56 -59 -115t-30 -125.5t-8.5 -120t10.5 -132t21 -126t28 -136.5q4 -19 6 -28q51 -238 81 -329q57 -171 152 -275h-272q-48 0 -82 34t-34 82v1304q0 48 34 82t82 34zM1346 1408h308q48 0 82 -34t34 -82v-1304q0 -48 -34 -82t-82 -34 +h-178q212 210 196 565l-469 -101q-2 -45 -12 -82t-31 -72t-59.5 -59.5t-93.5 -36.5q-123 -26 -199 40q-32 27 -53 61t-51.5 129t-64.5 258q-35 163 -45.5 263t-5.5 139t23 77q20 41 62.5 73t102.5 45q45 12 83.5 6.5t67 -17t54 -35t43 -48t34.5 -56.5l468 100 +q-68 175 -180 287z" /> + <glyph glyph-name="_584" unicode="&#xf26e;" +d="M1401 -11l-6 -6q-113 -113 -259 -175q-154 -64 -317 -64q-165 0 -317 64q-148 63 -259 175q-113 112 -175 258q-42 103 -54 189q-4 28 48 36q51 8 56 -20q1 -1 1 -4q18 -90 46 -159q50 -124 152 -226q98 -98 226 -152q132 -56 276 -56q143 0 276 56q128 55 225 152l6 6 +q10 10 25 6q12 -3 33 -22q36 -37 17 -58zM929 604l-66 -66l63 -63q21 -21 -7 -49q-17 -17 -32 -17q-10 0 -19 10l-62 61l-66 -66q-5 -5 -15 -5q-15 0 -31 16l-2 2q-18 15 -18 29q0 7 8 17l66 65l-66 66q-16 16 14 45q18 18 31 18q6 0 13 -5l65 -66l65 65q18 17 48 -13 +q27 -27 11 -44zM1400 547q0 -118 -46 -228q-45 -105 -126 -186q-80 -80 -187 -126t-228 -46t-228 46t-187 126q-82 82 -125 186q-15 33 -15 40h-1q-9 27 43 44q50 16 60 -12q37 -99 97 -167h1v339v2q3 136 102 232q105 103 253 103q147 0 251 -103t104 -249 +q0 -147 -104.5 -251t-250.5 -104q-58 0 -112 16q-28 11 -13 61q16 51 44 43l14 -3q14 -3 33 -6t30 -3q104 0 176 71.5t72 174.5q0 101 -72 171q-71 71 -175 71q-107 0 -178 -80q-64 -72 -64 -160v-413q110 -67 242 -67q96 0 185 36.5t156 103.5t103.5 155t36.5 183 +q0 198 -141 339q-140 140 -339 140q-200 0 -340 -140q-53 -53 -77 -87l-2 -2q-8 -11 -13 -15.5t-21.5 -9.5t-38.5 3q-21 5 -36.5 16.5t-15.5 26.5v680q0 15 10.5 26.5t27.5 11.5h877q30 0 30 -55t-30 -55h-811v-483h1q40 42 102 84t108 61q109 46 231 46q121 0 228 -46 +t187 -126q81 -81 126 -186q46 -112 46 -229zM1369 1128q9 -8 9 -18t-5.5 -18t-16.5 -21q-26 -26 -39 -26q-9 0 -16 7q-106 91 -207 133q-128 56 -276 56q-133 0 -262 -49q-27 -10 -45 37q-9 25 -8 38q3 16 16 20q130 57 299 57q164 0 316 -64q137 -58 235 -152z" /> + <glyph glyph-name="_585" unicode="&#xf270;" horiz-adv-x="1792" +d="M1551 60q15 6 26 3t11 -17.5t-15 -33.5q-13 -16 -44 -43.5t-95.5 -68t-141 -74t-188 -58t-229.5 -24.5q-119 0 -238 31t-209 76.5t-172.5 104t-132.5 105t-84 87.5q-8 9 -10 16.5t1 12t8 7t11.5 2t11.5 -4.5q192 -117 300 -166q389 -176 799 -90q190 40 391 135z +M1758 175q11 -16 2.5 -69.5t-28.5 -102.5q-34 -83 -85 -124q-17 -14 -26 -9t0 24q21 45 44.5 121.5t6.5 98.5q-5 7 -15.5 11.5t-27 6t-29.5 2.5t-35 0t-31.5 -2t-31 -3t-22.5 -2q-6 -1 -13 -1.5t-11 -1t-8.5 -1t-7 -0.5h-5.5h-4.5t-3 0.5t-2 1.5l-1.5 3q-6 16 47 40t103 30 +q46 7 108 1t76 -24zM1364 618q0 -31 13.5 -64t32 -58t37.5 -46t33 -32l13 -11l-227 -224q-40 37 -79 75.5t-58 58.5l-19 20q-11 11 -25 33q-38 -59 -97.5 -102.5t-127.5 -63.5t-140 -23t-137.5 21t-117.5 65.5t-83 113t-31 162.5q0 84 28 154t72 116.5t106.5 83t122.5 57 +t130 34.5t119.5 18.5t99.5 6.5v127q0 65 -21 97q-34 53 -121 53q-6 0 -16.5 -1t-40.5 -12t-56 -29.5t-56 -59.5t-48 -96l-294 27q0 60 22 119t67 113t108 95t151.5 65.5t190.5 24.5q100 0 181 -25t129.5 -61.5t81 -83t45 -86t12.5 -73.5v-589zM692 597q0 -86 70 -133 +q66 -44 139 -22q84 25 114 123q14 45 14 101v162q-59 -2 -111 -12t-106.5 -33.5t-87 -71t-32.5 -114.5z" /> + <glyph glyph-name="_586" unicode="&#xf271;" horiz-adv-x="1792" +d="M1536 1280q52 0 90 -38t38 -90v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128zM1152 1376v-288q0 -14 9 -23t23 -9 +h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 1376v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM1536 -128v1024h-1408v-1024h1408zM896 448h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224 +v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224z" /> + <glyph glyph-name="_587" unicode="&#xf272;" horiz-adv-x="1792" +d="M1152 416v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23 +t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47 +t47 -113v-96h128q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_588" unicode="&#xf273;" horiz-adv-x="1792" +d="M1111 151l-46 -46q-9 -9 -22 -9t-23 9l-188 189l-188 -189q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22t9 23l189 188l-189 188q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l188 -188l188 188q10 9 23 9t22 -9l46 -46q9 -9 9 -22t-9 -23l-188 -188l188 -188q9 -10 9 -23t-9 -22z +M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280 +q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_589" unicode="&#xf274;" horiz-adv-x="1792" +d="M1303 572l-512 -512q-10 -9 -23 -9t-23 9l-288 288q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l220 -220l444 444q10 9 23 9t22 -9l46 -46q9 -9 9 -22t-9 -23zM128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23 +t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47 +t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_590" unicode="&#xf275;" horiz-adv-x="1792" +d="M448 1536q26 0 45 -19t19 -45v-891l536 429q17 14 40 14q26 0 45 -19t19 -45v-379l536 429q17 14 40 14q26 0 45 -19t19 -45v-1152q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h384z" /> + <glyph glyph-name="_591" unicode="&#xf276;" horiz-adv-x="1024" +d="M512 448q66 0 128 15v-655q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v655q62 -15 128 -15zM512 1536q212 0 362 -150t150 -362t-150 -362t-362 -150t-362 150t-150 362t150 362t362 150zM512 1312q14 0 23 9t9 23t-9 23t-23 9q-146 0 -249 -103t-103 -249 +q0 -14 9 -23t23 -9t23 9t9 23q0 119 84.5 203.5t203.5 84.5z" /> + <glyph glyph-name="_592" unicode="&#xf277;" horiz-adv-x="1792" +d="M1745 1239q10 -10 10 -23t-10 -23l-141 -141q-28 -28 -68 -28h-1344q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h576v64q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-64h512q40 0 68 -28zM768 320h256v-512q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v512zM1600 768 +q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1344q-40 0 -68 28l-141 141q-10 10 -10 23t10 23l141 141q28 28 68 28h512v192h256v-192h576z" /> + <glyph glyph-name="_593" unicode="&#xf278;" horiz-adv-x="2048" +d="M2020 1525q28 -20 28 -53v-1408q0 -20 -11 -36t-29 -23l-640 -256q-24 -11 -48 0l-616 246l-616 -246q-10 -5 -24 -5q-19 0 -36 11q-28 20 -28 53v1408q0 20 11 36t29 23l640 256q24 11 48 0l616 -246l616 246q32 13 60 -6zM736 1390v-1270l576 -230v1270zM128 1173 +v-1270l544 217v1270zM1920 107v1270l-544 -217v-1270z" /> + <glyph glyph-name="_594" unicode="&#xf279;" horiz-adv-x="1792" +d="M512 1536q13 0 22.5 -9.5t9.5 -22.5v-1472q0 -20 -17 -28l-480 -256q-7 -4 -15 -4q-13 0 -22.5 9.5t-9.5 22.5v1472q0 20 17 28l480 256q7 4 15 4zM1760 1536q13 0 22.5 -9.5t9.5 -22.5v-1472q0 -20 -17 -28l-480 -256q-7 -4 -15 -4q-13 0 -22.5 9.5t-9.5 22.5v1472 +q0 20 17 28l480 256q7 4 15 4zM640 1536q8 0 14 -3l512 -256q18 -10 18 -29v-1472q0 -13 -9.5 -22.5t-22.5 -9.5q-8 0 -14 3l-512 256q-18 10 -18 29v1472q0 13 9.5 22.5t22.5 9.5z" /> + <glyph glyph-name="_595" unicode="&#xf27a;" horiz-adv-x="1792" +d="M640 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 640q0 53 -37.5 90.5t-90.5 37.5 +t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-110 0 -211 18q-173 -173 -435 -229q-52 -10 -86 -13q-12 -1 -22 6t-13 18q-4 15 20 37q5 5 23.5 21.5t25.5 23.5t23.5 25.5t24 31.5t20.5 37 +t20 48t14.5 57.5t12.5 72.5q-146 90 -229.5 216.5t-83.5 269.5q0 174 120 321.5t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" /> + <glyph glyph-name="_596" unicode="&#xf27b;" horiz-adv-x="1792" +d="M640 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 -53 -37.5 -90.5t-90.5 -37.5 +t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5 +t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51 +t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 130 71 248.5t191 204.5t286 136.5t348 50.5t348 -50.5t286 -136.5t191 -204.5t71 -248.5z" /> + <glyph glyph-name="_597" unicode="&#xf27c;" horiz-adv-x="1024" +d="M512 345l512 295v-591l-512 -296v592zM0 640v-591l512 296zM512 1527v-591l-512 -296v591zM512 936l512 295v-591z" /> + <glyph glyph-name="_598" unicode="&#xf27d;" horiz-adv-x="1792" +d="M1709 1018q-10 -236 -332 -651q-333 -431 -562 -431q-142 0 -240 263q-44 160 -132 482q-72 262 -157 262q-18 0 -127 -76l-77 98q24 21 108 96.5t130 115.5q156 138 241 146q95 9 153 -55.5t81 -203.5q44 -287 66 -373q55 -249 120 -249q51 0 154 161q101 161 109 246 +q13 139 -109 139q-57 0 -121 -26q120 393 459 382q251 -8 236 -326z" /> + <glyph glyph-name="f27e" unicode="&#xf27e;" +d="M0 1408h1536v-1536h-1536v1536zM1085 293l-221 631l221 297h-634l221 -297l-221 -631l317 -304z" /> + <glyph glyph-name="uniF280" unicode="&#xf280;" +d="M0 1408h1536v-1536h-1536v1536zM908 1088l-12 -33l75 -83l-31 -114l25 -25l107 57l107 -57l25 25l-31 114l75 83l-12 33h-95l-53 96h-32l-53 -96h-95zM641 925q32 0 44.5 -16t11.5 -63l174 21q0 55 -17.5 92.5t-50.5 56t-69 25.5t-85 7q-133 0 -199 -57.5t-66 -182.5v-72 +h-96v-128h76q20 0 20 -8v-382q0 -14 -5 -20t-18 -7l-73 -7v-88h448v86l-149 14q-6 1 -8.5 1.5t-3.5 2.5t-0.5 4t1 7t0.5 10v387h191l38 128h-231q-6 0 -2 6t4 9v80q0 27 1.5 40.5t7.5 28t19.5 20t36.5 5.5zM1248 96v86l-54 9q-7 1 -9.5 2.5t-2.5 3t1 7.5t1 12v520h-275 +l-23 -101l83 -22q23 -7 23 -27v-370q0 -14 -6 -18.5t-20 -6.5l-70 -9v-86h352z" /> + <glyph glyph-name="uniF281" unicode="&#xf281;" horiz-adv-x="1792" +d="M1792 690q0 -58 -29.5 -105.5t-79.5 -72.5q12 -46 12 -96q0 -155 -106.5 -287t-290.5 -208.5t-400 -76.5t-399.5 76.5t-290 208.5t-106.5 287q0 47 11 94q-51 25 -82 73.5t-31 106.5q0 82 58 140.5t141 58.5q85 0 145 -63q218 152 515 162l116 521q3 13 15 21t26 5 +l369 -81q18 37 54 59.5t79 22.5q62 0 106 -43.5t44 -105.5t-44 -106t-106 -44t-105.5 43.5t-43.5 105.5l-334 74l-104 -472q300 -9 519 -160q58 61 143 61q83 0 141 -58.5t58 -140.5zM418 491q0 -62 43.5 -106t105.5 -44t106 44t44 106t-44 105.5t-106 43.5q-61 0 -105 -44 +t-44 -105zM1228 136q11 11 11 26t-11 26q-10 10 -25 10t-26 -10q-41 -42 -121 -62t-160 -20t-160 20t-121 62q-11 10 -26 10t-25 -10q-11 -10 -11 -25.5t11 -26.5q43 -43 118.5 -68t122.5 -29.5t91 -4.5t91 4.5t122.5 29.5t118.5 68zM1225 341q62 0 105.5 44t43.5 106 +q0 61 -44 105t-105 44q-62 0 -106 -43.5t-44 -105.5t44 -106t106 -44z" /> + <glyph glyph-name="_602" unicode="&#xf282;" horiz-adv-x="1792" +d="M69 741h1q16 126 58.5 241.5t115 217t167.5 176t223.5 117.5t276.5 43q231 0 414 -105.5t294 -303.5q104 -187 104 -442v-188h-1125q1 -111 53.5 -192.5t136.5 -122.5t189.5 -57t213 -3t208 46.5t173.5 84.5v-377q-92 -55 -229.5 -92t-312.5 -38t-316 53 +q-189 73 -311.5 249t-124.5 372q-3 242 111 412t325 268q-48 -60 -78 -125.5t-46 -159.5h635q8 77 -8 140t-47 101.5t-70.5 66.5t-80.5 41t-75 20.5t-56 8.5l-22 1q-135 -5 -259.5 -44.5t-223.5 -104.5t-176 -140.5t-138 -163.5z" /> + <glyph glyph-name="_603" unicode="&#xf283;" horiz-adv-x="2304" +d="M0 32v608h2304v-608q0 -66 -47 -113t-113 -47h-1984q-66 0 -113 47t-47 113zM640 256v-128h384v128h-384zM256 256v-128h256v128h-256zM2144 1408q66 0 113 -47t47 -113v-224h-2304v224q0 66 47 113t113 47h1984z" /> + <glyph glyph-name="_604" unicode="&#xf284;" horiz-adv-x="1792" +d="M1584 246l-218 111q-74 -120 -196.5 -189t-263.5 -69q-147 0 -271 72t-196 196t-72 270q0 110 42.5 209.5t115 172t172 115t209.5 42.5q131 0 247.5 -60.5t192.5 -168.5l215 125q-110 169 -286.5 265t-378.5 96q-161 0 -308 -63t-253 -169t-169 -253t-63 -308t63 -308 +t169 -253t253 -169t308 -63q213 0 397.5 107t290.5 292zM1030 643l693 -352q-116 -253 -334.5 -400t-492.5 -147q-182 0 -348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71q260 0 470.5 -133.5t335.5 -366.5zM1543 640h-39v-160h-96v352h136q32 0 54.5 -20 +t28.5 -48t1 -56t-27.5 -48t-57.5 -20z" /> + <glyph glyph-name="uniF285" unicode="&#xf285;" horiz-adv-x="1792" +d="M1427 827l-614 386l92 151h855zM405 562l-184 116v858l1183 -743zM1424 697l147 -95v-858l-532 335zM1387 718l-500 -802h-855l356 571z" /> + <glyph glyph-name="uniF286" unicode="&#xf286;" horiz-adv-x="1792" +d="M640 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1152 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1664 496v-752h-640v320q0 80 -56 136t-136 56t-136 -56t-56 -136v-320h-640v752q0 16 16 16h96 +q16 0 16 -16v-112h128v624q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 6 2.5 9.5t8.5 5t9.5 2t11.5 0t9 -0.5v391q-32 15 -32 50q0 23 16.5 39t38.5 16t38.5 -16t16.5 -39q0 -35 -32 -50v-17q45 10 83 10q21 0 59.5 -7.5t54.5 -7.5 +q17 0 47 7.5t37 7.5q16 0 16 -16v-210q0 -15 -35 -21.5t-62 -6.5q-18 0 -54.5 7.5t-55.5 7.5q-40 0 -90 -12v-133q1 0 9 0.5t11.5 0t9.5 -2t8.5 -5t2.5 -9.5v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-624h128v112q0 16 16 16h96 +q16 0 16 -16z" /> + <glyph glyph-name="_607" unicode="&#xf287;" horiz-adv-x="2304" +d="M2288 731q16 -8 16 -27t-16 -27l-320 -192q-8 -5 -16 -5q-9 0 -16 4q-16 10 -16 28v128h-858q37 -58 83 -165q16 -37 24.5 -55t24 -49t27 -47t27 -34t31.5 -26t33 -8h96v96q0 14 9 23t23 9h320q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v96h-96 +q-32 0 -61 10t-51 23.5t-45 40.5t-37 46t-33.5 57t-28.5 57.5t-28 60.5q-23 53 -37 81.5t-36 65t-44.5 53.5t-46.5 17h-360q-22 -84 -91 -138t-157 -54q-106 0 -181 75t-75 181t75 181t181 75q88 0 157 -54t91 -138h104q24 0 46.5 17t44.5 53.5t36 65t37 81.5q19 41 28 60.5 +t28.5 57.5t33.5 57t37 46t45 40.5t51 23.5t61 10h107q21 57 70 92.5t111 35.5q80 0 136 -56t56 -136t-56 -136t-136 -56q-62 0 -111 35.5t-70 92.5h-107q-17 0 -33 -8t-31.5 -26t-27 -34t-27 -47t-24 -49t-24.5 -55q-46 -107 -83 -165h1114v128q0 18 16 28t32 -1z" /> + <glyph glyph-name="_608" unicode="&#xf288;" horiz-adv-x="1792" +d="M1150 774q0 -56 -39.5 -95t-95.5 -39h-253v269h253q56 0 95.5 -39.5t39.5 -95.5zM1329 774q0 130 -91.5 222t-222.5 92h-433v-896h180v269h253q130 0 222 91.5t92 221.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348 +t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="_609" unicode="&#xf289;" horiz-adv-x="2304" +d="M1645 438q0 59 -34 106.5t-87 68.5q-7 -45 -23 -92q-7 -24 -27.5 -38t-44.5 -14q-12 0 -24 3q-31 10 -45 38.5t-4 58.5q23 71 23 143q0 123 -61 227.5t-166 165.5t-228 61q-134 0 -247 -73t-167 -194q108 -28 188 -106q22 -23 22 -55t-22 -54t-54 -22t-55 22 +q-75 75 -180 75q-106 0 -181 -74.5t-75 -180.5t75 -180.5t181 -74.5h1046q79 0 134.5 55.5t55.5 133.5zM1798 438q0 -142 -100.5 -242t-242.5 -100h-1046q-169 0 -289 119.5t-120 288.5q0 153 100 267t249 136q62 184 221 298t354 114q235 0 408.5 -158.5t196.5 -389.5 +q116 -25 192.5 -118.5t76.5 -214.5zM2048 438q0 -175 -97 -319q-23 -33 -64 -33q-24 0 -43 13q-26 17 -32 48.5t12 57.5q71 104 71 233t-71 233q-18 26 -12 57t32 49t57.5 11.5t49.5 -32.5q97 -142 97 -318zM2304 438q0 -244 -134 -443q-23 -34 -64 -34q-23 0 -42 13 +q-26 18 -32.5 49t11.5 57q108 164 108 358q0 195 -108 357q-18 26 -11.5 57.5t32.5 48.5q26 18 57 12t49 -33q134 -198 134 -442z" /> + <glyph glyph-name="_610" unicode="&#xf28a;" +d="M1500 -13q0 -89 -63 -152.5t-153 -63.5t-153.5 63.5t-63.5 152.5q0 90 63.5 153.5t153.5 63.5t153 -63.5t63 -153.5zM1267 268q-115 -15 -192.5 -102.5t-77.5 -205.5q0 -74 33 -138q-146 -78 -379 -78q-109 0 -201 21t-153.5 54.5t-110.5 76.5t-76 85t-44.5 83 +t-23.5 66.5t-6 39.5q0 19 4.5 42.5t18.5 56t36.5 58t64 43.5t94.5 18t94 -17.5t63 -41t35.5 -53t17.5 -49t4 -33.5q0 -34 -23 -81q28 -27 82 -42t93 -17l40 -1q115 0 190 51t75 133q0 26 -9 48.5t-31.5 44.5t-49.5 41t-74 44t-93.5 47.5t-119.5 56.5q-28 13 -43 20 +q-116 55 -187 100t-122.5 102t-72 125.5t-20.5 162.5q0 78 20.5 150t66 137.5t112.5 114t166.5 77t221.5 28.5q120 0 220 -26t164.5 -67t109.5 -94t64 -105.5t19 -103.5q0 -46 -15 -82.5t-36.5 -58t-48.5 -36t-49 -19.5t-39 -5h-8h-32t-39 5t-44 14t-41 28t-37 46t-24 70.5 +t-10 97.5q-15 16 -59 25.5t-81 10.5l-37 1q-68 0 -117.5 -31t-70.5 -70t-21 -76q0 -24 5 -43t24 -46t53 -51t97 -53.5t150 -58.5q76 -25 138.5 -53.5t109 -55.5t83 -59t60.5 -59.5t41 -62.5t26.5 -62t14.5 -63.5t6 -62t1 -62.5z" /> + <glyph glyph-name="_611" unicode="&#xf28b;" +d="M704 352v576q0 14 -9 23t-23 9h-256q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h256q14 0 23 9t9 23zM1152 352v576q0 14 -9 23t-23 9h-256q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h256q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103 +t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_612" unicode="&#xf28c;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM768 96q148 0 273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273 +t73 -273t198 -198t273 -73zM864 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-192zM480 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-192z" /> + <glyph glyph-name="_613" unicode="&#xf28d;" +d="M1088 352v576q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 +t103 -385.5z" /> + <glyph glyph-name="_614" unicode="&#xf28e;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM768 96q148 0 273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273 +t73 -273t198 -198t273 -73zM480 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h576q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-576z" /> + <glyph glyph-name="_615" unicode="&#xf290;" horiz-adv-x="1792" +d="M1757 128l35 -313q3 -28 -16 -50q-19 -21 -48 -21h-1664q-29 0 -48 21q-19 22 -16 50l35 313h1722zM1664 967l86 -775h-1708l86 775q3 24 21 40.5t43 16.5h256v-128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5v128h384v-128q0 -53 37.5 -90.5t90.5 -37.5 +t90.5 37.5t37.5 90.5v128h256q25 0 43 -16.5t21 -40.5zM1280 1152v-256q0 -26 -19 -45t-45 -19t-45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-256q0 -26 -19 -45t-45 -19t-45 19t-19 45v256q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" /> + <glyph glyph-name="_616" unicode="&#xf291;" horiz-adv-x="2048" +d="M1920 768q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5h-15l-115 -662q-8 -46 -44 -76t-82 -30h-1280q-46 0 -82 30t-44 76l-115 662h-15q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5h1792zM485 -32q26 2 43.5 22.5t15.5 46.5l-32 416q-2 26 -22.5 43.5 +t-46.5 15.5t-43.5 -22.5t-15.5 -46.5l32 -416q2 -25 20.5 -42t43.5 -17h5zM896 32v416q0 26 -19 45t-45 19t-45 -19t-19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45zM1280 32v416q0 26 -19 45t-45 19t-45 -19t-19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45zM1632 27l32 416 +q2 26 -15.5 46.5t-43.5 22.5t-46.5 -15.5t-22.5 -43.5l-32 -416q-2 -26 15.5 -46.5t43.5 -22.5h5q25 0 43.5 17t20.5 42zM476 1244l-93 -412h-132l101 441q19 88 89 143.5t160 55.5h167q0 26 19 45t45 19h384q26 0 45 -19t19 -45h167q90 0 160 -55.5t89 -143.5l101 -441 +h-132l-93 412q-11 44 -45.5 72t-79.5 28h-167q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45h-167q-45 0 -79.5 -28t-45.5 -72z" /> + <glyph glyph-name="_617" unicode="&#xf292;" horiz-adv-x="1792" +d="M991 512l64 256h-254l-64 -256h254zM1759 1016l-56 -224q-7 -24 -31 -24h-327l-64 -256h311q15 0 25 -12q10 -14 6 -28l-56 -224q-5 -24 -31 -24h-327l-81 -328q-7 -24 -31 -24h-224q-16 0 -26 12q-9 12 -6 28l78 312h-254l-81 -328q-7 -24 -31 -24h-225q-15 0 -25 12 +q-9 12 -6 28l78 312h-311q-15 0 -25 12q-9 12 -6 28l56 224q7 24 31 24h327l64 256h-311q-15 0 -25 12q-10 14 -6 28l56 224q5 24 31 24h327l81 328q7 24 32 24h224q15 0 25 -12q9 -12 6 -28l-78 -312h254l81 328q7 24 32 24h224q15 0 25 -12q9 -12 6 -28l-78 -312h311 +q15 0 25 -12q9 -12 6 -28z" /> + <glyph glyph-name="_618" unicode="&#xf293;" +d="M841 483l148 -148l-149 -149zM840 1094l149 -149l-148 -148zM710 -130l464 464l-306 306l306 306l-464 464v-611l-255 255l-93 -93l320 -321l-320 -321l93 -93l255 255v-611zM1429 640q0 -209 -32 -365.5t-87.5 -257t-140.5 -162.5t-181.5 -86.5t-219.5 -24.5 +t-219.5 24.5t-181.5 86.5t-140.5 162.5t-87.5 257t-32 365.5t32 365.5t87.5 257t140.5 162.5t181.5 86.5t219.5 24.5t219.5 -24.5t181.5 -86.5t140.5 -162.5t87.5 -257t32 -365.5z" /> + <glyph glyph-name="_619" unicode="&#xf294;" horiz-adv-x="1024" +d="M596 113l173 172l-173 172v-344zM596 823l173 172l-173 172v-344zM628 640l356 -356l-539 -540v711l-297 -296l-108 108l372 373l-372 373l108 108l297 -296v711l539 -540z" /> + <glyph glyph-name="_620" unicode="&#xf295;" +d="M1280 256q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM512 1024q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5 +t112.5 -271.5zM1440 1344q0 -20 -13 -38l-1056 -1408q-19 -26 -51 -26h-160q-26 0 -45 19t-19 45q0 20 13 38l1056 1408q19 26 51 26h160q26 0 45 -19t19 -45zM768 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5 +t271.5 -112.5t112.5 -271.5z" /> + <glyph glyph-name="_621" unicode="&#xf296;" horiz-adv-x="1792" +d="M104 830l792 -1015l-868 630q-18 13 -25 34.5t0 42.5l101 308v0zM566 830h660l-330 -1015v0zM368 1442l198 -612h-462l198 612q8 23 33 23t33 -23zM1688 830l101 -308q7 -21 0 -42.5t-25 -34.5l-868 -630l792 1015v0zM1688 830h-462l198 612q8 23 33 23t33 -23z" /> + <glyph glyph-name="_622" unicode="&#xf297;" horiz-adv-x="1792" +d="M384 704h160v224h-160v-224zM1221 372v92q-104 -36 -243 -38q-135 -1 -259.5 46.5t-220.5 122.5l1 -96q88 -80 212 -128.5t272 -47.5q129 0 238 49zM640 704h640v224h-640v-224zM1792 736q0 -187 -99 -352q89 -102 89 -229q0 -157 -129.5 -268t-313.5 -111 +q-122 0 -225 52.5t-161 140.5q-19 -1 -57 -1t-57 1q-58 -88 -161 -140.5t-225 -52.5q-184 0 -313.5 111t-129.5 268q0 127 89 229q-99 165 -99 352q0 209 120 385.5t326.5 279.5t449.5 103t449.5 -103t326.5 -279.5t120 -385.5z" /> + <glyph glyph-name="_623" unicode="&#xf298;" +d="M515 625v-128h-252v128h252zM515 880v-127h-252v127h252zM1273 369v-128h-341v128h341zM1273 625v-128h-672v128h672zM1273 880v-127h-672v127h672zM1408 20v1240q0 8 -6 14t-14 6h-32l-378 -256l-210 171l-210 -171l-378 256h-32q-8 0 -14 -6t-6 -14v-1240q0 -8 6 -14 +t14 -6h1240q8 0 14 6t6 14zM553 1130l185 150h-406zM983 1130l221 150h-406zM1536 1260v-1240q0 -62 -43 -105t-105 -43h-1240q-62 0 -105 43t-43 105v1240q0 62 43 105t105 43h1240q62 0 105 -43t43 -105z" /> + <glyph glyph-name="_624" unicode="&#xf299;" horiz-adv-x="1792" +d="M896 720q-104 196 -160 278q-139 202 -347 318q-34 19 -70 36q-89 40 -94 32t34 -38l39 -31q62 -43 112.5 -93.5t94.5 -116.5t70.5 -113t70.5 -131q9 -17 13 -25q44 -84 84 -153t98 -154t115.5 -150t131 -123.5t148.5 -90.5q153 -66 154 -60q1 3 -49 37q-53 36 -81 57 +q-77 58 -179 211t-185 310zM549 177q-76 60 -132.5 125t-98 143.5t-71 154.5t-58.5 186t-52 209t-60.5 252t-76.5 289q273 0 497.5 -36t379 -92t271 -144.5t185.5 -172.5t110 -198.5t56 -199.5t12.5 -198.5t-9.5 -173t-20 -143.5t-13 -107l323 -327h-104l-281 285 +q-22 -2 -91.5 -14t-121.5 -19t-138 -6t-160.5 17t-167.5 59t-179 111z" /> + <glyph glyph-name="_625" unicode="&#xf29a;" horiz-adv-x="1792" +d="M1374 879q-6 26 -28.5 39.5t-48.5 7.5q-261 -62 -401 -62t-401 62q-26 6 -48.5 -7.5t-28.5 -39.5t7.5 -48.5t39.5 -28.5q194 -46 303 -58q-2 -158 -15.5 -269t-26.5 -155.5t-41 -115.5l-9 -21q-10 -25 1 -49t36 -34q9 -4 23 -4q44 0 60 41l8 20q54 139 71 259h42 +q17 -120 71 -259l8 -20q16 -41 60 -41q14 0 23 4q25 10 36 34t1 49l-9 21q-28 71 -41 115.5t-26.5 155.5t-15.5 269q109 12 303 58q26 6 39.5 28.5t7.5 48.5zM1024 1024q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z +M1600 640q0 -143 -55.5 -273.5t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5zM896 1408q-156 0 -298 -61t-245 -164t-164 -245t-61 -298t61 -298 +t164 -245t245 -164t298 -61t298 61t245 164t164 245t61 298t-61 298t-164 245t-245 164t-298 61zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="_626" unicode="&#xf29b;" +d="M1438 723q34 -35 29 -82l-44 -551q-4 -42 -34.5 -70t-71.5 -28q-6 0 -9 1q-44 3 -72.5 36.5t-25.5 77.5l35 429l-143 -8q55 -113 55 -240q0 -216 -148 -372l-137 137q91 101 91 235q0 145 -102.5 248t-247.5 103q-134 0 -236 -92l-137 138q120 114 284 141l264 300 +l-149 87l-181 -161q-33 -30 -77 -27.5t-73 35.5t-26.5 77t34.5 73l239 213q26 23 60 26.5t64 -14.5l488 -283q36 -21 48 -68q17 -67 -26 -117l-205 -232l371 20q49 3 83 -32zM1240 1180q-74 0 -126 52t-52 126t52 126t126 52t126.5 -52t52.5 -126t-52.5 -126t-126.5 -52z +M613 -62q106 0 196 61l139 -139q-146 -116 -335 -116q-148 0 -273.5 73t-198.5 198t-73 273q0 188 116 336l139 -139q-60 -88 -60 -197q0 -145 102.5 -247.5t247.5 -102.5z" /> + <glyph glyph-name="_627" unicode="&#xf29c;" +d="M880 336v-160q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h160q14 0 23 -9t9 -23zM1136 832q0 -50 -15 -90t-45.5 -69t-52 -44t-59.5 -36q-32 -18 -46.5 -28t-26 -24t-11.5 -29v-32q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v68q0 35 10.5 64.5 +t24 47.5t39 35.5t41 25.5t44.5 21q53 25 75 43t22 49q0 42 -43.5 71.5t-95.5 29.5q-56 0 -95 -27q-29 -20 -80 -83q-9 -12 -25 -12q-11 0 -19 6l-108 82q-10 7 -12 20t5 23q122 192 349 192q129 0 238.5 -89.5t109.5 -214.5zM768 1280q-130 0 -248.5 -51t-204 -136.5 +t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5 +t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_628" unicode="&#xf29d;" horiz-adv-x="1408" +d="M366 1225q-64 0 -110 45.5t-46 110.5q0 64 46 109.5t110 45.5t109.5 -45.5t45.5 -109.5q0 -65 -45.5 -110.5t-109.5 -45.5zM917 583q0 -50 -30 -67.5t-63.5 -6.5t-47.5 34l-367 438q-7 12 -14 15.5t-11 1.5l-3 -3q-7 -8 4 -21l122 -139l1 -354l-161 -457 +q-67 -192 -92 -234q-15 -26 -28 -32q-50 -26 -103 -1q-29 13 -41.5 43t-9.5 57q2 17 197 618l5 416l-85 -164l35 -222q4 -24 -1 -42t-14 -27.5t-19 -16t-17 -7.5l-7 -2q-19 -3 -34.5 3t-24 16t-14 22t-7.5 19.5t-2 9.5l-46 299l211 381q23 34 113 34q75 0 107 -40l424 -521 +q7 -5 14 -17l3 -3l-1 -1q7 -13 7 -29zM514 433q43 -113 88.5 -225t69.5 -168l24 -55q36 -93 42 -125q11 -70 -36 -97q-35 -22 -66 -16t-51 22t-29 35h-1q-6 16 -8 25l-124 351zM1338 -159q31 -49 31 -57q0 -5 -3 -7q-9 -5 -14.5 0.5t-15.5 26t-16 30.5q-114 172 -423 661 +q3 -1 7 1t7 4l3 2q11 9 11 17z" /> + <glyph glyph-name="_629" unicode="&#xf29e;" horiz-adv-x="2304" +d="M504 542h171l-1 265zM1530 641q0 87 -50.5 140t-146.5 53h-54v-388h52q91 0 145 57t54 138zM956 1018l1 -756q0 -14 -9.5 -24t-23.5 -10h-216q-14 0 -23.5 10t-9.5 24v62h-291l-55 -81q-10 -15 -28 -15h-267q-21 0 -30.5 18t3.5 35l556 757q9 14 27 14h332q14 0 24 -10 +t10 -24zM1783 641q0 -193 -125.5 -303t-324.5 -110h-270q-14 0 -24 10t-10 24v756q0 14 10 24t24 10h268q200 0 326 -109t126 -302zM1939 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5 +t-7.5 60t-20 91.5t-41 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2123 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-45 -108t-74 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5 +h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2304 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66 104.5t41 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96 +t9.5 -70.5z" /> + <glyph glyph-name="uniF2A0" unicode="&#xf2a0;" horiz-adv-x="1408" +d="M617 -153q0 11 -13 58t-31 107t-20 69q-1 4 -5 26.5t-8.5 36t-13.5 21.5q-15 14 -51 14q-23 0 -70 -5.5t-71 -5.5q-34 0 -47 11q-6 5 -11 15.5t-7.5 20t-6.5 24t-5 18.5q-37 128 -37 255t37 255q1 4 5 18.5t6.5 24t7.5 20t11 15.5q13 11 47 11q24 0 71 -5.5t70 -5.5 +q36 0 51 14q9 8 13.5 21.5t8.5 36t5 26.5q2 9 20 69t31 107t13 58q0 22 -43.5 52.5t-75.5 42.5q-20 8 -45 8q-34 0 -98 -18q-57 -17 -96.5 -40.5t-71 -66t-46 -70t-45.5 -94.5q-6 -12 -9 -19q-49 -107 -68 -216t-19 -244t19 -244t68 -216q56 -122 83 -161q63 -91 179 -127 +l6 -2q64 -18 98 -18q25 0 45 8q32 12 75.5 42.5t43.5 52.5zM776 760q-26 0 -45 19t-19 45.5t19 45.5q37 37 37 90q0 52 -37 91q-19 19 -19 45t19 45t45 19t45 -19q75 -75 75 -181t-75 -181q-21 -19 -45 -19zM957 579q-27 0 -45 19q-19 19 -19 45t19 45q112 114 112 272 +t-112 272q-19 19 -19 45t19 45t45 19t45 -19q150 -150 150 -362t-150 -362q-18 -19 -45 -19zM1138 398q-27 0 -45 19q-19 19 -19 45t19 45q90 91 138.5 208t48.5 245t-48.5 245t-138.5 208q-19 19 -19 45t19 45t45 19t45 -19q109 -109 167 -249t58 -294t-58 -294t-167 -249 +q-18 -19 -45 -19z" /> + <glyph glyph-name="uniF2A1" unicode="&#xf2a1;" horiz-adv-x="2176" +d="M192 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 352 +q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 864 +q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 1376q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 192q0 -80 -56 -136 +t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 1216q0 -80 -56 -136t-136 -56 +t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 192q0 -80 -56 -136t-136 -56t-136 56 +t-56 136t56 136t136 56t136 -56t56 -136zM1664 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136 +t56 136t136 56t136 -56t56 -136zM2176 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136z" /> + <glyph glyph-name="uniF2A2" unicode="&#xf2a2;" horiz-adv-x="1792" +d="M128 -192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM320 0q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM365 365l256 -256l-90 -90l-256 256zM704 384q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45z +M1411 704q0 -59 -11.5 -108.5t-37.5 -93.5t-44 -67.5t-53 -64.5q-31 -35 -45.5 -54t-33.5 -50t-26.5 -64t-7.5 -74q0 -159 -112.5 -271.5t-271.5 -112.5q-26 0 -45 19t-19 45t19 45t45 19q106 0 181 75t75 181q0 57 11.5 105.5t37 91t43.5 66.5t52 63q40 46 59.5 72 +t37.5 74.5t18 103.5q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM896 576q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45 +t45 19t45 -19t19 -45zM1184 704q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 93 -65.5 158.5t-158.5 65.5q-92 0 -158 -65.5t-66 -158.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 146 103 249t249 103t249 -103t103 -249zM1578 993q10 -25 -1 -49t-36 -34q-9 -4 -23 -4 +q-19 0 -35.5 11t-23.5 30q-68 178 -224 295q-21 16 -25 42t12 47q17 21 43 25t47 -12q183 -137 266 -351zM1788 1074q9 -25 -1.5 -49t-35.5 -34q-11 -4 -23 -4q-44 0 -60 41q-92 238 -297 393q-22 16 -25.5 42t12.5 47q16 22 42 25.5t47 -12.5q235 -175 341 -449z" /> + <glyph glyph-name="uniF2A3" unicode="&#xf2a3;" horiz-adv-x="2304" +d="M1032 576q-59 2 -84 55q-17 34 -48 53.5t-68 19.5q-53 0 -90.5 -37.5t-37.5 -90.5q0 -56 36 -89l10 -8q34 -31 82 -31q37 0 68 19.5t48 53.5q25 53 84 55zM1600 704q0 56 -36 89l-10 8q-34 31 -82 31q-37 0 -68 -19.5t-48 -53.5q-25 -53 -84 -55q59 -2 84 -55 +q17 -34 48 -53.5t68 -19.5q53 0 90.5 37.5t37.5 90.5zM1174 925q-17 -35 -55 -48t-73 4q-62 31 -134 31q-51 0 -99 -17q3 0 9.5 0.5t9.5 0.5q92 0 170.5 -50t118.5 -133q17 -36 3.5 -73.5t-49.5 -54.5q-18 -9 -39 -9q21 0 39 -9q36 -17 49.5 -54.5t-3.5 -73.5 +q-40 -83 -118.5 -133t-170.5 -50h-6q-16 2 -44 4l-290 27l-239 -120q-14 -7 -29 -7q-40 0 -57 35l-160 320q-11 23 -4 47.5t29 37.5l209 119l148 267q17 155 91.5 291.5t195.5 236.5q31 25 70.5 21.5t64.5 -34.5t21.5 -70t-34.5 -65q-70 -59 -117 -128q123 84 267 101 +q40 5 71.5 -19t35.5 -64q5 -40 -19 -71.5t-64 -35.5q-84 -10 -159 -55q46 10 99 10q115 0 218 -50q36 -18 49 -55.5t-5 -73.5zM2137 1085l160 -320q11 -23 4 -47.5t-29 -37.5l-209 -119l-148 -267q-17 -155 -91.5 -291.5t-195.5 -236.5q-26 -22 -61 -22q-45 0 -74 35 +q-25 31 -21.5 70t34.5 65q70 59 117 128q-123 -84 -267 -101q-4 -1 -12 -1q-36 0 -63.5 24t-31.5 60q-5 40 19 71.5t64 35.5q84 10 159 55q-46 -10 -99 -10q-115 0 -218 50q-36 18 -49 55.5t5 73.5q17 35 55 48t73 -4q62 -31 134 -31q51 0 99 17q-3 0 -9.5 -0.5t-9.5 -0.5 +q-92 0 -170.5 50t-118.5 133q-17 36 -3.5 73.5t49.5 54.5q18 9 39 9q-21 0 -39 9q-36 17 -49.5 54.5t3.5 73.5q40 83 118.5 133t170.5 50h6h1q14 -2 42 -4l291 -27l239 120q14 7 29 7q40 0 57 -35z" /> + <glyph glyph-name="uniF2A4" unicode="&#xf2a4;" horiz-adv-x="1792" +d="M1056 704q0 -26 19 -45t45 -19t45 19t19 45q0 146 -103 249t-249 103t-249 -103t-103 -249q0 -26 19 -45t45 -19t45 19t19 45q0 93 66 158.5t158 65.5t158 -65.5t66 -158.5zM835 1280q-117 0 -223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5q0 -26 19 -45t45 -19t45 19 +t19 45q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -55 -18 -103.5t-37.5 -74.5t-59.5 -72q-34 -39 -52 -63t-43.5 -66.5t-37 -91t-11.5 -105.5q0 -106 -75 -181t-181 -75q-26 0 -45 -19t-19 -45t19 -45t45 -19q159 0 271.5 112.5t112.5 271.5q0 41 7.5 74 +t26.5 64t33.5 50t45.5 54q35 41 53 64.5t44 67.5t37.5 93.5t11.5 108.5q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5zM591 561l226 -226l-579 -579q-12 -12 -29 -12t-29 12l-168 168q-12 12 -12 29t12 29zM1612 1524l168 -168q12 -12 12 -29t-12 -30l-233 -233 +l-26 -25l-71 -71q-66 153 -195 258l91 91l207 207q13 12 30 12t29 -12z" /> + <glyph glyph-name="uniF2A5" unicode="&#xf2a5;" +d="M866 1021q0 -27 -13 -94q-11 -50 -31.5 -150t-30.5 -150q-2 -11 -4.5 -12.5t-13.5 -2.5q-20 -2 -31 -2q-58 0 -84 49.5t-26 113.5q0 88 35 174t103 124q28 14 51 14q28 0 36.5 -16.5t8.5 -47.5zM1352 597q0 14 -39 75.5t-52 66.5q-21 8 -34 8q-91 0 -226 -77l-2 2 +q3 22 27.5 135t24.5 178q0 233 -242 233q-24 0 -68 -6q-94 -17 -168.5 -89.5t-111.5 -166.5t-37 -189q0 -146 80.5 -225t227.5 -79q25 0 25 -3t-1 -5q-4 -34 -26 -117q-14 -52 -51.5 -101t-82.5 -49q-42 0 -42 47q0 24 10.5 47.5t25 39.5t29.5 28.5t26 20t11 8.5q0 3 -7 10 +q-24 22 -58.5 36.5t-65.5 14.5q-35 0 -63.5 -34t-41 -75t-12.5 -75q0 -88 51.5 -142t138.5 -54q82 0 155 53t117.5 126t65.5 153q6 22 15.5 66.5t14.5 66.5q3 12 14 18q118 60 227 60q48 0 127 -18q1 -1 4 -1q5 0 9.5 4.5t4.5 8.5zM1536 1120v-960q0 -119 -84.5 -203.5 +t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="uniF2A6" unicode="&#xf2a6;" horiz-adv-x="1535" +d="M744 1231q0 24 -2 38.5t-8.5 30t-21 23t-37.5 7.5q-39 0 -78 -23q-105 -58 -159 -190.5t-54 -269.5q0 -44 8.5 -85.5t26.5 -80.5t52.5 -62.5t81.5 -23.5q4 0 18 -0.5t20 0t16 3t15 8.5t7 16q16 77 48 231.5t48 231.5q19 91 19 146zM1498 575q0 -7 -7.5 -13.5t-15.5 -6.5 +l-6 1q-22 3 -62 11t-72 12.5t-63 4.5q-167 0 -351 -93q-15 -8 -21 -27q-10 -36 -24.5 -105.5t-22.5 -100.5q-23 -91 -70 -179.5t-112.5 -164.5t-154.5 -123t-185 -47q-135 0 -214.5 83.5t-79.5 219.5q0 53 19.5 117t63 116.5t97.5 52.5q38 0 120 -33.5t83 -61.5 +q0 -1 -16.5 -12.5t-39.5 -31t-46 -44.5t-39 -61t-16 -74q0 -33 16.5 -53t48.5 -20q45 0 85 31.5t66.5 78t48 105.5t32.5 107t16 90v9q0 2 -3.5 3.5t-8.5 1.5h-10t-10 -0.5t-6 -0.5q-227 0 -352 122.5t-125 348.5q0 108 34.5 221t96 210t156 167.5t204.5 89.5q52 9 106 9 +q374 0 374 -360q0 -98 -38 -273t-43 -211l3 -3q101 57 182.5 88t167.5 31q22 0 53 -13q19 -7 80 -102.5t61 -116.5z" /> + <glyph glyph-name="uniF2A7" unicode="&#xf2a7;" horiz-adv-x="1664" +d="M831 863q32 0 59 -18l222 -148q61 -40 110 -97l146 -170q40 -46 29 -106l-72 -413q-6 -32 -29.5 -53.5t-55.5 -25.5l-527 -56l-352 -32h-9q-39 0 -67.5 28t-28.5 68q0 37 27 64t65 32l260 32h-448q-41 0 -69.5 30t-26.5 71q2 39 32 65t69 26l442 1l-521 64q-41 5 -66 37 +t-19 73q6 35 34.5 57.5t65.5 22.5h10l481 -60l-351 94q-38 10 -62 41.5t-18 68.5q6 36 33 58.5t62 22.5q6 0 20 -2l448 -96l217 -37q1 0 3 -0.5t3 -0.5q23 0 30.5 23t-12.5 36l-186 125q-35 23 -42 63.5t18 73.5q27 38 76 38zM761 661l186 -125l-218 37l-5 2l-36 38 +l-238 262q-1 1 -2.5 3.5t-2.5 3.5q-24 31 -18.5 70t37.5 64q31 23 68 17.5t64 -33.5l142 -147q-2 -1 -5 -3.5t-4 -4.5q-32 -45 -23 -99t55 -85zM1648 1115l15 -266q4 -73 -11 -147l-48 -219q-12 -59 -67 -87l-106 -54q2 62 -39 109l-146 170q-53 61 -117 103l-222 148 +q-34 23 -76 23q-51 0 -88 -37l-235 312q-25 33 -18 73.5t41 63.5q33 22 71.5 14t62.5 -40l266 -352l-262 455q-21 35 -10.5 75t47.5 59q35 18 72.5 6t57.5 -46l241 -420l-136 337q-15 35 -4.5 74t44.5 56q37 19 76 6t56 -51l193 -415l101 -196q8 -15 23 -17.5t27 7.5t11 26 +l-12 224q-2 41 26 71t69 31q39 0 67 -28.5t30 -67.5z" /> + <glyph glyph-name="uniF2A8" unicode="&#xf2a8;" horiz-adv-x="1792" +d="M335 180q-2 0 -6 2q-86 57 -168.5 145t-139.5 180q-21 30 -21 69q0 9 2 19t4 18t7 18t8.5 16t10.5 17t10 15t12 15.5t11 14.5q184 251 452 365q-110 198 -110 211q0 19 17 29q116 64 128 64q18 0 28 -16l124 -229q92 19 192 19q266 0 497.5 -137.5t378.5 -369.5 +q20 -31 20 -69t-20 -69q-91 -142 -218.5 -253.5t-278.5 -175.5q110 -198 110 -211q0 -20 -17 -29q-116 -64 -127 -64q-19 0 -29 16l-124 229l-64 119l-444 820l7 7q-58 -24 -99 -47q3 -5 127 -234t243 -449t119 -223q0 -7 -9 -9q-13 -3 -72 -3q-57 0 -60 7l-456 841 +q-39 -28 -82 -68q24 -43 214 -393.5t190 -354.5q0 -10 -11 -10q-14 0 -82.5 22t-72.5 28l-106 197l-224 413q-44 -53 -78 -106q2 -3 18 -25t23 -34l176 -327q0 -10 -10 -10zM1165 282l49 -91q273 111 450 385q-180 277 -459 389q67 -64 103 -148.5t36 -176.5 +q0 -106 -47 -200.5t-132 -157.5zM848 896q0 -20 14 -34t34 -14q86 0 147 -61t61 -147q0 -20 14 -34t34 -14t34 14t14 34q0 126 -89 215t-215 89q-20 0 -34 -14t-14 -34zM1214 961l-9 4l7 -7z" /> + <glyph glyph-name="uniF2A9" unicode="&#xf2a9;" horiz-adv-x="1280" +d="M1050 430q0 -215 -147 -374q-148 -161 -378 -161q-232 0 -378 161q-147 159 -147 374q0 147 68 270.5t189 196.5t268 73q96 0 182 -31q-32 -62 -39 -126q-66 28 -143 28q-167 0 -280.5 -123t-113.5 -291q0 -170 112.5 -288.5t281.5 -118.5t281 118.5t112 288.5 +q0 89 -32 166q66 13 123 49q41 -98 41 -212zM846 619q0 -192 -79.5 -345t-238.5 -253l-14 -1q-29 0 -62 5q83 32 146.5 102.5t99.5 154.5t58.5 189t30 192.5t7.5 178.5q0 69 -3 103q55 -160 55 -326zM791 947v-2q-73 214 -206 440q88 -59 142.5 -186.5t63.5 -251.5z +M1035 744q-83 0 -160 75q218 120 290 247q19 37 21 56q-42 -94 -139.5 -166.5t-204.5 -97.5q-35 54 -35 113q0 37 17 79t43 68q46 44 157 74q59 16 106 58.5t74 100.5q74 -105 74 -253q0 -109 -24 -170q-32 -77 -88.5 -130.5t-130.5 -53.5z" /> + <glyph glyph-name="uniF2AA" unicode="&#xf2aa;" +d="M1050 495q0 78 -28 147q-41 -25 -85 -34q22 -50 22 -114q0 -117 -77 -198.5t-193 -81.5t-193.5 81.5t-77.5 198.5q0 115 78 199.5t193 84.5q53 0 98 -19q4 43 27 87q-60 21 -125 21q-154 0 -257.5 -108.5t-103.5 -263.5t103.5 -261t257.5 -106t257.5 106.5t103.5 260.5z +M872 850q2 -24 2 -71q0 -63 -5 -123t-20.5 -132.5t-40.5 -130t-68.5 -106t-100.5 -70.5q21 -3 42 -3h10q219 139 219 411q0 116 -38 225zM872 850q-4 80 -44 171.5t-98 130.5q92 -156 142 -302zM1207 955q0 102 -51 174q-41 -86 -124 -109q-69 -19 -109 -53.5t-40 -99.5 +q0 -40 24 -77q74 17 140.5 67t95.5 115q-4 -52 -74.5 -111.5t-138.5 -97.5q52 -52 110 -52q51 0 90 37t60 90q17 42 17 117zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 +t84.5 -203.5z" /> + <glyph glyph-name="uniF2AB" unicode="&#xf2ab;" +d="M1279 388q0 22 -22 27q-67 15 -118 59t-80 108q-7 19 -7 25q0 15 19.5 26t43 17t43 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-12 0 -32 -8t-31 -8q-4 0 -12 2q5 95 5 114q0 79 -17 114q-36 78 -103 121.5t-152 43.5q-199 0 -275 -165q-17 -35 -17 -114q0 -19 5 -114 +q-4 -2 -14 -2q-12 0 -32 7.5t-30 7.5q-21 0 -38.5 -12t-17.5 -32q0 -21 19.5 -35.5t43 -20.5t43 -17t19.5 -26q0 -6 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -46 137 -68q2 -5 6 -26t11.5 -30.5t23.5 -9.5q12 0 37.5 4.5t39.5 4.5q35 0 67 -15t54 -32.5t57.5 -32.5 +t76.5 -15q43 0 79 15t57.5 32.5t53.5 32.5t67 15q14 0 39.5 -4t38.5 -4q16 0 23 10t11 30t6 25q137 22 137 68zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 +t103 -385.5z" /> + <glyph glyph-name="uniF2AC" unicode="&#xf2ac;" horiz-adv-x="1664" +d="M848 1408q134 1 240.5 -68.5t163.5 -192.5q27 -58 27 -179q0 -47 -9 -191q14 -7 28 -7q18 0 51 13.5t51 13.5q29 0 56 -18t27 -46q0 -32 -31.5 -54t-69 -31.5t-69 -29t-31.5 -47.5q0 -15 12 -43q37 -82 102.5 -150t144.5 -101q28 -12 80 -23q28 -6 28 -35 +q0 -70 -219 -103q-7 -11 -11 -39t-14 -46.5t-33 -18.5q-20 0 -62 6.5t-64 6.5q-37 0 -62 -5q-32 -5 -63 -22.5t-58 -38t-58 -40.5t-76 -33.5t-99 -13.5q-52 0 -96.5 13.5t-75 33.5t-57.5 40.5t-58 38t-62 22.5q-26 5 -63 5q-24 0 -65.5 -7.5t-58.5 -7.5q-25 0 -35 18.5 +t-14 47.5t-11 40q-219 33 -219 103q0 29 28 35q52 11 80 23q78 32 144.5 101t102.5 150q12 28 12 43q0 28 -31.5 47.5t-69.5 29.5t-69.5 31.5t-31.5 52.5q0 27 26 45.5t55 18.5q15 0 48 -13t53 -13q18 0 32 7q-9 142 -9 190q0 122 27 180q64 137 172 198t264 63z" /> + <glyph glyph-name="uniF2AD" unicode="&#xf2ad;" +d="M1280 388q0 22 -22 27q-67 14 -118 58t-80 109q-7 14 -7 25q0 15 19.5 26t42.5 17t42.5 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-11 0 -31 -8t-32 -8q-4 0 -12 2q5 63 5 115q0 78 -17 114q-36 78 -102.5 121.5t-152.5 43.5q-198 0 -275 -165q-18 -38 -18 -115 +q0 -38 6 -114q-10 -2 -15 -2q-11 0 -31.5 8t-30.5 8q-20 0 -37.5 -12.5t-17.5 -32.5q0 -21 19.5 -35.5t42.5 -20.5t42.5 -17t19.5 -26q0 -11 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -47 138 -69q2 -5 6 -26t11 -30.5t23 -9.5q13 0 38.5 5t38.5 5q35 0 67.5 -15 +t54.5 -32.5t57.5 -32.5t76.5 -15q43 0 79 15t57.5 32.5t54 32.5t67.5 15q13 0 39 -4.5t39 -4.5q15 0 22.5 9.5t11.5 31t5 24.5q138 22 138 69zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960 +q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="uniF2AE" unicode="&#xf2ae;" horiz-adv-x="2304" +d="M2304 1536q-69 -46 -125 -92t-89 -81t-59.5 -71.5t-37.5 -57.5t-22 -44.5t-14 -29.5q-10 -18 -35.5 -136.5t-48.5 -164.5q-15 -29 -50 -60.5t-67.5 -50.5t-72.5 -41t-48 -28q-47 -31 -151 -231q-341 14 -630 -158q-92 -53 -303 -179q47 16 86 31t55 22l15 7 +q71 27 163 64.5t133.5 53.5t108 34.5t142.5 31.5q186 31 465 -7q1 0 10 -3q11 -6 14 -17t-3 -22l-194 -345q-15 -29 -47 -22q-128 24 -354 24q-146 0 -402 -44.5t-392 -46.5q-82 -1 -149 13t-107 37t-61 40t-33 34l-1 1v2q0 6 6 6q138 0 371 55q192 366 374.5 524t383.5 158 +q5 0 14.5 -0.5t38 -5t55 -12t61.5 -24.5t63 -39.5t54 -59t40 -82.5l102 177q2 4 21 42.5t44.5 86.5t61 109.5t84 133.5t100.5 137q66 82 128 141.5t121.5 96.5t92.5 53.5t88 39.5z" /> + <glyph glyph-name="uniF2B0" unicode="&#xf2b0;" +d="M1322 640q0 -45 -5 -76l-236 14l224 -78q-19 -73 -58 -141l-214 103l177 -158q-44 -61 -107 -108l-157 178l103 -215q-61 -37 -140 -59l-79 228l14 -240q-38 -6 -76 -6t-76 6l14 238l-78 -226q-74 19 -140 59l103 215l-157 -178q-59 43 -108 108l178 158l-214 -104 +q-39 69 -58 141l224 79l-237 -14q-5 42 -5 76q0 35 5 77l238 -14l-225 79q19 73 58 140l214 -104l-177 159q46 61 107 108l158 -178l-103 215q67 39 140 58l77 -224l-13 236q36 6 75 6q38 0 76 -6l-14 -237l78 225q74 -19 140 -59l-103 -214l158 178q61 -47 107 -108 +l-177 -159l213 104q37 -62 58 -141l-224 -78l237 14q5 -31 5 -77zM1352 640q0 160 -78.5 295.5t-213 214t-292.5 78.5q-119 0 -227 -46.5t-186.5 -125t-124.5 -187.5t-46 -229q0 -119 46 -228t124.5 -187.5t186.5 -125t227 -46.5q158 0 292.5 78.5t213 214t78.5 294.5z +M1425 1023v-766l-657 -383l-657 383v766l657 383zM768 -183l708 412v823l-708 411l-708 -411v-823zM1536 1088v-896l-768 -448l-768 448v896l768 448z" /> + <glyph glyph-name="uniF2B1" unicode="&#xf2b1;" horiz-adv-x="1664" +d="M339 1318h691l-26 -72h-665q-110 0 -188.5 -79t-78.5 -189v-771q0 -95 60.5 -169.5t153.5 -93.5q23 -5 98 -5v-72h-45q-140 0 -239.5 100t-99.5 240v771q0 140 99.5 240t239.5 100zM1190 1536h247l-482 -1294q-23 -61 -40.5 -103.5t-45 -98t-54 -93.5t-64.5 -78.5 +t-79.5 -65t-95.5 -41t-116 -18.5v195q163 26 220 182q20 52 20 105q0 54 -20 106l-285 733h228l187 -585zM1664 978v-1111h-795q37 55 45 73h678v1038q0 85 -49.5 155t-129.5 99l25 67q101 -34 163.5 -123.5t62.5 -197.5z" /> + <glyph glyph-name="uniF2B2" unicode="&#xf2b2;" horiz-adv-x="1792" +d="M852 1227q0 -29 -17 -52.5t-45 -23.5t-45 23.5t-17 52.5t17 52.5t45 23.5t45 -23.5t17 -52.5zM688 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50 -21.5t-20 -51.5v-114q0 -30 20.5 -52t49.5 -22q30 0 50.5 22t20.5 52zM860 -149v114q0 30 -20 51.5t-50 21.5t-50.5 -21.5 +t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22q29 0 49.5 22t20.5 52zM1034 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1208 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114 +q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1476 535q-84 -160 -232 -259.5t-323 -99.5q-123 0 -229.5 51.5t-178.5 137t-113 197.5t-41 232q0 88 21 174q-104 -175 -104 -390q0 -162 65 -312t185 -251q30 57 91 57q56 0 86 -50q32 50 87 50q56 0 86 -50q32 50 87 50t87 -50 +q30 50 86 50q28 0 52.5 -15.5t37.5 -40.5q112 94 177 231.5t73 287.5zM1326 564q0 75 -72 75q-17 0 -47 -6q-95 -19 -149 -19q-226 0 -226 243q0 86 30 204q-83 -127 -83 -275q0 -150 89 -260.5t235 -110.5q111 0 210 70q13 48 13 79zM884 1223q0 50 -32 89.5t-81 39.5 +t-81 -39.5t-32 -89.5q0 -51 31.5 -90.5t81.5 -39.5t81.5 39.5t31.5 90.5zM1513 884q0 96 -37.5 179t-113 137t-173.5 54q-77 0 -149 -35t-127 -94q-48 -159 -48 -268q0 -104 45.5 -157t147.5 -53q53 0 142 19q36 6 53 6q51 0 77.5 -28t26.5 -80q0 -26 -4 -46 +q75 68 117.5 165.5t42.5 200.5zM1792 667q0 -111 -33.5 -249.5t-93.5 -204.5q-58 -64 -195 -142.5t-228 -104.5l-4 -1v-114q0 -43 -29.5 -75t-72.5 -32q-56 0 -86 50q-32 -50 -87 -50t-87 50q-30 -50 -86 -50q-55 0 -87 50q-30 -50 -86 -50q-47 0 -75 33.5t-28 81.5 +q-90 -68 -198 -68q-118 0 -211 80q54 1 106 20q-113 31 -182 127q32 -7 71 -7q89 0 164 46q-192 192 -240 306q-24 56 -24 160q0 57 9 125.5t31.5 146.5t55 141t86.5 105t120 42q59 0 81 -52q19 29 42 54q2 3 12 13t13 16q10 15 23 38t25 42t28 39q87 111 211.5 177 +t260.5 66q35 0 62 -4q59 64 146 64q83 0 140 -57q5 -5 5 -12q0 -5 -6 -13.5t-12.5 -16t-16 -17l-10.5 -10.5q17 -6 36 -18t19 -24q0 -6 -16 -25q157 -138 197 -378q25 30 60 30q45 0 100 -49q90 -80 90 -279z" /> + <glyph glyph-name="uniF2B3" unicode="&#xf2b3;" +d="M917 631q0 33 -6 64h-362v-132h217q-12 -76 -74.5 -120.5t-142.5 -44.5q-99 0 -169 71.5t-70 170.5t70 170.5t169 71.5q93 0 153 -59l104 101q-108 100 -257 100q-160 0 -272 -112.5t-112 -271.5t112 -271.5t272 -112.5q165 0 266.5 105t101.5 270zM1262 585h109v110 +h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="uniF2B4" unicode="&#xf2b4;" +d="M1536 1024v-839q0 -48 -49 -62q-174 -52 -338 -52q-73 0 -215.5 29.5t-227.5 29.5q-164 0 -370 -48v-338h-160v1368q-63 25 -101 81t-38 124q0 91 64 155t155 64t155 -64t64 -155q0 -68 -38 -124t-101 -81v-68q190 44 343 44q99 0 198 -15q14 -2 111.5 -22.5t149.5 -20.5 +q77 0 165 18q11 2 80 21t89 19q26 0 45 -19t19 -45z" /> + <glyph glyph-name="uniF2B5" unicode="&#xf2b5;" horiz-adv-x="2304" +d="M192 384q40 0 56 32t0 64t-56 32t-56 -32t0 -64t56 -32zM1665 442q-10 13 -38.5 50t-41.5 54t-38 49t-42.5 53t-40.5 47t-45 49l-125 -140q-83 -94 -208.5 -92t-205.5 98q-57 69 -56.5 158t58.5 157l177 206q-22 11 -51 16.5t-47.5 6t-56.5 -0.5t-49 -1q-92 0 -158 -66 +l-158 -158h-155v-544q5 0 21 0.5t22 0t19.5 -2t20.5 -4.5t17.5 -8.5t18.5 -13.5l297 -292q115 -111 227 -111q78 0 125 47q57 -20 112.5 8t72.5 85q74 -6 127 44q20 18 36 45.5t14 50.5q10 -10 43 -10q43 0 77 21t49.5 53t12 71.5t-30.5 73.5zM1824 384h96v512h-93l-157 180 +q-66 76 -169 76h-167q-89 0 -146 -67l-209 -243q-28 -33 -28 -75t27 -75q43 -51 110 -52t111 49l193 218q25 23 53.5 21.5t47 -27t8.5 -56.5q16 -19 56 -63t60 -68q29 -36 82.5 -105.5t64.5 -84.5q52 -66 60 -140zM2112 384q40 0 56 32t0 64t-56 32t-56 -32t0 -64t56 -32z +M2304 960v-640q0 -26 -19 -45t-45 -19h-434q-27 -65 -82 -106.5t-125 -51.5q-33 -48 -80.5 -81.5t-102.5 -45.5q-42 -53 -104.5 -81.5t-128.5 -24.5q-60 -34 -126 -39.5t-127.5 14t-117 53.5t-103.5 81l-287 282h-358q-26 0 -45 19t-19 45v672q0 26 19 45t45 19h421 +q14 14 47 48t47.5 48t44 40t50.5 37.5t51 25.5t62 19.5t68 5.5h117q99 0 181 -56q82 56 181 56h167q35 0 67 -6t56.5 -14.5t51.5 -26.5t44.5 -31t43 -39.5t39 -42t41 -48t41.5 -48.5h355q26 0 45 -19t19 -45z" /> + <glyph glyph-name="uniF2B6" unicode="&#xf2b6;" horiz-adv-x="1792" +d="M1792 882v-978q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v978q0 15 11 24q8 7 39 34.5t41.5 36t45.5 37.5t70 55.5t96 73t143.5 107t192.5 140.5q5 4 52.5 40t71.5 52.5t64 35t69 18.5t69 -18.5t65 -35.5t71 -52t52 -40q110 -80 192.5 -140.5t143.5 -107 +t96 -73t70 -55.5t45.5 -37.5t41.5 -36t39 -34.5q11 -9 11 -24zM1228 297q263 191 345 252q11 8 12.5 20.5t-6.5 23.5l-38 52q-8 11 -21 12.5t-24 -6.5q-231 -169 -343 -250q-5 -3 -52 -39t-71.5 -52.5t-64.5 -35t-69 -18.5t-69 18.5t-64.5 35t-71.5 52.5t-52 39 +q-186 134 -343 250q-11 8 -24 6.5t-21 -12.5l-38 -52q-8 -11 -6.5 -23.5t12.5 -20.5q82 -61 345 -252q10 -8 50 -38t65 -47t64 -39.5t77.5 -33.5t75.5 -11t75.5 11t79 34.5t64.5 39.5t65 47.5t48 36.5z" /> + <glyph glyph-name="uniF2B7" unicode="&#xf2b7;" horiz-adv-x="1792" +d="M1474 623l39 -51q8 -11 6.5 -23.5t-11.5 -20.5q-43 -34 -126.5 -98.5t-146.5 -113t-67 -51.5q-39 -32 -60 -48t-60.5 -41t-76.5 -36.5t-74 -11.5h-1h-1q-37 0 -74 11.5t-76 36.5t-61 41.5t-60 47.5q-5 4 -65 50.5t-143.5 111t-122.5 94.5q-11 8 -12.5 20.5t6.5 23.5 +l37 52q8 11 21.5 13t24.5 -7q94 -73 306 -236q5 -4 43.5 -35t60.5 -46.5t56.5 -32.5t58.5 -17h1h1q24 0 58.5 17t56.5 32.5t60.5 46.5t43.5 35q258 198 313 242q11 8 24 6.5t21 -12.5zM1664 -96v928q-90 83 -159 139q-91 74 -389 304q-3 2 -43 35t-61 48t-56 32.5t-59 17.5 +h-1h-1q-24 0 -59 -17.5t-56 -32.5t-61 -48t-43 -35q-215 -166 -315.5 -245.5t-129.5 -104t-82 -74.5q-14 -12 -21 -19v-928q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 832v-928q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v928q0 56 41 94 +q123 114 350 290.5t233 181.5q36 30 59 47.5t61.5 42t76 36.5t74.5 12h1h1q37 0 74.5 -12t76 -36.5t61.5 -42t59 -47.5q43 -36 156 -122t226 -177t201 -173q41 -38 41 -94z" /> + <glyph glyph-name="uniF2B8" unicode="&#xf2b8;" +d="M330 1l202 -214l-34 236l-216 213zM556 -225l274 218l-11 245l-300 -215zM245 413l227 -213l-48 327l-245 204zM495 189l317 214l-14 324l-352 -200zM843 178l95 -80l-2 239l-103 79q0 -1 1 -8.5t0 -12t-5 -7.5l-78 -52l85 -70q7 -6 7 -88zM138 930l256 -200l-68 465 +l-279 173zM1173 267l15 234l-230 -164l2 -240zM417 722l373 194l-19 441l-423 -163zM1270 357l20 233l-226 142l-2 -105l144 -95q6 -4 4 -9l-7 -119zM1461 496l30 222l-179 -128l-20 -228zM1273 329l-71 49l-8 -117q0 -5 -4 -8l-234 -187q-7 -5 -14 0l-98 83l7 -161 +q0 -5 -4 -8l-293 -234q-4 -2 -6 -2q-8 2 -8 3l-228 242q-4 4 -59 277q-2 7 5 11l61 37q-94 86 -95 92l-72 351q-2 7 6 12l94 45q-133 100 -135 108l-96 466q-2 10 7 13l433 135q5 0 8 -1l317 -153q6 -4 6 -9l20 -463q0 -7 -6 -10l-118 -61l126 -85q5 -2 5 -8l5 -123l121 74 +q5 4 11 0l84 -56l3 110q0 6 5 9l206 126q6 3 11 0l245 -135q4 -4 5 -7t-6.5 -60t-17.5 -124.5t-10 -70.5q0 -5 -4 -7l-191 -153q-6 -5 -13 0z" /> + <glyph glyph-name="uniF2B9" unicode="&#xf2b9;" horiz-adv-x="1664" +d="M1201 298q0 57 -5.5 107t-21 100.5t-39.5 86t-64 58t-91 22.5q-6 -4 -33.5 -20.5t-42.5 -24.5t-40.5 -20t-49 -17t-46.5 -5t-46.5 5t-49 17t-40.5 20t-42.5 24.5t-33.5 20.5q-51 0 -91 -22.5t-64 -58t-39.5 -86t-21 -100.5t-5.5 -107q0 -73 42 -121.5t103 -48.5h576 +q61 0 103 48.5t42 121.5zM1028 892q0 108 -76.5 184t-183.5 76t-183.5 -76t-76.5 -184q0 -107 76.5 -183t183.5 -76t183.5 76t76.5 183zM1664 352v-192q0 -14 -9 -23t-23 -9h-96v-224q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h1216 +q66 0 113 -47t47 -113v-224h96q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-96v-128h96q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-96v-128h96q14 0 23 -9t9 -23z" /> + <glyph glyph-name="uniF2BA" unicode="&#xf2ba;" horiz-adv-x="1664" +d="M1028 892q0 -107 -76.5 -183t-183.5 -76t-183.5 76t-76.5 183q0 108 76.5 184t183.5 76t183.5 -76t76.5 -184zM980 672q46 0 82.5 -17t60 -47.5t39.5 -67t24 -81t11.5 -82.5t3.5 -79q0 -67 -39.5 -118.5t-105.5 -51.5h-576q-66 0 -105.5 51.5t-39.5 118.5q0 48 4.5 93.5 +t18.5 98.5t36.5 91.5t63 64.5t93.5 26h5q7 -4 32 -19.5t35.5 -21t33 -17t37 -16t35 -9t39.5 -4.5t39.5 4.5t35 9t37 16t33 17t35.5 21t32 19.5zM1664 928q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-128h96q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-128h96 +q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-224q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h1216q66 0 113 -47t47 -113v-224h96q13 0 22.5 -9.5t9.5 -22.5v-192zM1408 -96v1472q0 13 -9.5 22.5t-22.5 9.5h-1216 +q-13 0 -22.5 -9.5t-9.5 -22.5v-1472q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5z" /> + <glyph glyph-name="uniF2BB" unicode="&#xf2bb;" horiz-adv-x="2048" +d="M1024 405q0 64 -9 117.5t-29.5 103t-60.5 78t-97 28.5q-6 -4 -30 -18t-37.5 -21.5t-35.5 -17.5t-43 -14.5t-42 -4.5t-42 4.5t-43 14.5t-35.5 17.5t-37.5 21.5t-30 18q-57 0 -97 -28.5t-60.5 -78t-29.5 -103t-9 -117.5t37 -106.5t91 -42.5h512q54 0 91 42.5t37 106.5z +M867 925q0 94 -66.5 160.5t-160.5 66.5t-160.5 -66.5t-66.5 -160.5t66.5 -160.5t160.5 -66.5t160.5 66.5t66.5 160.5zM1792 416v64q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM1792 676v56q0 15 -10.5 25.5t-25.5 10.5h-568 +q-15 0 -25.5 -10.5t-10.5 -25.5v-56q0 -15 10.5 -25.5t25.5 -10.5h568q15 0 25.5 10.5t10.5 25.5zM1792 928v64q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-352v96q0 14 -9 23t-23 9 +h-64q-14 0 -23 -9t-9 -23v-96h-768v96q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-96h-352q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2BC" unicode="&#xf2bc;" horiz-adv-x="2048" +d="M1024 405q0 -64 -37 -106.5t-91 -42.5h-512q-54 0 -91 42.5t-37 106.5t9 117.5t29.5 103t60.5 78t97 28.5q6 -4 30 -18t37.5 -21.5t35.5 -17.5t43 -14.5t42 -4.5t42 4.5t43 14.5t35.5 17.5t37.5 21.5t30 18q57 0 97 -28.5t60.5 -78t29.5 -103t9 -117.5zM867 925 +q0 -94 -66.5 -160.5t-160.5 -66.5t-160.5 66.5t-66.5 160.5t66.5 160.5t160.5 66.5t160.5 -66.5t66.5 -160.5zM1792 480v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM1792 732v-56q0 -15 -10.5 -25.5t-25.5 -10.5h-568 +q-15 0 -25.5 10.5t-10.5 25.5v56q0 15 10.5 25.5t25.5 10.5h568q15 0 25.5 -10.5t10.5 -25.5zM1792 992v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM1920 32v1216q0 13 -9.5 22.5t-22.5 9.5h-1728q-13 0 -22.5 -9.5 +t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h352v96q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-96h768v96q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-96h352q13 0 22.5 9.5t9.5 22.5zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-1728q-66 0 -113 47t-47 113v1216q0 66 47 113 +t113 47h1728q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2BD" unicode="&#xf2bd;" horiz-adv-x="1792" +d="M1523 197q-22 155 -87.5 257.5t-184.5 118.5q-67 -74 -159.5 -115.5t-195.5 -41.5t-195.5 41.5t-159.5 115.5q-119 -16 -184.5 -118.5t-87.5 -257.5q106 -150 271 -237.5t356 -87.5t356 87.5t271 237.5zM1280 896q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5 +t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1792 640q0 -182 -71 -347.5t-190.5 -286t-285.5 -191.5t-349 -71q-182 0 -348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF2BE" unicode="&#xf2be;" horiz-adv-x="1792" +d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348q0 -181 -70.5 -347t-190.5 -286t-286 -191.5t-349 -71.5t-349 71t-285.5 191.5t-190.5 286t-71 347.5t71 348t191 286t286 191t348 71zM1515 185q149 205 149 455q0 156 -61 298t-164 245t-245 164t-298 61t-298 -61 +t-245 -164t-164 -245t-61 -298q0 -250 149 -455q66 327 306 327q131 -128 313 -128t313 128q240 0 306 -327zM1280 832q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5z" /> + <glyph glyph-name="uniF2C0" unicode="&#xf2c0;" +d="M1201 752q47 -14 89.5 -38t89 -73t79.5 -115.5t55 -172t22 -236.5q0 -154 -100 -263.5t-241 -109.5h-854q-141 0 -241 109.5t-100 263.5q0 131 22 236.5t55 172t79.5 115.5t89 73t89.5 38q-79 125 -79 272q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5 +t198.5 -40.5t163.5 -109.5t109.5 -163.5t40.5 -198.5q0 -147 -79 -272zM768 1408q-159 0 -271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5zM1195 -128q88 0 150.5 71.5t62.5 173.5q0 239 -78.5 377t-225.5 145 +q-145 -127 -336 -127t-336 127q-147 -7 -225.5 -145t-78.5 -377q0 -102 62.5 -173.5t150.5 -71.5h854z" /> + <glyph glyph-name="uniF2C1" unicode="&#xf2c1;" horiz-adv-x="1280" +d="M1024 278q0 -64 -37 -107t-91 -43h-512q-54 0 -91 43t-37 107t9 118t29.5 104t61 78.5t96.5 28.5q80 -75 188 -75t188 75q56 0 96.5 -28.5t61 -78.5t29.5 -104t9 -118zM870 797q0 -94 -67.5 -160.5t-162.5 -66.5t-162.5 66.5t-67.5 160.5t67.5 160.5t162.5 66.5 +t162.5 -66.5t67.5 -160.5zM1152 -96v1376h-1024v-1376q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1280 1376v-1472q0 -66 -47 -113t-113 -47h-960q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h352v-96q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v96h352 +q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2C2" unicode="&#xf2c2;" horiz-adv-x="2048" +d="M896 324q0 54 -7.5 100.5t-24.5 90t-51 68.5t-81 25q-64 -64 -156 -64t-156 64q-47 0 -81 -25t-51 -68.5t-24.5 -90t-7.5 -100.5q0 -55 31.5 -93.5t75.5 -38.5h426q44 0 75.5 38.5t31.5 93.5zM768 768q0 80 -56 136t-136 56t-136 -56t-56 -136t56 -136t136 -56t136 56 +t56 136zM1792 288v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1408 544v64q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1792 544v64q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23 +v-64q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1792 800v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM128 1152h1792v96q0 14 -9 23t-23 9h-1728q-14 0 -23 -9t-9 -23v-96zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-1728 +q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2C3" unicode="&#xf2c3;" horiz-adv-x="2048" +d="M896 324q0 -55 -31.5 -93.5t-75.5 -38.5h-426q-44 0 -75.5 38.5t-31.5 93.5q0 54 7.5 100.5t24.5 90t51 68.5t81 25q64 -64 156 -64t156 64q47 0 81 -25t51 -68.5t24.5 -90t7.5 -100.5zM768 768q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136z +M1792 352v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1408 608v-64q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h320q14 0 23 -9t9 -23zM1792 608v-64q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v64 +q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 864v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1920 32v1120h-1792v-1120q0 -13 9.5 -22.5t22.5 -9.5h1728q13 0 22.5 9.5t9.5 22.5zM2048 1248v-1216q0 -66 -47 -113t-113 -47 +h-1728q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2C4" unicode="&#xf2c4;" horiz-adv-x="1792" +d="M1255 749q0 318 -105 474.5t-330 156.5q-222 0 -326 -157t-104 -474q0 -316 104 -471.5t326 -155.5q74 0 131 17q-22 43 -39 73t-44 65t-53.5 56.5t-63 36t-77.5 14.5q-46 0 -79 -16l-49 97q105 91 276 91q132 0 215.5 -54t150.5 -155q67 149 67 402zM1645 117h117 +q3 -27 -2 -67t-26.5 -95t-58 -100.5t-107 -78t-162.5 -32.5q-71 0 -130.5 19t-105.5 56t-79 78t-66 96q-97 -27 -205 -27q-150 0 -292.5 58t-253 158.5t-178 249t-67.5 317.5q0 170 67.5 319.5t178.5 250.5t253.5 159t291.5 58q121 0 238.5 -36t217 -106t176 -164.5 +t119.5 -219t43 -261.5q0 -190 -80.5 -347.5t-218.5 -264.5q47 -70 93.5 -106.5t104.5 -36.5q61 0 94 37.5t38 85.5z" /> + <glyph glyph-name="uniF2C5" unicode="&#xf2c5;" horiz-adv-x="2304" +d="M453 -101q0 -21 -16 -37.5t-37 -16.5q-1 0 -13 3q-63 15 -162 140q-225 284 -225 676q0 341 213 614q39 51 95 103.5t94 52.5q19 0 35 -13.5t16 -32.5q0 -27 -63 -90q-98 -102 -147 -184q-119 -199 -119 -449q0 -281 123 -491q50 -85 136 -173q2 -3 14.5 -16t19.5 -21 +t17 -20.5t14.5 -23.5t4.5 -21zM1796 33q0 -29 -17.5 -48.5t-46.5 -19.5h-1081q-26 0 -45 19t-19 45q0 29 17.5 48.5t46.5 19.5h1081q26 0 45 -19t19 -45zM1581 644q0 -134 -67 -233q-25 -38 -69.5 -78.5t-83.5 -60.5q-16 -10 -27 -10q-7 0 -15 6t-8 12q0 9 19 30t42 46 +t42 67.5t19 88.5q0 76 -35 130q-29 42 -46 42q-3 0 -3 -5q0 -12 7.5 -35.5t7.5 -36.5q0 -22 -21.5 -35t-44.5 -13q-66 0 -66 76q0 15 1.5 44t1.5 44q0 25 -10 46q-13 25 -42 53.5t-51 28.5q-5 0 -7 -0.5t-3.5 -2.5t-1.5 -6q0 -2 16 -26t16 -54q0 -37 -19 -68t-46 -54 +t-53.5 -46t-45.5 -54t-19 -68q0 -98 42 -160q29 -43 79 -63q16 -5 17 -10q1 -2 1 -5q0 -16 -18 -16q-6 0 -33 11q-119 43 -195 139.5t-76 218.5q0 55 24.5 115.5t60 115t70.5 108.5t59.5 113.5t24.5 111.5q0 53 -25 94q-29 48 -56 64q-19 9 -19 21q0 20 41 20q50 0 110 -29 +q41 -19 71 -44.5t49.5 -51t33.5 -62.5t22 -69t16 -80q0 -1 3 -17.5t4.5 -25t5.5 -25t9 -27t11 -21.5t14.5 -16.5t18.5 -5.5q23 0 37 14t14 37q0 25 -20 67t-20 52t10 10q27 0 93 -70q72 -76 102.5 -156t30.5 -186zM2304 615q0 -274 -138 -503q-19 -32 -48 -72t-68 -86.5 +t-81 -77t-74 -30.5q-16 0 -31 15.5t-15 31.5q0 15 29 50.5t68.5 77t48.5 52.5q183 230 183 531q0 131 -20.5 235t-72.5 211q-58 119 -163 228q-2 3 -13 13.5t-16.5 16.5t-15 17.5t-15 20t-9.5 18.5t-4 19q0 19 16 35.5t35 16.5q70 0 196 -169q98 -131 146 -273t60 -314 +q2 -42 2 -64z" /> + <glyph glyph-name="uniF2C6" unicode="&#xf2c6;" horiz-adv-x="1792" +d="M1189 229l147 693q9 44 -10.5 63t-51.5 7l-864 -333q-29 -11 -39.5 -25t-2.5 -26.5t32 -19.5l221 -69l513 323q21 14 32 6q7 -5 -4 -15l-415 -375v0v0l-16 -228q23 0 45 22l108 104l224 -165q64 -36 81 38zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71 +t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF2C7" unicode="&#xf2c7;" horiz-adv-x="1024" +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v907h128v-907q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5 +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192 +v128h192z" /> + <glyph glyph-name="uniF2C8" unicode="&#xf2c8;" horiz-adv-x="1024" +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v651h128v-651q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5 +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192 +v128h192z" /> + <glyph glyph-name="uniF2C9" unicode="&#xf2c9;" horiz-adv-x="1024" +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v395h128v-395q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5 +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192 +v128h192z" /> + <glyph glyph-name="uniF2CA" unicode="&#xf2ca;" horiz-adv-x="1024" +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v139h128v-139q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5 +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192 +v128h192z" /> + <glyph glyph-name="uniF2CB" unicode="&#xf2cb;" horiz-adv-x="1024" +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 79 56 135.5t136 56.5t136 -56.5t56 -135.5zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5t93.5 226.5z +M896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192v128h192z" /> + <glyph glyph-name="uniF2CC" unicode="&#xf2cc;" horiz-adv-x="1920" +d="M1433 1287q10 -10 10 -23t-10 -23l-626 -626q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l44 44q-72 91 -81.5 207t46.5 215q-74 71 -176 71q-106 0 -181 -75t-75 -181v-1280h-256v1280q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5q106 0 201 -41 +t166 -115q94 39 197 24.5t185 -79.5l44 44q10 10 23 10t23 -10zM1344 1024q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1600 896q-26 0 -45 19t-19 45t19 45t45 19t45 -19t19 -45t-19 -45t-45 -19zM1856 1024q26 0 45 -19t19 -45t-19 -45t-45 -19 +t-45 19t-19 45t19 45t45 19zM1216 896q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1408 832q0 26 19 45t45 19t45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45zM1728 896q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 768 +q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1344 640q-26 0 -45 19t-19 45t19 45t45 19t45 -19t19 -45t-19 -45t-45 -19zM1600 768q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1216 512q-26 0 -45 19t-19 45t19 45t45 19t45 -19 +t19 -45t-19 -45t-45 -19zM1472 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 512q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1344 512q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1216 384 +q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 256q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19z" /> + <glyph glyph-name="uniF2CD" unicode="&#xf2cd;" horiz-adv-x="1792" +d="M1664 448v-192q0 -169 -128 -286v-194q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v118q-63 -22 -128 -22h-768q-65 0 -128 22v-110q0 -17 -9.5 -28.5t-22.5 -11.5h-64q-13 0 -22.5 11.5t-9.5 28.5v186q-128 117 -128 286v192h1536zM704 864q0 -14 -9 -23t-23 -9t-23 9 +t-9 23t9 23t23 9t23 -9t9 -23zM768 928q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM704 992q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 992q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM768 1056q0 -14 -9 -23t-23 -9t-23 9 +t-9 23t9 23t23 9t23 -9t9 -23zM704 1120q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1792 608v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v640q0 106 75 181t181 75q108 0 184 -78q46 19 98 12t93 -39l22 22q11 11 22 0l42 -42 +q11 -11 0 -22l-314 -314q-11 -11 -22 0l-42 42q-11 11 0 22l22 22q-36 46 -40.5 104t23.5 108q-37 35 -88 35q-53 0 -90.5 -37.5t-37.5 -90.5v-640h1504q14 0 23 -9t9 -23zM896 1056q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 1120q0 -14 -9 -23t-23 -9 +t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM768 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM960 1120q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM896 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 1248q0 -14 -9 -23 +t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1024 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM960 1248q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1088 1248q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23z" /> + <glyph glyph-name="uniF2CE" unicode="&#xf2ce;" +d="M994 344q0 -86 -17 -197q-31 -215 -55 -313q-22 -90 -152 -90t-152 90q-24 98 -55 313q-17 110 -17 197q0 168 224 168t224 -168zM1536 768q0 -240 -134 -434t-350 -280q-8 -3 -15 3t-6 15q7 48 10 66q4 32 6 47q1 9 9 12q159 81 255.5 234t96.5 337q0 180 -91 330.5 +t-247 234.5t-337 74q-124 -7 -237 -61t-193.5 -140.5t-128 -202t-46.5 -240.5q1 -184 99 -336.5t257 -231.5q7 -3 9 -12q3 -21 6 -45q1 -9 5 -32.5t6 -35.5q1 -9 -6.5 -15t-15.5 -2q-148 58 -261 169.5t-173.5 264t-52.5 319.5q7 143 66 273.5t154.5 227t225 157.5t272.5 70 +q164 10 315.5 -46.5t261 -160.5t175 -250.5t65.5 -308.5zM994 800q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5zM1282 768q0 -122 -53.5 -228.5t-146.5 -177.5q-8 -6 -16 -2t-10 14q-6 52 -29 92q-7 10 3 20 +q58 54 91 127t33 155q0 111 -58.5 204t-157.5 141.5t-212 36.5q-133 -15 -229 -113t-109 -231q-10 -92 23.5 -176t98.5 -144q10 -10 3 -20q-24 -41 -29 -93q-2 -9 -10 -13t-16 2q-95 74 -148.5 183t-51.5 234q3 131 69 244t177 181.5t241 74.5q144 7 268 -60t196.5 -187.5 +t72.5 -263.5z" /> + <glyph glyph-name="uniF2D0" unicode="&#xf2d0;" horiz-adv-x="1792" +d="M256 128h1280v768h-1280v-768zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2D1" unicode="&#xf2d1;" horiz-adv-x="1792" +d="M1792 224v-192q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2D2" unicode="&#xf2d2;" horiz-adv-x="2048" +d="M256 0h768v512h-768v-512zM1280 512h512v768h-768v-256h96q66 0 113 -47t47 -113v-352zM2048 1376v-960q0 -66 -47 -113t-113 -47h-608v-352q0 -66 -47 -113t-113 -47h-960q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h608v352q0 66 47 113t113 47h960q66 0 113 -47 +t47 -113z" /> + <glyph glyph-name="uniF2D3" unicode="&#xf2d3;" horiz-adv-x="1792" +d="M1175 215l146 146q10 10 10 23t-10 23l-233 233l233 233q10 10 10 23t-10 23l-146 146q-10 10 -23 10t-23 -10l-233 -233l-233 233q-10 10 -23 10t-23 -10l-146 -146q-10 -10 -10 -23t10 -23l233 -233l-233 -233q-10 -10 -10 -23t10 -23l146 -146q10 -10 23 -10t23 10 +l233 233l233 -233q10 -10 23 -10t23 10zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2D4" unicode="&#xf2d4;" horiz-adv-x="1792" +d="M1257 425l-146 -146q-10 -10 -23 -10t-23 10l-169 169l-169 -169q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l169 169l-169 169q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l169 -169l169 169q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23 +l-169 -169l169 -169q10 -10 10 -23t-10 -23zM256 128h1280v1024h-1280v-1024zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2D5" unicode="&#xf2d5;" horiz-adv-x="1792" +d="M1070 358l306 564h-654l-306 -564h654zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF2D6" unicode="&#xf2d6;" horiz-adv-x="1794" +d="M1291 1060q-15 17 -35 8.5t-26 -28.5t5 -38q14 -17 40 -14.5t34 20.5t-18 52zM895 814q-8 -8 -19.5 -8t-18.5 8q-8 8 -8 19t8 18q7 8 18.5 8t19.5 -8q7 -7 7 -18t-7 -19zM1060 740l-35 -35q-12 -13 -29.5 -13t-30.5 13l-38 38q-12 13 -12 30t12 30l35 35q12 12 29.5 12 +t30.5 -12l38 -39q12 -12 12 -29.5t-12 -29.5zM951 870q-7 -8 -18.5 -8t-19.5 8q-7 8 -7 19t7 19q8 8 19 8t19 -8t8 -19t-8 -19zM1354 968q-34 -64 -107.5 -85.5t-127.5 16.5q-38 28 -61 66.5t-21 87.5t39 92t75.5 53t70.5 -5t70 -51q2 -2 13 -12.5t14.5 -13.5t13 -13.5 +t12.5 -15.5t10 -15.5t8.5 -18t4 -18.5t1 -21t-5 -22t-9.5 -24zM1555 486q3 20 -8.5 34.5t-27.5 21.5t-33 17t-23 20q-40 71 -84 98.5t-113 11.5q19 13 40 18.5t33 4.5l12 -1q2 45 -34 90q6 20 6.5 40.5t-2.5 30.5l-3 10q43 24 71 65t34 91q10 84 -43 150.5t-137 76.5 +q-60 7 -114 -18.5t-82 -74.5q-30 -51 -33.5 -101t14.5 -87t43.5 -64t56.5 -42q-45 4 -88 36t-57 88q-28 108 32 222q-16 21 -29 32q-50 0 -89 -19q19 24 42 37t36 14l13 1q0 50 -13 78q-10 21 -32.5 28.5t-47 -3.5t-37.5 -40q2 4 4 7q-7 -28 -6.5 -75.5t19 -117t48.5 -122.5 +q-25 -14 -47 -36q-35 -16 -85.5 -70.5t-84.5 -101.5l-33 -46q-90 -34 -181 -125.5t-75 -162.5q1 -16 11 -27q-15 -12 -30 -30q-21 -25 -21 -54t21.5 -40t63.5 6q41 19 77 49.5t55 60.5q-2 2 -6.5 5t-20.5 7.5t-33 3.5q23 5 51 12.5t40 10t27.5 6t26 4t23.5 0.5q14 -7 22 34 +q7 37 7 90q0 102 -40 150q106 -103 101 -219q-1 -29 -15 -50t-27 -27l-13 -6q-4 -7 -19 -32t-26 -45.5t-26.5 -52t-25 -61t-17 -63t-6.5 -66.5t10 -63q-35 54 -37 80q-22 -24 -34.5 -39t-33.5 -42t-30.5 -46t-16.5 -41t-0.5 -38t25.5 -27q45 -25 144 64t190.5 221.5 +t122.5 228.5q86 52 145 115.5t86 119.5q47 -93 154 -178q104 -83 167 -80q39 2 46 43zM1794 640q0 -182 -71 -348t-191 -286t-286.5 -191t-348.5 -71t-348.5 71t-286.5 191t-191 286t-71 348t71 348t191 286t286.5 191t348.5 71t348.5 -71t286.5 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF2D7" unicode="&#xf2d7;" +d="M518 1353v-655q103 -1 191.5 1.5t125.5 5.5l37 3q68 2 90.5 24.5t39.5 94.5l33 142h103l-14 -322l7 -319h-103l-29 127q-15 68 -45 93t-84 26q-87 8 -352 8v-556q0 -78 43.5 -115.5t133.5 -37.5h357q35 0 59.5 2t55 7.5t54 18t48.5 32t46 50.5t39 73l93 216h89 +q-6 -37 -31.5 -252t-30.5 -276q-146 5 -263.5 8t-162.5 4h-44h-628l-376 -12v102l127 25q67 13 91.5 37t25.5 79l8 643q3 402 -8 645q-2 61 -25.5 84t-91.5 36l-127 24v102l376 -12h702q139 0 374 27q-6 -68 -14 -194.5t-12 -219.5l-5 -92h-93l-32 124q-31 121 -74 179.5 +t-113 58.5h-548q-28 0 -35.5 -8.5t-7.5 -30.5z" /> + <glyph glyph-name="uniF2D8" unicode="&#xf2d8;" +d="M922 739v-182q0 -4 0.5 -15t0 -15l-1.5 -12t-3.5 -11.5t-6.5 -7.5t-11 -5.5t-16 -1.5v309q9 0 16 -1t11 -5t6.5 -5.5t3.5 -9.5t1 -10.5v-13.5v-14zM1238 643v-121q0 -1 0.5 -12.5t0 -15.5t-2.5 -11.5t-7.5 -10.5t-13.5 -3q-9 0 -14 9q-4 10 -4 165v7v8.5v9t1.5 8.5l3.5 7 +t5 5.5t8 1.5q6 0 10 -1.5t6.5 -4.5t4 -6t2 -8.5t0.5 -8v-9.5v-9zM180 407h122v472h-122v-472zM614 407h106v472h-159l-28 -221q-20 148 -32 221h-158v-472h107v312l45 -312h76l43 319v-319zM1039 712q0 67 -5 90q-3 16 -11 28.5t-17 20.5t-25 14t-26.5 8.5t-31 4t-29 1.5 +h-29.5h-12h-91v-472h56q169 -1 197 24.5t25 180.5q-1 62 -1 100zM1356 515v133q0 29 -2 45t-9.5 33.5t-24.5 25t-46 7.5q-46 0 -77 -34v154h-117v-472h110l7 30q30 -36 77 -36q50 0 66 30.5t16 83.5zM1536 1248v-1216q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113 +v1216q0 66 47 113t113 47h1216q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2D9" unicode="&#xf2d9;" horiz-adv-x="2176" +d="M1143 -197q-6 1 -11 4q-13 8 -36 23t-86 65t-116.5 104.5t-112 140t-89.5 172.5q-17 3 -175 37q66 -213 235 -362t391 -184zM502 409l168 -28q-25 76 -41 167.5t-19 145.5l-4 53q-84 -82 -121 -224q5 -65 17 -114zM612 1018q-43 -64 -77 -148q44 46 74 68zM2049 584 +q0 161 -62 307t-167.5 252t-250.5 168.5t-304 62.5q-147 0 -281 -52.5t-240 -148.5q-30 -58 -45 -160q60 51 143 83.5t158.5 43t143 13.5t108.5 -1l40 -3q33 -1 53 -15.5t24.5 -33t6.5 -37t-1 -28.5q-126 11 -227.5 0.5t-183 -43.5t-142.5 -71.5t-131 -98.5 +q4 -36 11.5 -92.5t35.5 -178t62 -179.5q123 -6 247.5 14.5t214.5 53.5t162.5 67t109.5 59l37 24q22 16 39.5 20.5t30.5 -5t17 -34.5q14 -97 -39 -121q-208 -97 -467 -134q-135 -20 -317 -16q41 -96 110 -176.5t137 -127t130.5 -79t101.5 -43.5l39 -12q143 -23 263 15 +q195 99 314 289t119 418zM2123 621q-14 -135 -40 -212q-70 -208 -181.5 -346.5t-318.5 -253.5q-48 -33 -82 -44q-72 -26 -163 -16q-36 -3 -73 -3q-283 0 -504.5 173t-295.5 442q-1 0 -4 0.5t-5 0.5q-6 -50 2.5 -112.5t26 -115t36 -98t31.5 -71.5l14 -26q8 -12 54 -82 +q-71 38 -124.5 106.5t-78.5 140t-39.5 137t-17.5 107.5l-2 42q-5 2 -33.5 12.5t-48.5 18t-53 20.5t-57.5 25t-50 25.5t-42.5 27t-25 25.5q19 -10 50.5 -25.5t113 -45.5t145.5 -38l2 32q11 149 94 290q41 202 176 365q28 115 81 214q15 28 32 45t49 32q158 74 303.5 104 +t302 11t306.5 -97q220 -115 333 -336t87 -474z" /> + <glyph glyph-name="uniF2DA" unicode="&#xf2da;" horiz-adv-x="1792" +d="M1341 752q29 44 -6.5 129.5t-121.5 142.5q-58 39 -125.5 53.5t-118 4.5t-68.5 -37q-12 -23 -4.5 -28t42.5 -10q23 -3 38.5 -5t44.5 -9.5t56 -17.5q36 -13 67.5 -31.5t53 -37t40 -38.5t30.5 -38t22 -34.5t16.5 -28.5t12 -18.5t10.5 -6t11 9.5zM1704 178 +q-52 -127 -148.5 -220t-214.5 -141.5t-253 -60.5t-266 13.5t-251 91t-210 161.5t-141.5 235.5t-46.5 303.5q1 41 8.5 84.5t12.5 64t24 80.5t23 73q-51 -208 1 -397t173 -318t291 -206t346 -83t349 74.5t289 244.5q20 27 18 14q0 -4 -4 -14zM1465 627q0 -104 -40.5 -199 +t-108.5 -164t-162 -109.5t-198 -40.5t-198 40.5t-162 109.5t-108.5 164t-40.5 199t40.5 199t108.5 164t162 109.5t198 40.5t198 -40.5t162 -109.5t108.5 -164t40.5 -199zM1752 915q-65 147 -180.5 251t-253 153.5t-292 53.5t-301 -36.5t-275.5 -129t-220 -211.5t-131 -297 +t-10 -373q-49 161 -51.5 311.5t35.5 272.5t109 227t165.5 180.5t207 126t232 71t242.5 9t236 -54t216 -124.5t178 -197q33 -50 62 -121t31 -112zM1690 573q12 244 -136.5 416t-396.5 240q-8 0 -10 5t24 8q125 -4 230 -50t173 -120t116 -168.5t58.5 -199t-1 -208 +t-61.5 -197.5t-122.5 -167t-185 -117.5t-248.5 -46.5q108 30 201.5 80t174 123t129.5 176.5t55 225.5z" /> + <glyph glyph-name="uniF2DB" unicode="&#xf2db;" +d="M192 256v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 512v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 768v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16 +q0 16 16 16h112zM192 1024v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 1280v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM1280 1440v-1472q0 -40 -28 -68t-68 -28h-832q-40 0 -68 28 +t-28 68v1472q0 40 28 68t68 28h832q40 0 68 -28t28 -68zM1536 208v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 464v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 720v-32 +q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 976v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 1232v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16 +h48q16 0 16 -16z" /> + <glyph glyph-name="uniF2DC" unicode="&#xf2dc;" horiz-adv-x="1664" +d="M1566 419l-167 -33l186 -107q23 -13 29.5 -38.5t-6.5 -48.5q-14 -23 -39 -29.5t-48 6.5l-186 106l55 -160q13 -38 -12 -63.5t-60.5 -20.5t-48.5 42l-102 300l-271 156v-313l208 -238q16 -18 17 -39t-11 -36.5t-28.5 -25t-37 -5.5t-36.5 22l-112 128v-214q0 -26 -19 -45 +t-45 -19t-45 19t-19 45v214l-112 -128q-16 -18 -36.5 -22t-37 5.5t-28.5 25t-11 36.5t17 39l208 238v313l-271 -156l-102 -300q-13 -37 -48.5 -42t-60.5 20.5t-12 63.5l55 160l-186 -106q-23 -13 -48 -6.5t-39 29.5q-13 23 -6.5 48.5t29.5 38.5l186 107l-167 33 +q-29 6 -42 29t-8.5 46.5t25.5 40t50 10.5l310 -62l271 157l-271 157l-310 -62q-4 -1 -13 -1q-27 0 -44 18t-19 40t11 43t40 26l167 33l-186 107q-23 13 -29.5 38.5t6.5 48.5t39 30t48 -7l186 -106l-55 160q-13 38 12 63.5t60.5 20.5t48.5 -42l102 -300l271 -156v313 +l-208 238q-16 18 -17 39t11 36.5t28.5 25t37 5.5t36.5 -22l112 -128v214q0 26 19 45t45 19t45 -19t19 -45v-214l112 128q16 18 36.5 22t37 -5.5t28.5 -25t11 -36.5t-17 -39l-208 -238v-313l271 156l102 300q13 37 48.5 42t60.5 -20.5t12 -63.5l-55 -160l186 106 +q23 13 48 6.5t39 -29.5q13 -23 6.5 -48.5t-29.5 -38.5l-186 -107l167 -33q27 -5 40 -26t11 -43t-19 -40t-44 -18q-9 0 -13 1l-310 62l-271 -157l271 -157l310 62q29 6 50 -10.5t25.5 -40t-8.5 -46.5t-42 -29z" /> + <glyph glyph-name="uniF2DD" unicode="&#xf2dd;" horiz-adv-x="1792" +d="M1473 607q7 118 -33 226.5t-113 189t-177 131t-221 57.5q-116 7 -225.5 -32t-192 -110.5t-135 -175t-59.5 -220.5q-7 -118 33 -226.5t113 -189t177.5 -131t221.5 -57.5q155 -9 293 59t224 195.5t94 283.5zM1792 1536l-349 -348q120 -117 180.5 -272t50.5 -321 +q-11 -183 -102 -339t-241 -255.5t-332 -124.5l-999 -132l347 347q-120 116 -180.5 271.5t-50.5 321.5q11 184 102 340t241.5 255.5t332.5 124.5q167 22 500 66t500 66z" /> + <glyph glyph-name="uniF2DE" unicode="&#xf2de;" horiz-adv-x="1792" +d="M948 508l163 -329h-51l-175 350l-171 -350h-49l179 374l-78 33l21 49l240 -102l-21 -50zM563 1100l304 -130l-130 -304l-304 130zM907 915l240 -103l-103 -239l-239 102zM1188 765l191 -81l-82 -190l-190 81zM1680 640q0 159 -62 304t-167.5 250.5t-250.5 167.5t-304 62 +t-304 -62t-250.5 -167.5t-167.5 -250.5t-62 -304t62 -304t167.5 -250.5t250.5 -167.5t304 -62t304 62t250.5 167.5t167.5 250.5t62 304zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71 +t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF2E0" unicode="&#xf2e0;" horiz-adv-x="1920" +d="M1334 302q-4 24 -27.5 34t-49.5 10.5t-48.5 12.5t-25.5 38q-5 47 33 139.5t75 181t32 127.5q-14 101 -117 103q-45 1 -75 -16l-3 -2l-5 -2.5t-4.5 -2t-5 -2t-5 -0.5t-6 1.5t-6 3.5t-6.5 5q-3 2 -9 8.5t-9 9t-8.5 7.5t-9.5 7.5t-9.5 5.5t-11 4.5t-11.5 2.5q-30 5 -48 -3 +t-45 -31q-1 -1 -9 -8.5t-12.5 -11t-15 -10t-16.5 -5.5t-17 3q-54 27 -84 40q-41 18 -94 -5t-76 -65q-16 -28 -41 -98.5t-43.5 -132.5t-40 -134t-21.5 -73q-22 -69 18.5 -119t110.5 -46q30 2 50.5 15t38.5 46q7 13 79 199.5t77 194.5q6 11 21.5 18t29.5 0q27 -15 21 -53 +q-2 -18 -51 -139.5t-50 -132.5q-6 -38 19.5 -56.5t60.5 -7t55 49.5q4 8 45.5 92t81.5 163.5t46 88.5q20 29 41 28q29 0 25 -38q-2 -16 -65.5 -147.5t-70.5 -159.5q-12 -53 13 -103t74 -74q17 -9 51 -15.5t71.5 -8t62.5 14t20 48.5zM383 86q3 -15 -5 -27.5t-23 -15.5 +q-14 -3 -26.5 5t-15.5 23q-3 14 5 27t22 16t27 -5t16 -23zM953 -177q12 -17 8.5 -37.5t-20.5 -32.5t-37.5 -8t-32.5 21q-11 17 -7.5 37.5t20.5 32.5t37.5 8t31.5 -21zM177 635q-18 -27 -49.5 -33t-57.5 13q-26 18 -32 50t12 58q18 27 49.5 33t57.5 -12q26 -19 32 -50.5 +t-12 -58.5zM1467 -42q19 -28 13 -61.5t-34 -52.5t-60.5 -13t-51.5 34t-13 61t33 53q28 19 60.5 13t52.5 -34zM1579 562q69 -113 42.5 -244.5t-134.5 -207.5q-90 -63 -199 -60q-20 -80 -84.5 -127t-143.5 -44.5t-140 57.5q-12 -9 -13 -10q-103 -71 -225 -48.5t-193 126.5 +q-50 73 -53 164q-83 14 -142.5 70.5t-80.5 128t-2 152t81 138.5q-36 60 -38 128t24.5 125t79.5 98.5t121 50.5q32 85 99 148t146.5 91.5t168 17t159.5 -66.5q72 21 140 17.5t128.5 -36t104.5 -80t67.5 -115t17.5 -140.5q52 -16 87 -57t45.5 -89t-5.5 -99.5t-58 -87.5z +M455 1222q14 -20 9.5 -44.5t-24.5 -38.5q-19 -14 -43.5 -9.5t-37.5 24.5q-14 20 -9.5 44.5t24.5 38.5q19 14 43.5 9.5t37.5 -24.5zM614 1503q4 -16 -5 -30.5t-26 -18.5t-31 5.5t-18 26.5q-3 17 6.5 31t25.5 18q17 4 31 -5.5t17 -26.5zM1800 555q4 -20 -6.5 -37t-30.5 -21 +q-19 -4 -36 6.5t-21 30.5t6.5 37t30.5 22q20 4 36.5 -7.5t20.5 -30.5zM1136 1448q16 -27 8.5 -58.5t-35.5 -47.5q-27 -16 -57.5 -8.5t-46.5 34.5q-16 28 -8.5 59t34.5 48t58 9t47 -36zM1882 792q4 -15 -4 -27.5t-23 -16.5q-15 -3 -27.5 5.5t-15.5 22.5q-3 15 5 28t23 16 +q14 3 26.5 -5t15.5 -23zM1691 1033q15 -22 10.5 -49t-26.5 -43q-22 -15 -49 -10t-42 27t-10 49t27 43t48.5 11t41.5 -28z" /> + <glyph glyph-name="uniF2E1" unicode="&#xf2e1;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E2" unicode="&#xf2e2;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E3" unicode="&#xf2e3;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E4" unicode="&#xf2e4;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E5" unicode="&#xf2e5;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E6" unicode="&#xf2e6;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E7" unicode="&#xf2e7;" horiz-adv-x="1792" + /> + <glyph glyph-name="_698" unicode="&#xf2e8;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E9" unicode="&#xf2e9;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2EA" unicode="&#xf2ea;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2EB" unicode="&#xf2eb;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2EC" unicode="&#xf2ec;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2ED" unicode="&#xf2ed;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2EE" unicode="&#xf2ee;" horiz-adv-x="1792" + /> + <glyph glyph-name="lessequal" unicode="&#xf500;" horiz-adv-x="1792" + /> + </font> +</defs></svg> diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.ttf b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.ttf differ diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.woff b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.woff differ diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.woff2 b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.woff2 differ diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/i18next/i18next.min.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/i18next/i18next.min.js new file mode 100644 index 0000000..3ba215d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/i18next/i18next.min.js @@ -0,0 +1,5 @@ +// i18next, v1.8.1 +// Copyright (c)2015 Jan Mühlemann (jamuhl). +// Distributed under MIT license +// http://i18next.com +!function(a){function b(a,b){if(!b||"function"==typeof b)return a;for(var c in b)a[c]=b[c];return a}function c(a,b){for(var d in b)d in a?c(a[d],b[d]):a[d]=b[d];return a}function d(a,b,c){var d,e=0,f=a.length,g=void 0===f||"[object Array]"!==Object.prototype.toString.apply(a)||"function"==typeof a;if(c)if(g){for(d in a)if(b.apply(a[d],c)===!1)break}else for(;f>e&&b.apply(a[e++],c)!==!1;);else if(g){for(d in a)if(b.call(a[d],d,a[d])===!1)break}else for(;f>e&&b.call(a[e],e,a[e++])!==!1;);return a}function e(a){return"string"==typeof a?a.replace(/[&<>"'\/]/g,function(a){return Q[a]}):a}function f(a){var b=function(a){if(window.XMLHttpRequest)return a(null,new XMLHttpRequest);if(window.ActiveXObject)try{return a(null,new ActiveXObject("Msxml2.XMLHTTP"))}catch(b){return a(null,new ActiveXObject("Microsoft.XMLHTTP"))}return a(new Error)},c=function(a){if("string"==typeof a)return a;var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")},d=function(a){a=a.replace(/\r\n/g,"\n");for(var b="",c=0;c<a.length;c++){var d=a.charCodeAt(c);128>d?b+=String.fromCharCode(d):d>127&&2048>d?(b+=String.fromCharCode(d>>6|192),b+=String.fromCharCode(63&d|128)):(b+=String.fromCharCode(d>>12|224),b+=String.fromCharCode(d>>6&63|128),b+=String.fromCharCode(63&d|128))}return b},e=function(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";a=d(a);var c,e,f,g,h,i,j,k="",l=0;do c=a.charCodeAt(l++),e=a.charCodeAt(l++),f=a.charCodeAt(l++),g=c>>2,h=(3&c)<<4|e>>4,i=(15&e)<<2|f>>6,j=63&f,isNaN(e)?i=j=64:isNaN(f)&&(j=64),k+=b.charAt(g)+b.charAt(h)+b.charAt(i)+b.charAt(j),c=e=f="",g=h=i=j="";while(l<a.length);return k},f=function(){for(var a=arguments[0],b=1;b<arguments.length;b++){var c=arguments[b];for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}return a},g=function(a,d,e,h){"function"==typeof e&&(h=e,e={}),e.cache=e.cache||!1,e.data=e.data||{},e.headers=e.headers||{},e.jsonp=e.jsonp||!1,e.async=void 0===e.async?!0:e.async;var i,j=f({accept:"*/*","content-type":"application/x-www-form-urlencoded;charset=UTF-8"},g.headers,e.headers);if(i="application/json"===j["content-type"]?JSON.stringify(e.data):c(e.data),"GET"===a){var k=[];if(i&&(k.push(i),i=null),e.cache||k.push("_="+(new Date).getTime()),e.jsonp&&(k.push("callback="+e.jsonp),k.push("jsonp="+e.jsonp)),k=k.join("&"),k.length>1&&(d+=d.indexOf("?")>-1?"&"+k:"?"+k),e.jsonp){var l=document.getElementsByTagName("head")[0],m=document.createElement("script");return m.type="text/javascript",m.src=d,void l.appendChild(m)}}b(function(b,c){if(b)return h(b);c.open(a,d,e.async);for(var f in j)j.hasOwnProperty(f)&&c.setRequestHeader(f,j[f]);c.onreadystatechange=function(){if(4===c.readyState){var a=c.responseText||"";if(!h)return;h(c.status,{text:function(){return a},json:function(){try{return JSON.parse(a)}catch(b){return T.error("Can not parse JSON. URL: "+d),{}}}})}},c.send(i)})},h={authBasic:function(a,b){g.headers.Authorization="Basic "+e(a+":"+b)},connect:function(a,b,c){return g("CONNECT",a,b,c)},del:function(a,b,c){return g("DELETE",a,b,c)},get:function(a,b,c){return g("GET",a,b,c)},head:function(a,b,c){return g("HEAD",a,b,c)},headers:function(a){g.headers=a||{}},isAllowed:function(a,b,c){this.options(a,function(a,d){c(-1!==d.text().indexOf(b))})},options:function(a,b,c){return g("OPTIONS",a,b,c)},patch:function(a,b,c){return g("PATCH",a,b,c)},post:function(a,b,c){return g("POST",a,b,c)},put:function(a,b,c){return g("PUT",a,b,c)},trace:function(a,b,c){return g("TRACE",a,b,c)}},i=a.type?a.type.toLowerCase():"get";h[i](a.url,a,function(b,c){200===b||0===b&&c.text()?a.success(c.json(),b,null):a.error(c.text(),b,null)})}function g(a,b){"function"==typeof a&&(b=a,a={}),a=a||{},T.extend(P,a),delete P.fixLng,P.functions&&(delete P.functions,T.extend(T,a.functions)),"string"==typeof P.ns&&(P.ns={namespaces:[P.ns],defaultNs:P.ns}),"string"==typeof P.fallbackNS&&(P.fallbackNS=[P.fallbackNS]),("string"==typeof P.fallbackLng||"boolean"==typeof P.fallbackLng)&&(P.fallbackLng=[P.fallbackLng]),P.interpolationPrefixEscaped=T.regexEscape(P.interpolationPrefix),P.interpolationSuffixEscaped=T.regexEscape(P.interpolationSuffix),P.lng||(P.lng=T.detectLanguage()),M=T.toLanguages(P.lng),H=M[0],T.log("currentLng set to: "+H),P.useCookie&&T.cookie.read(P.cookieName)!==H&&T.cookie.create(P.cookieName,H,P.cookieExpirationTime,P.cookieDomain),P.detectLngFromLocalStorage&&"undefined"!=typeof document&&window.localStorage&&T.localStorage.setItem("i18next_lng",H);var c=B;a.fixLng&&(c=function(a,b){return b=b||{},b.lng=b.lng||c.lng,B(a,b)},c.lng=H),W.setCurrentLng(H),I&&P.setJqueryExt&&u();var d;if(I&&I.Deferred&&(d=I.Deferred()),!P.resStore){var e=T.toLanguages(P.lng);"string"==typeof P.preload&&(P.preload=[P.preload]);for(var f=0,g=P.preload.length;g>f;f++)for(var h=T.toLanguages(P.preload[f]),i=0,j=h.length;j>i;i++)e.indexOf(h[i])<0&&e.push(h[i]);return J.sync.load(e,P,function(a,e){K=e,N=!0,b&&b(c),d&&d.resolve(c)}),d?d.promise():void 0}return K=P.resStore,N=!0,b&&b(c),d&&d.resolve(c),d?d.promise():void 0}function h(a,b){"string"==typeof a&&(a=[a]);for(var c=0,d=a.length;d>c;c++)P.preload.indexOf(a[c])<0&&P.preload.push(a[c]);return g(b)}function i(a,b,c,d){"string"!=typeof b?(c=b,b=P.ns.defaultNs):P.ns.namespaces.indexOf(b)<0&&P.ns.namespaces.push(b),K[a]=K[a]||{},K[a][b]=K[a][b]||{},d?T.deepExtend(K[a][b],c):T.extend(K[a][b],c),P.useLocalStorage&&O._storeLocal(K)}function j(a,b){"string"!=typeof b&&(b=P.ns.defaultNs),K[a]=K[a]||{};var c=K[a][b]||{},d=!1;for(var e in c)c.hasOwnProperty(e)&&(d=!0);return d}function k(a,b){return"string"!=typeof b&&(b=P.ns.defaultNs),K[a]=K[a]||{},T.extend({},K[a][b])}function l(a,b){"string"!=typeof b&&(b=P.ns.defaultNs),K[a]=K[a]||{},K[a][b]={},P.useLocalStorage&&O._storeLocal(K)}function m(a,b,c,d){"string"!=typeof b?(resource=b,b=P.ns.defaultNs):P.ns.namespaces.indexOf(b)<0&&P.ns.namespaces.push(b),K[a]=K[a]||{},K[a][b]=K[a][b]||{};for(var e=c.split(P.keyseparator),f=0,g=K[a][b];e[f];)f==e.length-1?g[e[f]]=d:(null==g[e[f]]&&(g[e[f]]={}),g=g[e[f]]),f++;P.useLocalStorage&&O._storeLocal(K)}function n(a,b,c){"string"!=typeof b?(resource=b,b=P.ns.defaultNs):P.ns.namespaces.indexOf(b)<0&&P.ns.namespaces.push(b);for(var d in c)"string"==typeof c[d]&&m(a,b,d,c[d])}function o(a){P.ns.defaultNs=a}function p(a,b){q([a],b)}function q(a,b){var c={dynamicLoad:P.dynamicLoad,resGetPath:P.resGetPath,getAsync:P.getAsync,customLoad:P.customLoad,ns:{namespaces:a,defaultNs:""}},d=T.toLanguages(P.lng);"string"==typeof P.preload&&(P.preload=[P.preload]);for(var e=0,f=P.preload.length;f>e;e++)for(var g=T.toLanguages(P.preload[e]),h=0,i=g.length;i>h;h++)d.indexOf(g[h])<0&&d.push(g[h]);for(var j=[],k=0,l=d.length;l>k;k++){var m=!1,n=K[d[k]];if(n)for(var o=0,p=a.length;p>o;o++)n[a[o]]||(m=!0);else m=!0;m&&j.push(d[k])}j.length?J.sync._fetch(j,c,function(c,d){var e=a.length*j.length;T.each(a,function(a,c){P.ns.namespaces.indexOf(c)<0&&P.ns.namespaces.push(c),T.each(j,function(a,f){K[f]=K[f]||{},K[f][c]=d[f][c],e--,0===e&&b&&(P.useLocalStorage&&J.sync._storeLocal(K),b())})})}):b&&b()}function r(a,b,c){return"function"==typeof b?(c=b,b={}):b||(b={}),b.lng=a,g(b,c)}function s(){return H}function t(a){K={},r(H,a)}function u(){function a(a,b,c){if(0!==b.length){var d="text";if(0===b.indexOf("[")){var e=b.split("]");b=e[1],d=e[0].substr(1,e[0].length-1)}b.indexOf(";")===b.length-1&&(b=b.substr(0,b.length-2));var f;if("html"===d)f=P.defaultValueFromContent?I.extend({defaultValue:a.html()},c):c,a.html(I.t(b,f));else if("text"===d)f=P.defaultValueFromContent?I.extend({defaultValue:a.text()},c):c,a.text(I.t(b,f));else if("prepend"===d)f=P.defaultValueFromContent?I.extend({defaultValue:a.html()},c):c,a.prepend(I.t(b,f));else if("append"===d)f=P.defaultValueFromContent?I.extend({defaultValue:a.html()},c):c,a.append(I.t(b,f));else if(0===d.indexOf("data-")){var g=d.substr("data-".length);f=P.defaultValueFromContent?I.extend({defaultValue:a.data(g)},c):c;var h=I.t(b,f);a.data(g,h),a.attr(d,h)}else f=P.defaultValueFromContent?I.extend({defaultValue:a.attr(d)},c):c,a.attr(d,I.t(b,f))}}function b(b,c){var d=b.attr(P.selectorAttr);if(d||"undefined"==typeof d||d===!1||(d=b.text()||b.val()),d){var e=b,f=b.data("i18n-target");if(f&&(e=b.find(f)||b),c||P.useDataAttrOptions!==!0||(c=b.data("i18n-options")),c=c||{},d.indexOf(";")>=0){var g=d.split(";");I.each(g,function(b,d){""!==d&&a(e,d,c)})}else a(e,d,c);P.useDataAttrOptions===!0&&b.data("i18n-options",c)}}I.t=I.t||B,I.fn.i18n=function(a){return this.each(function(){b(I(this),a);var c=I(this).find("["+P.selectorAttr+"]");c.each(function(){b(I(this),a)})})}}function v(a,b,c,d){if(!a)return a;if(d=d||b,a.indexOf(d.interpolationPrefix||P.interpolationPrefix)<0)return a;var e=d.interpolationPrefix?T.regexEscape(d.interpolationPrefix):P.interpolationPrefixEscaped,f=d.interpolationSuffix?T.regexEscape(d.interpolationSuffix):P.interpolationSuffixEscaped,g="HTML"+f,h=b.replace&&"object"==typeof b.replace?b.replace:b;return T.each(h,function(b,h){var i=c?c+P.keyseparator+b:b;"object"==typeof h&&null!==h?a=v(a,h,i,d):d.escapeInterpolation||P.escapeInterpolation?(a=a.replace(new RegExp([e,i,g].join(""),"g"),T.regexReplacementEscape(h)),a=a.replace(new RegExp([e,i,f].join(""),"g"),T.regexReplacementEscape(T.escape(h)))):a=a.replace(new RegExp([e,i,f].join(""),"g"),T.regexReplacementEscape(h))}),a}function w(a,b){var c=",",d="{",e="}",f=T.extend({},b);for(delete f.postProcess;-1!=a.indexOf(P.reusePrefix)&&(L++,!(L>P.maxRecursion));){var g=a.lastIndexOf(P.reusePrefix),h=a.indexOf(P.reuseSuffix,g)+P.reuseSuffix.length,i=a.substring(g,h),j=i.replace(P.reusePrefix,"").replace(P.reuseSuffix,"");if(g>=h)return T.error("there is an missing closing in following translation value",a),"";if(-1!=j.indexOf(c)){var k=j.indexOf(c);if(-1!=j.indexOf(d,k)&&-1!=j.indexOf(e,k)){var l=j.indexOf(d,k),m=j.indexOf(e,l)+e.length;try{f=T.extend(f,JSON.parse(j.substring(l,m))),j=j.substring(0,k)}catch(n){}}}var o=E(j,f);a=a.replace(i,T.regexReplacementEscape(o))}return a}function x(a){return a.context&&("string"==typeof a.context||"number"==typeof a.context)}function y(a){return void 0!==a.count&&"string"!=typeof a.count}function z(a){return void 0!==a.indefinite_article&&"string"!=typeof a.indefinite_article&&a.indefinite_article}function A(a,b){b=b||{};var c=C(a,b),d=F(a,b);return void 0!==d||d===c}function B(a,b){return b=b||{},N?(L=0,E.apply(null,arguments)):(T.log("i18next not finished initialization. you might have called t function before loading resources finished."),b.defaultValue||"")}function C(a,b){return void 0!==b.defaultValue?b.defaultValue:a}function D(){for(var a=[],b=1;b<arguments.length;b++)a.push(arguments[b]);return{postProcess:"sprintf",sprintf:a}}function E(a,b){if(b&&"object"!=typeof b?"sprintf"===P.shortcutFunction?b=D.apply(null,arguments):"defaultValue"===P.shortcutFunction&&(b={defaultValue:b}):b=b||{},"object"==typeof P.defaultVariables&&(b=T.extend({},P.defaultVariables,b)),void 0===a||null===a||""===a)return"";"number"==typeof a&&(a=String(a)),"string"==typeof a&&(a=[a]);var c=a[0];if(a.length>1)for(var d=0;d<a.length&&(c=a[d],!A(c,b));d++);var e,f=C(c,b),g=F(c,b),h=b.lng?T.toLanguages(b.lng,b.fallbackLng):M,i=b.ns||P.ns.defaultNs;c.indexOf(P.nsseparator)>-1&&(e=c.split(P.nsseparator),i=e[0],c=e[1]),void 0===g&&P.sendMissing&&"function"==typeof P.missingKeyHandler&&(b.lng?P.missingKeyHandler(h[0],i,c,f,h):P.missingKeyHandler(P.lng,i,c,f,h));var j;j="string"==typeof P.postProcess&&""!==P.postProcess?[P.postProcess]:"array"==typeof P.postProcess||"object"==typeof P.postProcess?P.postProcess:[],"string"==typeof b.postProcess&&""!==b.postProcess?j=j.concat([b.postProcess]):("array"==typeof b.postProcess||"object"==typeof b.postProcess)&&(j=j.concat(b.postProcess)),void 0!==g&&j.length&&j.forEach(function(a){X[a]&&(g=X[a](g,c,b))});var k=f;if(f.indexOf(P.nsseparator)>-1&&(e=f.split(P.nsseparator),k=e[1]),k===c&&P.parseMissingKey&&(f=P.parseMissingKey(f)),void 0===g&&(f=v(f,b),f=w(f,b),j.length)){var l=C(c,b);j.forEach(function(a){X[a]&&(g=X[a](l,c,b))})}return void 0!==g?g:f}function F(a,b){b=b||{};var c,d,e=C(a,b),f=M;if(!K)return e;if("cimode"===f[0].toLowerCase())return e;if(b.lngs&&(f=b.lngs),b.lng&&(f=T.toLanguages(b.lng,b.fallbackLng),!K[f[0]])){var g=P.getAsync;P.getAsync=!1,J.sync.load(f,P,function(a,b){T.extend(K,b),P.getAsync=g})}var h=b.ns||P.ns.defaultNs;if(a.indexOf(P.nsseparator)>-1){var i=a.split(P.nsseparator);h=i[0],a=i[1]}if(x(b)){c=T.extend({},b),delete c.context,c.defaultValue=P.contextNotFound;var j=h+P.nsseparator+a+"_"+b.context;if(d=B(j,c),d!=P.contextNotFound)return v(d,{context:b.context})}if(y(b,f[0])){c=T.extend({lngs:[f[0]]},b),delete c.count,c._origLng=c._origLng||c.lng||f[0],delete c.lng,c.defaultValue=P.pluralNotFound;var k;if(W.needsPlural(f[0],b.count)){k=h+P.nsseparator+a+P.pluralSuffix;var l=W.get(f[0],b.count);l>=0?k=k+"_"+l:1===l&&(k=h+P.nsseparator+a)}else k=h+P.nsseparator+a;if(d=B(k,c),d!=P.pluralNotFound)return v(d,{count:b.count,interpolationPrefix:b.interpolationPrefix,interpolationSuffix:b.interpolationSuffix});if(!(f.length>1))return c.lng=c._origLng,delete c._origLng,d=B(h+P.nsseparator+a,c),v(d,{count:b.count,interpolationPrefix:b.interpolationPrefix,interpolationSuffix:b.interpolationSuffix});var m=f.slice();if(m.shift(),b=T.extend(b,{lngs:m}),b._origLng=c._origLng,delete b.lng,d=B(h+P.nsseparator+a,b),d!=P.pluralNotFound)return d}if(z(b)){var n=T.extend({},b);delete n.indefinite_article,n.defaultValue=P.indefiniteNotFound;var o=h+P.nsseparator+a+(b.count&&!y(b,f[0])||!b.count?P.indefiniteSuffix:"");if(d=B(o,n),d!=P.indefiniteNotFound)return d}for(var p,q=a.split(P.keyseparator),r=0,s=f.length;s>r&&void 0===p;r++){for(var t=f[r],u=0,A=K[t]&&K[t][h];q[u];)A=A&&A[q[u]],u++;if(void 0!==A){var D=Object.prototype.toString.apply(A);if("string"==typeof A)A=v(A,b),A=w(A,b);else if("[object Array]"!==D||P.returnObjectTrees||b.returnObjectTrees){if(null===A&&P.fallbackOnNull===!0)A=void 0;else if(null!==A)if(P.returnObjectTrees||b.returnObjectTrees){if("[object Number]"!==D&&"[object Function]"!==D&&"[object RegExp]"!==D){var G="[object Array]"===D?[]:{};T.each(A,function(c){G[c]=E(h+P.nsseparator+a+P.keyseparator+c,b)}),A=G}}else P.objectTreeKeyHandler&&"function"==typeof P.objectTreeKeyHandler?A=P.objectTreeKeyHandler(a,A,t,h,b):(A="key '"+h+":"+a+" ("+t+")' returned an object instead of string.",T.log(A))}else A=A.join("\n"),A=v(A,b),A=w(A,b);"string"==typeof A&&""===A.trim()&&P.fallbackOnEmpty===!0&&(A=void 0),p=A}}if(void 0===p&&!b.isFallbackLookup&&(P.fallbackToDefaultNS===!0||P.fallbackNS&&P.fallbackNS.length>0)){if(b.isFallbackLookup=!0,P.fallbackNS.length){for(var H=0,I=P.fallbackNS.length;I>H;H++)if(p=F(P.fallbackNS[H]+P.nsseparator+a,b),p||""===p&&P.fallbackOnEmpty===!1){var L=p.indexOf(P.nsseparator)>-1?p.split(P.nsseparator)[1]:p,N=e.indexOf(P.nsseparator)>-1?e.split(P.nsseparator)[1]:e;if(L!==N)break}}else p=F(a,b);b.isFallbackLookup=!1}return p}function G(){var a,b=P.lngWhitelist||[],c=[];if("undefined"!=typeof window&&!function(){for(var a=window.location.search.substring(1),b=a.split("&"),d=0;d<b.length;d++){var e=b[d].indexOf("=");if(e>0){var f=b[d].substring(0,e);f==P.detectLngQS&&c.push(b[d].substring(e+1))}}}(),P.useCookie&&"undefined"!=typeof document){var d=T.cookie.read(P.cookieName);d&&c.push(d)}if(P.detectLngFromLocalStorage&&"undefined"!=typeof window&&window.localStorage&&c.push(T.localStorage.getItem("i18next_lng")),"undefined"!=typeof navigator){if(navigator.languages)for(var e=0;e<navigator.languages.length;e++)c.push(navigator.languages[e]);navigator.userLanguage&&c.push(navigator.userLanguage),navigator.language&&c.push(navigator.language)}return function(){for(var d=0;d<c.length;d++){var e=c[d];if(e.indexOf("-")>-1){var f=e.split("-");e=P.lowerCaseLng?f[0].toLowerCase()+"-"+f[1].toLowerCase():f[0].toLowerCase()+"-"+f[1].toUpperCase()}if(0===b.length||b.indexOf(e)>-1){a=e;break}}}(),a||(a=P.fallbackLng[0]),a}Array.prototype.indexOf||(Array.prototype.indexOf=function(a){"use strict";if(null==this)throw new TypeError;var b=Object(this),c=b.length>>>0;if(0===c)return-1;var d=0;if(arguments.length>0&&(d=Number(arguments[1]),d!=d?d=0:0!=d&&d!=1/0&&d!=-(1/0)&&(d=(d>0||-1)*Math.floor(Math.abs(d)))),d>=c)return-1;for(var e=d>=0?d:Math.max(c-Math.abs(d),0);c>e;e++)if(e in b&&b[e]===a)return e;return-1}),Array.prototype.lastIndexOf||(Array.prototype.lastIndexOf=function(a){"use strict";if(null==this)throw new TypeError;var b=Object(this),c=b.length>>>0;if(0===c)return-1;var d=c;arguments.length>1&&(d=Number(arguments[1]),d!=d?d=0:0!=d&&d!=1/0&&d!=-(1/0)&&(d=(d>0||-1)*Math.floor(Math.abs(d))));for(var e=d>=0?Math.min(d,c-1):c-Math.abs(d);e>=0;e--)if(e in b&&b[e]===a)return e;return-1}),"function"!=typeof String.prototype.trim&&(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")});var H,I=a.jQuery||a.Zepto,J={},K={},L=0,M=[],N=!1,O={};"undefined"!=typeof module&&module.exports?module.exports=J:(I&&(I.i18n=I.i18n||J),a.i18n=a.i18n||J),O={load:function(a,b,c){b.useLocalStorage?O._loadLocal(a,b,function(d,e){for(var f=[],g=0,h=a.length;h>g;g++)e[a[g]]||f.push(a[g]);f.length>0?O._fetch(f,b,function(a,b){T.extend(e,b),O._storeLocal(b),c(null,e)}):c(null,e)}):O._fetch(a,b,function(a,b){c(null,b)})},_loadLocal:function(a,b,c){var d={},e=(new Date).getTime();if(window.localStorage){var f=a.length;T.each(a,function(a,g){var h=T.localStorage.getItem("res_"+g);h&&(h=JSON.parse(h),h.i18nStamp&&h.i18nStamp+b.localStorageExpirationTime>e&&(d[g]=h)),f--,0===f&&c(null,d)})}},_storeLocal:function(a){if(window.localStorage)for(var b in a)a[b].i18nStamp=(new Date).getTime(),T.localStorage.setItem("res_"+b,JSON.stringify(a[b]))},_fetch:function(a,b,c){var d=b.ns,e={};if(b.dynamicLoad){var f=function(a,b){c(null,b)};if("function"==typeof b.customLoad)b.customLoad(a,d.namespaces,b,f);else{var g=v(b.resGetPath,{lng:a.join("+"),ns:d.namespaces.join("+")});T.ajax({url:g,success:function(a){T.log("loaded: "+g),f(null,a)},error:function(a,b,c){T.log("failed loading: "+g),f("failed loading resource.json error: "+c)},dataType:"json",async:b.getAsync})}}else{var h,i=d.namespaces.length*a.length;T.each(d.namespaces,function(d,f){T.each(a,function(a,d){var g=function(a,b){a&&(h=h||[],h.push(a)),e[d]=e[d]||{},e[d][f]=b,i--,0===i&&c(h,e)};"function"==typeof b.customLoad?b.customLoad(d,f,b,g):O._fetchOne(d,f,b,g)})})}},_fetchOne:function(a,b,c,d){var e=v(c.resGetPath,{lng:a,ns:b});T.ajax({url:e,success:function(a){T.log("loaded: "+e),d(null,a)},error:function(a,b,c){if(b&&200==b||a&&a.status&&200==a.status)T.error("There is a typo in: "+e);else if(b&&404==b||a&&a.status&&404==a.status)T.log("Does not exist: "+e);else{var f=b?b:a&&a.status?a.status:null;T.log(f+" when loading "+e)}d(c,{})},dataType:"json",async:c.getAsync})},postMissing:function(a,b,c,d,e){var f={};f[c]=d;var g=[];if("fallback"===P.sendMissingTo&&P.fallbackLng[0]!==!1)for(var h=0;h<P.fallbackLng.length;h++)g.push({lng:P.fallbackLng[h],url:v(P.resPostPath,{lng:P.fallbackLng[h],ns:b})});else if("current"===P.sendMissingTo||"fallback"===P.sendMissingTo&&P.fallbackLng[0]===!1)g.push({lng:a,url:v(P.resPostPath,{lng:a,ns:b})});else if("all"===P.sendMissingTo)for(var h=0,i=e.length;i>h;h++)g.push({lng:e[h],url:v(P.resPostPath,{lng:e[h],ns:b})});for(var j=0,k=g.length;k>j;j++){var l=g[j];T.ajax({url:l.url,type:P.sendType,data:f,success:function(){T.log("posted missing key '"+c+"' to: "+l.url);for(var a=c.split("."),e=0,f=K[l.lng][b];a[e];)f=f[a[e]]=e===a.length-1?d:f[a[e]]||{},e++},error:function(){T.log("failed posting missing key '"+c+"' to: "+l.url)},dataType:"json",async:P.postAsync})}},reload:t};var P={lng:void 0,load:"all",preload:[],lowerCaseLng:!1,returnObjectTrees:!1,fallbackLng:["dev"],fallbackNS:[],detectLngQS:"setLng",detectLngFromLocalStorage:!1,ns:"translation",fallbackOnNull:!0,fallbackOnEmpty:!1,fallbackToDefaultNS:!1,nsseparator:":",keyseparator:".",selectorAttr:"data-i18n",debug:!1,resGetPath:"locales/__lng__/__ns__.json",resPostPath:"locales/add/__lng__/__ns__",getAsync:!0,postAsync:!0,resStore:void 0,useLocalStorage:!1,localStorageExpirationTime:6048e5,dynamicLoad:!1,sendMissing:!1,sendMissingTo:"fallback",sendType:"POST",interpolationPrefix:"__",interpolationSuffix:"__",defaultVariables:!1,reusePrefix:"$t(",reuseSuffix:")",pluralSuffix:"_plural",pluralNotFound:["plural_not_found",Math.random()].join(""),contextNotFound:["context_not_found",Math.random()].join(""),escapeInterpolation:!1,indefiniteSuffix:"_indefinite",indefiniteNotFound:["indefinite_not_found",Math.random()].join(""),setJqueryExt:!0,defaultValueFromContent:!0,useDataAttrOptions:!1,cookieExpirationTime:void 0,useCookie:!0,cookieName:"i18next",cookieDomain:void 0,objectTreeKeyHandler:void 0,postProcess:void 0,parseMissingKey:void 0,missingKeyHandler:O.postMissing,shortcutFunction:"sprintf"},Q={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#x2F;"},R={create:function(a,b,c,d){var e;if(c){var f=new Date;f.setTime(f.getTime()+60*c*1e3),e="; expires="+f.toGMTString()}else e="";d=d?"domain="+d+";":"",document.cookie=a+"="+b+e+";"+d+"path=/"},read:function(a){for(var b=a+"=",c=document.cookie.split(";"),d=0;d<c.length;d++){for(var e=c[d];" "==e.charAt(0);)e=e.substring(1,e.length);if(0===e.indexOf(b))return e.substring(b.length,e.length)}return null},remove:function(a){this.create(a,"",-1)}},S={create:function(){},read:function(){return null},remove:function(){}},T={extend:I?I.extend:b,deepExtend:c,each:I?I.each:d,ajax:I?I.ajax:"undefined"!=typeof document?f:function(){},cookie:"undefined"!=typeof document?R:S,detectLanguage:G,escape:e,log:function(a){P.debug&&"undefined"!=typeof console&&console.log(a)},error:function(a){"undefined"!=typeof console&&console.error(a)},getCountyIndexOfLng:function(a){var b=0;return("nb-NO"===a||"nn-NO"===a||"nb-no"===a||"nn-no"===a)&&(b=1),b},toLanguages:function(a){function b(a){var b=a;if("string"==typeof a&&a.indexOf("-")>-1){var c=a.split("-");b=P.lowerCaseLng?c[0].toLowerCase()+"-"+c[1].toLowerCase():c[0].toLowerCase()+"-"+c[1].toUpperCase()}else b=P.lowerCaseLng?a.toLowerCase():a;return b}var c=this.log,d=[],e=P.lngWhitelist||!1,f=function(a){!e||e.indexOf(a)>-1?d.push(a):c("rejecting non-whitelisted language: "+a)};if("string"==typeof a&&a.indexOf("-")>-1){var g=a.split("-");"unspecific"!==P.load&&f(b(a)),"current"!==P.load&&f(b(g[this.getCountyIndexOfLng(a)]))}else f(b(a));for(var h=0;h<P.fallbackLng.length;h++)-1===d.indexOf(P.fallbackLng[h])&&P.fallbackLng[h]&&d.push(b(P.fallbackLng[h]));return d},regexEscape:function(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},regexReplacementEscape:function(a){return"string"==typeof a?a.replace(/\$/g,"$$$$"):a},localStorage:{setItem:function(a,b){if(window.localStorage)try{window.localStorage.setItem(a,b)}catch(c){T.log('failed to set value for key "'+a+'" to localStorage.')}},getItem:function(a,b){if(window.localStorage)try{return window.localStorage.getItem(a,b)}catch(c){return void T.log('failed to get value for key "'+a+'" from localStorage.')}}}};T.applyReplacement=v;var U=[["ach","Acholi",[1,2],1],["af","Afrikaans",[1,2],2],["ak","Akan",[1,2],1],["am","Amharic",[1,2],1],["an","Aragonese",[1,2],2],["ar","Arabic",[0,1,2,3,11,100],5],["arn","Mapudungun",[1,2],1],["ast","Asturian",[1,2],2],["ay","Aymará",[1],3],["az","Azerbaijani",[1,2],2],["be","Belarusian",[1,2,5],4],["bg","Bulgarian",[1,2],2],["bn","Bengali",[1,2],2],["bo","Tibetan",[1],3],["br","Breton",[1,2],1],["bs","Bosnian",[1,2,5],4],["ca","Catalan",[1,2],2],["cgg","Chiga",[1],3],["cs","Czech",[1,2,5],6],["csb","Kashubian",[1,2,5],7],["cy","Welsh",[1,2,3,8],8],["da","Danish",[1,2],2],["de","German",[1,2],2],["dev","Development Fallback",[1,2],2],["dz","Dzongkha",[1],3],["el","Greek",[1,2],2],["en","English",[1,2],2],["eo","Esperanto",[1,2],2],["es","Spanish",[1,2],2],["es_ar","Argentinean Spanish",[1,2],2],["et","Estonian",[1,2],2],["eu","Basque",[1,2],2],["fa","Persian",[1],3],["fi","Finnish",[1,2],2],["fil","Filipino",[1,2],1],["fo","Faroese",[1,2],2],["fr","French",[1,2],9],["fur","Friulian",[1,2],2],["fy","Frisian",[1,2],2],["ga","Irish",[1,2,3,7,11],10],["gd","Scottish Gaelic",[1,2,3,20],11],["gl","Galician",[1,2],2],["gu","Gujarati",[1,2],2],["gun","Gun",[1,2],1],["ha","Hausa",[1,2],2],["he","Hebrew",[1,2],2],["hi","Hindi",[1,2],2],["hr","Croatian",[1,2,5],4],["hu","Hungarian",[1,2],2],["hy","Armenian",[1,2],2],["ia","Interlingua",[1,2],2],["id","Indonesian",[1],3],["is","Icelandic",[1,2],12],["it","Italian",[1,2],2],["ja","Japanese",[1],3],["jbo","Lojban",[1],3],["jv","Javanese",[0,1],13],["ka","Georgian",[1],3],["kk","Kazakh",[1],3],["km","Khmer",[1],3],["kn","Kannada",[1,2],2],["ko","Korean",[1],3],["ku","Kurdish",[1,2],2],["kw","Cornish",[1,2,3,4],14],["ky","Kyrgyz",[1],3],["lb","Letzeburgesch",[1,2],2],["ln","Lingala",[1,2],1],["lo","Lao",[1],3],["lt","Lithuanian",[1,2,10],15],["lv","Latvian",[1,2,0],16],["mai","Maithili",[1,2],2],["mfe","Mauritian Creole",[1,2],1],["mg","Malagasy",[1,2],1],["mi","Maori",[1,2],1],["mk","Macedonian",[1,2],17],["ml","Malayalam",[1,2],2],["mn","Mongolian",[1,2],2],["mnk","Mandinka",[0,1,2],18],["mr","Marathi",[1,2],2],["ms","Malay",[1],3],["mt","Maltese",[1,2,11,20],19],["nah","Nahuatl",[1,2],2],["nap","Neapolitan",[1,2],2],["nb","Norwegian Bokmal",[1,2],2],["ne","Nepali",[1,2],2],["nl","Dutch",[1,2],2],["nn","Norwegian Nynorsk",[1,2],2],["no","Norwegian",[1,2],2],["nso","Northern Sotho",[1,2],2],["oc","Occitan",[1,2],1],["or","Oriya",[2,1],2],["pa","Punjabi",[1,2],2],["pap","Papiamento",[1,2],2],["pl","Polish",[1,2,5],7],["pms","Piemontese",[1,2],2],["ps","Pashto",[1,2],2],["pt","Portuguese",[1,2],2],["pt_br","Brazilian Portuguese",[1,2],2],["rm","Romansh",[1,2],2],["ro","Romanian",[1,2,20],20],["ru","Russian",[1,2,5],4],["sah","Yakut",[1],3],["sco","Scots",[1,2],2],["se","Northern Sami",[1,2],2],["si","Sinhala",[1,2],2],["sk","Slovak",[1,2,5],6],["sl","Slovenian",[5,1,2,3],21],["so","Somali",[1,2],2],["son","Songhay",[1,2],2],["sq","Albanian",[1,2],2],["sr","Serbian",[1,2,5],4],["su","Sundanese",[1],3],["sv","Swedish",[1,2],2],["sw","Swahili",[1,2],2],["ta","Tamil",[1,2],2],["te","Telugu",[1,2],2],["tg","Tajik",[1,2],1],["th","Thai",[1],3],["ti","Tigrinya",[1,2],1],["tk","Turkmen",[1,2],2],["tr","Turkish",[1,2],1],["tt","Tatar",[1],3],["ug","Uyghur",[1],3],["uk","Ukrainian",[1,2,5],4],["ur","Urdu",[1,2],2],["uz","Uzbek",[1,2],1],["vi","Vietnamese",[1],3],["wa","Walloon",[1,2],1],["wo","Wolof",[1],3],["yo","Yoruba",[1,2],2],["zh","Chinese",[1],3]],V={1:function(a){return Number(a>1)},2:function(a){return Number(1!=a)},3:function(){return 0},4:function(a){return Number(a%10==1&&a%100!=11?0:a%10>=2&&4>=a%10&&(10>a%100||a%100>=20)?1:2)},5:function(a){return Number(0===a?0:1==a?1:2==a?2:a%100>=3&&10>=a%100?3:a%100>=11?4:5)},6:function(a){return Number(1==a?0:a>=2&&4>=a?1:2)},7:function(a){return Number(1==a?0:a%10>=2&&4>=a%10&&(10>a%100||a%100>=20)?1:2)},8:function(a){return Number(1==a?0:2==a?1:8!=a&&11!=a?2:3)},9:function(a){return Number(a>=2)},10:function(a){return Number(1==a?0:2==a?1:7>a?2:11>a?3:4)},11:function(a){return Number(1==a||11==a?0:2==a||12==a?1:a>2&&20>a?2:3)},12:function(a){return Number(a%10!=1||a%100==11)},13:function(a){return Number(0!==a)},14:function(a){return Number(1==a?0:2==a?1:3==a?2:3)},15:function(a){return Number(a%10==1&&a%100!=11?0:a%10>=2&&(10>a%100||a%100>=20)?1:2)},16:function(a){return Number(a%10==1&&a%100!=11?0:0!==a?1:2)},17:function(a){return Number(1==a||a%10==1?0:1)},18:function(a){return Number(1==a?1:2)},19:function(a){return Number(1==a?0:0===a||a%100>1&&11>a%100?1:a%100>10&&20>a%100?2:3)},20:function(a){return Number(1==a?0:0===a||a%100>0&&20>a%100?1:2)},21:function(a){return Number(a%100==1?1:a%100==2?2:a%100==3||a%100==4?3:0)}},W={rules:function(){var a,b={};for(a=U.length;a--;)b[U[a][0]]={name:U[a][1],numbers:U[a][2],plurals:V[U[a][3]]};return b}(),addRule:function(a,b){W.rules[a]=b},setCurrentLng:function(a){if(!W.currentRule||W.currentRule.lng!==a){var b=a.split("-");W.currentRule={lng:a,rule:W.rules[b[0]]}}},needsPlural:function(a,b){var c,d=a.split("-");return c=W.currentRule&&W.currentRule.lng===a?W.currentRule.rule:W.rules[d[T.getCountyIndexOfLng(a)]],c&&c.numbers.length<=1?!1:1!==this.get(a,b)},get:function(a,b){function c(b,c){var d;if(d=W.currentRule&&W.currentRule.lng===a?W.currentRule.rule:W.rules[b]){var e;e=d.plurals(d.noAbs?c:Math.abs(c));var f=d.numbers[e];return 2===d.numbers.length&&1===d.numbers[0]&&(2===f?f=-1:1===f&&(f=1)),f}return 1===c?"1":"-1"}var d=a.split("-");return c(d[T.getCountyIndexOfLng(a)],b)}},X={},Y=function(a,b){X[a]=b},Z=function(){function a(a){return Object.prototype.toString.call(a).slice(8,-1).toLowerCase()}function b(a,b){for(var c=[];b>0;c[--b]=a);return c.join("")}var c=function(){return c.cache.hasOwnProperty(arguments[0])||(c.cache[arguments[0]]=c.parse(arguments[0])),c.format.call(null,c.cache[arguments[0]],arguments)};return c.format=function(c,d){var e,f,g,h,i,j,k,l=1,m=c.length,n="",o=[];for(f=0;m>f;f++)if(n=a(c[f]),"string"===n)o.push(c[f]);else if("array"===n){if(h=c[f],h[2])for(e=d[l],g=0;g<h[2].length;g++){if(!e.hasOwnProperty(h[2][g]))throw Z('[sprintf] property "%s" does not exist',h[2][g]);e=e[h[2][g]]}else e=h[1]?d[h[1]]:d[l++];if(/[^s]/.test(h[8])&&"number"!=a(e))throw Z("[sprintf] expecting number but found %s",a(e));switch(h[8]){case"b":e=e.toString(2);break;case"c":e=String.fromCharCode(e);break;case"d":e=parseInt(e,10);break;case"e":e=h[7]?e.toExponential(h[7]):e.toExponential();break;case"f":e=h[7]?parseFloat(e).toFixed(h[7]):parseFloat(e);break;case"o":e=e.toString(8);break;case"s":e=(e=String(e))&&h[7]?e.substring(0,h[7]):e;break;case"u":e=Math.abs(e);break;case"x":e=e.toString(16);break;case"X":e=e.toString(16).toUpperCase()}e=/[def]/.test(h[8])&&h[3]&&e>=0?"+"+e:e,j=h[4]?"0"==h[4]?"0":h[4].charAt(1):" ",k=h[6]-String(e).length,i=h[6]?b(j,k):"",o.push(h[5]?e+i:i+e)}return o.join("")},c.cache={},c.parse=function(a){for(var b=a,c=[],d=[],e=0;b;){if(null!==(c=/^[^\x25]+/.exec(b)))d.push(c[0]);else if(null!==(c=/^\x25{2}/.exec(b)))d.push("%");else{if(null===(c=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(b)))throw"[sprintf] huh?";if(c[2]){e|=1;var f=[],g=c[2],h=[];if(null===(h=/^([a-z_][a-z_\d]*)/i.exec(g)))throw"[sprintf] huh?";for(f.push(h[1]);""!==(g=g.substring(h[0].length));)if(null!==(h=/^\.([a-z_][a-z_\d]*)/i.exec(g)))f.push(h[1]);else{if(null===(h=/^\[(\d+)\]/.exec(g)))throw"[sprintf] huh?";f.push(h[1])}c[2]=f}else e|=2;if(3===e)throw"[sprintf] mixing positional and named placeholders is not (yet) supported";d.push(c)}b=b.substring(c[0].length)}return d},c}(),$=function(a,b){return b.unshift(a),Z.apply(null,b)};Y("sprintf",function(a,b,c){return c.sprintf?"[object Array]"===Object.prototype.toString.apply(c.sprintf)?$(a,c.sprintf):"object"==typeof c.sprintf?Z(a,c.sprintf):a:a}),J.init=g,J.setLng=r,J.preload=h,J.addResourceBundle=i,J.hasResourceBundle=j,J.getResourceBundle=k,J.addResource=m,J.addResources=n,J.removeResourceBundle=l,J.loadNamespace=p,J.loadNamespaces=q,J.setDefaultNamespace=o,J.t=B,J.translate=B,J.exists=A,J.detectLanguage=T.detectLanguage,J.pluralExtensions=W,J.sync=O,J.functions=T,J.lng=s,J.addPostProcessor=Y,J.applyReplacement=T.applyReplacement,J.options=P}("undefined"==typeof exports?window:exports); \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_444444_256x240.png b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_444444_256x240.png new file mode 100644 index 0000000..c2daae1 Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_444444_256x240.png differ diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_555555_256x240.png b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_555555_256x240.png new file mode 100644 index 0000000..4784928 Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_555555_256x240.png differ diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_777620_256x240.png b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_777620_256x240.png new file mode 100644 index 0000000..d2f58d2 Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_777620_256x240.png differ diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_777777_256x240.png b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_777777_256x240.png new file mode 100644 index 0000000..1d53258 Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_777777_256x240.png differ diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_cc0000_256x240.png b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_cc0000_256x240.png new file mode 100644 index 0000000..2825f20 Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_cc0000_256x240.png differ diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_ffffff_256x240.png b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_ffffff_256x240.png new file mode 100644 index 0000000..136a4f9 Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/images/ui-icons_ffffff_256x240.png differ diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/jquery-ui.min.css b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/jquery-ui.min.css new file mode 100644 index 0000000..776e259 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/css/base/jquery-ui.min.css @@ -0,0 +1,7 @@ +/*! jQuery UI - v1.12.1 - 2016-09-14 +* http://jqueryui.com +* Includes: core.css, accordion.css, autocomplete.css, menu.css, button.css, controlgroup.css, checkboxradio.css, datepicker.css, dialog.css, draggable.css, resizable.css, progressbar.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?bgShadowXPos=&bgOverlayXPos=&bgErrorXPos=&bgHighlightXPos=&bgContentXPos=&bgHeaderXPos=&bgActiveXPos=&bgHoverXPos=&bgDefaultXPos=&bgShadowYPos=&bgOverlayYPos=&bgErrorYPos=&bgHighlightYPos=&bgContentYPos=&bgHeaderYPos=&bgActiveYPos=&bgHoverYPos=&bgDefaultYPos=&bgShadowRepeat=&bgOverlayRepeat=&bgErrorRepeat=&bgHighlightRepeat=&bgContentRepeat=&bgHeaderRepeat=&bgActiveRepeat=&bgHoverRepeat=&bgDefaultRepeat=&iconsHover=url(%22images%2Fui-icons_555555_256x240.png%22)&iconsHighlight=url(%22images%2Fui-icons_777620_256x240.png%22)&iconsHeader=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsError=url(%22images%2Fui-icons_cc0000_256x240.png%22)&iconsDefault=url(%22images%2Fui-icons_777777_256x240.png%22)&iconsContent=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsActive=url(%22images%2Fui-icons_ffffff_256x240.png%22)&bgImgUrlShadow=&bgImgUrlOverlay=&bgImgUrlHover=&bgImgUrlHighlight=&bgImgUrlHeader=&bgImgUrlError=&bgImgUrlDefault=&bgImgUrlContent=&bgImgUrlActive=&opacityFilterShadow=Alpha(Opacity%3D30)&opacityFilterOverlay=Alpha(Opacity%3D30)&opacityShadowPerc=30&opacityOverlayPerc=30&iconColorHover=%23555555&iconColorHighlight=%23777620&iconColorHeader=%23444444&iconColorError=%23cc0000&iconColorDefault=%23777777&iconColorContent=%23444444&iconColorActive=%23ffffff&bgImgOpacityShadow=0&bgImgOpacityOverlay=0&bgImgOpacityError=95&bgImgOpacityHighlight=55&bgImgOpacityContent=75&bgImgOpacityHeader=75&bgImgOpacityActive=65&bgImgOpacityHover=75&bgImgOpacityDefault=75&bgTextureShadow=flat&bgTextureOverlay=flat&bgTextureError=flat&bgTextureHighlight=flat&bgTextureContent=flat&bgTextureHeader=flat&bgTextureActive=flat&bgTextureHover=flat&bgTextureDefault=flat&cornerRadius=3px&fwDefault=normal&ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&cornerRadiusShadow=8px&thicknessShadow=5px&offsetLeftShadow=0px&offsetTopShadow=0px&opacityShadow=.3&bgColorShadow=%23666666&opacityOverlay=.3&bgColorOverlay=%23aaaaaa&fcError=%235f3f3f&borderColorError=%23f1a899&bgColorError=%23fddfdf&fcHighlight=%23777620&borderColorHighlight=%23dad55e&bgColorHighlight=%23fffa90&fcContent=%23333333&borderColorContent=%23dddddd&bgColorContent=%23ffffff&fcHeader=%23333333&borderColorHeader=%23dddddd&bgColorHeader=%23e9e9e9&fcActive=%23ffffff&borderColorActive=%23003eff&bgColorActive=%23007fff&fcHover=%232b2b2b&borderColorHover=%23cccccc&bgColorHover=%23ededed&fcDefault=%23454545&borderColorDefault=%23c5c5c5&bgColorDefault=%23f6f6f6 +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;font-size:100%}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{margin:0;cursor:pointer;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-item-wrapper{position:relative;padding:3px 1em 3px .4em}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item-wrapper{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-button{padding:.4em 1em;display:inline-block;position:relative;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2em;box-sizing:border-box;text-indent:-9999px;white-space:nowrap}input.ui-button.ui-button-icon-only{text-indent:0}.ui-button-icon-only .ui-icon{position:absolute;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.ui-button.ui-icon-notext .ui-icon{padding:0;width:2.1em;height:2.1em;text-indent:-9999px;white-space:nowrap}input.ui-button.ui-icon-notext .ui-icon{width:auto;height:auto;text-indent:0;white-space:normal;padding:.4em 1em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-controlgroup{vertical-align:middle;display:inline-block}.ui-controlgroup > .ui-controlgroup-item{float:left;margin-left:0;margin-right:0}.ui-controlgroup > .ui-controlgroup-item:focus,.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus{z-index:9999}.ui-controlgroup-vertical > .ui-controlgroup-item{display:block;float:none;width:100%;margin-top:0;margin-bottom:0;text-align:left}.ui-controlgroup-vertical .ui-controlgroup-item{box-sizing:border-box}.ui-controlgroup .ui-controlgroup-label{padding:.4em 1em}.ui-controlgroup .ui-controlgroup-label span{font-size:80%}.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item{border-left:none}.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item{border-top:none}.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content{border-right:none}.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content{border-bottom:none}.ui-controlgroup-vertical .ui-spinner-input{width:75%;width:calc( 100% - 2.4em )}.ui-controlgroup-vertical .ui-spinner .ui-spinner-up{border-top-style:solid}.ui-checkboxradio-label .ui-icon-background{box-shadow:inset 1px 1px 1px #ccc;border-radius:.12em;border:none}.ui-checkboxradio-radio-label .ui-icon-background{width:16px;height:16px;border-radius:1em;overflow:visible;border:none}.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon{background-image:none;width:8px;height:8px;border-width:4px;border-style:solid}.ui-checkboxradio-disabled{pointer-events:none}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker .ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;left:.5em;top:.3em}.ui-dialog{position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-n{height:2px;top:0}.ui-dialog .ui-resizable-e{width:2px;right:0}.ui-dialog .ui-resizable-s{height:2px;bottom:0}.ui-dialog .ui-resizable-w{width:2px;left:0}.ui-dialog .ui-resizable-se,.ui-dialog .ui-resizable-sw,.ui-dialog .ui-resizable-ne,.ui-dialog .ui-resizable-nw{width:7px;height:7px}.ui-dialog .ui-resizable-se{right:0;bottom:0}.ui-dialog .ui-resizable-sw{left:0;bottom:0}.ui-dialog .ui-resizable-ne{right:0;top:0}.ui-dialog .ui-resizable-nw{left:0;top:0}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px 0.4em;margin:0.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-text{display:block;margin-right:20px;overflow:hidden;text-overflow:ellipsis}.ui-selectmenu-button.ui-button{text-align:left;white-space:nowrap;width:14em}.ui-selectmenu-icon.ui-icon{float:right;margin-top:0}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:.222em 0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:2em}.ui-spinner-button{width:1.6em;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top-style:none;border-bottom-style:none;border-right-style:none}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget.ui-widget-content{border:1px solid #c5c5c5}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #ddd;background:#e9e9e9;color:#333;font-weight:bold}.ui-widget-header a{color:#333}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default,.ui-button,html .ui-button.ui-state-disabled:hover,html .ui-button.ui-state-disabled:active{border:1px solid #c5c5c5;background:#f6f6f6;font-weight:normal;color:#454545}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited,a.ui-button,a:link.ui-button,a:visited.ui-button,.ui-button{color:#454545;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus,.ui-button:hover,.ui-button:focus{border:1px solid #ccc;background:#ededed;font-weight:normal;color:#2b2b2b}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited,a.ui-button:hover,a.ui-button:focus{color:#2b2b2b;text-decoration:none}.ui-visual-focus{box-shadow:0 0 3px 1px rgb(94,158,214)}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active,a.ui-button:active,.ui-button:active,.ui-button.ui-state-active:hover{border:1px solid #003eff;background:#007fff;font-weight:normal;color:#fff}.ui-icon-background,.ui-state-active .ui-icon-background{border:#003eff;background-color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #dad55e;background:#fffa90;color:#777620}.ui-state-checked{border:1px solid #dad55e;background:#fffa90}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#777620}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon,.ui-button:hover .ui-icon,.ui-button:focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon,.ui-button:active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon,.ui-button .ui-state-highlight.ui-icon{background-image:url("images/ui-icons_777620_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-button .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-caret-1-n{background-position:0 0}.ui-icon-caret-1-ne{background-position:-16px 0}.ui-icon-caret-1-e{background-position:-32px 0}.ui-icon-caret-1-se{background-position:-48px 0}.ui-icon-caret-1-s{background-position:-65px 0}.ui-icon-caret-1-sw{background-position:-80px 0}.ui-icon-caret-1-w{background-position:-96px 0}.ui-icon-caret-1-nw{background-position:-112px 0}.ui-icon-caret-2-n-s{background-position:-128px 0}.ui-icon-caret-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-65px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-65px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:1px -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.003;filter:Alpha(Opacity=.3)}.ui-widget-shadow{-webkit-box-shadow:0 0 5px #666;box-shadow:0 0 5px #666} \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-3.4.1.min.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-3.4.1.min.js new file mode 100644 index 0000000..a1c07fd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-3.4.1.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.4.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=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,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},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.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(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)}k.fn=k.prototype={jquery:f,constructor:k,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=k.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return k.each(this,e)},map:function(n){return this.pushStack(k.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)},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},k.extend=k.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&&(k.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||k.isPlainObject(n)?n:{},i=!1,a[t]=k.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},k.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){b(e,{nonce:t&&t.nonce})},each:function(e,t){var n,r=0;if(d(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},trim:function(e){return null==e?"":(e+"").replace(p,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(d(Object(e))?k.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(d(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.apply([],a)},guid:1,support:y}),"function"==typeof Symbol&&(k.fn[Symbol.iterator]=t[Symbol.iterator]),k.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var h=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,k="sizzle"+1*new Date,m=n.document,S=0,r=0,p=ue(),x=ue(),N=ue(),A=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="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",$=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",F=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),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-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|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(m.childNodes),m.childNodes),t[m.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&&((e?e.ownerDocument||e:m)!==C&&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&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$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[k]=!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:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),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=k,!C.getElementsByName||!C.getElementsByName(k).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){a.appendChild(e).innerHTML="<a id='"+k+"'></a><select id='"+k+"-\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~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),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("!=",$)}),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===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,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]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[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){A(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=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(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(F," ")+" ").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)[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===S&&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]=[S,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===S&&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[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[S,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[k]?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(B,"$1"));return s[k]?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=[S,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[k]||(e[k]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===S&&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[k]&&(v=Ce(v)),y&&!y[k]&&(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))[k]){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(B,"$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(B," ")}),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=N[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[k]?i.push(a):o.push(a);(a=N(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=S+=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&&(S=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&&(S=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=k.split("").sort(D).join("")===k,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);k.find=h,k.expr=h.selectors,k.expr[":"]=k.expr.pseudos,k.uniqueSort=k.unique=h.uniqueSort,k.text=h.getText,k.isXMLDoc=h.isXML,k.contains=h.contains,k.escapeSelector=h.escape;var T=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&k(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},N=k.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var D=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1<i.call(n,e)!==r}):k.filter(n,e,r)}k.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?k.find.matchesSelector(r,e)?[r]:[]:k.find.matches(e,k.grep(t,function(e){return 1===e.nodeType}))},k.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(k(e).filter(function(){for(t=0;t<r;t++)if(k.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)k.find(e,i[t],n);return 1<r?k.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&N.test(e)?k(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.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 k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.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(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(k.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&k(e);if(!N.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&&k.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?k.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(k(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(k.uniqueSort(k.merge(this.get(),k(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),k.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return T(e,"parentNode")},parentsUntil:function(e,t,n){return T(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return T(e,"nextSibling")},prevAll:function(e){return T(e,"previousSibling")},nextUntil:function(e,t,n){return T(e,"nextSibling",n)},prevUntil:function(e,t,n){return T(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return"undefined"!=typeof e.contentDocument?e.contentDocument:(A(e,"template")&&(e=e.content||e),k.merge([],e.childNodes))}},function(r,i){k.fn[r]=function(e,t){var n=k.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=k.filter(t,n)),1<this.length&&(O[r]||k.uniqueSort(n),H.test(r)&&n.reverse()),this.pushStack(n)}});var R=/[^\x20\t\r\n\f]+/g;function M(e){return e}function I(e){throw e}function W(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])}}k.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},k.each(e.match(R)||[],function(e,t){n[t]=!0}),n):k.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){k.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 k.each(arguments,function(e,t){var n;while(-1<(n=k.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<k.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},k.extend({Deferred:function(e){var o=[["notify","progress",k.Callbacks("memory"),k.Callbacks("memory"),2],["resolve","done",k.Callbacks("once memory"),k.Callbacks("once memory"),0,"resolved"],["reject","fail",k.Callbacks("once memory"),k.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 k.Deferred(function(r){k.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,M,s),l(u,o,I,s)):(u++,t.call(e,l(u,o,M,s),l(u,o,I,s),l(u,o,M,o.notifyWith))):(a!==M&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){k.Deferred.exceptionHook&&k.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==I&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(k.Deferred.getStackHook&&(t.stackTrace=k.Deferred.getStackHook()),C.setTimeout(t))}}return k.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:M,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:M)),o[2][3].add(l(0,e,m(n)?n:I))}).promise()},promise:function(e){return null!=e?k.extend(e,a):a}},s={};return k.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=k.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&&(W(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)W(i[t],a(t),o.reject);return o.promise()}});var $=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;k.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&$.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},k.readyException=function(e){C.setTimeout(function(){throw e})};var F=k.Deferred();function B(){E.removeEventListener("DOMContentLoaded",B),C.removeEventListener("load",B),k.ready()}k.fn.ready=function(e){return F.then(e)["catch"](function(e){k.readyException(e)}),this},k.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--k.readyWait:k.isReady)||(k.isReady=!0)!==e&&0<--k.readyWait||F.resolveWith(E,[k])}}),k.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(k.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(k(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},z=/^-ms-/,U=/-([a-z])/g;function X(e,t){return t.toUpperCase()}function V(e){return e.replace(z,"ms-").replace(U,X)}var G=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function Y(){this.expando=k.expando+Y.uid++}Y.uid=1,Y.prototype={cache:function(e){var t=e[this.expando];return t||(t={},G(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[V(t)]=n;else for(r in t)i[V(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][V(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(V):(t=V(t))in r?[t]:t.match(R)||[]).length;while(n--)delete r[t[n]]}(void 0===t||k.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&&!k.isEmptyObject(t)}};var Q=new Y,J=new Y,K=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function ee(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(Z,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:K.test(i)?JSON.parse(i):i)}catch(e){}J.set(e,t,n)}else n=void 0;return n}k.extend({hasData:function(e){return J.hasData(e)||Q.hasData(e)},data:function(e,t,n){return J.access(e,t,n)},removeData:function(e,t){J.remove(e,t)},_data:function(e,t,n){return Q.access(e,t,n)},_removeData:function(e,t){Q.remove(e,t)}}),k.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=J.get(o),1===o.nodeType&&!Q.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=V(r.slice(5)),ee(o,r,i[r]));Q.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){J.set(this,n)}):_(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=J.get(o,n))?t:void 0!==(t=ee(o,n))?t:void 0;this.each(function(){J.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){J.remove(this,e)})}}),k.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Q.get(e,t),n&&(!r||Array.isArray(n)?r=Q.access(e,t,k.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=k.queue(e,t),r=n.length,i=n.shift(),o=k._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){k.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Q.get(e,n)||Q.access(e,n,{empty:k.Callbacks("once memory").add(function(){Q.remove(e,[t+"queue",n])})})}}),k.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?k.queue(this[0],t):void 0===n?this:this.each(function(){var e=k.queue(this,t,n);k._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&k.dequeue(this,t)})},dequeue:function(e){return this.each(function(){k.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=k.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=Q.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var te=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ne=new RegExp("^(?:([+-])=|)("+te+")([a-z%]*)$","i"),re=["Top","Right","Bottom","Left"],ie=E.documentElement,oe=function(e){return k.contains(e.ownerDocument,e)},ae={composed:!0};ie.getRootNode&&(oe=function(e){return k.contains(e.ownerDocument,e)||e.getRootNode(ae)===e.ownerDocument});var se=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&oe(e)&&"none"===k.css(e,"display")},ue=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];for(o in i=n.apply(e,r||[]),t)e.style[o]=a[o];return i};function le(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return k.css(e,t,"")},u=s(),l=n&&n[3]||(k.cssNumber[t]?"":"px"),c=e.nodeType&&(k.cssNumber[t]||"px"!==l&&+u)&&ne.exec(k.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)k.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,k.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 ce={};function fe(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]=Q.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&se(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ce[s])||(o=a.body.appendChild(a.createElement(s)),u=k.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ce[s]=u)))):"none"!==n&&(l[c]="none",Q.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}k.fn.extend({show:function(){return fe(this,!0)},hide:function(){return fe(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){se(this)?k(this).show():k(this).hide()})}});var pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,"<select multiple='multiple'>","</select>"],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)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Q.set(e[n],"globalEval",!t||Q.get(t[n],"globalEval"))}ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;var me,xe,be=/<|&#?\w+;/;function we(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))k.merge(p,o.nodeType?[o]:o);else if(be.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+k.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;k.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<k.inArray(o,r))i&&i.push(o);else if(l=oe(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}me=E.createDocumentFragment().appendChild(E.createElement("div")),(xe=E.createElement("input")).setAttribute("type","radio"),xe.setAttribute("checked","checked"),xe.setAttribute("name","t"),me.appendChild(xe),y.checkClone=me.cloneNode(!0).cloneNode(!0).lastChild.checked,me.innerHTML="<textarea>x</textarea>",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(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)Ae(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=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.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),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.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)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t<arguments.length;t++)u[t]=arguments[t];if(s.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,s)){a=k.event.handlers.call(this,s,l),t=0;while((i=a[t++])&&!s.isPropagationStopped()){s.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!s.isImmediatePropagationStopped())s.rnamespace&&!1!==o.namespace&&!s.rnamespace.test(o.namespace)||(s.handleObj=o,s.data=o.data,void 0!==(r=((k.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,u))&&!1===(s.result=r)&&(s.preventDefault(),s.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,s),s.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<k(i,this).index(l):k.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(k.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[k.expando]?e:new k.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&De(t,"click",ke),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&De(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Q.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},k.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},k.Event=function(e,t){if(!(this instanceof k.Event))return new k.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?ke:Se,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&&k.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[k.expando]=!0},k.Event.prototype={constructor:k.Event,isDefaultPrevented:Se,isPropagationStopped:Se,isImmediatePropagationStopped:Se,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=ke,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=ke,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=ke,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},k.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&&Te.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&Ce.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},k.event.addProp),k.each({focus:"focusin",blur:"focusout"},function(e,t){k.event.special[e]={setup:function(){return De(this,e,Ne),!1},trigger:function(){return De(this,e),!0},delegateType:t}}),k.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){k.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||k.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),k.fn.extend({on:function(e,t,n,r){return Ae(this,e,t,n,r)},one:function(e,t,n,r){return Ae(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,k(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=Se),this.each(function(){k.event.remove(this,e,n,t)})}});var je=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/<script|<style|<link/i,Le=/checked\s*(?:[^=]|=\s*.checked.)/i,He=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n<r;n++)k.event.add(t,i,l[i][n]);J.hasData(e)&&(s=J.access(e),u=k.extend({},s),J.set(t,u))}}function Ie(n,r,i,o){r=g.apply([],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&&Le.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),Ie(t,r,i,o)});if(f&&(t=(e=we(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=k.map(ve(e,"script"),Pe)).length;c<f;c++)u=e,c!==p&&(u=k.clone(u,!0,!0),s&&k.merge(a,ve(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,k.map(a,Re),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Q.access(u,"globalEval")&&k.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?k._evalUrl&&!u.noModule&&k._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")}):b(u.textContent.replace(He,""),u,l))}return n}function We(e,t,n){for(var r,i=t?k.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||k.cleanData(ve(r)),r.parentNode&&(n&&oe(r)&&ye(ve(r,"script")),r.parentNode.removeChild(r));return e}k.extend({htmlPrefilter:function(e){return e.replace(je,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.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++)Me(o[r],a[r]);else Me(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=k.event.special,o=0;void 0!==(n=e[o]);o++)if(G(n)){if(t=n[Q.expando]){if(t.events)for(r in t.events)i[r]?k.event.remove(n,r):k.removeEvent(n,r,t.handle);n[Q.expando]=void 0}n[J.expando]&&(n[J.expando]=void 0)}}}),k.fn.extend({detach:function(e){return We(this,e,!0)},remove:function(e){return We(this,e)},text:function(e){return _(this,function(e){return void 0===e?k.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 Ie(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Oe(this,e).appendChild(e)})},prepend:function(){return Ie(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Oe(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Ie(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Ie(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&&(k.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 k.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&&!qe.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=k.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(k.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 Ie(this,arguments,function(e){var t=this.parentNode;k.inArray(this,n)<0&&(k.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),k.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){k.fn[e]=function(e){for(var t,n=[],r=k(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),k(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var $e=new RegExp("^("+te+")(?!px)[a-z%]+$","i"),Fe=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},Be=new RegExp(re.join("|"),"i");function _e(e,t,n){var r,i,o,a,s=e.style;return(n=n||Fe(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||oe(e)||(a=k.style(e,t)),!y.pixelBoxStyles()&&$e.test(a)&&Be.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 ze(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(u){s.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",u.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",ie.appendChild(s).appendChild(u);var e=C.getComputedStyle(u);n="1%"!==e.top,a=12===t(e.marginLeft),u.style.right="60%",o=36===t(e.right),r=36===t(e.width),u.style.position="absolute",i=12===t(u.offsetWidth/3),ie.removeChild(s),u=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s=E.createElement("div"),u=E.createElement("div");u.style&&(u.style.backgroundClip="content-box",u.cloneNode(!0).style.backgroundClip="",y.clearCloneStyle="content-box"===u.style.backgroundClip,k.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),a},scrollboxSize:function(){return e(),i}}))}();var Ue=["Webkit","Moz","ms"],Xe=E.createElement("div").style,Ve={};function Ge(e){var t=k.cssProps[e]||Ve[e];return t||(e in Xe?e:Ve[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=Ue.length;while(n--)if((e=Ue[n]+t)in Xe)return e}(e)||e)}var Ye=/^(none|table(?!-c[ea]).+)/,Qe=/^--/,Je={position:"absolute",visibility:"hidden",display:"block"},Ke={letterSpacing:"0",fontWeight:"400"};function Ze(e,t,n){var r=ne.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function et(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+=k.css(e,n+re[a],!0,i)),r?("content"===n&&(u-=k.css(e,"padding"+re[a],!0,i)),"margin"!==n&&(u-=k.css(e,"border"+re[a]+"Width",!0,i))):(u+=k.css(e,"padding"+re[a],!0,i),"padding"!==n?u+=k.css(e,"border"+re[a]+"Width",!0,i):s+=k.css(e,"border"+re[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 tt(e,t,n){var r=Fe(e),i=(!y.boxSizingReliable()||n)&&"border-box"===k.css(e,"boxSizing",!1,r),o=i,a=_e(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if($e.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||"auto"===a||!parseFloat(a)&&"inline"===k.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===k.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+et(e,t,n||(i?"border":"content"),o,r,a)+"px"}function nt(e,t,n,r,i){return new nt.prototype.init(e,t,n,r,i)}k.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=_e(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=V(t),u=Qe.test(t),l=e.style;if(u||(t=Ge(s)),a=k.cssHooks[t]||k.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=ne.exec(n))&&i[1]&&(n=le(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(k.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=V(t);return Qe.test(t)||(t=Ge(s)),(a=k.cssHooks[t]||k.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=_e(e,t,r)),"normal"===i&&t in Ke&&(i=Ke[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),k.each(["height","width"],function(e,u){k.cssHooks[u]={get:function(e,t,n){if(t)return!Ye.test(k.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?tt(e,u,n):ue(e,Je,function(){return tt(e,u,n)})},set:function(e,t,n){var r,i=Fe(e),o=!y.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===k.css(e,"boxSizing",!1,i),s=n?et(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-et(e,u,"border",!1,i)-.5)),s&&(r=ne.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=k.css(e,u)),Ze(0,t,s)}}}),k.cssHooks.marginLeft=ze(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(_e(e,"marginLeft"))||e.getBoundingClientRect().left-ue(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),k.each({margin:"",padding:"",border:"Width"},function(i,o){k.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+re[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(k.cssHooks[i+o].set=Ze)}),k.fn.extend({css:function(e,t){return _(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Fe(e),i=t.length;a<i;a++)o[t[a]]=k.css(e,t[a],!1,r);return o}return void 0!==n?k.style(e,t,n):k.css(e,t)},e,t,1<arguments.length)}}),((k.Tween=nt).prototype={constructor:nt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||k.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(k.cssNumber[n]?"":"px")},cur:function(){var e=nt.propHooks[this.prop];return e&&e.get?e.get(this):nt.propHooks._default.get(this)},run:function(e){var t,n=nt.propHooks[this.prop];return this.options.duration?this.pos=t=k.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):nt.propHooks._default.set(this),this}}).init.prototype=nt.prototype,(nt.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=k.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){k.fx.step[e.prop]?k.fx.step[e.prop](e):1!==e.elem.nodeType||!k.cssHooks[e.prop]&&null==e.elem.style[Ge(e.prop)]?e.elem[e.prop]=e.now:k.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=nt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},k.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},k.fx=nt.prototype.init,k.fx.step={};var rt,it,ot,at,st=/^(?:toggle|show|hide)$/,ut=/queueHooks$/;function lt(){it&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(lt):C.setTimeout(lt,k.fx.interval),k.fx.tick())}function ct(){return C.setTimeout(function(){rt=void 0}),rt=Date.now()}function ft(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=re[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function pt(e,t,n){for(var r,i=(dt.tweeners[t]||[]).concat(dt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function dt(o,e,t){var n,a,r=0,i=dt.prefilters.length,s=k.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=rt||ct(),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:k.extend({},e),opts:k.extend(!0,{specialEasing:{},easing:k.easing._default},t),originalProperties:e,originalOptions:t,startTime:rt||ct(),duration:t.duration,tweens:[],createTween:function(e,t){var n=k.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=V(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=k.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=dt.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(k._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return k.map(c,pt,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),k.fx.timer(k.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}k.Animation=k.extend(dt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return le(n.elem,e,ne.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(R);for(var n,r=0,i=e.length;r<i;r++)n=e[r],dt.tweeners[n]=dt.tweeners[n]||[],dt.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&&se(e),v=Q.get(e,"fxshow");for(r in n.queue||(null==(a=k._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--,k.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],st.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]||k.style(e,r)}if((u=!k.isEmptyObject(t))||!k.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Q.get(e,"display")),"none"===(c=k.css(e,"display"))&&(l?c=l:(fe([e],!0),l=e.style.display||l,c=k.css(e,"display"),fe([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===k.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=Q.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&fe([e],!0),p.done(function(){for(r in g||fe([e]),Q.remove(e,"fxshow"),d)k.style(e,r,d[r])})),u=pt(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?dt.prefilters.unshift(e):dt.prefilters.push(e)}}),k.speed=function(e,t,n){var r=e&&"object"==typeof e?k.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return k.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in k.fx.speeds?r.duration=k.fx.speeds[r.duration]:r.duration=k.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&&k.dequeue(this,r.queue)},r},k.fn.extend({fadeTo:function(e,t,n,r){return this.filter(se).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=k.isEmptyObject(t),o=k.speed(e,n,r),a=function(){var e=dt(this,k.extend({},t),o);(i||Q.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&&!1!==i&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=k.timers,r=Q.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&ut.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||k.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Q.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=k.timers,o=n?n.length:0;for(t.finish=!0,k.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})}}),k.each(["toggle","show","hide"],function(e,r){var i=k.fn[r];k.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(ft(r,!0),e,t,n)}}),k.each({slideDown:ft("show"),slideUp:ft("hide"),slideToggle:ft("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){k.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),k.timers=[],k.fx.tick=function(){var e,t=0,n=k.timers;for(rt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||k.fx.stop(),rt=void 0},k.fx.timer=function(e){k.timers.push(e),k.fx.start()},k.fx.interval=13,k.fx.start=function(){it||(it=!0,lt())},k.fx.stop=function(){it=null},k.fx.speeds={slow:600,fast:200,_default:400},k.fn.delay=function(r,e){return r=k.fx&&k.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)}})},ot=E.createElement("input"),at=E.createElement("select").appendChild(E.createElement("option")),ot.type="checkbox",y.checkOn=""!==ot.value,y.optSelected=at.selected,(ot=E.createElement("input")).value="t",ot.type="radio",y.radioValue="t"===ot.value;var ht,gt=k.expr.attrHandle;k.fn.extend({attr:function(e,t){return _(this,k.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){k.removeAttr(this,e)})}}),k.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?k.prop(e,t,n):(1===o&&k.isXMLDoc(e)||(i=k.attrHooks[t.toLowerCase()]||(k.expr.match.bool.test(t)?ht:void 0)),void 0!==n?null===n?void k.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=k.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(R);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),ht={set:function(e,t,n){return!1===t?k.removeAttr(e,n):e.setAttribute(n,n),n}},k.each(k.expr.match.bool.source.match(/\w+/g),function(e,t){var a=gt[t]||k.find.attr;gt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=gt[o],gt[o]=r,r=null!=a(e,t,n)?o:null,gt[o]=i),r}});var vt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;function mt(e){return(e.match(R)||[]).join(" ")}function xt(e){return e.getAttribute&&e.getAttribute("class")||""}function bt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(R)||[]}k.fn.extend({prop:function(e,t){return _(this,k.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[k.propFix[e]||e]})}}),k.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&k.isXMLDoc(e)||(t=k.propFix[t]||t,i=k.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=k.find.attr(e,"tabindex");return t?parseInt(t,10):vt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),y.optSelected||(k.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)}}),k.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){k.propFix[this.toLowerCase()]=this}),k.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){k(this).addClass(t.call(this,e,xt(this)))});if((e=bt(t)).length)while(n=this[u++])if(i=xt(n),r=1===n.nodeType&&" "+mt(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=mt(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){k(this).removeClass(t.call(this,e,xt(this)))});if(!arguments.length)return this.attr("class","");if((e=bt(t)).length)while(n=this[u++])if(i=xt(n),r=1===n.nodeType&&" "+mt(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=mt(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){k(this).toggleClass(i.call(this,e,xt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=k(this),r=bt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=xt(this))&&Q.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Q.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+mt(xt(n))+" ").indexOf(t))return!0;return!1}});var wt=/\r/g;k.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,k(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=k.map(t,function(e){return null==e?"":e+""})),(r=k.valHooks[this.type]||k.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=k.valHooks[t.type]||k.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(wt,""):null==e?"":e:void 0}}),k.extend({valHooks:{option:{get:function(e){var t=k.find.attr(e,"value");return null!=t?t:mt(k.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=k(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=k.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<k.inArray(k.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),k.each(["radio","checkbox"],function(){k.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<k.inArray(k(e).val(),t)}},y.checkOn||(k.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),y.focusin="onfocusin"in C;var Tt=/^(?:focusinfocus|focusoutblur)$/,Ct=function(e){e.stopPropagation()};k.extend(k.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&&!Tt.test(d+k.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[k.expando]?e:new k.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]:k.makeArray(t,[e]),c=k.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,Tt.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=(Q.get(o,"events")||{})[e.type]&&Q.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&G(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)||!G(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),k.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,Ct),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,Ct),k.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=k.extend(new k.Event,n,{type:e,isSimulated:!0});k.event.trigger(r,null,t)}}),k.fn.extend({trigger:function(e,t){return this.each(function(){k.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return k.event.trigger(e,t,n,!0)}}),y.focusin||k.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){k.event.simulate(r,e.target,k.event.fix(e))};k.event.special[r]={setup:function(){var e=this.ownerDocument||this,t=Q.access(e,r);t||e.addEventListener(n,i,!0),Q.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this,t=Q.access(e,r)-1;t?Q.access(e,r,t):(e.removeEventListener(n,i,!0),Q.remove(e,r))}}});var Et=C.location,kt=Date.now(),St=/\?/;k.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||k.error("Invalid XML: "+e),t};var Nt=/\[\]$/,At=/\r?\n/g,Dt=/^(?:submit|button|image|reset|file)$/i,jt=/^(?:input|select|textarea|keygen)/i;function qt(n,e,r,i){var t;if(Array.isArray(e))k.each(e,function(e,t){r||Nt.test(n)?i(n,t):qt(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)qt(n+"["+t+"]",e[t],r,i)}k.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&&!k.isPlainObject(e))k.each(e,function(){i(this.name,this.value)});else for(n in e)qt(n,e[n],t,i);return r.join("&")},k.fn.extend({serialize:function(){return k.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=k.prop(this,"elements");return e?k.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!k(this).is(":disabled")&&jt.test(this.nodeName)&&!Dt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=k(this).val();return null==n?null:Array.isArray(n)?k.map(n,function(e){return{name:t.name,value:e.replace(At,"\r\n")}}):{name:t.name,value:n.replace(At,"\r\n")}}).get()}});var Lt=/%20/g,Ht=/#.*$/,Ot=/([?&])_=[^&]*/,Pt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Rt=/^(?:GET|HEAD)$/,Mt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Ft=E.createElement("a");function Bt(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(R)||[];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 _t(t,i,o,a){var s={},u=t===Wt;function l(e){var r;return s[e]=!0,k.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 zt(e,t){var n,r,i=k.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&k.extend(!0,e,r),e}Ft.href=Et.href,k.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Et.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Et.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,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":k.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,k.ajaxSettings),t):zt(k.ajaxSettings,e)},ajaxPrefilter:Bt(It),ajaxTransport:Bt(Wt),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=k.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?k(y):k.event,x=k.Deferred(),b=k.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=Pt.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||Et.href)+"").replace(Mt,Et.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(R)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Ft.protocol+"//"+Ft.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=k.param(v.data,v.traditional)),_t(It,v,t,T),h)return T;for(i in(g=k.event&&v.global)&&0==k.active++&&k.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!Rt.test(v.type),f=v.url.replace(Ht,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(Lt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(St.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Ot,"$1"),o=(St.test(f)?"&":"?")+"_="+kt+++o),v.url=f+o),v.ifModified&&(k.lastModified[f]&&T.setRequestHeader("If-Modified-Since",k.lastModified[f]),k.etag[f]&&T.setRequestHeader("If-None-Match",k.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]?", "+$t+"; 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=_t(Wt,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)),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"))&&(k.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(k.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]),--k.active||k.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return k.get(e,t,n,"json")},getScript:function(e,t){return k.get(e,void 0,t,"script")}}),k.each(["get","post"],function(e,i){k[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),k.ajax(k.extend({url:e,type:i,dataType:r,data:t,success:n},k.isPlainObject(e)&&e))}}),k._evalUrl=function(e,t){return k.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){k.globalEval(e,t)}})},k.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=k(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){k(this).wrapInner(n.call(this,e))}):this.each(function(){var e=k(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){k(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){k(this).replaceWith(this.childNodes)}),this}}),k.expr.pseudos.hidden=function(e){return!k.expr.pseudos.visible(e)},k.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},k.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var Ut={0:200,1223:204},Xt=k.ajaxSettings.xhr();y.cors=!!Xt&&"withCredentials"in Xt,y.ajax=Xt=!!Xt,k.ajaxTransport(function(i){var o,a;if(y.cors||Xt&&!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(Ut[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()}}}),k.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),k.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 k.globalEval(e),e}}}),k.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),k.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=k("<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 Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.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(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.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?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Vt.childNodes.length),k.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=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=mt(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&k.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?k("<div>").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.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,k.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):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.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"===k.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"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.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)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.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?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.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){k.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}}),k.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),k.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)}}),k.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||k.guid++,i},k.holdReady=function(e){e?k.readyWait++:k.ready(!0)},k.isArray=Array.isArray,k.parseJSON=JSON.parse,k.nodeName=A,k.isFunction=m,k.isWindow=x,k.camelCase=V,k.type=w,k.now=Date.now,k.isNumeric=function(e){var t=k.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return k});var Qt=C.jQuery,Jt=C.$;return k.noConflict=function(e){return C.$===k&&(C.$=Jt),e&&C.jQuery===k&&(C.jQuery=Qt),k},e||(C.jQuery=C.$=k),k}); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-migrate-3.0.1.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-migrate-3.0.1.js new file mode 100644 index 0000000..6ba8af4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-migrate-3.0.1.js @@ -0,0 +1,626 @@ +/*! + * jQuery Migrate - v3.0.1 - 2017-09-26 + * Copyright jQuery Foundation and other contributors + */ +;( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "jquery" ], window, factory ); + } else if ( typeof module === "object" && module.exports ) { + + // Node/CommonJS + // eslint-disable-next-line no-undef + module.exports = factory( require( "jquery" ), window ); + } else { + + // Browser globals + factory( jQuery, window ); + } +} )( function( jQuery, window ) { +"use strict"; + + +jQuery.migrateVersion = "3.0.1"; + +/* exported migrateWarn, migrateWarnFunc, migrateWarnProp */ + +( function() { + + var rbadVersions = /^[12]\./; + + // Support: IE9 only + // IE9 only creates console object when dev tools are first opened + // IE9 console is a host object, callable but doesn't have .apply() + if ( !window.console || !window.console.log ) { + return; + } + + // Need jQuery 3.0.0+ and no older Migrate loaded + if ( !jQuery || rbadVersions.test( jQuery.fn.jquery ) ) { + window.console.log( "JQMIGRATE: jQuery 3.0.0+ REQUIRED" ); + } + if ( jQuery.migrateWarnings ) { + window.console.log( "JQMIGRATE: Migrate plugin loaded multiple times" ); + } + + // Show a message on the console so devs know we're active + window.console.log( "JQMIGRATE: Migrate is installed" + + ( jQuery.migrateMute ? "" : " with logging active" ) + + ", version " + jQuery.migrateVersion ); + +} )(); + +var warnedAbout = {}; + +// List of warnings already given; public read only +jQuery.migrateWarnings = []; + +// Set to false to disable traces that appear with warnings +if ( jQuery.migrateTrace === undefined ) { + jQuery.migrateTrace = true; +} + +// Forget any warnings we've already given; public +jQuery.migrateReset = function() { + warnedAbout = {}; + jQuery.migrateWarnings.length = 0; +}; + +function migrateWarn( msg ) { + var console = window.console; + if ( !warnedAbout[ msg ] ) { + warnedAbout[ msg ] = true; + jQuery.migrateWarnings.push( msg ); + if ( console && console.warn && !jQuery.migrateMute ) { + console.warn( "JQMIGRATE: " + msg ); + if ( jQuery.migrateTrace && console.trace ) { + console.trace(); + } + } + } +} + +function migrateWarnProp( obj, prop, value, msg ) { + Object.defineProperty( obj, prop, { + configurable: true, + enumerable: true, + get: function() { + migrateWarn( msg ); + return value; + }, + set: function( newValue ) { + migrateWarn( msg ); + value = newValue; + } + } ); +} + +function migrateWarnFunc( obj, prop, newFunc, msg ) { + obj[ prop ] = function() { + migrateWarn( msg ); + return newFunc.apply( this, arguments ); + }; +} + +if ( window.document.compatMode === "BackCompat" ) { + + // JQuery has never supported or tested Quirks Mode + migrateWarn( "jQuery is not compatible with Quirks Mode" ); +} + + +var oldInit = jQuery.fn.init, + oldIsNumeric = jQuery.isNumeric, + oldFind = jQuery.find, + rattrHashTest = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/, + rattrHashGlob = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g; + +jQuery.fn.init = function( arg1 ) { + var args = Array.prototype.slice.call( arguments ); + + if ( typeof arg1 === "string" && arg1 === "#" ) { + + // JQuery( "#" ) is a bogus ID selector, but it returned an empty set before jQuery 3.0 + migrateWarn( "jQuery( '#' ) is not a valid selector" ); + args[ 0 ] = []; + } + + return oldInit.apply( this, args ); +}; +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.find = function( selector ) { + var args = Array.prototype.slice.call( arguments ); + + // Support: PhantomJS 1.x + // String#match fails to match when used with a //g RegExp, only on some strings + if ( typeof selector === "string" && rattrHashTest.test( selector ) ) { + + // The nonstandard and undocumented unquoted-hash was removed in jQuery 1.12.0 + // First see if qS thinks it's a valid selector, if so avoid a false positive + try { + window.document.querySelector( selector ); + } catch ( err1 ) { + + // Didn't *look* valid to qSA, warn and try quoting what we think is the value + selector = selector.replace( rattrHashGlob, function( _, attr, op, value ) { + return "[" + attr + op + "\"" + value + "\"]"; + } ); + + // If the regexp *may* have created an invalid selector, don't update it + // Note that there may be false alarms if selector uses jQuery extensions + try { + window.document.querySelector( selector ); + migrateWarn( "Attribute selector with '#' must be quoted: " + args[ 0 ] ); + args[ 0 ] = selector; + } catch ( err2 ) { + migrateWarn( "Attribute selector with '#' was not fixed: " + args[ 0 ] ); + } + } + } + + return oldFind.apply( this, args ); +}; + +// Copy properties attached to original jQuery.find method (e.g. .attr, .isXML) +var findProp; +for ( findProp in oldFind ) { + if ( Object.prototype.hasOwnProperty.call( oldFind, findProp ) ) { + jQuery.find[ findProp ] = oldFind[ findProp ]; + } +} + +// The number of elements contained in the matched element set +jQuery.fn.size = function() { + migrateWarn( "jQuery.fn.size() is deprecated and removed; use the .length property" ); + return this.length; +}; + +jQuery.parseJSON = function() { + migrateWarn( "jQuery.parseJSON is deprecated; use JSON.parse" ); + return JSON.parse.apply( null, arguments ); +}; + +jQuery.isNumeric = function( val ) { + + // The jQuery 2.2.3 implementation of isNumeric + function isNumeric2( obj ) { + var realStringObj = obj && obj.toString(); + return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; + } + + var newValue = oldIsNumeric( val ), + oldValue = isNumeric2( val ); + + if ( newValue !== oldValue ) { + migrateWarn( "jQuery.isNumeric() should not be called on constructed objects" ); + } + + return oldValue; +}; + +migrateWarnFunc( jQuery, "holdReady", jQuery.holdReady, + "jQuery.holdReady is deprecated" ); + +migrateWarnFunc( jQuery, "unique", jQuery.uniqueSort, + "jQuery.unique is deprecated; use jQuery.uniqueSort" ); + +// Now jQuery.expr.pseudos is the standard incantation +migrateWarnProp( jQuery.expr, "filters", jQuery.expr.pseudos, + "jQuery.expr.filters is deprecated; use jQuery.expr.pseudos" ); +migrateWarnProp( jQuery.expr, ":", jQuery.expr.pseudos, + "jQuery.expr[':'] is deprecated; use jQuery.expr.pseudos" ); + + +var oldAjax = jQuery.ajax; + +jQuery.ajax = function( ) { + var jQXHR = oldAjax.apply( this, arguments ); + + // Be sure we got a jQXHR (e.g., not sync) + if ( jQXHR.promise ) { + migrateWarnFunc( jQXHR, "success", jQXHR.done, + "jQXHR.success is deprecated and removed" ); + migrateWarnFunc( jQXHR, "error", jQXHR.fail, + "jQXHR.error is deprecated and removed" ); + migrateWarnFunc( jQXHR, "complete", jQXHR.always, + "jQXHR.complete is deprecated and removed" ); + } + + return jQXHR; +}; + + +var oldRemoveAttr = jQuery.fn.removeAttr, + oldToggleClass = jQuery.fn.toggleClass, + rmatchNonSpace = /\S+/g; + +jQuery.fn.removeAttr = function( name ) { + var self = this; + + jQuery.each( name.match( rmatchNonSpace ), function( i, attr ) { + if ( jQuery.expr.match.bool.test( attr ) ) { + migrateWarn( "jQuery.fn.removeAttr no longer sets boolean properties: " + attr ); + self.prop( attr, false ); + } + } ); + + return oldRemoveAttr.apply( this, arguments ); +}; + +jQuery.fn.toggleClass = function( state ) { + + // Only deprecating no-args or single boolean arg + if ( state !== undefined && typeof state !== "boolean" ) { + return oldToggleClass.apply( this, arguments ); + } + + migrateWarn( "jQuery.fn.toggleClass( boolean ) is deprecated" ); + + // Toggle entire class name of each element + return this.each( function() { + var className = this.getAttribute && this.getAttribute( "class" ) || ""; + + if ( className ) { + jQuery.data( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || state === false ? + "" : + jQuery.data( this, "__className__" ) || "" + ); + } + } ); +}; + + +var internalSwapCall = false; + +// If this version of jQuery has .swap(), don't false-alarm on internal uses +if ( jQuery.swap ) { + jQuery.each( [ "height", "width", "reliableMarginRight" ], function( _, name ) { + var oldHook = jQuery.cssHooks[ name ] && jQuery.cssHooks[ name ].get; + + if ( oldHook ) { + jQuery.cssHooks[ name ].get = function() { + var ret; + + internalSwapCall = true; + ret = oldHook.apply( this, arguments ); + internalSwapCall = false; + return ret; + }; + } + } ); +} + +jQuery.swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + if ( !internalSwapCall ) { + migrateWarn( "jQuery.swap() is undocumented and deprecated" ); + } + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + +var oldData = jQuery.data; + +jQuery.data = function( elem, name, value ) { + var curData; + + // Name can be an object, and each entry in the object is meant to be set as data + if ( name && typeof name === "object" && arguments.length === 2 ) { + curData = jQuery.hasData( elem ) && oldData.call( this, elem ); + var sameKeys = {}; + for ( var key in name ) { + if ( key !== jQuery.camelCase( key ) ) { + migrateWarn( "jQuery.data() always sets/gets camelCased names: " + key ); + curData[ key ] = name[ key ]; + } else { + sameKeys[ key ] = name[ key ]; + } + } + + oldData.call( this, elem, sameKeys ); + + return name; + } + + // If the name is transformed, look for the un-transformed name in the data object + if ( name && typeof name === "string" && name !== jQuery.camelCase( name ) ) { + curData = jQuery.hasData( elem ) && oldData.call( this, elem ); + if ( curData && name in curData ) { + migrateWarn( "jQuery.data() always sets/gets camelCased names: " + name ); + if ( arguments.length > 2 ) { + curData[ name ] = value; + } + return curData[ name ]; + } + } + + return oldData.apply( this, arguments ); +}; + +var oldTweenRun = jQuery.Tween.prototype.run; +var linearEasing = function( pct ) { + return pct; + }; + +jQuery.Tween.prototype.run = function( ) { + if ( jQuery.easing[ this.easing ].length > 1 ) { + migrateWarn( + "'jQuery.easing." + this.easing.toString() + "' should use only one argument" + ); + + jQuery.easing[ this.easing ] = linearEasing; + } + + oldTweenRun.apply( this, arguments ); +}; + +jQuery.fx.interval = jQuery.fx.interval || 13; + +// Support: IE9, Android <=4.4 +// Avoid false positives on browsers that lack rAF +if ( window.requestAnimationFrame ) { + migrateWarnProp( jQuery.fx, "interval", jQuery.fx.interval, + "jQuery.fx.interval is deprecated" ); +} + +var oldLoad = jQuery.fn.load, + oldEventAdd = jQuery.event.add, + originalFix = jQuery.event.fix; + +jQuery.event.props = []; +jQuery.event.fixHooks = {}; + +migrateWarnProp( jQuery.event.props, "concat", jQuery.event.props.concat, + "jQuery.event.props.concat() is deprecated and removed" ); + +jQuery.event.fix = function( originalEvent ) { + var event, + type = originalEvent.type, + fixHook = this.fixHooks[ type ], + props = jQuery.event.props; + + if ( props.length ) { + migrateWarn( "jQuery.event.props are deprecated and removed: " + props.join() ); + while ( props.length ) { + jQuery.event.addProp( props.pop() ); + } + } + + if ( fixHook && !fixHook._migrated_ ) { + fixHook._migrated_ = true; + migrateWarn( "jQuery.event.fixHooks are deprecated and removed: " + type ); + if ( ( props = fixHook.props ) && props.length ) { + while ( props.length ) { + jQuery.event.addProp( props.pop() ); + } + } + } + + event = originalFix.call( this, originalEvent ); + + return fixHook && fixHook.filter ? fixHook.filter( event, originalEvent ) : event; +}; + +jQuery.event.add = function( elem, types ) { + + // This misses the multiple-types case but that seems awfully rare + if ( elem === window && types === "load" && window.document.readyState === "complete" ) { + migrateWarn( "jQuery(window).on('load'...) called after load event occurred" ); + } + return oldEventAdd.apply( this, arguments ); +}; + +jQuery.each( [ "load", "unload", "error" ], function( _, name ) { + + jQuery.fn[ name ] = function() { + var args = Array.prototype.slice.call( arguments, 0 ); + + // If this is an ajax load() the first arg should be the string URL; + // technically this could also be the "Anything" arg of the event .load() + // which just goes to show why this dumb signature has been deprecated! + // jQuery custom builds that exclude the Ajax module justifiably die here. + if ( name === "load" && typeof args[ 0 ] === "string" ) { + return oldLoad.apply( this, args ); + } + + migrateWarn( "jQuery.fn." + name + "() is deprecated" ); + + args.splice( 0, 0, name ); + if ( arguments.length ) { + return this.on.apply( this, args ); + } + + // Use .triggerHandler here because: + // - load and unload events don't need to bubble, only applied to window or image + // - error event should not bubble to window, although it does pre-1.7 + // See http://bugs.jquery.com/ticket/11820 + this.triggerHandler.apply( this, args ); + return this; + }; + +} ); + +jQuery.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( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + migrateWarn( "jQuery.fn." + name + "() event shorthand is deprecated" ); + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; +} ); + +// Trigger "ready" event only once, on document ready +jQuery( function() { + jQuery( window.document ).triggerHandler( "ready" ); +} ); + +jQuery.event.special.ready = { + setup: function() { + if ( this === window.document ) { + migrateWarn( "'ready' event is deprecated" ); + } + } +}; + +jQuery.fn.extend( { + + bind: function( types, data, fn ) { + migrateWarn( "jQuery.fn.bind() is deprecated" ); + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + migrateWarn( "jQuery.fn.unbind() is deprecated" ); + return this.off( types, null, fn ); + }, + delegate: function( selector, types, data, fn ) { + migrateWarn( "jQuery.fn.delegate() is deprecated" ); + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + migrateWarn( "jQuery.fn.undelegate() is deprecated" ); + return arguments.length === 1 ? + this.off( selector, "**" ) : + this.off( types, selector || "**", fn ); + }, + hover: function( fnOver, fnOut ) { + migrateWarn( "jQuery.fn.hover() is deprecated" ); + return this.on( "mouseenter", fnOver ).on( "mouseleave", fnOut || fnOver ); + } +} ); + + +var oldOffset = jQuery.fn.offset; + +jQuery.fn.offset = function() { + var docElem, + elem = this[ 0 ], + origin = { top: 0, left: 0 }; + + if ( !elem || !elem.nodeType ) { + migrateWarn( "jQuery.fn.offset() requires a valid DOM element" ); + return origin; + } + + docElem = ( elem.ownerDocument || window.document ).documentElement; + if ( !jQuery.contains( docElem, elem ) ) { + migrateWarn( "jQuery.fn.offset() requires an element connected to a document" ); + return origin; + } + + return oldOffset.apply( this, arguments ); +}; + + +var oldParam = jQuery.param; + +jQuery.param = function( data, traditional ) { + var ajaxTraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + + if ( traditional === undefined && ajaxTraditional ) { + + migrateWarn( "jQuery.param() no longer uses jQuery.ajaxSettings.traditional" ); + traditional = ajaxTraditional; + } + + return oldParam.call( this, data, traditional ); +}; + +var oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack; + +jQuery.fn.andSelf = function() { + migrateWarn( "jQuery.fn.andSelf() is deprecated and removed, use jQuery.fn.addBack()" ); + return oldSelf.apply( this, arguments ); +}; + + +var oldDeferred = jQuery.Deferred, + tuples = [ + + // Action, add listener, callbacks, .then handlers, final state + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), "rejected" ], + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ) ] + ]; + +jQuery.Deferred = function( func ) { + var deferred = oldDeferred(), + promise = deferred.promise(); + + deferred.pipe = promise.pipe = function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + migrateWarn( "deferred.pipe() is deprecated" ); + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + + // Deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this === promise ? newDefer.promise() : this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + + }; + + if ( func ) { + func.call( deferred, deferred ); + } + + return deferred; +}; + +// Preserve handler of uncaught exceptions in promise chains +jQuery.Deferred.exceptionHook = oldDeferred.exceptionHook; + +return jQuery; +} ); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-migrate-3.0.1.min.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-migrate-3.0.1.min.js new file mode 100644 index 0000000..cd6d6c8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-migrate-3.0.1.min.js @@ -0,0 +1,215 @@ +/*! jQuery Migrate v3.0.1 | (c) jQuery Foundation and other contributors | jquery.org/license */ + +void 0 === jQuery.migrateMute && (jQuery.migrateMute = !0), function(e) { + "function" == typeof define && define.amd ? define([ "jquery" ], window, e) : "object" == typeof module && module.exports ? module.exports = e(require("jquery"), window) : e(jQuery, window); +}(function(e, t) { + "use strict"; + function r(r) { + var n = t.console; + o[r] || (o[r] = !0, e.migrateWarnings.push(r), n && n.warn && !e.migrateMute && (n.warn("JQMIGRATE: " + r), + e.migrateTrace && n.trace && n.trace())); + } + function n(e, t, n, a) { + Object.defineProperty(e, t, { + configurable: !0, + enumerable: !0, + get: function() { + return r(a), n; + }, + set: function(e) { + r(a), n = e; + } + }); + } + function a(e, t, n, a) { + e[t] = function() { + return r(a), n.apply(this, arguments); + }; + } + e.migrateVersion = "3.0.1", function() { + var r = /^[12]\./; + t.console && t.console.log && (e && !r.test(e.fn.jquery) || t.console.log("JQMIGRATE: jQuery 3.0.0+ REQUIRED"), + e.migrateWarnings && t.console.log("JQMIGRATE: Migrate plugin loaded multiple times"), + t.console.log("JQMIGRATE: Migrate is installed" + (e.migrateMute ? "" : " with logging active") + ", version " + e.migrateVersion)); + }(); + var o = {}; + e.migrateWarnings = [], void 0 === e.migrateTrace && (e.migrateTrace = !0), e.migrateReset = function() { + o = {}, e.migrateWarnings.length = 0; + }, "BackCompat" === t.document.compatMode && r("jQuery is not compatible with Quirks Mode"); + var i = e.fn.init, s = e.isNumeric, u = e.find, c = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/, l = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g; + e.fn.init = function(e) { + var t = Array.prototype.slice.call(arguments); + return "string" == typeof e && "#" === e && (r("jQuery( '#' ) is not a valid selector"), + t[0] = []), i.apply(this, t); + }, e.fn.init.prototype = e.fn, e.find = function(e) { + var n = Array.prototype.slice.call(arguments); + if ("string" == typeof e && c.test(e)) try { + t.document.querySelector(e); + } catch (a) { + e = e.replace(l, function(e, t, r, n) { + return "[" + t + r + '"' + n + '"]'; + }); + try { + t.document.querySelector(e), r("Attribute selector with '#' must be quoted: " + n[0]), + n[0] = e; + } catch (e) { + r("Attribute selector with '#' was not fixed: " + n[0]); + } + } + return u.apply(this, n); + }; + var d; + for (d in u) Object.prototype.hasOwnProperty.call(u, d) && (e.find[d] = u[d]); + e.fn.size = function() { + return r("jQuery.fn.size() is deprecated and removed; use the .length property"), + this.length; + }, e.parseJSON = function() { + return r("jQuery.parseJSON is deprecated; use JSON.parse"), JSON.parse.apply(null, arguments); + }, e.isNumeric = function(t) { + var n = s(t), a = function(t) { + var r = t && t.toString(); + return !e.isArray(t) && r - parseFloat(r) + 1 >= 0; + }(t); + return n !== a && r("jQuery.isNumeric() should not be called on constructed objects"), + a; + }, a(e, "holdReady", e.holdReady, "jQuery.holdReady is deprecated"), a(e, "unique", e.uniqueSort, "jQuery.unique is deprecated; use jQuery.uniqueSort"), + n(e.expr, "filters", e.expr.pseudos, "jQuery.expr.filters is deprecated; use jQuery.expr.pseudos"), + n(e.expr, ":", e.expr.pseudos, "jQuery.expr[':'] is deprecated; use jQuery.expr.pseudos"); + var p = e.ajax; + e.ajax = function() { + var e = p.apply(this, arguments); + return e.promise && (a(e, "success", e.done, "jQXHR.success is deprecated and removed"), + a(e, "error", e.fail, "jQXHR.error is deprecated and removed"), a(e, "complete", e.always, "jQXHR.complete is deprecated and removed")), + e; + }; + var f = e.fn.removeAttr, y = e.fn.toggleClass, m = /\S+/g; + e.fn.removeAttr = function(t) { + var n = this; + return e.each(t.match(m), function(t, a) { + e.expr.match.bool.test(a) && (r("jQuery.fn.removeAttr no longer sets boolean properties: " + a), + n.prop(a, !1)); + }), f.apply(this, arguments); + }, e.fn.toggleClass = function(t) { + return void 0 !== t && "boolean" != typeof t ? y.apply(this, arguments) : (r("jQuery.fn.toggleClass( boolean ) is deprecated"), + this.each(function() { + var r = this.getAttribute && this.getAttribute("class") || ""; + r && e.data(this, "__className__", r), this.setAttribute && this.setAttribute("class", r || !1 === t ? "" : e.data(this, "__className__") || ""); + })); + }; + var h = !1; + e.swap && e.each([ "height", "width", "reliableMarginRight" ], function(t, r) { + var n = e.cssHooks[r] && e.cssHooks[r].get; + n && (e.cssHooks[r].get = function() { + var e; + return h = !0, e = n.apply(this, arguments), h = !1, e; + }); + }), e.swap = function(e, t, n, a) { + var o, i, s = {}; + h || r("jQuery.swap() is undocumented and deprecated"); + for (i in t) s[i] = e.style[i], e.style[i] = t[i]; + o = n.apply(e, a || []); + for (i in t) e.style[i] = s[i]; + return o; + }; + var g = e.data; + e.data = function(t, n, a) { + var o; + if (n && "object" == typeof n && 2 === arguments.length) { + o = e.hasData(t) && g.call(this, t); + var i = {}; + for (var s in n) s !== e.camelCase(s) ? (r("jQuery.data() always sets/gets camelCased names: " + s), + o[s] = n[s]) : i[s] = n[s]; + return g.call(this, t, i), n; + } + return n && "string" == typeof n && n !== e.camelCase(n) && (o = e.hasData(t) && g.call(this, t)) && n in o ? (r("jQuery.data() always sets/gets camelCased names: " + n), + arguments.length > 2 && (o[n] = a), o[n]) : g.apply(this, arguments); + }; + var v = e.Tween.prototype.run, j = function(e) { + return e; + }; + e.Tween.prototype.run = function() { + e.easing[this.easing].length > 1 && (r("'jQuery.easing." + this.easing.toString() + "' should use only one argument"), + e.easing[this.easing] = j), v.apply(this, arguments); + }, e.fx.interval = e.fx.interval || 13, t.requestAnimationFrame && n(e.fx, "interval", e.fx.interval, "jQuery.fx.interval is deprecated"); + var Q = e.fn.load, b = e.event.add, w = e.event.fix; + e.event.props = [], e.event.fixHooks = {}, n(e.event.props, "concat", e.event.props.concat, "jQuery.event.props.concat() is deprecated and removed"), + e.event.fix = function(t) { + var n, a = t.type, o = this.fixHooks[a], i = e.event.props; + if (i.length) for (r("jQuery.event.props are deprecated and removed: " + i.join()); i.length; ) e.event.addProp(i.pop()); + if (o && !o._migrated_ && (o._migrated_ = !0, r("jQuery.event.fixHooks are deprecated and removed: " + a), + (i = o.props) && i.length)) for (;i.length; ) e.event.addProp(i.pop()); + return n = w.call(this, t), o && o.filter ? o.filter(n, t) : n; + }, e.event.add = function(e, n) { + return e === t && "load" === n && "complete" === t.document.readyState && r("jQuery(window).on('load'...) called after load event occurred"), + b.apply(this, arguments); + }, e.each([ "load", "unload", "error" ], function(t, n) { + e.fn[n] = function() { + var e = Array.prototype.slice.call(arguments, 0); + return "load" === n && "string" == typeof e[0] ? Q.apply(this, e) : (r("jQuery.fn." + n + "() is deprecated"), + e.splice(0, 0, n), arguments.length ? this.on.apply(this, e) : (this.triggerHandler.apply(this, e), + this)); + }; + }), e.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(t, n) { + e.fn[n] = function(e, t) { + return r("jQuery.fn." + n + "() event shorthand is deprecated"), arguments.length > 0 ? this.on(n, null, e, t) : this.trigger(n); + }; + }), e(function() { + e(t.document).triggerHandler("ready"); + }), e.event.special.ready = { + setup: function() { + this === t.document && r("'ready' event is deprecated"); + } + }, e.fn.extend({ + bind: function(e, t, n) { + return r("jQuery.fn.bind() is deprecated"), this.on(e, null, t, n); + }, + unbind: function(e, t) { + return r("jQuery.fn.unbind() is deprecated"), this.off(e, null, t); + }, + delegate: function(e, t, n, a) { + return r("jQuery.fn.delegate() is deprecated"), this.on(t, e, n, a); + }, + undelegate: function(e, t, n) { + return r("jQuery.fn.undelegate() is deprecated"), 1 === arguments.length ? this.off(e, "**") : this.off(t, e || "**", n); + }, + hover: function(e, t) { + return r("jQuery.fn.hover() is deprecated"), this.on("mouseenter", e).on("mouseleave", t || e); + } + }); + var x = e.fn.offset; + e.fn.offset = function() { + var n, a = this[0], o = { + top: 0, + left: 0 + }; + return a && a.nodeType ? (n = (a.ownerDocument || t.document).documentElement, e.contains(n, a) ? x.apply(this, arguments) : (r("jQuery.fn.offset() requires an element connected to a document"), + o)) : (r("jQuery.fn.offset() requires a valid DOM element"), o); + }; + var k = e.param; + e.param = function(t, n) { + var a = e.ajaxSettings && e.ajaxSettings.traditional; + return void 0 === n && a && (r("jQuery.param() no longer uses jQuery.ajaxSettings.traditional"), + n = a), k.call(this, t, n); + }; + var A = e.fn.andSelf || e.fn.addBack; + e.fn.andSelf = function() { + return r("jQuery.fn.andSelf() is deprecated and removed, use jQuery.fn.addBack()"), + A.apply(this, arguments); + }; + var S = e.Deferred, q = [ [ "resolve", "done", e.Callbacks("once memory"), e.Callbacks("once memory"), "resolved" ], [ "reject", "fail", e.Callbacks("once memory"), e.Callbacks("once memory"), "rejected" ], [ "notify", "progress", e.Callbacks("memory"), e.Callbacks("memory") ] ]; + return e.Deferred = function(t) { + var n = S(), a = n.promise(); + return n.pipe = a.pipe = function() { + var t = arguments; + return r("deferred.pipe() is deprecated"), e.Deferred(function(r) { + e.each(q, function(o, i) { + var s = e.isFunction(t[o]) && t[o]; + n[i[1]](function() { + var t = s && s.apply(this, arguments); + t && e.isFunction(t.promise) ? t.promise().done(r.resolve).fail(r.reject).progress(r.notify) : r[i[0] + "With"](this === a ? r.promise() : this, s ? [ t ] : arguments); + }); + }), t = null; + }).promise(); + }, t && t.call(n, n), n; + }, e.Deferred.exceptionHook = S.exceptionHook, e; +}); \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-ui.min.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-ui.min.js new file mode 100644 index 0000000..25398a1 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-ui.min.js @@ -0,0 +1,13 @@ +/*! jQuery UI - v1.12.1 - 2016-09-14 +* http://jqueryui.com +* Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){function e(t){for(var e=t.css("visibility");"inherit"===e;)t=t.parent(),e=t.css("visibility");return"hidden"!==e}function i(t){for(var e,i;t.length&&t[0]!==document;){if(e=t.css("position"),("absolute"===e||"relative"===e||"fixed"===e)&&(i=parseInt(t.css("zIndex"),10),!isNaN(i)&&0!==i))return i;t=t.parent()}return 0}function s(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},t.extend(this._defaults,this.regional[""]),this.regional.en=t.extend(!0,{},this.regional[""]),this.regional["en-US"]=t.extend(!0,{},this.regional.en),this.dpDiv=n(t("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function n(e){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.on("mouseout",i,function(){t(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).removeClass("ui-datepicker-next-hover")}).on("mouseover",i,o)}function o(){t.datepicker._isDisabledDatepicker(m.inline?m.dpDiv.parent()[0]:m.input[0])||(t(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),t(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).addClass("ui-datepicker-next-hover"))}function a(e,i){t.extend(e,i);for(var s in i)null==i[s]&&(e[s]=i[s]);return e}function r(t){return function(){var e=this.element.val();t.apply(this,arguments),this._refresh(),e!==this.element.val()&&this._trigger("change")}}t.ui=t.ui||{},t.ui.version="1.12.1";var h=0,l=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},h=e.split(".")[0];e=e.split(".")[1];var l=h+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][l.toLowerCase()]=function(e){return!!t.data(e,l)},t[h]=t[h]||{},n=t[h][e],o=t[h][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:h,widgetName:e,widgetFullName:l}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var i,s,n=l.call(arguments,1),o=0,a=n.length;a>o;o++)for(i in n[o])s=n[o][i],n[o].hasOwnProperty(i)&&void 0!==s&&(e[i]=t.isPlainObject(s)?t.isPlainObject(e[i])?t.widget.extend({},e[i],s):t.widget.extend({},s):s);return e},t.widget.bridge=function(e,i){var s=i.prototype.widgetFullName||e;t.fn[e]=function(n){var o="string"==typeof n,a=l.call(arguments,1),r=this;return o?this.length||"instance"!==n?this.each(function(){var i,o=t.data(this,s);return"instance"===n?(r=o,!1):o?t.isFunction(o[n])&&"_"!==n.charAt(0)?(i=o[n].apply(o,a),i!==o&&void 0!==i?(r=i&&i.jquery?r.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+n+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+n+"'")}):r=void 0:(a.length&&(n=t.widget.extend.apply(null,[n].concat(a))),this.each(function(){var e=t.data(this,s);e?(e.option(n||{}),e._init&&e._init()):t.data(this,s,new i(n,this))})),r}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,i){i=t(i||this.defaultElement||this)[0],this.element=t(i),this.uuid=h++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},i!==this&&(t.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===i&&this.destroy()}}),this.document=t(i.style?i.ownerDocument:i.document||i),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.width<e.element[0].scrollWidth,o="scroll"===s||"auto"===s&&e.height<e.element[0].scrollHeight;return{width:o?t.position.scrollbarWidth():0,height:n?t.position.scrollbarWidth():0}},getWithinInfo:function(e){var i=t(e||window),s=t.isWindow(i[0]),n=!!i[0]&&9===i[0].nodeType,o=!s&&!n;return{element:i,isWindow:s,isDocument:n,offset:o?t(e).offset():{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:i.outerWidth(),height:i.outerHeight()}}},t.fn.position=function(n){if(!n||!n.of)return d.apply(this,arguments);n=t.extend({},n);var u,p,f,g,m,_,v=t(n.of),b=t.position.getWithinInfo(n.within),y=t.position.getScrollInfo(b),w=(n.collision||"flip").split(" "),k={};return _=s(v),v[0].preventDefault&&(n.at="left top"),p=_.width,f=_.height,g=_.offset,m=t.extend({},g),t.each(["my","at"],function(){var t,e,i=(n[this]||"").split(" ");1===i.length&&(i=r.test(i[0])?i.concat(["center"]):h.test(i[0])?["center"].concat(i):["center","center"]),i[0]=r.test(i[0])?i[0]:"center",i[1]=h.test(i[1])?i[1]:"center",t=l.exec(i[0]),e=l.exec(i[1]),k[this]=[t?t[0]:0,e?e[0]:0],n[this]=[c.exec(i[0])[0],c.exec(i[1])[0]]}),1===w.length&&(w[1]=w[0]),"right"===n.at[0]?m.left+=p:"center"===n.at[0]&&(m.left+=p/2),"bottom"===n.at[1]?m.top+=f:"center"===n.at[1]&&(m.top+=f/2),u=e(k.at,p,f),m.left+=u[0],m.top+=u[1],this.each(function(){var s,r,h=t(this),l=h.outerWidth(),c=h.outerHeight(),d=i(this,"marginLeft"),_=i(this,"marginTop"),x=l+d+i(this,"marginRight")+y.width,C=c+_+i(this,"marginBottom")+y.height,D=t.extend({},m),I=e(k.my,h.outerWidth(),h.outerHeight());"right"===n.my[0]?D.left-=l:"center"===n.my[0]&&(D.left-=l/2),"bottom"===n.my[1]?D.top-=c:"center"===n.my[1]&&(D.top-=c/2),D.left+=I[0],D.top+=I[1],s={marginLeft:d,marginTop:_},t.each(["left","top"],function(e,i){t.ui.position[w[e]]&&t.ui.position[w[e]][i](D,{targetWidth:p,targetHeight:f,elemWidth:l,elemHeight:c,collisionPosition:s,collisionWidth:x,collisionHeight:C,offset:[u[0]+I[0],u[1]+I[1]],my:n.my,at:n.at,within:b,elem:h})}),n.using&&(r=function(t){var e=g.left-D.left,i=e+p-l,s=g.top-D.top,r=s+f-c,u={target:{element:v,left:g.left,top:g.top,width:p,height:f},element:{element:h,left:D.left,top:D.top,width:l,height:c},horizontal:0>i?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-h,(i>0||u>a(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}});var c="ui-effects-",u="ui-effects-style",d="ui-effects-animated",p=t;t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:t>s.max?s.max:t)}function s(i){var s=l(),n=s._rgba=[];return i=i.toLowerCase(),f(h,function(t,o){var a,r=o.re.exec(i),h=r&&o.parse(r),l=o.space||"rgba";return h?(a=s[l](h),s[c[l].cache]=a[c[l].cache],n=s._rgba=a._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,o.transparent),s):o[i]}function n(t,e,i){return i=(i+1)%1,1>6*i?t+6*(e-t)*i:1>2*i?e:2>3*i?t+6*(e-t)*(2/3-i):t}var o,a="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],l=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=l.support={},p=t("<p>")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(c,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),l.fn=t.extend(l.prototype,{parse:function(n,a,r,h){if(n===e)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=t(n).css(a),a=e);var u=this,d=t.type(n),p=this._rgba=[];return a!==e&&(n=[n,a,r,h],d="array"),"string"===d?this.parse(s(n)||o._default):"array"===d?(f(c.rgba.props,function(t,e){p[e.idx]=i(n[e.idx],e)}),this):"object"===d?(n instanceof l?f(c,function(t,e){n[e.cache]&&(u[e.cache]=n[e.cache].slice())}):f(c,function(e,s){var o=s.cache;f(s.props,function(t,e){if(!u[o]&&s.to){if("alpha"===t||null==n[t])return;u[o]=s.to(u._rgba)}u[o][e.idx]=i(n[t],e,!0)}),u[o]&&0>t.inArray(null,u[o].slice(0,3))&&(u[o][3]=1,s.from&&(u._rgba=s.from(u[o])))}),this):e},is:function(t){var i=l(t),s=!0,n=this;return f(c,function(t,o){var a,r=i[o.cache];return r&&(a=n[o.cache]||o.to&&o.to(n._rgba)||[],f(o.props,function(t,i){return null!=r[i.idx]?s=r[i.idx]===a[i.idx]:e})),s}),s},_space:function(){var t=[],e=this;return f(c,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=l(t),n=s._space(),o=c[n],a=0===this.alpha()?l("transparent"):this,r=a[o.cache]||o.to(a._rgba),h=r.slice();return s=s[o.cache],f(o.props,function(t,n){var o=n.idx,a=r[o],l=s[o],c=u[n.type]||{};null!==l&&(null===a?h[o]=l:(c.mod&&(l-a>c.mod/2?a+=c.mod:a-l>c.mod/2&&(a-=c.mod)),h[o]=i((l-a)*e+a,n)))}),this[n](h)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=l(e)._rgba;return l(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&3>e&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,c.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,n=t[1]/255,o=t[2]/255,a=t[3],r=Math.max(s,n,o),h=Math.min(s,n,o),l=r-h,c=r+h,u=.5*c;return e=h===r?0:s===r?60*(n-o)/l+360:n===r?60*(o-s)/l+120:60*(s-n)/l+240,i=0===l?0:.5>=u?l/c:l/(2-c),[Math.round(e)%360,i,u,null==a?1:a]},c.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],o=t[3],a=.5>=s?s*(1+i):s+i-s*i,r=2*s-a;return[Math.round(255*n(r,a,e+1/3)),Math.round(255*n(r,a,e)),Math.round(255*n(r,a,e-1/3)),o]},f(c,function(s,n){var o=n.props,a=n.cache,h=n.to,c=n.from;l.fn[s]=function(s){if(h&&!this[a]&&(this[a]=h(this._rgba)),s===e)return this[a].slice();var n,r=t.type(s),u="array"===r||"object"===r?s:arguments,d=this[a].slice();return f(o,function(t,e){var s=u["object"===r?t:e.idx];null==s&&(s=d[e.idx]),d[e.idx]=i(s,e)}),c?(n=l(c(d)),n[a]=d,n):l(d)},f(o,function(e,i){l.fn[e]||(l.fn[e]=function(n){var o,a=t.type(n),h="alpha"===e?this._hsla?"hsla":"rgba":s,l=this[h](),c=l[i.idx];return"undefined"===a?c:("function"===a&&(n=n.call(this,c),a=t.type(n)),null==n&&i.empty?this:("string"===a&&(o=r.exec(n),o&&(n=c+parseFloat(o[2])*("+"===o[1]?1:-1))),l[i.idx]=n,this[h](l)))})})}),l.hook=function(e){var i=e.split(" ");f(i,function(e,i){t.cssHooks[i]={set:function(e,n){var o,a,r="";if("transparent"!==n&&("string"!==t.type(n)||(o=s(n)))){if(n=l(o||n),!d.rgba&&1!==n._rgba[3]){for(a="backgroundColor"===i?e.parentNode:e;(""===r||"transparent"===r)&&a&&a.style;)try{r=t.css(a,"backgroundColor"),a=a.parentNode}catch(h){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{e.style[i]=n}catch(h){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=l(e.elem,i),e.end=l(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},l.hook(a),t.cssHooks.borderColor={expand:function(t){var e={};return f(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},o=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(p),function(){function e(e){var i,s,n=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,o={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(o[t.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(o[i]=n[i]);return o}function i(e,i){var s,o,a={};for(s in i)o=i[s],e[s]!==o&&(n[s]||(t.fx.step[s]||!isNaN(parseFloat(o)))&&(a[s]=o));return a}var s=["add","remove","toggle"],n={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(p.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(n,o,a,r){var h=t.speed(o,a,r);return this.queue(function(){var o,a=t(this),r=a.attr("class")||"",l=h.children?a.find("*").addBack():a;l=l.map(function(){var i=t(this);return{el:i,start:e(this)}}),o=function(){t.each(s,function(t,e){n[e]&&a[e+"Class"](n[e])})},o(),l=l.map(function(){return this.end=e(this.el[0]),this.diff=i(this.start,this.end),this}),a.attr("class",r),l=l.map(function(){var e=this,i=t.Deferred(),s=t.extend({},h,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,l.get()).done(function(){o(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),h.complete.call(a[0])})})},t.fn.extend({addClass:function(e){return function(i,s,n,o){return s?t.effects.animateClass.call(this,{add:i},s,n,o):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,n,o){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,n,o):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(e){return function(i,s,n,o,a){return"boolean"==typeof s||void 0===s?n?t.effects.animateClass.call(this,s?{add:i}:{remove:i},n,o,a):e.apply(this,arguments):t.effects.animateClass.call(this,{toggle:i},s,n,o)}}(t.fn.toggleClass),switchClass:function(e,i,s,n,o){return t.effects.animateClass.call(this,{add:i,remove:e},s,n,o)}})}(),function(){function e(e,i,s,n){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(n=s,s=i,i={}),t.isFunction(s)&&(n=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=n||i.complete,e}function i(e){return!e||"number"==typeof e||t.fx.speeds[e]?!0:"string"!=typeof e||t.effects.effect[e]?t.isFunction(e)?!0:"object"!=typeof e||e.effect?!1:!0:!0}function s(t,e){var i=e.outerWidth(),s=e.outerHeight(),n=/^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,o=n.exec(t)||["",0,i,s,0];return{top:parseFloat(o[1])||0,right:"auto"===o[2]?i:parseFloat(o[2]),bottom:"auto"===o[3]?s:parseFloat(o[3]),left:parseFloat(o[4])||0}}t.expr&&t.expr.filters&&t.expr.filters.animated&&(t.expr.filters.animated=function(e){return function(i){return!!t(i).data(d)||e(i)}}(t.expr.filters.animated)),t.uiBackCompat!==!1&&t.extend(t.effects,{save:function(t,e){for(var i=0,s=e.length;s>i;i++)null!==e[i]&&t.data(c+e[i],t[0].style[e[i]])},restore:function(t,e){for(var i,s=0,n=e.length;n>s;s++)null!==e[s]&&(i=t.data(c+e[s]),t.css(e[s],i))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),"float":e.css("float")},s=t("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},o=document.activeElement;try{o.id}catch(a){o=document.body}return e.wrap(s),(e[0]===o||t.contains(e[0],o))&&t(o).trigger("focus"),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).trigger("focus")),e}}),t.extend(t.effects,{version:"1.12.1",define:function(e,i,s){return s||(s=i,i="effect"),t.effects.effect[e]=s,t.effects.effect[e].mode=i,s},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,n="vertical"!==i?(e||100)/100:1;return{height:t.height()*n,width:t.width()*s,outerHeight:t.outerHeight()*n,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();e>1&&s.splice.apply(s,[1,0].concat(s.splice(e,i))),t.dequeue()},saveStyle:function(t){t.data(u,t[0].style.cssText)},restoreStyle:function(t){t[0].style.cssText=t.data(u)||"",t.removeData(u)},mode:function(t,e){var i=t.is(":hidden");return"toggle"===e&&(e=i?"show":"hide"),(i?"hide"===e:"show"===e)&&(e="none"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createPlaceholder:function(e){var i,s=e.css("position"),n=e.position();return e.css({marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()),/^(static|relative)/.test(s)&&(s="absolute",i=t("<"+e[0].nodeName+">").insertAfter(e).css({display:/^(inline|ruby)/.test(e.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight"),"float":e.css("float")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).addClass("ui-effects-placeholder"),e.data(c+"placeholder",i)),e.css({position:s,left:n.left,top:n.top}),i},removePlaceholder:function(t){var e=c+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(e){t.effects.restoreStyle(e),t.effects.removePlaceholder(e)},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var o=e.cssUnit(i);o[0]>0&&(n[i]=o[0]*s+o[1])}),n}}),t.fn.extend({effect:function(){function i(e){function i(){r.removeData(d),t.effects.cleanUp(r),"hide"===s.mode&&r.hide(),a()}function a(){t.isFunction(h)&&h.call(r[0]),t.isFunction(e)&&e()}var r=t(this);s.mode=c.shift(),t.uiBackCompat===!1||o?"none"===s.mode?(r[l](),a()):n.call(r[0],s,i):(r.is(":hidden")?"hide"===l:"show"===l)?(r[l](),a()):n.call(r[0],s,a)}var s=e.apply(this,arguments),n=t.effects.effect[s.effect],o=n.mode,a=s.queue,r=a||"fx",h=s.complete,l=s.mode,c=[],u=function(e){var i=t(this),s=t.effects.mode(i,l)||o;i.data(d,!0),c.push(s),o&&("show"===s||s===o&&"hide"===s)&&i.show(),o&&"none"===s||t.effects.saveStyle(i),t.isFunction(e)&&e()};return t.fx.off||!n?l?this[l](s.duration,h):this.each(function(){h&&h.call(this)}):a===!1?this.each(u).each(i):this.queue(r,u).queue(r,i)},show:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="show",this.effect.call(this,n) +}}(t.fn.show),hide:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="hide",this.effect.call(this,n)}}(t.fn.hide),toggle:function(t){return function(s){if(i(s)||"boolean"==typeof s)return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s},cssClip:function(t){return t?this.css("clip","rect("+t.top+"px "+t.right+"px "+t.bottom+"px "+t.left+"px)"):s(this.css("clip"),this)},transfer:function(e,i){var s=t(this),n=t(e.to),o="fixed"===n.css("position"),a=t("body"),r=o?a.scrollTop():0,h=o?a.scrollLeft():0,l=n.offset(),c={top:l.top-r,left:l.left-h,height:n.innerHeight(),width:n.innerWidth()},u=s.offset(),d=t("<div class='ui-effects-transfer'></div>").appendTo("body").addClass(e.className).css({top:u.top-r,left:u.left-h,height:s.innerHeight(),width:s.innerWidth(),position:o?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){d.remove(),t.isFunction(i)&&i()})}}),t.fx.step.clip=function(e){e.clipInit||(e.start=t(e.elem).cssClip(),"string"==typeof e.end&&(e.end=s(e.end,e.elem)),e.clipInit=!0),t(e.elem).cssClip({top:e.pos*(e.end.top-e.start.top)+e.start.top,right:e.pos*(e.end.right-e.start.right)+e.start.right,bottom:e.pos*(e.end.bottom-e.start.bottom)+e.start.bottom,left:e.pos*(e.end.left-e.start.left)+e.start.left})}}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return.5>t?i(2*t)/2:1-i(-2*t+2)/2}})}();var f=t.effects;t.effects.define("blind","hide",function(e,i){var s={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},n=t(this),o=e.direction||"up",a=n.cssClip(),r={clip:t.extend({},a)},h=t.effects.createPlaceholder(n);r.clip[s[o][0]]=r.clip[s[o][1]],"show"===e.mode&&(n.cssClip(r.clip),h&&h.css(t.effects.clipToBox(r)),r.clip=a),h&&h.animate(t.effects.clipToBox(r),e.duration,e.easing),n.animate(r,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("bounce",function(e,i){var s,n,o,a=t(this),r=e.mode,h="hide"===r,l="show"===r,c=e.direction||"up",u=e.distance,d=e.times||5,p=2*d+(l||h?1:0),f=e.duration/p,g=e.easing,m="up"===c||"down"===c?"top":"left",_="up"===c||"left"===c,v=0,b=a.queue().length;for(t.effects.createPlaceholder(a),o=a.css(m),u||(u=a["top"===m?"outerHeight":"outerWidth"]()/3),l&&(n={opacity:1},n[m]=o,a.css("opacity",0).css(m,_?2*-u:2*u).animate(n,f,g)),h&&(u/=Math.pow(2,d-1)),n={},n[m]=o;d>v;v++)s={},s[m]=(_?"-=":"+=")+u,a.animate(s,f,g).animate(n,f,g),u=h?2*u:u/2;h&&(s={opacity:0},s[m]=(_?"-=":"+=")+u,a.animate(s,f,g)),a.queue(i),t.effects.unshift(a,b,p+1)}),t.effects.define("clip","hide",function(e,i){var s,n={},o=t(this),a=e.direction||"vertical",r="both"===a,h=r||"horizontal"===a,l=r||"vertical"===a;s=o.cssClip(),n.clip={top:l?(s.bottom-s.top)/2:s.top,right:h?(s.right-s.left)/2:s.right,bottom:l?(s.bottom-s.top)/2:s.bottom,left:h?(s.right-s.left)/2:s.left},t.effects.createPlaceholder(o),"show"===e.mode&&(o.cssClip(n.clip),n.clip=s),o.animate(n,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("drop","hide",function(e,i){var s,n=t(this),o=e.mode,a="show"===o,r=e.direction||"left",h="up"===r||"down"===r?"top":"left",l="up"===r||"left"===r?"-=":"+=",c="+="===l?"-=":"+=",u={opacity:0};t.effects.createPlaceholder(n),s=e.distance||n["top"===h?"outerHeight":"outerWidth"](!0)/2,u[h]=l+s,a&&(n.css(u),u[h]=c+s,u.opacity=1),n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("explode","hide",function(e,i){function s(){b.push(this),b.length===u*d&&n()}function n(){p.css({visibility:"visible"}),t(b).remove(),i()}var o,a,r,h,l,c,u=e.pieces?Math.round(Math.sqrt(e.pieces)):3,d=u,p=t(this),f=e.mode,g="show"===f,m=p.show().css("visibility","hidden").offset(),_=Math.ceil(p.outerWidth()/d),v=Math.ceil(p.outerHeight()/u),b=[];for(o=0;u>o;o++)for(h=m.top+o*v,c=o-(u-1)/2,a=0;d>a;a++)r=m.left+a*_,l=a-(d-1)/2,p.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-a*_,top:-o*v}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:_,height:v,left:r+(g?l*_:0),top:h+(g?c*v:0),opacity:g?0:1}).animate({left:r+(g?0:l*_),top:h+(g?0:c*v),opacity:g?1:0},e.duration||500,e.easing,s)}),t.effects.define("fade","toggle",function(e,i){var s="show"===e.mode;t(this).css("opacity",s?0:1).animate({opacity:s?1:0},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("fold","hide",function(e,i){var s=t(this),n=e.mode,o="show"===n,a="hide"===n,r=e.size||15,h=/([0-9]+)%/.exec(r),l=!!e.horizFirst,c=l?["right","bottom"]:["bottom","right"],u=e.duration/2,d=t.effects.createPlaceholder(s),p=s.cssClip(),f={clip:t.extend({},p)},g={clip:t.extend({},p)},m=[p[c[0]],p[c[1]]],_=s.queue().length;h&&(r=parseInt(h[1],10)/100*m[a?0:1]),f.clip[c[0]]=r,g.clip[c[0]]=r,g.clip[c[1]]=0,o&&(s.cssClip(g.clip),d&&d.css(t.effects.clipToBox(g)),g.clip=p),s.queue(function(i){d&&d.animate(t.effects.clipToBox(f),u,e.easing).animate(t.effects.clipToBox(g),u,e.easing),i()}).animate(f,u,e.easing).animate(g,u,e.easing).queue(i),t.effects.unshift(s,_,4)}),t.effects.define("highlight","show",function(e,i){var s=t(this),n={backgroundColor:s.css("backgroundColor")};"hide"===e.mode&&(n.opacity=0),t.effects.saveStyle(s),s.css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(n,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("size",function(e,i){var s,n,o,a=t(this),r=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],l=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],c=e.mode,u="effect"!==c,d=e.scale||"both",p=e.origin||["middle","center"],f=a.css("position"),g=a.position(),m=t.effects.scaledDimensions(a),_=e.from||m,v=e.to||t.effects.scaledDimensions(a,0);t.effects.createPlaceholder(a),"show"===c&&(o=_,_=v,v=o),n={from:{y:_.height/m.height,x:_.width/m.width},to:{y:v.height/m.height,x:v.width/m.width}},("box"===d||"both"===d)&&(n.from.y!==n.to.y&&(_=t.effects.setTransition(a,h,n.from.y,_),v=t.effects.setTransition(a,h,n.to.y,v)),n.from.x!==n.to.x&&(_=t.effects.setTransition(a,l,n.from.x,_),v=t.effects.setTransition(a,l,n.to.x,v))),("content"===d||"both"===d)&&n.from.y!==n.to.y&&(_=t.effects.setTransition(a,r,n.from.y,_),v=t.effects.setTransition(a,r,n.to.y,v)),p&&(s=t.effects.getBaseline(p,m),_.top=(m.outerHeight-_.outerHeight)*s.y+g.top,_.left=(m.outerWidth-_.outerWidth)*s.x+g.left,v.top=(m.outerHeight-v.outerHeight)*s.y+g.top,v.left=(m.outerWidth-v.outerWidth)*s.x+g.left),a.css(_),("content"===d||"both"===d)&&(h=h.concat(["marginTop","marginBottom"]).concat(r),l=l.concat(["marginLeft","marginRight"]),a.find("*[width]").each(function(){var i=t(this),s=t.effects.scaledDimensions(i),o={height:s.height*n.from.y,width:s.width*n.from.x,outerHeight:s.outerHeight*n.from.y,outerWidth:s.outerWidth*n.from.x},a={height:s.height*n.to.y,width:s.width*n.to.x,outerHeight:s.height*n.to.y,outerWidth:s.width*n.to.x};n.from.y!==n.to.y&&(o=t.effects.setTransition(i,h,n.from.y,o),a=t.effects.setTransition(i,h,n.to.y,a)),n.from.x!==n.to.x&&(o=t.effects.setTransition(i,l,n.from.x,o),a=t.effects.setTransition(i,l,n.to.x,a)),u&&t.effects.saveStyle(i),i.css(o),i.animate(a,e.duration,e.easing,function(){u&&t.effects.restoreStyle(i)})})),a.animate(v,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){var e=a.offset();0===v.opacity&&a.css("opacity",_.opacity),u||(a.css("position","static"===f?"relative":f).offset(e),t.effects.saveStyle(a)),i()}})}),t.effects.define("scale",function(e,i){var s=t(this),n=e.mode,o=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"effect"!==n?0:100),a=t.extend(!0,{from:t.effects.scaledDimensions(s),to:t.effects.scaledDimensions(s,o,e.direction||"both"),origin:e.origin||["middle","center"]},e);e.fade&&(a.from.opacity=1,a.to.opacity=0),t.effects.effect.size.call(this,a,i)}),t.effects.define("puff","hide",function(e,i){var s=t.extend(!0,{},e,{fade:!0,percent:parseInt(e.percent,10)||150});t.effects.effect.scale.call(this,s,i)}),t.effects.define("pulsate","show",function(e,i){var s=t(this),n=e.mode,o="show"===n,a="hide"===n,r=o||a,h=2*(e.times||5)+(r?1:0),l=e.duration/h,c=0,u=1,d=s.queue().length;for((o||!s.is(":visible"))&&(s.css("opacity",0).show(),c=1);h>u;u++)s.animate({opacity:c},l,e.easing),c=1-c;s.animate({opacity:c},l,e.easing),s.queue(i),t.effects.unshift(s,d,h+1)}),t.effects.define("shake",function(e,i){var s=1,n=t(this),o=e.direction||"left",a=e.distance||20,r=e.times||3,h=2*r+1,l=Math.round(e.duration/h),c="up"===o||"down"===o?"top":"left",u="up"===o||"left"===o,d={},p={},f={},g=n.queue().length;for(t.effects.createPlaceholder(n),d[c]=(u?"-=":"+=")+a,p[c]=(u?"+=":"-=")+2*a,f[c]=(u?"-=":"+=")+2*a,n.animate(d,l,e.easing);r>s;s++)n.animate(p,l,e.easing).animate(f,l,e.easing);n.animate(p,l,e.easing).animate(d,l/2,e.easing).queue(i),t.effects.unshift(n,g,h+1)}),t.effects.define("slide","show",function(e,i){var s,n,o=t(this),a={up:["bottom","top"],down:["top","bottom"],left:["right","left"],right:["left","right"]},r=e.mode,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h,u=e.distance||o["top"===l?"outerHeight":"outerWidth"](!0),d={};t.effects.createPlaceholder(o),s=o.cssClip(),n=o.position()[l],d[l]=(c?-1:1)*u+n,d.clip=o.cssClip(),d.clip[a[h][1]]=d.clip[a[h][0]],"show"===r&&(o.cssClip(d.clip),o.css(l,d[l]),d.clip=s,d[l]=n),o.animate(d,{queue:!1,duration:e.duration,easing:e.easing,complete:i})});var f;t.uiBackCompat!==!1&&(f=t.effects.define("transfer",function(e,i){t(this).transfer(e,i)})),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,.\/:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.widget("ui.accordion",{version:"1.12.1",options:{active:0,animate:{},classes:{"ui-accordion-header":"ui-corner-top","ui-accordion-header-collapsed":"ui-corner-all","ui-accordion-content":"ui-corner-bottom"},collapsible:!1,event:"click",header:"> li > :first-child, > :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var e=this.options;this.prevShow=this.prevHide=t(),this._addClass("ui-accordion","ui-widget ui-helper-reset"),this.element.attr("role","tablist"),e.collapsible||e.active!==!1&&null!=e.active||(e.active=0),this._processPanels(),0>e.active&&(e.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():t()}},_createIcons:function(){var e,i,s=this.options.icons;s&&(e=t("<span>"),this._addClass(e,"ui-accordion-header-icon","ui-icon "+s.header),e.prependTo(this.headers),i=this.active.children(".ui-accordion-header-icon"),this._removeClass(i,s.header)._addClass(i,null,s.activeHeader)._addClass(this.headers,"ui-accordion-icons"))},_destroyIcons:function(){this._removeClass(this.headers,"ui-accordion-icons"),this.headers.children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeAttr("role"),this.headers.removeAttr("role aria-expanded aria-selected aria-controls tabIndex").removeUniqueId(),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role aria-hidden aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){return"active"===t?(this._activate(e),void 0):("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||this.options.active!==!1||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons()),void 0)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t),this._toggleClass(this.headers.add(this.headers.next()),null,"ui-state-disabled",!!t)},_keydown:function(e){if(!e.altKey&&!e.ctrlKey){var i=t.ui.keyCode,s=this.headers.length,n=this.headers.index(e.target),o=!1;switch(e.keyCode){case i.RIGHT:case i.DOWN:o=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:o=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(e);break;case i.HOME:o=this.headers[0];break;case i.END:o=this.headers[s-1]}o&&(t(e.target).attr("tabIndex",-1),t(o).attr("tabIndex",0),t(o).trigger("focus"),e.preventDefault())}},_panelKeyDown:function(e){e.keyCode===t.ui.keyCode.UP&&e.ctrlKey&&t(e.currentTarget).prev().trigger("focus")},refresh:function(){var e=this.options;this._processPanels(),e.active===!1&&e.collapsible===!0||!this.headers.length?(e.active=!1,this.active=t()):e.active===!1?this._activate(0):this.active.length&&!t.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(e.active=!1,this.active=t()):this._activate(Math.max(0,e.active-1)):e.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var t=this.headers,e=this.panels;this.headers=this.element.find(this.options.header),this._addClass(this.headers,"ui-accordion-header ui-accordion-header-collapsed","ui-state-default"),this.panels=this.headers.next().filter(":not(.ui-accordion-content-active)").hide(),this._addClass(this.panels,"ui-accordion-content","ui-helper-reset ui-widget-content"),e&&(this._off(t.not(this.headers)),this._off(e.not(this.panels)))},_refresh:function(){var e,i=this.options,s=i.heightStyle,n=this.element.parent();this.active=this._findActive(i.active),this._addClass(this.active,"ui-accordion-header-active","ui-state-active")._removeClass(this.active,"ui-accordion-header-collapsed"),this._addClass(this.active.next(),"ui-accordion-content-active"),this.active.next().show(),this.headers.attr("role","tab").each(function(){var e=t(this),i=e.uniqueId().attr("id"),s=e.next(),n=s.uniqueId().attr("id");e.attr("aria-controls",n),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(i.event),"fill"===s?(e=n.height(),this.element.siblings(":visible").each(function(){var i=t(this),s=i.css("position");"absolute"!==s&&"fixed"!==s&&(e-=i.outerHeight(!0))}),this.headers.each(function(){e-=t(this).outerHeight(!0)}),this.headers.next().each(function(){t(this).height(Math.max(0,e-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===s&&(e=0,this.headers.next().each(function(){var i=t(this).is(":visible");i||t(this).show(),e=Math.max(e,t(this).css("height","").height()),i||t(this).hide()}).height(e))},_activate:function(e){var i=this._findActive(e)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return"number"==typeof e?this.headers.eq(e):t()},_setupEvents:function(e){var i={keydown:"_keydown"};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(e){var i,s,n=this.options,o=this.active,a=t(e.currentTarget),r=a[0]===o[0],h=r&&n.collapsible,l=h?t():a.next(),c=o.next(),u={oldHeader:o,oldPanel:c,newHeader:h?t():a,newPanel:l};e.preventDefault(),r&&!n.collapsible||this._trigger("beforeActivate",e,u)===!1||(n.active=h?!1:this.headers.index(a),this.active=r?t():a,this._toggle(u),this._removeClass(o,"ui-accordion-header-active","ui-state-active"),n.icons&&(i=o.children(".ui-accordion-header-icon"),this._removeClass(i,null,n.icons.activeHeader)._addClass(i,null,n.icons.header)),r||(this._removeClass(a,"ui-accordion-header-collapsed")._addClass(a,"ui-accordion-header-active","ui-state-active"),n.icons&&(s=a.children(".ui-accordion-header-icon"),this._removeClass(s,null,n.icons.header)._addClass(s,null,n.icons.activeHeader)),this._addClass(a.next(),"ui-accordion-content-active")))},_toggle:function(e){var i=e.newPanel,s=this.prevShow.length?this.prevShow:e.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,e):(s.hide(),i.show(),this._toggleComplete(e)),s.attr({"aria-hidden":"true"}),s.prev().attr({"aria-selected":"false","aria-expanded":"false"}),i.length&&s.length?s.prev().attr({tabIndex:-1,"aria-expanded":"false"}):i.length&&this.headers.filter(function(){return 0===parseInt(t(this).attr("tabIndex"),10)}).attr("tabIndex",-1),i.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(t,e,i){var s,n,o,a=this,r=0,h=t.css("box-sizing"),l=t.length&&(!e.length||t.index()<e.index()),c=this.options.animate||{},u=l&&c.down||c,d=function(){a._toggleComplete(i)};return"number"==typeof u&&(o=u),"string"==typeof u&&(n=u),n=n||u.easing||c.easing,o=o||u.duration||c.duration,e.length?t.length?(s=t.show().outerHeight(),e.animate(this.hideProps,{duration:o,easing:n,step:function(t,e){e.now=Math.round(t)}}),t.hide().animate(this.showProps,{duration:o,easing:n,complete:d,step:function(t,i){i.now=Math.round(t),"height"!==i.prop?"content-box"===h&&(r+=i.now):"content"!==a.options.heightStyle&&(i.now=Math.round(s-e.outerHeight()-r),r=0)}}),void 0):e.animate(this.hideProps,o,n,d):t.animate(this.showProps,o,n,d)},_toggleComplete:function(t){var e=t.oldPanel,i=e.prev();this._removeClass(e,"ui-accordion-content-active"),this._removeClass(i,"ui-accordion-header-active")._addClass(i,"ui-accordion-header-collapsed"),e.length&&(e.parent()[0].className=e.parent()[0].className),this._trigger("activate",null,t)}}),t.ui.safeActiveElement=function(t){var e;try{e=t.activeElement}catch(i){e=t.body}return e||(e=t.body),e.nodeName||(e=t.body),e},t.widget("ui.menu",{version:"1.12.1",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault()},"click .ui-menu-item":function(e){var i=t(e.target),s=t(t.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(e),e.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(e):!this.element.is(":focus")&&s.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){if(!this.previousFilter){var i=t(e.target).closest(".ui-menu-item"),s=t(e.currentTarget);i[0]===s[0]&&(this._removeClass(s.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(e,s))}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.find(this.options.items).eq(0);e||this.focus(t,i)},blur:function(e){this._delay(function(){var i=!t.contains(this.element[0],t.ui.safeActiveElement(this.document[0]));i&&this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t),this.mouseHandled=!1}})},_destroy:function(){var e=this.element.find(".ui-menu-item").removeAttr("role aria-disabled"),i=e.children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),i.children().each(function(){var e=t(this);e.data("ui-menu-submenu-caret")&&e.remove()})},_keydown:function(e){var i,s,n,o,a=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:a=!1,s=this.previousFilter||"",o=!1,n=e.keyCode>=96&&105>=e.keyCode?""+(e.keyCode-96):String.fromCharCode(e.keyCode),clearTimeout(this.filterTimer),n===s?o=!0:n=s+n,i=this._filterMenuItems(n),i=o&&-1!==i.index(this.active.next())?this.active.nextAll(".ui-menu-item"):i,i.length||(n=String.fromCharCode(e.keyCode),i=this._filterMenuItems(n)),i.length?(this.focus(e,i),this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}a&&e.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var e,i,s,n,o,a=this,r=this.options.icons.submenu,h=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),s=h.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),i=e.prev(),s=t("<span>").data("ui-menu-submenu-caret",!0);a._addClass(s,"ui-menu-icon","ui-icon "+r),i.attr("aria-haspopup","true").prepend(s),e.attr("aria-labelledby",i.attr("id"))}),this._addClass(s,"ui-menu","ui-widget ui-widget-content ui-front"),e=h.add(this.element),i=e.find(this.options.items),i.not(".ui-menu-item").each(function(){var e=t(this);a._isDivider(e)&&a._addClass(e,"ui-menu-divider","ui-widget-content")}),n=i.not(".ui-menu-item, .ui-menu-divider"),o=n.children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(n,"ui-menu-item")._addClass(o,"ui-menu-item-wrapper"),i.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){if("icons"===t){var i=this.element.find(".ui-menu-icon");this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)}this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t+""),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i,s,n;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children(".ui-menu-item-wrapper"),this._addClass(s,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),n=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(n,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=e.children(".ui-menu"),i.length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var i,s,n,o,a,r;this._hasScroll()&&(i=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,n=e.offset().top-this.activeMenu.offset().top-i-s,o=this.activeMenu.scrollTop(),a=this.activeMenu.height(),r=e.outerHeight(),0>n?this.activeMenu.scrollTop(o+n):n+r>a&&this.activeMenu.scrollTop(o+n-a+r))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this._removeClass(this.active.children(".ui-menu-item-wrapper"),null,"ui-state-active"),this._trigger("blur",t,{item:this.active}),this.active=null)},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(e){var i=t.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true"),e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:t(e&&e.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(e),this._removeClass(s.find(".ui-state-active"),null,"ui-state-active"),this.activeMenu=s},this.delay)},_close:function(t){t||(t=this.active?this.active.parent():this.element),t.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false")},_closeOnDocumentClick:function(e){return!t(e.target).closest(".ui-menu").length},_isDivider:function(t){return!/[^\-\u2014\u2013\s]/.test(t.text())},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,i){var s;this.active&&(s="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.find(this.options.items)[e]()),this.focus(i,s)},nextPage:function(e){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=t(this),0>i.offset().top-s-n}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items)[this.active?"last":"first"]())),void 0):(this.next(e),void 0)},previousPage:function(e){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=t(this),i.offset().top-s+n>0}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items).first())),void 0):(this.next(e),void 0)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(e){this.active=this.active||t(e.target).closest(".ui-menu-item");var i={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(e,!0),this._trigger("select",e,i)},_filterMenuItems:function(e){var i=e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&"),s=RegExp("^"+i,"i");return this.activeMenu.find(this.options.items).filter(".ui-menu-item").filter(function(){return s.test(t.trim(t(this).children(".ui-menu-item-wrapper").text()))})}}),t.widget("ui.autocomplete",{version:"1.12.1",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var e,i,s,n=this.element[0].nodeName.toLowerCase(),o="textarea"===n,a="input"===n; +this.isMultiLine=o||!a&&this._isContentEditable(this.element),this.valueMethod=this.element[o||a?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return e=!0,s=!0,i=!0,void 0;e=!1,s=!1,i=!1;var o=t.ui.keyCode;switch(n.keyCode){case o.PAGE_UP:e=!0,this._move("previousPage",n);break;case o.PAGE_DOWN:e=!0,this._move("nextPage",n);break;case o.UP:e=!0,this._keyEvent("previous",n);break;case o.DOWN:e=!0,this._keyEvent("next",n);break;case o.ENTER:this.menu.active&&(e=!0,n.preventDefault(),this.menu.select(n));break;case o.TAB:this.menu.active&&this.menu.select(n);break;case o.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(e)return e=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),void 0;if(!i){var n=t.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(t){return s?(s=!1,t.preventDefault(),void 0):(this._searchTimeout(t),void 0)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(clearTimeout(this.searching),this.close(t),this._change(t),void 0)}}),this._initSource(),this.menu=t("<ul>").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(e){e.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,this.element[0]!==t.ui.safeActiveElement(this.document[0])&&this.element.trigger("focus")})},menufocus:function(e,i){var s,n;return this.isNewMenu&&(this.isNewMenu=!1,e.originalEvent&&/^mouse/.test(e.originalEvent.type))?(this.menu.blur(),this.document.one("mousemove",function(){t(e.target).trigger(e.originalEvent)}),void 0):(n=i.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",e,{item:n})&&e.originalEvent&&/^key/.test(e.originalEvent.type)&&this._value(n.value),s=i.item.attr("aria-label")||n.value,s&&t.trim(s).length&&(this.liveRegion.children().hide(),t("<div>").text(s).appendTo(this.liveRegion)),void 0)},menuselect:function(e,i){var s=i.item.data("ui-autocomplete-item"),n=this.previous;this.element[0]!==t.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=n,this._delay(function(){this.previous=n,this.selectedItem=s})),!1!==this._trigger("select",e,{item:s})&&this._value(s.value),this.term=this._value(),this.close(e),this.selectedItem=s}}),this.liveRegion=t("<div>",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(e){var i=this.menu.element[0];return e.target===this.element[0]||e.target===i||t.contains(i,e.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e&&e[0]||(e=this.element.closest(".ui-front, dialog")),e.length||(e=this.document[0].body),e},_initSource:function(){var e,i,s=this;t.isArray(this.options.source)?(e=this.options.source,this.source=function(i,s){s(t.ui.autocomplete.filter(e,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(e,n){s.xhr&&s.xhr.abort(),s.xhr=t.ajax({url:i,data:e,dataType:"json",success:function(t){n(t)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(t){clearTimeout(this.searching),this.searching=this._delay(function(){var e=this.term===this._value(),i=this.menu.element.is(":visible"),s=t.altKey||t.ctrlKey||t.metaKey||t.shiftKey;(!e||e&&!i&&!s)&&(this.selectedItem=null,this.search(null,t))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length<this.options.minLength?this.close(e):this._trigger("search",e)!==!1?this._search(t):void 0},_search:function(t){this.pending++,this._addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:t},this._response())},_response:function(){var e=++this.requestIndex;return t.proxy(function(t){e===this.requestIndex&&this.__response(t),this.pending--,this.pending||this._removeClass("ui-autocomplete-loading")},this)},__response:function(t){t&&(t=this._normalize(t)),this._trigger("response",null,{content:t}),!this.options.disabled&&t&&t.length&&!this.cancelSearch?(this._suggest(t),this._trigger("open")):this._close()},close:function(t){this.cancelSearch=!0,this._close(t)},_close:function(t){this._off(this.document,"mousedown"),this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",t))},_change:function(t){this.previous!==this._value()&&this._trigger("change",t,{item:this.selectedItem})},_normalize:function(e){return e.length&&e[0].label&&e[0].value?e:t.map(e,function(e){return"string"==typeof e?{label:e,value:e}:t.extend({},e,{label:e.label||e.value,value:e.value||e.label})})},_suggest:function(e){var i=this.menu.element.empty();this._renderMenu(i,e),this.isNewMenu=!0,this.menu.refresh(),i.show(),this._resizeMenu(),i.position(t.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next(),this._on(this.document,{mousedown:"_closeOnClickOutside"})},_resizeMenu:function(){var t=this.menu.element;t.outerWidth(Math.max(t.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(e,i){var s=this;t.each(i,function(t,i){s._renderItemData(e,i)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-autocomplete-item",e)},_renderItem:function(e,i){return t("<li>").append(t("<div>").text(i.label)).appendTo(e)},_move:function(t,e){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),this.menu.blur(),void 0):(this.menu[t](e),void 0):(this.search(null,e),void 0)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),t.extend(t.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(e,i){var s=RegExp(t.ui.autocomplete.escapeRegex(i),"i");return t.grep(e,function(t){return s.test(t.label||t.value||t)})}}),t.widget("ui.autocomplete",t.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(t>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(e){var i;this._superApply(arguments),this.options.disabled||this.cancelSearch||(i=e&&e.length?this.options.messages.results(e.length):this.options.messages.noResults,this.liveRegion.children().hide(),t("<div>").text(i).appendTo(this.liveRegion))}}),t.ui.autocomplete;var g=/ui-corner-([a-z]){2,6}/g;t.widget("ui.controlgroup",{version:"1.12.1",defaultElement:"<div>",options:{direction:"horizontal",disabled:null,onlyVisible:!0,items:{button:"input[type=button], input[type=submit], input[type=reset], button, a",controlgroupLabel:".ui-controlgroup-label",checkboxradio:"input[type='checkbox'], input[type='radio']",selectmenu:"select",spinner:".ui-spinner-input"}},_create:function(){this._enhance()},_enhance:function(){this.element.attr("role","toolbar"),this.refresh()},_destroy:function(){this._callChildMethod("destroy"),this.childWidgets.removeData("ui-controlgroup-data"),this.element.removeAttr("role"),this.options.items.controlgroupLabel&&this.element.find(this.options.items.controlgroupLabel).find(".ui-controlgroup-label-contents").contents().unwrap()},_initWidgets:function(){var e=this,i=[];t.each(this.options.items,function(s,n){var o,a={};return n?"controlgroupLabel"===s?(o=e.element.find(n),o.each(function(){var e=t(this);e.children(".ui-controlgroup-label-contents").length||e.contents().wrapAll("<span class='ui-controlgroup-label-contents'></span>")}),e._addClass(o,null,"ui-widget ui-widget-content ui-state-default"),i=i.concat(o.get()),void 0):(t.fn[s]&&(a=e["_"+s+"Options"]?e["_"+s+"Options"]("middle"):{classes:{}},e.element.find(n).each(function(){var n=t(this),o=n[s]("instance"),r=t.widget.extend({},a);if("button"!==s||!n.parent(".ui-spinner").length){o||(o=n[s]()[s]("instance")),o&&(r.classes=e._resolveClassesValues(r.classes,o)),n[s](r);var h=n[s]("widget");t.data(h[0],"ui-controlgroup-data",o?o:n[s]("instance")),i.push(h[0])}})),void 0):void 0}),this.childWidgets=t(t.unique(i)),this._addClass(this.childWidgets,"ui-controlgroup-item")},_callChildMethod:function(e){this.childWidgets.each(function(){var i=t(this),s=i.data("ui-controlgroup-data");s&&s[e]&&s[e]()})},_updateCornerClass:function(t,e){var i="ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all",s=this._buildSimpleOptions(e,"label").classes.label;this._removeClass(t,null,i),this._addClass(t,null,s)},_buildSimpleOptions:function(t,e){var i="vertical"===this.options.direction,s={classes:{}};return s.classes[e]={middle:"",first:"ui-corner-"+(i?"top":"left"),last:"ui-corner-"+(i?"bottom":"right"),only:"ui-corner-all"}[t],s},_spinnerOptions:function(t){var e=this._buildSimpleOptions(t,"ui-spinner");return e.classes["ui-spinner-up"]="",e.classes["ui-spinner-down"]="",e},_buttonOptions:function(t){return this._buildSimpleOptions(t,"ui-button")},_checkboxradioOptions:function(t){return this._buildSimpleOptions(t,"ui-checkboxradio-label")},_selectmenuOptions:function(t){var e="vertical"===this.options.direction;return{width:e?"auto":!1,classes:{middle:{"ui-selectmenu-button-open":"","ui-selectmenu-button-closed":""},first:{"ui-selectmenu-button-open":"ui-corner-"+(e?"top":"tl"),"ui-selectmenu-button-closed":"ui-corner-"+(e?"top":"left")},last:{"ui-selectmenu-button-open":e?"":"ui-corner-tr","ui-selectmenu-button-closed":"ui-corner-"+(e?"bottom":"right")},only:{"ui-selectmenu-button-open":"ui-corner-top","ui-selectmenu-button-closed":"ui-corner-all"}}[t]}},_resolveClassesValues:function(e,i){var s={};return t.each(e,function(n){var o=i.options.classes[n]||"";o=t.trim(o.replace(g,"")),s[n]=(o+" "+e[n]).replace(/\s+/g," ")}),s},_setOption:function(t,e){return"direction"===t&&this._removeClass("ui-controlgroup-"+this.options.direction),this._super(t,e),"disabled"===t?(this._callChildMethod(e?"disable":"enable"),void 0):(this.refresh(),void 0)},refresh:function(){var e,i=this;this._addClass("ui-controlgroup ui-controlgroup-"+this.options.direction),"horizontal"===this.options.direction&&this._addClass(null,"ui-helper-clearfix"),this._initWidgets(),e=this.childWidgets,this.options.onlyVisible&&(e=e.filter(":visible")),e.length&&(t.each(["first","last"],function(t,s){var n=e[s]().data("ui-controlgroup-data");if(n&&i["_"+n.widgetName+"Options"]){var o=i["_"+n.widgetName+"Options"](1===e.length?"only":s);o.classes=i._resolveClassesValues(o.classes,n),n.element[n.widgetName](o)}else i._updateCornerClass(e[s](),s)}),this._callChildMethod("refresh"))}}),t.widget("ui.checkboxradio",[t.ui.formResetMixin,{version:"1.12.1",options:{disabled:null,label:null,icon:!0,classes:{"ui-checkboxradio-label":"ui-corner-all","ui-checkboxradio-icon":"ui-corner-all"}},_getCreateOptions:function(){var e,i,s=this,n=this._super()||{};return this._readType(),i=this.element.labels(),this.label=t(i[i.length-1]),this.label.length||t.error("No label found for checkboxradio widget"),this.originalLabel="",this.label.contents().not(this.element[0]).each(function(){s.originalLabel+=3===this.nodeType?t(this).text():this.outerHTML}),this.originalLabel&&(n.label=this.originalLabel),e=this.element[0].disabled,null!=e&&(n.disabled=e),n},_create:function(){var t=this.element[0].checked;this._bindFormResetHandler(),null==this.options.disabled&&(this.options.disabled=this.element[0].disabled),this._setOption("disabled",this.options.disabled),this._addClass("ui-checkboxradio","ui-helper-hidden-accessible"),this._addClass(this.label,"ui-checkboxradio-label","ui-button ui-widget"),"radio"===this.type&&this._addClass(this.label,"ui-checkboxradio-radio-label"),this.options.label&&this.options.label!==this.originalLabel?this._updateLabel():this.originalLabel&&(this.options.label=this.originalLabel),this._enhance(),t&&(this._addClass(this.label,"ui-checkboxradio-checked","ui-state-active"),this.icon&&this._addClass(this.icon,null,"ui-state-hover")),this._on({change:"_toggleClasses",focus:function(){this._addClass(this.label,null,"ui-state-focus ui-visual-focus")},blur:function(){this._removeClass(this.label,null,"ui-state-focus ui-visual-focus")}})},_readType:function(){var e=this.element[0].nodeName.toLowerCase();this.type=this.element[0].type,"input"===e&&/radio|checkbox/.test(this.type)||t.error("Can't create checkboxradio on element.nodeName="+e+" and element.type="+this.type)},_enhance:function(){this._updateIcon(this.element[0].checked)},widget:function(){return this.label},_getRadioGroup:function(){var e,i=this.element[0].name,s="input[name='"+t.ui.escapeSelector(i)+"']";return i?(e=this.form.length?t(this.form[0].elements).filter(s):t(s).filter(function(){return 0===t(this).form().length}),e.not(this.element)):t([])},_toggleClasses:function(){var e=this.element[0].checked;this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",e),this.options.icon&&"checkbox"===this.type&&this._toggleClass(this.icon,null,"ui-icon-check ui-state-checked",e)._toggleClass(this.icon,null,"ui-icon-blank",!e),"radio"===this.type&&this._getRadioGroup().each(function(){var e=t(this).checkboxradio("instance");e&&e._removeClass(e.label,"ui-checkboxradio-checked","ui-state-active")})},_destroy:function(){this._unbindFormResetHandler(),this.icon&&(this.icon.remove(),this.iconSpace.remove())},_setOption:function(t,e){return"label"!==t||e?(this._super(t,e),"disabled"===t?(this._toggleClass(this.label,null,"ui-state-disabled",e),this.element[0].disabled=e,void 0):(this.refresh(),void 0)):void 0},_updateIcon:function(e){var i="ui-icon ui-icon-background ";this.options.icon?(this.icon||(this.icon=t("<span>"),this.iconSpace=t("<span> </span>"),this._addClass(this.iconSpace,"ui-checkboxradio-icon-space")),"checkbox"===this.type?(i+=e?"ui-icon-check ui-state-checked":"ui-icon-blank",this._removeClass(this.icon,null,e?"ui-icon-blank":"ui-icon-check")):i+="ui-icon-blank",this._addClass(this.icon,"ui-checkboxradio-icon",i),e||this._removeClass(this.icon,null,"ui-icon-check ui-state-checked"),this.icon.prependTo(this.label).after(this.iconSpace)):void 0!==this.icon&&(this.icon.remove(),this.iconSpace.remove(),delete this.icon)},_updateLabel:function(){var t=this.label.contents().not(this.element[0]);this.icon&&(t=t.not(this.icon[0])),this.iconSpace&&(t=t.not(this.iconSpace[0])),t.remove(),this.label.append(this.options.label)},refresh:function(){var t=this.element[0].checked,e=this.element[0].disabled;this._updateIcon(t),this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",t),null!==this.options.label&&this._updateLabel(),e!==this.options.disabled&&this._setOptions({disabled:e})}}]),t.ui.checkboxradio,t.widget("ui.button",{version:"1.12.1",defaultElement:"<button>",options:{classes:{"ui-button":"ui-corner-all"},disabled:null,icon:null,iconPosition:"beginning",label:null,showLabel:!0},_getCreateOptions:function(){var t,e=this._super()||{};return this.isInput=this.element.is("input"),t=this.element[0].disabled,null!=t&&(e.disabled=t),this.originalLabel=this.isInput?this.element.val():this.element.html(),this.originalLabel&&(e.label=this.originalLabel),e},_create:function(){!this.option.showLabel&!this.options.icon&&(this.options.showLabel=!0),null==this.options.disabled&&(this.options.disabled=this.element[0].disabled||!1),this.hasTitle=!!this.element.attr("title"),this.options.label&&this.options.label!==this.originalLabel&&(this.isInput?this.element.val(this.options.label):this.element.html(this.options.label)),this._addClass("ui-button","ui-widget"),this._setOption("disabled",this.options.disabled),this._enhance(),this.element.is("a")&&this._on({keyup:function(e){e.keyCode===t.ui.keyCode.SPACE&&(e.preventDefault(),this.element[0].click?this.element[0].click():this.element.trigger("click"))}})},_enhance:function(){this.element.is("button")||this.element.attr("role","button"),this.options.icon&&(this._updateIcon("icon",this.options.icon),this._updateTooltip())},_updateTooltip:function(){this.title=this.element.attr("title"),this.options.showLabel||this.title||this.element.attr("title",this.options.label)},_updateIcon:function(e,i){var s="iconPosition"!==e,n=s?this.options.iconPosition:i,o="top"===n||"bottom"===n;this.icon?s&&this._removeClass(this.icon,null,this.options.icon):(this.icon=t("<span>"),this._addClass(this.icon,"ui-button-icon","ui-icon"),this.options.showLabel||this._addClass("ui-button-icon-only")),s&&this._addClass(this.icon,null,i),this._attachIcon(n),o?(this._addClass(this.icon,null,"ui-widget-icon-block"),this.iconSpace&&this.iconSpace.remove()):(this.iconSpace||(this.iconSpace=t("<span> </span>"),this._addClass(this.iconSpace,"ui-button-icon-space")),this._removeClass(this.icon,null,"ui-wiget-icon-block"),this._attachIconSpace(n))},_destroy:function(){this.element.removeAttr("role"),this.icon&&this.icon.remove(),this.iconSpace&&this.iconSpace.remove(),this.hasTitle||this.element.removeAttr("title")},_attachIconSpace:function(t){this.icon[/^(?:end|bottom)/.test(t)?"before":"after"](this.iconSpace)},_attachIcon:function(t){this.element[/^(?:end|bottom)/.test(t)?"append":"prepend"](this.icon)},_setOptions:function(t){var e=void 0===t.showLabel?this.options.showLabel:t.showLabel,i=void 0===t.icon?this.options.icon:t.icon;e||i||(t.showLabel=!0),this._super(t)},_setOption:function(t,e){"icon"===t&&(e?this._updateIcon(t,e):this.icon&&(this.icon.remove(),this.iconSpace&&this.iconSpace.remove())),"iconPosition"===t&&this._updateIcon(t,e),"showLabel"===t&&(this._toggleClass("ui-button-icon-only",null,!e),this._updateTooltip()),"label"===t&&(this.isInput?this.element.val(e):(this.element.html(e),this.icon&&(this._attachIcon(this.options.iconPosition),this._attachIconSpace(this.options.iconPosition)))),this._super(t,e),"disabled"===t&&(this._toggleClass(null,"ui-state-disabled",e),this.element[0].disabled=e,e&&this.element.blur())},refresh:function(){var t=this.element.is("input, button")?this.element[0].disabled:this.element.hasClass("ui-button-disabled");t!==this.options.disabled&&this._setOptions({disabled:t}),this._updateTooltip()}}),t.uiBackCompat!==!1&&(t.widget("ui.button",t.ui.button,{options:{text:!0,icons:{primary:null,secondary:null}},_create:function(){this.options.showLabel&&!this.options.text&&(this.options.showLabel=this.options.text),!this.options.showLabel&&this.options.text&&(this.options.text=this.options.showLabel),this.options.icon||!this.options.icons.primary&&!this.options.icons.secondary?this.options.icon&&(this.options.icons.primary=this.options.icon):this.options.icons.primary?this.options.icon=this.options.icons.primary:(this.options.icon=this.options.icons.secondary,this.options.iconPosition="end"),this._super()},_setOption:function(t,e){return"text"===t?(this._super("showLabel",e),void 0):("showLabel"===t&&(this.options.text=e),"icon"===t&&(this.options.icons.primary=e),"icons"===t&&(e.primary?(this._super("icon",e.primary),this._super("iconPosition","beginning")):e.secondary&&(this._super("icon",e.secondary),this._super("iconPosition","end"))),this._superApply(arguments),void 0)}}),t.fn.button=function(e){return function(){return!this.length||this.length&&"INPUT"!==this[0].tagName||this.length&&"INPUT"===this[0].tagName&&"checkbox"!==this.attr("type")&&"radio"!==this.attr("type")?e.apply(this,arguments):(t.ui.checkboxradio||t.error("Checkboxradio widget missing"),0===arguments.length?this.checkboxradio({icon:!1}):this.checkboxradio.apply(this,arguments))}}(t.fn.button),t.fn.buttonset=function(){return t.ui.controlgroup||t.error("Controlgroup widget missing"),"option"===arguments[0]&&"items"===arguments[1]&&arguments[2]?this.controlgroup.apply(this,[arguments[0],"items.button",arguments[2]]):"option"===arguments[0]&&"items"===arguments[1]?this.controlgroup.apply(this,[arguments[0],"items.button"]):("object"==typeof arguments[0]&&arguments[0].items&&(arguments[0].items={button:arguments[0].items}),this.controlgroup.apply(this,arguments))}),t.ui.button,t.extend(t.ui,{datepicker:{version:"1.12.1"}});var m;t.extend(s.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(t){return a(this._defaults,t||{}),this},_attachDatepicker:function(e,i){var s,n,o;s=e.nodeName.toLowerCase(),n="div"===s||"span"===s,e.id||(this.uuid+=1,e.id="dp"+this.uuid),o=this._newInst(t(e),n),o.settings=t.extend({},i||{}),"input"===s?this._connectDatepicker(e,o):n&&this._inlineDatepicker(e,o)},_newInst:function(e,i){var s=e[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:s,input:e,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:i,dpDiv:i?n(t("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(e,i){var s=t(e);i.append=t([]),i.trigger=t([]),s.hasClass(this.markerClassName)||(this._attachments(s,i),s.addClass(this.markerClassName).on("keydown",this._doKeyDown).on("keypress",this._doKeyPress).on("keyup",this._doKeyUp),this._autoSize(i),t.data(e,"datepicker",i),i.settings.disabled&&this._disableDatepicker(e))},_attachments:function(e,i){var s,n,o,a=this._get(i,"appendText"),r=this._get(i,"isRTL");i.append&&i.append.remove(),a&&(i.append=t("<span class='"+this._appendClass+"'>"+a+"</span>"),e[r?"before":"after"](i.append)),e.off("focus",this._showDatepicker),i.trigger&&i.trigger.remove(),s=this._get(i,"showOn"),("focus"===s||"both"===s)&&e.on("focus",this._showDatepicker),("button"===s||"both"===s)&&(n=this._get(i,"buttonText"),o=this._get(i,"buttonImage"),i.trigger=t(this._get(i,"buttonImageOnly")?t("<img/>").addClass(this._triggerClass).attr({src:o,alt:n,title:n}):t("<button type='button'></button>").addClass(this._triggerClass).html(o?t("<img/>").attr({src:o,alt:n,title:n}):n)),e[r?"before":"after"](i.trigger),i.trigger.on("click",function(){return t.datepicker._datepickerShowing&&t.datepicker._lastInput===e[0]?t.datepicker._hideDatepicker():t.datepicker._datepickerShowing&&t.datepicker._lastInput!==e[0]?(t.datepicker._hideDatepicker(),t.datepicker._showDatepicker(e[0])):t.datepicker._showDatepicker(e[0]),!1}))},_autoSize:function(t){if(this._get(t,"autoSize")&&!t.inline){var e,i,s,n,o=new Date(2009,11,20),a=this._get(t,"dateFormat");a.match(/[DM]/)&&(e=function(t){for(i=0,s=0,n=0;t.length>n;n++)t[n].length>i&&(i=t[n].length,s=n);return s},o.setMonth(e(this._get(t,a.match(/MM/)?"monthNames":"monthNamesShort"))),o.setDate(e(this._get(t,a.match(/DD/)?"dayNames":"dayNamesShort"))+20-o.getDay())),t.input.attr("size",this._formatDate(t,o).length)}},_inlineDatepicker:function(e,i){var s=t(e);s.hasClass(this.markerClassName)||(s.addClass(this.markerClassName).append(i.dpDiv),t.data(e,"datepicker",i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(e),i.dpDiv.css("display","block"))},_dialogDatepicker:function(e,i,s,n,o){var r,h,l,c,u,d=this._dialogInst;return d||(this.uuid+=1,r="dp"+this.uuid,this._dialogInput=t("<input type='text' id='"+r+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.on("keydown",this._doKeyDown),t("body").append(this._dialogInput),d=this._dialogInst=this._newInst(this._dialogInput,!1),d.settings={},t.data(this._dialogInput[0],"datepicker",d)),a(d.settings,n||{}),i=i&&i.constructor===Date?this._formatDate(d,i):i,this._dialogInput.val(i),this._pos=o?o.length?o:[o.pageX,o.pageY]:null,this._pos||(h=document.documentElement.clientWidth,l=document.documentElement.clientHeight,c=document.documentElement.scrollLeft||document.body.scrollLeft,u=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[h/2-100+c,l/2-150+u]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),d.settings.onSelect=s,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),t.blockUI&&t.blockUI(this.dpDiv),t.data(this._dialogInput[0],"datepicker",d),this},_destroyDatepicker:function(e){var i,s=t(e),n=t.data(e,"datepicker");s.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),t.removeData(e,"datepicker"),"input"===i?(n.append.remove(),n.trigger.remove(),s.removeClass(this.markerClassName).off("focus",this._showDatepicker).off("keydown",this._doKeyDown).off("keypress",this._doKeyPress).off("keyup",this._doKeyUp)):("div"===i||"span"===i)&&s.removeClass(this.markerClassName).empty(),m===n&&(m=null))},_enableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,"datepicker");n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!1,o.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().removeClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}))},_disableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,"datepicker");n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!0,o.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().addClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}),this._disabledInputs[this._disabledInputs.length]=e)},_isDisabledDatepicker:function(t){if(!t)return!1;for(var e=0;this._disabledInputs.length>e;e++)if(this._disabledInputs[e]===t)return!0;return!1},_getInst:function(e){try{return t.data(e,"datepicker")}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(e,i,s){var n,o,r,h,l=this._getInst(e);return 2===arguments.length&&"string"==typeof i?"defaults"===i?t.extend({},t.datepicker._defaults):l?"all"===i?t.extend({},l.settings):this._get(l,i):null:(n=i||{},"string"==typeof i&&(n={},n[i]=s),l&&(this._curInst===l&&this._hideDatepicker(),o=this._getDateDatepicker(e,!0),r=this._getMinMaxDate(l,"min"),h=this._getMinMaxDate(l,"max"),a(l.settings,n),null!==r&&void 0!==n.dateFormat&&void 0===n.minDate&&(l.settings.minDate=this._formatDate(l,r)),null!==h&&void 0!==n.dateFormat&&void 0===n.maxDate&&(l.settings.maxDate=this._formatDate(l,h)),"disabled"in n&&(n.disabled?this._disableDatepicker(e):this._enableDatepicker(e)),this._attachments(t(e),l),this._autoSize(l),this._setDate(l,o),this._updateAlternate(l),this._updateDatepicker(l)),void 0)},_changeDatepicker:function(t,e,i){this._optionDatepicker(t,e,i)},_refreshDatepicker:function(t){var e=this._getInst(t);e&&this._updateDatepicker(e)},_setDateDatepicker:function(t,e){var i=this._getInst(t);i&&(this._setDate(i,e),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(t,e){var i=this._getInst(t);return i&&!i.inline&&this._setDateFromField(i,e),i?this._getDate(i):null},_doKeyDown:function(e){var i,s,n,o=t.datepicker._getInst(e.target),a=!0,r=o.dpDiv.is(".ui-datepicker-rtl");if(o._keyEvent=!0,t.datepicker._datepickerShowing)switch(e.keyCode){case 9:t.datepicker._hideDatepicker(),a=!1;break;case 13:return n=t("td."+t.datepicker._dayOverClass+":not(."+t.datepicker._currentClass+")",o.dpDiv),n[0]&&t.datepicker._selectDay(e.target,o.selectedMonth,o.selectedYear,n[0]),i=t.datepicker._get(o,"onSelect"),i?(s=t.datepicker._formatDate(o),i.apply(o.input?o.input[0]:null,[s,o])):t.datepicker._hideDatepicker(),!1;case 27:t.datepicker._hideDatepicker();break;case 33:t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 34:t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 35:(e.ctrlKey||e.metaKey)&&t.datepicker._clearDate(e.target),a=e.ctrlKey||e.metaKey;break;case 36:(e.ctrlKey||e.metaKey)&&t.datepicker._gotoToday(e.target),a=e.ctrlKey||e.metaKey;break;case 37:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?1:-1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 38:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,-7,"D"),a=e.ctrlKey||e.metaKey;break;case 39:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?-1:1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 40:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,7,"D"),a=e.ctrlKey||e.metaKey;break;default:a=!1}else 36===e.keyCode&&e.ctrlKey?t.datepicker._showDatepicker(this):a=!1;a&&(e.preventDefault(),e.stopPropagation())},_doKeyPress:function(e){var i,s,n=t.datepicker._getInst(e.target);return t.datepicker._get(n,"constrainInput")?(i=t.datepicker._possibleChars(t.datepicker._get(n,"dateFormat")),s=String.fromCharCode(null==e.charCode?e.keyCode:e.charCode),e.ctrlKey||e.metaKey||" ">s||!i||i.indexOf(s)>-1):void 0},_doKeyUp:function(e){var i,s=t.datepicker._getInst(e.target);if(s.input.val()!==s.lastVal)try{i=t.datepicker.parseDate(t.datepicker._get(s,"dateFormat"),s.input?s.input.val():null,t.datepicker._getFormatConfig(s)),i&&(t.datepicker._setDateFromField(s),t.datepicker._updateAlternate(s),t.datepicker._updateDatepicker(s))}catch(n){}return!0},_showDatepicker:function(e){if(e=e.target||e,"input"!==e.nodeName.toLowerCase()&&(e=t("input",e.parentNode)[0]),!t.datepicker._isDisabledDatepicker(e)&&t.datepicker._lastInput!==e){var s,n,o,r,h,l,c;s=t.datepicker._getInst(e),t.datepicker._curInst&&t.datepicker._curInst!==s&&(t.datepicker._curInst.dpDiv.stop(!0,!0),s&&t.datepicker._datepickerShowing&&t.datepicker._hideDatepicker(t.datepicker._curInst.input[0])),n=t.datepicker._get(s,"beforeShow"),o=n?n.apply(e,[e,s]):{},o!==!1&&(a(s.settings,o),s.lastVal=null,t.datepicker._lastInput=e,t.datepicker._setDateFromField(s),t.datepicker._inDialog&&(e.value=""),t.datepicker._pos||(t.datepicker._pos=t.datepicker._findPos(e),t.datepicker._pos[1]+=e.offsetHeight),r=!1,t(e).parents().each(function(){return r|="fixed"===t(this).css("position"),!r}),h={left:t.datepicker._pos[0],top:t.datepicker._pos[1]},t.datepicker._pos=null,s.dpDiv.empty(),s.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),t.datepicker._updateDatepicker(s),h=t.datepicker._checkOffset(s,h,r),s.dpDiv.css({position:t.datepicker._inDialog&&t.blockUI?"static":r?"fixed":"absolute",display:"none",left:h.left+"px",top:h.top+"px"}),s.inline||(l=t.datepicker._get(s,"showAnim"),c=t.datepicker._get(s,"duration"),s.dpDiv.css("z-index",i(t(e))+1),t.datepicker._datepickerShowing=!0,t.effects&&t.effects.effect[l]?s.dpDiv.show(l,t.datepicker._get(s,"showOptions"),c):s.dpDiv[l||"show"](l?c:null),t.datepicker._shouldFocusInput(s)&&s.input.trigger("focus"),t.datepicker._curInst=s)) +}},_updateDatepicker:function(e){this.maxRows=4,m=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e);var i,s=this._getNumberOfMonths(e),n=s[1],a=17,r=e.dpDiv.find("."+this._dayOverClass+" a");r.length>0&&o.apply(r.get(0)),e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),n>1&&e.dpDiv.addClass("ui-datepicker-multi-"+n).css("width",a*n+"em"),e.dpDiv[(1!==s[0]||1!==s[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e===t.datepicker._curInst&&t.datepicker._datepickerShowing&&t.datepicker._shouldFocusInput(e)&&e.input.trigger("focus"),e.yearshtml&&(i=e.yearshtml,setTimeout(function(){i===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),i=e.yearshtml=null},0))},_shouldFocusInput:function(t){return t.input&&t.input.is(":visible")&&!t.input.is(":disabled")&&!t.input.is(":focus")},_checkOffset:function(e,i,s){var n=e.dpDiv.outerWidth(),o=e.dpDiv.outerHeight(),a=e.input?e.input.outerWidth():0,r=e.input?e.input.outerHeight():0,h=document.documentElement.clientWidth+(s?0:t(document).scrollLeft()),l=document.documentElement.clientHeight+(s?0:t(document).scrollTop());return i.left-=this._get(e,"isRTL")?n-a:0,i.left-=s&&i.left===e.input.offset().left?t(document).scrollLeft():0,i.top-=s&&i.top===e.input.offset().top+r?t(document).scrollTop():0,i.left-=Math.min(i.left,i.left+n>h&&h>n?Math.abs(i.left+n-h):0),i.top-=Math.min(i.top,i.top+o>l&&l>o?Math.abs(o+r):0),i},_findPos:function(e){for(var i,s=this._getInst(e),n=this._get(s,"isRTL");e&&("hidden"===e.type||1!==e.nodeType||t.expr.filters.hidden(e));)e=e[n?"previousSibling":"nextSibling"];return i=t(e).offset(),[i.left,i.top]},_hideDatepicker:function(e){var i,s,n,o,a=this._curInst;!a||e&&a!==t.data(e,"datepicker")||this._datepickerShowing&&(i=this._get(a,"showAnim"),s=this._get(a,"duration"),n=function(){t.datepicker._tidyDialog(a)},t.effects&&(t.effects.effect[i]||t.effects[i])?a.dpDiv.hide(i,t.datepicker._get(a,"showOptions"),s,n):a.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?s:null,n),i||n(),this._datepickerShowing=!1,o=this._get(a,"onClose"),o&&o.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),t.blockUI&&(t.unblockUI(),t("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(t){t.dpDiv.removeClass(this._dialogClass).off(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(t.datepicker._curInst){var i=t(e.target),s=t.datepicker._getInst(i[0]);(i[0].id!==t.datepicker._mainDivId&&0===i.parents("#"+t.datepicker._mainDivId).length&&!i.hasClass(t.datepicker.markerClassName)&&!i.closest("."+t.datepicker._triggerClass).length&&t.datepicker._datepickerShowing&&(!t.datepicker._inDialog||!t.blockUI)||i.hasClass(t.datepicker.markerClassName)&&t.datepicker._curInst!==s)&&t.datepicker._hideDatepicker()}},_adjustDate:function(e,i,s){var n=t(e),o=this._getInst(n[0]);this._isDisabledDatepicker(n[0])||(this._adjustInstDate(o,i+("M"===s?this._get(o,"showCurrentAtPos"):0),s),this._updateDatepicker(o))},_gotoToday:function(e){var i,s=t(e),n=this._getInst(s[0]);this._get(n,"gotoCurrent")&&n.currentDay?(n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear):(i=new Date,n.selectedDay=i.getDate(),n.drawMonth=n.selectedMonth=i.getMonth(),n.drawYear=n.selectedYear=i.getFullYear()),this._notifyChange(n),this._adjustDate(s)},_selectMonthYear:function(e,i,s){var n=t(e),o=this._getInst(n[0]);o["selected"+("M"===s?"Month":"Year")]=o["draw"+("M"===s?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(o),this._adjustDate(n)},_selectDay:function(e,i,s,n){var o,a=t(e);t(n).hasClass(this._unselectableClass)||this._isDisabledDatepicker(a[0])||(o=this._getInst(a[0]),o.selectedDay=o.currentDay=t("a",n).html(),o.selectedMonth=o.currentMonth=i,o.selectedYear=o.currentYear=s,this._selectDate(e,this._formatDate(o,o.currentDay,o.currentMonth,o.currentYear)))},_clearDate:function(e){var i=t(e);this._selectDate(i,"")},_selectDate:function(e,i){var s,n=t(e),o=this._getInst(n[0]);i=null!=i?i:this._formatDate(o),o.input&&o.input.val(i),this._updateAlternate(o),s=this._get(o,"onSelect"),s?s.apply(o.input?o.input[0]:null,[i,o]):o.input&&o.input.trigger("change"),o.inline?this._updateDatepicker(o):(this._hideDatepicker(),this._lastInput=o.input[0],"object"!=typeof o.input[0]&&o.input.trigger("focus"),this._lastInput=null)},_updateAlternate:function(e){var i,s,n,o=this._get(e,"altField");o&&(i=this._get(e,"altFormat")||this._get(e,"dateFormat"),s=this._getDate(e),n=this.formatDate(i,s,this._getFormatConfig(e)),t(o).val(n))},noWeekends:function(t){var e=t.getDay();return[e>0&&6>e,""]},iso8601Week:function(t){var e,i=new Date(t.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),e=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((e-i)/864e5)/7)+1},parseDate:function(e,i,s){if(null==e||null==i)throw"Invalid arguments";if(i="object"==typeof i?""+i:i+"",""===i)return null;var n,o,a,r,h=0,l=(s?s.shortYearCutoff:null)||this._defaults.shortYearCutoff,c="string"!=typeof l?l:(new Date).getFullYear()%100+parseInt(l,10),u=(s?s.dayNamesShort:null)||this._defaults.dayNamesShort,d=(s?s.dayNames:null)||this._defaults.dayNames,p=(s?s.monthNamesShort:null)||this._defaults.monthNamesShort,f=(s?s.monthNames:null)||this._defaults.monthNames,g=-1,m=-1,_=-1,v=-1,b=!1,y=function(t){var i=e.length>n+1&&e.charAt(n+1)===t;return i&&n++,i},w=function(t){var e=y(t),s="@"===t?14:"!"===t?20:"y"===t&&e?4:"o"===t?3:2,n="y"===t?s:1,o=RegExp("^\\d{"+n+","+s+"}"),a=i.substring(h).match(o);if(!a)throw"Missing number at position "+h;return h+=a[0].length,parseInt(a[0],10)},k=function(e,s,n){var o=-1,a=t.map(y(e)?n:s,function(t,e){return[[e,t]]}).sort(function(t,e){return-(t[1].length-e[1].length)});if(t.each(a,function(t,e){var s=e[1];return i.substr(h,s.length).toLowerCase()===s.toLowerCase()?(o=e[0],h+=s.length,!1):void 0}),-1!==o)return o+1;throw"Unknown name at position "+h},x=function(){if(i.charAt(h)!==e.charAt(n))throw"Unexpected literal at position "+h;h++};for(n=0;e.length>n;n++)if(b)"'"!==e.charAt(n)||y("'")?x():b=!1;else switch(e.charAt(n)){case"d":_=w("d");break;case"D":k("D",u,d);break;case"o":v=w("o");break;case"m":m=w("m");break;case"M":m=k("M",p,f);break;case"y":g=w("y");break;case"@":r=new Date(w("@")),g=r.getFullYear(),m=r.getMonth()+1,_=r.getDate();break;case"!":r=new Date((w("!")-this._ticksTo1970)/1e4),g=r.getFullYear(),m=r.getMonth()+1,_=r.getDate();break;case"'":y("'")?x():b=!0;break;default:x()}if(i.length>h&&(a=i.substr(h),!/^\s+/.test(a)))throw"Extra/unparsed characters found in date: "+a;if(-1===g?g=(new Date).getFullYear():100>g&&(g+=(new Date).getFullYear()-(new Date).getFullYear()%100+(c>=g?0:-100)),v>-1)for(m=1,_=v;;){if(o=this._getDaysInMonth(g,m-1),o>=_)break;m++,_-=o}if(r=this._daylightSavingAdjust(new Date(g,m-1,_)),r.getFullYear()!==g||r.getMonth()+1!==m||r.getDate()!==_)throw"Invalid date";return r},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(t,e,i){if(!e)return"";var s,n=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,o=(i?i.dayNames:null)||this._defaults.dayNames,a=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,r=(i?i.monthNames:null)||this._defaults.monthNames,h=function(e){var i=t.length>s+1&&t.charAt(s+1)===e;return i&&s++,i},l=function(t,e,i){var s=""+e;if(h(t))for(;i>s.length;)s="0"+s;return s},c=function(t,e,i,s){return h(t)?s[e]:i[e]},u="",d=!1;if(e)for(s=0;t.length>s;s++)if(d)"'"!==t.charAt(s)||h("'")?u+=t.charAt(s):d=!1;else switch(t.charAt(s)){case"d":u+=l("d",e.getDate(),2);break;case"D":u+=c("D",e.getDay(),n,o);break;case"o":u+=l("o",Math.round((new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime()-new Date(e.getFullYear(),0,0).getTime())/864e5),3);break;case"m":u+=l("m",e.getMonth()+1,2);break;case"M":u+=c("M",e.getMonth(),a,r);break;case"y":u+=h("y")?e.getFullYear():(10>e.getFullYear()%100?"0":"")+e.getFullYear()%100;break;case"@":u+=e.getTime();break;case"!":u+=1e4*e.getTime()+this._ticksTo1970;break;case"'":h("'")?u+="'":d=!0;break;default:u+=t.charAt(s)}return u},_possibleChars:function(t){var e,i="",s=!1,n=function(i){var s=t.length>e+1&&t.charAt(e+1)===i;return s&&e++,s};for(e=0;t.length>e;e++)if(s)"'"!==t.charAt(e)||n("'")?i+=t.charAt(e):s=!1;else switch(t.charAt(e)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":n("'")?i+="'":s=!0;break;default:i+=t.charAt(e)}return i},_get:function(t,e){return void 0!==t.settings[e]?t.settings[e]:this._defaults[e]},_setDateFromField:function(t,e){if(t.input.val()!==t.lastVal){var i=this._get(t,"dateFormat"),s=t.lastVal=t.input?t.input.val():null,n=this._getDefaultDate(t),o=n,a=this._getFormatConfig(t);try{o=this.parseDate(i,s,a)||n}catch(r){s=e?"":s}t.selectedDay=o.getDate(),t.drawMonth=t.selectedMonth=o.getMonth(),t.drawYear=t.selectedYear=o.getFullYear(),t.currentDay=s?o.getDate():0,t.currentMonth=s?o.getMonth():0,t.currentYear=s?o.getFullYear():0,this._adjustInstDate(t)}},_getDefaultDate:function(t){return this._restrictMinMax(t,this._determineDate(t,this._get(t,"defaultDate"),new Date))},_determineDate:function(e,i,s){var n=function(t){var e=new Date;return e.setDate(e.getDate()+t),e},o=function(i){try{return t.datepicker.parseDate(t.datepicker._get(e,"dateFormat"),i,t.datepicker._getFormatConfig(e))}catch(s){}for(var n=(i.toLowerCase().match(/^c/)?t.datepicker._getDate(e):null)||new Date,o=n.getFullYear(),a=n.getMonth(),r=n.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":r+=parseInt(l[1],10);break;case"w":case"W":r+=7*parseInt(l[1],10);break;case"m":case"M":a+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a));break;case"y":case"Y":o+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a))}l=h.exec(i)}return new Date(o,a,r)},a=null==i||""===i?s:"string"==typeof i?o(i):"number"==typeof i?isNaN(i)?s:n(i):new Date(i.getTime());return a=a&&"Invalid Date"==""+a?s:a,a&&(a.setHours(0),a.setMinutes(0),a.setSeconds(0),a.setMilliseconds(0)),this._daylightSavingAdjust(a)},_daylightSavingAdjust:function(t){return t?(t.setHours(t.getHours()>12?t.getHours()+2:0),t):null},_setDate:function(t,e,i){var s=!e,n=t.selectedMonth,o=t.selectedYear,a=this._restrictMinMax(t,this._determineDate(t,e,new Date));t.selectedDay=t.currentDay=a.getDate(),t.drawMonth=t.selectedMonth=t.currentMonth=a.getMonth(),t.drawYear=t.selectedYear=t.currentYear=a.getFullYear(),n===t.selectedMonth&&o===t.selectedYear||i||this._notifyChange(t),this._adjustInstDate(t),t.input&&t.input.val(s?"":this._formatDate(t))},_getDate:function(t){var e=!t.currentYear||t.input&&""===t.input.val()?null:this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return e},_attachHandlers:function(e){var i=this._get(e,"stepMonths"),s="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){t.datepicker._adjustDate(s,-i,"M")},next:function(){t.datepicker._adjustDate(s,+i,"M")},hide:function(){t.datepicker._hideDatepicker()},today:function(){t.datepicker._gotoToday(s)},selectDay:function(){return t.datepicker._selectDay(s,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return t.datepicker._selectMonthYear(s,this,"M"),!1},selectYear:function(){return t.datepicker._selectMonthYear(s,this,"Y"),!1}};t(this).on(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(t){var e,i,s,n,o,a,r,h,l,c,u,d,p,f,g,m,_,v,b,y,w,k,x,C,D,I,T,P,M,S,H,z,O,A,N,W,E,F,L,R=new Date,B=this._daylightSavingAdjust(new Date(R.getFullYear(),R.getMonth(),R.getDate())),Y=this._get(t,"isRTL"),j=this._get(t,"showButtonPanel"),q=this._get(t,"hideIfNoPrevNext"),K=this._get(t,"navigationAsDateFormat"),U=this._getNumberOfMonths(t),V=this._get(t,"showCurrentAtPos"),$=this._get(t,"stepMonths"),X=1!==U[0]||1!==U[1],G=this._daylightSavingAdjust(t.currentDay?new Date(t.currentYear,t.currentMonth,t.currentDay):new Date(9999,9,9)),Q=this._getMinMaxDate(t,"min"),J=this._getMinMaxDate(t,"max"),Z=t.drawMonth-V,te=t.drawYear;if(0>Z&&(Z+=12,te--),J)for(e=this._daylightSavingAdjust(new Date(J.getFullYear(),J.getMonth()-U[0]*U[1]+1,J.getDate())),e=Q&&Q>e?Q:e;this._daylightSavingAdjust(new Date(te,Z,1))>e;)Z--,0>Z&&(Z=11,te--);for(t.drawMonth=Z,t.drawYear=te,i=this._get(t,"prevText"),i=K?this.formatDate(i,this._daylightSavingAdjust(new Date(te,Z-$,1)),this._getFormatConfig(t)):i,s=this._canAdjustMonth(t,-1,te,Z)?"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>":q?"":"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>",n=this._get(t,"nextText"),n=K?this.formatDate(n,this._daylightSavingAdjust(new Date(te,Z+$,1)),this._getFormatConfig(t)):n,o=this._canAdjustMonth(t,1,te,Z)?"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>":q?"":"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>",a=this._get(t,"currentText"),r=this._get(t,"gotoCurrent")&&t.currentDay?G:B,a=K?this.formatDate(a,r,this._getFormatConfig(t)):a,h=t.inline?"":"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>"+this._get(t,"closeText")+"</button>",l=j?"<div class='ui-datepicker-buttonpane ui-widget-content'>"+(Y?h:"")+(this._isInRange(t,r)?"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'>"+a+"</button>":"")+(Y?"":h)+"</div>":"",c=parseInt(this._get(t,"firstDay"),10),c=isNaN(c)?0:c,u=this._get(t,"showWeek"),d=this._get(t,"dayNames"),p=this._get(t,"dayNamesMin"),f=this._get(t,"monthNames"),g=this._get(t,"monthNamesShort"),m=this._get(t,"beforeShowDay"),_=this._get(t,"showOtherMonths"),v=this._get(t,"selectOtherMonths"),b=this._getDefaultDate(t),y="",k=0;U[0]>k;k++){for(x="",this.maxRows=4,C=0;U[1]>C;C++){if(D=this._daylightSavingAdjust(new Date(te,Z,t.selectedDay)),I=" ui-corner-all",T="",X){if(T+="<div class='ui-datepicker-group",U[1]>1)switch(C){case 0:T+=" ui-datepicker-group-first",I=" ui-corner-"+(Y?"right":"left");break;case U[1]-1:T+=" ui-datepicker-group-last",I=" ui-corner-"+(Y?"left":"right");break;default:T+=" ui-datepicker-group-middle",I=""}T+="'>"}for(T+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+I+"'>"+(/all|left/.test(I)&&0===k?Y?o:s:"")+(/all|right/.test(I)&&0===k?Y?s:o:"")+this._generateMonthYearHeader(t,Z,te,Q,J,k>0||C>0,f,g)+"</div><table class='ui-datepicker-calendar'><thead>"+"<tr>",P=u?"<th class='ui-datepicker-week-col'>"+this._get(t,"weekHeader")+"</th>":"",w=0;7>w;w++)M=(w+c)%7,P+="<th scope='col'"+((w+c+6)%7>=5?" class='ui-datepicker-week-end'":"")+">"+"<span title='"+d[M]+"'>"+p[M]+"</span></th>";for(T+=P+"</tr></thead><tbody>",S=this._getDaysInMonth(te,Z),te===t.selectedYear&&Z===t.selectedMonth&&(t.selectedDay=Math.min(t.selectedDay,S)),H=(this._getFirstDayOfMonth(te,Z)-c+7)%7,z=Math.ceil((H+S)/7),O=X?this.maxRows>z?this.maxRows:z:z,this.maxRows=O,A=this._daylightSavingAdjust(new Date(te,Z,1-H)),N=0;O>N;N++){for(T+="<tr>",W=u?"<td class='ui-datepicker-week-col'>"+this._get(t,"calculateWeek")(A)+"</td>":"",w=0;7>w;w++)E=m?m.apply(t.input?t.input[0]:null,[A]):[!0,""],F=A.getMonth()!==Z,L=F&&!v||!E[0]||Q&&Q>A||J&&A>J,W+="<td class='"+((w+c+6)%7>=5?" ui-datepicker-week-end":"")+(F?" ui-datepicker-other-month":"")+(A.getTime()===D.getTime()&&Z===t.selectedMonth&&t._keyEvent||b.getTime()===A.getTime()&&b.getTime()===D.getTime()?" "+this._dayOverClass:"")+(L?" "+this._unselectableClass+" ui-state-disabled":"")+(F&&!_?"":" "+E[1]+(A.getTime()===G.getTime()?" "+this._currentClass:"")+(A.getTime()===B.getTime()?" ui-datepicker-today":""))+"'"+(F&&!_||!E[2]?"":" title='"+E[2].replace(/'/g,"&#39;")+"'")+(L?"":" data-handler='selectDay' data-event='click' data-month='"+A.getMonth()+"' data-year='"+A.getFullYear()+"'")+">"+(F&&!_?"&#xa0;":L?"<span class='ui-state-default'>"+A.getDate()+"</span>":"<a class='ui-state-default"+(A.getTime()===B.getTime()?" ui-state-highlight":"")+(A.getTime()===G.getTime()?" ui-state-active":"")+(F?" ui-priority-secondary":"")+"' href='#'>"+A.getDate()+"</a>")+"</td>",A.setDate(A.getDate()+1),A=this._daylightSavingAdjust(A);T+=W+"</tr>"}Z++,Z>11&&(Z=0,te++),T+="</tbody></table>"+(X?"</div>"+(U[0]>0&&C===U[1]-1?"<div class='ui-datepicker-row-break'></div>":""):""),x+=T}y+=x}return y+=l,t._keyEvent=!1,y},_generateMonthYearHeader:function(t,e,i,s,n,o,a,r){var h,l,c,u,d,p,f,g,m=this._get(t,"changeMonth"),_=this._get(t,"changeYear"),v=this._get(t,"showMonthAfterYear"),b="<div class='ui-datepicker-title'>",y="";if(o||!m)y+="<span class='ui-datepicker-month'>"+a[e]+"</span>";else{for(h=s&&s.getFullYear()===i,l=n&&n.getFullYear()===i,y+="<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>",c=0;12>c;c++)(!h||c>=s.getMonth())&&(!l||n.getMonth()>=c)&&(y+="<option value='"+c+"'"+(c===e?" selected='selected'":"")+">"+r[c]+"</option>");y+="</select>"}if(v||(b+=y+(!o&&m&&_?"":"&#xa0;")),!t.yearshtml)if(t.yearshtml="",o||!_)b+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(u=this._get(t,"yearRange").split(":"),d=(new Date).getFullYear(),p=function(t){var e=t.match(/c[+\-].*/)?i+parseInt(t.substring(1),10):t.match(/[+\-].*/)?d+parseInt(t,10):parseInt(t,10);return isNaN(e)?d:e},f=p(u[0]),g=Math.max(f,p(u[1]||"")),f=s?Math.max(f,s.getFullYear()):f,g=n?Math.min(g,n.getFullYear()):g,t.yearshtml+="<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";g>=f;f++)t.yearshtml+="<option value='"+f+"'"+(f===i?" selected='selected'":"")+">"+f+"</option>";t.yearshtml+="</select>",b+=t.yearshtml,t.yearshtml=null}return b+=this._get(t,"yearSuffix"),v&&(b+=(!o&&m&&_?"":"&#xa0;")+y),b+="</div>"},_adjustInstDate:function(t,e,i){var s=t.selectedYear+("Y"===i?e:0),n=t.selectedMonth+("M"===i?e:0),o=Math.min(t.selectedDay,this._getDaysInMonth(s,n))+("D"===i?e:0),a=this._restrictMinMax(t,this._daylightSavingAdjust(new Date(s,n,o)));t.selectedDay=a.getDate(),t.drawMonth=t.selectedMonth=a.getMonth(),t.drawYear=t.selectedYear=a.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(t)},_restrictMinMax:function(t,e){var i=this._getMinMaxDate(t,"min"),s=this._getMinMaxDate(t,"max"),n=i&&i>e?i:e;return s&&n>s?s:n},_notifyChange:function(t){var e=this._get(t,"onChangeMonthYear");e&&e.apply(t.input?t.input[0]:null,[t.selectedYear,t.selectedMonth+1,t])},_getNumberOfMonths:function(t){var e=this._get(t,"numberOfMonths");return null==e?[1,1]:"number"==typeof e?[1,e]:e},_getMinMaxDate:function(t,e){return this._determineDate(t,this._get(t,e+"Date"),null)},_getDaysInMonth:function(t,e){return 32-this._daylightSavingAdjust(new Date(t,e,32)).getDate()},_getFirstDayOfMonth:function(t,e){return new Date(t,e,1).getDay()},_canAdjustMonth:function(t,e,i,s){var n=this._getNumberOfMonths(t),o=this._daylightSavingAdjust(new Date(i,s+(0>e?e:n[0]*n[1]),1));return 0>e&&o.setDate(this._getDaysInMonth(o.getFullYear(),o.getMonth())),this._isInRange(t,o)},_isInRange:function(t,e){var i,s,n=this._getMinMaxDate(t,"min"),o=this._getMinMaxDate(t,"max"),a=null,r=null,h=this._get(t,"yearRange");return h&&(i=h.split(":"),s=(new Date).getFullYear(),a=parseInt(i[0],10),r=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(a+=s),i[1].match(/[+\-].*/)&&(r+=s)),(!n||e.getTime()>=n.getTime())&&(!o||e.getTime()<=o.getTime())&&(!a||e.getFullYear()>=a)&&(!r||r>=e.getFullYear())},_getFormatConfig:function(t){var e=this._get(t,"shortYearCutoff");return e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),{shortYearCutoff:e,dayNamesShort:this._get(t,"dayNamesShort"),dayNames:this._get(t,"dayNames"),monthNamesShort:this._get(t,"monthNamesShort"),monthNames:this._get(t,"monthNames")}},_formatDate:function(t,e,i,s){e||(t.currentDay=t.selectedDay,t.currentMonth=t.selectedMonth,t.currentYear=t.selectedYear);var n=e?"object"==typeof e?e:this._daylightSavingAdjust(new Date(s,i,e)):this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return this.formatDate(this._get(t,"dateFormat"),n,this._getFormatConfig(t))}}),t.fn.datepicker=function(e){if(!this.length)return this;t.datepicker.initialized||(t(document).on("mousedown",t.datepicker._checkExternalClick),t.datepicker.initialized=!0),0===t("#"+t.datepicker._mainDivId).length&&t("body").append(t.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof e||"isDisabled"!==e&&"getDate"!==e&&"widget"!==e?"option"===e&&2===arguments.length&&"string"==typeof arguments[1]?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof e?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this].concat(i)):t.datepicker._attachDatepicker(this,e)}):t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i))},t.datepicker=new s,t.datepicker.initialized=!1,t.datepicker.uuid=(new Date).getTime(),t.datepicker.version="1.12.1",t.datepicker,t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var _=!1;t(document).on("mouseup",function(){_=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!_){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,n="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!n&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),_=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,_=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.ui.safeBlur=function(e){e&&"body"!==e.nodeName.toLowerCase()&&t(e).trigger("blur")},t.widget("ui.draggable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this._addClass("ui-draggable"),this._setHandleClassName(),this._mouseInit()},_setOption:function(t,e){this._super(t,e),"handle"===t&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?(this.destroyOnClear=!0,void 0):(this._removeHandleClassName(),this._mouseDestroy(),void 0)},_mouseCapture:function(e){var i=this.options;return this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(e),this.handle?(this._blurActiveElement(e),this._blockFrames(i.iframeFix===!0?"iframe":i.iframeFix),!0):!1)},_blockFrames:function(e){this.iframeBlocks=this.document.find(e).map(function(){var e=t(this);return t("<div>").css("position","absolute").appendTo(e.parent()).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(e){var i=t.ui.safeActiveElement(this.document[0]),s=t(e.target);s.closest(i).length||t.ui.safeBlur(i)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===t(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(e),this.originalPosition=this.position=this._generatePosition(e,!1),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",e)===!1?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_refreshOffsets:function(t){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:t.pageX-this.offset.left,top:t.pageY-this.offset.top}},_mouseDrag:function(e,i){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",e,s)===!1)return this._mouseUp(new t.Event("mouseup",e)),!1;this.position=s.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",e)!==!1&&i._clear()}):this._trigger("stop",e)!==!1&&this._clear(),!1},_mouseUp:function(e){return this._unblockFrames(),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),this.handleElement.is(e.target)&&this.element.trigger("focus"),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp(new t.Event("mouseup",{target:this.element[0]})):this._clear(),this},_getHandle:function(e){return this.options.handle?!!t(e.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this._addClass(this.handleElement,"ui-draggable-handle")},_removeHandleClassName:function(){this._removeClass(this.handleElement,"ui-draggable-handle")},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper),n=s?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return n.parents("body").length||n.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s&&n[0]===this.element[0]&&this._setPositionRelative(),n[0]===this.element[0]||/(fixed|absolute)/.test(n.css("position"))||n.css("position","absolute"),n},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_isRootNode:function(t){return/(html|body)/i.test(t.tagName)||t===this.document[0]},_getParentOffset:function(){var e=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.element.position(),e=this._isRootNode(this.scrollParent[0]);return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+(e?0:this.scrollParent.scrollTop()),left:t.left-(parseInt(this.helper.css("left"),10)||0)+(e?0:this.scrollParent.scrollLeft())} +},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options,o=this.document[0];return this.relativeContainer=null,n.containment?"window"===n.containment?(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):"document"===n.containment?(this.containment=[0,0,t(o).width()-this.helperProportions.width-this.margins.left,(t(o).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):n.containment.constructor===Array?(this.containment=n.containment,void 0):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=t(n.containment),s=i[0],s&&(e=/(scroll|auto)/.test(i.css("overflow")),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=i),void 0):(this.containment=null,void 0)},_convertPositionTo:function(t,e){e||(e=this.position);var i="absolute"===t?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(t,e){var i,s,n,o,a=this.options,r=this._isRootNode(this.scrollParent[0]),h=t.pageX,l=t.pageY;return r&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),e&&(this.containment&&(this.relativeContainer?(s=this.relativeContainer.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,t.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),t.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),t.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),a.grid&&(n=a.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/a.grid[1])*a.grid[1]:this.originalPageY,l=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-a.grid[1]:n+a.grid[1]:n,o=a.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/a.grid[0])*a.grid[0]:this.originalPageX,h=i?o-this.offset.click.left>=i[0]||o-this.offset.click.left>i[2]?o:o-this.offset.click.left>=i[0]?o-a.grid[0]:o+a.grid[0]:o),"y"===a.axis&&(h=this.originalPageX),"x"===a.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:r?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:r?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s,this],!0),/^(drag|start|stop)/.test(e)&&(this.positionAbs=this._convertPositionTo("absolute"),s.offset=this.positionAbs),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i,s){var n=t.extend({},i,{item:s.element});s.sortables=[],t(s.options.connectToSortable).each(function(){var i=t(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push(i),i.refreshPositions(),i._trigger("activate",e,n))})},stop:function(e,i,s){var n=t.extend({},i,{item:s.element});s.cancelHelperRemoval=!1,t.each(s.sortables,function(){var t=this;t.isOver?(t.isOver=0,s.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,n))})},drag:function(e,i,s){t.each(s.sortables,function(){var n=!1,o=this;o.positionAbs=s.positionAbs,o.helperProportions=s.helperProportions,o.offset.click=s.offset.click,o._intersectsWith(o.containerCache)&&(n=!0,t.each(s.sortables,function(){return this.positionAbs=s.positionAbs,this.helperProportions=s.helperProportions,this.offset.click=s.offset.click,this!==o&&this._intersectsWith(this.containerCache)&&t.contains(o.element[0],this.element[0])&&(n=!1),n})),n?(o.isOver||(o.isOver=1,s._parent=i.helper.parent(),o.currentItem=i.helper.appendTo(o.element).data("ui-sortable-item",!0),o.options._helper=o.options.helper,o.options.helper=function(){return i.helper[0]},e.target=o.currentItem[0],o._mouseCapture(e,!0),o._mouseStart(e,!0,!0),o.offset.click.top=s.offset.click.top,o.offset.click.left=s.offset.click.left,o.offset.parent.left-=s.offset.parent.left-o.offset.parent.left,o.offset.parent.top-=s.offset.parent.top-o.offset.parent.top,s._trigger("toSortable",e),s.dropped=o.element,t.each(s.sortables,function(){this.refreshPositions()}),s.currentItem=s.element,o.fromOutside=s),o.currentItem&&(o._mouseDrag(e),i.position=o.position)):o.isOver&&(o.isOver=0,o.cancelHelperRemoval=!0,o.options._revert=o.options.revert,o.options.revert=!1,o._trigger("out",e,o._uiHash(o)),o._mouseStop(e,!0),o.options.revert=o.options._revert,o.options.helper=o.options._helper,o.placeholder&&o.placeholder.remove(),i.helper.appendTo(s._parent),s._refreshOffsets(e),i.position=s._generatePosition(e,!0),s._trigger("fromSortable",e),s.dropped=!1,t.each(s.sortables,function(){this.refreshPositions()}))})}}),t.ui.plugin.add("draggable","cursor",{start:function(e,i,s){var n=t("body"),o=s.options;n.css("cursor")&&(o._cursor=n.css("cursor")),n.css("cursor",o.cursor)},stop:function(e,i,s){var n=s.options;n._cursor&&t("body").css("cursor",n._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("opacity")&&(o._opacity=n.css("opacity")),n.css("opacity",o.opacity)},stop:function(e,i,s){var n=s.options;n._opacity&&t(i.helper).css("opacity",n._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(e,i,s){var n=s.options,o=!1,a=s.scrollParentNotHidden[0],r=s.document[0];a!==r&&"HTML"!==a.tagName?(n.axis&&"x"===n.axis||(s.overflowOffset.top+a.offsetHeight-e.pageY<n.scrollSensitivity?a.scrollTop=o=a.scrollTop+n.scrollSpeed:e.pageY-s.overflowOffset.top<n.scrollSensitivity&&(a.scrollTop=o=a.scrollTop-n.scrollSpeed)),n.axis&&"y"===n.axis||(s.overflowOffset.left+a.offsetWidth-e.pageX<n.scrollSensitivity?a.scrollLeft=o=a.scrollLeft+n.scrollSpeed:e.pageX-s.overflowOffset.left<n.scrollSensitivity&&(a.scrollLeft=o=a.scrollLeft-n.scrollSpeed))):(n.axis&&"x"===n.axis||(e.pageY-t(r).scrollTop()<n.scrollSensitivity?o=t(r).scrollTop(t(r).scrollTop()-n.scrollSpeed):t(window).height()-(e.pageY-t(r).scrollTop())<n.scrollSensitivity&&(o=t(r).scrollTop(t(r).scrollTop()+n.scrollSpeed))),n.axis&&"y"===n.axis||(e.pageX-t(r).scrollLeft()<n.scrollSensitivity?o=t(r).scrollLeft(t(r).scrollLeft()-n.scrollSpeed):t(window).width()-(e.pageX-t(r).scrollLeft())<n.scrollSensitivity&&(o=t(r).scrollLeft(t(r).scrollLeft()+n.scrollSpeed)))),o!==!1&&t.ui.ddmanager&&!n.dropBehaviour&&t.ui.ddmanager.prepareOffsets(s,e)}}),t.ui.plugin.add("draggable","snap",{start:function(e,i,s){var n=s.options;s.snapElements=[],t(n.snap.constructor!==String?n.snap.items||":data(ui-draggable)":n.snap).each(function(){var e=t(this),i=e.offset();this!==s.element[0]&&s.snapElements.push({item:this,width:e.outerWidth(),height:e.outerHeight(),top:i.top,left:i.left})})},drag:function(e,i,s){var n,o,a,r,h,l,c,u,d,p,f=s.options,g=f.snapTolerance,m=i.offset.left,_=m+s.helperProportions.width,v=i.offset.top,b=v+s.helperProportions.height;for(d=s.snapElements.length-1;d>=0;d--)h=s.snapElements[d].left-s.margins.left,l=h+s.snapElements[d].width,c=s.snapElements[d].top-s.margins.top,u=c+s.snapElements[d].height,h-g>_||m>l+g||c-g>b||v>u+g||!t.contains(s.snapElements[d].item.ownerDocument,s.snapElements[d].item)?(s.snapElements[d].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=!1):("inner"!==f.snapMode&&(n=g>=Math.abs(c-b),o=g>=Math.abs(u-v),a=g>=Math.abs(h-_),r=g>=Math.abs(l-m),n&&(i.position.top=s._convertPositionTo("relative",{top:c-s.helperProportions.height,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left)),p=n||o||a||r,"outer"!==f.snapMode&&(n=g>=Math.abs(c-v),o=g>=Math.abs(u-b),a=g>=Math.abs(h-m),r=g>=Math.abs(l-_),n&&(i.position.top=s._convertPositionTo("relative",{top:c,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u-s.helperProportions.height,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left)),!s.snapElements[d].snapping&&(n||o||a||r||p)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=n||o||a||r||p)}}),t.ui.plugin.add("draggable","stack",{start:function(e,i,s){var n,o=s.options,a=t.makeArray(t(o.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});a.length&&(n=parseInt(t(a[0]).css("zIndex"),10)||0,t(a).each(function(e){t(this).css("zIndex",n+e)}),this.css("zIndex",n+a.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("zIndex")&&(o._zIndex=n.css("zIndex")),n.css("zIndex",o.zIndex)},stop:function(e,i,s){var n=s.options;n._zIndex&&t(i.helper).css("zIndex",n._zIndex)}}),t.ui.draggable,t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("<div>"),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidth<t.width,n=this._isNumber(t.height)&&e.maxHeight&&e.maxHeight<t.height,o=this._isNumber(t.width)&&e.minWidth&&e.minWidth>t.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("<div style='overflow:hidden;'></div>"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,g=s.maxWidth&&p>s.maxWidth,m=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),g&&(p-=l),m&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable,t.widget("ui.dialog",{version:"1.12.1",options:{appendTo:"body",autoOpen:!0,buttons:[],classes:{"ui-dialog":"ui-corner-all","ui-dialog-titlebar":"ui-corner-all"},closeOnEscape:!0,closeText:"Close",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(e){var i=t(this).css(e).offset().top;0>i&&t(this).css("top",e.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},sizeRelatedOptions:{buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},resizableRelatedOptions:{maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),null==this.options.title&&null!=this.originalTitle&&(this.options.title=this.originalTitle),this.options.disabled&&(this.options.disabled=!1),this._createWrapper(),this.element.show().removeAttr("title").appendTo(this.uiDialog),this._addClass("ui-dialog-content","ui-widget-content"),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&t.fn.draggable&&this._makeDraggable(),this.options.resizable&&t.fn.resizable&&this._makeResizable(),this._isOpen=!1,this._trackFocus()},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var e=this.options.appendTo;return e&&(e.jquery||e.nodeType)?t(e):this.document.find(e||"body").eq(0)},_destroy:function(){var t,e=this.originalPosition;this._untrackInstance(),this._destroyOverlay(),this.element.removeUniqueId().css(this.originalCss).detach(),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),t=e.parent.children().eq(e.index),t.length&&t[0]!==this.element[0]?t.before(this.element):e.parent.append(this.element)},widget:function(){return this.uiDialog +},disable:t.noop,enable:t.noop,close:function(e){var i=this;this._isOpen&&this._trigger("beforeClose",e)!==!1&&(this._isOpen=!1,this._focusedElement=null,this._destroyOverlay(),this._untrackInstance(),this.opener.filter(":focusable").trigger("focus").length||t.ui.safeBlur(t.ui.safeActiveElement(this.document[0])),this._hide(this.uiDialog,this.options.hide,function(){i._trigger("close",e)}))},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(e,i){var s=!1,n=this.uiDialog.siblings(".ui-front:visible").map(function(){return+t(this).css("z-index")}).get(),o=Math.max.apply(null,n);return o>=+this.uiDialog.css("z-index")&&(this.uiDialog.css("z-index",o+1),s=!0),s&&!i&&this._trigger("focus",e),s},open:function(){var e=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),void 0):(this._isOpen=!0,this.opener=t(t.ui.safeActiveElement(this.document[0])),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this.overlay&&this.overlay.css("z-index",this.uiDialog.css("z-index")-1),this._show(this.uiDialog,this.options.show,function(){e._focusTabbable(),e._trigger("focus")}),this._makeFocusTarget(),this._trigger("open"),void 0)},_focusTabbable:function(){var t=this._focusedElement;t||(t=this.element.find("[autofocus]")),t.length||(t=this.element.find(":tabbable")),t.length||(t=this.uiDialogButtonPane.find(":tabbable")),t.length||(t=this.uiDialogTitlebarClose.filter(":tabbable")),t.length||(t=this.uiDialog),t.eq(0).trigger("focus")},_keepFocus:function(e){function i(){var e=t.ui.safeActiveElement(this.document[0]),i=this.uiDialog[0]===e||t.contains(this.uiDialog[0],e);i||this._focusTabbable()}e.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=t("<div>").hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._addClass(this.uiDialog,"ui-dialog","ui-widget ui-widget-content ui-front"),this._on(this.uiDialog,{keydown:function(e){if(this.options.closeOnEscape&&!e.isDefaultPrevented()&&e.keyCode&&e.keyCode===t.ui.keyCode.ESCAPE)return e.preventDefault(),this.close(e),void 0;if(e.keyCode===t.ui.keyCode.TAB&&!e.isDefaultPrevented()){var i=this.uiDialog.find(":tabbable"),s=i.filter(":first"),n=i.filter(":last");e.target!==n[0]&&e.target!==this.uiDialog[0]||e.shiftKey?e.target!==s[0]&&e.target!==this.uiDialog[0]||!e.shiftKey||(this._delay(function(){n.trigger("focus")}),e.preventDefault()):(this._delay(function(){s.trigger("focus")}),e.preventDefault())}},mousedown:function(t){this._moveToTop(t)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var e;this.uiDialogTitlebar=t("<div>"),this._addClass(this.uiDialogTitlebar,"ui-dialog-titlebar","ui-widget-header ui-helper-clearfix"),this._on(this.uiDialogTitlebar,{mousedown:function(e){t(e.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.trigger("focus")}}),this.uiDialogTitlebarClose=t("<button type='button'></button>").button({label:t("<a>").text(this.options.closeText).html(),icon:"ui-icon-closethick",showLabel:!1}).appendTo(this.uiDialogTitlebar),this._addClass(this.uiDialogTitlebarClose,"ui-dialog-titlebar-close"),this._on(this.uiDialogTitlebarClose,{click:function(t){t.preventDefault(),this.close(t)}}),e=t("<span>").uniqueId().prependTo(this.uiDialogTitlebar),this._addClass(e,"ui-dialog-title"),this._title(e),this.uiDialogTitlebar.prependTo(this.uiDialog),this.uiDialog.attr({"aria-labelledby":e.attr("id")})},_title:function(t){this.options.title?t.text(this.options.title):t.html("&#160;")},_createButtonPane:function(){this.uiDialogButtonPane=t("<div>"),this._addClass(this.uiDialogButtonPane,"ui-dialog-buttonpane","ui-widget-content ui-helper-clearfix"),this.uiButtonSet=t("<div>").appendTo(this.uiDialogButtonPane),this._addClass(this.uiButtonSet,"ui-dialog-buttonset"),this._createButtons()},_createButtons:function(){var e=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),t.isEmptyObject(i)||t.isArray(i)&&!i.length?(this._removeClass(this.uiDialog,"ui-dialog-buttons"),void 0):(t.each(i,function(i,s){var n,o;s=t.isFunction(s)?{click:s,text:i}:s,s=t.extend({type:"button"},s),n=s.click,o={icon:s.icon,iconPosition:s.iconPosition,showLabel:s.showLabel,icons:s.icons,text:s.text},delete s.click,delete s.icon,delete s.iconPosition,delete s.showLabel,delete s.icons,"boolean"==typeof s.text&&delete s.text,t("<button></button>",s).button(o).appendTo(e.uiButtonSet).on("click",function(){n.apply(e.element[0],arguments)})}),this._addClass(this.uiDialog,"ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),void 0)},_makeDraggable:function(){function e(t){return{position:t.position,offset:t.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,n){i._addClass(t(this),"ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,e(n))},drag:function(t,s){i._trigger("drag",t,e(s))},stop:function(n,o){var a=o.offset.left-i.document.scrollLeft(),r=o.offset.top-i.document.scrollTop();s.position={my:"left top",at:"left"+(a>=0?"+":"")+a+" "+"top"+(r>=0?"+":"")+r,of:i.window},i._removeClass(t(this),"ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",n,e(o))}})},_makeResizable:function(){function e(t){return{originalPosition:t.originalPosition,originalSize:t.originalSize,position:t.position,size:t.size}}var i=this,s=this.options,n=s.resizable,o=this.uiDialog.css("position"),a="string"==typeof n?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:a,start:function(s,n){i._addClass(t(this),"ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,e(n))},resize:function(t,s){i._trigger("resize",t,e(s))},stop:function(n,o){var a=i.uiDialog.offset(),r=a.left-i.document.scrollLeft(),h=a.top-i.document.scrollTop();s.height=i.uiDialog.height(),s.width=i.uiDialog.width(),s.position={my:"left top",at:"left"+(r>=0?"+":"")+r+" "+"top"+(h>=0?"+":"")+h,of:i.window},i._removeClass(t(this),"ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",n,e(o))}}).css("position",o)},_trackFocus:function(){this._on(this.widget(),{focusin:function(e){this._makeFocusTarget(),this._focusedElement=t(e.target)}})},_makeFocusTarget:function(){this._untrackInstance(),this._trackingInstances().unshift(this)},_untrackInstance:function(){var e=this._trackingInstances(),i=t.inArray(this,e);-1!==i&&e.splice(i,1)},_trackingInstances:function(){var t=this.document.data("ui-dialog-instances");return t||(t=[],this.document.data("ui-dialog-instances",t)),t},_minHeight:function(){var t=this.options;return"auto"===t.height?t.minHeight:Math.min(t.minHeight,t.height)},_position:function(){var t=this.uiDialog.is(":visible");t||this.uiDialog.show(),this.uiDialog.position(this.options.position),t||this.uiDialog.hide()},_setOptions:function(e){var i=this,s=!1,n={};t.each(e,function(t,e){i._setOption(t,e),t in i.sizeRelatedOptions&&(s=!0),t in i.resizableRelatedOptions&&(n[t]=e)}),s&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",n)},_setOption:function(e,i){var s,n,o=this.uiDialog;"disabled"!==e&&(this._super(e,i),"appendTo"===e&&this.uiDialog.appendTo(this._appendTo()),"buttons"===e&&this._createButtons(),"closeText"===e&&this.uiDialogTitlebarClose.button({label:t("<a>").text(""+this.options.closeText).html()}),"draggable"===e&&(s=o.is(":data(ui-draggable)"),s&&!i&&o.draggable("destroy"),!s&&i&&this._makeDraggable()),"position"===e&&this._position(),"resizable"===e&&(n=o.is(":data(ui-resizable)"),n&&!i&&o.resizable("destroy"),n&&"string"==typeof i&&o.resizable("option","handles",i),n||i===!1||this._makeResizable()),"title"===e&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var t,e,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),t=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),e=Math.max(0,s.minHeight-t),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-t):"none","auto"===s.height?this.element.css({minHeight:e,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-t)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var e=t(this);return t("<div>").css({position:"absolute",width:e.outerWidth(),height:e.outerHeight()}).appendTo(e.parent()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(e){return t(e.target).closest(".ui-dialog").length?!0:!!t(e.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var e=!0;this._delay(function(){e=!1}),this.document.data("ui-dialog-overlays")||this._on(this.document,{focusin:function(t){e||this._allowInteraction(t)||(t.preventDefault(),this._trackingInstances()[0]._focusTabbable())}}),this.overlay=t("<div>").appendTo(this._appendTo()),this._addClass(this.overlay,null,"ui-widget-overlay ui-front"),this._on(this.overlay,{mousedown:"_keepFocus"}),this.document.data("ui-dialog-overlays",(this.document.data("ui-dialog-overlays")||0)+1)}},_destroyOverlay:function(){if(this.options.modal&&this.overlay){var t=this.document.data("ui-dialog-overlays")-1;t?this.document.data("ui-dialog-overlays",t):(this._off(this.document,"focusin"),this.document.removeData("ui-dialog-overlays")),this.overlay.remove(),this.overlay=null}}}),t.uiBackCompat!==!1&&t.widget("ui.dialog",t.ui.dialog,{options:{dialogClass:""},_createWrapper:function(){this._super(),this.uiDialog.addClass(this.options.dialogClass)},_setOption:function(t,e){"dialogClass"===t&&this.uiDialog.removeClass(this.options.dialogClass).addClass(e),this._superApply(arguments)}}),t.ui.dialog,t.widget("ui.droppable",{version:"1.12.1",widgetEventPrefix:"drop",options:{accept:"*",addClasses:!0,greedy:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var e,i=this.options,s=i.accept;this.isover=!1,this.isout=!0,this.accept=t.isFunction(s)?s:function(t){return t.is(s)},this.proportions=function(){return arguments.length?(e=arguments[0],void 0):e?e:e={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight}},this._addToManager(i.scope),i.addClasses&&this._addClass("ui-droppable")},_addToManager:function(e){t.ui.ddmanager.droppables[e]=t.ui.ddmanager.droppables[e]||[],t.ui.ddmanager.droppables[e].push(this)},_splice:function(t){for(var e=0;t.length>e;e++)t[e]===this&&t.splice(e,1)},_destroy:function(){var e=t.ui.ddmanager.droppables[this.options.scope];this._splice(e)},_setOption:function(e,i){if("accept"===e)this.accept=t.isFunction(i)?i:function(t){return t.is(i)};else if("scope"===e){var s=t.ui.ddmanager.droppables[this.options.scope];this._splice(s),this._addToManager(i)}this._super(e,i)},_activate:function(e){var i=t.ui.ddmanager.current;this._addActiveClass(),i&&this._trigger("activate",e,this.ui(i))},_deactivate:function(e){var i=t.ui.ddmanager.current;this._removeActiveClass(),i&&this._trigger("deactivate",e,this.ui(i))},_over:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._addHoverClass(),this._trigger("over",e,this.ui(i)))},_out:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._removeHoverClass(),this._trigger("out",e,this.ui(i)))},_drop:function(e,i){var s=i||t.ui.ddmanager.current,n=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var i=t(this).droppable("instance");return i.options.greedy&&!i.options.disabled&&i.options.scope===s.options.scope&&i.accept.call(i.element[0],s.currentItem||s.element)&&v(s,t.extend(i,{offset:i.element.offset()}),i.options.tolerance,e)?(n=!0,!1):void 0}),n?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this._removeActiveClass(),this._removeHoverClass(),this._trigger("drop",e,this.ui(s)),this.element):!1):!1},ui:function(t){return{draggable:t.currentItem||t.element,helper:t.helper,position:t.position,offset:t.positionAbs}},_addHoverClass:function(){this._addClass("ui-droppable-hover")},_removeHoverClass:function(){this._removeClass("ui-droppable-hover")},_addActiveClass:function(){this._addClass("ui-droppable-active")},_removeActiveClass:function(){this._removeClass("ui-droppable-active")}});var v=t.ui.intersect=function(){function t(t,e,i){return t>=e&&e+i>t}return function(e,i,s,n){if(!i.offset)return!1;var o=(e.positionAbs||e.position.absolute).left+e.margins.left,a=(e.positionAbs||e.position.absolute).top+e.margins.top,r=o+e.helperProportions.width,h=a+e.helperProportions.height,l=i.offset.left,c=i.offset.top,u=l+i.proportions().width,d=c+i.proportions().height;switch(s){case"fit":return o>=l&&u>=r&&a>=c&&d>=h;case"intersect":return o+e.helperProportions.width/2>l&&u>r-e.helperProportions.width/2&&a+e.helperProportions.height/2>c&&d>h-e.helperProportions.height/2;case"pointer":return t(n.pageY,c,i.proportions().height)&&t(n.pageX,l,i.proportions().width);case"touch":return(a>=c&&d>=a||h>=c&&d>=h||c>a&&h>d)&&(o>=l&&u>=o||r>=l&&u>=r||l>o&&r>u);default:return!1}}}();t.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,i){var s,n,o=t.ui.ddmanager.droppables[e.options.scope]||[],a=i?i.type:null,r=(e.currentItem||e.element).find(":data(ui-droppable)").addBack();t:for(s=0;o.length>s;s++)if(!(o[s].options.disabled||e&&!o[s].accept.call(o[s].element[0],e.currentItem||e.element))){for(n=0;r.length>n;n++)if(r[n]===o[s].element[0]){o[s].proportions().height=0;continue t}o[s].visible="none"!==o[s].element.css("display"),o[s].visible&&("mousedown"===a&&o[s]._activate.call(o[s],i),o[s].offset=o[s].element.offset(),o[s].proportions({width:o[s].element[0].offsetWidth,height:o[s].element[0].offsetHeight}))}},drop:function(e,i){var s=!1;return t.each((t.ui.ddmanager.droppables[e.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&v(e,this,this.options.tolerance,i)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(e,i){e.element.parentsUntil("body").on("scroll.droppable",function(){e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)})},drag:function(e,i){e.options.refreshPositions&&t.ui.ddmanager.prepareOffsets(e,i),t.each(t.ui.ddmanager.droppables[e.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,o,a=v(e,this,this.options.tolerance,i),r=!a&&this.isover?"isout":a&&!this.isover?"isover":null;r&&(this.options.greedy&&(n=this.options.scope,o=this.element.parents(":data(ui-droppable)").filter(function(){return t(this).droppable("instance").options.scope===n}),o.length&&(s=t(o[0]).droppable("instance"),s.greedyChild="isover"===r)),s&&"isover"===r&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[r]=!0,this["isout"===r?"isover":"isout"]=!1,this["isover"===r?"_over":"_out"].call(this,i),s&&"isout"===r&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(e,i){e.element.parentsUntil("body").off("scroll.droppable"),e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)}},t.uiBackCompat!==!1&&t.widget("ui.droppable",t.ui.droppable,{options:{hoverClass:!1,activeClass:!1},_addActiveClass:function(){this._super(),this.options.activeClass&&this.element.addClass(this.options.activeClass)},_removeActiveClass:function(){this._super(),this.options.activeClass&&this.element.removeClass(this.options.activeClass)},_addHoverClass:function(){this._super(),this.options.hoverClass&&this.element.addClass(this.options.hoverClass)},_removeHoverClass:function(){this._super(),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass)}}),t.ui.droppable,t.widget("ui.progressbar",{version:"1.12.1",options:{classes:{"ui-progressbar":"ui-corner-all","ui-progressbar-value":"ui-corner-left","ui-progressbar-complete":"ui-corner-right"},max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.attr({role:"progressbar","aria-valuemin":this.min}),this._addClass("ui-progressbar","ui-widget ui-widget-content"),this.valueDiv=t("<div>").appendTo(this.element),this._addClass(this.valueDiv,"ui-progressbar-value","ui-widget-header"),this._refreshValue()},_destroy:function(){this.element.removeAttr("role aria-valuemin aria-valuemax aria-valuenow"),this.valueDiv.remove()},value:function(t){return void 0===t?this.options.value:(this.options.value=this._constrainedValue(t),this._refreshValue(),void 0)},_constrainedValue:function(t){return void 0===t&&(t=this.options.value),this.indeterminate=t===!1,"number"!=typeof t&&(t=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,t))},_setOptions:function(t){var e=t.value;delete t.value,this._super(t),this.options.value=this._constrainedValue(e),this._refreshValue()},_setOption:function(t,e){"max"===t&&(e=Math.max(this.min,e)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var e=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||e>this.min).width(i.toFixed(0)+"%"),this._toggleClass(this.valueDiv,"ui-progressbar-complete",null,e===this.options.max)._toggleClass("ui-progressbar-indeterminate",null,this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=t("<div>").appendTo(this.valueDiv),this._addClass(this.overlayDiv,"ui-progressbar-overlay"))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":e}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),e===this.options.max&&this._trigger("complete")}}),t.widget("ui.selectable",t.ui.mouse,{version:"1.12.1",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var e=this;this._addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){e.elementPos=t(e.element[0]).offset(),e.selectees=t(e.options.filter,e.element[0]),e._addClass(e.selectees,"ui-selectee"),e.selectees.each(function(){var i=t(this),s=i.offset(),n={left:s.left-e.elementPos.left,top:s.top-e.elementPos.top};t.data(this,"selectable-item",{element:this,$element:i,left:n.left,top:n.top,right:n.left+i.outerWidth(),bottom:n.top+i.outerHeight(),startselected:!1,selected:i.hasClass("ui-selected"),selecting:i.hasClass("ui-selecting"),unselecting:i.hasClass("ui-unselecting")})})},this.refresh(),this._mouseInit(),this.helper=t("<div>"),this._addClass(this.helper,"ui-selectable-helper")},_destroy:function(){this.selectees.removeData("selectable-item"),this._mouseDestroy()},_mouseStart:function(e){var i=this,s=this.options;this.opos=[e.pageX,e.pageY],this.elementPos=t(this.element[0]).offset(),this.options.disabled||(this.selectees=t(s.filter,this.element[0]),this._trigger("start",e),t(s.appendTo).append(this.helper),this.helper.css({left:e.pageX,top:e.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=t.data(this,"selectable-item");s.startselected=!0,e.metaKey||e.ctrlKey||(i._removeClass(s.$element,"ui-selected"),s.selected=!1,i._addClass(s.$element,"ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",e,{unselecting:s.element}))}),t(e.target).parents().addBack().each(function(){var s,n=t.data(this,"selectable-item");return n?(s=!e.metaKey&&!e.ctrlKey||!n.$element.hasClass("ui-selected"),i._removeClass(n.$element,s?"ui-unselecting":"ui-selected")._addClass(n.$element,s?"ui-selecting":"ui-unselecting"),n.unselecting=!s,n.selecting=s,n.selected=s,s?i._trigger("selecting",e,{selecting:n.element}):i._trigger("unselecting",e,{unselecting:n.element}),!1):void 0}))},_mouseDrag:function(e){if(this.dragged=!0,!this.options.disabled){var i,s=this,n=this.options,o=this.opos[0],a=this.opos[1],r=e.pageX,h=e.pageY;return o>r&&(i=r,r=o,o=i),a>h&&(i=h,h=a,a=i),this.helper.css({left:o,top:a,width:r-o,height:h-a}),this.selectees.each(function(){var i=t.data(this,"selectable-item"),l=!1,c={};i&&i.element!==s.element[0]&&(c.left=i.left+s.elementPos.left,c.right=i.right+s.elementPos.left,c.top=i.top+s.elementPos.top,c.bottom=i.bottom+s.elementPos.top,"touch"===n.tolerance?l=!(c.left>r||o>c.right||c.top>h||a>c.bottom):"fit"===n.tolerance&&(l=c.left>o&&r>c.right&&c.top>a&&h>c.bottom),l?(i.selected&&(s._removeClass(i.$element,"ui-selected"),i.selected=!1),i.unselecting&&(s._removeClass(i.$element,"ui-unselecting"),i.unselecting=!1),i.selecting||(s._addClass(i.$element,"ui-selecting"),i.selecting=!0,s._trigger("selecting",e,{selecting:i.element}))):(i.selecting&&((e.metaKey||e.ctrlKey)&&i.startselected?(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,s._addClass(i.$element,"ui-selected"),i.selected=!0):(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,i.startselected&&(s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",e,{unselecting:i.element}))),i.selected&&(e.metaKey||e.ctrlKey||i.startselected||(s._removeClass(i.$element,"ui-selected"),i.selected=!1,s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",e,{unselecting:i.element})))))}),!1}},_mouseStop:function(e){var i=this;return this.dragged=!1,t(".ui-unselecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",e,{unselected:s.element})}),t(".ui-selecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-selecting")._addClass(s.$element,"ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",e,{selected:s.element})}),this._trigger("stop",e),this.helper.remove(),!1}}),t.widget("ui.selectmenu",[t.ui.formResetMixin,{version:"1.12.1",defaultElement:"<select>",options:{appendTo:null,classes:{"ui-selectmenu-button-open":"ui-corner-top","ui-selectmenu-button-closed":"ui-corner-all"},disabled:null,icons:{button:"ui-icon-triangle-1-s"},position:{my:"left top",at:"left bottom",collision:"none"},width:!1,change:null,close:null,focus:null,open:null,select:null},_create:function(){var e=this.element.uniqueId().attr("id");this.ids={element:e,button:e+"-button",menu:e+"-menu"},this._drawButton(),this._drawMenu(),this._bindFormResetHandler(),this._rendered=!1,this.menuItems=t()},_drawButton:function(){var e,i=this,s=this._parseOption(this.element.find("option:selected"),this.element[0].selectedIndex);this.labels=this.element.labels().attr("for",this.ids.button),this._on(this.labels,{click:function(t){this.button.focus(),t.preventDefault()}}),this.element.hide(),this.button=t("<span>",{tabindex:this.options.disabled?-1:0,id:this.ids.button,role:"combobox","aria-expanded":"false","aria-autocomplete":"list","aria-owns":this.ids.menu,"aria-haspopup":"true",title:this.element.attr("title")}).insertAfter(this.element),this._addClass(this.button,"ui-selectmenu-button ui-selectmenu-button-closed","ui-button ui-widget"),e=t("<span>").appendTo(this.button),this._addClass(e,"ui-selectmenu-icon","ui-icon "+this.options.icons.button),this.buttonItem=this._renderButtonItem(s).appendTo(this.button),this.options.width!==!1&&this._resizeButton(),this._on(this.button,this._buttonEvents),this.button.one("focusin",function(){i._rendered||i._refreshMenu()})},_drawMenu:function(){var e=this;this.menu=t("<ul>",{"aria-hidden":"true","aria-labelledby":this.ids.button,id:this.ids.menu}),this.menuWrap=t("<div>").append(this.menu),this._addClass(this.menuWrap,"ui-selectmenu-menu","ui-front"),this.menuWrap.appendTo(this._appendTo()),this.menuInstance=this.menu.menu({classes:{"ui-menu":"ui-corner-bottom"},role:"listbox",select:function(t,i){t.preventDefault(),e._setSelection(),e._select(i.item.data("ui-selectmenu-item"),t)},focus:function(t,i){var s=i.item.data("ui-selectmenu-item");null!=e.focusIndex&&s.index!==e.focusIndex&&(e._trigger("focus",t,{item:s}),e.isOpen||e._select(s,t)),e.focusIndex=s.index,e.button.attr("aria-activedescendant",e.menuItems.eq(s.index).attr("id"))}}).menu("instance"),this.menuInstance._off(this.menu,"mouseleave"),this.menuInstance._closeOnDocumentClick=function(){return!1},this.menuInstance._isDivider=function(){return!1}},refresh:function(){this._refreshMenu(),this.buttonItem.replaceWith(this.buttonItem=this._renderButtonItem(this._getSelectedItem().data("ui-selectmenu-item")||{})),null===this.options.width&&this._resizeButton()},_refreshMenu:function(){var t,e=this.element.find("option");this.menu.empty(),this._parseOptions(e),this._renderMenu(this.menu,this.items),this.menuInstance.refresh(),this.menuItems=this.menu.find("li").not(".ui-selectmenu-optgroup").find(".ui-menu-item-wrapper"),this._rendered=!0,e.length&&(t=this._getSelectedItem(),this.menuInstance.focus(null,t),this._setAria(t.data("ui-selectmenu-item")),this._setOption("disabled",this.element.prop("disabled")))},open:function(t){this.options.disabled||(this._rendered?(this._removeClass(this.menu.find(".ui-state-active"),null,"ui-state-active"),this.menuInstance.focus(null,this._getSelectedItem())):this._refreshMenu(),this.menuItems.length&&(this.isOpen=!0,this._toggleAttr(),this._resizeMenu(),this._position(),this._on(this.document,this._documentClick),this._trigger("open",t)))},_position:function(){this.menuWrap.position(t.extend({of:this.button},this.options.position))},close:function(t){this.isOpen&&(this.isOpen=!1,this._toggleAttr(),this.range=null,this._off(this.document),this._trigger("close",t))},widget:function(){return this.button},menuWidget:function(){return this.menu},_renderButtonItem:function(e){var i=t("<span>");return this._setText(i,e.label),this._addClass(i,"ui-selectmenu-text"),i},_renderMenu:function(e,i){var s=this,n="";t.each(i,function(i,o){var a;o.optgroup!==n&&(a=t("<li>",{text:o.optgroup}),s._addClass(a,"ui-selectmenu-optgroup","ui-menu-divider"+(o.element.parent("optgroup").prop("disabled")?" ui-state-disabled":"")),a.appendTo(e),n=o.optgroup),s._renderItemData(e,o)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-selectmenu-item",e)},_renderItem:function(e,i){var s=t("<li>"),n=t("<div>",{title:i.element.attr("title")});return i.disabled&&this._addClass(s,null,"ui-state-disabled"),this._setText(n,i.label),s.append(n).appendTo(e)},_setText:function(t,e){e?t.text(e):t.html("&#160;")},_move:function(t,e){var i,s,n=".ui-menu-item";this.isOpen?i=this.menuItems.eq(this.focusIndex).parent("li"):(i=this.menuItems.eq(this.element[0].selectedIndex).parent("li"),n+=":not(.ui-state-disabled)"),s="first"===t||"last"===t?i["first"===t?"prevAll":"nextAll"](n).eq(-1):i[t+"All"](n).eq(0),s.length&&this.menuInstance.focus(e,s)},_getSelectedItem:function(){return this.menuItems.eq(this.element[0].selectedIndex).parent("li")},_toggle:function(t){this[this.isOpen?"close":"open"](t)},_setSelection:function(){var t;this.range&&(window.getSelection?(t=window.getSelection(),t.removeAllRanges(),t.addRange(this.range)):this.range.select(),this.button.focus())},_documentClick:{mousedown:function(e){this.isOpen&&(t(e.target).closest(".ui-selectmenu-menu, #"+t.ui.escapeSelector(this.ids.button)).length||this.close(e))}},_buttonEvents:{mousedown:function(){var t;window.getSelection?(t=window.getSelection(),t.rangeCount&&(this.range=t.getRangeAt(0))):this.range=document.selection.createRange()},click:function(t){this._setSelection(),this._toggle(t)},keydown:function(e){var i=!0;switch(e.keyCode){case t.ui.keyCode.TAB:case t.ui.keyCode.ESCAPE:this.close(e),i=!1;break;case t.ui.keyCode.ENTER:this.isOpen&&this._selectFocusedItem(e);break;case t.ui.keyCode.UP:e.altKey?this._toggle(e):this._move("prev",e);break;case t.ui.keyCode.DOWN:e.altKey?this._toggle(e):this._move("next",e);break;case t.ui.keyCode.SPACE:this.isOpen?this._selectFocusedItem(e):this._toggle(e);break;case t.ui.keyCode.LEFT:this._move("prev",e);break;case t.ui.keyCode.RIGHT:this._move("next",e);break;case t.ui.keyCode.HOME:case t.ui.keyCode.PAGE_UP:this._move("first",e);break;case t.ui.keyCode.END:case t.ui.keyCode.PAGE_DOWN:this._move("last",e);break;default:this.menu.trigger(e),i=!1}i&&e.preventDefault()}},_selectFocusedItem:function(t){var e=this.menuItems.eq(this.focusIndex).parent("li");e.hasClass("ui-state-disabled")||this._select(e.data("ui-selectmenu-item"),t)},_select:function(t,e){var i=this.element[0].selectedIndex;this.element[0].selectedIndex=t.index,this.buttonItem.replaceWith(this.buttonItem=this._renderButtonItem(t)),this._setAria(t),this._trigger("select",e,{item:t}),t.index!==i&&this._trigger("change",e,{item:t}),this.close(e)},_setAria:function(t){var e=this.menuItems.eq(t.index).attr("id");this.button.attr({"aria-labelledby":e,"aria-activedescendant":e}),this.menu.attr("aria-activedescendant",e)},_setOption:function(t,e){if("icons"===t){var i=this.button.find("span.ui-icon");this._removeClass(i,null,this.options.icons.button)._addClass(i,null,e.button)}this._super(t,e),"appendTo"===t&&this.menuWrap.appendTo(this._appendTo()),"width"===t&&this._resizeButton()},_setOptionDisabled:function(t){this._super(t),this.menuInstance.option("disabled",t),this.button.attr("aria-disabled",t),this._toggleClass(this.button,null,"ui-state-disabled",t),this.element.prop("disabled",t),t?(this.button.attr("tabindex",-1),this.close()):this.button.attr("tabindex",0)},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e&&e[0]||(e=this.element.closest(".ui-front, dialog")),e.length||(e=this.document[0].body),e},_toggleAttr:function(){this.button.attr("aria-expanded",this.isOpen),this._removeClass(this.button,"ui-selectmenu-button-"+(this.isOpen?"closed":"open"))._addClass(this.button,"ui-selectmenu-button-"+(this.isOpen?"open":"closed"))._toggleClass(this.menuWrap,"ui-selectmenu-open",null,this.isOpen),this.menu.attr("aria-hidden",!this.isOpen)},_resizeButton:function(){var t=this.options.width;return t===!1?(this.button.css("width",""),void 0):(null===t&&(t=this.element.show().outerWidth(),this.element.hide()),this.button.outerWidth(t),void 0)},_resizeMenu:function(){this.menu.outerWidth(Math.max(this.button.outerWidth(),this.menu.width("").outerWidth()+1))},_getCreateOptions:function(){var t=this._super();return t.disabled=this.element.prop("disabled"),t},_parseOptions:function(e){var i=this,s=[];e.each(function(e,n){s.push(i._parseOption(t(n),e))}),this.items=s},_parseOption:function(t,e){var i=t.parent("optgroup");return{element:t,index:e,value:t.val(),label:t.text(),optgroup:i.attr("label")||"",disabled:i.prop("disabled")||t.prop("disabled")}},_destroy:function(){this._unbindFormResetHandler(),this.menuWrap.remove(),this.button.remove(),this.element.show(),this.element.removeUniqueId(),this.labels.attr("for",this.ids.element)}}]),t.widget("ui.slider",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"slide",options:{animate:!1,classes:{"ui-slider":"ui-corner-all","ui-slider-handle":"ui-corner-all","ui-slider-range":"ui-corner-all ui-widget-header"},distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this._calculateNewMax(),this._addClass("ui-slider ui-slider-"+this.orientation,"ui-widget ui-widget-content"),this._refresh(),this._animateOff=!1 +},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var e,i,s=this.options,n=this.element.find(".ui-slider-handle"),o="<span tabindex='0'></span>",a=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),e=n.length;i>e;e++)a.push(o);this.handles=n.add(t(a.join("")).appendTo(this.element)),this._addClass(this.handles,"ui-slider-handle","ui-state-default"),this.handle=this.handles.eq(0),this.handles.each(function(e){t(this).data("ui-slider-handle-index",e).attr("tabIndex",0)})},_createRange:function(){var e=this.options;e.range?(e.range===!0&&(e.values?e.values.length&&2!==e.values.length?e.values=[e.values[0],e.values[0]]:t.isArray(e.values)&&(e.values=e.values.slice(0)):e.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?(this._removeClass(this.range,"ui-slider-range-min ui-slider-range-max"),this.range.css({left:"",bottom:""})):(this.range=t("<div>").appendTo(this.element),this._addClass(this.range,"ui-slider-range")),("min"===e.range||"max"===e.range)&&this._addClass(this.range,"ui-slider-range-"+e.range)):(this.range&&this.range.remove(),this.range=null)},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this._mouseDestroy()},_mouseCapture:function(e){var i,s,n,o,a,r,h,l,c=this,u=this.options;return u.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:e.pageX,y:e.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(e){var i=Math.abs(s-c.values(e));(n>i||n===i&&(e===c._lastChangedValue||c.values(e)===u.min))&&(n=i,o=t(this),a=e)}),r=this._start(e,a),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=a,this._addClass(o,null,"ui-state-active"),o.trigger("focus"),h=o.offset(),l=!t(e.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:e.pageX-h.left-o.width()/2,top:e.pageY-h.top-o.height()/2-(parseInt(o.css("borderTopWidth"),10)||0)-(parseInt(o.css("borderBottomWidth"),10)||0)+(parseInt(o.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,a,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(t){var e={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(e);return this._slide(t,this._handleIndex,i),!1},_mouseStop:function(t){return this._removeClass(this.handles,null,"ui-state-active"),this._mouseSliding=!1,this._stop(t,this._handleIndex),this._change(t,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(t){var e,i,s,n,o;return"horizontal"===this.orientation?(e=this.elementSize.width,i=t.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(e=this.elementSize.height,i=t.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/e,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),o=this._valueMin()+s*n,this._trimAlignValue(o)},_uiHash:function(t,e,i){var s={handle:this.handles[t],handleIndex:t,value:void 0!==e?e:this.value()};return this._hasMultipleValues()&&(s.value=void 0!==e?e:this.values(t),s.values=i||this.values()),s},_hasMultipleValues:function(){return this.options.values&&this.options.values.length},_start:function(t,e){return this._trigger("start",t,this._uiHash(e))},_slide:function(t,e,i){var s,n,o=this.value(),a=this.values();this._hasMultipleValues()&&(n=this.values(e?0:1),o=this.values(e),2===this.options.values.length&&this.options.range===!0&&(i=0===e?Math.min(n,i):Math.max(n,i)),a[e]=i),i!==o&&(s=this._trigger("slide",t,this._uiHash(e,i,a)),s!==!1&&(this._hasMultipleValues()?this.values(e,i):this.value(i)))},_stop:function(t,e){this._trigger("stop",t,this._uiHash(e))},_change:function(t,e){this._keySliding||this._mouseSliding||(this._lastChangedValue=e,this._trigger("change",t,this._uiHash(e)))},value:function(t){return arguments.length?(this.options.value=this._trimAlignValue(t),this._refreshValue(),this._change(null,0),void 0):this._value()},values:function(e,i){var s,n,o;if(arguments.length>1)return this.options.values[e]=this._trimAlignValue(i),this._refreshValue(),this._change(null,e),void 0;if(!arguments.length)return this._values();if(!t.isArray(arguments[0]))return this._hasMultipleValues()?this._values(e):this.value();for(s=this.options.values,n=arguments[0],o=0;s.length>o;o+=1)s[o]=this._trimAlignValue(n[o]),this._change(null,o);this._refreshValue()},_setOption:function(e,i){var s,n=0;switch("range"===e&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),t.isArray(this.options.values)&&(n=this.options.values.length),this._super(e,i),e){case"orientation":this._detectOrientation(),this._removeClass("ui-slider-horizontal ui-slider-vertical")._addClass("ui-slider-"+this.orientation),this._refreshValue(),this.options.range&&this._refreshRange(i),this.handles.css("horizontal"===i?"bottom":"left","");break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=n-1;s>=0;s--)this._change(null,s);this._animateOff=!1;break;case"step":case"min":case"max":this._animateOff=!0,this._calculateNewMax(),this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_setOptionDisabled:function(t){this._super(t),this._toggleClass(null,"ui-state-disabled",!!t)},_value:function(){var t=this.options.value;return t=this._trimAlignValue(t)},_values:function(t){var e,i,s;if(arguments.length)return e=this.options.values[t],e=this._trimAlignValue(e);if(this._hasMultipleValues()){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(t){if(this._valueMin()>=t)return this._valueMin();if(t>=this._valueMax())return this._valueMax();var e=this.options.step>0?this.options.step:1,i=(t-this._valueMin())%e,s=t-i;return 2*Math.abs(i)>=e&&(s+=i>0?e:-e),parseFloat(s.toFixed(5))},_calculateNewMax:function(){var t=this.options.max,e=this._valueMin(),i=this.options.step,s=Math.round((t-e)/i)*i;t=s+e,t>this.options.max&&(t-=i),this.max=parseFloat(t.toFixed(this._precision()))},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_valueMin:function(){return this.options.min},_valueMax:function(){return this.max},_refreshRange:function(t){"vertical"===t&&this.range.css({width:"",left:""}),"horizontal"===t&&this.range.css({height:"",bottom:""})},_refreshValue:function(){var e,i,s,n,o,a=this.options.range,r=this.options,h=this,l=this._animateOff?!1:r.animate,c={};this._hasMultipleValues()?this.handles.each(function(s){i=100*((h.values(s)-h._valueMin())/(h._valueMax()-h._valueMin())),c["horizontal"===h.orientation?"left":"bottom"]=i+"%",t(this).stop(1,1)[l?"animate":"css"](c,r.animate),h.options.range===!0&&("horizontal"===h.orientation?(0===s&&h.range.stop(1,1)[l?"animate":"css"]({left:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:r.animate})):(0===s&&h.range.stop(1,1)[l?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:r.animate}))),e=i}):(s=this.value(),n=this._valueMin(),o=this._valueMax(),i=o!==n?100*((s-n)/(o-n)):0,c["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[l?"animate":"css"](c,r.animate),"min"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:i+"%"},r.animate),"max"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:100-i+"%"},r.animate),"min"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:i+"%"},r.animate),"max"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:100-i+"%"},r.animate))},_handleEvents:{keydown:function(e){var i,s,n,o,a=t(e.target).data("ui-slider-handle-index");switch(e.keyCode){case t.ui.keyCode.HOME:case t.ui.keyCode.END:case t.ui.keyCode.PAGE_UP:case t.ui.keyCode.PAGE_DOWN:case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(e.preventDefault(),!this._keySliding&&(this._keySliding=!0,this._addClass(t(e.target),null,"ui-state-active"),i=this._start(e,a),i===!1))return}switch(o=this.options.step,s=n=this._hasMultipleValues()?this.values(a):this.value(),e.keyCode){case t.ui.keyCode.HOME:n=this._valueMin();break;case t.ui.keyCode.END:n=this._valueMax();break;case t.ui.keyCode.PAGE_UP:n=this._trimAlignValue(s+(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.PAGE_DOWN:n=this._trimAlignValue(s-(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:if(s===this._valueMax())return;n=this._trimAlignValue(s+o);break;case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(s===this._valueMin())return;n=this._trimAlignValue(s-o)}this._slide(e,a,n)},keyup:function(e){var i=t(e.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(e,i),this._change(e,i),this._removeClass(t(e.target),null,"ui-state-active"))}}}),t.widget("ui.sortable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return t>=e&&e+i>t},_isFloating:function(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))},_create:function(){this.containerCache={},this._addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(t,e){this._super(t,e),"handle"===t&&this._setHandleClassName()},_setHandleClassName:function(){var e=this;this._removeClass(this.element.find(".ui-sortable-handle"),"ui-sortable-handle"),t.each(this.items,function(){e._addClass(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item,"ui-sortable-handle")})},_destroy:function(){this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(e,i){var s=null,n=!1,o=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,o.widgetName+"-item")===o?(s=t(this),!1):void 0}),t.data(e.target,o.widgetName+"-item")===o&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,o,a=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),a.containment&&this._setContainment(),a.cursor&&"auto"!==a.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",a.cursor),this.storedStylesheet=t("<style>*{ cursor: "+a.cursor+" !important; }</style>").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY<a.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+a.scrollSpeed:e.pageY-this.overflowOffset.top<a.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-a.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-e.pageX<a.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+a.scrollSpeed:e.pageX-this.overflowOffset.left<a.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-a.scrollSpeed)):(e.pageY-this.document.scrollTop()<a.scrollSensitivity?r=this.document.scrollTop(this.document.scrollTop()-a.scrollSpeed):this.window.height()-(e.pageY-this.document.scrollTop())<a.scrollSensitivity&&(r=this.document.scrollTop(this.document.scrollTop()+a.scrollSpeed)),e.pageX-this.document.scrollLeft()<a.scrollSensitivity?r=this.document.scrollLeft(this.document.scrollLeft()-a.scrollSpeed):this.window.width()-(e.pageX-this.document.scrollLeft())<a.scrollSensitivity&&(r=this.document.scrollLeft(this.document.scrollLeft()+a.scrollSpeed))),r!==!1&&t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp(new t.Event("mouseup",{target:null})),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,h=r+t.height,l=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+l>r&&h>s+l,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var e,i,s="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),n="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width),o=s&&n;return o?(e=this._getDragVerticalDirection(),i=this._getDragHorizontalDirection(),this.floating?"right"===i||"down"===e?2:1:e&&("down"===e?2:1)):!1},_intersectsWithSides:function(t){var e=this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&e||"up"===s&&!e)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){function i(){r.push(this)}var s,n,o,a,r=[],h=[],l=this._connectWith();if(l&&e)for(s=l.length-1;s>=0;s--)for(o=t(l[s],this.document[0]),n=o.length-1;n>=0;n--)a=t.data(o[n],this.widgetFullName),a&&a!==this&&!a.options.disabled&&h.push([t.isFunction(a.options.items)?a.options.items.call(a.element):t(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a]);for(h.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return t(r)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,h,l,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i],this.document[0]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,l=r.length;l>s;s++)h=t(r[s]),h.data(this.widgetName+"-item",a),c.push({item:h,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.floating=this.items.length?"x"===this.options.axis||this._isFloating(this.items[0].item):!1,this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]);return e._addClass(n,"ui-sortable-placeholder",i||e.currentItem[0].className)._removeClass(n,"ui-sortable-helper"),"tbody"===s?e._createTrPlaceholder(e.currentItem.find("tr").eq(0),t("<tr>",e.document[0]).appendTo(n)):"tr"===s?e._createTrPlaceholder(e.currentItem,n):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_createTrPlaceholder:function(e,i){var s=this;e.children().each(function(){t("<td>&#160;</td>",s.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(e){var i,s,n,o,a,r,h,l,c,u,d=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!t.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(d&&t.contains(this.containers[i].element[0],d.element[0]))continue;d=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",e,this._uiHash(this)),this.containers[i].containerCache.over=0);if(d)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,o=null,c=d.floating||this._isFloating(this.currentItem),a=c?"left":"top",r=c?"width":"height",u=c?"pageX":"pageY",s=this.items.length-1;s>=0;s--)t.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(h=this.items[s].item.offset()[a],l=!1,e[u]-h>this.items[s][r]/2&&(l=!0),n>Math.abs(e[u]-h)&&(n=Math.abs(e[u]-h),o=this.items[s],this.direction=l?"up":"down"));if(!o&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;o?this._rearrange(e,o,null,!0):this._rearrange(e,null,this.containers[p].element,!0),this._trigger("change",e,this._uiHash()),this.containers[p]._trigger("change",e,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.left<this.containment[0]&&(o=this.containment[0]+this.offset.click.left),e.pageY-this.offset.click.top<this.containment[1]&&(a=this.containment[1]+this.offset.click.top),e.pageX-this.offset.click.left>this.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter; +this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){function i(t,e,i){return function(s){i._trigger(t,s,e._uiHash(e))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&n.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||n.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(n.push(function(t){this._trigger("remove",t,this._uiHash())}),n.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)e||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(s=0;n.length>s;s++)n[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}}),t.widget("ui.spinner",{version:"1.12.1",defaultElement:"<input>",widgetEventPrefix:"spin",options:{classes:{"ui-spinner":"ui-corner-all","ui-spinner-down":"ui-corner-br","ui-spinner-up":"ui-corner-tr"},culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var e=this._super(),i=this.element;return t.each(["min","max","step"],function(t,s){var n=i.attr(s);null!=n&&n.length&&(e[s]=n)}),e},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t),void 0)},mousewheel:function(t,e){if(e){if(!this.spinning&&!this._start(t))return!1;this._spin((e>0?1:-1)*this.options.step,t),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(t)},100),t.preventDefault()}},"mousedown .ui-spinner-button":function(e){function i(){var e=this.element[0]===t.ui.safeActiveElement(this.document[0]);e||(this.element.trigger("focus"),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===t.ui.safeActiveElement(this.document[0])?this.previous:this.element.val(),e.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(e)!==!1&&this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(e){return t(e.currentTarget).hasClass("ui-state-active")?this._start(e)===!1?!1:(this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap("<span>").parent().append("<a></a><a></a>")},_draw:function(){this._enhance(),this._addClass(this.uiSpinner,"ui-spinner","ui-widget ui-widget-content"),this._addClass("ui-spinner-input"),this.element.attr("role","spinbutton"),this.buttons=this.uiSpinner.children("a").attr("tabIndex",-1).attr("aria-hidden",!0).button({classes:{"ui-button":""}}),this._removeClass(this.buttons,"ui-corner-all"),this._addClass(this.buttons.first(),"ui-spinner-button ui-spinner-up"),this._addClass(this.buttons.last(),"ui-spinner-button ui-spinner-down"),this.buttons.first().button({icon:this.options.icons.up,showLabel:!1}),this.buttons.last().button({icon:this.options.icons.down,showLabel:!1}),this.buttons.height()>Math.ceil(.5*this.uiSpinner.height())&&this.uiSpinner.height()>0&&this.uiSpinner.height(this.uiSpinner.height())},_keydown:function(e){var i=this.options,s=t.ui.keyCode;switch(e.keyCode){case s.UP:return this._repeat(null,1,e),!0;case s.DOWN:return this._repeat(null,-1,e),!0;case s.PAGE_UP:return this._repeat(null,i.page,e),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,e),!0}return!1},_start:function(t){return this.spinning||this._trigger("start",t)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(t,e,i){t=t||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,e,i)},t),this._spin(e*this.options.step,i)},_spin:function(t,e){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+t*this._increment(this.counter)),this.spinning&&this._trigger("spin",e,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(e){var i=this.options.incremental;return i?t.isFunction(i)?i(e):Math.floor(e*e*e/5e4-e*e/500+17*e/200+1):1},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_adjustValue:function(t){var e,i,s=this.options;return e=null!==s.min?s.min:0,i=t-e,i=Math.round(i/s.step)*s.step,t=e+i,t=parseFloat(t.toFixed(this._precision())),null!==s.max&&t>s.max?s.max:null!==s.min&&s.min>t?s.min:t},_stop:function(t){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",t))},_setOption:function(t,e){var i,s,n;return"culture"===t||"numberFormat"===t?(i=this._parse(this.element.val()),this.options[t]=e,this.element.val(this._format(i)),void 0):(("max"===t||"min"===t||"step"===t)&&"string"==typeof e&&(e=this._parse(e)),"icons"===t&&(s=this.buttons.first().find(".ui-icon"),this._removeClass(s,null,this.options.icons.up),this._addClass(s,null,e.up),n=this.buttons.last().find(".ui-icon"),this._removeClass(n,null,this.options.icons.down),this._addClass(n,null,e.down)),this._super(t,e),void 0)},_setOptionDisabled:function(t){this._super(t),this._toggleClass(this.uiSpinner,null,"ui-state-disabled",!!t),this.element.prop("disabled",!!t),this.buttons.button(t?"disable":"enable")},_setOptions:r(function(t){this._super(t)}),_parse:function(t){return"string"==typeof t&&""!==t&&(t=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(t,10,this.options.culture):+t),""===t||isNaN(t)?null:t},_format:function(t){return""===t?"":window.Globalize&&this.options.numberFormat?Globalize.format(t,this.options.numberFormat,this.options.culture):t},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},isValid:function(){var t=this.value();return null===t?!1:t===this._adjustValue(t)},_value:function(t,e){var i;""!==t&&(i=this._parse(t),null!==i&&(e||(i=this._adjustValue(i)),t=this._format(i))),this.element.val(t),this._refresh()},_destroy:function(){this.element.prop("disabled",!1).removeAttr("autocomplete role aria-valuemin aria-valuemax aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:r(function(t){this._stepUp(t)}),_stepUp:function(t){this._start()&&(this._spin((t||1)*this.options.step),this._stop())},stepDown:r(function(t){this._stepDown(t)}),_stepDown:function(t){this._start()&&(this._spin((t||1)*-this.options.step),this._stop())},pageUp:r(function(t){this._stepUp((t||1)*this.options.page)}),pageDown:r(function(t){this._stepDown((t||1)*this.options.page)}),value:function(t){return arguments.length?(r(this._value).call(this,t),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}}),t.uiBackCompat!==!1&&t.widget("ui.spinner",t.ui.spinner,{_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml())},_uiSpinnerHtml:function(){return"<span>"},_buttonHtml:function(){return"<a></a><a></a>"}}),t.ui.spinner,t.widget("ui.tabs",{version:"1.12.1",delay:300,options:{active:null,classes:{"ui-tabs":"ui-corner-all","ui-tabs-nav":"ui-corner-all","ui-tabs-panel":"ui-corner-bottom","ui-tabs-tab":"ui-corner-top"},collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:function(){var t=/#.*$/;return function(e){var i,s;i=e.href.replace(t,""),s=location.href.replace(t,"");try{i=decodeURIComponent(i)}catch(n){}try{s=decodeURIComponent(s)}catch(n){}return e.hash.length>1&&i===s}}(),_create:function(){var e=this,i=this.options;this.running=!1,this._addClass("ui-tabs","ui-widget ui-widget-content"),this._toggleClass("ui-tabs-collapsible",null,i.collapsible),this._processTabs(),i.active=this._initialActive(),t.isArray(i.disabled)&&(i.disabled=t.unique(i.disabled.concat(t.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):t(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var e=this.options.active,i=this.options.collapsible,s=location.hash.substring(1);return null===e&&(s&&this.tabs.each(function(i,n){return t(n).attr("aria-controls")===s?(e=i,!1):void 0}),null===e&&(e=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===e||-1===e)&&(e=this.tabs.length?0:!1)),e!==!1&&(e=this.tabs.index(this.tabs.eq(e)),-1===e&&(e=i?!1:0)),!i&&e===!1&&this.anchors.length&&(e=0),e},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):t()}},_tabKeydown:function(e){var i=t(t.ui.safeActiveElement(this.document[0])).closest("li"),s=this.tabs.index(i),n=!0;if(!this._handlePageNav(e)){switch(e.keyCode){case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:s++;break;case t.ui.keyCode.UP:case t.ui.keyCode.LEFT:n=!1,s--;break;case t.ui.keyCode.END:s=this.anchors.length-1;break;case t.ui.keyCode.HOME:s=0;break;case t.ui.keyCode.SPACE:return e.preventDefault(),clearTimeout(this.activating),this._activate(s),void 0;case t.ui.keyCode.ENTER:return e.preventDefault(),clearTimeout(this.activating),this._activate(s===this.options.active?!1:s),void 0;default:return}e.preventDefault(),clearTimeout(this.activating),s=this._focusNextTab(s,n),e.ctrlKey||e.metaKey||(i.attr("aria-selected","false"),this.tabs.eq(s).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",s)},this.delay))}},_panelKeydown:function(e){this._handlePageNav(e)||e.ctrlKey&&e.keyCode===t.ui.keyCode.UP&&(e.preventDefault(),this.active.trigger("focus"))},_handlePageNav:function(e){return e.altKey&&e.keyCode===t.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):e.altKey&&e.keyCode===t.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(e,i){function s(){return e>n&&(e=0),0>e&&(e=n),e}for(var n=this.tabs.length-1;-1!==t.inArray(s(),this.options.disabled);)e=i?e+1:e-1;return e},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).trigger("focus"),t},_setOption:function(t,e){return"active"===t?(this._activate(e),void 0):(this._super(t,e),"collapsible"===t&&(this._toggleClass("ui-tabs-collapsible",null,e),e||this.options.active!==!1||this._activate(0)),"event"===t&&this._setupEvents(e),"heightStyle"===t&&this._setupHeightStyle(e),void 0)},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var e=this.options,i=this.tablist.children(":has(a[href])");e.disabled=t.map(i.filter(".ui-state-disabled"),function(t){return i.index(t)}),this._processTabs(),e.active!==!1&&this.anchors.length?this.active.length&&!t.contains(this.tablist[0],this.active[0])?this.tabs.length===e.disabled.length?(e.active=!1,this.active=t()):this._activate(this._findNextTab(Math.max(0,e.active-1),!1)):e.active=this.tabs.index(this.active):(e.active=!1,this.active=t()),this._refresh()},_refresh:function(){this._setOptionDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._addClass(this.active,"ui-tabs-active","ui-state-active"),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var e=this,i=this.tabs,s=this.anchors,n=this.panels;this.tablist=this._getList().attr("role","tablist"),this._addClass(this.tablist,"ui-tabs-nav","ui-helper-reset ui-helper-clearfix ui-widget-header"),this.tablist.on("mousedown"+this.eventNamespace,"> li",function(e){t(this).is(".ui-state-disabled")&&e.preventDefault()}).on("focus"+this.eventNamespace,".ui-tabs-anchor",function(){t(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").attr({role:"tab",tabIndex:-1}),this._addClass(this.tabs,"ui-tabs-tab","ui-state-default"),this.anchors=this.tabs.map(function(){return t("a",this)[0]}).attr({role:"presentation",tabIndex:-1}),this._addClass(this.anchors,"ui-tabs-anchor"),this.panels=t(),this.anchors.each(function(i,s){var n,o,a,r=t(s).uniqueId().attr("id"),h=t(s).closest("li"),l=h.attr("aria-controls");e._isLocal(s)?(n=s.hash,a=n.substring(1),o=e.element.find(e._sanitizeSelector(n))):(a=h.attr("aria-controls")||t({}).uniqueId()[0].id,n="#"+a,o=e.element.find(n),o.length||(o=e._createPanel(a),o.insertAfter(e.panels[i-1]||e.tablist)),o.attr("aria-live","polite")),o.length&&(e.panels=e.panels.add(o)),l&&h.data("ui-tabs-aria-controls",l),h.attr({"aria-controls":a,"aria-labelledby":r}),o.attr("aria-labelledby",r)}),this.panels.attr("role","tabpanel"),this._addClass(this.panels,"ui-tabs-panel","ui-widget-content"),i&&(this._off(i.not(this.tabs)),this._off(s.not(this.anchors)),this._off(n.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol, ul").eq(0)},_createPanel:function(e){return t("<div>").attr("id",e).data("ui-tabs-destroy",!0)},_setOptionDisabled:function(e){var i,s,n;for(t.isArray(e)&&(e.length?e.length===this.anchors.length&&(e=!0):e=!1),n=0;s=this.tabs[n];n++)i=t(s),e===!0||-1!==t.inArray(n,e)?(i.attr("aria-disabled","true"),this._addClass(i,null,"ui-state-disabled")):(i.removeAttr("aria-disabled"),this._removeClass(i,null,"ui-state-disabled"));this.options.disabled=e,this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,e===!0)},_setupEvents:function(e){var i={};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(t){t.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(e){var i,s=this.element.parent();"fill"===e?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=t(this).outerHeight(!0)}),this.panels.each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.panels.each(function(){i=Math.max(i,t(this).height("").height())}).height(i))},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),o=n.closest("li"),a=o[0]===s[0],r=a&&i.collapsible,h=r?t():this._getPanelForTab(o),l=s.length?this._getPanelForTab(s):t(),c={oldTab:s,oldPanel:l,newTab:r?t():o,newPanel:h};e.preventDefault(),o.hasClass("ui-state-disabled")||o.hasClass("ui-tabs-loading")||this.running||a&&!i.collapsible||this._trigger("beforeActivate",e,c)===!1||(i.active=r?!1:this.tabs.index(o),this.active=a?t():o,this.xhr&&this.xhr.abort(),l.length||h.length||t.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(o),e),this._toggle(e,c))},_toggle:function(e,i){function s(){o.running=!1,o._trigger("activate",e,i)}function n(){o._addClass(i.newTab.closest("li"),"ui-tabs-active","ui-state-active"),a.length&&o.options.show?o._show(a,o.options.show,s):(a.show(),s())}var o=this,a=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){o._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),n()}):(this._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),r.hide(),n()),r.attr("aria-hidden","true"),i.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),a.length&&r.length?i.oldTab.attr("tabIndex",-1):a.length&&this.tabs.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),a.attr("aria-hidden","false"),i.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(e){var i,s=this._findActive(e);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return e===!1?t():this.tabs.eq(e)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+t.ui.escapeSelector(e)+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.tablist.removeAttr("role").off(this.eventNamespace),this.anchors.removeAttr("role tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){t.data(this,"ui-tabs-destroy")?t(this).remove():t(this).removeAttr("role tabIndex aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded")}),this.tabs.each(function(){var e=t(this),i=e.data("ui-tabs-aria-controls");i?e.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):e.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(e){var i=this.options.disabled;i!==!1&&(void 0===e?i=!1:(e=this._getIndex(e),i=t.isArray(i)?t.map(i,function(t){return t!==e?t:null}):t.map(this.tabs,function(t,i){return i!==e?i:null})),this._setOptionDisabled(i))},disable:function(e){var i=this.options.disabled;if(i!==!0){if(void 0===e)i=!0;else{if(e=this._getIndex(e),-1!==t.inArray(e,i))return;i=t.isArray(i)?t.merge([e],i).sort():[e]}this._setOptionDisabled(i)}},load:function(e,i){e=this._getIndex(e);var s=this,n=this.tabs.eq(e),o=n.find(".ui-tabs-anchor"),a=this._getPanelForTab(n),r={tab:n,panel:a},h=function(t,e){"abort"===e&&s.panels.stop(!1,!0),s._removeClass(n,"ui-tabs-loading"),a.removeAttr("aria-busy"),t===s.xhr&&delete s.xhr};this._isLocal(o[0])||(this.xhr=t.ajax(this._ajaxSettings(o,i,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(this._addClass(n,"ui-tabs-loading"),a.attr("aria-busy","true"),this.xhr.done(function(t,e,n){setTimeout(function(){a.html(t),s._trigger("load",i,r),h(n,e)},1)}).fail(function(t,e){setTimeout(function(){h(t,e)},1)})))},_ajaxSettings:function(e,i,s){var n=this;return{url:e.attr("href").replace(/#.*$/,""),beforeSend:function(e,o){return n._trigger("beforeLoad",i,t.extend({jqXHR:e,ajaxSettings:o},s))}}},_getPanelForTab:function(e){var i=t(e).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}}),t.uiBackCompat!==!1&&t.widget("ui.tabs",t.ui.tabs,{_processTabs:function(){this._superApply(arguments),this._addClass(this.tabs,"ui-tab")}}),t.ui.tabs,t.widget("ui.tooltip",{version:"1.12.1",options:{classes:{"ui-tooltip":"ui-corner-all ui-widget-shadow"},content:function(){var e=t(this).attr("title")||"";return t("<a>").text(e).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,track:!1,close:null,open:null},_addDescribedBy:function(e,i){var s=(e.attr("aria-describedby")||"").split(/\s+/);s.push(i),e.data("ui-tooltip-id",i).attr("aria-describedby",t.trim(s.join(" ")))},_removeDescribedBy:function(e){var i=e.data("ui-tooltip-id"),s=(e.attr("aria-describedby")||"").split(/\s+/),n=t.inArray(i,s);-1!==n&&s.splice(n,1),e.removeData("ui-tooltip-id"),s=t.trim(s.join(" ")),s?e.attr("aria-describedby",s):e.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.liveRegion=t("<div>").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this.disabledTitles=t([])},_setOption:function(e,i){var s=this;this._super(e,i),"content"===e&&t.each(this.tooltips,function(t,e){s._updateContent(e.element)})},_setOptionDisabled:function(t){this[t?"_disable":"_enable"]()},_disable:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s.element[0],e.close(n,!0)}),this.disabledTitles=this.disabledTitles.add(this.element.find(this.options.items).addBack().filter(function(){var e=t(this);return e.is("[title]")?e.data("ui-tooltip-title",e.attr("title")).removeAttr("title"):void 0}))},_enable:function(){this.disabledTitles.each(function(){var e=t(this);e.data("ui-tooltip-title")&&e.attr("title",e.data("ui-tooltip-title"))}),this.disabledTitles=t([])},open:function(e){var i=this,s=t(e?e.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),e&&"mouseover"===e.type&&s.parents().each(function(){var e,s=t(this);s.data("ui-tooltip-open")&&(e=t.Event("blur"),e.target=e.currentTarget=this,i.close(e,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._registerCloseHandlers(e,s),this._updateContent(s,e))},_updateContent:function(t,e){var i,s=this.options.content,n=this,o=e?e.type:null;return"string"==typeof s||s.nodeType||s.jquery?this._open(e,t,s):(i=s.call(t[0],function(i){n._delay(function(){t.data("ui-tooltip-open")&&(e&&(e.type=o),this._open(e,t,i))})}),i&&this._open(e,t,i),void 0)},_open:function(e,i,s){function n(t){l.of=t,a.is(":hidden")||a.position(l)}var o,a,r,h,l=t.extend({},this.options.position);if(s){if(o=this._find(i))return o.tooltip.find(".ui-tooltip-content").html(s),void 0;i.is("[title]")&&(e&&"mouseover"===e.type?i.attr("title",""):i.removeAttr("title")),o=this._tooltip(i),a=o.tooltip,this._addDescribedBy(i,a.attr("id")),a.find(".ui-tooltip-content").html(s),this.liveRegion.children().hide(),h=t("<div>").html(a.find(".ui-tooltip-content").html()),h.removeAttr("name").find("[name]").removeAttr("name"),h.removeAttr("id").find("[id]").removeAttr("id"),h.appendTo(this.liveRegion),this.options.track&&e&&/^mouse/.test(e.type)?(this._on(this.document,{mousemove:n}),n(e)):a.position(t.extend({of:i},this.options.position)),a.hide(),this._show(a,this.options.show),this.options.track&&this.options.show&&this.options.show.delay&&(r=this.delayedShow=setInterval(function(){a.is(":visible")&&(n(l.of),clearInterval(r))},t.fx.interval)),this._trigger("open",e,{tooltip:a})}},_registerCloseHandlers:function(e,i){var s={keyup:function(e){if(e.keyCode===t.ui.keyCode.ESCAPE){var s=t.Event(e);s.currentTarget=i[0],this.close(s,!0)}}};i[0]!==this.element[0]&&(s.remove=function(){this._removeTooltip(this._find(i).tooltip)}),e&&"mouseover"!==e.type||(s.mouseleave="close"),e&&"focusin"!==e.type||(s.focusout="close"),this._on(!0,i,s)},close:function(e){var i,s=this,n=t(e?e.currentTarget:this.element),o=this._find(n);return o?(i=o.tooltip,o.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&!n.attr("title")&&n.attr("title",n.data("ui-tooltip-title")),this._removeDescribedBy(n),o.hiding=!0,i.stop(!0),this._hide(i,this.options.hide,function(){s._removeTooltip(t(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),e&&"mouseleave"===e.type&&t.each(this.parents,function(e,i){t(i.element).attr("title",i.title),delete s.parents[e]}),o.closing=!0,this._trigger("close",e,{tooltip:i}),o.hiding||(o.closing=!1)),void 0):(n.removeData("ui-tooltip-open"),void 0)},_tooltip:function(e){var i=t("<div>").attr("role","tooltip"),s=t("<div>").appendTo(i),n=i.uniqueId().attr("id");return this._addClass(s,"ui-tooltip-content"),this._addClass(i,"ui-tooltip","ui-widget ui-widget-content"),i.appendTo(this._appendTo(e)),this.tooltips[n]={element:e,tooltip:i}},_find:function(t){var e=t.data("ui-tooltip-id");return e?this.tooltips[e]:null},_removeTooltip:function(t){t.remove(),delete this.tooltips[t.attr("id")]},_appendTo:function(t){var e=t.closest(".ui-front, dialog");return e.length||(e=this.document[0].body),e},_destroy:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur"),o=s.element;n.target=n.currentTarget=o[0],e.close(n,!0),t("#"+i).remove(),o.data("ui-tooltip-title")&&(o.attr("title")||o.attr("title",o.data("ui-tooltip-title")),o.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}}),t.uiBackCompat!==!1&&t.widget("ui.tooltip",t.ui.tooltip,{options:{tooltipClass:null},_tooltip:function(){var t=this._superApply(arguments);return this.options.tooltipClass&&t.tooltip.addClass(this.options.tooltipClass),t}}),t.ui.tooltip}); \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery.ui.touch-punch.min.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery.ui.touch-punch.min.js new file mode 100644 index 0000000..31272ce --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery.ui.touch-punch.min.js @@ -0,0 +1,11 @@ +/*! + * jQuery UI Touch Punch 0.2.3 + * + * Copyright 2011–2014, Dave Furfero + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Depends: + * jquery.ui.widget.js + * jquery.ui.mouse.js + */ +!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery); \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js new file mode 100644 index 0000000..49a02c2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js @@ -0,0 +1,235 @@ +(function() { + function indentLine(str,length) { + if (length <= 0) { + return str; + } + var i = (new Array(length)).join(" "); + str = str.replace(/^\s*/,i); + return str; + } + function formatExpression(str) { + var length = str.length; + var start = 0; + var inString = false; + var inRegex = false; + var inBox = false; + var quoteChar; + var list = []; + var stack = []; + var frame; + var v; + var matchingBrackets = { + "(":")", + "[":"]", + "{":"}" + } + for (var i=0;i<length;i++) { + var c = str[i]; + if (!inString && !inRegex) { + if (c === "/") { + inRegex = true; + frame = {type:"regex",pos:i}; + list.push(frame); + stack.push(frame); + } else if (c === "'" || c === '"') { + inString = true; + quoteChar = c; + frame = {type:"string",pos:i}; + list.push(frame); + stack.push(frame); + } else if (c === ";") { + frame = {type:";",pos:i}; + list.push(frame); + } else if (c === ",") { + frame = {type:",",pos:i}; + list.push(frame); + } else if (c === "&") { + frame = {type:"&",pos:i}; + list.push(frame); + } else if (/[\(\[\{]/.test(c)) { + frame = {type:"open-block",char:c,pos:i}; + list.push(frame); + stack.push(frame); + } else if (/[\}\)\]]/.test(c)) { + var oldFrame = stack.pop(); + if (matchingBrackets[oldFrame.char] !== c) { + // console.log("Stack frame mismatch",c,"at",i,"expected",matchingBrackets[oldFrame.char],"from",oldFrame.pos); + // console.log(list); + return str; + } + //console.log("Closing",c,"at",i,"compare",oldFrame.type,oldFrame.pos); + oldFrame.width = i-oldFrame.pos; + frame = {type:"close-block",pos:i,char:c,width:oldFrame.width} + list.push(frame); + } + } else { + if (c === "\\") { + // an escaped char - stay in current mode and skip the next char + i++; + } + if (inString) { + if (c === quoteChar) { + // Next char must be a ] + inString = false; + var f = stack.pop(); + f.end = i; + } + } else if (inRegex) { + if (c === "/") { + inRegex = false; + var f = stack.pop(); + f.end = i; + } + } + } + } + // console.log("list",list); + + var result = str; + var indent = 0; + var offset = 0; + var pre,post,indented,hasNewline; + var longStack = []; + list.forEach(function(f) { + if (f.type === ";" || f.type === ",") { + if (longStack[longStack.length-1]) { + pre = result.substring(0,offset+f.pos+1); + post = result.substring(offset+f.pos+1); + indented = indentLine(post,indent); + hasNewline = /\n$/.test(pre); + // console.log("A§"+pre+"§\n§"+indented+"§",hasNewline); + result = pre+(hasNewline?"":"\n")+indented; + offset += indented.length-post.length+(hasNewline?0:1); + } + } else if (f.type === "&") { + pre = result.substring(0,offset+f.pos+1); + var lastLineBreak = pre.lastIndexOf("\n"); + var lineLength = pre.length - lastLineBreak; + if (lineLength > 70) { + post = result.substring(offset+f.pos+1); + if (!/^\n/.test(post)) { + indented = indentLine(post,indent); + hasNewline = /\n$/.test(pre); + result = pre+(hasNewline?"":"\n")+indented; + offset += indented.length-post.length+(hasNewline?0:1); + } + } + + } else if (f.type === "open-block") { + if (f.width > 40) { + longStack.push(true); + indent += 4; + pre = result.substring(0,offset+f.pos+1); + post = result.substring(offset+f.pos+1); + hasNewline = /\n$/.test(pre); + indented = indentLine(post,indent); + result = pre+(hasNewline?"":"\n")+indented; + offset += indented.length-post.length+(hasNewline?0:1); + } else { + longStack.push(false); + } + } else if (f.type === "close-block") { + if (f.width > 40) { + indent -= 4; + pre = result.substring(0,offset+f.pos); + post = result.substring(offset+f.pos); + indented = indentLine(post,indent); + hasNewline = /\n *$/.test(pre); + if (hasNewline) { + result = pre + post; + } else { + result = pre+"\n"+indented; + offset += indented.length-post.length+1; + } + } + longStack.pop(); + } + }) + //console.log(result); + return result; + } + + jsonata.format = formatExpression; + jsonata.functions = + { + '$abs':{ args:[ 'number' ]}, + '$append':{ args:[ 'array1', 'array2' ]}, + '$assert':{ args: [ 'arg', 'str' ]}, + '$average':{ args:[ 'array' ]}, + '$base64decode':{ args:[ ]}, + '$base64encode':{ args:[ ]}, + '$boolean':{ args:[ 'arg' ]}, + '$ceil':{ args:[ 'number' ]}, + '$contains':{ args:[ 'str', 'pattern' ]}, + '$count':{ args:[ 'array' ]}, + '$decodeUrl':{ args:[ 'str' ]}, + '$decodeUrlComponent':{ args:[ 'str' ]}, + '$distinct':{ args:[ 'array' ]}, + '$each':{ args:[ 'object', 'function' ]}, + '$encodeUrl':{ args: ['str'] }, + '$encodeUrlComponent':{ args:[ 'str' ]}, + '$env': { args:[ 'arg' ]}, + '$error':{ args:[ 'str' ]}, + '$eval': { args: ['expr', 'context']}, + '$exists':{ args:[ 'arg' ]}, + '$filter':{ args:[ 'array', 'function' ]}, + '$floor':{ args:[ 'number' ]}, + '$flowContext': {args:['string']}, + '$formatBase': {args:['number','radix']}, + '$formatInteger': {args:['number', 'picture']}, + '$formatNumber': {args:['number', 'picture', 'options']}, + '$fromMillis': {args:['number']}, + '$globalContext': {args:['string']}, + '$join':{ args:[ 'array', 'separator' ]}, + '$keys':{ args:[ 'object' ]}, + '$length':{ args:[ 'str' ]}, + '$lookup':{ args:[ 'object', 'key' ]}, + '$lowercase':{ args:[ 'str' ]}, + '$map':{ args:[ 'array', 'function' ]}, + '$match':{ args:[ 'str', 'pattern', 'limit' ]}, + '$max':{ args:[ 'array' ]}, + '$merge':{ args:[ 'array' ]}, + '$millis':{ args:[ ]}, + '$min':{ args:[ 'array' ]}, + '$not':{ args:[ 'arg' ]}, + '$now':{ args:[ ]}, + '$number':{ args:[ 'arg' ]}, + '$pad': {args:['str', 'width','char']}, + '$parseInteger': {args:['string', 'picture']}, + '$power':{ args:[ 'base', 'exponent' ]}, + '$random':{ args:[ ]}, + '$reduce':{ args:[ 'array', 'function' , 'init' ]}, + '$replace':{ args:[ 'str', 'pattern', 'replacement', 'limit' ]}, + '$reverse':{ args:[ 'array' ]}, + '$round':{ args:[ 'number', 'precision' ]}, + '$shuffle':{ args:[ 'array' ]}, + '$sift':{ args: ['object', 'function'] }, + '$single':{ args: ['array', 'function'] }, + '$sort':{ args:[ 'array', 'function' ]}, + '$split':{ args:[ 'str', 'separator', 'limit' ]}, + '$spread':{ args:[ 'object' ]}, + '$sqrt':{ args:[ 'number' ]}, + '$string':{ args:[ 'arg', 'prettify' ]}, + '$substring':{ args:[ 'str', 'start', 'length' ]}, + '$substringAfter':{ args:[ 'str', 'chars' ]}, + '$substringBefore':{ args:[ 'str', 'chars' ]}, + '$sum':{ args:[ 'array' ]}, + '$toMillis':{args:['timestamp']}, // <------------- + '$trim':{ args:[ 'str' ]}, + '$type':{ args:['value']}, + '$uppercase':{ args:[ 'str' ]}, + '$zip':{ args:[ 'array1' ]} + } + jsonata.getFunctionSnippet = function(fn) { + var snippetText = ""; + if (jsonata.functions.hasOwnProperty(fn)) { + var def = jsonata.functions[fn]; + snippetText = "\\"+fn+"("; + if (def.args) { + snippetText += def.args.map(function(a,i) { return "${"+(i+1)+":"+a+"}"}).join(", "); + } + snippetText += ")\n" + } + return snippetText; + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/mode-jsonata.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/mode-jsonata.js new file mode 100644 index 0000000..4835851 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/mode-jsonata.js @@ -0,0 +1,156 @@ +ace.define("ace/mode/jsonata",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules","ace/worker/worker_client","ace/mode/text"], function(require, exports, module) { + + "use strict"; + + var oop = require("../lib/oop"); + var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + + var WorkerClient = require("../worker/worker_client").WorkerClient; + var jsonataFunctions = Object.keys(jsonata.functions); + // sort in length order (long->short) otherwise substringAfter gets matched + // as substring etc. + jsonataFunctions.sort(function(A,B) { + return B.length-A.length; + }); + jsonataFunctions = jsonataFunctions.join("|").replace(/\$/g,"\\$"); + + var JSONataHighlightRules = function() { + + var keywordMapper = this.createKeywordMapper({ + "keyword.operator": + "and|or|in", + "constant.language": + "null|Infinity|NaN|undefined", + "constant.language.boolean": + "true|false", + "storage.type": + "function" + }, "identifier"); + this.$rules = { + "start" : [ + { + token: "string.regexp", + regex: "\\/", + next: "regex" + }, + { + token : "string", + regex : "'(?=.)", + next : "qstring" + }, + { + token : "string", + regex : '"(?=.)', + next : "qqstring" + }, + { + token : "constant.numeric", // hex + regex : /0(?:[xX][0-9a-fA-F]+|[bB][01]+)\b/ + }, + { + token : "constant.numeric", // float + regex : /[+-]?\d[\d_]*(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/ + }, + { + token: "keyword", + regex: /λ/ + }, + { + token: "keyword", + regex: jsonataFunctions + }, + { + token : keywordMapper, + regex : "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*" + }, + { + token : "punctuation.operator", + regex : /[.](?![.])/ + }, + { + token : "keyword.operator", + regex : /\|\||<=|>=|\.\.|\*\*|!=|:=|[=<>`!$%&*+\-~\/^]/, + next : "start" + }, + { + token : "punctuation.operator", + regex : /[?:,;.]/, + next : "start" + }, + { + token : "paren.lparen", + regex : /[\[({]/, + next : "start" + }, + { + token : "paren.rparen", + regex : /[\])}]/ + } + ], + "qqstring" : [ + { + token : "string", + regex : '"|$', + next : "start" + }, + { + defaultToken: "string" + } + ], + "qstring" : [ + { + token : "string", + regex : "'|$", + next : "start" + }, + { + defaultToken: "string" + } + ], + "regex" : [ + { + token: "string.regexp", + regex: "\\\\/" + }, + { + token: "string.regexp", + regex: "/[sxngimy]*", + next: "start" + }, + { + defaultToken: "string.regexp" + } + ] + }; + }; + + oop.inherits(JSONataHighlightRules, TextHighlightRules); + + var TextMode = require("./text").Mode; + var Mode = function() { + this.HighlightRules = JSONataHighlightRules; + }; + oop.inherits(Mode, TextMode); + + + (function() { + this.createWorker = function(session) { + var worker = new WorkerClient(["ace"], "ace/mode/jsonata_worker", "JSONataWorker"); + worker.attachToDocument(session.getDocument()); + + worker.on("annotate", function(e) { + session.setAnnotations(e.data); + }); + + worker.on("terminate", function() { + session.clearAnnotations(); + }); + + return worker; + }; + this.$id = "ace/mode/jsonata"; + }).call(Mode.prototype); + + exports.Mode = Mode; + +}); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/snippets-jsonata.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/snippets-jsonata.js new file mode 100644 index 0000000..eda3b1f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/snippets-jsonata.js @@ -0,0 +1,11 @@ +ace.define("ace/snippets/jsonata",["require","exports","module"], function(require, exports, module) { + "use strict"; + var snippetText = ""; + for (var fn in jsonata.functions) { + if (jsonata.functions.hasOwnProperty(fn)) { + snippetText += "# "+fn+"\nsnippet "+fn+"\n\t"+jsonata.getFunctionSnippet(fn)+"\n" + } + } + exports.snippetText = snippetText; + exports.scope = "jsonata"; +}); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/worker-jsonata.js b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/worker-jsonata.js new file mode 100644 index 0000000..ca0fe70 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/worker-jsonata.js @@ -0,0 +1,2140 @@ +// jsonata-es5.min.js is prepended to this file as part of the Grunt build + +;(function(window) { + if (typeof window.window != "undefined" && window.document) + return; + if (window.require && window.define) + return; + + if (!window.console) { + window.console = function() { + var msgs = Array.prototype.slice.call(arguments, 0); + postMessage({type: "log", data: msgs}); + }; + window.console.error = + window.console.warn = + window.console.log = + window.console.trace = window.console; + } + window.window = window; + window.ace = window; + window.onerror = function(message, file, line, col, err) { + postMessage({type: "error", data: { + message: message, + data: err.data, + file: file, + line: line, + col: col, + stack: err.stack + }}); + }; + + window.normalizeModule = function(parentId, moduleName) { + // normalize plugin requires + if (moduleName.indexOf("!") !== -1) { + var chunks = moduleName.split("!"); + return window.normalizeModule(parentId, chunks[0]) + "!" + window.normalizeModule(parentId, chunks[1]); + } + // normalize relative requires + if (moduleName.charAt(0) == ".") { + var base = parentId.split("/").slice(0, -1).join("/"); + moduleName = (base ? base + "/" : "") + moduleName; + + while (moduleName.indexOf(".") !== -1 && previous != moduleName) { + var previous = moduleName; + moduleName = moduleName.replace(/^\.\//, "").replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, ""); + } + } + + return moduleName; + }; + + window.require = function require(parentId, id) { + if (!id) { + id = parentId; + parentId = null; + } + if (!id.charAt) + throw new Error("worker.js require() accepts only (parentId, id) as arguments"); + + id = window.normalizeModule(parentId, id); + + var module = window.require.modules[id]; + if (module) { + if (!module.initialized) { + module.initialized = true; + module.exports = module.factory().exports; + } + return module.exports; + } + + if (!window.require.tlns) + return console.log("unable to load " + id); + + var path = resolveModuleId(id, window.require.tlns); + if (path.slice(-3) != ".js") path += ".js"; + + window.require.id = id; + window.require.modules[id] = {}; // prevent infinite loop on broken modules + importScripts(path); + return window.require(parentId, id); + }; + function resolveModuleId(id, paths) { + var testPath = id, tail = ""; + while (testPath) { + var alias = paths[testPath]; + if (typeof alias == "string") { + return alias + tail; + } else if (alias) { + return alias.location.replace(/\/*$/, "/") + (tail || alias.main || alias.name); + } else if (alias === false) { + return ""; + } + var i = testPath.lastIndexOf("/"); + if (i === -1) break; + tail = testPath.substr(i) + tail; + testPath = testPath.slice(0, i); + } + return id; + } + window.require.modules = {}; + window.require.tlns = {}; + + window.define = function(id, deps, factory) { + if (arguments.length == 2) { + factory = deps; + if (typeof id != "string") { + deps = id; + id = window.require.id; + } + } else if (arguments.length == 1) { + factory = id; + deps = []; + id = window.require.id; + } + + if (typeof factory != "function") { + window.require.modules[id] = { + exports: factory, + initialized: true + }; + return; + } + + if (!deps.length) + // If there is no dependencies, we inject "require", "exports" and + // "module" as dependencies, to provide CommonJS compatibility. + deps = ["require", "exports", "module"]; + + var req = function(childId) { + return window.require(id, childId); + }; + + window.require.modules[id] = { + exports: {}, + factory: function() { + var module = this; + var returnExports = factory.apply(this, deps.map(function(dep) { + switch (dep) { + // Because "require", "exports" and "module" aren't actual + // dependencies, we must handle them seperately. + case "require": return req; + case "exports": return module.exports; + case "module": return module; + // But for all other dependencies, we can just go ahead and + // require them. + default: return req(dep); + } + })); + if (returnExports) + module.exports = returnExports; + return module; + } + }; + }; + window.define.amd = {}; + require.tlns = {}; + window.initBaseUrls = function initBaseUrls(topLevelNamespaces) { + for (var i in topLevelNamespaces) + require.tlns[i] = topLevelNamespaces[i]; + }; + + window.initSender = function initSender() { + + var EventEmitter = window.require("ace/lib/event_emitter").EventEmitter; + var oop = window.require("ace/lib/oop"); + + var Sender = function() {}; + + (function() { + + oop.implement(this, EventEmitter); + + this.callback = function(data, callbackId) { + postMessage({ + type: "call", + id: callbackId, + data: data + }); + }; + + this.emit = function(name, data) { + postMessage({ + type: "event", + name: name, + data: data + }); + }; + + }).call(Sender.prototype); + + return new Sender(); + }; + + var main = window.main = null; + var sender = window.sender = null; + + window.onmessage = function(e) { + var msg = e.data; + if (msg.event && sender) { + sender._signal(msg.event, msg.data); + } + else if (msg.command) { + if (main[msg.command]) + main[msg.command].apply(main, msg.args); + else if (window[msg.command]) + window[msg.command].apply(window, msg.args); + else + throw new Error("Unknown command:" + msg.command); + } + else if (msg.init) { + window.initBaseUrls(msg.tlns); + require("ace/lib/es5-shim"); + sender = window.sender = window.initSender(); + var clazz = require(msg.module)[msg.classname]; + main = window.main = new clazz(sender); + } + }; +})(this); + +define("ace/lib/oop",["require","exports","module"], function(require, exports, module) { + "use strict"; + + exports.inherits = function(ctor, superCtor) { + ctor.super_ = superCtor; + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; + + exports.mixin = function(obj, mixin) { + for (var key in mixin) { + obj[key] = mixin[key]; + } + return obj; + }; + + exports.implement = function(proto, mixin) { + exports.mixin(proto, mixin); + }; + +}); + +define("ace/range",["require","exports","module"], function(require, exports, module) { + "use strict"; + var comparePoints = function(p1, p2) { + return p1.row - p2.row || p1.column - p2.column; + }; + var Range = function(startRow, startColumn, endRow, endColumn) { + this.start = { + row: startRow, + column: startColumn + }; + + this.end = { + row: endRow, + column: endColumn + }; + }; + + (function() { + this.isEqual = function(range) { + return this.start.row === range.start.row && + this.end.row === range.end.row && + this.start.column === range.start.column && + this.end.column === range.end.column; + }; + this.toString = function() { + return ("Range: [" + this.start.row + "/" + this.start.column + + "] -> [" + this.end.row + "/" + this.end.column + "]"); + }; + + this.contains = function(row, column) { + return this.compare(row, column) == 0; + }; + this.compareRange = function(range) { + var cmp, + end = range.end, + start = range.start; + + cmp = this.compare(end.row, end.column); + if (cmp == 1) { + cmp = this.compare(start.row, start.column); + if (cmp == 1) { + return 2; + } else if (cmp == 0) { + return 1; + } else { + return 0; + } + } else if (cmp == -1) { + return -2; + } else { + cmp = this.compare(start.row, start.column); + if (cmp == -1) { + return -1; + } else if (cmp == 1) { + return 42; + } else { + return 0; + } + } + }; + this.comparePoint = function(p) { + return this.compare(p.row, p.column); + }; + this.containsRange = function(range) { + return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0; + }; + this.intersects = function(range) { + var cmp = this.compareRange(range); + return (cmp == -1 || cmp == 0 || cmp == 1); + }; + this.isEnd = function(row, column) { + return this.end.row == row && this.end.column == column; + }; + this.isStart = function(row, column) { + return this.start.row == row && this.start.column == column; + }; + this.setStart = function(row, column) { + if (typeof row == "object") { + this.start.column = row.column; + this.start.row = row.row; + } else { + this.start.row = row; + this.start.column = column; + } + }; + this.setEnd = function(row, column) { + if (typeof row == "object") { + this.end.column = row.column; + this.end.row = row.row; + } else { + this.end.row = row; + this.end.column = column; + } + }; + this.inside = function(row, column) { + if (this.compare(row, column) == 0) { + if (this.isEnd(row, column) || this.isStart(row, column)) { + return false; + } else { + return true; + } + } + return false; + }; + this.insideStart = function(row, column) { + if (this.compare(row, column) == 0) { + if (this.isEnd(row, column)) { + return false; + } else { + return true; + } + } + return false; + }; + this.insideEnd = function(row, column) { + if (this.compare(row, column) == 0) { + if (this.isStart(row, column)) { + return false; + } else { + return true; + } + } + return false; + }; + this.compare = function(row, column) { + if (!this.isMultiLine()) { + if (row === this.start.row) { + return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0); + } + } + + if (row < this.start.row) + return -1; + + if (row > this.end.row) + return 1; + + if (this.start.row === row) + return column >= this.start.column ? 0 : -1; + + if (this.end.row === row) + return column <= this.end.column ? 0 : 1; + + return 0; + }; + this.compareStart = function(row, column) { + if (this.start.row == row && this.start.column == column) { + return -1; + } else { + return this.compare(row, column); + } + }; + this.compareEnd = function(row, column) { + if (this.end.row == row && this.end.column == column) { + return 1; + } else { + return this.compare(row, column); + } + }; + this.compareInside = function(row, column) { + if (this.end.row == row && this.end.column == column) { + return 1; + } else if (this.start.row == row && this.start.column == column) { + return -1; + } else { + return this.compare(row, column); + } + }; + this.clipRows = function(firstRow, lastRow) { + if (this.end.row > lastRow) + var end = {row: lastRow + 1, column: 0}; + else if (this.end.row < firstRow) + var end = {row: firstRow, column: 0}; + + if (this.start.row > lastRow) + var start = {row: lastRow + 1, column: 0}; + else if (this.start.row < firstRow) + var start = {row: firstRow, column: 0}; + + return Range.fromPoints(start || this.start, end || this.end); + }; + this.extend = function(row, column) { + var cmp = this.compare(row, column); + + if (cmp == 0) + return this; + else if (cmp == -1) + var start = {row: row, column: column}; + else + var end = {row: row, column: column}; + + return Range.fromPoints(start || this.start, end || this.end); + }; + + this.isEmpty = function() { + return (this.start.row === this.end.row && this.start.column === this.end.column); + }; + this.isMultiLine = function() { + return (this.start.row !== this.end.row); + }; + this.clone = function() { + return Range.fromPoints(this.start, this.end); + }; + this.collapseRows = function() { + if (this.end.column == 0) + return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0) + else + return new Range(this.start.row, 0, this.end.row, 0) + }; + this.toScreenRange = function(session) { + var screenPosStart = session.documentToScreenPosition(this.start); + var screenPosEnd = session.documentToScreenPosition(this.end); + + return new Range( + screenPosStart.row, screenPosStart.column, + screenPosEnd.row, screenPosEnd.column + ); + }; + this.moveBy = function(row, column) { + this.start.row += row; + this.start.column += column; + this.end.row += row; + this.end.column += column; + }; + + }).call(Range.prototype); + Range.fromPoints = function(start, end) { + return new Range(start.row, start.column, end.row, end.column); + }; + Range.comparePoints = comparePoints; + + Range.comparePoints = function(p1, p2) { + return p1.row - p2.row || p1.column - p2.column; + }; + + + exports.Range = Range; +}); + +define("ace/apply_delta",["require","exports","module"], function(require, exports, module) { + "use strict"; + + function throwDeltaError(delta, errorText){ + console.log("Invalid Delta:", delta); + throw "Invalid Delta: " + errorText; + } + + function positionInDocument(docLines, position) { + return position.row >= 0 && position.row < docLines.length && + position.column >= 0 && position.column <= docLines[position.row].length; + } + + function validateDelta(docLines, delta) { + if (delta.action != "insert" && delta.action != "remove") + throwDeltaError(delta, "delta.action must be 'insert' or 'remove'"); + if (!(delta.lines instanceof Array)) + throwDeltaError(delta, "delta.lines must be an Array"); + if (!delta.start || !delta.end) + throwDeltaError(delta, "delta.start/end must be an present"); + var start = delta.start; + if (!positionInDocument(docLines, delta.start)) + throwDeltaError(delta, "delta.start must be contained in document"); + var end = delta.end; + if (delta.action == "remove" && !positionInDocument(docLines, end)) + throwDeltaError(delta, "delta.end must contained in document for 'remove' actions"); + var numRangeRows = end.row - start.row; + var numRangeLastLineChars = (end.column - (numRangeRows == 0 ? start.column : 0)); + if (numRangeRows != delta.lines.length - 1 || delta.lines[numRangeRows].length != numRangeLastLineChars) + throwDeltaError(delta, "delta.range must match delta lines"); + } + + exports.applyDelta = function(docLines, delta, doNotValidate) { + + var row = delta.start.row; + var startColumn = delta.start.column; + var line = docLines[row] || ""; + switch (delta.action) { + case "insert": + var lines = delta.lines; + if (lines.length === 1) { + docLines[row] = line.substring(0, startColumn) + delta.lines[0] + line.substring(startColumn); + } else { + var args = [row, 1].concat(delta.lines); + docLines.splice.apply(docLines, args); + docLines[row] = line.substring(0, startColumn) + docLines[row]; + docLines[row + delta.lines.length - 1] += line.substring(startColumn); + } + break; + case "remove": + var endColumn = delta.end.column; + var endRow = delta.end.row; + if (row === endRow) { + docLines[row] = line.substring(0, startColumn) + line.substring(endColumn); + } else { + docLines.splice( + row, endRow - row + 1, + line.substring(0, startColumn) + docLines[endRow].substring(endColumn) + ); + } + break; + } + } +}); + +define("ace/lib/event_emitter",["require","exports","module"], function(require, exports, module) { + "use strict"; + + var EventEmitter = {}; + var stopPropagation = function() { this.propagationStopped = true; }; + var preventDefault = function() { this.defaultPrevented = true; }; + + EventEmitter._emit = + EventEmitter._dispatchEvent = function(eventName, e) { + this._eventRegistry || (this._eventRegistry = {}); + this._defaultHandlers || (this._defaultHandlers = {}); + + var listeners = this._eventRegistry[eventName] || []; + var defaultHandler = this._defaultHandlers[eventName]; + if (!listeners.length && !defaultHandler) + return; + + if (typeof e != "object" || !e) + e = {}; + + if (!e.type) + e.type = eventName; + if (!e.stopPropagation) + e.stopPropagation = stopPropagation; + if (!e.preventDefault) + e.preventDefault = preventDefault; + + listeners = listeners.slice(); + for (var i=0; i<listeners.length; i++) { + listeners[i](e, this); + if (e.propagationStopped) + break; + } + + if (defaultHandler && !e.defaultPrevented) + return defaultHandler(e, this); + }; + + + EventEmitter._signal = function(eventName, e) { + var listeners = (this._eventRegistry || {})[eventName]; + if (!listeners) + return; + listeners = listeners.slice(); + for (var i=0; i<listeners.length; i++) + listeners[i](e, this); + }; + + EventEmitter.once = function(eventName, callback) { + var _self = this; + callback && this.addEventListener(eventName, function newCallback() { + _self.removeEventListener(eventName, newCallback); + callback.apply(null, arguments); + }); + }; + + + EventEmitter.setDefaultHandler = function(eventName, callback) { + var handlers = this._defaultHandlers + if (!handlers) + handlers = this._defaultHandlers = {_disabled_: {}}; + + if (handlers[eventName]) { + var old = handlers[eventName]; + var disabled = handlers._disabled_[eventName]; + if (!disabled) + handlers._disabled_[eventName] = disabled = []; + disabled.push(old); + var i = disabled.indexOf(callback); + if (i != -1) + disabled.splice(i, 1); + } + handlers[eventName] = callback; + }; + EventEmitter.removeDefaultHandler = function(eventName, callback) { + var handlers = this._defaultHandlers + if (!handlers) + return; + var disabled = handlers._disabled_[eventName]; + + if (handlers[eventName] == callback) { + var old = handlers[eventName]; + if (disabled) + this.setDefaultHandler(eventName, disabled.pop()); + } else if (disabled) { + var i = disabled.indexOf(callback); + if (i != -1) + disabled.splice(i, 1); + } + }; + + EventEmitter.on = + EventEmitter.addEventListener = function(eventName, callback, capturing) { + this._eventRegistry = this._eventRegistry || {}; + + var listeners = this._eventRegistry[eventName]; + if (!listeners) + listeners = this._eventRegistry[eventName] = []; + + if (listeners.indexOf(callback) == -1) + listeners[capturing ? "unshift" : "push"](callback); + return callback; + }; + + EventEmitter.off = + EventEmitter.removeListener = + EventEmitter.removeEventListener = function(eventName, callback) { + this._eventRegistry = this._eventRegistry || {}; + + var listeners = this._eventRegistry[eventName]; + if (!listeners) + return; + + var index = listeners.indexOf(callback); + if (index !== -1) + listeners.splice(index, 1); + }; + + EventEmitter.removeAllListeners = function(eventName) { + if (this._eventRegistry) this._eventRegistry[eventName] = []; + }; + + exports.EventEmitter = EventEmitter; + +}); + +define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(require, exports, module) { + "use strict"; + + var oop = require("./lib/oop"); + var EventEmitter = require("./lib/event_emitter").EventEmitter; + + var Anchor = exports.Anchor = function(doc, row, column) { + this.$onChange = this.onChange.bind(this); + this.attach(doc); + + if (typeof column == "undefined") + this.setPosition(row.row, row.column); + else + this.setPosition(row, column); + }; + + (function() { + + oop.implement(this, EventEmitter); + this.getPosition = function() { + return this.$clipPositionToDocument(this.row, this.column); + }; + this.getDocument = function() { + return this.document; + }; + this.$insertRight = false; + this.onChange = function(delta) { + if (delta.start.row == delta.end.row && delta.start.row != this.row) + return; + + if (delta.start.row > this.row) + return; + + var point = $getTransformedPoint(delta, {row: this.row, column: this.column}, this.$insertRight); + this.setPosition(point.row, point.column, true); + }; + + function $pointsInOrder(point1, point2, equalPointsInOrder) { + var bColIsAfter = equalPointsInOrder ? point1.column <= point2.column : point1.column < point2.column; + return (point1.row < point2.row) || (point1.row == point2.row && bColIsAfter); + } + + function $getTransformedPoint(delta, point, moveIfEqual) { + var deltaIsInsert = delta.action == "insert"; + var deltaRowShift = (deltaIsInsert ? 1 : -1) * (delta.end.row - delta.start.row); + var deltaColShift = (deltaIsInsert ? 1 : -1) * (delta.end.column - delta.start.column); + var deltaStart = delta.start; + var deltaEnd = deltaIsInsert ? deltaStart : delta.end; // Collapse insert range. + if ($pointsInOrder(point, deltaStart, moveIfEqual)) { + return { + row: point.row, + column: point.column + }; + } + if ($pointsInOrder(deltaEnd, point, !moveIfEqual)) { + return { + row: point.row + deltaRowShift, + column: point.column + (point.row == deltaEnd.row ? deltaColShift : 0) + }; + } + + return { + row: deltaStart.row, + column: deltaStart.column + }; + } + this.setPosition = function(row, column, noClip) { + var pos; + if (noClip) { + pos = { + row: row, + column: column + }; + } else { + pos = this.$clipPositionToDocument(row, column); + } + + if (this.row == pos.row && this.column == pos.column) + return; + + var old = { + row: this.row, + column: this.column + }; + + this.row = pos.row; + this.column = pos.column; + this._signal("change", { + old: old, + value: pos + }); + }; + this.detach = function() { + this.document.removeEventListener("change", this.$onChange); + }; + this.attach = function(doc) { + this.document = doc || this.document; + this.document.on("change", this.$onChange); + }; + this.$clipPositionToDocument = function(row, column) { + var pos = {}; + + if (row >= this.document.getLength()) { + pos.row = Math.max(0, this.document.getLength() - 1); + pos.column = this.document.getLine(pos.row).length; + } + else if (row < 0) { + pos.row = 0; + pos.column = 0; + } + else { + pos.row = row; + pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column)); + } + + if (column < 0) + pos.column = 0; + + return pos; + }; + + }).call(Anchor.prototype); + +}); + +define("ace/document",["require","exports","module","ace/lib/oop","ace/apply_delta","ace/lib/event_emitter","ace/range","ace/anchor"], function(require, exports, module) { + "use strict"; + var oop = require("./lib/oop"); + var applyDelta = require("./apply_delta").applyDelta; + var EventEmitter = require("./lib/event_emitter").EventEmitter; + var Range = require("./range").Range; + var Anchor = require("./anchor").Anchor; + + var Document = function(textOrLines) { + this.$lines = [""]; + if (textOrLines.length === 0) { + this.$lines = [""]; + } else if (Array.isArray(textOrLines)) { + this.insertMergedLines({row: 0, column: 0}, textOrLines); + } else { + this.insert({row: 0, column:0}, textOrLines); + } + }; + + (function() { + + oop.implement(this, EventEmitter); + this.setValue = function(text) { + var len = this.getLength() - 1; + this.remove(new Range(0, 0, len, this.getLine(len).length)); + this.insert({row: 0, column: 0}, text); + }; + this.getValue = function() { + return this.getAllLines().join(this.getNewLineCharacter()); + }; + this.createAnchor = function(row, column) { + return new Anchor(this, row, column); + }; + if ("aaa".split(/a/).length === 0) { + this.$split = function(text) { + return text.replace(/\r\n|\r/g, "\n").split("\n"); + }; + } else { + this.$split = function(text) { + return text.split(/\r\n|\r|\n/); + }; + } + + + this.$detectNewLine = function(text) { + var match = text.match(/^.*?(\r\n|\r|\n)/m); + this.$autoNewLine = match ? match[1] : "\n"; + this._signal("changeNewLineMode"); + }; + this.getNewLineCharacter = function() { + switch (this.$newLineMode) { + case "windows": + return "\r\n"; + case "unix": + return "\n"; + default: + return this.$autoNewLine || "\n"; + } + }; + + this.$autoNewLine = ""; + this.$newLineMode = "auto"; + this.setNewLineMode = function(newLineMode) { + if (this.$newLineMode === newLineMode) + return; + + this.$newLineMode = newLineMode; + this._signal("changeNewLineMode"); + }; + this.getNewLineMode = function() { + return this.$newLineMode; + }; + this.isNewLine = function(text) { + return (text == "\r\n" || text == "\r" || text == "\n"); + }; + this.getLine = function(row) { + return this.$lines[row] || ""; + }; + this.getLines = function(firstRow, lastRow) { + return this.$lines.slice(firstRow, lastRow + 1); + }; + this.getAllLines = function() { + return this.getLines(0, this.getLength()); + }; + this.getLength = function() { + return this.$lines.length; + }; + this.getTextRange = function(range) { + return this.getLinesForRange(range).join(this.getNewLineCharacter()); + }; + this.getLinesForRange = function(range) { + var lines; + if (range.start.row === range.end.row) { + lines = [this.getLine(range.start.row).substring(range.start.column, range.end.column)]; + } else { + lines = this.getLines(range.start.row, range.end.row); + lines[0] = (lines[0] || "").substring(range.start.column); + var l = lines.length - 1; + if (range.end.row - range.start.row == l) + lines[l] = lines[l].substring(0, range.end.column); + } + return lines; + }; + this.insertLines = function(row, lines) { + console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."); + return this.insertFullLines(row, lines); + }; + this.removeLines = function(firstRow, lastRow) { + console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."); + return this.removeFullLines(firstRow, lastRow); + }; + this.insertNewLine = function(position) { + console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."); + return this.insertMergedLines(position, ["", ""]); + }; + this.insert = function(position, text) { + if (this.getLength() <= 1) + this.$detectNewLine(text); + + return this.insertMergedLines(position, this.$split(text)); + }; + this.insertInLine = function(position, text) { + var start = this.clippedPos(position.row, position.column); + var end = this.pos(position.row, position.column + text.length); + + this.applyDelta({ + start: start, + end: end, + action: "insert", + lines: [text] + }, true); + + return this.clonePos(end); + }; + + this.clippedPos = function(row, column) { + var length = this.getLength(); + if (row === undefined) { + row = length; + } else if (row < 0) { + row = 0; + } else if (row >= length) { + row = length - 1; + column = undefined; + } + var line = this.getLine(row); + if (column == undefined) + column = line.length; + column = Math.min(Math.max(column, 0), line.length); + return {row: row, column: column}; + }; + + this.clonePos = function(pos) { + return {row: pos.row, column: pos.column}; + }; + + this.pos = function(row, column) { + return {row: row, column: column}; + }; + + this.$clipPosition = function(position) { + var length = this.getLength(); + if (position.row >= length) { + position.row = Math.max(0, length - 1); + position.column = this.getLine(length - 1).length; + } else { + position.row = Math.max(0, position.row); + position.column = Math.min(Math.max(position.column, 0), this.getLine(position.row).length); + } + return position; + }; + this.insertFullLines = function(row, lines) { + row = Math.min(Math.max(row, 0), this.getLength()); + var column = 0; + if (row < this.getLength()) { + lines = lines.concat([""]); + column = 0; + } else { + lines = [""].concat(lines); + row--; + column = this.$lines[row].length; + } + this.insertMergedLines({row: row, column: column}, lines); + }; + this.insertMergedLines = function(position, lines) { + var start = this.clippedPos(position.row, position.column); + var end = { + row: start.row + lines.length - 1, + column: (lines.length == 1 ? start.column : 0) + lines[lines.length - 1].length + }; + + this.applyDelta({ + start: start, + end: end, + action: "insert", + lines: lines + }); + + return this.clonePos(end); + }; + this.remove = function(range) { + var start = this.clippedPos(range.start.row, range.start.column); + var end = this.clippedPos(range.end.row, range.end.column); + this.applyDelta({ + start: start, + end: end, + action: "remove", + lines: this.getLinesForRange({start: start, end: end}) + }); + return this.clonePos(start); + }; + this.removeInLine = function(row, startColumn, endColumn) { + var start = this.clippedPos(row, startColumn); + var end = this.clippedPos(row, endColumn); + + this.applyDelta({ + start: start, + end: end, + action: "remove", + lines: this.getLinesForRange({start: start, end: end}) + }, true); + + return this.clonePos(start); + }; + this.removeFullLines = function(firstRow, lastRow) { + firstRow = Math.min(Math.max(0, firstRow), this.getLength() - 1); + lastRow = Math.min(Math.max(0, lastRow ), this.getLength() - 1); + var deleteFirstNewLine = lastRow == this.getLength() - 1 && firstRow > 0; + var deleteLastNewLine = lastRow < this.getLength() - 1; + var startRow = ( deleteFirstNewLine ? firstRow - 1 : firstRow ); + var startCol = ( deleteFirstNewLine ? this.getLine(startRow).length : 0 ); + var endRow = ( deleteLastNewLine ? lastRow + 1 : lastRow ); + var endCol = ( deleteLastNewLine ? 0 : this.getLine(endRow).length ); + var range = new Range(startRow, startCol, endRow, endCol); + var deletedLines = this.$lines.slice(firstRow, lastRow + 1); + + this.applyDelta({ + start: range.start, + end: range.end, + action: "remove", + lines: this.getLinesForRange(range) + }); + return deletedLines; + }; + this.removeNewLine = function(row) { + if (row < this.getLength() - 1 && row >= 0) { + this.applyDelta({ + start: this.pos(row, this.getLine(row).length), + end: this.pos(row + 1, 0), + action: "remove", + lines: ["", ""] + }); + } + }; + this.replace = function(range, text) { + if (!(range instanceof Range)) + range = Range.fromPoints(range.start, range.end); + if (text.length === 0 && range.isEmpty()) + return range.start; + if (text == this.getTextRange(range)) + return range.end; + + this.remove(range); + var end; + if (text) { + end = this.insert(range.start, text); + } + else { + end = range.start; + } + + return end; + }; + this.applyDeltas = function(deltas) { + for (var i=0; i<deltas.length; i++) { + this.applyDelta(deltas[i]); + } + }; + this.revertDeltas = function(deltas) { + for (var i=deltas.length-1; i>=0; i--) { + this.revertDelta(deltas[i]); + } + }; + this.applyDelta = function(delta, doNotValidate) { + var isInsert = delta.action == "insert"; + if (isInsert ? delta.lines.length <= 1 && !delta.lines[0] + : !Range.comparePoints(delta.start, delta.end)) { + return; + } + + if (isInsert && delta.lines.length > 20000) + this.$splitAndapplyLargeDelta(delta, 20000); + applyDelta(this.$lines, delta, doNotValidate); + this._signal("change", delta); + }; + + this.$splitAndapplyLargeDelta = function(delta, MAX) { + var lines = delta.lines; + var l = lines.length; + var row = delta.start.row; + var column = delta.start.column; + var from = 0, to = 0; + do { + from = to; + to += MAX - 1; + var chunk = lines.slice(from, to); + if (to > l) { + delta.lines = chunk; + delta.start.row = row + from; + delta.start.column = column; + break; + } + chunk.push(""); + this.applyDelta({ + start: this.pos(row + from, column), + end: this.pos(row + to, column = 0), + action: delta.action, + lines: chunk + }, true); + } while(true); + }; + this.revertDelta = function(delta) { + this.applyDelta({ + start: this.clonePos(delta.start), + end: this.clonePos(delta.end), + action: (delta.action == "insert" ? "remove" : "insert"), + lines: delta.lines.slice() + }); + }; + this.indexToPosition = function(index, startRow) { + var lines = this.$lines || this.getAllLines(); + var newlineLength = this.getNewLineCharacter().length; + for (var i = startRow || 0, l = lines.length; i < l; i++) { + index -= lines[i].length + newlineLength; + if (index < 0) + return {row: i, column: index + lines[i].length + newlineLength}; + } + return {row: l-1, column: lines[l-1].length}; + }; + this.positionToIndex = function(pos, startRow) { + var lines = this.$lines || this.getAllLines(); + var newlineLength = this.getNewLineCharacter().length; + var index = 0; + var row = Math.min(pos.row, lines.length); + for (var i = startRow || 0; i < row; ++i) + index += lines[i].length + newlineLength; + + return index + pos.column; + }; + + }).call(Document.prototype); + + exports.Document = Document; + }); + + define("ace/lib/lang",["require","exports","module"], function(require, exports, module) { + "use strict"; + + exports.last = function(a) { + return a[a.length - 1]; + }; + + exports.stringReverse = function(string) { + return string.split("").reverse().join(""); + }; + + exports.stringRepeat = function (string, count) { + var result = ''; + while (count > 0) { + if (count & 1) + result += string; + + if (count >>= 1) + string += string; + } + return result; + }; + + var trimBeginRegexp = /^\s\s*/; + var trimEndRegexp = /\s\s*$/; + + exports.stringTrimLeft = function (string) { + return string.replace(trimBeginRegexp, ''); + }; + + exports.stringTrimRight = function (string) { + return string.replace(trimEndRegexp, ''); + }; + + exports.copyObject = function(obj) { + var copy = {}; + for (var key in obj) { + copy[key] = obj[key]; + } + return copy; + }; + + exports.copyArray = function(array){ + var copy = []; + for (var i=0, l=array.length; i<l; i++) { + if (array[i] && typeof array[i] == "object") + copy[i] = this.copyObject(array[i]); + else + copy[i] = array[i]; + } + return copy; + }; + + exports.deepCopy = function deepCopy(obj) { + if (typeof obj !== "object" || !obj) + return obj; + var copy; + if (Array.isArray(obj)) { + copy = []; + for (var key = 0; key < obj.length; key++) { + copy[key] = deepCopy(obj[key]); + } + return copy; + } + if (Object.prototype.toString.call(obj) !== "[object Object]") + return obj; + + copy = {}; + for (var key in obj) + copy[key] = deepCopy(obj[key]); + return copy; + }; + + exports.arrayToMap = function(arr) { + var map = {}; + for (var i=0; i<arr.length; i++) { + map[arr[i]] = 1; + } + return map; + + }; + + exports.createMap = function(props) { + var map = Object.create(null); + for (var i in props) { + map[i] = props[i]; + } + return map; + }; + exports.arrayRemove = function(array, value) { + for (var i = 0; i <= array.length; i++) { + if (value === array[i]) { + array.splice(i, 1); + } + } + }; + + exports.escapeRegExp = function(str) { + return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1'); + }; + + exports.escapeHTML = function(str) { + return str.replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;"); + }; + + exports.getMatchOffsets = function(string, regExp) { + var matches = []; + + string.replace(regExp, function(str) { + matches.push({ + offset: arguments[arguments.length-2], + length: str.length + }); + }); + + return matches; + }; + exports.deferredCall = function(fcn) { + var timer = null; + var callback = function() { + timer = null; + fcn(); + }; + + var deferred = function(timeout) { + deferred.cancel(); + timer = setTimeout(callback, timeout || 0); + return deferred; + }; + + deferred.schedule = deferred; + + deferred.call = function() { + this.cancel(); + fcn(); + return deferred; + }; + + deferred.cancel = function() { + clearTimeout(timer); + timer = null; + return deferred; + }; + + deferred.isPending = function() { + return timer; + }; + + return deferred; + }; + + + exports.delayedCall = function(fcn, defaultTimeout) { + var timer = null; + var callback = function() { + timer = null; + fcn(); + }; + + var _self = function(timeout) { + if (timer == null) + timer = setTimeout(callback, timeout || defaultTimeout); + }; + + _self.delay = function(timeout) { + timer && clearTimeout(timer); + timer = setTimeout(callback, timeout || defaultTimeout); + }; + _self.schedule = _self; + + _self.call = function() { + this.cancel(); + fcn(); + }; + + _self.cancel = function() { + timer && clearTimeout(timer); + timer = null; + }; + + _self.isPending = function() { + return timer; + }; + + return _self; + }; + }); + + define("ace/worker/mirror",["require","exports","module","ace/range","ace/document","ace/lib/lang"], function(require, exports, module) { + "use strict"; + + var Range = require("../range").Range; + var Document = require("../document").Document; + var lang = require("../lib/lang"); + + var Mirror = exports.Mirror = function(sender) { + this.sender = sender; + var doc = this.doc = new Document(""); + + var deferredUpdate = this.deferredUpdate = lang.delayedCall(this.onUpdate.bind(this)); + + var _self = this; + sender.on("change", function(e) { + var data = e.data; + if (data[0].start) { + doc.applyDeltas(data); + } else { + for (var i = 0; i < data.length; i += 2) { + if (Array.isArray(data[i+1])) { + var d = {action: "insert", start: data[i], lines: data[i+1]}; + } else { + var d = {action: "remove", start: data[i], end: data[i+1]}; + } + doc.applyDelta(d, true); + } + } + if (_self.$timeout) + return deferredUpdate.schedule(_self.$timeout); + _self.onUpdate(); + }); + }; + + (function() { + + this.$timeout = 500; + + this.setTimeout = function(timeout) { + this.$timeout = timeout; + }; + + this.setValue = function(value) { + this.doc.setValue(value); + this.deferredUpdate.schedule(this.$timeout); + }; + + this.getValue = function(callbackId) { + this.sender.callback(this.doc.getValue(), callbackId); + }; + + this.onUpdate = function() { + }; + + this.isPending = function() { + return this.deferredUpdate.isPending(); + }; + + }).call(Mirror.prototype); + + }); + + define("ace/lib/es5-shim",["require","exports","module"], function(require, exports, module) { + + function Empty() {} + + if (!Function.prototype.bind) { + Function.prototype.bind = function bind(that) { // .length is 1 + var target = this; + if (typeof target != "function") { + throw new TypeError("Function.prototype.bind called on incompatible " + target); + } + var args = slice.call(arguments, 1); // for normal call + var bound = function () { + + if (this instanceof bound) { + + var result = target.apply( + this, + args.concat(slice.call(arguments)) + ); + if (Object(result) === result) { + return result; + } + return this; + + } else { + return target.apply( + that, + args.concat(slice.call(arguments)) + ); + + } + + }; + if(target.prototype) { + Empty.prototype = target.prototype; + bound.prototype = new Empty(); + Empty.prototype = null; + } + return bound; + }; + } + var call = Function.prototype.call; + var prototypeOfArray = Array.prototype; + var prototypeOfObject = Object.prototype; + var slice = prototypeOfArray.slice; + var _toString = call.bind(prototypeOfObject.toString); + var owns = call.bind(prototypeOfObject.hasOwnProperty); + var defineGetter; + var defineSetter; + var lookupGetter; + var lookupSetter; + var supportsAccessors; + if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) { + defineGetter = call.bind(prototypeOfObject.__defineGetter__); + defineSetter = call.bind(prototypeOfObject.__defineSetter__); + lookupGetter = call.bind(prototypeOfObject.__lookupGetter__); + lookupSetter = call.bind(prototypeOfObject.__lookupSetter__); + } + if ([1,2].splice(0).length != 2) { + if(function() { // test IE < 9 to splice bug - see issue #138 + function makeArray(l) { + var a = new Array(l+2); + a[0] = a[1] = 0; + return a; + } + var array = [], lengthBefore; + + array.splice.apply(array, makeArray(20)); + array.splice.apply(array, makeArray(26)); + + lengthBefore = array.length; //46 + array.splice(5, 0, "XXX"); // add one element + + lengthBefore + 1 == array.length + + if (lengthBefore + 1 == array.length) { + return true;// has right splice implementation without bugs + } + }()) {//IE 6/7 + var array_splice = Array.prototype.splice; + Array.prototype.splice = function(start, deleteCount) { + if (!arguments.length) { + return []; + } else { + return array_splice.apply(this, [ + start === void 0 ? 0 : start, + deleteCount === void 0 ? (this.length - start) : deleteCount + ].concat(slice.call(arguments, 2))) + } + }; + } else {//IE8 + Array.prototype.splice = function(pos, removeCount){ + var length = this.length; + if (pos > 0) { + if (pos > length) + pos = length; + } else if (pos == void 0) { + pos = 0; + } else if (pos < 0) { + pos = Math.max(length + pos, 0); + } + + if (!(pos+removeCount < length)) + removeCount = length - pos; + + var removed = this.slice(pos, pos+removeCount); + var insert = slice.call(arguments, 2); + var add = insert.length; + if (pos === length) { + if (add) { + this.push.apply(this, insert); + } + } else { + var remove = Math.min(removeCount, length - pos); + var tailOldPos = pos + remove; + var tailNewPos = tailOldPos + add - remove; + var tailCount = length - tailOldPos; + var lengthAfterRemove = length - remove; + + if (tailNewPos < tailOldPos) { // case A + for (var i = 0; i < tailCount; ++i) { + this[tailNewPos+i] = this[tailOldPos+i]; + } + } else if (tailNewPos > tailOldPos) { // case B + for (i = tailCount; i--; ) { + this[tailNewPos+i] = this[tailOldPos+i]; + } + } // else, add == remove (nothing to do) + + if (add && pos === lengthAfterRemove) { + this.length = lengthAfterRemove; // truncate array + this.push.apply(this, insert); + } else { + this.length = lengthAfterRemove + add; // reserves space + for (i = 0; i < add; ++i) { + this[pos+i] = insert[i]; + } + } + } + return removed; + }; + } + } + if (!Array.isArray) { + Array.isArray = function isArray(obj) { + return _toString(obj) == "[object Array]"; + }; + } + var boxedString = Object("a"), + splitString = boxedString[0] != "a" || !(0 in boxedString); + + if (!Array.prototype.forEach) { + Array.prototype.forEach = function forEach(fun /*, thisp*/) { + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, + thisp = arguments[1], + i = -1, + length = self.length >>> 0; + if (_toString(fun) != "[object Function]") { + throw new TypeError(); // TODO message + } + + while (++i < length) { + if (i in self) { + fun.call(thisp, self[i], i, object); + } + } + }; + } + if (!Array.prototype.map) { + Array.prototype.map = function map(fun /*, thisp*/) { + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, + length = self.length >>> 0, + result = Array(length), + thisp = arguments[1]; + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + for (var i = 0; i < length; i++) { + if (i in self) + result[i] = fun.call(thisp, self[i], i, object); + } + return result; + }; + } + if (!Array.prototype.filter) { + Array.prototype.filter = function filter(fun /*, thisp */) { + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, + length = self.length >>> 0, + result = [], + value, + thisp = arguments[1]; + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + for (var i = 0; i < length; i++) { + if (i in self) { + value = self[i]; + if (fun.call(thisp, value, i, object)) { + result.push(value); + } + } + } + return result; + }; + } + if (!Array.prototype.every) { + Array.prototype.every = function every(fun /*, thisp */) { + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, + length = self.length >>> 0, + thisp = arguments[1]; + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + for (var i = 0; i < length; i++) { + if (i in self && !fun.call(thisp, self[i], i, object)) { + return false; + } + } + return true; + }; + } + if (!Array.prototype.some) { + Array.prototype.some = function some(fun /*, thisp */) { + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, + length = self.length >>> 0, + thisp = arguments[1]; + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + for (var i = 0; i < length; i++) { + if (i in self && fun.call(thisp, self[i], i, object)) { + return true; + } + } + return false; + }; + } + if (!Array.prototype.reduce) { + Array.prototype.reduce = function reduce(fun /*, initial*/) { + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, + length = self.length >>> 0; + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + if (!length && arguments.length == 1) { + throw new TypeError("reduce of empty array with no initial value"); + } + + var i = 0; + var result; + if (arguments.length >= 2) { + result = arguments[1]; + } else { + do { + if (i in self) { + result = self[i++]; + break; + } + if (++i >= length) { + throw new TypeError("reduce of empty array with no initial value"); + } + } while (true); + } + + for (; i < length; i++) { + if (i in self) { + result = fun.call(void 0, result, self[i], i, object); + } + } + + return result; + }; + } + if (!Array.prototype.reduceRight) { + Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) { + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, + length = self.length >>> 0; + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + if (!length && arguments.length == 1) { + throw new TypeError("reduceRight of empty array with no initial value"); + } + + var result, i = length - 1; + if (arguments.length >= 2) { + result = arguments[1]; + } else { + do { + if (i in self) { + result = self[i--]; + break; + } + if (--i < 0) { + throw new TypeError("reduceRight of empty array with no initial value"); + } + } while (true); + } + + do { + if (i in this) { + result = fun.call(void 0, result, self[i], i, object); + } + } while (i--); + + return result; + }; + } + if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) { + Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) { + var self = splitString && _toString(this) == "[object String]" ? + this.split("") : + toObject(this), + length = self.length >>> 0; + + if (!length) { + return -1; + } + + var i = 0; + if (arguments.length > 1) { + i = toInteger(arguments[1]); + } + i = i >= 0 ? i : Math.max(0, length + i); + for (; i < length; i++) { + if (i in self && self[i] === sought) { + return i; + } + } + return -1; + }; + } + if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) { + Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) { + var self = splitString && _toString(this) == "[object String]" ? + this.split("") : + toObject(this), + length = self.length >>> 0; + + if (!length) { + return -1; + } + var i = length - 1; + if (arguments.length > 1) { + i = Math.min(i, toInteger(arguments[1])); + } + i = i >= 0 ? i : length - Math.abs(i); + for (; i >= 0; i--) { + if (i in self && sought === self[i]) { + return i; + } + } + return -1; + }; + } + if (!Object.getPrototypeOf) { + Object.getPrototypeOf = function getPrototypeOf(object) { + return object.__proto__ || ( + object.constructor ? + object.constructor.prototype : + prototypeOfObject + ); + }; + } + if (!Object.getOwnPropertyDescriptor) { + var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " + + "non-object: "; + Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) { + if ((typeof object != "object" && typeof object != "function") || object === null) + throw new TypeError(ERR_NON_OBJECT + object); + if (!owns(object, property)) + return; + + var descriptor, getter, setter; + descriptor = { enumerable: true, configurable: true }; + if (supportsAccessors) { + var prototype = object.__proto__; + object.__proto__ = prototypeOfObject; + + var getter = lookupGetter(object, property); + var setter = lookupSetter(object, property); + object.__proto__ = prototype; + + if (getter || setter) { + if (getter) descriptor.get = getter; + if (setter) descriptor.set = setter; + return descriptor; + } + } + descriptor.value = object[property]; + return descriptor; + }; + } + if (!Object.getOwnPropertyNames) { + Object.getOwnPropertyNames = function getOwnPropertyNames(object) { + return Object.keys(object); + }; + } + if (!Object.create) { + var createEmpty; + if (Object.prototype.__proto__ === null) { + createEmpty = function () { + return { "__proto__": null }; + }; + } else { + createEmpty = function () { + var empty = {}; + for (var i in empty) + empty[i] = null; + empty.constructor = + empty.hasOwnProperty = + empty.propertyIsEnumerable = + empty.isPrototypeOf = + empty.toLocaleString = + empty.toString = + empty.valueOf = + empty.__proto__ = null; + return empty; + } + } + + Object.create = function create(prototype, properties) { + var object; + if (prototype === null) { + object = createEmpty(); + } else { + if (typeof prototype != "object") + throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'"); + var Type = function () {}; + Type.prototype = prototype; + object = new Type(); + object.__proto__ = prototype; + } + if (properties !== void 0) + Object.defineProperties(object, properties); + return object; + }; + } + + function doesDefinePropertyWork(object) { + try { + Object.defineProperty(object, "sentinel", {}); + return "sentinel" in object; + } catch (exception) { + } + } + if (Object.defineProperty) { + var definePropertyWorksOnObject = doesDefinePropertyWork({}); + var definePropertyWorksOnDom = typeof document == "undefined" || + doesDefinePropertyWork(document.createElement("div")); + if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) { + var definePropertyFallback = Object.defineProperty; + } + } + + if (!Object.defineProperty || definePropertyFallback) { + var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: "; + var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: " + var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " + + "on this javascript engine"; + + Object.defineProperty = function defineProperty(object, property, descriptor) { + if ((typeof object != "object" && typeof object != "function") || object === null) + throw new TypeError(ERR_NON_OBJECT_TARGET + object); + if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null) + throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor); + if (definePropertyFallback) { + try { + return definePropertyFallback.call(Object, object, property, descriptor); + } catch (exception) { + } + } + if (owns(descriptor, "value")) { + + if (supportsAccessors && (lookupGetter(object, property) || + lookupSetter(object, property))) + { + var prototype = object.__proto__; + object.__proto__ = prototypeOfObject; + delete object[property]; + object[property] = descriptor.value; + object.__proto__ = prototype; + } else { + object[property] = descriptor.value; + } + } else { + if (!supportsAccessors) + throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED); + if (owns(descriptor, "get")) + defineGetter(object, property, descriptor.get); + if (owns(descriptor, "set")) + defineSetter(object, property, descriptor.set); + } + + return object; + }; + } + if (!Object.defineProperties) { + Object.defineProperties = function defineProperties(object, properties) { + for (var property in properties) { + if (owns(properties, property)) + Object.defineProperty(object, property, properties[property]); + } + return object; + }; + } + if (!Object.seal) { + Object.seal = function seal(object) { + return object; + }; + } + if (!Object.freeze) { + Object.freeze = function freeze(object) { + return object; + }; + } + try { + Object.freeze(function () {}); + } catch (exception) { + Object.freeze = (function freeze(freezeObject) { + return function freeze(object) { + if (typeof object == "function") { + return object; + } else { + return freezeObject(object); + } + }; + })(Object.freeze); + } + if (!Object.preventExtensions) { + Object.preventExtensions = function preventExtensions(object) { + return object; + }; + } + if (!Object.isSealed) { + Object.isSealed = function isSealed(object) { + return false; + }; + } + if (!Object.isFrozen) { + Object.isFrozen = function isFrozen(object) { + return false; + }; + } + if (!Object.isExtensible) { + Object.isExtensible = function isExtensible(object) { + if (Object(object) === object) { + throw new TypeError(); // TODO message + } + var name = ''; + while (owns(object, name)) { + name += '?'; + } + object[name] = true; + var returnValue = owns(object, name); + delete object[name]; + return returnValue; + }; + } + if (!Object.keys) { + var hasDontEnumBug = true, + dontEnums = [ + "toString", + "toLocaleString", + "valueOf", + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable", + "constructor" + ], + dontEnumsLength = dontEnums.length; + + for (var key in {"toString": null}) { + hasDontEnumBug = false; + } + + Object.keys = function keys(object) { + + if ( + (typeof object != "object" && typeof object != "function") || + object === null + ) { + throw new TypeError("Object.keys called on a non-object"); + } + + var keys = []; + for (var name in object) { + if (owns(object, name)) { + keys.push(name); + } + } + + if (hasDontEnumBug) { + for (var i = 0, ii = dontEnumsLength; i < ii; i++) { + var dontEnum = dontEnums[i]; + if (owns(object, dontEnum)) { + keys.push(dontEnum); + } + } + } + return keys; + }; + + } + if (!Date.now) { + Date.now = function now() { + return new Date().getTime(); + }; + } + var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" + + "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" + + "\u2029\uFEFF"; + if (!String.prototype.trim || ws.trim()) { + ws = "[" + ws + "]"; + var trimBeginRegexp = new RegExp("^" + ws + ws + "*"), + trimEndRegexp = new RegExp(ws + ws + "*$"); + String.prototype.trim = function trim() { + return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, ""); + }; + } + + function toInteger(n) { + n = +n; + if (n !== n) { // isNaN + n = 0; + } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) { + n = (n > 0 || -1) * Math.floor(Math.abs(n)); + } + return n; + } + + function isPrimitive(input) { + var type = typeof input; + return ( + input === null || + type === "undefined" || + type === "boolean" || + type === "number" || + type === "string" + ); + } + + function toPrimitive(input) { + var val, valueOf, toString; + if (isPrimitive(input)) { + return input; + } + valueOf = input.valueOf; + if (typeof valueOf === "function") { + val = valueOf.call(input); + if (isPrimitive(val)) { + return val; + } + } + toString = input.toString; + if (typeof toString === "function") { + val = toString.call(input); + if (isPrimitive(val)) { + return val; + } + } + throw new TypeError(); + } + var toObject = function (o) { + if (o == null) { // this matches both null and undefined + throw new TypeError("can't convert "+o+" to object"); + } + return Object(o); + }; + + }); + define("ace/mode/jsonata_worker",["require","exports","ace/lib/oop","ace/worker/mirror"], function(require, exports) { + var oop = require("../lib/oop"); + var Mirror = require("../worker/mirror").Mirror; + + var JSONataWorker = exports.JSONataWorker = function(sender) { + Mirror.call(this, sender); + this.setTimeout(200); + }; + + oop.inherits(JSONataWorker, Mirror); + + (function() { + + this.onUpdate = function() { + var value = this.doc.getValue(); + var errors = []; + try { + if (value) { + jsonata(value); + } + } catch (e) { + var pos = this.doc.indexToPosition(e.position-1); + var msg = e.message; + msg = msg.replace(/ at column \d+/,""); + errors.push({ + row: pos.row, + column: pos.column, + text: msg, + type: "error" + }); + } + this.sender.emit("annotate", errors); + }; + + }).call(JSONataWorker.prototype); + + }); diff --git a/packages/connector/packages/node_modules/@node-red/editor-client/templates/index.mst b/packages/connector/packages/node_modules/@node-red/editor-client/templates/index.mst new file mode 100644 index 0000000..0cacd19 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/editor-client/templates/index.mst @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<meta http-equiv="X-UA-Compatible" content="IE=edge" /> +<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/> +<meta name="apple-mobile-web-app-capable" content="yes"> +<meta name="mobile-web-app-capable" content="yes"> +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<title>{{ page.title }}</title> +<link rel="icon" type="image/png" href="{{ page.favicon }}"> +<link rel="mask-icon" href="{{ page.tabicon }}" color="#8f0000"> +<link rel="stylesheet" href="vendor/jquery/css/base/jquery-ui.min.css"> +<link rel="stylesheet" href="vendor/font-awesome/css/font-awesome.min.css"> +<link rel="stylesheet" href="red/style.min.css"> +{{#page.css}} +<link rel="stylesheet" href="{{.}}"> +{{/page.css}} +</head> +<body spellcheck="false"> +<div id="red-ui-editor"></div> +<script src="vendor/vendor.js"></script> +<script src="{{ asset.red }}"></script> +<script src="{{ asset.main }}"></script> +{{# page.scripts }} +<script src="{{.}}"></script> +{{/ page.scripts }} + +</body> +</html> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/.npmignore b/packages/connector/packages/node_modules/@node-red/nodes/.npmignore new file mode 100644 index 0000000..99c96b4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/.npmignore @@ -0,0 +1,2 @@ +src +docs diff --git a/packages/connector/packages/node_modules/@node-red/nodes/99-sample.html.demo b/packages/connector/packages/node_modules/@node-red/nodes/99-sample.html.demo new file mode 100644 index 0000000..467815f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/99-sample.html.demo @@ -0,0 +1,80 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!-- Sample html file that corresponds to the 99-sample.js file --> +<!-- This creates and configures the onscreen elements of the node --> + +<!-- If you use this as a template, update the copyright with your own name. --> + +<!-- First, the content of the edit dialog is defined. --> + +<script type="text/x-red" data-template-name="sample"> + <!-- data-template-name identifies the node type this is for --> + + <!-- Each of the following divs creates a field in the edit dialog. --> + <!-- Generally, there should be an input for each property of the node. --> + <!-- The for and id attributes identify the corresponding property --> + <!-- (with the 'node-input-' prefix). --> + <!-- The available icon classes are defined Font Awesome Icons (FA Icons) --> + <div class="form-row"> + <label for="node-input-topic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label> + <input type="text" id="node-input-topic" data-i18n="[placeholder]common.label.topic"> + </div> + + <br/> + <!-- By convention, most nodes have a 'name' property. The following div --> + <!-- provides the necessary field. Should always be the last option --> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> + + +<!-- Next, some simple help text is provided for the node. --> +<script type="text/x-red" data-help-name="sample"> + <!-- data-help-name identifies the node type this help is for --> + <!-- This content appears in the Info sidebar when a node is selected --> + <!-- The first <p> is used as the pop-up tool tip when hovering over a --> + <!-- node in the palette. --> + <p>Simple sample input node. Just sends a single message when it starts up. + This is not very useful.</p> + <p>Outputs an object called <code>msg</code> containing <code>msg.topic</code> and + <code>msg.payload</code>. msg.payload is a String.</p> +</script> + +<!-- Finally, the node type is registered along with all of its properties --> +<!-- The example below shows a small subset of the properties that can be set--> +<script type="text/javascript"> + RED.nodes.registerType('sample',{ + category: 'input', // the palette category + defaults: { // defines the editable properties of the node + name: {value:""}, // along with default values. + topic: {value:"", required:true} + }, + inputs:1, // set the number of inputs - only 0 or 1 + outputs:1, // set the number of outputs - 0 to n + color: "#ddd", // set icon color + // set the icon (held in icons dir below where you save the node) + icon: "myicon.png", // saved in icons/myicon.png + label: function() { // sets the default label contents + return this.name||this.topic||"sample"; + }, + labelStyle: function() { // sets the class to apply to the label + return this.name?"node_label_italic":""; + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/99-sample.js.demo b/packages/connector/packages/node_modules/@node-red/nodes/99-sample.js.demo new file mode 100644 index 0000000..5648458 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/99-sample.js.demo @@ -0,0 +1,68 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +// If you use this as a template, update the copyright with your own name. + +// Sample Node-RED node file + + +module.exports = function(RED) { + "use strict"; + // require any external libraries we may need.... + //var foo = require("foo-library"); + + // The main node definition - most things happen in here + function SampleNode(n) { + // Create a RED node + RED.nodes.createNode(this,n); + + // Store local copies of the node configuration (as defined in the .html) + this.topic = n.topic; + + // copy "this" object in case we need it in context of callbacks of other functions. + var node = this; + + // Do whatever you need to do in here - declare callbacks etc + // Note: this sample doesn't do anything much - it will only send + // this message once at startup... + // Look at other real nodes for some better ideas of what to do.... + var msg = {}; + msg.topic = this.topic; + msg.payload = "Hello world !" + + // send out the message to the rest of the workspace. + // ... this message will get sent at startup so you may not see it in a debug node. + this.send(msg); + + // respond to inputs.... + this.on('input', function (msg) { + node.warn("I saw a payload: "+msg.payload); + // in this example just send it straight on... should process it here really + node.send(msg); + }); + + this.on("close", function() { + // Called when the node is shutdown - eg on redeploy. + // Allows ports to be closed, connections dropped etc. + // eg: node.client.disconnect(); + }); + } + + // Register the node by name. This must be called before overriding any of the + // Node functions. + RED.nodes.registerType("sample",SampleNode); + +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/LICENSE b/packages/connector/packages/node_modules/@node-red/nodes/LICENSE new file mode 100644 index 0000000..fc619bd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/LICENSE @@ -0,0 +1,178 @@ +Copyright JS Foundation and other contributors, http://js.foundation + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/packages/connector/packages/node_modules/@node-red/nodes/README.md b/packages/connector/packages/node_modules/@node-red/nodes/README.md new file mode 100644 index 0000000..89b5ad7 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/README.md @@ -0,0 +1,10 @@ +@node-red/nodes +==================== + +Node-RED core nodes module. + +This provides all of the core Node-RED nodes. + +### Source + +The main Node-RED modules are maintained as a monorepo on [GitHub](https://github.com/node-red/node-red). diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/20-inject.html b/packages/connector/packages/node_modules/@node-red/nodes/core/common/20-inject.html new file mode 100644 index 0000000..87ec3f8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/20-inject.html @@ -0,0 +1,520 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-template-name="inject"> + <div class="form-row"> + <label for="node-input-payload"><i class="fa fa-envelope"></i> <span data-i18n="common.label.payload"></span></label> + <input type="text" id="node-input-payload" style="width:70%"> + <input type="hidden" id="node-input-payloadType"> + </div> + + <div class="form-row"> + <label for="node-input-topic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label> + <input type="text" id="node-input-topic"> + </div> + + <div class="form-row" id="node-once"> + <label for="node-input-once">&nbsp;</label> + <input type="checkbox" id="node-input-once" style="display:inline-block; width:15px; vertical-align:baseline;"> + <span data-i18n="inject.onstart"></span>&nbsp; + <input type="text" id="node-input-onceDelay" placeholder="0.1" style="width:45px; height:28px;">&nbsp; + <span data-i18n="inject.onceDelay"></span> + </div> + + <div class="form-row"> + <label for=""><i class="fa fa-repeat"></i> <span data-i18n="inject.label.repeat"></span></label> + <select id="inject-time-type-select"> + <option value="none" data-i18n="inject.none"></option> + <option value="interval" data-i18n="inject.interval"></option> + <option value="interval-time" data-i18n="inject.interval-time"></option> + <option value="time" data-i18n="inject.time"></option> + </select> + <input type="hidden" id="node-input-repeat"> + <input type="hidden" id="node-input-crontab"> + </div> + + <div class="form-row inject-time-row hidden" id="inject-time-row-interval"> + <span data-i18n="inject.every"></span> + <input id="inject-time-interval-count" class="inject-time-count" value="1"></input> + <select style="width:100px" id="inject-time-interval-units"> + <option value="s" data-i18n="inject.seconds"></option> + <option value="m" data-i18n="inject.minutes"></option> + <option value="h" data-i18n="inject.hours"></option> + </select><br/> + </div> + + <div class="form-row inject-time-row hidden" id="inject-time-row-interval-time"> + <span data-i18n="inject.every"></span> <select style="width:90px; margin-left:20px;" id="inject-time-interval-time-units" class="inject-time-int-count" value="1"> + <option value="1">1</option> + <option value="2">2</option> + <option value="3">3</option> + <option value="4">4</option> + <option value="5">5</option> + <option value="6">6</option> + <option value="10">10</option> + <option value="12">12</option> + <option value="15">15</option> + <option value="20">20</option> + <option value="30">30</option> + <option value="0">60</option> + </select> <span data-i18n="inject.minutes"></span><br/> + <span data-i18n="inject.between"></span> <select id="inject-time-interval-time-start" class="inject-time-times"></select> + <span data-i18n="inject.and"></span> <select id="inject-time-interval-time-end" class="inject-time-times"></select><br/> + <div id="inject-time-interval-time-days" class="inject-time-days" style="margin-top:5px"> + <div style="display:inline-block; vertical-align:top; margin-right:5px;" data-i18n="inject.on">on</div> + <div style="display:inline-block;"> + <div> + <label><input type='checkbox' checked value='1'/> <span data-i18n="inject.days.0"></span></label> + <label><input type='checkbox' checked value='2'/> <span data-i18n="inject.days.1"></span></label> + <label><input type='checkbox' checked value='3'/> <span data-i18n="inject.days.2"></span></label> + </div> + <div> + <label><input type='checkbox' checked value='4'/> <span data-i18n="inject.days.3"></span></label> + <label><input type='checkbox' checked value='5'/> <span data-i18n="inject.days.4"></span></label> + <label><input type='checkbox' checked value='6'/> <span data-i18n="inject.days.5"></span></label> + </div> + <div> + <label><input type='checkbox' checked value='0'/> <span data-i18n="inject.days.6"></span></label> + </div> + </div> + </div> + </div> + + <div class="form-row inject-time-row hidden" id="inject-time-row-time"> + <span data-i18n="inject.at"></span> <input type="text" id="inject-time-time" value="12:00"></input><br/> + <div id="inject-time-time-days" class="inject-time-days"> + <div style="display:inline-block; vertical-align:top; margin-right:5px;" data-i18n="inject.on"></div> + <div style="display:inline-block;"> + <div> + <label><input type='checkbox' checked value='1'/> <span data-i18n="inject.days.0"></span></label> + <label><input type='checkbox' checked value='2'/> <span data-i18n="inject.days.1"></span></label> + <label><input type='checkbox' checked value='3'/> <span data-i18n="inject.days.2"></span></label> + </div> + <div> + <label><input type='checkbox' checked value='4'/> <span data-i18n="inject.days.3"></span></label> + <label><input type='checkbox' checked value='5'/> <span data-i18n="inject.days.4"></span></label> + <label><input type='checkbox' checked value='6'/> <span data-i18n="inject.days.5"></span></label> + </div> + <div> + <label><input type='checkbox' checked value='0'/> <span data-i18n="inject.days.6"></span></label> + </div> + </div> + </div> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + + <div class="form-tips" data-i18n="[html]inject.tip"></div> +</script> +<style> + .inject-time-row { + padding-left: 110px; + } + .inject-time-row select { + margin: 3px 0; + } + .inject-time-days label { + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + vertical-align: baseline; + width: 100px; + } + .inject-time-days input { + width: auto !important; + vertical-align: baseline !important; + } + .inject-time-times { + width: 90px !important; + } + #inject-time-time { + width: 75px; + margin-left: 8px; + margin-bottom: 8px; + } + .inject-time-count { + width: 40px !important; + } +</style> + +<script type="text/javascript"> + RED.nodes.registerType('inject',{ + category: 'common', + color:"#a6bbcf", + defaults: { + name: {value:""}, + topic: {value:""}, + payload: {value:"", validate: RED.validators.typedInput("payloadType")}, + payloadType: {value:"date"}, + repeat: {value:"", validate:function(v) { return ((v === "") || (RED.validators.number(v) && (v >= 0) && (v <= 2147483))) }}, + crontab: {value:""}, + once: {value:false}, + onceDelay: {value:0.1} + }, + icon: "inject.svg", + inputs:0, + outputs:1, + outputLabels: function(index) { + var lab = this.payloadType; + if (lab === "json") { + try { + lab = typeof JSON.parse(this.payload); + if (lab === "object") { + if (Array.isArray(JSON.parse(this.payload))) { lab = "Array"; } + } + } catch(e) { + return this._("inject.label.invalid"); } + } + var name = "inject.label."+lab; + var label = this._(name); + if (name !== label) { + return label; + } + return lab; + }, + label: function() { + var suffix = ""; + // if fire once then add small indication + if (this.once) { + suffix = " ¹"; + } + // but replace with repeat one if set to repeat + if ((this.repeat && this.repeat != 0) || this.crontab) { + suffix = " ↻"; + } + if (this.name) { + return this.name+suffix; + } else if (this.payloadType === "string" || + this.payloadType === "str" || + this.payloadType === "num" || + this.payloadType === "bool" || + this.payloadType === "json") { + if ((this.topic !== "") && ((this.topic.length + this.payload.length) <= 32)) { + return this.topic + ":" + this.payload+suffix; + } else if (this.payload.length > 0 && this.payload.length < 24) { + return this.payload+suffix; + } else { + return this._("inject.inject")+suffix; + } + } else if (this.payloadType === 'date') { + if ((this.topic !== "") && (this.topic.length <= 16)) { + return this.topic + ":" + this._("inject.timestamp")+suffix; + } else { + return this._("inject.timestamp")+suffix; + } + } else if (this.payloadType === 'flow' || this.payloadType === 'global') { + var key = RED.utils.parseContextKey(this.payload); + return this.payloadType+"."+key.key+suffix; + } else { + return this._("inject.inject")+suffix; + } + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + if (this.payloadType == null) { + if (this.payload == "") { + this.payloadType = "date"; + } else { + this.payloadType = "str"; + } + } else if (this.payloadType === 'string' || this.payloadType === 'none') { + this.payloadType = "str"; + } + $("#node-input-payloadType").val(this.payloadType); + + $("#node-input-payload").typedInput({ + default: 'str', + typeField: $("#node-input-payloadType"), + types:['flow','global','str','num','bool','json','bin','date','env'] + }); + + $("#inject-time-type-select").on("change", function() { + $("#node-input-crontab").val(''); + var id = $("#inject-time-type-select").val(); + $(".inject-time-row").hide(); + $("#inject-time-row-"+id).show(); + if ((id == "none") || (id == "interval") || (id == "interval-time")) { + $("#node-once").show(); + } + else { + $("#node-once").hide(); + $("#node-input-once").prop('checked', false); + } + }); + + $("#node-input-once").on("change", function() { + $("#node-input-onceDelay").attr('disabled', !$("#node-input-once").prop('checked')); + }) + + $(".inject-time-times").each(function() { + for (var i=0; i<24; i++) { + var l = (i<10?"0":"")+i+":00"; + $(this).append($("<option></option>").val(i).text(l)); + } + }); + $("<option></option>").val(24).text("00:00").appendTo("#inject-time-interval-time-end"); + $("#inject-time-interval-time-start").on("change", function() { + var start = Number($("#inject-time-interval-time-start").val()); + var end = Number($("#inject-time-interval-time-end").val()); + $("#inject-time-interval-time-end option").remove(); + for (var i=start+1; i<25; i++) { + var l = (i<10?"0":"")+i+":00"; + if (i==24) { + l = "00:00"; + } + var opt = $("<option></option>").val(i).text(l).appendTo("#inject-time-interval-time-end"); + if (i === end) { + opt.attr("selected","selected"); + } + } + }); + + $(".inject-time-count").spinner({ + //max:60, + min:1 + }); + + var repeattype = "none"; + if (this.repeat != "" && this.repeat != 0) { + repeattype = "interval"; + var r = "s"; + var c = this.repeat; + if (this.repeat % 60 === 0) { r = "m"; c = c/60; } + if (this.repeat % 1440 === 0) { r = "h"; c = c/60; } + $("#inject-time-interval-count").val(c); + $("#inject-time-interval-units").val(r); + $("#inject-time-interval-days").prop("disabled","disabled"); + } else if (this.crontab) { + var cronparts = this.crontab.split(" "); + var days = cronparts[4]; + if (!isNaN(cronparts[0]) && !isNaN(cronparts[1])) { + repeattype = "time"; + // Fixed time + var time = cronparts[1]+":"+cronparts[0]; + $("#inject-time-time").val(time); + $("#inject-time-type-select").val("s"); + if (days == "*") { + $("#inject-time-time-days input[type=checkbox]").prop("checked",true); + } else { + $("#inject-time-time-days input[type=checkbox]").removeAttr("checked"); + days.split(",").forEach(function(v) { + $("#inject-time-time-days [value=" + v + "]").prop("checked", true); + }); + } + } else { + repeattype = "interval-time"; + // interval - time period + var minutes = cronparts[0].slice(2); + if (minutes === "") { minutes = "0"; } + $("#inject-time-interval-time-units").val(minutes); + if (days == "*") { + $("#inject-time-interval-time-days input[type=checkbox]").prop("checked",true); + } else { + $("#inject-time-interval-time-days input[type=checkbox]").removeAttr("checked"); + days.split(",").forEach(function(v) { + $("#inject-time-interval-time-days [value=" + v + "]").prop("checked", true); + }); + } + var time = cronparts[1]; + var timeparts = time.split(","); + var start; + var end; + if (timeparts.length == 1) { + // 0 or 0-10 + var hours = timeparts[0].split("-"); + if (hours.length == 1) { + if (hours[0] === "") { + start = "0"; + end = "0"; + } + else { + start = hours[0]; + end = Number(hours[0])+1; + } + } else { + start = hours[0]; + end = Number(hours[1])+1; + } + } else { + // 23,0 or 17-23,0-10 or 23,0-2 or 17-23,0 + var startparts = timeparts[0].split("-"); + start = startparts[0]; + + var endparts = timeparts[1].split("-"); + if (endparts.length == 1) { + end = Number(endparts[0])+1; + } else { + end = Number(endparts[1])+1; + } + } + $("#inject-time-interval-time-end").val(end); + $("#inject-time-interval-time-start").val(start); + + } + } else { + $("#inject-time-type-select").val("none"); + } + + $(".inject-time-row").hide(); + $("#inject-time-type-select").val(repeattype); + $("#inject-time-row-"+repeattype).show(); + + $("#node-input-payload").typedInput('type',this.payloadType); + + $("#inject-time-type-select").trigger("change"); + $("#inject-time-interval-time-start").trigger("change"); + + }, + oneditsave: function() { + var repeat = ""; + var crontab = ""; + var type = $("#inject-time-type-select").val(); + if (type == "none") { + // nothing + } else if (type == "interval") { + var count = $("#inject-time-interval-count").val(); + var units = $("#inject-time-interval-units").val(); + if (units == "s") { + repeat = count; + } else { + if (units == "m") { + //crontab = "*/"+count+" * * * "+days; + repeat = count * 60; + } else if (units == "h") { + //crontab = "0 */"+count+" * * "+days; + repeat = count * 60 * 60; + } + } + } else if (type == "interval-time") { + repeat = ""; + var count = $("#inject-time-interval-time-units").val(); + var startTime = Number($("#inject-time-interval-time-start").val()); + var endTime = Number($("#inject-time-interval-time-end").val()); + var days = $('#inject-time-interval-time-days input[type=checkbox]:checked').map(function(_, el) { + return $(el).val() + }).get(); + if (days.length == 0) { + crontab = ""; + } else { + if (days.length == 7) { + days="*"; + } else { + days = days.join(","); + } + var timerange = ""; + if (endTime == 0) { + timerange = startTime+"-23"; + } else if (startTime+1 < endTime) { + timerange = startTime+"-"+(endTime-1); + } else if (startTime+1 == endTime) { + timerange = startTime; + } else { + var startpart = ""; + var endpart = ""; + if (startTime == 23) { + startpart = "23"; + } else { + startpart = startTime+"-23"; + } + if (endTime == 1) { + endpart = "0"; + } else { + endpart = "0-"+(endTime-1); + } + timerange = startpart+","+endpart; + } + if (count === "0") { + crontab = count+" "+timerange+" * * "+days; + } else { + crontab = "*/"+count+" "+timerange+" * * "+days; + } + } + } else if (type == "time") { + var time = $("#inject-time-time").val(); + var days = $('#inject-time-time-days input[type=checkbox]:checked').map(function(_, el) { + return $(el).val() + }).get(); + if (days.length == 0) { + crontab = ""; + } else { + if (days.length == 7) { + days="*"; + } else { + days = days.join(","); + } + var parts = time.split(":"); + if (parts.length === 2) { + repeat = ""; + parts[1] = ("00" + (parseInt(parts[1]) % 60)).substr(-2); + parts[0] = ("00" + (parseInt(parts[0]) % 24)).substr(-2); + crontab = parts[1]+" "+parts[0]+" * * "+days; + } + else { crontab = ""; } + } + } + + $("#node-input-repeat").val(repeat); + $("#node-input-crontab").val(crontab); + }, + button: { + enabled: function() { + return !this.changed + }, + onclick: function() { + if (this.changed) { + return RED.notify(RED._("notification.warning", {message:RED._("notification.warnings.undeployedChanges")}),"warning"); + } + var payload = this.payload; + if ((this.payloadType === 'flow') || + (this.payloadType === 'global')) { + var key = RED.utils.parseContextKey(payload); + payload = this.payloadType+"."+key.key; + } + var label = this._def.label.call(this); + if (label.length > 30) { + label = label.substring(0,50)+"..."; + } + label = label.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"); + var node = this; + $.ajax({ + url: "inject/"+this.id, + type:"POST", + success: function(resp) { + RED.notify(node._("inject.success",{label:label}),{type:"success",id:"inject"}); + }, + error: function(jqXHR,textStatus,errorThrown) { + if (jqXHR.status == 404) { + RED.notify(node._("common.notification.error",{message:node._("common.notification.errors.not-deployed")}),"error"); + } else if (jqXHR.status == 500) { + RED.notify(node._("common.notification.error",{message:node._("inject.errors.failed")}),"error"); + } else if (jqXHR.status == 0) { + RED.notify(node._("common.notification.error",{message:node._("common.notification.errors.no-response")}),"error"); + } else { + RED.notify(node._("common.notification.error",{message:node._("common.notification.errors.unexpected",{status:jqXHR.status,message:textStatus})}),"error"); + } + } + }); + } + } + }); + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/20-inject.js b/packages/connector/packages/node_modules/@node-red/nodes/core/common/20-inject.js new file mode 100644 index 0000000..c0d9e0c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/20-inject.js @@ -0,0 +1,127 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var cron = require("cron"); + + function InjectNode(n) { + RED.nodes.createNode(this,n); + this.topic = n.topic; + this.payload = n.payload; + this.payloadType = n.payloadType; + this.repeat = n.repeat; + this.crontab = n.crontab; + this.once = n.once; + this.onceDelay = (n.onceDelay || 0.1) * 1000; + this.interval_id = null; + this.cronjob = null; + var node = this; + + if (node.repeat > 2147483) { + node.error(RED._("inject.errors.toolong", this)); + delete node.repeat; + } + + node.repeaterSetup = function () { + if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) { + this.repeat = this.repeat * 1000; + if (RED.settings.verbose) { + this.log(RED._("inject.repeat", this)); + } + this.interval_id = setInterval(function() { + node.emit("input", {}); + }, this.repeat); + } else if (this.crontab) { + if (RED.settings.verbose) { + this.log(RED._("inject.crontab", this)); + } + this.cronjob = new cron.CronJob(this.crontab, function() { node.emit("input", {}); }, null, true); + } + }; + + if (this.once) { + this.onceTimeout = setTimeout( function() { + node.emit("input",{}); + node.repeaterSetup(); + }, this.onceDelay); + } else { + node.repeaterSetup(); + } + + this.on("input",function(msg) { + msg.topic = this.topic; + if (this.payloadType !== 'flow' && this.payloadType !== 'global') { + try { + if ( (this.payloadType == null && this.payload === "") || this.payloadType === "date") { + msg.payload = Date.now(); + } else if (this.payloadType == null) { + msg.payload = this.payload; + } else if (this.payloadType === 'none') { + msg.payload = ""; + } else { + msg.payload = RED.util.evaluateNodeProperty(this.payload,this.payloadType,this,msg); + } + this.send(msg); + msg = null; + } catch(err) { + this.error(err,msg); + } + } else { + RED.util.evaluateNodeProperty(this.payload,this.payloadType,this,msg, function(err,res) { + if (err) { + node.error(err,msg); + } else { + msg.payload = res; + node.send(msg); + } + + }); + } + }); + } + + RED.nodes.registerType("inject",InjectNode); + + InjectNode.prototype.close = function() { + if (this.onceTimeout) { + clearTimeout(this.onceTimeout); + } + if (this.interval_id != null) { + clearInterval(this.interval_id); + if (RED.settings.verbose) { this.log(RED._("inject.stopped")); } + } else if (this.cronjob != null) { + this.cronjob.stop(); + if (RED.settings.verbose) { this.log(RED._("inject.stopped")); } + delete this.cronjob; + } + }; + + RED.httpAdmin.post("/inject/:id", RED.auth.needsPermission("inject.write"), function(req,res) { + var node = RED.nodes.getNode(req.params.id); + if (node != null) { + try { + node.receive(); + res.sendStatus(200); + } catch(err) { + res.sendStatus(500); + node.error(RED._("inject.failed",{error:err.toString()})); + } + } else { + res.sendStatus(404); + } + }); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/21-debug.html b/packages/connector/packages/node_modules/@node-red/nodes/core/common/21-debug.html new file mode 100644 index 0000000..5e2f3ba --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/21-debug.html @@ -0,0 +1,381 @@ + +<script type="text/x-red" data-template-name="debug"> + <div class="form-row"> + <label for="node-input-typed-complete"><i class="fa fa-list"></i> <span data-i18n="debug.output"></span></label> + <input id="node-input-typed-complete" type="text" style="width: 70%"> + <input id="node-input-complete" type="hidden"> + <input id="node-input-targetType" type="hidden"> + </div> + + <div class="form-row"> + <label for="node-input-tosidebar"><i class="fa fa-random"></i> <span data-i18n="debug.to"></span></label> + <label for="node-input-tosidebar" style="width:70%"> + <input type="checkbox" id="node-input-tosidebar" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="debug.toSidebar"></span> + </label> + </div> + <div class="form-row"> + <label for="node-input-console"> </label> + <label for="node-input-console" style="width:70%"> + <input type="checkbox" id="node-input-console" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="debug.toConsole"></span> + </label> + </div> + <div class="form-row" id="node-tostatus-line"> + <label for="node-input-tostatus"> </label> + <label for="node-input-tostatus" style="width:70%"> + <input type="checkbox" id="node-input-tostatus" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="debug.toStatus"></span> + </label> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> + +<script src="debug/view/debug-utils.js"></script> + +<script type="text/javascript"> +(function() { + var subWindow = null; + RED.nodes.registerType('debug',{ + category: 'common', + defaults: { + name: {value:""}, + active: {value:true}, + tosidebar: {value:true}, + console: {value:false}, + tostatus: {value:false}, + complete: {value:"false", required:true}, + targetType: {value:undefined} + }, + label: function() { + var suffix = ""; + if (this.console === true || this.console === "true") { suffix = " ⇲"; } + if (this.targetType === "jsonata") { + return (this.name || "JSONata") + suffix; + } + if (this.complete === true || this.complete === "true") { + return (this.name||"msg") + suffix; + } else { + return (this.name || "msg." + ((!this.complete || this.complete === "false") ? "payload" : this.complete)) + suffix; + } + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + color:"#87a980", + inputs:1, + outputs:0, + icon: "debug.svg", + align: "right", + button: { + toggle: "active", + visible: function() { return this.tosidebar; }, + onclick: function() { + var label = this.name||"debug"; + var node = this; + $.ajax({ + url: "debug/"+this.id+"/"+(this.active?"enable":"disable"), + type: "POST", + success: function(resp, textStatus, xhr) { + var historyEvent = { + t:'edit', + node:node, + changes:{ + active:!node.active + }, + dirty:node.dirty, + changed:node.changed + }; + node.changed = true; + node.dirty = true; + RED.nodes.dirty(true); + RED.history.push(historyEvent); + RED.view.redraw(); + if (xhr.status == 200) { + RED.notify(node._("debug.notification.activated",{label:label}),"success"); + } else if (xhr.status == 201) { + RED.notify(node._("debug.notification.deactivated",{label:label}),"success"); + } + }, + error: function(jqXHR,textStatus,errorThrown) { + if (jqXHR.status == 404) { + RED.notify(node._("common.notification.error", {message: node._("common.notification.errors.not-deployed")}),"error"); + } else if (jqXHR.status === 0) { + RED.notify(node._("common.notification.error", {message: node._("common.notification.errors.no-response")}),"error"); + } else { + RED.notify(node._("common.notification.error",{message:node._("common.notification.errors.unexpected",{status:err.status,message:err.response})}),"error"); + } + } + }); + } + }, + onpaletteadd: function() { + var options = { + messageMouseEnter: function(sourceId) { + if (sourceId) { + var n = RED.nodes.node(sourceId); + if (n) { + n.highlighted = true; + n.dirty = true; + } + RED.view.redraw(); + } + }, + messageMouseLeave: function(sourceId) { + if (sourceId) { + var n = RED.nodes.node(sourceId); + if (n) { + n.highlighted = false; + n.dirty = true; + } + RED.view.redraw(); + } + }, + messageSourceClick: function(sourceId, aliasId, path) { + // Get all of the nodes that could have logged this message + var candidateNodes = [RED.nodes.node(sourceId)] + if (path) { + for (var i=2;i<path.length;i++) { + candidateNodes.push(RED.nodes.node(path[i])) + } + } + if (aliasId) { + candidateNodes.push(RED.nodes.node(aliasId)); + } + if (candidateNodes.length > 1) { + // The node is in a subflow. Check to see if the active + // workspace is a subflow in the node's parentage. If + // so, reveal the relevant subflow instance node. + var ws = RED.workspaces.active(); + for (var i=0;i<candidateNodes.length;i++) { + if (candidateNodes[i].z === ws) { + RED.view.reveal(candidateNodes[i].id); + return + } + } + // The active workspace is unrelated to the node. So + // fall back to revealing the top most node + } + RED.view.reveal(candidateNodes[0].id); + }, + clear: function() { + RED.nodes.eachNode(function(node) { + node.highlighted = false; + node.dirty = true; + }); + RED.view.redraw(); + } + }; + + var uiComponents = RED.debug.init(options); + + RED.sidebar.addTab({ + id: "debug", + label: this._("debug.sidebar.label"), + name: this._("debug.sidebar.name"), + content: uiComponents.content, + toolbar: uiComponents.footer, + enableOnEdit: true, + pinned: true, + iconClass: "fa fa-bug", + action: "core:show-debug-tab" + }); + RED.actions.add("core:show-debug-tab",function() { RED.sidebar.show('debug'); }); + + var that = this; + RED._debug = function(msg) { + that.handleDebugMessage("", { + name:"debug", + msg:msg + }); + }; + + this.refreshMessageList = function() { + RED.debug.refreshMessageList(RED.workspaces.active()); + if (subWindow) { + try { + subWindow.postMessage({event:"workspaceChange",activeWorkspace:RED.workspaces.active()},"*"); + } catch(err) { + console.log(err); + } + } + }; + RED.events.on("workspace:change", this.refreshMessageList); + + this.handleDebugMessage = function(t,o) { + // console.log("->",o.id,o.z,o._alias); + // + // sourceNode should be the top-level node - one that is on a flow. + var sourceNode; + var pathParts; + if (o.path) { + // Path is a `/`-separated list of ids that identifies the + // complete parentage of the node that generated this message. + // flow-id/subflow-A-instance/subflow-A-type/subflow-B-instance/subflow-B-type/node-id + + // If it has one id, that is a top level flow + // each subsequent id is the instance id of a subflow node + // + pathParts = o.path.split("/"); + if (pathParts.length === 1) { + // The source node is on a flow - so can use its id to find + sourceNode = RED.nodes.node(o.id); + } else if (pathParts.length > 1) { + // Highlight the subflow instance node. + sourceNode = RED.nodes.node(pathParts[1]); + } + } else { + // This is probably redundant... + sourceNode = RED.nodes.node(o.id) || RED.nodes.node(o.z); + } + if (sourceNode) { + o._source = { + id:sourceNode.id, + z:sourceNode.z, + name:sourceNode.name, + type:sourceNode.type, + // _alias identifies the actual logging node. This is + // not necessarily the same as sourceNode, which will be + // the top-level subflow instance node. + // This means the node's name is displayed in the sidebar. + _alias:o._alias, + path: pathParts + }; + } + RED.debug.handleDebugMessage(o); + if (subWindow) { + try { + subWindow.postMessage({event:"message",msg:o},"*"); + } catch(err) { + console.log(err); + } + } + }; + RED.comms.subscribe("debug",this.handleDebugMessage); + + this.clearMessageList = function() { + RED.debug.clearMessageList(true); + if (subWindow) { + try { + subWindow.postMessage({event:"projectChange"},"*"); + } catch(err) { + console.log(err); + } + } + }; + RED.events.on("project:change", this.clearMessageList); + RED.actions.add("core:clear-debug-messages", function() { RED.debug.clearMessageList(true) }); + + $("#red-ui-sidebar-debug-open").on("click", function(e) { + e.preventDefault(); + subWindow = window.open(document.location.toString().replace(/[?#].*$/,"")+"debug/view/view.html"+document.location.search,"nodeREDDebugView","menubar=no,location=no,toolbar=no,chrome,height=500,width=600"); + subWindow.onload = function() { + subWindow.postMessage({event:"workspaceChange",activeWorkspace:RED.workspaces.active()},"*"); + }; + }); + RED.popover.tooltip($("#red-ui-sidebar-debug-open"),RED._('node-red:debug.sidebar.openWindow')); + + + + $(window).on('beforeunload',function() { + if (subWindow) { + try { + subWindow.close(); + } catch(err) { + console.log(err); + } + } + }); + + this.handleWindowMessage = function(evt) { + var msg = evt.data; + if (msg.event === "mouseEnter") { + options.messageMouseEnter(msg.id); + } else if (msg.event === "mouseLeave") { + options.messageMouseLeave(msg.id); + } else if (msg.event === "mouseClick") { + options.messageSourceClick(msg.id,msg._alias,msg.path); + } else if (msg.event === "clear") { + options.clear(); + } + }; + window.addEventListener('message',this.handleWindowMessage); + }, + onpaletteremove: function() { + RED.comms.unsubscribe("debug",this.handleDebugMessage); + RED.sidebar.removeTab("debug"); + RED.events.off("workspace:change", this.refreshMessageList); + window.removeEventListener("message",this.handleWindowMessage); + RED.actions.remove("core:show-debug-tab"); + RED.actions.remove("core:clear-debug-messages"); + + delete RED._debug; + }, + oneditprepare: function() { + var none = { + value: "none", + label: RED._("node-red:debug.none"), + hasValue: false + }; + if (this.tosidebar === undefined) { + this.tosidebar = true; + $("#node-input-tosidebar").prop('checked', true); + } + if (typeof this.console === "string") { + this.console = (this.console == 'true'); + $("#node-input-console").prop('checked', this.console); + $("#node-input-tosidebar").prop('checked', true); + } + var fullType = { + value: "full", + label: RED._("node-red:debug.msgobj"), + hasValue: false + }; + $("#node-input-typed-complete").typedInput({ + default: "msg", + types:['msg', fullType, "jsonata"], + typeField: $("#node-input-targetType") + }); + if (this.targetType === "jsonata") { + var property = this.complete || ""; + $("#node-input-typed-complete").typedInput('type','jsonata'); + $("#node-input-typed-complete").typedInput('value',property); + } else if ((this.targetType === "full") || this.complete === "true" || this.complete === true) { + // show complete message object + $("#node-input-typed-complete").typedInput('type','full'); + } else { + var property = (!this.complete||(this.complete === "false")) ? "payload" : this.complete+""; + $("#node-input-typed-complete").typedInput('type','msg'); + $("#node-input-typed-complete").typedInput('value',property); + } + $("#node-input-typed-complete").on('change',function() { + if ($("#node-input-typed-complete").typedInput('type') === 'msg' && + $("#node-input-typed-complete").typedInput('value') === '' + ) { + $("#node-input-typed-complete").typedInput('value','payload'); + } + if ($("#node-input-typed-complete").typedInput('type') === 'full') { + $("#node-tostatus-line").hide(); + } else { + $("#node-tostatus-line").show(); + } + }); + $("#node-input-complete").on('change',function() { + if ($("#node-input-typed-complete").typedInput('type') === 'full') { + $("#node-tostatus-line").hide(); + } else { + $("#node-tostatus-line").show(); + } + }); + }, + oneditsave: function() { + var type = $("#node-input-typed-complete").typedInput('type'); + if (type === 'full') { + $("#node-input-complete").val("true"); + } else { + $("#node-input-complete").val($("#node-input-typed-complete").typedInput('value')); + } + } + }); +})(); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/21-debug.js b/packages/connector/packages/node_modules/@node-red/nodes/core/common/21-debug.js new file mode 100644 index 0000000..b00371b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/21-debug.js @@ -0,0 +1,185 @@ +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var events = require("events"); + var path = require("path"); + var debuglength = RED.settings.debugMaxLength || 1000; + var useColors = RED.settings.debugUseColors || false; + util.inspect.styles.boolean = "red"; + + function DebugNode(n) { + var hasEditExpression = (n.targetType === "jsonata"); + var editExpression = hasEditExpression ? n.complete : null; + RED.nodes.createNode(this,n); + this.name = n.name; + this.complete = hasEditExpression ? null : (n.complete||"payload").toString(); + if (this.complete === "false") { this.complete = "payload"; } + this.console = ""+(n.console || false); + this.tostatus = (this.complete !== "true") && (n.tostatus || false); + this.tosidebar = n.tosidebar; + if (this.tosidebar === undefined) { this.tosidebar = true; } + this.severity = n.severity || 40; + this.active = (n.active === null || typeof n.active === "undefined") || n.active; + if (this.tostatus) { this.status({fill:"grey", shape:"ring"}); } + else { this.status({}); } + + var node = this; + var levels = { + off: 1, + fatal: 10, + error: 20, + warn: 30, + info: 40, + debug: 50, + trace: 60, + audit: 98, + metric: 99 + }; + var colors = { + "0": "grey", + "10": "grey", + "20": "red", + "30": "yellow", + "40": "grey", + "50": "green", + "60": "blue" + }; + var preparedEditExpression = null; + if (editExpression) { + try { + preparedEditExpression = RED.util.prepareJSONataExpression(editExpression, this); + } + catch (e) { + node.error(RED._("debug.invalid-exp", {error: editExpression})); + return; + } + } + + function prepareValue(msg, done) { + // Either apply the jsonata expression or... + if (preparedEditExpression) { + RED.util.evaluateJSONataExpression(preparedEditExpression, msg, (err, value) => { + if (err) { + done(RED._("debug.invalid-exp", {error: editExpression})); + } else { + done(null,{id:node.id, z:node.z, _alias: node._alias, path:node._flow.path, name:node.name, topic:msg.topic, msg:value}); + } + }); + } else { + // Extract the required message property + var property = "payload"; + var output = msg[property]; + if (node.complete !== "false" && typeof node.complete !== "undefined") { + property = node.complete; + try { + output = RED.util.getMessageProperty(msg,node.complete); + } catch(err) { + output = undefined; + } + } + done(null,{id:node.id, z:node.z, _alias: node._alias, path:node._flow.path, name:node.name, topic:msg.topic, property:property, msg:output}); + } + } + + this.on("input", function(msg, send, done) { + if (this.complete === "true") { + // debug complete msg object + if (this.console === "true") { + node.log("\n"+util.inspect(msg, {colors:useColors, depth:10})); + } + if (this.active && this.tosidebar) { + sendDebug({id:node.id, z:node.z, _alias: node._alias, path:node._flow.path, name:node.name, topic:msg.topic, msg:msg}); + } + done(); + } else { + prepareValue(msg,function(err,debugMsg) { + if (err) { + node.error(err); + return; + } + var output = debugMsg.msg; + if (node.console === "true") { + if (typeof output === "string") { + node.log((output.indexOf("\n") !== -1 ? "\n" : "") + output); + } else if (typeof output === "object") { + node.log("\n"+util.inspect(output, {colors:useColors, depth:10})); + } else { + node.log(util.inspect(output, {colors:useColors})); + } + } + if (node.tostatus === true) { + var st = (typeof output === 'string')?output:util.inspect(output); + var severity = node.severity; + if (st.length > 32) { st = st.substr(0,32) + "..."; } + node.status({fill:colors[severity], shape:"dot", text:st}); + } + if (node.active) { + if (node.tosidebar == true) { + sendDebug(debugMsg); + } + } + done(); + }); + } + }) + } + + RED.nodes.registerType("debug",DebugNode, { + settings: { + debugUseColors: { + value: false, + }, + debugMaxLength: { + value: 1000, + } + } + }); + + function sendDebug(msg) { + // don't put blank errors in sidebar (but do add to logs) + //if ((msg.msg === "") && (msg.hasOwnProperty("level")) && (msg.level === 20)) { return; } + msg = RED.util.encodeObject(msg,{maxLength:debuglength}); + RED.comms.publish("debug",msg); + } + + DebugNode.logHandler = new events.EventEmitter(); + DebugNode.logHandler.on("log",function(msg) { + if (msg.level === RED.log.WARN || msg.level === RED.log.ERROR) { + sendDebug(msg); + } + }); + RED.log.addHandler(DebugNode.logHandler); + + RED.httpAdmin.post("/debug/:id/:state", RED.auth.needsPermission("debug.write"), function(req,res) { + var node = RED.nodes.getNode(req.params.id); + var state = req.params.state; + if (node !== null && typeof node !== "undefined" ) { + if (state === "enable") { + node.active = true; + res.sendStatus(200); + if (node.tostatus) { node.status({fill:"grey", shape:"dot"}); } + } else if (state === "disable") { + node.active = false; + res.sendStatus(201); + if (node.tostatus && node.hasOwnProperty("oldStatus")) { + node.oldStatus.shape = "dot"; + node.status(node.oldStatus); + } + } else { + res.sendStatus(404); + } + } else { + res.sendStatus(404); + } + }); + + // As debug/view/debug-utils.js is loaded via <script> tag, it won't get + // the auth header attached. So do not use RED.auth.needsPermission here. + RED.httpAdmin.get("/debug/view/*",function(req,res) { + var options = { + root: __dirname + '/lib/debug/', + dotfiles: 'deny' + }; + res.sendFile(req.params[0], options); + }); +}; diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/24-complete.html b/packages/connector/packages/node_modules/@node-red/nodes/core/common/24-complete.html new file mode 100644 index 0000000..c801ca7 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/24-complete.html @@ -0,0 +1,136 @@ +<script type="text/x-red" data-template-name="complete"> + <div class="form-row node-input-target-row"> + <button id="node-input-complete-target-select" class="red-ui-button" data-i18n="common.label.selectNodes"></button> + </div> + <div class="form-row node-input-target-row node-input-target-list-row" style="min-height: 100px"> + <div id="node-input-complete-target-container-div"></div> + </div> + + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> +<script type="text/javascript"> + RED.nodes.registerType('complete',{ + category: 'common', + color:"#c0edc0", + defaults: { + name: {value:""}, + scope: {value:[]}, + uncaught: {value:false} + }, + inputs:0, + outputs:1, + icon: "alert.svg", + label: function() { + if (this.name) { + return this.name; + } + return this._("complete.completeNodes",{number:this.scope.length}); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + var node = this; + var scope = node.scope || []; + + this._resize = function() { + var rows = $("#dialog-form>div:not(.node-input-target-list-row)"); + var height = $("#dialog-form").height(); + for (var i=0;i<rows.length;i++) { + height -= $(rows[i]).outerHeight(true); + } + var editorRow = $("#dialog-form>div.node-input-target-list-row"); + editorRow.css("height",height+"px"); + }; + + var dirList = $("#node-input-complete-target-container-div").css({width: "100%", height: "100%"}) + .treeList({multi:true}).on("treelistitemmouseover", function(e, item) { + item.node.highlighted = true; + item.node.dirty = true; + RED.view.redraw(); + }).on("treelistitemmouseout", function(e, item) { + item.node.highlighted = false; + item.node.dirty = true; + RED.view.redraw(); + }) + var candidateNodes = RED.nodes.filterNodes({z:node.z}); + var allChecked = true; + var items = []; + var nodeItemMap = {}; + + candidateNodes.forEach(function(n) { + if (n.id === node.id) { + return; + } + var isChecked = scope.indexOf(n.id) !== -1; + + allChecked = allChecked && isChecked; + + var nodeDef = RED.nodes.getType(n.type); + var label; + var sublabel; + if (nodeDef) { + var l = nodeDef.label; + label = (typeof l === "function" ? l.call(n) : l)||""; + sublabel = n.type; + if (sublabel.indexOf("subflow:") === 0) { + var subflowId = sublabel.substring(8); + var subflow = RED.nodes.subflow(subflowId); + sublabel = "subflow : "+subflow.name; + } + } + if (!nodeDef || !label) { + label = n.type; + } + nodeItemMap[n.id] = { + node: n, + label: label, + sublabel: sublabel, + selected: isChecked + }; + items.push(nodeItemMap[n.id]); + }); + dirList.treeList('data',items); + + $("#node-input-complete-target-select").on("click", function(e) { + e.preventDefault(); + var preselected = dirList.treeList('selected').map(function(n) {return n.node.id}); + RED.tray.hide(); + RED.view.selectNodes({ + selected: preselected, + onselect: function(selection) { + RED.tray.show(); + var newlySelected = {}; + selection.forEach(function(n) { + newlySelected[n.id] = true; + if (nodeItemMap[n.id]) { + nodeItemMap[n.id].treeList.select(true); + } + }) + preselected.forEach(function(id) { + if (!newlySelected[id]) { + nodeItemMap[id].treeList.select(false); + } + }) + }, + oncancel: function() { + RED.tray.show(); + }, + filter: function(n) { + return n.id !== node.id; + } + }); + }) + + }, + oneditsave: function() { + this.scope = $("#node-input-complete-target-container-div").treeList('selected').map(function(i) { return i.node.id}) + }, + oneditresize: function(size) { + this._resize(); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/24-complete.js b/packages/connector/packages/node_modules/@node-red/nodes/core/common/24-complete.js new file mode 100644 index 0000000..78008f8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/24-complete.js @@ -0,0 +1,30 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + + function CompleteNode(n) { + RED.nodes.createNode(this,n); + var node = this; + this.scope = n.scope; + this.on("input",function(msg) { + this.send(msg); + }); + } + + RED.nodes.registerType("complete",CompleteNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/25-catch.html b/packages/connector/packages/node_modules/@node-red/nodes/core/common/25-catch.html new file mode 100644 index 0000000..7cc170b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/25-catch.html @@ -0,0 +1,174 @@ + +<script type="text/x-red" data-template-name="catch"> + <div class="form-row"> + <label style="width: auto" for="node-input-scope" data-i18n="catch.label.source"></label> + <select id="node-input-scope-select"> + <option value="all" data-i18n="catch.scope.all"></option> + <option value="target" data-i18n="catch.scope.selected"></options> + </select> + </div> + <div class="form-row node-input-uncaught-row"> + <input type="checkbox" id="node-input-uncaught" style="display: inline-block; width: auto; vertical-align: top; margin-left: 30px; margin-right: 5px;"> + <label for="node-input-uncaught" style="width: auto" data-i18n="catch.label.uncaught"></label> + </div> + <div class="form-row node-input-target-row"> + <button id="node-input-catch-target-select" class="red-ui-button" data-i18n="common.label.selectNodes"></button> + </div> + <div class="form-row node-input-target-row node-input-target-list-row" style="min-height: 100px"> + <div id="node-input-catch-target-container-div"></div> + </div> + + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> +<script type="text/javascript"> + RED.nodes.registerType('catch',{ + category: 'common', + color:"#e49191", + defaults: { + name: {value:""}, + scope: {value:null}, + uncaught: {value:false} + }, + inputs:0, + outputs:1, + icon: "alert.svg", + label: function() { + if (this.name) { + return this.name; + } + if (this.scope) { + return this._("catch.catchNodes",{number:this.scope.length}); + } + return this.uncaught?this._("catch.catchUncaught"):this._("catch.catch") + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + var node = this; + var scope = node.scope || []; + + this._resize = function() { + var rows = $("#dialog-form>div:not(.node-input-target-list-row)"); + var height = $("#dialog-form").height(); + for (var i=0;i<rows.length;i++) { + height -= $(rows[i]).outerHeight(true); + } + var editorRow = $("#dialog-form>div.node-input-target-list-row"); + editorRow.css("height",height+"px"); + }; + + var dirList = $("#node-input-catch-target-container-div").css({width: "100%", height: "100%"}) + .treeList({multi:true}).on("treelistitemmouseover", function(e, item) { + item.node.highlighted = true; + item.node.dirty = true; + RED.view.redraw(); + }).on("treelistitemmouseout", function(e, item) { + item.node.highlighted = false; + item.node.dirty = true; + RED.view.redraw(); + }) + var candidateNodes = RED.nodes.filterNodes({z:node.z}); + var allChecked = true; + var items = []; + var nodeItemMap = {}; + + candidateNodes.forEach(function(n) { + if (n.id === node.id) { + return; + } + var isChecked = scope.indexOf(n.id) !== -1; + + allChecked = allChecked && isChecked; + + var nodeDef = RED.nodes.getType(n.type); + var label; + var sublabel; + if (nodeDef) { + var l = nodeDef.label; + label = (typeof l === "function" ? l.call(n) : l)||""; + sublabel = n.type; + if (sublabel.indexOf("subflow:") === 0) { + var subflowId = sublabel.substring(8); + var subflow = RED.nodes.subflow(subflowId); + sublabel = "subflow : "+subflow.name; + } + } + if (!nodeDef || !label) { + label = n.type; + } + nodeItemMap[n.id] = { + node: n, + label: label, + sublabel: sublabel, + selected: isChecked + }; + items.push(nodeItemMap[n.id]); + }); + dirList.treeList('data',items); + + $("#node-input-catch-target-select").on("click", function(e) { + e.preventDefault(); + var preselected = dirList.treeList('selected').map(function(n) {return n.node.id}); + RED.tray.hide(); + RED.view.selectNodes({ + selected: preselected, + onselect: function(selection) { + RED.tray.show(); + var newlySelected = {}; + selection.forEach(function(n) { + newlySelected[n.id] = true; + if (nodeItemMap[n.id]) { + nodeItemMap[n.id].treeList.select(true); + } + }) + preselected.forEach(function(id) { + if (!newlySelected[id]) { + nodeItemMap[id].treeList.select(false); + } + }) + }, + oncancel: function() { + RED.tray.show(); + }, + filter: function(n) { + return n.id !== node.id; + } + }); + }) + + $("#node-input-scope-select").on("change", function(e) { + var scope = $(this).val(); + if (scope === "target") { + $(".node-input-target-row").show(); + $(".node-input-uncaught-row").hide(); + } else { + $(".node-input-target-row").hide(); + $(".node-input-uncaught-row").show(); + } + node._resize(); + }); + if (this.scope === null) { + $("#node-input-scope-select").val("all"); + } else { + $("#node-input-scope-select").val("target"); + } + $("#node-input-scope-select").trigger("change"); + }, + oneditsave: function() { + var scope = $("#node-input-scope-select").val(); + if (scope === 'all') { + this.scope = null; + } else { + $("#node-input-uncaught").prop("checked",false); + this.scope = $("#node-input-catch-target-container-div").treeList('selected').map(function(i) { return i.node.id}) + } + }, + oneditresize: function(size) { + this._resize(); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/25-catch.js b/packages/connector/packages/node_modules/@node-red/nodes/core/common/25-catch.js new file mode 100644 index 0000000..8624518 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/25-catch.js @@ -0,0 +1,31 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + + function CatchNode(n) { + RED.nodes.createNode(this,n); + var node = this; + this.scope = n.scope; + this.uncaught = n.uncaught; + this.on("input",function(msg) { + this.send(msg); + }); + } + + RED.nodes.registerType("catch",CatchNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/25-status.html b/packages/connector/packages/node_modules/@node-red/nodes/core/common/25-status.html new file mode 100644 index 0000000..283d505 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/25-status.html @@ -0,0 +1,159 @@ + +<script type="text/x-red" data-template-name="status"> + <div class="form-row"> + <label style="width: auto" for="node-input-scope" data-i18n="status.label.source"></label> + <select id="node-input-scope-select"> + <option value="all" data-i18n="status.scope.all"></option> + <option value="target" data-i18n="status.scope.selected"></options> + </select> + </div> + <div class="form-row node-input-target-row"> + <button id="node-input-status-target-select" class="red-ui-button" data-i18n="common.label.selectNodes"></button> + </div> + <div class="form-row node-input-target-row node-input-target-list-row" style="min-height: 100px"> + <div id="node-input-status-target-container-div"></div> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('status',{ + category: 'common', + color:"#94c1d0", + defaults: { + name: {value:""}, + scope: {value:null} + }, + inputs:0, + outputs:1, + icon: "status.svg", + label: function() { + return this.name||(this.scope?this._("status.statusNodes",{number:this.scope.length}):this._("status.status")); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + var node = this; + var scope = node.scope || []; + this._resize = function() { + var rows = $("#dialog-form>div:not(.node-input-target-list-row)"); + var height = $("#dialog-form").height(); + for (var i=0;i<rows.length;i++) { + height -= $(rows[i]).outerHeight(true); + } + var editorRow = $("#dialog-form>div.node-input-target-list-row"); + editorRow.css("height",height+"px"); + }; + + var dirList = $("#node-input-status-target-container-div").css({width: "100%", height: "100%"}) + .treeList({multi:true}).on("treelistitemmouseover", function(e, item) { + item.node.highlighted = true; + item.node.dirty = true; + RED.view.redraw(); + }).on("treelistitemmouseout", function(e, item) { + item.node.highlighted = false; + item.node.dirty = true; + RED.view.redraw(); + }) + var candidateNodes = RED.nodes.filterNodes({z:node.z}); + var allChecked = true; + var items = []; + var nodeItemMap = {}; + + candidateNodes.forEach(function(n) { + if (n.id === node.id) { + return; + } + var isChecked = scope.indexOf(n.id) !== -1; + + allChecked = allChecked && isChecked; + + var nodeDef = RED.nodes.getType(n.type); + var label; + var sublabel; + if (nodeDef) { + var l = nodeDef.label; + label = (typeof l === "function" ? l.call(n) : l)||""; + sublabel = n.type; + if (sublabel.indexOf("subflow:") === 0) { + var subflowId = sublabel.substring(8); + var subflow = RED.nodes.subflow(subflowId); + sublabel = "subflow : "+subflow.name; + } + } + if (!nodeDef || !label) { + label = n.type; + } + nodeItemMap[n.id] = { + node: n, + label: label, + sublabel: sublabel, + selected: isChecked + }; + items.push(nodeItemMap[n.id]); + }); + dirList.treeList('data',items); + + $("#node-input-status-target-select").on("click", function(e) { + e.preventDefault(); + var preselected = dirList.treeList('selected').map(function(n) {return n.node.id}); + RED.tray.hide(); + RED.view.selectNodes({ + selected: preselected, + onselect: function(selection) { + RED.tray.show(); + var newlySelected = {}; + selection.forEach(function(n) { + newlySelected[n.id] = true; + if (nodeItemMap[n.id]) { + nodeItemMap[n.id].treeList.select(true); + } + }) + preselected.forEach(function(id) { + if (!newlySelected[id]) { + nodeItemMap[id].treeList.select(false); + } + }) + }, + oncancel: function() { + RED.tray.show(); + }, + filter: function(n) { + return n.id !== node.id; + } + }); + }) + + $("#node-input-scope-select").on("change", function(e) { + var scope = $(this).val(); + if (scope === "target") { + $(".node-input-target-row").show(); + } else { + $(".node-input-target-row").hide(); + } + node._resize(); + }); + if (this.scope === null) { + $("#node-input-scope-select").val("all"); + } else { + $("#node-input-scope-select").val("target"); + } + $("#node-input-scope-select").trigger("change"); + }, + oneditsave: function() { + var scope = $("#node-input-scope-select").val(); + if (scope === 'all') { + this.scope = null; + } else { + this.scope = $("#node-input-status-target-container-div").treeList('selected').map(function(i) { return i.node.id}) + } + }, + oneditresize: function(size) { + this._resize(); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/25-status.js b/packages/connector/packages/node_modules/@node-red/nodes/core/common/25-status.js new file mode 100644 index 0000000..b36468d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/25-status.js @@ -0,0 +1,30 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + + function StatusNode(n) { + RED.nodes.createNode(this,n); + var node = this; + this.scope = n.scope; + this.on("input", function(msg) { + this.send(msg); + }); + } + + RED.nodes.registerType("status",StatusNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/60-link.html b/packages/connector/packages/node_modules/@node-red/nodes/core/common/60-link.html new file mode 100644 index 0000000..9c70b4e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/60-link.html @@ -0,0 +1,223 @@ + +<script type="text/x-red" data-template-name="link in"> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-row node-input-link-row"></div> +</script> +<script type="text/x-red" data-template-name="link out"> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-row node-input-link-row"></div> +</script> + +<script type="text/javascript"> +(function() { + + var treeList; + + function onEditPrepare(node,targetType) { + if (!node.links) { + node.links = []; + } + node.oldLinks = []; + + var activeSubflow = RED.nodes.subflow(node.z); + + treeList = $("<div>") + .css({width: "100%", height: "100%"}) + .appendTo(".node-input-link-row") + .treeList({}) + .on('treelistitemmouseover',function(e,item) { + if (item.node) { + item.node.highlighted = true; + item.node.dirty = true; + RED.view.redraw(); + } + }) + .on('treelistitemmouseout',function(e,item) { + if (item.node) { + item.node.highlighted = false; + item.node.dirty = true; + RED.view.redraw(); + } + }); + var candidateNodes = RED.nodes.filterNodes({type:targetType}); + + var flows = []; + var flowMap = {}; + + if (activeSubflow) { + flowMap[activeSubflow.id] = { + id: activeSubflow.id, + class: 'red-ui-palette-header', + label: "Subflow : "+(activeSubflow.name || activeSubflow.id), + expanded: true, + children: [] + }; + flows.push(flowMap[activeSubflow.id]) + } else { + RED.nodes.eachWorkspace(function(ws) { + flowMap[ws.id] = { + id: ws.id, + class: 'red-ui-palette-header', + label: (ws.label || ws.id)+(node.z===ws.id ? " *":""), + expanded: true, + children: [] + } + flows.push(flowMap[ws.id]) + }) + } + + candidateNodes.forEach(function(n) { + if (flowMap[n.z]) { + var isChecked = false; + isChecked = (node.links.indexOf(n.id) !== -1) || (n.links||[]).indexOf(node.id) !== -1; + if (isChecked) { + node.oldLinks.push(n.id); + } + flowMap[n.z].children.push({ + id: n.id, + node: n, + label: n.name||n.id, + selected: isChecked + }) + } + }); + flows = flows.filter(function(f) { return f.children.length > 0 }) + treeList.treeList('data',flows); + setTimeout(function() { + treeList.treeList('show',node.z); + },100); + } + + function resizeNodeList() { + var rows = $("#dialog-form>div:not(.node-input-link-row)"); + var height = $("#dialog-form").height(); + for (var i=0;i<rows.length;i++) { + height -= $(rows[i]).outerHeight(true); + } + var editorRow = $("#dialog-form>div.node-input-link-row"); + height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); + $(".node-input-link-row").css("height",height+"px"); + } + + function onEditSave(node) { + var flows = treeList.treeList('data'); + node.links = []; + flows.forEach(function(f) { + f.children.forEach(function(n) { + if (n.selected) { + node.links.push(n.id); + } + }) + }) + node.oldLinks.sort(); + node.links.sort(); + var nodeMap = {}; + var length = Math.max(node.oldLinks.length,node.links.length); + for (var i=0;i<length;i++) { + if (i<node.oldLinks.length) { + nodeMap[node.oldLinks[i]] = nodeMap[node.oldLinks[i]]||{}; + nodeMap[node.oldLinks[i]].old = true; + } + if (i<node.links.length) { + nodeMap[node.links[i]] = nodeMap[node.links[i]]||{}; + nodeMap[node.links[i]].new = true; + } + } + var n; + for (var id in nodeMap) { + if (nodeMap.hasOwnProperty(id)) { + n = RED.nodes.node(id); + if (n) { + if (nodeMap[id].old && !nodeMap[id].new) { + // Removed id + i = n.links.indexOf(node.id); + if (i > -1) { + n.links.splice(i,1); + } + } else if (!nodeMap[id].old && nodeMap[id].new) { + // Added id + i = n.links.indexOf(id); + if (i === -1) { + n.links.push(node.id); + } + } + } + } + } + } + + function onAdd() { + for (var i=0;i<this.links.length;i++) { + var n = RED.nodes.node(this.links[i]); + if (n && n.links.indexOf(this.id) === -1) { + n.links.push(this.id); + } + } + } + + RED.nodes.registerType('link in',{ + category: 'common', + color:"#ddd",//"#87D8CF", + defaults: { + name: {value:""}, + links: { value: [] } + }, + inputs:0, + outputs:1, + icon: "link-out.svg", + outputLabels: function(i) { + return this.name||this._("link.linkIn"); + }, + label: function() { + return this.name||this._("link.linkIn"); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + onEditPrepare(this,"link out"); + }, + oneditsave: function() { + onEditSave(this); + }, + onadd: onAdd, + oneditresize: resizeNodeList + }); + + RED.nodes.registerType('link out',{ + category: 'common', + color:"#ddd",//"#87D8CF", + defaults: { + name: {value:""}, + links: { value: []} + }, + align:"right", + inputs:1, + outputs:0, + icon: "link-out.svg", + inputLabels: function(i) { + return this.name||this._("link.linkOut"); + }, + label: function() { + return this.name||this._("link.linkOut"); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + onEditPrepare(this,"link in"); + }, + oneditsave: function() { + onEditSave(this); + }, + onadd: onAdd, + oneditresize: resizeNodeList + }); +})(); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/60-link.js b/packages/connector/packages/node_modules/@node-red/nodes/core/common/60-link.js new file mode 100644 index 0000000..df0cf88 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/60-link.js @@ -0,0 +1,50 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + + function LinkInNode(n) { + RED.nodes.createNode(this,n); + var node = this; + var event = "node:"+n.id; + var handler = function(msg) { + msg._event = n.event; + node.receive(msg); + } + RED.events.on(event,handler); + this.on("input", function(msg) { + this.send(msg); + }); + this.on("close",function() { + RED.events.removeListener(event,handler); + }); + } + + RED.nodes.registerType("link in",LinkInNode); + + function LinkOutNode(n) { + RED.nodes.createNode(this,n); + var node = this; + var event = "node:"+n.id; + this.on("input", function(msg) { + msg._event = event; + RED.events.emit(event,msg) + this.send(msg); + }); + } + RED.nodes.registerType("link out",LinkOutNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/90-comment.html b/packages/connector/packages/node_modules/@node-red/nodes/core/common/90-comment.html new file mode 100644 index 0000000..76c4547 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/90-comment.html @@ -0,0 +1,63 @@ + +<script type="text/x-red" data-template-name="comment"> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-row node-text-editor-row"> + <input type="hidden" id="node-input-info" autofocus="autofocus"> + <div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-input-info-editor"></div> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('comment',{ + category: 'common', + color:"#ffffff", + defaults: { + name: {value:""}, + info: {value:""} + }, + inputs:0, + outputs:0, + icon: "comment.svg", + label: function() { + return this.name||this._("comment.comment"); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + info: function() { + return this.name?"# "+this.name+"\n\n---\n\n":""; + }, + oneditprepare: function() { + var that = this; + this.editor = RED.editor.createEditor({ + id: 'node-input-info-editor', + mode: 'ace/mode/markdown', + value: $("#node-input-info").val() + }); + this.editor.focus(); + }, + oneditsave: function() { + $("#node-input-info").val(this.editor.getValue()); + this.editor.destroy(); + delete this.editor; + }, + oneditcancel: function() { + this.editor.destroy(); + delete this.editor; + }, + oneditresize: function(size) { + var rows = $("#dialog-form>div:not(.node-text-editor-row)"); + var height = $("#dialog-form").height(); + for (var i=0; i<rows.length; i++) { + height -= $(rows[i]).outerHeight(true); + } + var editorRow = $("#dialog-form>div.node-text-editor-row"); + height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); + $(".node-text-editor").css("height",height+"px"); + this.editor.resize(); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/90-comment.js b/packages/connector/packages/node_modules/@node-red/nodes/core/common/90-comment.js new file mode 100644 index 0000000..83d86e4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/90-comment.js @@ -0,0 +1,23 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + function CommentNode(n) { + RED.nodes.createNode(this,n); + } + RED.nodes.registerType("comment",CommentNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/98-unknown.html b/packages/connector/packages/node_modules/@node-red/nodes/core/common/98-unknown.html new file mode 100644 index 0000000..1bb681f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/98-unknown.html @@ -0,0 +1,23 @@ + +<script type="text/x-red" data-template-name="unknown"> + <div class="form-tips"><span data-i18n="[html]unknown.tip"></span></div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('unknown',{ + category: 'unknown', + color:"#fff0f0", + defaults: { + name: {value:""} + }, + inputs:1, + outputs:1, + icon: "", + label: function() { + return "("+this.name+")"||this._("unknown.label.unknown"); + }, + labelStyle: function() { + return "node_label_unknown"; + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/98-unknown.js b/packages/connector/packages/node_modules/@node-red/nodes/core/common/98-unknown.js new file mode 100644 index 0000000..0ee463b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/98-unknown.js @@ -0,0 +1,23 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + function UnknownNode(n) { + RED.nodes.createNode(this,n); + } + RED.nodes.registerType("unknown",UnknownNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug-utils.js b/packages/connector/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug-utils.js new file mode 100644 index 0000000..ddab5bb --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug-utils.js @@ -0,0 +1,565 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +if (!RED) { + var RED = {} +} +RED.debug = (function() { + var config; + var messageList; + var messageTable; + var filterType = "filterAll"; + var filteredNodes = {}; // id->true means hide, so default to all visible + + var view = 'list'; + var messages = []; + var messagesByNode = {}; + var sbc; + var activeWorkspace; + var numMessages = 100; // Hardcoded number of message to show in debug window scrollback + + var filterVisible = false; + + var debugNodeList; + var debugNodeListExpandedFlows = {}; + + function init(_config) { + config = _config; + + var content = $("<div>").css({"position":"relative","height":"100%"}); + var toolbar = $('<div class="red-ui-sidebar-header">'+ + '<span class="button-group"><a id="red-ui-sidebar-debug-filter" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-filter"></i> <span></span></a></span>'+ + '<span class="button-group"><a id="red-ui-sidebar-debug-clear" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-trash"></i></a></span></div>').appendTo(content); + + var footerToolbar = $('<div>'+ + // '<span class="button-group">'+ + // '<a class="red-ui-footer-button-toggle text-button selected" id="red-ui-sidebar-debug-view-list" href="#"><span data-i18n="">list</span></a>'+ + // '<a class="red-ui-footer-button-toggle text-button" id="red-ui-sidebar-debug-view-table" href="#"><span data-i18n="">table</span></a> '+ + // '</span>'+ + '<span class="button-group"><a id="red-ui-sidebar-debug-open" class="red-ui-footer-button" href="#"><i class="fa fa-desktop"></i></a></span> ' + + '</div>'); + + messageList = $('<div class="red-ui-debug-content red-ui-debug-content-list"/>').appendTo(content); + sbc = messageList[0]; + messageTable = $('<div class="red-ui-debug-content red-ui-debug-content-table hide"/>').appendTo(content); + + var filterDialog = $('<div class="red-ui-debug-filter-box hide">'+ + '<div class="red-ui-debug-filter-row">'+ + '<span class="button-group">'+ + '<a class="red-ui-sidebar-header-button-toggle red-ui-sidebar-debug-filter-option selected" id="red-ui-sidebar-debug-filterAll" href="#"><span data-i18n="node-red:debug.sidebar.filterAll"></span></a>'+ + '<a class="red-ui-sidebar-header-button-toggle red-ui-sidebar-debug-filter-option" id="red-ui-sidebar-debug-filterSelected" href="#"><span data-i18n="node-red:debug.sidebar.filterSelected"></span></a>'+ + '<a class="red-ui-sidebar-header-button-toggle red-ui-sidebar-debug-filter-option" id="red-ui-sidebar-debug-filterCurrent" href="#"><span data-i18n="node-red:debug.sidebar.filterCurrent"></span></a> '+ + '</span>'+ + '</div>'+ + '</div>').appendTo(toolbar);//content); + + // var filterTypeRow = $('<div class="red-ui-debug-filter-row"></div>').appendTo(filterDialog); + // $('<select><option>Show all debug nodes</option><option>Show selected debug nodes</option><option>Show current flow only</option></select>').appendTo(filterTypeRow); + + var debugNodeListRow = $('<div class="red-ui-debug-filter-row hide" id="red-ui-sidebar-debug-filter-node-list-row"></div>').appendTo(filterDialog); + var flowCheckboxes = {}; + var debugNodeListHeader = $('<div><span data-i18n="node-red:debug.sidebar.debugNodes"></span><span></span></div>'); + var headerCheckbox = $('<input type="checkbox">').appendTo(debugNodeListHeader.find("span")[1]).checkboxSet(); + + debugNodeList = $('<ol>',{style:"text-align: left; min-height: 250px; max-height: 250px"}).appendTo(debugNodeListRow).editableList({ + header: debugNodeListHeader, + class: 'red-ui-nodeList', + addItem: function(container,i,node) { + var row = $("<div>").appendTo(container); + row.attr('id','debug-filter-node-list-node-'+node.id.replace(/\./g,"_")); + if (node.type === 'tab') { + container.parent().addClass('red-ui-editableList-section-header'); + if (!debugNodeListExpandedFlows.hasOwnProperty(node.id)) { + debugNodeListExpandedFlows[node.id] = true; + } + var chevron = $('<i class="fa fa-angle-right"></i>').appendTo(row); + $('<span>').text(RED.utils.getNodeLabel(node,node.id)).appendTo(row); + var muteControl = $('<input type="checkbox">').appendTo($('<span class="meta">').appendTo(row)); + muteControl.checkboxSet({ + parent: headerCheckbox + }); + flowCheckboxes[node.id] = muteControl; + row.on("click", function(e) { + e.stopPropagation(); + debugNodeListExpandedFlows[node.id] = !debugNodeListExpandedFlows[node.id]; + row.toggleClass('expanded',debugNodeListExpandedFlows[node.id]); + debugNodeList.editableList('filter'); + }) + row.addClass("expandable"); + if (node.disabled) { + container.addClass('disabled'); + muteControl.checkboxSet('disable'); + debugNodeListExpandedFlows[node.id] = false; + } + row.toggleClass('expanded',debugNodeListExpandedFlows[node.id]); + } else { + $('<span>',{style: "margin-left: 20px"}).text(RED.utils.getNodeLabel(node,node.id)).appendTo(row); + row.on("mouseenter",function() { + config.messageMouseEnter(node.id); + }); + row.on("mouseleave",function() { + config.messageMouseLeave(node.id); + }); + var muteControl = $('<input type="checkbox">').prop('checked',!filteredNodes[node.id]).appendTo($('<span class="meta">').appendTo(row)); + muteControl.checkboxSet({ + parent: flowCheckboxes[node.z] + }).on("change", function(e) { + filteredNodes[node.id] = !$(this).prop('checked'); + $(".red-ui-debug-msg-node-"+node.id.replace(/\./g,"_")).toggleClass('hide',filteredNodes[node.id]); + }); + if (!node.active || RED.nodes.workspace(node.z).disabled) { + container.addClass('disabled'); + muteControl.checkboxSet('disable'); + } + } + }, + addButton: false, + scrollOnAdd: false, + filter: function(node) { + return (node.type === 'tab' || debugNodeListExpandedFlows[node.z] ) + }, + sort: function(A,B) { + + } + }); + + try { + content.i18n(); + } catch(err) { + console.log("TODO: i18n library support"); + } + + toolbar.find('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.filterAll')); + + var filterButtonHandler = function(type) { + return function(e) { + e.preventDefault(); + if (filterType !== type) { + $('.red-ui-sidebar-debug-filter-option').removeClass('selected'); + $(this).addClass('selected'); + if (filterType === 'filterSelected') { + debugNodeListRow.slideUp(); + } + filterType = type; + if (filterType === 'filterSelected') { + debugNodeListRow.slideDown(); + } + + $('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.'+filterType)); + refreshMessageList(); + } + } + } + filterDialog.find('#red-ui-sidebar-debug-filterAll').on("click",filterButtonHandler('filterAll')); + filterDialog.find('#red-ui-sidebar-debug-filterSelected').on("click",filterButtonHandler('filterSelected')); + filterDialog.find('#red-ui-sidebar-debug-filterCurrent').on("click",filterButtonHandler('filterCurrent')); + + + // $('#red-ui-sidebar-debug-view-list').on("click",function(e) { + // e.preventDefault(); + // if (!$(this).hasClass('selected')) { + // $(this).addClass('selected'); + // $('#red-ui-sidebar-debug-view-table').removeClass('selected'); + // showMessageList(); + // } + // }); + // $('#red-ui-sidebar-debug-view-table').on("click",function(e) { + // e.preventDefault(); + // if (!$(this).hasClass('selected')) { + // $(this).addClass('selected'); + // $('#red-ui-sidebar-debug-view-list').removeClass('selected'); + // showMessageTable(); + // } + // }); + + + var hideFilterTimeout; + toolbar.on('mouseleave',function() { + if ($('#red-ui-sidebar-debug-filter').hasClass('selected')) { + clearTimeout(hideFilterTimeout); + hideFilterTimeout = setTimeout(function() { + filterVisible = false; + $('#red-ui-sidebar-debug-filter').removeClass('selected'); + filterDialog.slideUp(200); + },300); + } + }); + toolbar.on('mouseenter',function() { + if ($('#red-ui-sidebar-debug-filter').hasClass('selected')) { + clearTimeout(hideFilterTimeout); + } + }) + toolbar.find('#red-ui-sidebar-debug-filter').on("click",function(e) { + e.preventDefault(); + if ($(this).hasClass('selected')) { + filterVisible = false; + $(this).removeClass('selected'); + clearTimeout(hideFilterTimeout); + filterDialog.slideUp(200); + } else { + $(this).addClass('selected'); + filterVisible = true; + refreshDebugNodeList(); + filterDialog.slideDown(200); + } + }); + RED.popover.tooltip(toolbar.find('#red-ui-sidebar-debug-filter'),RED._('node-red:debug.sidebar.filterLog')); + + toolbar.find("#red-ui-sidebar-debug-clear").on("click", function(e) { + e.preventDefault(); + clearMessageList(false); + }); + RED.popover.tooltip(toolbar.find("#red-ui-sidebar-debug-clear"),RED._('node-red:debug.sidebar.clearLog'),"core:clear-debug-messages"); + + + + return { + content: content, + footer: footerToolbar + } + + } + + function refreshDebugNodeList() { + debugNodeList.editableList('empty'); + var candidateNodes = RED.nodes.filterNodes({type:'debug'}); + var workspaceOrder = RED.nodes.getWorkspaceOrder(); + var workspaceOrderMap = {}; + workspaceOrder.forEach(function(ws,i) { + workspaceOrderMap[ws] = i; + }); + candidateNodes = candidateNodes.filter(function(node) { + return workspaceOrderMap.hasOwnProperty(node.z); + }) + candidateNodes.sort(function(A,B) { + var wsA = workspaceOrderMap[A.z]; + var wsB = workspaceOrderMap[B.z]; + if (wsA !== wsB) { + return wsA-wsB; + } + var labelA = RED.utils.getNodeLabel(A,A.id); + var labelB = RED.utils.getNodeLabel(B,B.id); + return labelA.localeCompare(labelB); + }) + var currentWs = null; + var nodeList = []; + candidateNodes.forEach(function(node) { + if (currentWs !== node.z) { + currentWs = node.z; + nodeList.push(RED.nodes.workspace(node.z)); + } + nodeList.push(node); + }) + + + debugNodeList.editableList('addItems',nodeList) + } + + function getTimestamp() { + var d = new Date(); + return d.toLocaleString(); + } + + function sanitize(m) { + return m.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"); + } + + function refreshMessageList(_activeWorkspace) { + if (_activeWorkspace) { + activeWorkspace = _activeWorkspace.replace(/\./g,"_"); + } + if (filterType === "filterAll") { + $(".red-ui-debug-msg").removeClass("hide"); + } else { + $(".red-ui-debug-msg").each(function() { + if (filterType === 'filterCurrent') { + $(this).toggleClass('hide',!$(this).hasClass('red-ui-debug-msg-flow-'+activeWorkspace)); + } else if (filterType === 'filterSelected') { + var id = $(this).data('source'); + if (id) { + $(this).toggleClass('hide',!!filteredNodes[id]); + } + } + }); + } + } + function refreshMessageTable() { + + } + + function showMessageList() { + view = 'list'; + messageTable.hide(); + messageTable.empty(); + + messages.forEach(function(m) { + messageList.append(m.el); + }) + messageList.show(); + } + function showMessageTable() { + view = 'table'; + messageList.hide(); + messageList.empty(); + + Object.keys(messagesByNode).forEach(function(id) { + var m = messagesByNode[id]; + var msg = m.el; + var sourceNode = m.source; + if (sourceNode) { + var wrapper = $("<div>",{id:"red-ui-debug-msg-source-"+sourceNode.id.replace(/\./g,"_")}).appendTo(messageTable); + wrapper.append(msg); + } + }); + messageTable.show(); + } + function formatString(str) { + return str.replace(/\n/g,"&crarr;").replace(/\t/g,"&rarr;"); + } + + + var menuOptionMenu; + var activeMenuMessage; + function showMessageMenu(button,dbgMessage,sourceId) { + activeMenuMessage = dbgMessage; + if (!menuOptionMenu) { + menuOptionMenu = RED.menu.init({id:"red-ui-debug-msg-option-menu", + options: [ + {id:"red-ui-debug-msg-menu-item-collapse",label:RED._("node-red:debug.messageMenu.collapseAll"),onselect:function(){ + activeMenuMessage.collapse(); + }}, + {id:"red-ui-debug-msg-menu-item-clear-pins",label:RED._("node-red:debug.messageMenu.clearPinned"),onselect:function(){ + activeMenuMessage.clearPinned(); + }}, + null, + {id:"red-ui-debug-msg-menu-item-filter", label:RED._("node-red:debug.messageMenu.filterNode"),onselect:function(){ + var candidateNodes = RED.nodes.filterNodes({type:'debug'}); + candidateNodes.forEach(function(n) { + filteredNodes[n.id] = true; + }); + delete filteredNodes[sourceId]; + $("#red-ui-sidebar-debug-filterSelected").trigger("click"); + refreshMessageList(); + }}, + {id:"red-ui-debug-msg-menu-item-clear-filter",label:RED._("node-red:debug.messageMenu.clearFilter"),onselect:function(){ + $("#red-ui-sidebar-debug-filterAll").trigger("click"); + refreshMessageList(); + }} + ] + }); + menuOptionMenu.css({ + position: "absolute" + }) + menuOptionMenu.on('mouseleave', function(){ $(this).hide() }); + menuOptionMenu.on('mouseup', function() { $(this).hide() }); + menuOptionMenu.appendTo("body"); + } + + var filterOptionDisabled = false; + var sourceNode = RED.nodes.node(sourceId); + if (sourceNode && sourceNode.type !== 'debug') { + filterOptionDisabled = true; + } + RED.menu.setDisabled('red-ui-debug-msg-menu-item-filter',filterOptionDisabled); + RED.menu.setDisabled('red-ui-debug-msg-menu-item-clear-filter',filterOptionDisabled); + + var elementPos = button.offset(); + menuOptionMenu.css({ + top: elementPos.top+"px", + left: (elementPos.left - menuOptionMenu.width() + 20)+"px" + }) + menuOptionMenu.show(); + } + + var stack = []; + var busy = false; + function handleDebugMessage(o) { + if (o) { stack.push(o); } + if (!busy && (stack.length > 0)) { + busy = true; + processDebugMessage(stack.shift()); + setTimeout(function() { + busy = false; + handleDebugMessage(); + }, 15); // every 15mS = 66 times a second + if (stack.length > numMessages) { stack = stack.splice(-numMessages); } + } + } + + function processDebugMessage(o) { + var msg = $("<div/>"); + var sourceNode = o._source; + + msg.on("mouseenter", function() { + msg.addClass('red-ui-debug-msg-hover'); + if (o._source) { + // highlight the top-level node (could be subflow instance) + config.messageMouseEnter(o._source.id); + if (o._source._alias) { + // this is inside a subflow - highlight the node itself + config.messageMouseEnter(o._source._alias); + } + // if path.length > 2, we are nested - highlight subflow instances + for (var i=2;i<o._source.path.length;i++) { + config.messageMouseEnter(o._source.path[i]); + } + } + }); + msg.on("mouseleave", function() { + msg.removeClass('red-ui-debug-msg-hover'); + if (o._source) { + config.messageMouseLeave(o._source.id); + if (o._source._alias) { + config.messageMouseLeave(o._source._alias); + } + for (var i=2;i<o._source.path.length;i++) { + config.messageMouseLeave(o._source.path[i]); + } + } + }); + var name = sanitize(((o.name?o.name:o.id)||"").toString()); + var topic = sanitize((o.topic||"").toString()); + var property = sanitize(o.property?o.property:''); + var payload = o.msg; + var format = sanitize((o.format||"").toString()); + msg.attr("class", 'red-ui-debug-msg'+(o.level?(' red-ui-debug-msg-level-'+o.level):'')+ + (sourceNode?( + " red-ui-debug-msg-node-"+sourceNode.id.replace(/\./g,"_")+ + (sourceNode.z?" red-ui-debug-msg-flow-"+sourceNode.z.replace(/\./g,"_"):"") + ):"")); + + if (sourceNode) { + msg.data('source',sourceNode.id); + if (filterType === "filterCurrent" && activeWorkspace) { + if (sourceNode.z && sourceNode.z.replace(/\./g,"_") !== activeWorkspace) { + msg.addClass('hide'); + } + } else if (filterType === 'filterSelected'){ + if (!!filteredNodes[sourceNode.id]) { + msg.addClass('hide'); + } + } + } + + var metaRow = $('<div class="red-ui-debug-msg-meta"></div>').appendTo(msg); + $('<span class="red-ui-debug-msg-date">'+ getTimestamp()+'</span>').appendTo(metaRow); + if (sourceNode) { + $('<a>',{href:"#",class:"red-ui-debug-msg-name"}).text('node: '+sanitize(o.name||sourceNode.name||sourceNode.id)) + .appendTo(metaRow) + .on("click", function(evt) { + evt.preventDefault(); + config.messageSourceClick(sourceNode.id, sourceNode._alias, sourceNode.path); + }); + } else if (name) { + $('<span class="red-ui-debug-msg-name">'+name+'</span>').appendTo(metaRow); + } + + payload = RED.utils.decodeObject(payload,format); + + var el = $('<span class="red-ui-debug-msg-payload"></span>').appendTo(msg); + var path = o.property||''; + var debugMessage = RED.utils.createObjectElement(payload, { + key: /*true*/null, + typeHint: format, + hideKey: false, + path: path, + sourceId: sourceNode&&sourceNode.id, + rootPath: path + }); + // Do this in a separate step so the element functions aren't stripped + debugMessage.appendTo(el); + // NOTE: relying on function error to have a "type" that all other msgs don't + if (o.hasOwnProperty("type") && (o.type === "function")) { + var errorLvlType = 'error'; + var errorLvl = 20; + if (o.hasOwnProperty("level") && o.level === 30) { + errorLvl = 30; + errorLvlType = 'warn'; + } + msg.addClass('red-ui-debug-msg-level-' + errorLvl); + $('<span class="red-ui-debug-msg-topic">function : (' + errorLvlType + ')</span>').appendTo(metaRow); + } else { + var tools = $('<span class="red-ui-debug-msg-tools button-group"></span>').appendTo(metaRow); + var filterMessage = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-caret-down"></i></button>').appendTo(tools); + filterMessage.on("click", function(e) { + e.preventDefault(); + e.stopPropagation(); + showMessageMenu(filterMessage,debugMessage,sourceNode&&sourceNode.id); + }); + $('<span class="red-ui-debug-msg-topic">'+ + (o.topic?topic+' : ':'')+ + (o.property?'msg.'+property:'msg')+" : "+format+ + '</span>').appendTo(metaRow); + } + + var atBottom = (sbc.scrollHeight-messageList.height()-sbc.scrollTop) < 5; + var m = { + el: msg + }; + messages.push(m); + if (sourceNode) { + m.source = sourceNode; + messagesByNode[sourceNode.id] = m; + } + if (view == "list") { + messageList.append(msg); + } else { + if (sourceNode) { + var wrapper = $("#red-ui-debug-msg-source-"+sourceNode.id.replace(/\./g,"_")); + if (wrapper.length === 0 ) { + wrapper = $("<div>",{id:"red-ui-debug-msg-source-"+sourceNode.id.replace(/\./g,"_")}).appendTo(messageTable); + } + wrapper.empty(); + wrapper.append(msg); + } + } + + if (messages.length === numMessages) { + m = messages.shift(); + if (view === "list") { + m.el.remove(); + } + } + if (atBottom) { + messageList.scrollTop(sbc.scrollHeight); + } + } + + function clearMessageList(clearFilter) { + $(".red-ui-debug-msg").remove(); + config.clear(); + if (!!clearFilter) { + clearFilterSettings(); + } + refreshDebugNodeList(); + } + + function clearFilterSettings() { + filteredNodes = {}; + filterType = 'filterAll'; + $('.red-ui-sidebar-debug-filter-option').removeClass('selected'); + $('#red-ui-sidebar-debug-filterAll').addClass('selected'); + $('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.filterAll')); + $('#red-ui-sidebar-debug-filter-node-list-row').slideUp(); + } + + return { + init: init, + refreshMessageList:refreshMessageList, + handleDebugMessage: handleDebugMessage, + clearMessageList: clearMessageList + } +})(); diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug.js b/packages/connector/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug.js new file mode 100644 index 0000000..3cca62e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/lib/debug/debug.js @@ -0,0 +1,32 @@ +$(function() { + RED.i18n.init({},function() { + var options = { + messageMouseEnter: function(sourceId) { + window.opener.postMessage({event:"mouseEnter",id:sourceId},'*'); + }, + messageMouseLeave: function(sourceId) { + window.opener.postMessage({event:"mouseLeave",id:sourceId},'*'); + }, + messageSourceClick: function(sourceId, aliasId, path) { + window.opener.postMessage({event:"mouseClick",id:sourceId, _alias: aliasId, path: path},'*'); + }, + clear: function() { + window.opener.postMessage({event:"clear"},'*'); + } + } + + var uiComponents = RED.debug.init(options); + + $(".red-ui-debug-window").append(uiComponents.content); + + window.addEventListener('message',function(evt) { + if (evt.data.event === "message") { + RED.debug.handleDebugMessage(evt.data.msg); + } else if (evt.data.event === "workspaceChange") { + RED.debug.refreshMessageList(evt.data.activeWorkspace); + } else if (evt.data.event === "projectChange") { + RED.debug.clearMessageList(true); + } + },false); + }) +}); diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/common/lib/debug/view.html b/packages/connector/packages/node_modules/@node-red/nodes/core/common/lib/debug/view.html new file mode 100644 index 0000000..3f0bdcf --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/common/lib/debug/view.html @@ -0,0 +1,13 @@ +<html> +<head> + <link rel="stylesheet" href="../../red/style.min.css"> + <link rel="stylesheet" href="../../vendor/font-awesome/css/font-awesome.min.css"> + <title>Node-RED Debug Tools</title> +</head> +<body class="red-ui-editor red-ui-debug-window"> +</body> +<script src="../../vendor/vendor.js"></script> +<script src="../../red/red.min.js"></script> +<script src="debug-utils.js"></script> +<script src="debug.js"></script> +</html> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/10-function.html b/packages/connector/packages/node_modules/@node-red/nodes/core/function/10-function.html new file mode 100644 index 0000000..9202d96 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/10-function.html @@ -0,0 +1,134 @@ + +<script type="text/x-red" data-template-name="function"> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <div style="display: inline-block; width: calc(100% - 105px)"><input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"></div> + </div> + <div class="form-row" style="margin-bottom: 0px;"> + <label for="node-input-func"><i class="fa fa-wrench"></i> <span data-i18n="function.label.function"></span></label> + <input type="hidden" id="node-input-func" autofocus="autofocus"> + <input type="hidden" id="node-input-noerr"> + </div> + <div class="form-row node-text-editor-row" style="position:relative"> + <div style="position: absolute; right:0; bottom:calc(100% + 3px);"><button id="node-function-expand-js" class="red-ui-button red-ui-button-small"><i class="fa fa-expand"></i></button></div> + <div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-input-func-editor" ></div> + </div> + <div class="form-row" style="margin-bottom: 0px"> + <label for="node-input-outputs"><i class="fa fa-random"></i> <span data-i18n="function.label.outputs"></span></label> + <input id="node-input-outputs" style="width: 60px;" value="1"> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('function',{ + color:"#fdd0a2", + category: 'function', + defaults: { + name: {value:""}, + func: {value:"\nreturn msg;"}, + outputs: {value:1}, + noerr: {value:0,required:true,validate:function(v) { return !v; }} + }, + inputs:1, + outputs:1, + icon: "function.svg", + label: function() { + return this.name||this._("function.function"); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + var that = this; + $( "#node-input-outputs" ).spinner({ + min:0, + change: function(event, ui) { + var value = this.value; + if (!value.match(/^\d+$/)) { value = 1; } + else if (value < this.min) { value = this.min; } + if (value !== this.value) { $(this).spinner("value", value); } + } + }); + + this.editor = RED.editor.createEditor({ + id: 'node-input-func-editor', + mode: 'ace/mode/nrjavascript', + value: $("#node-input-func").val(), + globals: { + msg:true, + context:true, + RED: true, + util: true, + flow: true, + global: true, + console: true, + Buffer: true, + setTimeout: true, + clearTimeout: true, + setInterval: true, + clearInterval: true + } + }); + + RED.library.create({ + url:"functions", // where to get the data from + type:"function", // the type of object the library is for + editor:this.editor, // the field name the main text body goes to + mode:"ace/mode/nrjavascript", + fields:['name','outputs'], + ext:"js" + }); + this.editor.focus(); + + RED.popover.tooltip($("#node-function-expand-js"), RED._("node-red:common.label.expand")); + + $("#node-function-expand-js").on("click", function(e) { + e.preventDefault(); + var value = that.editor.getValue(); + RED.editor.editJavaScript({ + value: value, + width: "Infinity", + cursor: that.editor.getCursorPosition(), + mode: "ace/mode/nrjavascript", + complete: function(v,cursor) { + that.editor.setValue(v, -1); + that.editor.gotoLine(cursor.row+1,cursor.column,false); + setTimeout(function() { + that.editor.focus(); + },300); + } + }) + }) + }, + oneditsave: function() { + var annot = this.editor.getSession().getAnnotations(); + this.noerr = 0; + $("#node-input-noerr").val(0); + for (var k=0; k < annot.length; k++) { + //console.log(annot[k].type,":",annot[k].text, "on line", annot[k].row); + if (annot[k].type === "error") { + $("#node-input-noerr").val(annot.length); + this.noerr = annot.length; + } + } + $("#node-input-func").val(this.editor.getValue()); + this.editor.destroy(); + delete this.editor; + }, + oneditcancel: function() { + this.editor.destroy(); + delete this.editor; + }, + oneditresize: function(size) { + var rows = $("#dialog-form>div:not(.node-text-editor-row)"); + var height = $("#dialog-form").height(); + for (var i=0; i<rows.length; i++) { + height -= $(rows[i]).outerHeight(true); + } + var editorRow = $("#dialog-form>div.node-text-editor-row"); + height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); + $(".node-text-editor").css("height",height+"px"); + this.editor.resize(); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/10-function.js b/packages/connector/packages/node_modules/@node-red/nodes/core/function/10-function.js new file mode 100644 index 0000000..65a1b4a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/10-function.js @@ -0,0 +1,316 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var util = require("util"); + var vm = require("vm"); + + function sendResults(node,send,_msgid,msgs,cloneFirstMessage) { + if (msgs == null) { + return; + } else if (!util.isArray(msgs)) { + msgs = [msgs]; + } + var msgCount = 0; + for (var m=0; m<msgs.length; m++) { + if (msgs[m]) { + if (!util.isArray(msgs[m])) { + msgs[m] = [msgs[m]]; + } + for (var n=0; n < msgs[m].length; n++) { + var msg = msgs[m][n]; + if (msg !== null && msg !== undefined) { + if (typeof msg === 'object' && !Buffer.isBuffer(msg) && !util.isArray(msg)) { + if (msgCount === 0 && cloneFirstMessage !== false) { + msgs[m][n] = RED.util.cloneMessage(msgs[m][n]); + msg = msgs[m][n]; + } + msg._msgid = _msgid; + msgCount++; + } else { + var type = typeof msg; + if (type === 'object') { + type = Buffer.isBuffer(msg)?'Buffer':(util.isArray(msg)?'Array':'Date'); + } + node.error(RED._("function.error.non-message-returned",{ type: type })); + } + } + } + } + } + if (msgCount>0) { + send(msgs); + } + } + + function FunctionNode(n) { + RED.nodes.createNode(this,n); + var node = this; + this.name = n.name; + this.func = n.func; + + var handleNodeDoneCall = true; + // Check to see if the Function appears to call `node.done()`. If so, + // we will assume it is well written and does actually call node.done(). + // Otherwise, we will call node.done() after the function returns regardless. + if (/node\.done\s*\(\s*\)/.test(this.func)) { + handleNodeDoneCall = false; + } + + var functionText = "var results = null;"+ + "results = (function(msg,__send__,__done__){ "+ + "var __msgid__ = msg._msgid;"+ + "var node = {"+ + "id:__node__.id,"+ + "name:__node__.name,"+ + "log:__node__.log,"+ + "error:__node__.error,"+ + "warn:__node__.warn,"+ + "debug:__node__.debug,"+ + "trace:__node__.trace,"+ + "on:__node__.on,"+ + "status:__node__.status,"+ + "send:function(msgs,cloneMsg){ __node__.send(__send__,__msgid__,msgs,cloneMsg);},"+ + "done:__done__"+ + "};\n"+ + this.func+"\n"+ + "})(msg,send,done);"; + this.topic = n.topic; + this.outstandingTimers = []; + this.outstandingIntervals = []; + var sandbox = { + console:console, + util:util, + Buffer:Buffer, + Date: Date, + RED: { + util: RED.util + }, + __node__: { + id: node.id, + name: node.name, + log: function() { + node.log.apply(node, arguments); + }, + error: function() { + node.error.apply(node, arguments); + }, + warn: function() { + node.warn.apply(node, arguments); + }, + debug: function() { + node.debug.apply(node, arguments); + }, + trace: function() { + node.trace.apply(node, arguments); + }, + send: function(send, id, msgs, cloneMsg) { + sendResults(node, send, id, msgs, cloneMsg); + }, + on: function() { + if (arguments[0] === "input") { + throw new Error(RED._("function.error.inputListener")); + } + node.on.apply(node, arguments); + }, + status: function() { + node.status.apply(node, arguments); + } + }, + context: { + set: function() { + node.context().set.apply(node,arguments); + }, + get: function() { + return node.context().get.apply(node,arguments); + }, + keys: function() { + return node.context().keys.apply(node,arguments); + }, + get global() { + return node.context().global; + }, + get flow() { + return node.context().flow; + } + }, + flow: { + set: function() { + node.context().flow.set.apply(node,arguments); + }, + get: function() { + return node.context().flow.get.apply(node,arguments); + }, + keys: function() { + return node.context().flow.keys.apply(node,arguments); + } + }, + global: { + set: function() { + node.context().global.set.apply(node,arguments); + }, + get: function() { + return node.context().global.get.apply(node,arguments); + }, + keys: function() { + return node.context().global.keys.apply(node,arguments); + } + }, + env: { + get: function(envVar) { + var flow = node._flow; + return flow.getSetting(envVar); + } + }, + setTimeout: function () { + var func = arguments[0]; + var timerId; + arguments[0] = function() { + sandbox.clearTimeout(timerId); + try { + func.apply(this,arguments); + } catch(err) { + node.error(err,{}); + } + }; + timerId = setTimeout.apply(this,arguments); + node.outstandingTimers.push(timerId); + return timerId; + }, + clearTimeout: function(id) { + clearTimeout(id); + var index = node.outstandingTimers.indexOf(id); + if (index > -1) { + node.outstandingTimers.splice(index,1); + } + }, + setInterval: function() { + var func = arguments[0]; + var timerId; + arguments[0] = function() { + try { + func.apply(this,arguments); + } catch(err) { + node.error(err,{}); + } + }; + timerId = setInterval.apply(this,arguments); + node.outstandingIntervals.push(timerId); + return timerId; + }, + clearInterval: function(id) { + clearInterval(id); + var index = node.outstandingIntervals.indexOf(id); + if (index > -1) { + node.outstandingIntervals.splice(index,1); + } + } + }; + if (util.hasOwnProperty('promisify')) { + sandbox.setTimeout[util.promisify.custom] = function(after, value) { + return new Promise(function(resolve, reject) { + sandbox.setTimeout(function(){ resolve(value); }, after); + }); + }; + } + var context = vm.createContext(sandbox); + try { + this.script = vm.createScript(functionText, { + filename: 'Function node:'+this.id+(this.name?' ['+this.name+']':''), // filename for stack traces + displayErrors: true + // Using the following options causes node 4/6 to not include the line number + // in the stack output. So don't use them. + // lineOffset: -11, // line number offset to be used for stack traces + // columnOffset: 0, // column number offset to be used for stack traces + }); + this.on("input", function(msg,send,done) { + try { + var start = process.hrtime(); + context.msg = msg; + context.send = send; + context.done = done; + + this.script.runInContext(context); + sendResults(this,send,msg._msgid,context.results,false); + if (handleNodeDoneCall) { + done(); + } + + var duration = process.hrtime(start); + var converted = Math.floor((duration[0] * 1e9 + duration[1])/10000)/100; + this.metric("duration", msg, converted); + if (process.env.NODE_RED_FUNCTION_TIME) { + this.status({fill:"yellow",shape:"dot",text:""+converted}); + } + } catch(err) { + if ((typeof err === "object") && err.hasOwnProperty("stack")) { + //remove unwanted part + var index = err.stack.search(/\n\s*at ContextifyScript.Script.runInContext/); + err.stack = err.stack.slice(0, index).split('\n').slice(0,-1).join('\n'); + var stack = err.stack.split(/\r?\n/); + + //store the error in msg to be used in flows + msg.error = err; + + var line = 0; + var errorMessage; + if (stack.length > 0) { + while (line < stack.length && stack[line].indexOf("ReferenceError") !== 0) { + line++; + } + + if (line < stack.length) { + errorMessage = stack[line]; + var m = /:(\d+):(\d+)$/.exec(stack[line+1]); + if (m) { + var lineno = Number(m[1])-1; + var cha = m[2]; + errorMessage += " (line "+lineno+", col "+cha+")"; + } + } + } + if (!errorMessage) { + errorMessage = err.toString(); + } + done(errorMessage); + } + else if (typeof err === "string") { + done(err); + } + else { + done(JSON.stringify(err)); + } + } + }); + this.on("close", function() { + while (node.outstandingTimers.length > 0) { + clearTimeout(node.outstandingTimers.pop()); + } + while (node.outstandingIntervals.length > 0) { + clearInterval(node.outstandingIntervals.pop()); + } + this.status({}); + }); + } catch(err) { + // eg SyntaxError - which v8 doesn't include line number information + // so we can't do better than this + this.error(err); + } + } + RED.nodes.registerType("function",FunctionNode); + RED.library.register("functions"); +}; diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/10-switch.html b/packages/connector/packages/node_modules/@node-red/nodes/core/function/10-switch.html new file mode 100644 index 0000000..6524a10 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/10-switch.html @@ -0,0 +1,461 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/html" data-template-name="switch"> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-row"> + <label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="switch.label.property"></span></label> + <input type="text" id="node-input-property" style="width: 70%"/> + <input type="hidden" id="node-input-outputs"/> + </div> + <div class="form-row node-input-rule-container-row"> + <ol id="node-input-rule-container"></ol> + </div> + <div class="form-row"> + <select id="node-input-checkall" style="width:100%; margin-right:5px;"> + <option value="true" data-i18n="switch.checkall"></option> + <option value="false" data-i18n="switch.stopfirst"></option> + </select> + </div> + <div class="form-row"> + <input type="checkbox" id="node-input-repair" style="display: inline-block; width: auto; vertical-align: top;"> + <label style="width: auto;" for="node-input-repair"><span data-i18n="switch.label.repair"></span></label></input> + </div> +</script> + +<script type="text/javascript"> +(function() { + var operators = [ + {v:"eq",t:"==",kind:'V'}, + {v:"neq",t:"!=",kind:'V'}, + {v:"lt",t:"<",kind:'V'}, + {v:"lte",t:"<=",kind:'V'}, + {v:"gt",t:">",kind:'V'}, + {v:"gte",t:">=",kind:'V'}, + {v:"hask",t:"switch.rules.hask",kind:'V'}, + {v:"btwn",t:"switch.rules.btwn",kind:'V'}, + {v:"cont",t:"switch.rules.cont",kind:'V'}, + {v:"regex",t:"switch.rules.regex",kind:'V'}, + {v:"true",t:"switch.rules.true",kind:'V'}, + {v:"false",t:"switch.rules.false",kind:'V'}, + {v:"null",t:"switch.rules.null",kind:'V'}, + {v:"nnull",t:"switch.rules.nnull",kind:'V'}, + {v:"istype",t:"switch.rules.istype",kind:'V'}, + {v:"empty",t:"switch.rules.empty",kind:'V'}, + {v:"nempty",t:"switch.rules.nempty",kind:'V'}, + {v:"head",t:"switch.rules.head",kind:'S'}, + {v:"index",t:"switch.rules.index",kind:'S'}, + {v:"tail",t:"switch.rules.tail",kind:'S'}, + {v:"jsonata_exp",t:"switch.rules.exp",kind:'O'}, + {v:"else",t:"switch.rules.else",kind:'O'} + ]; + + function clipValueLength(v) { + if (v.length > 15) { + return v.substring(0,15)+"..."; + } + return v; + } + function prop2name(key) { + var result = RED.utils.parseContextKey(key); + return result.key; + } + function getValueLabel(t,v) { + if (t === 'str') { + return '"'+clipValueLength(v)+'"'; + } else if (t === 'msg') { + return t+"."+clipValueLength(v); + } else if (t === 'flow' || t === 'global') { + return t+"."+clipValueLength(prop2name(v)); + } + return clipValueLength(v); + } + RED.nodes.registerType('switch', { + color: "#E2D96E", + category: 'function', + defaults: { + name: {value:""}, + property: {value:"payload", required:true, validate: RED.validators.typedInput("propertyType")}, + propertyType: { value:"msg" }, + rules: {value:[{t:"eq", v:"", vt:"str"}]}, + checkall: {value:"true", required:true}, + repair: {value:false}, + outputs: {value:1} + }, + inputs: 1, + outputs: 1, + outputLabels: function(index) { + var rule = this.rules[index]; + var label = ""; + if (rule) { + for (var i=0;i<operators.length;i++) { + if (operators[i].v === rule.t) { + label = /^switch/.test(operators[i].t)?this._(operators[i].t):operators[i].t; + break; + } + } + if ((rule.t === 'btwn') || (rule.t === 'index')) { + label += " "+getValueLabel(rule.vt,rule.v)+" & "+getValueLabel(rule.v2t,rule.v2); + } else if (rule.t !== 'true' && rule.t !== 'false' && rule.t !== 'null' && rule.t !== 'nnull' && rule.t !== 'empty' && rule.t !== 'nempty' && rule.t !== 'else' ) { + label += " "+getValueLabel(rule.vt,rule.v); + } + return label; + } + }, + icon: "switch.svg", + label: function() { + return this.name||this._("switch.switch"); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + var node = this; + var previousValueType = {value:"prev",label:this._("switch.previous"),hasValue:false}; + + $("#node-input-property").typedInput({default:this.propertyType||'msg',types:['msg','flow','global','jsonata','env']}); + var outputCount = $("#node-input-outputs").val("{}"); + + var andLabel = this._("switch.and"); + var caseLabel = this._("switch.ignorecase"); + + function resizeRule(rule) { + var newWidth = rule.width(); + var selectField = rule.find("select"); + var type = selectField.val()||""; + var valueField = rule.find(".node-input-rule-value"); + var typeField = rule.find(".node-input-rule-type-value"); + var numField = rule.find(".node-input-rule-num-value"); + var expField = rule.find(".node-input-rule-exp-value"); + var keyField = rule.find(".node-input-rule-key-value"); + var btwnField1 = rule.find(".node-input-rule-btwn-value"); + var btwnField2 = rule.find(".node-input-rule-btwn-value2"); + var selectWidth; + if (type.length < 4) { + selectWidth = 60; + } else if (type === "regex") { + selectWidth = 147; + } else { + selectWidth = 120; + } + selectField.width(selectWidth); + if ((type === "btwn") || (type === "index")) { + btwnField1.typedInput("width",(newWidth-selectWidth-70)); + btwnField2.typedInput("width",(newWidth-selectWidth-70)); + } else if ((type === "head") || (type === "tail")) { + numField.typedInput("width",(newWidth-selectWidth-70)); + } else if (type === "jsonata_exp") { + expField.typedInput("width",(newWidth-selectWidth-70)); + } else if (type === "istype") { + typeField.typedInput("width",(newWidth-selectWidth-70)); + } else { + if (type === "true" || type === "false" || type === "null" || type === "nnull" || type === "empty" || type === "nempty" || type === "else") { + // valueField.hide(); + } else { + valueField.typedInput("width",(newWidth-selectWidth-70)); + } + } + } + + $("#node-input-rule-container").css('min-height','150px').css('min-width','450px').editableList({ + addItem: function(container,i,opt) { + if (!opt.hasOwnProperty('r')) { + opt.r = {}; + } + var rule = opt.r; + if (!rule.hasOwnProperty('t')) { + rule.t = 'eq'; + } + if (!opt.hasOwnProperty('i')) { + opt._i = Math.floor((0x99999-0x10000)*Math.random()).toString(); + } + container.css({ + overflow: 'hidden', + whiteSpace: 'nowrap' + }); + var row = $('<div/>').appendTo(container); + var row2 = $('<div/>',{style:"padding-top: 5px; padding-left: 175px;"}).appendTo(container); + var row3 = $('<div/>',{style:"padding-top: 5px; padding-left: 102px;"}).appendTo(container); + var selectField = $('<select/>',{style:"width:120px; margin-left: 5px; text-align: center;"}).appendTo(row); + var group0 = $('<optgroup/>', { label: "value rules" }).appendTo(selectField); + for (var d in operators) { + if(operators[d].kind === 'V') { + group0.append($("<option></option>").val(operators[d].v).text(/^switch/.test(operators[d].t)?node._(operators[d].t):operators[d].t)); + } + } + var group1 = $('<optgroup/>', { label: "sequence rules" }).appendTo(selectField); + for (var d in operators) { + if(operators[d].kind === 'S') { + group1.append($("<option></option>").val(operators[d].v).text(/^switch/.test(operators[d].t)?node._(operators[d].t):operators[d].t)); + } + } + for (var d in operators) { + if(operators[d].kind === 'O') { + selectField.append($("<option></option>").val(operators[d].v).text(/^switch/.test(operators[d].t)?node._(operators[d].t):operators[d].t)); + } + } + + function createValueField(){ + return $('<input/>',{class:"node-input-rule-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'str',types:['msg','flow','global','str','num','jsonata','env',previousValueType]}); + } + + function createNumValueField(){ + return $('<input/>',{class:"node-input-rule-num-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'num',types:['flow','global','num','jsonata','env']}); + } + + function createExpValueField(){ + return $('<input/>',{class:"node-input-rule-exp-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'jsonata',types:['jsonata']}); + } + + function createBtwnValueField(){ + return $('<input/>',{class:"node-input-rule-btwn-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]}); + } + + function createBtwnAndLabel(){ + return $('<span/>',{class:"node-input-rule-btwn-label"}).text(" "+andLabel+" ").appendTo(row3); + } + + function createBtwnValue2Field(){ + return $('<input/>',{class:"node-input-rule-btwn-value2",type:"text",style:"margin-left:2px;"}).appendTo(row3).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]}); + } + + function createTypeValueField(){ + return $('<input/>',{class:"node-input-rule-type-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'string',types:[ + {value:"string",label:RED._("common.type.string"),hasValue:false,icon:"red/images/typedInput/az.png"}, + {value:"number",label:RED._("common.type.number"),hasValue:false,icon:"red/images/typedInput/09.png"}, + {value:"boolean",label:RED._("common.type.boolean"),hasValue:false,icon:"red/images/typedInput/bool.png"}, + {value:"array",label:RED._("common.type.array"),hasValue:false,icon:"red/images/typedInput/json.png"}, + {value:"buffer",label:RED._("common.type.buffer"),hasValue:false,icon:"red/images/typedInput/bin.png"}, + {value:"object",label:RED._("common.type.object"),hasValue:false,icon:"red/images/typedInput/json.png"}, + {value:"json",label:RED._("common.type.jsonString"),hasValue:false,icon:"red/images/typedInput/json.png"}, + {value:"undefined",label:RED._("common.type.undefined"),hasValue:false}, + {value:"null",label:RED._("common.type.null"),hasValue:false} + ]}); + } + + var valueField = null; + var numValueField = null; + var expValueField = null; + var btwnAndLabel = null; + var btwnValueField = null; + var btwnValue2Field = null; + var typeValueField = null; + + var finalspan = $('<span/>',{style:"float: right;margin-top: 6px;"}).appendTo(row); + finalspan.append(' &#8594; <span class="node-input-rule-index">'+(i+1)+'</span> '); + var caseSensitive = $('<input/>',{id:"node-input-rule-case-"+i,class:"node-input-rule-case",type:"checkbox",style:"width:auto;vertical-align:top"}).appendTo(row2); + $('<label/>',{for:"node-input-rule-case-"+i,style:"margin-left: 3px;"}).text(caseLabel).appendTo(row2); + selectField.on("change", function() { + var type = selectField.val(); + if (valueField){ + valueField.typedInput('hide'); + } + if (expValueField){ + expValueField.typedInput('hide'); + } + if (numValueField){ + numValueField.typedInput('hide'); + } + if (typeValueField){ + typeValueField.typedInput('hide'); + } + if (btwnValueField){ + btwnValueField.typedInput('hide'); + } + if (btwnValue2Field){ + btwnValue2Field.typedInput('hide'); + } + + if ((type === "btwn") || (type === "index")) { + if (!btwnValueField){ + btwnValueField = createBtwnValueField(); + } + btwnValueField.typedInput('show'); + } else if ((type === "head") || (type === "tail")) { + if (!numValueField){ + numValueField = createNumValueField(); + } + numValueField.typedInput('show'); + } else if (type === "jsonata_exp") { + if (!expValueField){ + expValueField = createExpValueField(); + } + expValueField.typedInput('show'); + } else if (type === "istype") { + if (!typeValueField){ + typeValueField = createTypeValueField(); + } + typeValueField.typedInput('show'); + } else if (! (type === "true" || type === "false" || type === "null" || type === "nnull" || type === "empty" || type === "nempty" || type === "else" )) { + if (!valueField){ + valueField = createValueField(); + } + valueField.typedInput('show'); + } + if (type === "regex") { + row2.show(); + row3.hide(); + } else if ((type === "btwn") || (type === "index")) { + row2.hide(); + row3.show(); + if (!btwnValue2Field){ + btwnValue2Field = createBtwnValue2Field(); + } + btwnValue2Field.typedInput('show'); + } else { + row2.hide(); + row3.hide(); + } + resizeRule(container); + + }); + selectField.val(rule.t); + if ((rule.t == "btwn") || (rule.t == "index")) { + if (!btwnValueField){ + btwnValueField = createBtwnValueField(); + } + btwnValueField.typedInput('value',rule.v); + btwnValueField.typedInput('type',rule.vt||'num'); + + if (!btwnValue2Field){ + btwnValue2Field = createBtwnValue2Field(); + } + btwnValue2Field.typedInput('value',rule.v2); + btwnValue2Field.typedInput('type',rule.v2t||'num'); + } else if ((rule.t === "head") || (rule.t === "tail")) { + if (!numValueField){ + numValueField = createNumValueField(); + } + numValueField.typedInput('value',rule.v); + numValueField.typedInput('type',rule.vt||'num'); + } else if (rule.t === "istype") { + if (!typeValueField){ + typeValueField =createTypeValueField(); + } + typeValueField.typedInput('value',rule.vt); + typeValueField.typedInput('type',rule.vt); + } else if (rule.t === "jsonata_exp") { + if (!expValueField){ + expValueField = createExpValueField(); + } + expValueField.typedInput('value',rule.v); + expValueField.typedInput('type',rule.vt||'jsonata'); + } else if (typeof rule.v != "undefined") { + if (!valueField){ + valueField = createValueField(); + } + valueField.typedInput('value',rule.v); + valueField.typedInput('type',rule.vt||'str'); + } + if (rule.case) { + caseSensitive.prop('checked',true); + } else { + caseSensitive.prop('checked',false); + } + selectField.change(); + + var currentOutputs = JSON.parse(outputCount.val()||"{}"); + currentOutputs[opt.hasOwnProperty('i')?opt.i:opt._i] = i; + outputCount.val(JSON.stringify(currentOutputs)); + }, + removeItem: function(opt) { + var currentOutputs = JSON.parse(outputCount.val()||"{}"); + if (opt.hasOwnProperty('i')) { + currentOutputs[opt.i] = -1; + } else { + delete currentOutputs[opt._i]; + } + var rules = $("#node-input-rule-container").editableList('items'); + rules.each(function(i) { + $(this).find(".node-input-rule-index").html(i+1); + var data = $(this).data('data'); + currentOutputs[data.hasOwnProperty('i')?data.i:data._i] = i; + }); + outputCount.val(JSON.stringify(currentOutputs)); + }, + resizeItem: resizeRule, + sortItems: function(rules) { + var currentOutputs = JSON.parse(outputCount.val()||"{}"); + var rules = $("#node-input-rule-container").editableList('items'); + rules.each(function(i) { + $(this).find(".node-input-rule-index").html(i+1); + var data = $(this).data('data'); + currentOutputs[data.hasOwnProperty('i')?data.i:data._i] = i; + }); + outputCount.val(JSON.stringify(currentOutputs)); + }, + sortable: true, + removable: true + }); + + for (var i=0;i<this.rules.length;i++) { + var rule = this.rules[i]; + $("#node-input-rule-container").editableList('addItem',{r:rule,i:i}); + } + }, + oneditsave: function() { + var rules = $("#node-input-rule-container").editableList('items'); + var node = this; + node.rules = []; + rules.each(function(i) { + var ruleData = $(this).data('data'); + var rule = $(this); + var type = rule.find("select").val(); + var r = {t:type}; + if (!(type === "true" || type === "false" || type === "null" || type === "nnull" || type === "empty" || type === "nempty" || type === "else")) { + if ((type === "btwn") || (type === "index")) { + r.v = rule.find(".node-input-rule-btwn-value").typedInput('value'); + r.vt = rule.find(".node-input-rule-btwn-value").typedInput('type'); + r.v2 = rule.find(".node-input-rule-btwn-value2").typedInput('value'); + r.v2t = rule.find(".node-input-rule-btwn-value2").typedInput('type'); + } else if ((type === "head") || (type === "tail")) { + r.v = rule.find(".node-input-rule-num-value").typedInput('value'); + r.vt = rule.find(".node-input-rule-num-value").typedInput('type'); + } else if (type === "istype") { + r.v = rule.find(".node-input-rule-type-value").typedInput('type'); + r.vt = rule.find(".node-input-rule-type-value").typedInput('type'); + } else if (type === "jsonata_exp") { + r.v = rule.find(".node-input-rule-exp-value").typedInput('value'); + r.vt = rule.find(".node-input-rule-exp-value").typedInput('type'); + } else { + r.v = rule.find(".node-input-rule-value").typedInput('value'); + r.vt = rule.find(".node-input-rule-value").typedInput('type'); + } + if (type === "regex") { + r.case = rule.find(".node-input-rule-case").prop("checked"); + } + } + node.rules.push(r); + }); + this.propertyType = $("#node-input-property").typedInput('type'); + }, + oneditresize: function(size) { + var rows = $("#dialog-form>div:not(.node-input-rule-container-row)"); + var height = size.height; + for (var i=0;i<rows.length;i++) { + height -= $(rows[i]).outerHeight(true); + } + var editorRow = $("#dialog-form>div.node-input-rule-container-row"); + height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); + height += 16; + $("#node-input-rule-container").editableList('height',height); + } + }); +})(); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/10-switch.js b/packages/connector/packages/node_modules/@node-red/nodes/core/function/10-switch.js new file mode 100644 index 0000000..1761853 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/10-switch.js @@ -0,0 +1,505 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + + var operators = { + 'eq': function(a, b) { return a == b; }, + 'neq': function(a, b) { return a != b; }, + 'lt': function(a, b) { return a < b; }, + 'lte': function(a, b) { return a <= b; }, + 'gt': function(a, b) { return a > b; }, + 'gte': function(a, b) { return a >= b; }, + 'btwn': function(a, b, c) { return (a >= b && a <= c) || (a <= b && a >= c); }, + 'cont': function(a, b) { return (a + "").indexOf(b) != -1; }, + 'regex': function(a, b, c, d) { return (a + "").match(new RegExp(b,d?'i':'')); }, + 'true': function(a) { return a === true; }, + 'false': function(a) { return a === false; }, + 'null': function(a) { return (typeof a == "undefined" || a === null); }, + 'nnull': function(a) { return (typeof a != "undefined" && a !== null); }, + 'empty': function(a) { + if (typeof a === 'string' || Array.isArray(a) || Buffer.isBuffer(a)) { + return a.length === 0; + } else if (typeof a === 'object' && a !== null) { + return Object.keys(a).length === 0; + } + return false; + }, + 'nempty': function(a) { + if (typeof a === 'string' || Array.isArray(a) || Buffer.isBuffer(a)) { + return a.length !== 0; + } else if (typeof a === 'object' && a !== null) { + return Object.keys(a).length !== 0; + } + return false; + }, + 'istype': function(a, b) { + if (b === "array") { return Array.isArray(a); } + else if (b === "buffer") { return Buffer.isBuffer(a); } + else if (b === "json") { + try { JSON.parse(a); return true; } // or maybe ??? a !== null; } + catch(e) { return false;} + } + else if (b === "null") { return a === null; } + else { return typeof a === b && !Array.isArray(a) && !Buffer.isBuffer(a) && a !== null; } + }, + 'head': function(a, b, c, d, parts) { + var count = Number(b); + return (parts.index < count); + }, + 'tail': function(a, b, c, d, parts) { + var count = Number(b); + return (parts.count -count <= parts.index); + }, + 'index': function(a, b, c, d, parts) { + var min = Number(b); + var max = Number(c); + var index = parts.index; + return ((min <= index) && (index <= max)); + }, + 'hask': function(a, b) { + return (typeof b !== "object" ) && a.hasOwnProperty(b+""); + }, + 'jsonata_exp': function(a, b) { return (b === true); }, + 'else': function(a) { return a === true; } + }; + + var _maxKeptCount; + + function getMaxKeptCount() { + if (_maxKeptCount === undefined) { + var name = "nodeMessageBufferMaxLength"; + if (RED.settings.hasOwnProperty(name)) { + _maxKeptCount = RED.settings[name]; + } + else { + _maxKeptCount = 0; + } + } + return _maxKeptCount; + } + + function getProperty(node,msg,done) { + if (node.propertyType === 'jsonata') { + RED.util.evaluateJSONataExpression(node.property,msg,(err,value) => { + if (err) { + done(RED._("switch.errors.invalid-expr",{error:err.message})); + } else { + done(undefined,value); + } + }); + } else { + RED.util.evaluateNodeProperty(node.property,node.propertyType,node,msg,(err,value) => { + if (err) { + done(undefined,undefined); + } else { + done(undefined,value); + } + }); + } + } + + function getV1(node,msg,rule,hasParts,done) { + if (rule.vt === 'prev') { + return done(undefined,node.previousValue); + } else if (rule.vt === 'jsonata') { + var exp = rule.v; + if (rule.t === 'jsonata_exp') { + if (hasParts) { + exp.assign("I", msg.parts.index); + exp.assign("N", msg.parts.count); + } + } + RED.util.evaluateJSONataExpression(exp,msg,(err,value) => { + if (err) { + done(RED._("switch.errors.invalid-expr",{error:err.message})); + } else { + done(undefined, value); + } + }); + } else if (rule.vt === 'json') { + done(undefined,"json"); // TODO: ?! invalid case + } else if (rule.vt === 'null') { + done(undefined,"null"); + } else { + RED.util.evaluateNodeProperty(rule.v,rule.vt,node,msg, function(err,value) { + if (err) { + done(undefined, undefined); + } else { + done(undefined, value); + } + }); + } + } + + function getV2(node,msg,rule,done) { + var v2 = rule.v2; + if (rule.v2t === 'prev') { + return done(undefined,node.previousValue); + } else if (rule.v2t === 'jsonata') { + RED.util.evaluateJSONataExpression(rule.v2,msg,(err,value) => { + if (err) { + done(RED._("switch.errors.invalid-expr",{error:err.message})); + } else { + done(undefined,value); + } + }); + } else if (typeof v2 !== 'undefined') { + RED.util.evaluateNodeProperty(rule.v2,rule.v2t,node,msg, function(err,value) { + if (err) { + done(undefined,undefined); + } else { + done(undefined,value); + } + }); + } else { + done(undefined,v2); + } + } + + function applyRule(node, msg, property, state, done) { + var rule = node.rules[state.currentRule]; + var v1,v2; + + getV1(node,msg,rule,state.hasParts, (err,value) => { + if (err) { + return done(err); + } + v1 = value; + getV2(node,msg,rule, (err,value) => { + if (err) { + return done(err); + } + v2 = value; + if (rule.t == "else") { + property = state.elseflag; + state.elseflag = true; + } + if (operators[rule.t](property,v1,v2,rule.case,msg.parts)) { + state.onward.push(msg); + state.elseflag = false; + if (node.checkall == "false") { + return done(undefined,false); + } + } else { + state.onward.push(null); + } + done(undefined, state.currentRule < node.rules.length - 1); + }); + }); + } + + function applyRules(node, msg, property,state,done) { + if (!state) { + state = { + currentRule: 0, + elseflag: true, + onward: [], + hasParts: msg.hasOwnProperty("parts") && + msg.parts.hasOwnProperty("id") && + msg.parts.hasOwnProperty("index") + } + } + applyRule(node,msg,property,state,(err,hasMore) => { + if (err) { + return done(err); + } + if (hasMore) { + state.currentRule++; + applyRules(node,msg,property,state,done); + } else { + node.previousValue = property; + done(undefined,state.onward); + } + }); + } + + + function SwitchNode(n) { + RED.nodes.createNode(this, n); + this.rules = n.rules || []; + this.property = n.property; + this.propertyType = n.propertyType || "msg"; + + if (this.propertyType === 'jsonata') { + try { + this.property = RED.util.prepareJSONataExpression(this.property,this); + } catch(err) { + this.error(RED._("switch.errors.invalid-expr",{error:err.message})); + return; + } + } + + this.checkall = n.checkall || "true"; + this.previousValue = null; + var node = this; + var valid = true; + var repair = n.repair; + var needsCount = repair; + + for (var i=0; i<this.rules.length; i+=1) { + var rule = this.rules[i]; + needsCount = needsCount || ((rule.t === "tail") || (rule.t === "jsonata_exp")); + if (!rule.vt) { + if (!isNaN(Number(rule.v))) { + rule.vt = 'num'; + } else { + rule.vt = 'str'; + } + } + if (rule.vt === 'num') { + if (!isNaN(Number(rule.v))) { + rule.v = Number(rule.v); + } + } else if (rule.vt === "jsonata") { + try { + rule.v = RED.util.prepareJSONataExpression(rule.v,node); + } catch(err) { + this.error(RED._("switch.errors.invalid-expr",{error:err.message})); + valid = false; + } + } + if (typeof rule.v2 !== 'undefined') { + if (!rule.v2t) { + if (!isNaN(Number(rule.v2))) { + rule.v2t = 'num'; + } else { + rule.v2t = 'str'; + } + } + if (rule.v2t === 'num') { + rule.v2 = Number(rule.v2); + } else if (rule.v2t === 'jsonata') { + try { + rule.v2 = RED.util.prepareJSONataExpression(rule.v2,node); + } catch(err) { + this.error(RED._("switch.errors.invalid-expr",{error:err.message})); + valid = false; + } + } + } + } + if (!valid) { + return; + } + + var pendingCount = 0; + var pendingId = 0; + var pendingIn = {}; + var pendingOut = {}; + var received = {}; + + function addMessageToGroup(id, msg, parts) { + if (!(id in pendingIn)) { + pendingIn[id] = { + count: undefined, + msgs: [], + seq_no: pendingId++ + }; + } + var group = pendingIn[id]; + group.msgs.push(msg); + pendingCount++; + var max_msgs = getMaxKeptCount(); + if ((max_msgs > 0) && (pendingCount > max_msgs)) { + clearPending(); + node.error(RED._("switch.errors.too-many"), msg); + } + if (parts.hasOwnProperty("count")) { + group.count = parts.count; + } + return group; + } + + function drainMessageGroup(msgs,count,done) { + var msg = msgs.shift(); + msg.parts.count = count; + processMessage(msg,false, err => { + if (err) { + done(err); + } else { + if (msgs.length === 0) { + done() + } else { + drainMessageGroup(msgs,count,done); + } + } + }) + } + function addMessageToPending(msg,done) { + var parts = msg.parts; + // We've already checked the msg.parts has the require bits + var group = addMessageToGroup(parts.id, msg, parts); + var msgs = group.msgs; + var count = group.count; + var msgsCount = msgs.length; + if (count === msgsCount) { + // We have a complete group - send the individual parts + drainMessageGroup(msgs,count,err => { + pendingCount -= msgsCount; + delete pendingIn[parts.id]; + done(); + }) + return; + } + done(); + } + + function sendGroup(onwards, port_count) { + var counts = new Array(port_count).fill(0); + for (var i = 0; i < onwards.length; i++) { + var onward = onwards[i]; + for (var j = 0; j < port_count; j++) { + counts[j] += (onward[j] !== null) ? 1 : 0 + } + } + var ids = new Array(port_count); + for (var j = 0; j < port_count; j++) { + ids[j] = RED.util.generateId(); + } + var ports = new Array(port_count); + var indexes = new Array(port_count).fill(0); + for (var i = 0; i < onwards.length; i++) { + var onward = onwards[i]; + for (var j = 0; j < port_count; j++) { + var msg = onward[j]; + if (msg) { + var new_msg = RED.util.cloneMessage(msg); + var parts = new_msg.parts; + parts.id = ids[j]; + parts.index = indexes[j]; + parts.count = counts[j]; + ports[j] = new_msg; + indexes[j]++; + } + else { + ports[j] = null; + } + } + node.send(ports); + } + } + + function sendGroupMessages(onward, msg) { + var parts = msg.parts; + var gid = parts.id; + received[gid] = ((gid in received) ? received[gid] : 0) +1; + var send_ok = (received[gid] === parts.count); + + if (!(gid in pendingOut)) { + pendingOut[gid] = { + onwards: [] + }; + } + var group = pendingOut[gid]; + var onwards = group.onwards; + onwards.push(onward); + pendingCount++; + if (send_ok) { + sendGroup(onwards, onward.length, msg); + pendingCount -= onward.length; + delete pendingOut[gid]; + delete received[gid]; + } + var max_msgs = getMaxKeptCount(); + if ((max_msgs > 0) && (pendingCount > max_msgs)) { + clearPending(); + node.error(RED._("switch.errors.too-many"), msg); + } + } + + function processMessage(msg, checkParts, done) { + var hasParts = msg.hasOwnProperty("parts") && + msg.parts.hasOwnProperty("id") && + msg.parts.hasOwnProperty("index"); + + if (needsCount && checkParts && hasParts) { + addMessageToPending(msg,done); + } else { + getProperty(node,msg,(err,property) => { + if (err) { + node.warn(err); + done(); + } else { + applyRules(node,msg,property,undefined,(err,onward) => { + if (err) { + node.warn(err); + } else { + if (!repair || !hasParts) { + node.send(onward); + } else { + sendGroupMessages(onward, msg); + } + } + done(); + }); + } + }); + } + } + + function clearPending() { + pendingCount = 0; + pendingId = 0; + pendingIn = {}; + pendingOut = {}; + received = {}; + } + + var pendingMessages = []; + var handlingMessage = false; + var processMessageQueue = function(msg) { + if (msg) { + + // A new message has arrived - add it to the message queue + pendingMessages.push(msg); + if (handlingMessage) { + // The node is currently processing a message, so do nothing + // more with this message + return; + } + } + if (pendingMessages.length === 0) { + // There are no more messages to process, clear the active flag + // and return + handlingMessage = false; + return; + } + + // There are more messages to process. Get the next message and + // start processing it. Recurse back in to check for any more + var nextMsg = pendingMessages.shift(); + handlingMessage = true; + processMessage(nextMsg,true,err => { + if (err) { + node.error(err,nextMsg); + } + processMessageQueue() + }); + } + + this.on('input', function(msg) { + processMessageQueue(msg); + }); + + this.on('close', function() { + clearPending(); + }); + } + + RED.nodes.registerType("switch", SwitchNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/15-change.html b/packages/connector/packages/node_modules/@node-red/nodes/core/function/15-change.html new file mode 100644 index 0000000..fc9fa8d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/15-change.html @@ -0,0 +1,266 @@ + +<script type="text/html" data-template-name="change"> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-row" style="margin-bottom:0;"> + <label><i class="fa fa-list"></i> <span data-i18n="change.label.rules"></span></label> + </div> + <div class="form-row node-input-rule-container-row"> + <ol id="node-input-rule-container"></ol> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('change', { + color: "#E2D96E", + category: 'function', + defaults: { + name: {value:""}, + rules:{value:[{t:"set",p:"payload",pt:"msg",to:"",tot:"str"}]}, + // legacy + action: {value:""}, + property: {value:""}, + from: {value:""}, + to: {value:""}, + reg: {value:false} + }, + inputs: 1, + outputs: 1, + icon: "swap.svg", + label: function() { + function prop2name(type, key) { + var result = RED.utils.parseContextKey(key); + return type +"." +result.key; + } + if (this.name) { + return this.name; + } + if (!this.rules) { + if (this.action === "replace") { + return this._("change.label.set",{property:"msg."+this.property}); + } else if (this.action === "change") { + return this._("change.label.change",{property:"msg."+this.property}); + } else if (this.action === "move") { + return this._("change.label.move",{property:"msg."+this.property}); + } else { + return this._("change.label.delete",{property:"msg."+this.property}); + } + } else { + if (this.rules.length == 1) { + if (this.rules[0].t === "set") { + return this._("change.label.set",{property:prop2name((this.rules[0].pt||"msg"), this.rules[0].p)}); + } else if (this.rules[0].t === "change") { + return this._("change.label.change",{property:prop2name((this.rules[0].pt||"msg"), this.rules[0].p)}); + } else if (this.rules[0].t === "move") { + return this._("change.label.move",{property:prop2name((this.rules[0].pt||"msg"), this.rules[0].p)}); + } else { + return this._("change.label.delete",{property:prop2name((this.rules[0].pt||"msg"), this.rules[0].p)}); + } + } else { + return this._("change.label.changeCount",{count:this.rules.length}); + } + } + }, + labelStyle: function() { + return this.name ? "node_label_italic" : ""; + }, + oneditprepare: function() { + var set = this._("change.action.set"); + var change = this._("change.action.change"); + var del = this._("change.action.delete"); + var move = this._("change.action.move"); + var to = this._("change.action.to"); + var search = this._("change.action.search"); + var replace = this._("change.action.replace"); + var regex = this._("change.label.regex"); + + function resizeRule(rule) { + var newWidth = rule.width(); + rule.find('.red-ui-typedInput').typedInput("width",newWidth-130); + + } + $('#node-input-rule-container').css('min-height','150px').css('min-width','450px').editableList({ + addItem: function(container,i,opt) { + var rule = opt; + if (!rule.hasOwnProperty('t')) { + rule = {t:"set",p:"payload",to:"",tot:"str"}; + } + if (rule.t === "change" && rule.re) { + rule.fromt = 're'; + delete rule.re; + } + if (rule.t === "set" && !rule.tot) { + if (rule.to.indexOf("msg.") === 0 && !rule.tot) { + rule.to = rule.to.substring(4); + rule.tot = "msg"; + } else { + rule.tot = "str"; + } + } + if (rule.t === "move" && !rule.tot) { + rule.tot = "msg"; + } + container.css({ + overflow: 'hidden', + whiteSpace: 'nowrap' + }); + var row1 = $('<div/>').appendTo(container); + var row2 = $('<div/>',{style:"margin-top:8px;"}).appendTo(container); + var row3 = $('<div/>',{style:"margin-top:8px;"}).appendTo(container); + var row4 = $('<div/>',{style:"margin-top:8px;"}).appendTo(container); + + var selectField = $('<select/>',{class:"node-input-rule-type",style:"width:110px; margin-right:10px;"}).appendTo(row1); + var selectOptions = [{v:"set",l:set},{v:"change",l:change},{v:"delete",l:del},{v:"move",l:move}]; + for (var i=0; i<4; i++) { + selectField.append($("<option></option>").val(selectOptions[i].v).text(selectOptions[i].l)); + } + + var propertyName = $('<input/>',{class:"node-input-rule-property-name",type:"text"}) + .appendTo(row1) + .typedInput({types:['msg','flow','global']}); + + $('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"}) + .text(to) + .appendTo(row2); + var propertyValue = $('<input/>',{class:"node-input-rule-property-value",type:"text"}) + .appendTo(row2) + .typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','date','jsonata','env']}); + + var row3_1 = $('<div/>').appendTo(row3); + $('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"}) + .text(search) + .appendTo(row3_1); + var fromValue = $('<input/>',{class:"node-input-rule-property-search-value",type:"text"}) + .appendTo(row3_1) + .typedInput({default:'str',types:['msg','flow','global','str','re','num','bool','env']}); + + var row3_2 = $('<div/>',{style:"margin-top:8px;"}).appendTo(row3); + $('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"}) + .text(replace) + .appendTo(row3_2); + var toValue = $('<input/>',{class:"node-input-rule-property-replace-value",type:"text"}) + .appendTo(row3_2) + .typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','env']}); + + $('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"}) + .text(to) + .appendTo(row4); + var moveValue = $('<input/>',{class:"node-input-rule-property-move-value",type:"text"}) + .appendTo(row4) + .typedInput({default:'msg',types:['msg','flow','global']}); + + selectField.on("change", function() { + var width = $("#node-input-rule-container").width(); + var type = $(this).val(); + if (type == "set") { + row2.show(); + row3.hide(); + row4.hide(); + } else if (type == "change") { + row2.hide(); + row3.show(); + row4.hide(); + } else if (type == "delete") { + row2.hide(); + row3.hide(); + row4.hide(); + } else if (type == "move") { + row2.hide(); + row3.hide(); + row4.show(); + } + resizeRule(container); + }); + + selectField.val(rule.t); + propertyName.typedInput('value',rule.p); + propertyName.typedInput('type',rule.pt); + propertyValue.typedInput('value',rule.to); + propertyValue.typedInput('type',rule.tot); + moveValue.typedInput('value',rule.to); + moveValue.typedInput('type',rule.tot); + fromValue.typedInput('value',rule.from); + fromValue.typedInput('type',rule.fromt); + toValue.typedInput('value',rule.to); + toValue.typedInput('type',rule.tot); + selectField.change(); + + var newWidth = $("#node-input-rule-container").width(); + resizeRule(container); + }, + resizeItem: resizeRule, + removable: true, + sortable: true + }); + + if (!this.rules) { + var rule = { + t:(this.action=="replace"?"set":this.action), + p:this.property, + pt:"msg" + }; + + if ((rule.t === "set")||(rule.t === "move")) { + rule.to = this.to; + } else if (rule.t === "change") { + rule.from = this.from; + rule.to = this.to; + rule.re = this.reg; + } + + delete this.to; + delete this.from; + delete this.reg; + delete this.action; + delete this.property; + + this.rules = [rule]; + } + + for (var i=0; i<this.rules.length; i++) { + var rule = this.rules[i]; + $("#node-input-rule-container").editableList('addItem',rule); + } + }, + oneditsave: function() { + var rules = $("#node-input-rule-container").editableList('items'); + var node = this; + node.rules= []; + rules.each(function(i) { + var rule = $(this); + var type = rule.find(".node-input-rule-type").val(); + var r = { + t:type, + p:rule.find(".node-input-rule-property-name").typedInput('value'), + pt:rule.find(".node-input-rule-property-name").typedInput('type') + }; + if (type === "set") { + r.to = rule.find(".node-input-rule-property-value").typedInput('value'); + r.tot = rule.find(".node-input-rule-property-value").typedInput('type'); + } else if (type === "move") { + r.to = rule.find(".node-input-rule-property-move-value").typedInput('value'); + r.tot = rule.find(".node-input-rule-property-move-value").typedInput('type'); + } else if (type === "change") { + r.from = rule.find(".node-input-rule-property-search-value").typedInput('value'); + r.fromt = rule.find(".node-input-rule-property-search-value").typedInput('type'); + r.to = rule.find(".node-input-rule-property-replace-value").typedInput('value'); + r.tot = rule.find(".node-input-rule-property-replace-value").typedInput('type'); + } + node.rules.push(r); + }); + }, + oneditresize: function(size) { + var rows = $("#dialog-form>div:not(.node-input-rule-container-row)"); + var height = size.height; + for (var i=0; i<rows.length; i++) { + height -= $(rows[i]).outerHeight(true); + } + var editorRow = $("#dialog-form>div.node-input-rule-container-row"); + height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); + height += 16; + $("#node-input-rule-container").editableList('height',height); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/15-change.js b/packages/connector/packages/node_modules/@node-red/nodes/core/function/15-change.js new file mode 100644 index 0000000..5c9093b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/15-change.js @@ -0,0 +1,344 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + + function ChangeNode(n) { + RED.nodes.createNode(this, n); + var node = this; + + this.rules = n.rules; + var rule; + if (!this.rules) { + rule = { + t:(n.action=="replace"?"set":n.action), + p:n.property||"" + } + + if ((rule.t === "set")||(rule.t === "move")) { + rule.to = n.to||""; + } else if (rule.t === "change") { + rule.from = n.from||""; + rule.to = n.to||""; + rule.re = (n.reg===null||n.reg); + } + this.rules = [rule]; + } + + var valid = true; + for (var i=0;i<this.rules.length;i++) { + rule = this.rules[i]; + // Migrate to type-aware rules + if (!rule.pt) { + rule.pt = "msg"; + } + if (rule.t === "change" && rule.re) { + rule.fromt = 're'; + delete rule.re; + } + if (rule.t === "set" && !rule.tot) { + if (rule.to.indexOf("msg.") === 0 && !rule.tot) { + rule.to = rule.to.substring(4); + rule.tot = "msg"; + } + } + if (!rule.tot) { + rule.tot = "str"; + } + if (!rule.fromt) { + rule.fromt = "str"; + } + if (rule.t === "change" && rule.fromt !== 'msg' && rule.fromt !== 'flow' && rule.fromt !== 'global') { + rule.fromRE = rule.from; + if (rule.fromt !== 're') { + rule.fromRE = rule.fromRE.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); + } + try { + rule.fromRE = new RegExp(rule.fromRE, "g"); + } catch (e) { + valid = false; + this.error(RED._("change.errors.invalid-from",{error:e.message})); + } + } + if (rule.tot === 'num') { + rule.to = Number(rule.to); + } else if (rule.tot === 'json' || rule.tot === 'bin') { + try { + // check this is parsable JSON + JSON.parse(rule.to); + } catch(e2) { + valid = false; + this.error(RED._("change.errors.invalid-json")); + } + } else if (rule.tot === 'bool') { + rule.to = /^true$/i.test(rule.to); + } else if (rule.tot === 'jsonata') { + try { + rule.to = RED.util.prepareJSONataExpression(rule.to,this); + } catch(e) { + valid = false; + this.error(RED._("change.errors.invalid-expr",{error:e.message})); + } + } else if (rule.tot === 'env') { + rule.to = RED.util.evaluateNodeProperty(rule.to,'env',node); + } + } + + function getToValue(msg,rule,done) { + var value = rule.to; + if (rule.tot === 'json') { + value = JSON.parse(rule.to); + } else if (rule.tot === 'bin') { + value = Buffer.from(JSON.parse(rule.to)) + } + if (rule.tot === "msg") { + value = RED.util.getMessageProperty(msg,rule.to); + } else if ((rule.tot === 'flow') || (rule.tot === 'global')) { + RED.util.evaluateNodeProperty(rule.to, rule.tot, node, msg, (err,value) => { + if (err) { + done(undefined,undefined); + } else { + done(undefined,value); + } + }); + return + } else if (rule.tot === 'date') { + value = Date.now(); + } else if (rule.tot === 'jsonata') { + RED.util.evaluateJSONataExpression(rule.to,msg, (err, value) => { + if (err) { + done(RED._("change.errors.invalid-expr",{error:err.message})) + } else { + done(undefined, value); + } + }); + return; + } + done(undefined,value); + } + + function getFromValueType(fromValue, done) { + var fromType; + var fromRE; + if (typeof fromValue === 'number' || fromValue instanceof Number) { + fromType = 'num'; + } else if (typeof fromValue === 'boolean') { + fromType = 'bool' + } else if (fromValue instanceof RegExp) { + fromType = 're'; + fromRE = fromValue; + } else if (typeof fromValue === 'string') { + fromType = 'str'; + fromRE = fromValue.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); + try { + fromRE = new RegExp(fromRE, "g"); + } catch (e) { + done(new Error(RED._("change.errors.invalid-from",{error:e.message}))); + } + } else { + done(new Error(RED._("change.errors.invalid-from",{error:"unsupported type: "+(typeof fromValue)}))); + } + done(undefined,{ + fromType, + fromValue, + fromRE + }); + } + function getFromValue(msg,rule, done) { + var fromValue; + var fromType; + var fromRE; + if (rule.t === 'change') { + if (rule.fromt === 'msg' || rule.fromt === 'flow' || rule.fromt === 'global') { + if (rule.fromt === "msg") { + return getFromValueType(RED.util.getMessageProperty(msg,rule.from),done); + } else if (rule.fromt === 'flow' || rule.fromt === 'global') { + var contextKey = RED.util.parseContextStore(rule.from); + node.context()[rule.fromt].get(contextKey.key, contextKey.store, (err,fromValue) => { + if (err) { + done(err) + } else { + getFromValueType(fromValue,done); + } + }); + return; + } + } else { + fromType = rule.fromt; + fromValue = rule.from; + fromRE = rule.fromRE; + } + } + done(undefined, { + fromType, + fromValue, + fromRE + }); + } + function applyRule(msg,rule,done) { + var property = rule.p; + var current; + var fromValue; + var fromType; + var fromRE; + + try { + getToValue(msg,rule,(err,value) => { + if (err) { + node.error(err, msg); + return done(undefined,null); + } else { + getFromValue(msg,rule,(err,fromParts) => { + if (err) { + node.error(err, msg); + return done(undefined,null); + } else { + fromValue = fromParts.fromValue; + fromType = fromParts.fromType; + fromRE = fromParts.fromRE; + if (rule.pt === 'msg') { + try { + if (rule.t === 'delete') { + RED.util.setMessageProperty(msg,property,undefined); + } else if (rule.t === 'set') { + RED.util.setMessageProperty(msg,property,value); + } else if (rule.t === 'change') { + current = RED.util.getMessageProperty(msg,property); + if (typeof current === 'string') { + if ((fromType === 'num' || fromType === 'bool' || fromType === 'str') && current === fromValue) { + // str representation of exact from number/boolean + // only replace if they match exactly + RED.util.setMessageProperty(msg,property,value); + } else { + current = current.replace(fromRE,value); + RED.util.setMessageProperty(msg,property,current); + } + } else if ((typeof current === 'number' || current instanceof Number) && fromType === 'num') { + if (current == Number(fromValue)) { + RED.util.setMessageProperty(msg,property,value); + } + } else if (typeof current === 'boolean' && fromType === 'bool') { + if (current.toString() === fromValue) { + RED.util.setMessageProperty(msg,property,value); + } + } + } + } catch(err) {} + return done(undefined,msg); + } else if (rule.pt === 'flow' || rule.pt === 'global') { + var contextKey = RED.util.parseContextStore(property); + var target = node.context()[rule.pt]; + var callback = err => { + if (err) { + node.error(err, msg); + return done(undefined,null); + } else { + done(undefined,msg); + } + } + if (rule.t === 'delete') { + target.set(contextKey.key,undefined,contextKey.store,callback); + } else if (rule.t === 'set') { + target.set(contextKey.key,value,contextKey.store,callback); + } else if (rule.t === 'change') { + target.get(contextKey.key,contextKey.store,(err,current) => { + if (err) { + node.error(err, msg); + return done(undefined,null); + } + if (typeof current === 'string') { + if ((fromType === 'num' || fromType === 'bool' || fromType === 'str') && current === fromValue) { + // str representation of exact from number/boolean + // only replace if they match exactly + target.set(contextKey.key,value,contextKey.store,callback); + } else { + current = current.replace(fromRE,value); + target.set(contextKey.key,current,contextKey.store,callback); + } + } else if ((typeof current === 'number' || current instanceof Number) && fromType === 'num') { + if (current == Number(fromValue)) { + target.set(contextKey.key,value,contextKey.store,callback); + } + } else if (typeof current === 'boolean' && fromType === 'bool') { + if (current.toString() === fromValue) { + target.set(contextKey.key,value,contextKey.store,callback); + } + } + }); + } + } + } + }) + } + }); + } catch(err) { + // This is an okay error + done(undefined,msg); + } + } + function completeApplyingRules(msg,currentRule,done) { + if (!msg) { + return done(); + } else if (currentRule === node.rules.length - 1) { + return done(undefined, msg); + } else { + applyRules(msg, currentRule+1,done); + } + } + function applyRules(msg, currentRule, done) { + if (currentRule >= node.rules.length) { + return done(undefined,msg); + } + var r = node.rules[currentRule]; + if (r.t === "move") { + if ((r.tot !== r.pt) || (r.p.indexOf(r.to) !== -1)) { + applyRule(msg,{t:"set", p:r.to, pt:r.tot, to:r.p, tot:r.pt},(err,msg) => { + applyRule(msg,{t:"delete", p:r.p, pt:r.pt}, (err,msg) => { + completeApplyingRules(msg,currentRule,done); + }) + }); + } else { // 2 step move if we are moving from a child + applyRule(msg,{t:"set", p:"_temp_move", pt:r.tot, to:r.p, tot:r.pt},(err,msg)=> { + applyRule(msg,{t:"delete", p:r.p, pt:r.pt},(err,msg)=> { + applyRule(msg,{t:"set", p:r.to, pt:r.tot, to:"_temp_move", tot:r.pt},(err,msg)=> { + applyRule(msg,{t:"delete", p:"_temp_move", pt:r.pt},(err,msg)=> { + completeApplyingRules(msg,currentRule,done); + }); + }); + }); + }); + } + } else { + applyRule(msg,r,(err,msg)=> { completeApplyingRules(msg,currentRule,done); }); + } + } + + if (valid) { + this.on('input', function(msg, send, done) { + applyRules(msg, 0, (err,msg) => { + if (err) { + done(err); + } else if (msg) { + send(msg); + done(); + } + }) + }); + } + } + RED.nodes.registerType("change", ChangeNode); +}; diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/16-range.html b/packages/connector/packages/node_modules/@node-red/nodes/core/function/16-range.html new file mode 100644 index 0000000..77d123d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/16-range.html @@ -0,0 +1,70 @@ + +<script type="text/x-red" data-template-name="range"> + <div class="form-row"> + <label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="common.label.property"></span></label> + <input type="text" id="node-input-property" style="width:calc(70% - 1px)"/> + </div> + <div class="form-row"> + <label for="node-input-action"><i class="fa fa-dot-circle-o"></i> <span data-i18n="range.label.action"></span></label> + <select id="node-input-action" style="width:70%;"> + <option value="scale" data-i18n="range.scale.payload"></option> + <option value="clamp" data-i18n="range.scale.limit"></option> + <option value="roll" data-i18n="range.scale.wrap"></option> + </select> + </div> + <br/> + <div class="form-row"><i class="fa fa-sign-in"></i> <span data-i18n="range.label.inputrange"></span>:</div> + <div class="form-row"><label></label> + <span data-i18n="range.label.from"></span>: <input type="text" id="node-input-minin" data-i18n="[placeholder]range.placeholder.min" style="width:100px;"/> + &nbsp;&nbsp;<span data-i18n="range.label.to"></span>: <input type="text" id="node-input-maxin" data-i18n="[placeholder]range.placeholder.maxin" style="width:100px;"/> + </div> + <div class="form-row"><i class="fa fa-sign-out"></i> <span data-i18n="range.label.resultrange"></span>:</div> + <div class="form-row"><label></label> + <span data-i18n="range.label.from"></span>: <input type="text" id="node-input-minout" data-i18n="[placeholder]range.placeholder.min" style="width:100px;"/> + &nbsp;&nbsp;<span data-i18n="range.label.to"></span>: <input type="text" id="node-input-maxout" data-i18n="[placeholder]range.placeholder.maxout" style="width:100px;"/> + </div> + <br/> + <div class="form-row"><label></label> + <input type="checkbox" id="node-input-round" style="display: inline-block; width: auto; vertical-align: top;"> + <label style="width: auto;" for="node-input-round"><span data-i18n="range.label.roundresult"></span></label></input> + </div> + <br/> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-tips" id="node-tip"><span data-i18n="range.tip"></span></div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('range', { + color: "#E2D96E", + category: 'function', + defaults: { + minin: {value:"",required:true,validate:RED.validators.number()}, + maxin: {value:"",required:true,validate:RED.validators.number()}, + minout: {value:"",required:true,validate:RED.validators.number()}, + maxout: {value:"",required:true,validate:RED.validators.number()}, + action: {value:"scale"}, + round: {value:false}, + property: {value:"payload",required:true}, + name: {value:""} + }, + inputs: 1, + outputs: 1, + icon: "range.svg", + label: function() { + if (this.minout !== "" && this.maxout !== "") { return this.name||this.minout + " - " + this.maxout; } + else { return this.name||this._("range.range"); } + }, + labelStyle: function() { + return this.name ? "node_label_italic" : ""; + }, + oneditprepare: function() { + if (this.property === undefined) { + $("#node-input-property").val("payload"); + } + $("#node-input-property").typedInput({default:'msg',types:['msg']}); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/16-range.js b/packages/connector/packages/node_modules/@node-red/nodes/core/function/16-range.js new file mode 100644 index 0000000..b92b155 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/16-range.js @@ -0,0 +1,54 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + function RangeNode(n) { + RED.nodes.createNode(this, n); + this.action = n.action; + this.round = n.round || false; + this.minin = Number(n.minin); + this.maxin = Number(n.maxin); + this.minout = Number(n.minout); + this.maxout = Number(n.maxout); + this.property = n.property||"payload"; + var node = this; + + this.on('input', function (msg) { + var value = RED.util.getMessageProperty(msg,node.property); + if (value !== undefined) { + var n = Number(value); + if (!isNaN(n)) { + if (node.action == "clamp") { + if (n < node.minin) { n = node.minin; } + if (n > node.maxin) { n = node.maxin; } + } + if (node.action == "roll") { + var divisor = node.maxin - node.minin; + n = ((n - node.minin) % divisor + divisor) % divisor + node.minin; + } + value = ((n - node.minin) / (node.maxin - node.minin) * (node.maxout - node.minout)) + node.minout; + if (node.round) { value = Math.round(value); } + RED.util.setMessageProperty(msg,node.property,value); + node.send(msg); + } + else { node.log(RED._("range.errors.notnumber")+": "+value); } + } + else { node.send(msg); } // If no payload - just pass it on. + }); + } + RED.nodes.registerType("range", RangeNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/80-template.html b/packages/connector/packages/node_modules/@node-red/nodes/core/function/80-template.html new file mode 100644 index 0000000..e781b95 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/80-template.html @@ -0,0 +1,155 @@ + +<script type="text/x-red" data-template-name="template"> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <div style="display: inline-block; width: calc(100% - 105px)"><input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"></div> + </div> + <div class="form-row"> + <label for="node-input-field"><i class="fa fa-ellipsis-h"></i> <span data-i18n="template.label.property"></span></label> + <input type="text" id="node-input-field" placeholder="payload" style="width:250px;"> + <input type="hidden" id="node-input-fieldType"> + </div> + <div class="form-row" style="position: relative; margin-bottom: 0px;"> + <label for="node-input-template"><i class="fa fa-file-code-o"></i> <span data-i18n="template.label.template"></span></label> + <input type="hidden" id="node-input-template" autofocus="autofocus"> + <div style="position: absolute; right:0;display:inline-block; text-align: right; font-size: 0.8em;"> + <span data-i18n="template.label.format"></span>: + <select id="node-input-format" style="width:110px; font-size: 10px !important; height: 24px; padding:0;"> + <option value="handlebars">mustache</option> + <option value="html">HTML</option> + <option value="json">JSON</option> + <option value="javascript">Javascript</option> + <option value="css">CSS</option> + <option value="markdown">Markdown</option> + <option value="python">Python</option> + <option value="sql">SQL</option> + <option value="yaml">YAML</option> + <option value="text" data-i18n="template.label.none"></option> + </select> + <button id="node-template-expand-editor" class="red-ui-button red-ui-button-small"><i class="fa fa-expand"></i></button> + </div> + </div> + <div class="form-row node-text-editor-row"> + <div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-input-template-editor" ></div> + </div> + <div class="form-row"> + <label for="node-input-syntax"><i class="fa fa-code"></i> <span data-i18n="template.label.syntax"></span></label> + <select id="node-input-syntax" style="width:180px;"> + <option value="mustache" data-i18n="template.label.mustache"></option> + <option value="plain" data-i18n="template.label.plain"></option> + </select> + </div> + <div class="form-row"> + <label for="node-input-output"><i class="fa fa-long-arrow-right"></i> <span data-i18n="template.label.output"></span></label> + <select id="node-input-output" style="width:180px;"> + <option value="str" data-i18n="template.label.plain"></option> + <option value="json" data-i18n="template.label.json"></option> + <option value="yaml" data-i18n="template.label.yaml"></option> + </select> + </div> + +</script> + +<script type="text/javascript"> + RED.nodes.registerType('template',{ + color:"rgb(243, 181, 103)", + category: 'function', + defaults: { + name: {value:""}, + field: {value:"payload", validate:RED.validators.typedInput("fieldType")}, + fieldType: {value:"msg"}, + format: {value:"handlebars"}, + syntax: {value:"mustache"}, + template: {value:"This is the payload: {{payload}} !"}, + output: {value:"str"} + }, + inputs:1, + outputs:1, + icon: "template.svg", + label: function() { + return this.name||this._("template.template");; + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + var that = this; + if (!this.field) { + this.field = 'payload'; + $("#node-input-field").val("payload"); + } + if (!this.fieldType) { + this.fieldType = 'msg'; + } + if (!this.syntax) { + this.syntax = 'mustache'; + $("#node-input-syntax").val(this.syntax); + } + $("#node-input-field").typedInput({ + default: 'msg', + types: ['msg','flow','global'], + typeField: $("#node-input-fieldType") + }); + + this.editor = RED.editor.createEditor({ + id: 'node-input-template-editor', + mode: 'ace/mode/html', + value: $("#node-input-template").val() + }); + RED.library.create({ + url:"templates", // where to get the data from + type:"template", // the type of object the library is for + editor:that.editor, // the field name the main text body goes to + fields:['name','format','output','syntax'], + ext: "txt" + }); + this.editor.focus(); + + $("#node-input-format").on("change", function() { + var mod = "ace/mode/"+$("#node-input-format").val(); + that.editor.getSession().setMode({ + path: mod, + v: Date.now() + }); + }); + RED.popover.tooltip($("#node-template-expand-editor"), RED._("node-red:common.label.expand")); + $("#node-template-expand-editor").on("click", function(e) { + e.preventDefault(); + var value = that.editor.getValue(); + RED.editor.editText({ + mode: $("#node-input-format").val(), + value: value, + width: "Infinity", + cursor: that.editor.getCursorPosition(), + complete: function(v,cursor) { + that.editor.setValue(v, -1); + that.editor.gotoLine(cursor.row+1,cursor.column,false); + setTimeout(function() { + that.editor.focus(); + },300); + } + }) + }) + }, + oneditsave: function() { + $("#node-input-template").val(this.editor.getValue()); + this.editor.destroy(); + delete this.editor; + }, + oneditcancel: function() { + this.editor.destroy(); + delete this.editor; + }, + oneditresize: function(size) { + var rows = $("#dialog-form>div:not(.node-text-editor-row)"); + var height = $("#dialog-form").height(); + for (var i=0; i<rows.length; i++) { + height -= $(rows[i]).outerHeight(true); + } + var editorRow = $("#dialog-form>div.node-text-editor-row"); + height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); + $(".node-text-editor").css("height",height+"px"); + this.editor.resize(); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/80-template.js b/packages/connector/packages/node_modules/@node-red/nodes/core/function/80-template.js new file mode 100644 index 0000000..5700e2f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/80-template.js @@ -0,0 +1,198 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var mustache = require("mustache"); + var yaml = require("js-yaml"); + + function extractTokens(tokens,set) { + set = set || new Set(); + tokens.forEach(function(token) { + if (token[0] !== 'text') { + set.add(token[1]); + if (token.length > 4) { + extractTokens(token[4],set); + } + } + }); + return set; + } + + function parseContext(key) { + var match = /^(flow|global)(\[(\w+)\])?\.(.+)/.exec(key); + if (match) { + var parts = {}; + parts.type = match[1]; + parts.store = (match[3] === '') ? "default" : match[3]; + parts.field = match[4]; + return parts; + } + return undefined; + } + + /** + * Custom Mustache Context capable to collect message property and node + * flow and global context + */ + + function NodeContext(msg, nodeContext, parent, escapeStrings, cachedContextTokens) { + this.msgContext = new mustache.Context(msg,parent); + this.nodeContext = nodeContext; + this.escapeStrings = escapeStrings; + this.cachedContextTokens = cachedContextTokens; + } + + NodeContext.prototype = new mustache.Context(); + + NodeContext.prototype.lookup = function (name) { + // try message first: + try { + var value = this.msgContext.lookup(name); + if (value !== undefined) { + if (this.escapeStrings && typeof value === "string") { + value = value.replace(/\\/g, "\\\\"); + value = value.replace(/\n/g, "\\n"); + value = value.replace(/\t/g, "\\t"); + value = value.replace(/\r/g, "\\r"); + value = value.replace(/\f/g, "\\f"); + value = value.replace(/[\b]/g, "\\b"); + } + return value; + } + + // try flow/global context: + var context = parseContext(name); + if (context) { + var type = context.type; + var store = context.store; + var field = context.field; + var target = this.nodeContext[type]; + if (target) { + return this.cachedContextTokens[name]; + } + } + return ''; + } + catch(err) { + throw err; + } + } + + NodeContext.prototype.push = function push (view) { + return new NodeContext(view, this.nodeContext, this.msgContext, undefined, this.cachedContextTokens); + }; + + function TemplateNode(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.field = n.field || "payload"; + this.template = n.template; + this.syntax = n.syntax || "mustache"; + this.fieldType = n.fieldType || "msg"; + this.outputFormat = n.output || "str"; + + var node = this; + + function output(msg,value) { + /* istanbul ignore else */ + if (node.outputFormat === "json") { + value = JSON.parse(value); + } + /* istanbul ignore else */ + if (node.outputFormat === "yaml") { + value = yaml.load(value); + } + + if (node.fieldType === 'msg') { + RED.util.setMessageProperty(msg, node.field, value); + node.send(msg); + } else if ((node.fieldType === 'flow') || + (node.fieldType === 'global')) { + var context = RED.util.parseContextStore(node.field); + var target = node.context()[node.fieldType]; + target.set(context.key, value, context.store, function (err) { + if (err) { + node.error(err, msg); + } else { + node.send(msg); + } + }); + } + } + + node.on("input", function(msg) { + + try { + /*** + * Allow template contents to be defined externally + * through inbound msg.template IFF node.template empty + */ + var template = node.template; + if (msg.hasOwnProperty("template")) { + if (template == "" || template === null) { + template = msg.template; + } + } + + if (node.syntax === "mustache") { + var is_json = (node.outputFormat === "json"); + var promises = []; + var tokens = extractTokens(mustache.parse(template)); + var resolvedTokens = {}; + tokens.forEach(function(name) { + var context = parseContext(name); + if (context) { + var type = context.type; + var store = context.store; + var field = context.field; + var target = node.context()[type]; + if (target) { + var promise = new Promise((resolve, reject) => { + target.get(field, store, (err, val) => { + if (err) { + reject(err); + } else { + resolvedTokens[name] = val; + resolve(); + } + }); + }); + promises.push(promise); + return; + } + } + }); + + Promise.all(promises).then(function() { + var value = mustache.render(template, new NodeContext(msg, node.context(), null, is_json, resolvedTokens)); + output(msg, value); + }).catch(function (err) { + node.error(err.message,msg); + }); + } else { + output(msg, template); + } + } + catch(err) { + node.error(err.message, msg); + } + }); + } + + RED.nodes.registerType("template",TemplateNode); + RED.library.register("templates"); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/89-delay.html b/packages/connector/packages/node_modules/@node-red/nodes/core/function/89-delay.html new file mode 100644 index 0000000..76271c8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/89-delay.html @@ -0,0 +1,268 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-template-name="delay"> + <div class="form-row"> + <label for="node-input-delay-action"><i class="fa fa-tasks"></i> <span data-i18n="delay.action"></span></label> + <select id="node-input-delay-action" style="width:270px !important"> + <option value="delay" data-i18n="delay.delaymsg"></option> + <option value="rate" data-i18n="delay.limitrate"></option> + </select> + </div> + + <div id="delay-details"> + <div class="form-row"> + <label></label> + <select id="node-input-delay-type" style="width:270px !important"> + <option value="delay" data-i18n="delay.delayfixed"></option> + <option value="random" data-i18n="delay.randomdelay"></option> + <option value="delayv" data-i18n="delay.delayvarmsg"></option> + </select> + </div> + <div class="form-row" id="delay-details-for"> + <label for="node-input-timeout"><i class="fa fa-clock-o"></i> <span data-i18n="delay.for"></span></label> + <input type="text" id="node-input-timeout" style="text-align:end; width:50px !important"> + <select id="node-input-timeoutUnits" style="width:200px !important"> + <option value="milliseconds" data-i18n="delay.milisecs"></option> + <option value="seconds" data-i18n="delay.secs"></option> + <option value="minutes" data-i18n="delay.mins"></option> + <option value="hours" data-i18n="delay.hours"></option> + <option value="days" data-i18n="delay.days"></option> + </select> + </div> + <div id="random-details" class="form-row"> + <label for="node-input-randomFirst"><i class="fa fa-clock-o"></i> <span data-i18n="delay.between"></span></label> + <input type="text" id="node-input-randomFirst" placeholder="" style="text-align:end; width:30px !important"> + <span data-i18n="delay.and"></span> + <input type="text" id="node-input-randomLast" placeholder="" style="text-align:end; width:30px !important"> + <select id="node-input-randomUnits" style="width:140px !important"> + <option value="milliseconds" data-i18n="delay.milisecs"></option> + <option value="seconds" data-i18n="delay.secs"></option> + <option value="minutes" data-i18n="delay.mins"></option> + <option value="hours" data-i18n="delay.hours"></option> + <option value="days" data-i18n="delay.days"></option> + </select> + </div> + </div> + + <div id="rate-details"> + <div class="form-row"> + <label></label> + <select id="node-input-rate-type" style="width:270px !important"> + <option value="all" data-i18n="delay.limitall"></option> + <option value="topic" data-i18n="delay.limittopic"></option> + </select> + </div> + <div class="form-row"> + <label for="node-input-rate"><i class="fa fa-clock-o"></i> <span data-i18n="delay.rate"></span></label> + <input type="text" id="node-input-rate" placeholder="1" style="text-align:end; width:40px !important"> + <label for="node-input-rateUnits"><span data-i18n="delay.msgper"></span></label> + <input type="text" id="node-input-nbRateUnits" placeholder="1" style="text-align:end; width:40px !important"> + <select id="node-input-rateUnits" style="width:90px !important"> + <option value="second" data-i18n="delay.label.units.second.singular"></option> + <option value="minute" data-i18n="delay.label.units.minute.singular"></option> + <option value="hour" data-i18n="delay.label.units.hour.singular"></option> + <option value="day" data-i18n="delay.label.units.day.singular"></option> + </select> + </div> + <div class="form-row" id="rate-details-drop"> + <label></label><input style="width: 30px;" type="checkbox" id="node-input-drop"><label style="width: 250px;" for="node-input-drop" data-i18n="delay.dropmsg"></label> + </div> + <div class="form-row" id="rate-details-per-topic"> + <label></label> + <select id="node-input-rate-topic-type" style="width:270px !important"> + <option value="queue" data-i18n="delay.fairqueue"></option> + <option value="timed" data-i18n="delay.timedqueue"></option> + </select> + </div> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('delay',{ + category: 'function', + color:"#E6E0F8", + defaults: { + name: {value:""}, + pauseType: {value:"delay", required:true}, + timeout: {value:"5", required:true, validate:function(v) { return RED.validators.number(v) && (v >= 0); }}, + timeoutUnits: {value:"seconds"}, + rate: {value:"1", required:true, validate:function(v) { return RED.validators.number(v) && (v >= 0); }}, + nbRateUnits: {value:"1", required:false, validate:RED.validators.regex(/\d+|/)}, + rateUnits: {value: "second"}, + randomFirst: {value:"1", required:true, validate:function(v) { return RED.validators.number(v) && (v >= 0); }}, + randomLast: {value:"5", required:true, validate:function(v) { return RED.validators.number(v) && (v >= 0); }}, + randomUnits: {value: "seconds"}, + drop: {value:false} + }, + inputs:1, + outputs:1, + icon: "timer.svg", + label: function() { + if (this.name) { + return this.name; + } + if (this.pauseType == "delayv") { + return this._("delay.label.variable"); + } else if (this.pauseType == "delay") { + var units = this.timeoutUnits ? this.timeoutUnits.charAt(0) : "s"; + if (this.timeoutUnits == "milliseconds") { units = "ms"; } + return this._("delay.label.delay")+" "+this.timeout+units; + } else if (this.pauseType == "random") { + return this._("delay.label.random"); + } else { + var rate = this.rate+" msg/"+(this.rateUnits ? (this.nbRateUnits > 1 ? this.nbRateUnits : '') + this.rateUnits.charAt(0) : "s"); + if (this.pauseType == "rate") { + return this._("delay.label.limit")+" "+rate; + } else if (this.pauseType == "timed") { + return this._("delay.label.limitTopic")+" "+rate; + } else { + return this._("delay.label.limitTopic")+" "+rate; + } + } + // var units = ''; + // if (this.nbRateUnits > 1) { + // units = this.nbRateUnits + ' ' + this._("delay.label.units." + this.rateUnits + ".plural"); + // } else { + // units = this._("delay.label.units." + this.rateUnits + ".singular"); + // } + // return this.name || this.rate + " " + this._("delay.label.timed") + ' ' + units; + // } else { + // var units = this.rateUnits ? (this.nbRateUnits > 1 ? this.nbRateUnits : '') + this.rateUnits.charAt(0) : "s"; + // return this.name || this._("delay.label.queue")+" "+this.rate+" msg/"+units; + // } + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + var node = this; + $( "#node-input-timeout" ).spinner({min:1}); + $( "#node-input-rate" ).spinner({min:1}); + $( "#node-input-nbRateUnits" ).spinner({min:1}); + + $( "#node-input-randomFirst" ).spinner({min:0}); + $( "#node-input-randomLast" ).spinner({min:1}); + + $('.ui-spinner-button').on("click", function() { + $(this).siblings('input').trigger("change"); + }); + + $( "#node-input-nbRateUnits" ).on('change keyup', function() { + var $this = $(this); + var val = parseInt($this.val()); + var type = "singular"; + if (val > 1) { + type = "plural"; + } + if ($this.attr("data-type") == type) { + return; + } + $this.attr("data-type", type); + $("#node-input-rateUnits option").each(function () { + var $option = $(this); + var key = "delay.label.units." + $option.val() + "." + type; + $option.attr('data-i18n', 'node-red:' + key); + $option.html(node._(key)); + }); + }); + + if (this.pauseType == "delay") { + $("#node-input-delay-action").val('delay'); + $("#node-input-delay-type").val('delay'); + } else if (this.pauseType == "delayv") { + $("#node-input-delay-action").val('delay'); + $("#node-input-delay-type").val('delayv'); + } else if (this.pauseType == "random") { + $("#node-input-delay-action").val('delay'); + $("#node-input-delay-type").val('random'); + } else if (this.pauseType == "rate") { + $("#node-input-delay-action").val('rate'); + $("#node-input-rate-type").val('all'); + } else if (this.pauseType == "queue") { + $("#node-input-delay-action").val('rate'); + $("#node-input-rate-type").val('topic'); + $("#node-input-rate-topic-type").val('queue'); + } else if (this.pauseType == "timed") { + $("#node-input-delay-action").val('rate'); + $("#node-input-rate-type").val('topic'); + $("#node-input-rate-topic-type").val('timed'); + } + + if (!this.timeoutUnits) { + $("#node-input-timeoutUnits option").filter(function() { + return $(this).val() == 'seconds'; + }).attr('selected', true); + } + + if (!this.randomUnits) { + $("#node-input-randomUnits option").filter(function() { + return $(this).val() == 'seconds'; + }).attr('selected', true); + } + + $("#node-input-delay-action").on("change",function() { + if (this.value === "delay") { + $("#delay-details").show(); + $("#rate-details").hide(); + } else if (this.value === "rate") { + $("#delay-details").hide(); + $("#rate-details").show(); + } + }).trigger("change"); + + $("#node-input-delay-type").on("change", function() { + if (this.value === "delay") { + $("#delay-details-for").show(); + $("#random-details").hide(); + } else if (this.value === "delayv") { + $("#delay-details-for").show(); + $("#random-details").hide(); + } else if (this.value === "random") { + $("#delay-details-for").hide(); + $("#random-details").show(); + } + }).trigger("change"); + + $("#node-input-rate-type").on("change", function() { + if (this.value === "all") { + $("#node-input-drop").attr('disabled',false).next().css("opacity",1) + $("#rate-details-per-topic").hide(); + } else if (this.value === "topic") { + $("#node-input-drop").prop('checked',true).attr('disabled',true).next().css("opacity",0.5) + $("#rate-details-per-topic").show(); + } + }).trigger("change"); + }, + oneditsave: function() { + var action = $("#node-input-delay-action").val(); + if (action === "delay") { + this.pauseType = $("#node-input-delay-type").val(); + } else if (action === "rate") { + action = $("#node-input-rate-type").val(); + if (action === "all") { + this.pauseType = "rate"; + } else { + this.pauseType = $("#node-input-rate-topic-type").val(); + } + } + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/89-delay.js b/packages/connector/packages/node_modules/@node-red/nodes/core/function/89-delay.js new file mode 100644 index 0000000..49d856d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/89-delay.js @@ -0,0 +1,281 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +//Simple node to introduce a pause into a flow +module.exports = function(RED) { + "use strict"; + + var MILLIS_TO_NANOS = 1000000; + var SECONDS_TO_NANOS = 1000000000; + + function DelayNode(n) { + RED.nodes.createNode(this,n); + + this.pauseType = n.pauseType; + this.timeoutUnits = n.timeoutUnits; + this.randomUnits = n.randomUnits; + this.rateUnits = n.rateUnits; + + if (n.timeoutUnits === "milliseconds") { + this.timeout = n.timeout; + } else if (n.timeoutUnits === "minutes") { + this.timeout = n.timeout * (60 * 1000); + } else if (n.timeoutUnits === "hours") { + this.timeout = n.timeout * (60 * 60 * 1000); + } else if (n.timeoutUnits === "days") { + this.timeout = n.timeout * (24 * 60 * 60 * 1000); + } else { // Default to seconds + this.timeout = n.timeout * 1000; + } + + if (n.rateUnits === "minute") { + this.rate = (60 * 1000)/n.rate; + } else if (n.rateUnits === "hour") { + this.rate = (60 * 60 * 1000)/n.rate; + } else if (n.rateUnits === "day") { + this.rate = (24 * 60 * 60 * 1000)/n.rate; + } else { // Default to seconds + this.rate = 1000/n.rate; + } + + this.rate *= (n.nbRateUnits > 0 ? n.nbRateUnits : 1); + + if (n.randomUnits === "milliseconds") { + this.randomFirst = n.randomFirst * 1; + this.randomLast = n.randomLast * 1; + } else if (n.randomUnits === "minutes") { + this.randomFirst = n.randomFirst * (60 * 1000); + this.randomLast = n.randomLast * (60 * 1000); + } else if (n.randomUnits === "hours") { + this.randomFirst = n.randomFirst * (60 * 60 * 1000); + this.randomLast = n.randomLast * (60 * 60 * 1000); + } else if (n.randomUnits === "days") { + this.randomFirst = n.randomFirst * (24 * 60 * 60 * 1000); + this.randomLast = n.randomLast * (24 * 60 * 60 * 1000); + } else { // Default to seconds + this.randomFirst = n.randomFirst * 1000; + this.randomLast = n.randomLast * 1000; + } + + this.diff = this.randomLast - this.randomFirst; + this.name = n.name; + this.idList = []; + this.buffer = []; + this.intervalID = -1; + this.randomID = -1; + this.lastSent = null; + this.drop = n.drop; + var node = this; + + function ourTimeout(handler, delay) { + var toutID = setTimeout(handler, delay); + return { + clear: function() { clearTimeout(toutID); }, + trigger: function() { clearTimeout(toutID); return handler(); } + }; + } + + var clearDelayList = function(s) { + for (var i=0; i<node.idList.length; i++ ) { node.idList[i].clear(); } + node.idList = []; + if (s) { node.status({text:"reset"}); } + else { node.status({}); } + } + + var flushDelayList = function() { + var len = node.idList.length; + for (var i=0; i<len; i++ ) { node.idList[0].trigger(); } + node.idList = []; + node.status({text:"flushed"}); + } + + node.reportDepth = function() { + if (!node.busy) { + node.busy = setTimeout(function() { + if (node.buffer.length > 0) { node.status({text:node.buffer.length}); } + else { node.status({}); } + node.busy = null; + }, 500); + } + } + + if (node.pauseType === "delay") { + node.on("input", function(msg) { + if (msg.hasOwnProperty("flush")) { flushDelayList(); } + else { + var id = ourTimeout(function() { + node.idList.splice(node.idList.indexOf(id),1); + if (node.idList.length === 0) { node.status({}); } + node.send(msg); + }, node.timeout); + node.idList.push(id); + if ((node.timeout > 1000) && (node.idList.length !== 0)) { + node.status({fill:"blue",shape:"dot",text:" "}); + } + if (msg.hasOwnProperty("reset")) { clearDelayList(true); } + } + }); + node.on("close", function() { clearDelayList(); }); + } + else if (node.pauseType === "delayv") { + node.on("input", function(msg) { + var delayvar = Number(node.timeout); + if (msg.hasOwnProperty("delay") && !isNaN(parseFloat(msg.delay))) { + delayvar = parseFloat(msg.delay); + } + if (delayvar < 0) { delayvar = 0; } + var id = ourTimeout(function() { + node.idList.splice(node.idList.indexOf(id),1); + if (node.idList.length === 0) { node.status({}); } + node.send(msg); + }, delayvar); + node.idList.push(id); + if ((delayvar >= 0) && (node.idList.length !== 0)) { + node.status({fill:"blue",shape:"dot",text:delayvar/1000+"s"}); + } + if (msg.hasOwnProperty("reset")) { clearDelayList(true); } + if (msg.hasOwnProperty("flush")) { flushDelayList(); } + }); + node.on("close", function() { clearDelayList(); }); + } + else if (node.pauseType === "rate") { + node.on("input", function(msg) { + if (msg.hasOwnProperty("reset")) { + if (node.intervalID !== -1 ) { + clearInterval(node.intervalID); + node.intervalID = -1; + } + node.buffer = []; + node.status({text:"reset"}); + return; + } + if (!node.drop) { + var m = RED.util.cloneMessage(msg); + delete m.flush; + if (node.intervalID !== -1) { + node.buffer.push(m); + node.reportDepth(); + } + else { + node.send(m); + node.reportDepth(); + node.intervalID = setInterval(function() { + if (node.buffer.length === 0) { + clearInterval(node.intervalID); + node.intervalID = -1; + } + if (node.buffer.length > 0) { + node.send(node.buffer.shift()); + } + node.reportDepth(); + }, node.rate); + } + if (msg.hasOwnProperty("flush")) { + while (node.buffer.length > 0) { + node.send(node.buffer.shift()); + } + node.status({}); + } + } + else { + var timeSinceLast; + if (node.lastSent) { + timeSinceLast = process.hrtime(node.lastSent); + } + if (!node.lastSent) { // ensuring that we always send the first message + node.lastSent = process.hrtime(); + node.send(msg); + } + else if ( ( (timeSinceLast[0] * SECONDS_TO_NANOS) + timeSinceLast[1] ) > (node.rate * MILLIS_TO_NANOS) ) { + node.lastSent = process.hrtime(); + node.send(msg); + } + } + }); + node.on("close", function() { + clearInterval(node.intervalID); + clearTimeout(node.busy); + node.buffer = []; + node.status({}); + }); + } + else if ((node.pauseType === "queue") || (node.pauseType === "timed")) { + node.intervalID = setInterval(function() { + if (node.pauseType === "queue") { + if (node.buffer.length > 0) { + node.send(node.buffer.shift()); // send the first on the queue + } + } + else { + while (node.buffer.length > 0) { // send the whole queue + node.send(node.buffer.shift()); + } + } + node.reportDepth(); + },node.rate); + + var hit; + node.on("input", function(msg) { + if (!msg.hasOwnProperty("topic")) { msg.topic = "_none_"; } + hit = false; + for (var b in node.buffer) { // check if already in queue + if (msg.topic === node.buffer[b].topic) { + node.buffer[b] = msg; // if so - replace existing entry + hit = true; + break; + } + } + if (!hit) { + node.buffer.push(msg); // if not add to end of queue + node.reportDepth(); + } + if (msg.hasOwnProperty("reset")) { + node.buffer = []; + node.status({text:"reset"}); + } + if (msg.hasOwnProperty("flush")) { + while (node.buffer.length > 0) { + node.send(node.buffer.shift()); + } + node.status({}); + } + }); + node.on("close", function() { + clearInterval(node.intervalID); + node.buffer = []; + node.status({}); + }); + } + else if (node.pauseType === "random") { + node.on("input", function(msg) { + var wait = node.randomFirst + (node.diff * Math.random()); + var id = ourTimeout(function() { + node.idList.splice(node.idList.indexOf(id),1); + node.send(msg); + node.status({}); + }, wait); + node.idList.push(id); + if ((node.timeout >= 1000) && (node.idList.length !== 0)) { + node.status({fill:"blue",shape:"dot",text:parseInt(wait/10)/100+"s"}); + } + if (msg.hasOwnProperty("reset")) { clearDelayList(true); } + if (msg.hasOwnProperty("flush")) { flushDelayList(); } + }); + node.on("close", function() { clearDelayList(); }); + } + } + RED.nodes.registerType("delay",DelayNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/89-trigger.html b/packages/connector/packages/node_modules/@node-red/nodes/core/function/89-trigger.html new file mode 100644 index 0000000..d20391b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/89-trigger.html @@ -0,0 +1,183 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/html" data-template-name="trigger"> + <div class="form-row"> + <label data-i18n="trigger.send" for="node-input-op1"></label> + <input type="hidden" id="node-input-op1type"> + <input style="width:70%" type="text" id="node-input-op1" placeholder="1"> + </div> + <div class="form-row"> + <label data-i18n="trigger.then"></label> + <select id="node-then-type" style="width:70%;"> + <option value="block" data-i18n="trigger.wait-reset"></option> + <option value="wait" data-i18n="trigger.wait-for"></option> + <option value="loop" data-i18n="trigger.wait-loop"></option> + </select> + </div> + <div class="form-row node-type-duration"> + <label></label> + <input type="text" id="node-input-duration" style="text-align:end; width:70px !important"> + <select id="node-input-units" style="width:140px !important"> + <option value="ms" data-i18n="trigger.duration.ms"></option> + <option value="s" data-i18n="trigger.duration.s"></option> + <option value="min" data-i18n="trigger.duration.m"></option> + <option value="hr" data-i18n="trigger.duration.h"></option> + </select> + </div> + <div class="form-row node-type-wait"> + <label></label> + <input type="checkbox" id="node-input-extend" style="margin-left:0px; vertical-align:top; width:auto !important;"> <label style="width:auto !important;" for="node-input-extend" data-i18n="trigger.extend"></label> + </div> + <div class="form-row node-type-wait"> + <label data-i18n="trigger.then-send"></label> + <input type="hidden" id="node-input-op2type"> + <input style="width:70%" type="text" id="node-input-op2" placeholder="0"> + </div> + <div class="form-row"> + <label data-i18n="trigger.label.reset" style="width:auto"></label> + <div style="display:inline-block; width:70%;vertical-align:top"> + <ul> + <li data-i18n="trigger.label.resetMessage"></li> + <li><span data-i18n="trigger.label.resetPayload"></span> <input type="text" id="node-input-reset" style="width:150px" data-i18n="[placeholder]trigger.label.resetprompt"></li> + </ul> + </div> + <br/> + <div class="form-row"> + <label data-i18n="trigger.for" for="node-input-bytopic"></label> + <select id="node-input-bytopic"> + <option value="all" data-i18n="trigger.alltopics"></option> + <option value="topic" data-i18n="trigger.bytopics"></option> + </select> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"></input> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('trigger',{ + category: 'function', + color:"#E6E0F8", + defaults: { + op1: {value:"1", validate: RED.validators.typedInput("op1type")}, + op2: {value:"0", validate: RED.validators.typedInput("op2type")}, + op1type: {value:"val"}, + op2type: {value:"val"}, + duration: {value:"250",required:true,validate:RED.validators.number()}, + extend: {value:"false"}, + units: {value:"ms"}, + reset: {value:""}, + bytopic: {value: "all"}, + name: {value:""} + }, + inputs:1, + outputs:1, + icon: "trigger.svg", + label: function() { + if (this.duration > 0) { + return this.name|| this._("trigger.label.trigger")+" "+this.duration+this.units; + } + if (this.duration < 0) { + return this.name|| this._("trigger.label.trigger-loop")+" "+(this.duration * -1)+this.units; + } + else { + return this.name|| this._("trigger.label.trigger-block"); + } + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + $("#node-then-type").on("change", function() { + if ($(this).val() == "block") { + $(".node-type-wait").hide(); + $(".node-type-duration").hide(); + } + else if ($(this).val() == "loop") { + if ($("#node-input-duration").val() == 0) { $("#node-input-duration").val(250); } + $(".node-type-wait").hide(); + $(".node-type-duration").show(); + } else { + if ($("#node-input-duration").val() == 0) { $("#node-input-duration").val(250); } + $(".node-type-wait").show(); + $(".node-type-duration").show(); + } + }); + + if (this.op1type === 'val') { + $("#node-input-op1type").val('str'); + } + if (this.op2type === 'val') { + $("#node-input-op2type").val('str'); + } + + var optionNothing = {value:"nul",label:this._("trigger.output.nothing"),hasValue:false}; + var optionPayload = {value:"pay",label:this._("trigger.output.existing"),hasValue:false}; + var optionOriginalPayload = {value:"pay",label:this._("trigger.output.original"),hasValue:false}; + var optionLatestPayload = {value:"payl",label:this._("trigger.output.latest"),hasValue:false}; + + $("#node-input-op1").typedInput({ + default: 'str', + typeField: $("#node-input-op1type"), + types:['flow','global','str','num','bool','json','bin','date','env', + optionPayload, + optionNothing + ] + }); + $("#node-input-op2").typedInput({ + default: 'str', + typeField: $("#node-input-op2type"), + types:['flow','global','str','num','bool','json','bin','date','env', + optionOriginalPayload, + optionLatestPayload, + optionNothing + ] + }); + + if (this.bytopic === undefined) { + $("#node-input-bytopic").val("all"); + } + + if (this.duration == "0") { + $("#node-then-type").val("block"); + } + else if ((this.duration * 1) < 0) { + $("#node-then-type").val("loop"); + $("#node-input-duration").val(this.duration*-1); + } else { + $("#node-then-type").val("wait"); + } + $("#node-then-type").trigger("change"); + + if (this.extend === "true" || this.extend === true) { + $("#node-input-extend").prop("checked",true); + } else { + $("#node-input-extend").prop("checked",false); + } + + }, + oneditsave: function() { + if ($("#node-then-type").val() == "block") { + $("#node-input-duration").val("0"); + } + if ($("#node-then-type").val() == "loop") { + $("#node-input-duration").val($("#node-input-duration").val() * -1); + } + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/89-trigger.js b/packages/connector/packages/node_modules/@node-red/nodes/core/function/89-trigger.js new file mode 100644 index 0000000..4debeac --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/89-trigger.js @@ -0,0 +1,271 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var mustache = require("mustache"); + function TriggerNode(n) { + RED.nodes.createNode(this,n); + this.bytopic = n.bytopic || "all"; + this.op1 = n.op1 || "1"; + this.op2 = n.op2 || "0"; + this.op1type = n.op1type || "str"; + this.op2type = n.op2type || "str"; + + if (this.op1type === 'val') { + if (this.op1 === 'true' || this.op1 === 'false') { + this.op1type = 'bool' + } else if (this.op1 === 'null') { + this.op1type = 'null'; + this.op1 = null; + } else { + this.op1type = 'str'; + } + } + if (this.op2type === 'val') { + if (this.op2 === 'true' || this.op2 === 'false') { + this.op2type = 'bool' + } else if (this.op2 === 'null') { + this.op2type = 'null'; + this.op2 = null; + } else { + this.op2type = 'str'; + } + } + this.extend = n.extend || "false"; + this.units = n.units || "ms"; + this.reset = n.reset || ''; + this.duration = parseFloat(n.duration); + if (isNaN(this.duration)) { + this.duration = 250; + } + if (this.duration < 0) { + this.loop = true; + this.duration = this.duration * -1; + this.extend = false; + } + + if (this.units == "s") { this.duration = this.duration * 1000; } + if (this.units == "min") { this.duration = this.duration * 1000 * 60; } + if (this.units == "hr") { this.duration = this.duration * 1000 *60 * 60; } + + this.op1Templated = (this.op1type === 'str' && this.op1.indexOf("{{") != -1); + this.op2Templated = (this.op2type === 'str' && this.op2.indexOf("{{") != -1); + if ((this.op1type === "num") && (!isNaN(this.op1))) { this.op1 = Number(this.op1); } + if ((this.op2type === "num") && (!isNaN(this.op2))) { this.op2 = Number(this.op2); } + //if (this.op1 == "null") { this.op1 = null; } + //if (this.op2 == "null") { this.op2 = null; } + //try { this.op1 = JSON.parse(this.op1); } + //catch(e) { this.op1 = this.op1; } + //try { this.op2 = JSON.parse(this.op2); } + //catch(e) { this.op2 = this.op2; } + + var node = this; + node.topics = {}; + + var npay = {}; + var pendingMessages = []; + var activeMessagePromise = null; + var processMessageQueue = function(msg) { + if (msg) { + // A new message has arrived - add it to the message queue + pendingMessages.push(msg); + if (activeMessagePromise !== null) { + // The node is currently processing a message, so do nothing + // more with this message + return; + } + } + if (pendingMessages.length === 0) { + // There are no more messages to process, clear the active flag + // and return + activeMessagePromise = null; + return; + } + + // There are more messages to process. Get the next message and + // start processing it. Recurse back in to check for any more + var nextMsg = pendingMessages.shift(); + activeMessagePromise = processMessage(nextMsg) + .then(processMessageQueue) + .catch((err) => { + node.error(err,nextMsg); + return processMessageQueue(); + }); + } + + this.on('input', function(msg) { + processMessageQueue(msg); + }); + + var processMessage = function(msg) { + var topic = msg.topic || "_none"; + var promise; + if (node.bytopic === "all") { topic = "_none"; } + node.topics[topic] = node.topics[topic] || {}; + if (msg.hasOwnProperty("reset") || ((node.reset !== '') && msg.hasOwnProperty("payload") && (msg.payload !== null) && msg.payload.toString && (msg.payload.toString() == node.reset)) ) { + if (node.loop === true) { clearInterval(node.topics[topic].tout); } + else { clearTimeout(node.topics[topic].tout); } + delete node.topics[topic]; + node.status({}); + } + else { + if (node.op2type === "payl") { npay[topic] = RED.util.cloneMessage(msg); } + if (((!node.topics[topic].tout) && (node.topics[topic].tout !== 0)) || (node.loop === true)) { + promise = Promise.resolve(); + if (node.op2type === "pay") { node.topics[topic].m2 = RED.util.cloneMessage(msg.payload); } + else if (node.op2Templated) { node.topics[topic].m2 = mustache.render(node.op2,msg); } + else if (node.op2type !== "nul") { + promise = new Promise((resolve,reject) => { + RED.util.evaluateNodeProperty(node.op2,node.op2type,node,msg,(err,value) => { + if (err) { + reject(err); + } else { + node.topics[topic].m2 = value; + resolve(); + } + }); + }); + } + + return promise.then(() => { + promise = Promise.resolve(); + if (node.op1type === "pay") { } + else if (node.op1Templated) { msg.payload = mustache.render(node.op1,msg); } + else if (node.op1type !== "nul") { + promise = new Promise((resolve,reject) => { + RED.util.evaluateNodeProperty(node.op1,node.op1type,node,msg,(err,value) => { + if (err) { + reject(err); + } else { + msg.payload = value; + resolve(); + } + }); + }); + } + return promise.then(() => { + if (node.duration === 0) { node.topics[topic].tout = 0; } + else if (node.loop === true) { + /* istanbul ignore else */ + if (node.topics[topic].tout) { clearInterval(node.topics[topic].tout); } + /* istanbul ignore else */ + if (node.op1type !== "nul") { + var msg2 = RED.util.cloneMessage(msg); + node.topics[topic].tout = setInterval(function() { node.send(RED.util.cloneMessage(msg2)); }, node.duration); + } + } + else { + if (!node.topics[topic].tout) { + node.topics[topic].tout = setTimeout(function() { + var msg2 = null; + if (node.op2type !== "nul") { + var promise = Promise.resolve(); + msg2 = RED.util.cloneMessage(msg); + if (node.op2type === "flow" || node.op2type === "global") { + promise = new Promise((resolve,reject) => { + RED.util.evaluateNodeProperty(node.op2,node.op2type,node,msg,(err,value) => { + if (err) { + reject(err); + } else { + node.topics[topic].m2 = value; + resolve(); + } + }); + }); + } + promise.then(() => { + if (node.op2type === "payl") { + node.send(npay[topic]); + delete npay[topic]; + } + else { + msg2.payload = node.topics[topic].m2; + node.send(msg2); + } + delete node.topics[topic]; + node.status({}); + }).catch(err => { + node.error(err); + }); + } else { + delete node.topics[topic]; + node.status({}); + } + + }, node.duration); + } + } + node.status({fill:"blue",shape:"dot",text:" "}); + if (node.op1type !== "nul") { node.send(RED.util.cloneMessage(msg)); } + }); + }); + } + else if ((node.extend === "true" || node.extend === true) && (node.duration > 0)) { + /* istanbul ignore else */ + if (node.op2type === "payl") { node.topics[topic].m2 = RED.util.cloneMessage(msg.payload); } + /* istanbul ignore else */ + if (node.topics[topic].tout) { clearTimeout(node.topics[topic].tout); } + node.topics[topic].tout = setTimeout(function() { + var msg2 = null; + var promise = Promise.resolve(); + + if (node.op2type !== "nul") { + if (node.op2type === "flow" || node.op2type === "global") { + promise = new Promise((resolve,reject) => { + RED.util.evaluateNodeProperty(node.op2,node.op2type,node,msg,(err,value) => { + if (err) { + reject(err); + } else { + node.topics[topic].m2 = value; + resolve(); + } + }); + }); + } + } + promise.then(() => { + if (node.op2type !== "nul") { + if (node.topics[topic] !== undefined) { + msg2 = RED.util.cloneMessage(msg); + msg2.payload = node.topics[topic].m2; + } + } + delete node.topics[topic]; + node.status({}); + node.send(msg2); + }).catch(err => { + node.error(err); + }); + }, node.duration); + } + } + return Promise.resolve(); + } + this.on("close", function() { + for (var t in node.topics) { + /* istanbul ignore else */ + if (node.topics[t]) { + if (node.loop === true) { clearInterval(node.topics[t].tout); } + else { clearTimeout(node.topics[t].tout); } + delete node.topics[t]; + } + } + node.status({}); + }); + } + RED.nodes.registerType("trigger",TriggerNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/90-exec.html b/packages/connector/packages/node_modules/@node-red/nodes/core/function/90-exec.html new file mode 100644 index 0000000..c6102d3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/90-exec.html @@ -0,0 +1,84 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-template-name="exec"> + <div class="form-row"> + <label for="node-input-command"><i class="fa fa-file"></i> <span data-i18n="exec.label.command"></span></label> + <input type="text" id="node-input-command" data-i18n="[placeholder]exec.label.command"> + </div> + <div class="form-row"> + <label><i class="fa fa-plus"></i> <span data-i18n="exec.label.append"></span></label> + <input type="checkbox" id="node-input-addpay" style="display:inline-block; width:auto; vertical-align:top;"> + &nbsp;msg.payload + </div> + <div class="form-row"> + <label for="node-input-append"> </label> + <input type="text" id="node-input-append" data-i18n="[placeholder]exec.placeholder.extraparams"> + </div> + <div class="form-row"> + <label><i class="fa fa-sign-out"></i> <span data-i18n="exec.label.return"></span></label> + <select type="text" id="node-input-useSpawn" style="width:70%"> + <option value="false" data-i18n="exec.opt.exec"></option> + <option value="true" data-i18n="exec.opt.spawn"></option> + </select> + </div> + <div class="form-row"> + <label for="node-input-timer"><i class="fa fa-clock-o"></i> <span data-i18n="exec.label.timeout"></span></label> + <input type="text" id="node-input-timer" style="width:65px;" data-i18n="[placeholder]exec.label.timeoutplace"> + <span data-i18n="exec.label.seconds"></span> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('exec',{ + category: 'function', + color:"darksalmon", + defaults: { + command: {value:""}, + addpay: {value:true}, + append: {value:""}, + useSpawn: {value:"false"}, + timer: {value:""}, + oldrc: {value:false}, + name: {value:""} + }, + inputs:1, + outputs:3, + outputLabels: function(i) { + return [ + this._("exec.label.stdout"), + this._("exec.label.stderr"), + this._("exec.label.retcode") + ][i]; + }, + icon: "cog.svg", + label: function() { + return this.name||this.command||(this.useSpawn=="true"?this._("exec.spawn"):this._("exec.exec")); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + if ($("#node-input-useSpawn").val() === null) { + $("#node-input-useSpawn").val(this.useSpawn.toString()); + } + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/function/90-exec.js b/packages/connector/packages/node_modules/@node-red/nodes/core/function/90-exec.js new file mode 100644 index 0000000..f5e7edd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/function/90-exec.js @@ -0,0 +1,190 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var spawn = require('child_process').spawn; + var exec = require('child_process').exec; + var isUtf8 = require('is-utf8'); + + function ExecNode(n) { + RED.nodes.createNode(this,n); + this.cmd = (n.command || "").trim(); + if (n.addpay === undefined) { n.addpay = true; } + this.addpay = n.addpay; + this.append = (n.append || "").trim(); + this.useSpawn = (n.useSpawn == "true"); + this.timer = Number(n.timer || 0)*1000; + this.activeProcesses = {}; + this.oldrc = (n.oldrc || false).toString(); + var node = this; + + var cleanup = function(p) { + node.activeProcesses[p].kill(); + //node.status({fill:"red",shape:"dot",text:"timeout"}); + //node.error("Exec node timeout"); + } + + this.on("input", function(msg, nodeSend, nodeDone) { + if (msg.hasOwnProperty("kill")) { + if (typeof msg.kill !== "string" || msg.kill.length === 0 || !msg.kill.toUpperCase().startsWith("SIG") ) { msg.kill = "SIGTERM"; } + if (msg.hasOwnProperty("pid")) { + if (node.activeProcesses.hasOwnProperty(msg.pid) ) { + node.activeProcesses[msg.pid].kill(msg.kill.toUpperCase()); + node.status({fill:"red",shape:"dot",text:"killed"}); + } + } + else { + if (Object.keys(node.activeProcesses).length === 1) { + node.activeProcesses[Object.keys(node.activeProcesses)[0]].kill(msg.kill.toUpperCase()); + node.status({fill:"red",shape:"dot",text:"killed"}); + } + } + nodeDone(); + } + else { + var child; + if (this.useSpawn === true) { + // make the extra args into an array + // then prepend with the msg.payload + var arg = node.cmd; + if ((node.addpay === true) && msg.hasOwnProperty("payload")) { arg += " "+msg.payload; } + if (node.append.trim() !== "") { arg += " "+node.append; } + // slice whole line by spaces and removes any quotes since spawn can't handle them + arg = arg.match(/(?:[^\s"]+|"[^"]*")+/g).map((a) => { + if (/^".*"$/.test(a)) { + return a.slice(1,-1) + } else { + return a + } + }); + var cmd = arg.shift(); + /* istanbul ignore else */ + if (RED.settings.verbose) { node.log(cmd+" ["+arg+"]"); } + child = spawn(cmd,arg); + node.status({fill:"blue",shape:"dot",text:"pid:"+child.pid}); + var unknownCommand = (child.pid === undefined); + if (node.timer !== 0) { + child.tout = setTimeout(function() { cleanup(child.pid); }, node.timer); + } + node.activeProcesses[child.pid] = child; + child.stdout.on('data', function (data) { + if (node.activeProcesses.hasOwnProperty(child.pid) && node.activeProcesses[child.pid] !== null) { + // console.log('[exec] stdout: ' + data,child.pid); + if (isUtf8(data)) { msg.payload = data.toString(); } + else { msg.payload = data; } + nodeSend([RED.util.cloneMessage(msg),null,null]); + } + }); + child.stderr.on('data', function (data) { + if (node.activeProcesses.hasOwnProperty(child.pid) && node.activeProcesses[child.pid] !== null) { + if (isUtf8(data)) { msg.payload = data.toString(); } + else { msg.payload = Buffer.from(data); } + nodeSend([null,RED.util.cloneMessage(msg),null]); + } + }); + child.on('close', function (code,signal) { + if (unknownCommand || (node.activeProcesses.hasOwnProperty(child.pid) && node.activeProcesses[child.pid] !== null)) { + delete node.activeProcesses[child.pid]; + if (child.tout) { clearTimeout(child.tout); } + msg.payload = code; + if (node.oldrc === "false") { + msg.payload = {code:code}; + if (signal) { msg.payload.signal = signal; } + } + if (code === 0) { node.status({}); } + if (code === null) { node.status({fill:"red",shape:"dot",text:"killed"}); } + else if (code < 0) { node.status({fill:"red",shape:"dot",text:"rc:"+code}); } + else { node.status({fill:"yellow",shape:"dot",text:"rc:"+code}); } + nodeSend([null,null,RED.util.cloneMessage(msg)]); + } + nodeDone(); + }); + child.on('error', function (code) { + if (child.tout) { clearTimeout(child.tout); } + delete node.activeProcesses[child.pid]; + if (node.activeProcesses.hasOwnProperty(child.pid) && node.activeProcesses[child.pid] !== null) { + node.error(code,RED.util.cloneMessage(msg)); + } + }); + } + else { + var cl = node.cmd; + if ((node.addpay === true) && msg.hasOwnProperty("payload")) { cl += " "+msg.payload; } + if (node.append.trim() !== "") { cl += " "+node.append; } + /* istanbul ignore else */ + if (RED.settings.verbose) { node.log(cl); } + child = exec(cl, {encoding:'binary', maxBuffer:10000000}, function (error, stdout, stderr) { + var msg2, msg3; + delete msg.payload; + if (stderr) { + msg2 = RED.util.cloneMessage(msg); + msg2.payload = stderr; + } + msg.payload = Buffer.from(stdout,"binary"); + if (isUtf8(msg.payload)) { msg.payload = msg.payload.toString(); } + node.status({}); + //console.log('[exec] stdout: ' + stdout); + //console.log('[exec] stderr: ' + stderr); + if (error !== null) { + msg3 = RED.util.cloneMessage(msg); + msg3.payload = {code:error.code, message:error.message}; + if (error.signal) { msg3.payload.signal = error.signal; } + if (error.code === null) { node.status({fill:"red",shape:"dot",text:"killed"}); } + else { node.status({fill:"red",shape:"dot",text:"error:"+error.code}); } + if (RED.settings.verbose) { node.log('error:' + error); } + } + else if (node.oldrc === "false") { + msg3 = RED.util.cloneMessage(msg); + msg3.payload = {code:0}; + } + if (!msg3) { node.status({}); } + else { + msg.rc = msg3.payload; + if (msg2) { msg2.rc = msg3.payload; } + } + nodeSend([msg,msg2,msg3]); + if (child.tout) { clearTimeout(child.tout); } + delete node.activeProcesses[child.pid]; + nodeDone(); + }); + node.status({fill:"blue",shape:"dot",text:"pid:"+child.pid}); + child.on('error',function() {}); + if (node.timer !== 0) { + child.tout = setTimeout(function() { cleanup(child.pid); }, node.timer); + } + node.activeProcesses[child.pid] = child; + } + } + }); + + this.on('close',function() { + for (var pid in node.activeProcesses) { + /* istanbul ignore else */ + if (node.activeProcesses.hasOwnProperty(pid)) { + if (node.activeProcesses[pid].tout) { clearTimeout(node.activeProcesses[pid].tout); } + // console.log("KILLING",pid); + var process = node.activeProcesses[pid]; + node.activeProcesses[pid] = null; + process.kill(); + } + } + node.activeProcesses = {}; + node.status({}); + }); + } + RED.nodes.registerType("exec",ExecNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/05-tls.html b/packages/connector/packages/node_modules/@node-red/nodes/core/network/05-tls.html new file mode 100644 index 0000000..2813242 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/05-tls.html @@ -0,0 +1,192 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-template-name="tls-config"> + <div class="form-row" class="hide" id="node-config-row-uselocalfiles"> + <input type="checkbox" id="node-config-input-uselocalfiles" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-config-input-uselocalfiles" style="width: 70%;"><span data-i18n="tls.label.use-local-files"></label> + </div> + <div class="form-row"> + <label style="width: 120px;"><i class="fa fa-file-text-o"></i> <span data-i18n="tls.label.cert"></span></label> + <span class="tls-config-input-data"> + <label class="red-ui-button" for="node-config-input-certfile"><i class="fa fa-upload"></i> <span data-i18n="tls.label.upload"></span></label> + <input class="hide" type="file" id="node-config-input-certfile"> + <span id="tls-config-certname" style="width: calc(100% - 280px); overflow: hidden; line-height:34px; height:34px; text-overflow: ellipsis; white-space: nowrap; display: inline-block; vertical-align: middle;"> </span> + <button class="red-ui-button red-ui-button-small" id="tls-config-button-cert-clear" style="margin-left: 10px"><i class="fa fa-times"></i></button> + </span> + <input type="hidden" id="node-config-input-certname"> + <input type="hidden" id="node-config-input-certdata"> + <input class="hide tls-config-input-path" style="width: calc(100% - 170px);" type="text" id="node-config-input-cert" data-i18n="[placeholder]tls.placeholder.cert"> + </div> + <div class="form-row"> + <label style="width: 120px;" for="node-config-input-key"><i class="fa fa-file-text-o"></i> <span data-i18n="tls.label.key"></span></label> + <span class="tls-config-input-data"> + <label class="red-ui-button" for="node-config-input-keyfile"><i class="fa fa-upload"></i> <span data-i18n="tls.label.upload"></span></label> + <input class="hide" type="file" id="node-config-input-keyfile"> + <span id="tls-config-keyname" style="width: calc(100% - 280px); overflow: hidden; line-height:34px; height:34px; text-overflow: ellipsis; white-space: nowrap; display: inline-block; vertical-align: middle;"> </span> + <button class="red-ui-button red-ui-button-small" id="tls-config-button-key-clear" style="margin-left: 10px"><i class="fa fa-times"></i></button> + </span> + <input type="hidden" id="node-config-input-keyname"> + <input type="hidden" id="node-config-input-keydata"> + <input class="hide tls-config-input-path" style="width: calc(100% - 170px);" type="text" id="node-config-input-key" data-i18n="[placeholder]tls.placeholder.key"> + </div> + <div class="form-row"> + <label style="width: 100px; margin-left: 20px;" for="node-config-input-passphrase"> <span data-i18n="tls.label.passphrase"></span></label> + <input type="password" style="width: calc(100% - 170px);" id="node-config-input-passphrase" data-i18n="[placeholder]tls.placeholder.passphrase"> + </div> + <div class="form-row"> + <label style="width: 120px;" for="node-config-input-ca"><i class="fa fa-file-text-o"></i> <span data-i18n="tls.label.ca"></span></label> + <span class="tls-config-input-data"> + <label class="red-ui-button" for="node-config-input-cafile"><i class="fa fa-upload"></i> <span data-i18n="tls.label.upload"></span></label> + <input class="hide" type="file" title=" " id="node-config-input-cafile"> + <span id="tls-config-caname" style="width: calc(100% - 280px); overflow: hidden; line-height:34px; height:34px; text-overflow: ellipsis; white-space: nowrap; display: inline-block; vertical-align: middle;"> </span> + <button class="red-ui-button red-ui-button-small" id="tls-config-button-ca-clear" style="margin-left: 10px"><i class="fa fa-times"></i></button> + </span> + <input type="hidden" id="node-config-input-caname"> + <input type="hidden" id="node-config-input-cadata"> + <input class="hide tls-config-input-path" style="width: calc(100% - 170px);" type="text" id="node-config-input-ca" data-i18n="[placeholder]tls.placeholder.ca"> + </div> + <div class="form-row"> + <input type="checkbox" id="node-config-input-verifyservercert" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-config-input-verifyservercert" style="width: calc(100% - 170px);" data-i18n="tls.label.verify-server-cert"></label> + </div> + <div class="form-row"> + <label style="width: 120px;" for="node-config-input-servername"><i class="fa fa-server"></i> <span data-i18n="tls.label.servername"></span></label> + <input style="width: calc(100% - 170px);" type="text" id="node-config-input-servername" data-i18n="[placeholder]tls.placeholder.servername"> + </div> + <hr> + <div class="form-row"> + <label style="width: 120px;" for="node-config-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input style="width: calc(100% - 170px);" type="text" id="node-config-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('tls-config',{ + category: 'config', + defaults: { + name: {value:""}, + cert: {value:"", validate: function(v) { + var currentKey = $("#node-config-input-key").val(); + if (currentKey === undefined) { + currentKey = this.key; + } + return currentKey === '' || v != ''; + }}, + key: {value:"", validate: function(v) { + var currentCert = $("#node-config-input-cert").val(); + if (currentCert === undefined) { + currentCert = this.cert; + } + return currentCert === '' || v != ''; + }}, + ca: {value:""}, + certname: {value:""}, + keyname: {value:""}, + caname: {value:""}, + servername: {value:""}, + verifyservercert: {value: true} + }, + credentials: { + certdata: {type:"text"}, + keydata: {type:"text"}, + cadata: {type:"text"}, + passphrase: {type:"password"} + }, + label: function() { + return this.name || this._("tls.tls"); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + function updateFileUpload() { + if ($("#node-config-input-uselocalfiles").is(':checked')) { + $(".tls-config-input-path").show(); + $(".tls-config-input-data").hide(); + } else { + $(".tls-config-input-data").show(); + $(".tls-config-input-path").hide(); + } + } + $("#node-config-input-uselocalfiles").on("click",function() { + updateFileUpload(); + }); + + function saveFile(property, file) { + var dataInputId = "#node-config-input-"+property+"data"; + var filenameInputId = "#node-config-input-"+property+"name"; + var filename = file.name; + var reader = new FileReader(); + reader.onload = function(event) { + $("#tls-config-"+property+"name").text(filename); + $(filenameInputId).val(filename); + $(dataInputId).val(event.target.result); + } + reader.readAsText(file,"UTF-8"); + } + $("#node-config-input-certfile" ).on("change", function() { + saveFile("cert", this.files[0]); + }); + $("#node-config-input-keyfile" ).on("change", function() { + saveFile("key", this.files[0]); + }); + $("#node-config-input-cafile" ).on("change", function() { + saveFile("ca", this.files[0]); + }); + + function clearNameData(prop) { + $("#tls-config-"+prop+"name").text(""); + $("#node-config-input-"+prop+"data").val(""); + $("#node-config-input-"+prop+"name").val(""); + } + $("#tls-config-button-cert-clear").on("click", function() { + clearNameData("cert"); + }); + $("#tls-config-button-key-clear").on("click", function() { + clearNameData("key"); + }); + $("#tls-config-button-ca-clear").on("click", function() { + clearNameData("ca"); + }); + + if (RED.settings.tlsConfigDisableLocalFiles) { + $("#node-config-row-uselocalfiles").hide(); + } else { + $("#node-config-row-uselocalfiles").show(); + } + // in case paths were set from old TLS config + if(this.cert || this.key || this.ca) { + $("#node-config-input-uselocalfiles").prop('checked',true); + } + $("#tls-config-certname").text(this.certname); + $("#tls-config-keyname").text(this.keyname); + $("#tls-config-caname").text(this.caname); + updateFileUpload(); + }, + oneditsave: function() { + if ($("#node-config-input-uselocalfiles").is(':checked')) { + clearNameData("ca"); + clearNameData("cert"); + clearNameData("key"); + } else { + $("#node-config-input-ca").val(""); + $("#node-config-input-cert").val(""); + $("#node-config-input-key").val(""); + } + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/05-tls.js b/packages/connector/packages/node_modules/@node-red/nodes/core/network/05-tls.js new file mode 100644 index 0000000..078bac2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/05-tls.js @@ -0,0 +1,114 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var fs = require('fs'); +module.exports = function(RED) { + "use strict"; + + function TLSConfig(n) { + RED.nodes.createNode(this,n); + this.valid = true; + this.verifyservercert = n.verifyservercert; + var certPath = n.cert.trim(); + var keyPath = n.key.trim(); + var caPath = n.ca.trim(); + this.servername = (n.servername||"").trim(); + + if ((certPath.length > 0) || (keyPath.length > 0) || (caPath.length > 0)) { + + if ( (certPath.length > 0) !== (keyPath.length > 0)) { + this.valid = false; + this.error(RED._("tls.error.missing-file")); + return; + } + + try { + if (certPath) { + this.cert = fs.readFileSync(certPath); + } + if (keyPath) { + this.key = fs.readFileSync(keyPath); + } + if (caPath) { + this.ca = fs.readFileSync(caPath); + } + } catch(err) { + this.valid = false; + this.error(err.toString()); + return; + } + } else { + if (this.credentials) { + var certData = this.credentials.certdata || ""; + var keyData = this.credentials.keydata || ""; + var caData = this.credentials.cadata || ""; + + if ((certData.length > 0) !== (keyData.length > 0)) { + this.valid = false; + this.error(RED._("tls.error.missing-file")); + return; + } + + if (certData) { + this.cert = certData; + } + if (keyData) { + this.key = keyData; + } + if (caData) { + this.ca = caData; + } + } + } + } + RED.nodes.registerType("tls-config", TLSConfig, { + credentials: { + certdata: {type:"text"}, + keydata: {type:"text"}, + cadata: {type:"text"}, + passphrase: {type:"password"} + }, + settings: { + tlsConfigDisableLocalFiles: { + value: false, + exportable: true + } + } + }); + + TLSConfig.prototype.addTLSOptions = function(opts) { + if (this.valid) { + if (this.key) { + opts.key = this.key; + } + if (this.cert) { + opts.cert = this.cert; + } + if (this.ca) { + opts.ca = this.ca; + } + if (this.credentials && this.credentials.passphrase) { + opts.passphrase = this.credentials.passphrase; + } + if (this.servername) { + opts.servername = this.servername; + } + opts.rejectUnauthorized = this.verifyservercert; + } + return opts; + } + +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/06-httpproxy.html b/packages/connector/packages/node_modules/@node-red/nodes/core/network/06-httpproxy.html new file mode 100644 index 0000000..37129e3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/06-httpproxy.html @@ -0,0 +1,129 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-template-name="http proxy"> + <div class="form-row"> + <label for="node-config-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-config-input-name"> + </div> + <div class="form-row"> + <label for="node-config-input-url"><i class="fa fa-globe"></i> <span data-i18n="httpin.label.url"></span></label> + <input type="text" id="node-config-input-url" placeholder="http://hostname:port"> + </div> + <div class="form-row"> + <input type="checkbox" id="node-config-input-useAuth" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-config-input-useAuth" style="width: 70%;"><span data-i18n="httpin.use-proxyauth"></span></label> + <div style="margin-left: 20px" class="node-config-input-useAuth-row hide"> + <div class="form-row"> + <label for="node-config-input-username"><i class="fa fa-user"></i> <span data-i18n="common.label.username"></span></label> + <input type="text" id="node-config-input-username"> + </div> + <div class="form-row"> + <label for="node-config-input-password"><i class="fa fa-lock"></i> <span data-i18n="common.label.password"></span></label> + <input type="password" id="node-config-input-password"> + </div> + </div> + </div> + <div class="form-row" style="margin-bottom:0;"> + <label><i class="fa fa-list"></i> <span data-i18n="httpin.noproxy-hosts"></span></label> + </div> + <div class="form-row node-config-input-noproxy-container-row"> + <ol id="node-config-input-noproxy-container"></ol> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('http proxy', { + category: 'config', + defaults: { + name: {value:''}, + url: {value:'',validate:function(v) { return (v && (v.indexOf('://') !== -1) && (v.trim().indexOf('http') === 0)); }}, + noproxy: {value:[]} + }, + credentials: { + username: {type:'text'}, + password: {type:'password'} + }, + label: function() { + return this.name || this.url || ('http proxy:' + this.id); + }, + oneditprepare: function() { + $('#node-config-input-useAuth').on("change", function() { + if ($(this).is(":checked")) { + $('.node-config-input-useAuth-row').show(); + } else { + $('.node-config-input-useAuth-row').hide(); + $('#node-config-input-username').val(''); + $('#node-config-input-password').val(''); + } + }); + if (this.credentials.username || this.credentials.has_password) { + $('#node-config-input-useAuth').prop('checked', true); + } else { + $('#node-config-input-useAuth').prop('checked', false); + } + $('#node-config-input-useAuth').change(); + + var hostList = $('#node-config-input-noproxy-container') + .css({'min-height':'150px','min-width':'450px'}) + .editableList({ + addItem: function(container, index, data) { + var row = $('<div/>') + .css({overflow: 'hidden',whiteSpace: 'nowrap'}) + .appendTo(container); + + var hostField = $('<input/>',{class:'node-config-input-host',type:'text',placeholder:'hostname'}) + .css({width:'100%'}) + .appendTo(row); + if (data.host) { + hostField.val(data.host); + } + }, + removable: true + }); + if (this.noproxy) { + for (var i in this.noproxy) { + hostList.editableList('addItem', {host:this.noproxy[i]}); + } + } + if (hostList.editableList('items').length == 0) { + hostList.editableList('addItem', {host:''}); + } + }, + oneditsave: function() { + var hosts = $('#node-config-input-noproxy-container').editableList('items'); + var node = this; + node.noproxy = []; + hosts.each(function(i) { + var host = $(this).find('.node-config-input-host').val().trim(); + if (host) { + node.noproxy.push(host); + } + }); + }, + oneditresize: function(size) { + var rows = $('#node-config-dialog-edit-form>div:not(.node-config-input-noproxy-container-row)'); + var height = size.height; + for (var i = 0; i < rows.length; i++) { + height -= $(rows[i]).outerHeight(true); + } + + var editorRow = $('#node-config-dialog-edit-form>div.node-config-input-noproxy-container-row'); + height -= (parseInt(editorRow.css('margin-top')) + parseInt(editorRow.css('margin-bottom'))); + $('#node-config-input-noproxy-container').editableList('height',height); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/06-httpproxy.js b/packages/connector/packages/node_modules/@node-red/nodes/core/network/06-httpproxy.js new file mode 100644 index 0000000..abcee66 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/06-httpproxy.js @@ -0,0 +1,33 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + 'use strict'; + + function HTTPProxyConfig(n) { + RED.nodes.createNode(this, n); + this.name = n.name; + this.url = n.url; + this.noproxy = n.noproxy; + }; + + RED.nodes.registerType('http proxy', HTTPProxyConfig, { + credentials: { + username: {type:'text'}, + password: {type:'password'} + } + }); +}; diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/10-mqtt.html b/packages/connector/packages/node_modules/@node-red/nodes/core/network/10-mqtt.html new file mode 100644 index 0000000..91b3d8c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/10-mqtt.html @@ -0,0 +1,447 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-template-name="mqtt in"> + <div class="form-row"> + <label for="node-input-broker"><i class="fa fa-globe"></i> <span data-i18n="mqtt.label.broker"></span></label> + <input type="text" id="node-input-broker"> + </div> + <div class="form-row"> + <label for="node-input-topic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label> + <input type="text" id="node-input-topic" data-i18n="[placeholder]common.label.topic"> + </div> + <div class="form-row"> + <label for="node-input-qos"><i class="fa fa-empire"></i> <span data-i18n="mqtt.label.qos"></span></label> + <select id="node-input-qos" style="width:125px !important"> + <option value="0">0</option> + <option value="1">1</option> + <option value="2">2</option> + </select> + </div> + <div class="form-row"> + <label for="node-input-datatype"><i class="fa fa-sign-out"></i> <span data-i18n="mqtt.label.output"></span></label> + <select id="node-input-datatype" style="width:70%;"> + <option value="auto" data-i18n="mqtt.output.auto"></option> + <option value="buffer" data-i18n="mqtt.output.buffer"></option> + <option value="utf8" data-i18n="mqtt.output.string"></option> + <option value="json" data-i18n="mqtt.output.json"></option> + <option value="base64" data-i18n="mqtt.output.base64"></option> + </select> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('mqtt in',{ + category: 'network', + defaults: { + name: {value:""}, + topic: {value:"",required:true,validate: RED.validators.regex(/^(#$|(\+|[^+#]*)(\/(\+|[^+#]*))*(\/(\+|#|[^+#]*))?$)/)}, + qos: {value: "2"}, + datatype: {value:"auto",required:true}, + broker: {type:"mqtt-broker", required:true} + }, + color:"#d8bfd8", + inputs:0, + outputs:1, + icon: "bridge.svg", + label: function() { + return this.name||this.topic||"mqtt"; + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + if (this.qos === undefined) { + $("#node-input-qos").val("2"); + } + if (this.datatype === undefined) { + $("#node-input-datatype").val("auto"); + } + } + }); +</script> + +<script type="text/x-red" data-template-name="mqtt out"> + <div class="form-row"> + <label for="node-input-broker"><i class="fa fa-globe"></i> <span data-i18n="mqtt.label.broker"></span></label> + <input type="text" id="node-input-broker"> + </div> + <div class="form-row"> + <label for="node-input-topic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label> + <input type="text" id="node-input-topic" data-i18n="[placeholder]common.label.topic"> + </div> + <div class="form-row"> + <label for="node-input-qos"><i class="fa fa-empire"></i> <span data-i18n="mqtt.label.qos"></span></label> + <select id="node-input-qos" style="width:125px !important"> + <option value=""></option> + <option value="0">0</option> + <option value="1">1</option> + <option value="2">2</option> + </select> + &nbsp;&nbsp;<i class="fa fa-history"></i>&nbsp;<span data-i18n="mqtt.retain"></span> &nbsp;<select id="node-input-retain" style="width:125px !important"> + <option value=""></option> + <option value="false" data-i18n="mqtt.false"></option> + <option value="true" data-i18n="mqtt.true"></option> + </select> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-tips"><span data-i18n="mqtt.tip"></span></div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('mqtt out',{ + category: 'network', + defaults: { + name: {value:""}, + topic: {value:""}, + qos: {value:""}, + retain: {value:""}, + broker: {type:"mqtt-broker", required:true} + }, + color:"#d8bfd8", + inputs:1, + outputs:0, + icon: "bridge.svg", + align: "right", + label: function() { + return this.name||this.topic||"mqtt"; + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + } + }); +</script> + +<script type="text/html" data-template-name="mqtt-broker"> + <div class="form-row"> + <label for="node-config-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-config-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-row"> + <ul style="min-width: 600px; margin-bottom: 20px;" id="node-config-mqtt-broker-tabs"></ul> + </div> + <div id="node-config-mqtt-broker-tabs-content" style="min-height:150px;"> + <div id="mqtt-broker-tab-connection" style="display:none"> + <div class="form-row node-input-broker"> + <label for="node-config-input-broker"><i class="fa fa-globe"></i> <span data-i18n="mqtt.label.broker"></span></label> + <input type="text" id="node-config-input-broker" style="width:40%;" data-i18n="[placeholder]mqtt.label.example"> + <label for="node-config-input-port" style="margin-left:20px; width:43px; "> <span data-i18n="mqtt.label.port"></span></label> + <input type="text" id="node-config-input-port" data-i18n="[placeholder]mqtt.label.port" style="width:55px"> + </div> + <div class="form-row"> + <input type="checkbox" id="node-config-input-usetls" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-config-input-usetls" style="width: auto" data-i18n="mqtt.label.use-tls"></label> + <div id="node-config-row-tls" class="hide"> + <label style="width: auto; margin-left: 20px; margin-right: 10px;" for="node-config-input-tls"><span data-i18n="mqtt.label.tls-config"></span></label><input style="width: 300px;" type="text" id="node-config-input-tls"> + </div> + </div> + <div class="form-row"> + <label for="node-config-input-clientid"><i class="fa fa-tag"></i> <span data-i18n="mqtt.label.clientid"></span></label> + <input type="text" id="node-config-input-clientid" data-i18n="[placeholder]mqtt.placeholder.clientid"> + </div> + <div class="form-row"> + <label for="node-config-input-keepalive" style="width: auto"><i class="fa fa-clock-o"></i> <span data-i18n="mqtt.label.keepalive"></span></label> + <input type="text" id="node-config-input-keepalive" style="width: 50px"> + <input type="checkbox" id="node-config-input-cleansession" style="margin-left: 30px; height: 1em;display: inline-block; width: auto; vertical-align: middle;"> + <label for="node-config-input-cleansession" style="width: auto;" data-i18n="mqtt.label.cleansession"></label> + </div> + <div class="form-row"> + <input type="checkbox" id="node-config-input-compatmode" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-config-input-compatmode" style="width: auto;" data-i18n="mqtt.label.compatmode"></label> + </div> + </div> + <div id="mqtt-broker-tab-security" style="display:none"> + <div class="form-row"> + <label for="node-config-input-user"><i class="fa fa-user"></i> <span data-i18n="common.label.username"></span></label> + <input type="text" id="node-config-input-user"> + </div> + <div class="form-row"> + <label for="node-config-input-password"><i class="fa fa-lock"></i> <span data-i18n="common.label.password"></span></label> + <input type="password" id="node-config-input-password"> + </div> + </div> + <div id="mqtt-broker-tab-messages" style="display:none"> + <div id="mqtt-broker-section-birth"> + <div class="red-ui-palette-header"> + <i class="fa fa-angle-down"></i><span data-i18n="mqtt.sections-label.birth-message"></span> + </div> + <div class="section-content" style="padding:10px 0 0 10px"> + <div class="form-row"> + <label style="width: 100px !important;" for="node-config-input-birthTopic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label> + <input style="width: calc(100% - 300px) !important" type="text" id="node-config-input-birthTopic" data-i18n="[placeholder]mqtt.placeholder.birth-topic"> + <label style="margin-left: 10px; width: 90px !important;" for="node-config-input-birthRetain"><i class="fa fa-history"></i> <span data-i18n="mqtt.label.retain"></span></label> + <select id="node-config-input-birthRetain" style="width:75px !important"> + <option value="false" data-i18n="mqtt.false"></option> + <option value="true" data-i18n="mqtt.true"></option> + </select> + </div> + <div class="form-row"> + <label style="width: 100px !important;" for="node-config-input-birthPayload"><i class="fa fa-envelope"></i> <span data-i18n="common.label.payload"></span></label> + <input style="width: calc(100% - 300px) !important" type="text" id="node-config-input-birthPayload" style="width:300px" data-i18n="[placeholder]common.label.payload"> + <label style="margin-left: 10px; width: 90px !important;" for="node-config-input-birthQos"><i class="fa fa-empire"></i> <span data-i18n="mqtt.label.qos"></span></label> + <select id="node-config-input-birthQos" style="width:75px !important"> + <option value="0">0</option> + <option value="1">1</option> + <option value="2">2</option> + </select> + </div> + </div> + </div> + <div id="mqtt-broker-section-close"> + <div class="red-ui-palette-header"> + <i class="fa fa-angle-down"></i><span data-i18n="mqtt.sections-label.close-message"></span> + </div> + <div class="section-content" style="padding:10px 0 0 10px"> + <div class="form-row"> + <label style="width: 100px !important;" for="node-config-input-closeTopic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label> + <input style="width: calc(100% - 300px) !important" type="text" id="node-config-input-closeTopic" style="width:300px" data-i18n="[placeholder]mqtt.placeholder.close-topic"> + <label style="margin-left: 10px; width: 90px !important;" for="node-config-input-closeRetain"><i class="fa fa-history"></i> <span data-i18n="mqtt.label.retain"></span></label> + <select id="node-config-input-closeRetain" style="width:75px !important"> + <option value="false" data-i18n="mqtt.false"></option> + <option value="true" data-i18n="mqtt.true"></option> + </select> + </div> + <div class="form-row"> + <label style="width: 100px !important;" for="node-config-input-closePayload"><i class="fa fa-envelope"></i> <span data-i18n="common.label.payload"></span></label> + <input style="width: calc(100% - 300px) !important" type="text" id="node-config-input-closePayload" style="width:300px" data-i18n="[placeholder]common.label.payload"> + <label style="margin-left: 10px; width: 90px !important;" for="node-config-input-closeQos"><i class="fa fa-empire"></i> <span data-i18n="mqtt.label.qos"></span></label> + <select id="node-config-input-closeQos" style="width:75px !important"> + <option value="0">0</option> + <option value="1">1</option> + <option value="2">2</option> + </select> + </div> + </div> + </div> + <div id="mqtt-broker-section-will"> + <div class="red-ui-palette-header"> + <i class="fa fa-angle-down"></i><span data-i18n="mqtt.sections-label.will-message"></span> + </div> + <div class="section-content" style="padding:10px 0 0 10px"> + <div class="form-row"> + <label style="width: 100px !important;" for="node-config-input-willTopic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label> + <input style="width: calc(100% - 300px) !important" type="text" id="node-config-input-willTopic" style="width:300px" data-i18n="[placeholder]mqtt.placeholder.will-topic"> + <label style="margin-left: 10px; width: 90px !important;" for="node-config-input-willRetain"><i class="fa fa-history"></i> <span data-i18n="mqtt.label.retain"></span></label> + <select id="node-config-input-willRetain" style="width:75px !important"> + <option value="false" data-i18n="mqtt.false"></option> + <option value="true" data-i18n="mqtt.true"></option> + </select> + </div> + <div class="form-row"> + <label style="width: 100px !important;" for="node-config-input-willPayload"><i class="fa fa-envelope"></i> <span data-i18n="common.label.payload"></span></label> + <input style="width: calc(100% - 300px) !important" type="text" id="node-config-input-willPayload" style="width:300px" data-i18n="[placeholder]common.label.payload"> + <label style="margin-left: 10px; width: 90px !important;" for="node-config-input-willQos"><i class="fa fa-empire"></i> <span data-i18n="mqtt.label.qos"></span></label> + <select id="node-config-input-willQos" style="width:75px !important"> + <option value="0">0</option> + <option value="1">1</option> + <option value="2">2</option> + </select> + </div> + </div> + </div> + </div> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('mqtt-broker',{ + category: 'config', + defaults: { + name: {value:""}, + broker: {value:"",required:true}, + port: {value:1883,required:false,validate:RED.validators.number(true)}, + tls: {type:"tls-config",required: false}, + clientid: {value:"", validate: function(v) { + if ($("#node-config-input-clientid").length) { + // Currently editing the node + return $("#node-config-input-cleansession").is(":checked") || (v||"").length > 0; + } else { + return (this.cleansession===undefined || this.cleansession) || (v||"").length > 0; + } + }}, + usetls: {value: false}, + verifyservercert: { value: false}, + compatmode: { value: false}, + keepalive: {value:60,validate:RED.validators.number()}, + cleansession: {value: true}, + birthTopic: {value:""}, + birthQos: {value:"0"}, + birthRetain: {value:false}, + birthPayload: {value:""}, + closeTopic: {value:""}, + closeQos: {value:"0"}, + closeRetain: {value:false}, + closePayload: {value:""}, + willTopic: {value:""}, + willQos: {value:"0"}, + willRetain: {value:false}, + willPayload: {value:""} + }, + credentials: { + user: {type:"text"}, + password: {type: "password"} + }, + label: function() { + if (this.name) { + return this.name; + } + var b = this.broker; + if (b === "") { b = "undefined"; } + var lab = ""; + lab = (this.clientid?this.clientid+"@":"")+b; + if (b.indexOf("://") === -1){ + if (!this.port){ lab = lab + ":1883"; } + else { lab = lab + ":" + this.port; } + } + return lab; + }, + oneditprepare: function () { + var tabs = RED.tabs.create({ + id: "node-config-mqtt-broker-tabs", + onchange: function(tab) { + $("#node-config-mqtt-broker-tabs-content").children().hide(); + $("#" + tab.id).show(); + } + }); + tabs.addTab({ + id: "mqtt-broker-tab-connection", + label: this._("mqtt.tabs-label.connection") + }); + tabs.addTab({ + id: "mqtt-broker-tab-security", + label: this._("mqtt.tabs-label.security") + }); + + tabs.addTab({ + id: "mqtt-broker-tab-messages", + label: this._("mqtt.tabs-label.messages") + }); + + function setUpSection(sectionId, isExpanded) { + var birthMessageSection = $(sectionId); + var paletteHeader = birthMessageSection.find('.red-ui-palette-header'); + var twistie = paletteHeader.find('i'); + var sectionContent = birthMessageSection.find('.section-content'); + + function toggleSection(expanded) { + twistie.toggleClass('expanded', expanded); + sectionContent.toggle(expanded); + } + paletteHeader.on("click", function(e) { + e.preventDefault(); + var isExpanded = twistie.hasClass('expanded'); + toggleSection(!isExpanded); + }); + toggleSection(isExpanded); + } + + // show first section if none are set so the user gets the idea + var showBirthSection = this.birthTopic !== "" + || this.willTopic === "" + && this.birthTopic === "" + && this.closeTopic == ""; + setUpSection('#mqtt-broker-section-birth', showBirthSection); + setUpSection('#mqtt-broker-section-close', this.closeTopic !== ""); + setUpSection('#mqtt-broker-section-will', this.willTopic !== ""); + + setTimeout(function() { tabs.resize(); },0); + if (typeof this.cleansession === 'undefined') { + this.cleansession = true; + $("#node-config-input-cleansession").prop("checked",true); + } + if (typeof this.usetls === 'undefined') { + this.usetls = false; + $("#node-config-input-usetls").prop("checked",false); + } + if (typeof this.compatmode === 'undefined') { + this.compatmode = false; + $("#node-config-input-compatmode").prop('checked', false); + } + if (typeof this.keepalive === 'undefined') { + this.keepalive = 15; + $("#node-config-input-keepalive").val(this.keepalive); + } + if (typeof this.birthQos === 'undefined') { + this.birthQos = "0"; + $("#node-config-input-birthQos").val("0"); + } + if (typeof this.closeQos === 'undefined') { + this.willQos = "0"; + $("#node-config-input-willQos").val("0"); + } + if (typeof this.willQos === 'undefined') { + this.willQos = "0"; + $("#node-config-input-willQos").val("0"); + } + + function updateTLSOptions() { + if ($("#node-config-input-usetls").is(':checked')) { + $("#node-config-row-tls").show(); + } else { + $("#node-config-row-tls").hide(); + } + } + updateTLSOptions(); + $("#node-config-input-usetls").on("click",function() { + updateTLSOptions(); + }); + var node = this; + function updateClientId() { + if ($("#node-config-input-cleansession").is(":checked")) { + $("#node-config-input-clientid").attr("placeholder",node._("mqtt.placeholder.clientid")); + } else { + $("#node-config-input-clientid").attr("placeholder",node._("mqtt.placeholder.clientid-nonclean")); + } + $("#node-config-input-clientid").change(); + } + setTimeout(updateClientId,0); + $("#node-config-input-cleansession").on("click",function() { + updateClientId(); + }); + + function updatePortEntry(){ + var disabled = $("#node-config-input-port").prop("disabled"); + if ($("#node-config-input-broker").val().indexOf("://") === -1){ + if (disabled){ + $("#node-config-input-port").prop("disabled", false); + } + } + else { + if (!disabled){ + $("#node-config-input-port").prop("disabled", true); + } + } + } + $("#node-config-input-broker").on("change", function() { + updatePortEntry(); + }); + $("#node-config-input-broker").on( "keyup", function() { + updatePortEntry(); + }); + setTimeout(updatePortEntry,50); + + }, + oneditsave: function() { + if (!$("#node-config-input-usetls").is(':checked')) { + $("#node-config-input-tls").val(""); + } + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/10-mqtt.js b/packages/connector/packages/node_modules/@node-red/nodes/core/network/10-mqtt.js new file mode 100644 index 0000000..7ab6242 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/10-mqtt.js @@ -0,0 +1,513 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var mqtt = require("mqtt"); + var util = require("util"); + var isUtf8 = require('is-utf8'); + var HttpsProxyAgent = require('https-proxy-agent'); + var url = require('url'); + + function matchTopic(ts,t) { + if (ts == "#") { + return true; + } + /* The following allows shared subscriptions (as in MQTT v5) + http://docs.oasis-open.org/mqtt/mqtt/v5.0/cs02/mqtt-v5.0-cs02.html#_Toc514345522 + + 4.8.2 describes shares like: + $share/{ShareName}/{filter} + $share is a literal string that marks the Topic Filter as being a Shared Subscription Topic Filter. + {ShareName} is a character string that does not include "/", "+" or "#" + {filter} The remainder of the string has the same syntax and semantics as a Topic Filter in a non-shared subscription. Refer to section 4.7. + */ + else if(ts.startsWith("$share")){ + ts = ts.replace(/^\$share\/[^#+/]+\/(.*)/g,"$1"); + + } + var re = new RegExp("^"+ts.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$"); + return re.test(t); + } + + function MQTTBrokerNode(n) { + RED.nodes.createNode(this,n); + + // Configuration options passed by Node Red + this.broker = n.broker; + this.port = n.port; + this.clientid = n.clientid; + this.usetls = n.usetls; + this.usews = n.usews; + this.verifyservercert = n.verifyservercert; + this.compatmode = n.compatmode; + this.keepalive = n.keepalive; + this.cleansession = n.cleansession; + + // Config node state + this.brokerurl = ""; + this.connected = false; + this.connecting = false; + this.closing = false; + this.options = {}; + this.queue = []; + this.subscriptions = {}; + + if (n.birthTopic) { + this.birthMessage = { + topic: n.birthTopic, + payload: n.birthPayload || "", + qos: Number(n.birthQos||0), + retain: n.birthRetain=="true"|| n.birthRetain===true + }; + } + + if (n.closeTopic) { + this.closeMessage = { + topic: n.closeTopic, + payload: n.closePayload || "", + qos: Number(n.closeQos||0), + retain: n.closeRetain=="true"|| n.closeRetain===true + }; + } + + if (this.credentials) { + this.username = this.credentials.user; + this.password = this.credentials.password; + } + + // If the config node is missing certain options (it was probably deployed prior to an update to the node code), + // select/generate sensible options for the new fields + if (typeof this.usetls === 'undefined') { + this.usetls = false; + } + if (typeof this.usews === 'undefined') { + this.usews = false; + } + if (typeof this.compatmode === 'undefined') { + this.compatmode = false; + } + if (typeof this.verifyservercert === 'undefined') { + this.verifyservercert = false; + } + if (typeof this.keepalive === 'undefined') { + this.keepalive = 60; + } else if (typeof this.keepalive === 'string') { + this.keepalive = Number(this.keepalive); + } + if (typeof this.cleansession === 'undefined') { + this.cleansession = true; + } + + var prox, noprox; + if (process.env.http_proxy) { prox = process.env.http_proxy; } + if (process.env.HTTP_PROXY) { prox = process.env.HTTP_PROXY; } + if (process.env.no_proxy) { noprox = process.env.no_proxy.split(","); } + if (process.env.NO_PROXY) { noprox = process.env.NO_PROXY.split(","); } + + + // Create the URL to pass in to the MQTT.js library + if (this.brokerurl === "") { + // if the broker may be ws:// or wss:// or even tcp:// + if (this.broker.indexOf("://") > -1) { + this.brokerurl = this.broker; + // Only for ws or wss, check if proxy env var for additional configuration + if (this.brokerurl.indexOf("wss://") > -1 || this.brokerurl.indexOf("ws://") > -1 ) { + // check if proxy is set in env + var noproxy; + if (noprox) { + for (var i = 0; i < noprox.length; i += 1) { + if (this.brokerurl.indexOf(noprox[i].trim()) !== -1) { noproxy=true; } + } + } + if (prox && !noproxy) { + var parsedUrl = url.parse(this.brokerurl); + var proxyOpts = url.parse(prox); + // true for wss + proxyOpts.secureEndpoint = parsedUrl.protocol ? parsedUrl.protocol === 'wss:' : true; + // Set Agent for wsOption in MQTT + var agent = new HttpsProxyAgent(proxyOpts); + this.options.wsOptions = { + agent: agent + } + } + } + } else { + // construct the std mqtt:// url + if (this.usetls) { + this.brokerurl="mqtts://"; + } else { + this.brokerurl="mqtt://"; + } + if (this.broker !== "") { + //Check for an IPv6 address + if (/(?:^|(?<=\s))(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(?=\s|$)/.test(this.broker)) { + this.brokerurl = this.brokerurl+"["+this.broker+"]:"; + } else { + this.brokerurl = this.brokerurl+this.broker+":"; + } + // port now defaults to 1883 if unset. + if (!this.port){ + this.brokerurl = this.brokerurl+"1883"; + } else { + this.brokerurl = this.brokerurl+this.port; + } + } else { + this.brokerurl = this.brokerurl+"localhost:1883"; + } + } + } + + if (!this.cleansession && !this.clientid) { + this.cleansession = true; + this.warn(RED._("mqtt.errors.nonclean-missingclientid")); + } + + // Build options for passing to the MQTT.js API + this.options.clientId = this.clientid || 'mqtt_' + (1+Math.random()*4294967295).toString(16); + this.options.username = this.username; + this.options.password = this.password; + this.options.keepalive = this.keepalive; + this.options.clean = this.cleansession; + this.options.reconnectPeriod = RED.settings.mqttReconnectTime||5000; + if (this.compatmode == "true" || this.compatmode === true) { + this.options.protocolId = 'MQIsdp'; + this.options.protocolVersion = 3; + } + if (this.usetls && n.tls) { + var tlsNode = RED.nodes.getNode(n.tls); + if (tlsNode) { + tlsNode.addTLSOptions(this.options); + } + } + // console.log(this.brokerurl,this.options); + + // If there's no rejectUnauthorized already, then this could be an + // old config where this option was provided on the broker node and + // not the tls node + if (typeof this.options.rejectUnauthorized === 'undefined') { + this.options.rejectUnauthorized = (this.verifyservercert == "true" || this.verifyservercert === true); + } + + if (n.willTopic) { + this.options.will = { + topic: n.willTopic, + payload: n.willPayload || "", + qos: Number(n.willQos||0), + retain: n.willRetain=="true"|| n.willRetain===true + }; + } + + // Define functions called by MQTT in and out nodes + var node = this; + this.users = {}; + + this.register = function(mqttNode) { + node.users[mqttNode.id] = mqttNode; + if (Object.keys(node.users).length === 1) { + node.connect(); + } + }; + + this.deregister = function(mqttNode,done) { + delete node.users[mqttNode.id]; + if (node.closing) { + return done(); + } + if (Object.keys(node.users).length === 0) { + if (node.client && node.client.connected) { + return node.client.end(done); + } else { + node.client.end(); + return done(); + } + } + done(); + }; + + this.connect = function () { + if (!node.connected && !node.connecting) { + node.connecting = true; + try { + node.client = mqtt.connect(node.brokerurl ,node.options); + node.client.setMaxListeners(0); + // Register successful connect or reconnect handler + node.client.on('connect', function () { + node.connecting = false; + node.connected = true; + node.log(RED._("mqtt.state.connected",{broker:(node.clientid?node.clientid+"@":"")+node.brokerurl})); + for (var id in node.users) { + if (node.users.hasOwnProperty(id)) { + node.users[id].status({fill:"green",shape:"dot",text:"node-red:common.status.connected"}); + } + } + // Remove any existing listeners before resubscribing to avoid duplicates in the event of a re-connection + node.client.removeAllListeners('message'); + + // Re-subscribe to stored topics + for (var s in node.subscriptions) { + if (node.subscriptions.hasOwnProperty(s)) { + var topic = s; + var qos = 0; + for (var r in node.subscriptions[s]) { + if (node.subscriptions[s].hasOwnProperty(r)) { + qos = Math.max(qos,node.subscriptions[s][r].qos); + node.client.on('message',node.subscriptions[s][r].handler); + } + } + var options = {qos: qos}; + node.client.subscribe(topic, options); + } + } + + // Send any birth message + if (node.birthMessage) { + node.publish(node.birthMessage); + } + }); + node.client.on("reconnect", function() { + for (var id in node.users) { + if (node.users.hasOwnProperty(id)) { + node.users[id].status({fill:"yellow",shape:"ring",text:"node-red:common.status.connecting"}); + } + } + }) + // Register disconnect handlers + node.client.on('close', function () { + if (node.connected) { + node.connected = false; + node.log(RED._("mqtt.state.disconnected",{broker:(node.clientid?node.clientid+"@":"")+node.brokerurl})); + for (var id in node.users) { + if (node.users.hasOwnProperty(id)) { + node.users[id].status({fill:"red",shape:"ring",text:"node-red:common.status.disconnected"}); + } + } + } else if (node.connecting) { + node.log(RED._("mqtt.state.connect-failed",{broker:(node.clientid?node.clientid+"@":"")+node.brokerurl})); + } + }); + + // Register connect error handler + // The client's own reconnect logic will take care of errors + node.client.on('error', function (error) {}); + }catch(err) { + console.log(err); + } + } + }; + + this.subscribe = function (topic,qos,callback,ref) { + ref = ref||0; + node.subscriptions[topic] = node.subscriptions[topic]||{}; + var sub = { + topic:topic, + qos:qos, + handler:function(mtopic,mpayload, mpacket) { + if (matchTopic(topic,mtopic)) { + callback(mtopic,mpayload, mpacket); + } + }, + ref: ref + }; + node.subscriptions[topic][ref] = sub; + if (node.connected) { + node.client.on('message',sub.handler); + var options = {}; + options.qos = qos; + node.client.subscribe(topic, options); + } + }; + + this.unsubscribe = function (topic, ref, removed) { + ref = ref||0; + var sub = node.subscriptions[topic]; + if (sub) { + if (sub[ref]) { + node.client.removeListener('message',sub[ref].handler); + delete sub[ref]; + } + if (removed) { + if (Object.keys(sub).length === 0) { + delete node.subscriptions[topic]; + if (node.connected) { + node.client.unsubscribe(topic); + } + } + } + } + }; + + this.publish = function (msg,done) { + if (node.connected) { + if (msg.payload === null || msg.payload === undefined) { + msg.payload = ""; + } else if (!Buffer.isBuffer(msg.payload)) { + if (typeof msg.payload === "object") { + msg.payload = JSON.stringify(msg.payload); + } else if (typeof msg.payload !== "string") { + msg.payload = "" + msg.payload; + } + } + + var options = { + qos: msg.qos || 0, + retain: msg.retain || false + }; + node.client.publish(msg.topic, msg.payload, options, function(err) { + done && done(); + return + }); + } + }; + + this.on('close', function(done) { + this.closing = true; + if (this.connected) { + // Send close message + if (node.closeMessage) { + node.publish(node.closeMessage); + } + this.client.once('close', function() { + done(); + }); + this.client.end(); + } else if (this.connecting || node.client.reconnecting) { + node.client.end(); + done(); + } else { + done(); + } + }); + + } + + RED.nodes.registerType("mqtt-broker",MQTTBrokerNode,{ + credentials: { + user: {type:"text"}, + password: {type: "password"} + } + }); + + function MQTTInNode(n) { + RED.nodes.createNode(this,n); + this.topic = n.topic; + this.qos = parseInt(n.qos); + if (isNaN(this.qos) || this.qos < 0 || this.qos > 2) { + this.qos = 2; + } + this.broker = n.broker; + this.brokerConn = RED.nodes.getNode(this.broker); + if (!/^(#$|(\+|[^+#]*)(\/(\+|[^+#]*))*(\/(\+|#|[^+#]*))?$)/.test(this.topic)) { + return this.warn(RED._("mqtt.errors.invalid-topic")); + } + this.datatype = n.datatype || "utf8"; + var node = this; + if (this.brokerConn) { + this.status({fill:"red",shape:"ring",text:"node-red:common.status.disconnected"}); + if (this.topic) { + node.brokerConn.register(this); + this.brokerConn.subscribe(this.topic,this.qos,function(topic,payload,packet) { + if (node.datatype === "buffer") { + // payload = payload; + } else if (node.datatype === "base64") { + payload = payload.toString('base64'); + } else if (node.datatype === "utf8") { + payload = payload.toString('utf8'); + } else if (node.datatype === "json") { + if (isUtf8(payload)) { + payload = payload.toString(); + try { payload = JSON.parse(payload); } + catch(e) { node.error(RED._("mqtt.errors.invalid-json-parse"),{payload:payload, topic:topic, qos:packet.qos, retain:packet.retain}); return; } + } + else { node.error((RED._("mqtt.errors.invalid-json-string")),{payload:payload, topic:topic, qos:packet.qos, retain:packet.retain}); return; } + } else { + if (isUtf8(payload)) { payload = payload.toString(); } + } + var msg = {topic:topic, payload:payload, qos:packet.qos, retain:packet.retain}; + if ((node.brokerConn.broker === "localhost")||(node.brokerConn.broker === "127.0.0.1")) { + msg._topic = topic; + } + node.send(msg); + }, this.id); + if (this.brokerConn.connected) { + node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"}); + } + } + else { + this.error(RED._("mqtt.errors.not-defined")); + } + this.on('close', function(removed, done) { + if (node.brokerConn) { + node.brokerConn.unsubscribe(node.topic,node.id, removed); + node.brokerConn.deregister(node,done); + } + }); + } else { + this.error(RED._("mqtt.errors.missing-config")); + } + } + RED.nodes.registerType("mqtt in",MQTTInNode); + + function MQTTOutNode(n) { + RED.nodes.createNode(this,n); + this.topic = n.topic; + this.qos = n.qos || null; + this.retain = n.retain; + this.broker = n.broker; + this.brokerConn = RED.nodes.getNode(this.broker); + var node = this; + var chk = /[\+#]/; + + if (this.brokerConn) { + this.status({fill:"red",shape:"ring",text:"node-red:common.status.disconnected"}); + this.on("input",function(msg,send,done) { + if (msg.qos) { + msg.qos = parseInt(msg.qos); + if ((msg.qos !== 0) && (msg.qos !== 1) && (msg.qos !== 2)) { + msg.qos = null; + } + } + msg.qos = Number(node.qos || msg.qos || 0); + msg.retain = node.retain || msg.retain || false; + msg.retain = ((msg.retain === true) || (msg.retain === "true")) || false; + if (node.topic) { + msg.topic = node.topic; + } + if ( msg.hasOwnProperty("payload")) { + if (msg.hasOwnProperty("topic") && (typeof msg.topic === "string") && (msg.topic !== "")) { // topic must exist + if (chk.test(msg.topic)) { node.warn(RED._("mqtt.errors.invalid-topic")); } + this.brokerConn.publish(msg, done); // send the message + } else { + node.warn(RED._("mqtt.errors.invalid-topic")); + done(); + } + } else { + done(); + } + }); + if (this.brokerConn.connected) { + node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"}); + } + node.brokerConn.register(node); + this.on('close', function(done) { + node.brokerConn.deregister(node,done); + }); + } else { + this.error(RED._("mqtt.errors.missing-config")); + } + } + RED.nodes.registerType("mqtt out",MQTTOutNode); +}; diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/21-httpin.html b/packages/connector/packages/node_modules/@node-red/nodes/core/network/21-httpin.html new file mode 100644 index 0000000..d3ab7fe --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/21-httpin.html @@ -0,0 +1,280 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-template-name="http in"> + <div class="form-row"> + <label for="node-input-method"><i class="fa fa-tasks"></i> <span data-i18n="httpin.label.method"></span></label> + <select type="text" id="node-input-method" style="width:70%;"> + <option value="get">GET</option> + <option value="post">POST</option> + <option value="put">PUT</option> + <option value="delete">DELETE</option> + <option value="patch">PATCH</option> + </select> + </div> + <div class="form-row form-row-http-in-upload hide"> + <label>&nbsp;</label> + <input type="checkbox" id="node-input-upload" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-input-upload" style="width: 70%;" data-i18n="httpin.label.upload"></label> + </div> + <div class="form-row"> + <label for="node-input-url"><i class="fa fa-globe"></i> <span data-i18n="httpin.label.url"></span></label> + <input id="node-input-url" type="text" placeholder="/url"> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-row row-swagger-doc"> + <label for="node-input-swaggerDoc"><i class="fa fa-file-text-o"></i> <span data-i18n="httpin.label.doc"></span></label> + <input type="text" id="node-input-swaggerDoc"> + </div> + <div id="node-input-tip" class="form-tips"><span data-i18n="httpin.tip.in"></span><code><span id="node-input-path"></span></code>.</div> +</script> + +<script type="text/x-red" data-template-name="http response"> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-row"> + <label for="node-input-statusCode"><i class="fa fa-long-arrow-left"></i> <span data-i18n="httpin.label.status"></span></label> + <input type="text" id="node-input-statusCode" placeholder="msg.statusCode"> + </div> + <div class="form-row" style="margin-bottom:0;"> + <label><i class="fa fa-list"></i> <span data-i18n="httpin.label.headers"></span></label> + </div> + <div class="form-row node-input-headers-container-row"> + <ol id="node-input-headers-container"></ol> + </div> + <div class="form-tips"><span data-i18n="[html]httpin.tip.res"></span></div> +</script> + +<script type="text/javascript"> +(function() { + RED.nodes.registerType('http in',{ + category: 'network', + color:"rgb(231, 231, 174)", + defaults: { + name: {value:""}, + url: {value:"",required:true}, + method: {value:"get",required:true}, + upload: {value:false}, + swaggerDoc: {type:"swagger-doc", required:false} + }, + inputs:0, + outputs:1, + icon: "white-globe.svg", + label: function() { + if (this.name) { + return this.name; + } else if (this.url) { + var root = RED.settings.httpNodeRoot; + if (root.slice(-1) != "/") { + root = root+"/"; + } + if (this.url.charAt(0) == "/") { + root += this.url.slice(1); + } else { + root += this.url; + } + return "["+this.method+"] "+root; + } else { + return "http"; + } + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + var root = RED.settings.httpNodeRoot; + if (root.slice(-1) == "/") { + root = root.slice(0,-1); + } + if (root == "") { + $("#node-input-tip").hide(); + } else { + $("#node-input-path").html(root); + $("#node-input-tip").show(); + } + if(!RED.nodes.getType("swagger-doc")){ + $('.row-swagger-doc').hide(); + } + $("#node-input-method").on("change", function() { + if ($(this).val() === "post") { + $(".form-row-http-in-upload").show(); + } else { + $(".form-row-http-in-upload").hide(); + } + }).change(); + + + } + + }); + var headerTypes = [ + {value:"content-type",label:"Content-Type",hasValue: false}, + {value:"location",label:"Location",hasValue: false}, + {value:"other",label:RED._("node-red:httpin.label.other"),icon:"red/images/typedInput/az.png"} + ] + var contentTypes = [ + {value:"application/json",label:"application/json",hasValue: false}, + {value:"application/xml",label:"application/xml",hasValue: false}, + {value:"text/css",label:"text/css",hasValue: false}, + {value:"text/html",label:"text/html",hasValue: false}, + {value:"text/plain",label:"text/plain",hasValue: false}, + {value:"image/gif",label:"image/gif",hasValue: false}, + {value:"image/png",label:"image/png",hasValue: false}, + {value:"other",label:RED._("node-red:httpin.label.other"),icon:"red/images/typedInput/az.png"} + ]; + + RED.nodes.registerType('http response',{ + category: 'network', + color:"rgb(231, 231, 174)", + defaults: { + name: {value:""}, + statusCode: {value:"",validate: RED.validators.number(true)}, + headers: {value:{}} + }, + inputs:1, + outputs:0, + align: "right", + icon: "white-globe.svg", + label: function() { + return this.name||("http"+(this.statusCode?" ("+this.statusCode+")":"")); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + function resizeRule(rule) { + var newWidth = rule.width(); + rule.find('.red-ui-typedInput').typedInput("width",(newWidth-15)/2); + } + var headerList = $("#node-input-headers-container").css('min-height','150px').css('min-width','450px').editableList({ + addItem: function(container,i,header) { + var row = $('<div/>').css({ + overflow: 'hidden', + whiteSpace: 'nowrap' + }).appendTo(container); + + var propertyName = $('<input/>',{class:"node-input-header-name",type:"text"}) + .appendTo(row) + .typedInput({types:headerTypes}); + + var propertyValue = $('<input/>',{class:"node-input-header-value",type:"text",style:"margin-left: 10px"}) + .appendTo(row) + .typedInput({types: + header.h === 'content-type'?contentTypes:[{value:"other",label:"other",icon:"red/images/typedInput/az.png"}] + }); + + var matchedType = headerTypes.filter(function(ht) { + return ht.value === header.h + }); + if (matchedType.length === 0) { + propertyName.typedInput('type','other'); + propertyName.typedInput('value',header.h); + propertyValue.typedInput('value',header.v); + } else { + propertyName.typedInput('type',header.h); + + if (header.h === "content-type") { + matchedType = contentTypes.filter(function(ct) { + return ct.value === header.v; + }); + if (matchedType.length === 0) { + propertyValue.typedInput('type','other'); + propertyValue.typedInput('value',header.v); + } else { + propertyValue.typedInput('type',header.v); + } + } else { + propertyValue.typedInput('value',header.v); + } + } + + matchedType = headerTypes.filter(function(ht) { + return ht.value === header.h + }); + if (matchedType.length === 0) { + propertyName.typedInput('type','other'); + propertyName.typedInput('value',header.h); + } else { + propertyName.typedInput('type',header.h); + } + + propertyName.on('change',function(event) { + var type = propertyName.typedInput('type'); + if (type === 'content-type') { + propertyValue.typedInput('types',contentTypes); + } else { + propertyValue.typedInput('types',[{value:"other",label:"other",icon:"red/images/typedInput/az.png"}]); + } + }); + + + + resizeRule(container); + }, + resizeItem: resizeRule, + removable: true + }); + + if (this.headers) { + for (var key in this.headers) { + if (this.headers.hasOwnProperty(key)) { + headerList.editableList('addItem',{h:key,v:this.headers[key]}); + } + } + } + }, + oneditsave: function() { + var headers = $("#node-input-headers-container").editableList('items'); + var node = this; + node.headers = {}; + headers.each(function(i) { + var header = $(this); + var keyType = header.find(".node-input-header-name").typedInput('type'); + var keyValue = header.find(".node-input-header-name").typedInput('value'); + var valueType = header.find(".node-input-header-value").typedInput('type'); + var valueValue = header.find(".node-input-header-value").typedInput('value'); + var key = keyType; + var value = valueType; + if (keyType === 'other') { + key = keyValue; + } + if (valueType === 'other') { + value = valueValue; + } + if (key !== '') { + node.headers[key] = value; + } + }); + }, + oneditresize: function(size) { + var rows = $("#dialog-form>div:not(.node-input-headers-container-row)"); + var height = size.height; + for (var i=0; i<rows.length; i++) { + height -= $(rows[i]).outerHeight(true); + } + var editorRow = $("#dialog-form>div.node-input-headers-container-row"); + height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); + + $("#node-input-headers-container").editableList('height',height); + } + }); +})(); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/21-httpin.js b/packages/connector/packages/node_modules/@node-red/nodes/core/network/21-httpin.js new file mode 100644 index 0000000..fc3fafd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/21-httpin.js @@ -0,0 +1,353 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var bodyParser = require("body-parser"); + var multer = require("multer"); + var cookieParser = require("cookie-parser"); + var getBody = require('raw-body'); + var cors = require('cors'); + var onHeaders = require('on-headers'); + var typer = require('content-type'); + var mediaTyper = require('media-typer'); + var isUtf8 = require('is-utf8'); + var hashSum = require("hash-sum"); + + function rawBodyParser(req, res, next) { + if (req.skipRawBodyParser) { next(); } // don't parse this if told to skip + if (req._body) { return next(); } + req.body = ""; + req._body = true; + + var isText = true; + var checkUTF = false; + + if (req.headers['content-type']) { + var contentType = typer.parse(req.headers['content-type']) + if (contentType.type) { + var parsedType = mediaTyper.parse(contentType.type); + if (parsedType.type === "text") { + isText = true; + } else if (parsedType.subtype === "xml" || parsedType.suffix === "xml") { + isText = true; + } else if (parsedType.type !== "application") { + isText = false; + } else if (parsedType.subtype !== "octet-stream") { + checkUTF = true; + } else { + // applicatino/octet-stream + isText = false; + } + + } + } + + getBody(req, { + length: req.headers['content-length'], + encoding: isText ? "utf8" : null + }, function (err, buf) { + if (err) { return next(err); } + if (!isText && checkUTF && isUtf8(buf)) { + buf = buf.toString() + } + req.body = buf; + next(); + }); + } + + var corsSetup = false; + + function createRequestWrapper(node,req) { + // This misses a bunch of properties (eg headers). Before we use this function + // need to ensure it captures everything documented by Express and HTTP modules. + var wrapper = { + _req: req + }; + var toWrap = [ + "param", + "get", + "is", + "acceptsCharset", + "acceptsLanguage", + "app", + "baseUrl", + "body", + "cookies", + "fresh", + "hostname", + "ip", + "ips", + "originalUrl", + "params", + "path", + "protocol", + "query", + "route", + "secure", + "signedCookies", + "stale", + "subdomains", + "xhr", + "socket" // TODO: tidy this up + ]; + toWrap.forEach(function(f) { + if (typeof req[f] === "function") { + wrapper[f] = function() { + node.warn(RED._("httpin.errors.deprecated-call",{method:"msg.req."+f})); + var result = req[f].apply(req,arguments); + if (result === req) { + return wrapper; + } else { + return result; + } + } + } else { + wrapper[f] = req[f]; + } + }); + + + return wrapper; + } + function createResponseWrapper(node,res) { + var wrapper = { + _res: res + }; + var toWrap = [ + "append", + "attachment", + "cookie", + "clearCookie", + "download", + "end", + "format", + "get", + "json", + "jsonp", + "links", + "location", + "redirect", + "render", + "send", + "sendfile", + "sendFile", + "sendStatus", + "set", + "status", + "type", + "vary" + ]; + toWrap.forEach(function(f) { + wrapper[f] = function() { + node.warn(RED._("httpin.errors.deprecated-call",{method:"msg.res."+f})); + var result = res[f].apply(res,arguments); + if (result === res) { + return wrapper; + } else { + return result; + } + } + }); + return wrapper; + } + + var corsHandler = function(req,res,next) { next(); } + + if (RED.settings.httpNodeCors) { + corsHandler = cors(RED.settings.httpNodeCors); + RED.httpNode.options("*",corsHandler); + } + + function HTTPIn(n) { + RED.nodes.createNode(this,n); + if (RED.settings.httpNodeRoot !== false) { + + if (!n.url) { + this.warn(RED._("httpin.errors.missing-path")); + return; + } + this.url = n.url; + if (this.url[0] !== '/') { + this.url = '/'+this.url; + } + this.method = n.method; + this.upload = n.upload; + this.swaggerDoc = n.swaggerDoc; + + var node = this; + + this.errorHandler = function(err,req,res,next) { + node.warn(err); + res.sendStatus(500); + }; + + this.callback = function(req,res) { + var msgid = RED.util.generateId(); + res._msgid = msgid; + if (node.method.match(/^(post|delete|put|options|patch)$/)) { + node.send({_msgid:msgid,req:req,res:createResponseWrapper(node,res),payload:req.body}); + } else if (node.method == "get") { + node.send({_msgid:msgid,req:req,res:createResponseWrapper(node,res),payload:req.query}); + } else { + node.send({_msgid:msgid,req:req,res:createResponseWrapper(node,res)}); + } + }; + + var httpMiddleware = function(req,res,next) { next(); } + + if (RED.settings.httpNodeMiddleware) { + if (typeof RED.settings.httpNodeMiddleware === "function") { + httpMiddleware = RED.settings.httpNodeMiddleware; + } + } + + var maxApiRequestSize = RED.settings.apiMaxLength || '5mb'; + var jsonParser = bodyParser.json({limit:maxApiRequestSize}); + var urlencParser = bodyParser.urlencoded({limit:maxApiRequestSize,extended:true}); + + var metricsHandler = function(req,res,next) { next(); } + if (this.metric()) { + metricsHandler = function(req, res, next) { + var startAt = process.hrtime(); + onHeaders(res, function() { + if (res._msgid) { + var diff = process.hrtime(startAt); + var ms = diff[0] * 1e3 + diff[1] * 1e-6; + var metricResponseTime = ms.toFixed(3); + var metricContentLength = res._headers["content-length"]; + //assuming that _id has been set for res._metrics in HttpOut node! + node.metric("response.time.millis", {_msgid:res._msgid} , metricResponseTime); + node.metric("response.content-length.bytes", {_msgid:res._msgid} , metricContentLength); + } + }); + next(); + }; + } + + var multipartParser = function(req,res,next) { next(); } + if (this.upload) { + var mp = multer({ storage: multer.memoryStorage() }).any(); + multipartParser = function(req,res,next) { + mp(req,res,function(err) { + req._body = true; + next(err); + }) + }; + } + + if (this.method == "get") { + RED.httpNode.get(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,this.callback,this.errorHandler); + } else if (this.method == "post") { + RED.httpNode.post(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,jsonParser,urlencParser,multipartParser,rawBodyParser,this.callback,this.errorHandler); + } else if (this.method == "put") { + RED.httpNode.put(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,jsonParser,urlencParser,rawBodyParser,this.callback,this.errorHandler); + } else if (this.method == "patch") { + RED.httpNode.patch(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,jsonParser,urlencParser,rawBodyParser,this.callback,this.errorHandler); + } else if (this.method == "delete") { + RED.httpNode.delete(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,jsonParser,urlencParser,rawBodyParser,this.callback,this.errorHandler); + } + + this.on("close",function() { + var node = this; + RED.httpNode._router.stack.forEach(function(route,i,routes) { + if (route.route && route.route.path === node.url && route.route.methods[node.method]) { + routes.splice(i,1); + } + }); + }); + } else { + this.warn(RED._("httpin.errors.not-created")); + } + } + RED.nodes.registerType("http in",HTTPIn); + + + function HTTPOut(n) { + RED.nodes.createNode(this,n); + var node = this; + this.headers = n.headers||{}; + this.statusCode = n.statusCode; + this.on("input",function(msg) { + if (msg.res) { + var headers = RED.util.cloneMessage(node.headers); + if (msg.headers) { + if (msg.headers.hasOwnProperty('x-node-red-request-node')) { + var headerHash = msg.headers['x-node-red-request-node']; + delete msg.headers['x-node-red-request-node']; + var hash = hashSum(msg.headers); + if (hash === headerHash) { + delete msg.headers; + } + } + if (msg.headers) { + for (var h in msg.headers) { + if (msg.headers.hasOwnProperty(h) && !headers.hasOwnProperty(h)) { + headers[h] = msg.headers[h]; + } + } + } + } + if (Object.keys(headers).length > 0) { + msg.res._res.set(headers); + } + if (msg.cookies) { + for (var name in msg.cookies) { + if (msg.cookies.hasOwnProperty(name)) { + if (msg.cookies[name] === null || msg.cookies[name].value === null) { + if (msg.cookies[name]!==null) { + msg.res._res.clearCookie(name,msg.cookies[name]); + } else { + msg.res._res.clearCookie(name); + } + } else if (typeof msg.cookies[name] === 'object') { + msg.res._res.cookie(name,msg.cookies[name].value,msg.cookies[name]); + } else { + msg.res._res.cookie(name,msg.cookies[name]); + } + } + } + } + var statusCode = node.statusCode || msg.statusCode || 200; + if (typeof msg.payload == "object" && !Buffer.isBuffer(msg.payload)) { + msg.res._res.status(statusCode).jsonp(msg.payload); + } else { + if (msg.res._res.get('content-length') == null) { + var len; + if (msg.payload == null) { + len = 0; + } else if (Buffer.isBuffer(msg.payload)) { + len = msg.payload.length; + } else if (typeof msg.payload == "number") { + len = Buffer.byteLength(""+msg.payload); + } else { + len = Buffer.byteLength(msg.payload); + } + msg.res._res.set('content-length', len); + } + + if (typeof msg.payload === "number") { + msg.payload = ""+msg.payload; + } + msg.res._res.status(statusCode).send(msg.payload); + } + } else { + node.warn(RED._("httpin.errors.no-response")); + } + }); + } + RED.nodes.registerType("http response",HTTPOut); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/21-httprequest.html b/packages/connector/packages/node_modules/@node-red/nodes/core/network/21-httprequest.html new file mode 100644 index 0000000..03106dc --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/21-httprequest.html @@ -0,0 +1,231 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-template-name="http request"> + <div class="form-row"> + <label for="node-input-method"><i class="fa fa-tasks"></i> <span data-i18n="httpin.label.method"></span></label> + <select type="text" id="node-input-method" style="width:70%;"> + <option value="GET">GET</option> + <option value="POST">POST</option> + <option value="PUT">PUT</option> + <option value="DELETE">DELETE</option> + <option value="HEAD">HEAD</option> + <option value="use" data-i18n="httpin.setby"></option> + </select> + </div> + + <div class="form-row"> + <label for="node-input-url"><i class="fa fa-globe"></i> <span data-i18n="httpin.label.url"></span></label> + <input id="node-input-url" type="text" placeholder="http://"> + </div> + + <div class="form-row node-input-paytoqs-row"> + <input type="checkbox" id="node-input-paytoqs" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-input-paytoqs" style="width: auto" data-i18n="httpin.label.paytoqs"></label> + </div> + + <div class="form-row"> + <input type="checkbox" id="node-input-usetls" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-input-usetls" style="width: auto" data-i18n="httpin.use-tls"></label> + <div id="node-row-tls" class="hide"> + <label style="width: auto; margin-left: 20px; margin-right: 10px;" for="node-input-tls"><span data-i18n="httpin.tls-config"></span></label><input type="text" style="width: 300px" id="node-input-tls"> + </div> + </div> + + <div class="form-row"> + <input type="checkbox" id="node-input-useAuth" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-input-useAuth" style="width: 70%;"><span data-i18n="httpin.basicauth"></span></label> + <div style="margin-left: 20px" class="node-input-useAuth-row hide"> + <div class="form-row"> + <label for="node-input-authType-select"><i class="fa fa-user-secret "></i> <span data-i18n="httpin.label.authType"></span></label> + <select type="text" id="node-input-authType-select" style="width:70%;"> + <option value="basic" data-i18n="httpin.basic"></option> + <option value="digest" data-i18n="httpin.digest"></option> + <option value="bearer" data-i18n="httpin.bearer"></option> + </select> + <input type="hidden" id="node-input-authType"> + </div> + <div class="form-row node-input-basic-row"> + <label for="node-input-user"><i class="fa fa-user"></i> <span data-i18n="common.label.username"></span></label> + <input type="text" id="node-input-user"> + </div> + <div class="form-row"> + <label for="node-input-password"> <i class="fa fa-lock"></i> <span data-i18n="common.label.password" id="node-span-password"></span><span data-i18n="httpin.label.bearerToken" id="node-span-token" style="display:none"></span></label> + <input type="password" id="node-input-password"> + </div> + </div> + </div> + + <div class="form-row"> + <input type="checkbox" id="node-input-persist" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-input-persist" style="width: auto" data-i18n="httpin.persist"></label> + </div> + + <div class="form-row"> + <input type="checkbox" id="node-input-useProxy" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-input-useProxy" style="width: auto;"><span data-i18n="httpin.use-proxy"></span></label> + <div id="node-input-useProxy-row" class="hide"> + <label style="width: auto; margin-left: 20px; margin-right: 10px;" for="node-input-proxy"><i class="fa fa-globe"></i> <span data-i18n="httpin.proxy-config"></span></label><input type="text" style="width: 270px" id="node-input-proxy"> + </div> + </div> + + <div class="form-row"> + <label for="node-input-ret"><i class="fa fa-arrow-left"></i> <span data-i18n="httpin.label.return"></span></label> + <select type="text" id="node-input-ret" style="width:70%;"> + <option value="txt" data-i18n="httpin.utf8"></option> + <option value="bin" data-i18n="httpin.binary"></option> + <option value="obj" data-i18n="httpin.json"></option> + </select> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-tips" id="tip-json" hidden><span data-i18n="httpin.tip.req"></span></div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('http request',{ + category: 'network', + color:"rgb(231, 231, 174)", + defaults: { + name: {value:""}, + method:{value:"GET"}, + ret: {value:"txt"}, + paytoqs: {value: false}, + url:{value:"",validate:function(v) { return (v.trim().length === 0) || (v.indexOf("://") === -1) || (v.trim().indexOf("http") === 0)} }, + tls: {type:"tls-config",required: false}, + persist: {value:false}, + proxy: {type:"http proxy",required: false}, + authType: {value: ""} + }, + credentials: { + user: {type:"text"}, + password: {type: "password"} + }, + inputs:1, + outputs:1, + outputLabels: function(i) { + return ({ + txt: this._("httpin.label.utf8String"), + bin: this._("httpin.label.binaryBuffer"), + obj: this._("httpin.label.jsonObject") + }[this.ret]); + }, + icon: "white-globe.svg", + label: function() { + return this.name||this._("httpin.httpreq"); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + $("#node-input-useAuth").on("change", function() { + if ($(this).is(":checked")) { + $(".node-input-useAuth-row").show(); + // Nodes (< version 0.20.x) with credentials but without authentication type, need type 'basic' + if (!$('#node-input-authType').val()) { + $("#node-input-authType-select").val('basic').trigger("change"); + } + } else { + $(".node-input-useAuth-row").hide(); + $('#node-input-authType').val(''); + $('#node-input-user').val(''); + $('#node-input-password').val(''); + } + }); + $("#node-input-authType-select").on("change", function() { + var val = $(this).val(); + $("#node-input-authType").val(val); + if (val === "basic" || val === "digest") { + $(".node-input-basic-row").show(); + $('#node-span-password').show(); + $('#node-span-token').hide(); + } else if (val === "bearer") { + $(".node-input-basic-row").hide(); + $('#node-span-password').hide(); + $('#node-span-token').show(); + $('#node-input-user').val(''); + } + }); + $("#node-input-method").on("change", function() { + if ($(this).val() == "GET") { + $(".node-input-paytoqs-row").show(); + } else { + $(".node-input-paytoqs-row").hide(); + } + }); + if (this.authType) { + $('#node-input-useAuth').prop('checked', true); + $("#node-input-authType-select").val(this.authType); + $("#node-input-authType-select").change(); + } else { + $('#node-input-useAuth').prop('checked', false); + } + $("#node-input-useAuth").change(); + + function updateTLSOptions() { + if ($("#node-input-usetls").is(':checked')) { + $("#node-row-tls").show(); + } else { + $("#node-row-tls").hide(); + } + } + if (this.tls) { + $('#node-input-usetls').prop('checked', true); + } else { + $('#node-input-usetls').prop('checked', false); + } + updateTLSOptions(); + $("#node-input-usetls").on("click",function() { + updateTLSOptions(); + }); + + function updateProxyOptions() { + if ($("#node-input-useProxy").is(":checked")) { + $("#node-input-useProxy-row").show(); + } else { + $("#node-input-useProxy-row").hide(); + } + } + if (this.proxy) { + $("#node-input-useProxy").prop("checked", true); + } else { + $("#node-input-useProxy").prop("checked", false); + } + updateProxyOptions(); + $("#node-input-useProxy").on("click", function() { + updateProxyOptions(); + }); + + $("#node-input-ret").on("change", function() { + if ($("#node-input-ret").val() === "obj") { + $("#tip-json").show(); + } else { + $("#tip-json").hide(); + } + }); + }, + oneditsave: function() { + if (!$("#node-input-usetls").is(':checked')) { + $("#node-input-tls").val("_ADD_"); + } + if (!$("#node-input-useProxy").is(":checked")) { + $("#node-input-proxy").val("_ADD_"); + } + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js b/packages/connector/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js new file mode 100644 index 0000000..4c39f9f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js @@ -0,0 +1,400 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var request = require("request"); + var mustache = require("mustache"); + var querystring = require("querystring"); + var cookie = require("cookie"); + var hashSum = require("hash-sum"); + + function HTTPRequest(n) { + RED.nodes.createNode(this,n); + var node = this; + var nodeUrl = n.url; + var isTemplatedUrl = (nodeUrl||"").indexOf("{{") != -1; + var nodeMethod = n.method || "GET"; + var paytoqs = n.paytoqs; + var nodeHTTPPersistent = n["persist"]; + if (n.tls) { + var tlsNode = RED.nodes.getNode(n.tls); + } + this.ret = n.ret || "txt"; + this.authType = n.authType || "basic"; + if (RED.settings.httpRequestTimeout) { this.reqTimeout = parseInt(RED.settings.httpRequestTimeout) || 120000; } + else { this.reqTimeout = 120000; } + + var prox, noprox; + if (process.env.http_proxy) { prox = process.env.http_proxy; } + if (process.env.HTTP_PROXY) { prox = process.env.HTTP_PROXY; } + if (process.env.no_proxy) { noprox = process.env.no_proxy.split(","); } + if (process.env.NO_PROXY) { noprox = process.env.NO_PROXY.split(","); } + + var proxyConfig = null; + if (n.proxy) { + proxyConfig = RED.nodes.getNode(n.proxy); + prox = proxyConfig.url; + noprox = proxyConfig.noproxy; + } + + this.on("input",function(msg,nodeSend,nodeDone) { + var preRequestTimestamp = process.hrtime(); + node.status({fill:"blue",shape:"dot",text:"httpin.status.requesting"}); + var url = nodeUrl || msg.url; + if (msg.url && nodeUrl && (nodeUrl !== msg.url)) { // revert change below when warning is finally removed + node.warn(RED._("common.errors.nooverride")); + } + if (isTemplatedUrl) { + url = mustache.render(nodeUrl,msg); + } + if (!url) { + node.error(RED._("httpin.errors.no-url"),msg); + nodeDone(); + return; + } + // url must start http:// or https:// so assume http:// if not set + if (url.indexOf("://") !== -1 && url.indexOf("http") !== 0) { + node.warn(RED._("httpin.errors.invalid-transport")); + node.status({fill:"red",shape:"ring",text:"httpin.errors.invalid-transport"}); + nodeDone(); + return; + } + if (!((url.indexOf("http://") === 0) || (url.indexOf("https://") === 0))) { + if (tlsNode) { + url = "https://"+url; + } else { + url = "http://"+url; + } + } + + var method = nodeMethod.toUpperCase() || "GET"; + if (msg.method && n.method && (n.method !== "use")) { // warn if override option not set + node.warn(RED._("common.errors.nooverride")); + } + if (msg.method && n.method && (n.method === "use")) { + method = msg.method.toUpperCase(); // use the msg parameter + } + + var isHttps = (/^https/i.test(url)); + + var opts = {}; + opts.url = url; + // set defaultport, else when using HttpsProxyAgent, it's defaultPort of 443 will be used :(. + opts.defaultPort = isHttps?443:80; + opts.timeout = node.reqTimeout; + opts.method = method; + opts.headers = {}; + opts.encoding = null; // Force NodeJs to return a Buffer (instead of a string) + opts.maxRedirects = 21; + opts.jar = request.jar(); + opts.proxy = null; + opts.forever = nodeHTTPPersistent; + if (msg.requestTimeout !== undefined) { + if (isNaN(msg.requestTimeout)) { + node.warn(RED._("httpin.errors.timeout-isnan")); + } else if (msg.requestTimeout < 1) { + node.warn(RED._("httpin.errors.timeout-isnegative")); + } else { + opts.timeout = msg.requestTimeout; + } + } + var ctSet = "Content-Type"; // set default camel case + var clSet = "Content-Length"; + if (msg.headers) { + if (msg.headers.hasOwnProperty('x-node-red-request-node')) { + var headerHash = msg.headers['x-node-red-request-node']; + delete msg.headers['x-node-red-request-node']; + var hash = hashSum(msg.headers); + if (hash === headerHash) { + delete msg.headers; + } + } + if (msg.headers) { + for (var v in msg.headers) { + if (msg.headers.hasOwnProperty(v)) { + var name = v.toLowerCase(); + if (name !== "content-type" && name !== "content-length") { + // only normalise the known headers used later in this + // function. Otherwise leave them alone. + name = v; + } + else if (name === 'content-type') { ctSet = v; } + else { clSet = v; } + opts.headers[name] = msg.headers[v]; + } + } + } + } + if (msg.hasOwnProperty('followRedirects')) { + opts.followRedirect = msg.followRedirects; + } + var redirectList = []; + if (!opts.hasOwnProperty('followRedirect') || opts.followRedirect) { + opts.followRedirect = function(res) { + var redirectInfo = { + location: res.headers.location, + }; + if (res.headers.hasOwnProperty('set-cookie')) { + redirectInfo.cookies = extractCookies(res.headers['set-cookie']); + } + redirectList.push(redirectInfo); + if (this.headers.cookie) { + delete this.headers.cookie; + } + return true; + }; + } + if (opts.headers.hasOwnProperty('cookie')) { + var cookies = cookie.parse(opts.headers.cookie, {decode:String}); + for (var name in cookies) { + opts.jar.setCookie(cookie.serialize(name, cookies[name], {encode:String}), url); + } + delete opts.headers.cookie; + } + if (msg.cookies) { + for (var name in msg.cookies) { + if (msg.cookies.hasOwnProperty(name)) { + if (msg.cookies[name] === null || msg.cookies[name].value === null) { + // This case clears a cookie for HTTP In/Response nodes. + // Ignore for this node. + } else if (typeof msg.cookies[name] === 'object') { + if(msg.cookies[name].encode === false){ + // If the encode option is false, the value is not encoded. + opts.jar.setCookie(cookie.serialize(name, msg.cookies[name].value, {encode: String}), url); + } else { + // The value is encoded by encodeURIComponent(). + opts.jar.setCookie(cookie.serialize(name, msg.cookies[name].value), url); + } + } else { + opts.jar.setCookie(cookie.serialize(name, msg.cookies[name]), url); + } + } + } + } + if (this.credentials) { + if (this.authType === "basic") { + if (this.credentials.user) { + opts.auth = { + user: this.credentials.user, + pass: this.credentials.password || "" + }; + } + } else if (this.authType === "digest") { + if (this.credentials.user) { + // The first request will be sent without auth information. Based on the 401 response, the library can determine + // which auth type is required by the server. Then the request is resubmitted with the appropriate auth header. + opts.auth = { + user: this.credentials.user, + pass: this.credentials.password || "", + sendImmediately: false + }; + } + } else if (this.authType === "bearer") { + opts.auth = { + bearer: this.credentials.password || "" + }; + } + } + var payload = null; + + if (method !== 'GET' && method !== 'HEAD' && typeof msg.payload !== "undefined") { + if (opts.headers['content-type'] == 'multipart/form-data' && typeof msg.payload === "object") { + opts.formData = {}; + + for (var opt in msg.payload) { + if (msg.payload.hasOwnProperty(opt)) { + var val = msg.payload[opt]; + if (val !== undefined && val !== null) { + if (typeof val === 'string' || Buffer.isBuffer(val)) { + opts.formData[opt] = val; + } else if (typeof val === 'object' && val.hasOwnProperty('value')) { + // Treat as file to upload - ensure it has an options object + // as request complains if it doesn't + if (!val.hasOwnProperty('options')) { + val.options = {}; + } + opts.formData[opt] = val; + } else { + opts.formData[opt] = JSON.stringify(val); + } + } + } + } + } else { + if (typeof msg.payload === "string" || Buffer.isBuffer(msg.payload)) { + payload = msg.payload; + } else if (typeof msg.payload == "number") { + payload = msg.payload+""; + } else { + if (opts.headers['content-type'] == 'application/x-www-form-urlencoded') { + payload = querystring.stringify(msg.payload); + } else { + payload = JSON.stringify(msg.payload); + if (opts.headers['content-type'] == null) { + opts.headers[ctSet] = "application/json"; + } + } + } + if (opts.headers['content-length'] == null) { + if (Buffer.isBuffer(payload)) { + opts.headers[clSet] = payload.length; + } else { + opts.headers[clSet] = Buffer.byteLength(payload); + } + } + opts.body = payload; + } + } + + if (method == 'GET' && typeof msg.payload !== "undefined" && paytoqs) { + if (typeof msg.payload === "object") { + try { + if (opts.url.indexOf("?") !== -1) { + opts.url += (opts.url.endsWith("?")?"":"&") + querystring.stringify(msg.payload); + } else { + opts.url += "?" + querystring.stringify(msg.payload); + } + } catch(err) { + node.error(RED._("httpin.errors.invalid-payload"),msg); + nodeDone(); + return; + } + } else { + node.error(RED._("httpin.errors.invalid-payload"),msg); + nodeDone(); + return; + } + } + + // revert to user supplied Capitalisation if needed. + if (opts.headers.hasOwnProperty('content-type') && (ctSet !== 'content-type')) { + opts.headers[ctSet] = opts.headers['content-type']; + delete opts.headers['content-type']; + } + if (opts.headers.hasOwnProperty('content-length') && (clSet !== 'content-length')) { + opts.headers[clSet] = opts.headers['content-length']; + delete opts.headers['content-length']; + } + + var noproxy; + if (noprox) { + for (var i = 0; i < noprox.length; i += 1) { + if (url.indexOf(noprox[i]) !== -1) { noproxy=true; } + } + } + if (prox && !noproxy) { + var match = prox.match(/^(http:\/\/)?(.+)?:([0-9]+)?/i); + if (match) { + opts.proxy = prox; + } else { + node.warn("Bad proxy url: "+ prox); + opts.proxy = null; + } + } + if (proxyConfig && proxyConfig.credentials && opts.proxy == proxyConfig.url) { + var proxyUsername = proxyConfig.credentials.username || ''; + var proxyPassword = proxyConfig.credentials.password || ''; + if (proxyUsername || proxyPassword) { + opts.headers['proxy-authorization'] = + 'Basic ' + + Buffer.from(proxyUsername + ':' + proxyPassword).toString('base64'); + } + } + if (tlsNode) { + tlsNode.addTLSOptions(opts); + } else { + if (msg.hasOwnProperty('rejectUnauthorized')) { + opts.rejectUnauthorized = msg.rejectUnauthorized; + } + } + request(opts, function(err, res, body) { + if(err){ + if(err.code === 'ETIMEDOUT' || err.code === 'ESOCKETTIMEDOUT') { + node.error(RED._("common.notification.errors.no-response"), msg); + node.status({fill:"red", shape:"ring", text:"common.notification.errors.no-response"}); + }else{ + node.error(err,msg); + node.status({fill:"red", shape:"ring", text:err.code}); + } + msg.payload = err.toString() + " : " + url; + msg.statusCode = err.code; + nodeSend(msg); + nodeDone(); + }else{ + msg.statusCode = res.statusCode; + msg.headers = res.headers; + msg.responseUrl = res.request.uri.href; + msg.payload = body; + msg.redirectList = redirectList; + + if (msg.headers.hasOwnProperty('set-cookie')) { + msg.responseCookies = extractCookies(msg.headers['set-cookie']); + } + msg.headers['x-node-red-request-node'] = hashSum(msg.headers); + // msg.url = url; // revert when warning above finally removed + if (node.metric()) { + // Calculate request time + var diff = process.hrtime(preRequestTimestamp); + var ms = diff[0] * 1e3 + diff[1] * 1e-6; + var metricRequestDurationMillis = ms.toFixed(3); + node.metric("duration.millis", msg, metricRequestDurationMillis); + if (res.client && res.client.bytesRead) { + node.metric("size.bytes", msg, res.client.bytesRead); + } + } + + // Convert the payload to the required return type + if (node.ret !== "bin") { + msg.payload = msg.payload.toString('utf8'); // txt + + if (node.ret === "obj") { + try { msg.payload = JSON.parse(msg.payload); } // obj + catch(e) { node.warn(RED._("httpin.errors.json-error")); } + } + } + node.status({}); + nodeSend(msg); + nodeDone(); + } + }); + }); + + this.on("close",function() { + node.status({}); + }); + + function extractCookies(setCookie) { + var cookies = {}; + setCookie.forEach(function(c) { + var parsedCookie = cookie.parse(c); + var eq_idx = c.indexOf('='); + var key = c.substr(0, eq_idx).trim() + parsedCookie.value = parsedCookie[key]; + delete parsedCookie[key]; + cookies[key] = parsedCookie; + }); + return cookies; + } + } + + RED.nodes.registerType("http request",HTTPRequest,{ + credentials: { + user: {type:"text"}, + password: {type: "password"} + } + }); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/22-websocket.html b/packages/connector/packages/node_modules/@node-red/nodes/core/network/22-websocket.html new file mode 100644 index 0000000..4e62cb9 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/22-websocket.html @@ -0,0 +1,264 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- WebSocket Input Node --> +<script type="text/x-red" data-template-name="websocket in"> + <div class="form-row"> + <label for="node-input-mode"><i class="fa fa-dot-circle-o"></i> <span data-i18n="websocket.label.type"></span></label> + <select id="node-input-mode"> + <option value="server" data-i18n="websocket.listenon"></option> + <option value="client" data-i18n="websocket.connectto"></option> + </select> + </div> + <div class="form-row" id="websocket-server-row"> + <label for="node-input-server"><i class="fa fa-bookmark"></i> <span data-i18n="websocket.label.path"></span></label> + <input type="text" id="node-input-server"> + </div> + <div class="form-row" id="websocket-client-row"> + <label for="node-input-client"><i class="fa fa-bookmark"></i> <span data-i18n="websocket.label.url"></span></label> + <input type="text" id="node-input-client"> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> + +<script type="text/javascript"> + +(function() { + + function ws_oneditprepare() { + $("#websocket-client-row").hide(); + $("#node-input-mode").on("change", function() { + if ( $("#node-input-mode").val() === 'client') { + $("#websocket-server-row").hide(); + $("#websocket-client-row").show(); + } + else { + $("#websocket-server-row").show(); + $("#websocket-client-row").hide(); + } + }); + + if (this.client) { + $("#node-input-mode").val('client').change(); + } + else { + $("#node-input-mode").val('server').change(); + } + } + + function ws_oneditsave() { + if ($("#node-input-mode").val() === 'client') { + $("#node-input-server").append('<option value="">Dummy</option>'); + $("#node-input-server").val(''); + } + else { + $("#node-input-client").append('<option value="">Dummy</option>'); + $("#node-input-client").val(''); + } + } + + function ws_label() { + var nodeid = (this.client)?this.client:this.server; + var wsNode = RED.nodes.node(nodeid); + return this.name||(wsNode?"[ws] "+wsNode.label():"websocket"); + } + + function ws_validateserver() { + if ($("#node-input-mode").val() === 'client' || (this.client && !this.server)) { + return true; + } + else { + return RED.nodes.node(this.server) != null; + } + } + + function ws_validateclient() { + if ($("#node-input-mode").val() === 'client' || (this.client && !this.server)) { + return RED.nodes.node(this.client) != null; + } + else { + return true; + } + } + + RED.nodes.registerType('websocket in',{ + category: 'network', + defaults: { + name: {value:""}, + server: {type:"websocket-listener", validate: ws_validateserver}, + client: {type:"websocket-client", validate: ws_validateclient} + }, + color:"rgb(215, 215, 160)", + inputs:0, + outputs:1, + icon: "white-globe.svg", + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + label: ws_label, + oneditsave: ws_oneditsave, + oneditprepare: ws_oneditprepare + }); + + RED.nodes.registerType('websocket out',{ + category: 'network', + defaults: { + name: {value:""}, + server: {type:"websocket-listener", validate: ws_validateserver}, + client: {type:"websocket-client", validate: ws_validateclient} + }, + color:"rgb(215, 215, 160)", + inputs:1, + outputs:0, + icon: "white-globe.svg", + align: "right", + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + label: ws_label, + oneditsave: ws_oneditsave, + oneditprepare: ws_oneditprepare + }); + + RED.nodes.registerType('websocket-listener',{ + category: 'config', + defaults: { + path: {value:"",required:true,validate:RED.validators.regex(/^((?!\/debug\/ws).)*$/)}, + wholemsg: {value:"false"} + }, + inputs:0, + outputs:0, + label: function() { + var root = RED.settings.httpNodeRoot; + if (root.slice(-1) != "/") { + root = root+"/"; + } + if (this.path.charAt(0) == "/") { + root += this.path.slice(1); + } else { + root += this.path; + } + return root; + }, + oneditprepare: function() { + var root = RED.settings.httpNodeRoot; + if (root.slice(-1) == "/") { + root = root.slice(0,-1); + } + if (root === "") { + $("#node-config-ws-tip").hide(); + } else { + $("#node-config-ws-path").html(root); + $("#node-config-ws-tip").show(); + } + } + }); + + RED.nodes.registerType('websocket-client',{ + category: 'config', + defaults: { + path: {value:"",required:true,validate:RED.validators.regex(/^((?!\/debug\/ws).)*$/)}, + tls: {type:"tls-config",required: false}, + wholemsg: {value:"false"} + }, + inputs:0, + outputs:0, + label: function() { + return this.path; + }, + oneditprepare: function() { + $("#node-config-input-path").on("change keyup paste",function() { + $(".node-config-row-tls").toggle(/^wss:/i.test($(this).val())) + }); + $("#node-config-input-path").change(); + }, + oneditsave: function() { + if (!/^wss:/i.test($("#node-config-input-path").val())) { + $("#node-config-input-tls").val("_ADD_"); + } + } + }); + +})(); +</script> + +<!-- WebSocket out Node --> +<script type="text/x-red" data-template-name="websocket out"> + <div class="form-row"> + <label for="node-input-mode"><i class="fa fa-dot-circle-o"></i> <span data-i18n="websocket.label.type"></span></label> + <select id="node-input-mode"> + <option value="server" data-i18n="websocket.listenon"></option> + <option value="client" data-i18n="websocket.connectto"></option> + </select> + </div> + <div class="form-row" id="websocket-server-row"> + <label for="node-input-server"><i class="fa fa-bookmark"></i> <span data-i18n="websocket.label.path"></span></label> + <input type="text" id="node-input-server"> + </div> + <div class="form-row" id="websocket-client-row"> + <label for="node-input-client"><i class="fa fa-bookmark"></i> <span data-i18n="websocket.label.url"></span></label> + <input type="text" id="node-input-client"> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> + +<!-- WebSocket Server configuration node --> +<script type="text/x-red" data-template-name="websocket-listener"> + <div class="form-row"> + <label for="node-config-input-path"><i class="fa fa-bookmark"></i> <span data-i18n="websocket.label.path"></span></label> + <input id="node-config-input-path" type="text" placeholder="/ws/example"> + </div> + <div class="form-row"> + <label for="node-config-input-wholemsg" data-i18n="websocket.sendrec"></label> + <select type="text" id="node-config-input-wholemsg" style="width: 70%;"> + <option value="false" data-i18n="websocket.payload"></option> + <option value="true" data-i18n="websocket.message"></option> + </select> + </div> + <div class="form-tips"> + <span data-i18n="[html]websocket.tip.path1"></span> + <p id="node-config-ws-tip"><span data-i18n="[html]websocket.tip.path2"></span><code><span id="node-config-ws-path"></span></code>.</p> + </div> +</script> + +<!-- WebSocket Client configuration node --> +<script type="text/x-red" data-template-name="websocket-client"> + <div class="form-row"> + <label for="node-config-input-path"><i class="fa fa-bookmark"></i> <span data-i18n="websocket.label.url"></span></label> + <input id="node-config-input-path" type="text" placeholder="ws://example.com/ws"> + </div> + <div class="form-row node-config-row-tls hide"> + <label for="node-config-input-tls" data-i18n="httpin.tls-config"></label> + <input type="text" id="node-config-input-tls"> + </div> + + <div class="form-row"> + <label for="node-config-input-wholemsg" data-i18n="websocket.sendrec"></label> + <select type="text" id="node-config-input-wholemsg" style="width: 70%;"> + <option value="false" data-i18n="websocket.payload"></option> + <option value="true" data-i18n="websocket.message"></option> + </select> + </div> + <div class="form-tips"> + <p><span data-i18n="[html]websocket.tip.url1"></span></p> + <span data-i18n="[html]websocket.tip.url2"></span> + </div> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/22-websocket.js b/packages/connector/packages/node_modules/@node-red/nodes/core/network/22-websocket.js new file mode 100644 index 0000000..315f3ca --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/22-websocket.js @@ -0,0 +1,370 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var ws = require("ws"); + var inspect = require("util").inspect; + var url = require("url"); + var HttpsProxyAgent = require('https-proxy-agent'); + + + var serverUpgradeAdded = false; + function handleServerUpgrade(request, socket, head) { + const pathname = url.parse(request.url).pathname; + if (listenerNodes.hasOwnProperty(pathname)) { + listenerNodes[pathname].server.handleUpgrade(request, socket, head, function done(ws) { + listenerNodes[pathname].server.emit('connection', ws, request); + }); + } else { + // Don't destroy the socket as other listeners may want to handle the + // event. + } + } + var listenerNodes = {}; + var activeListenerNodes = 0; + + + // A node red node that sets up a local websocket server + function WebSocketListenerNode(n) { + // Create a RED node + RED.nodes.createNode(this,n); + var node = this; + + // Store local copies of the node configuration (as defined in the .html) + node.path = n.path; + node.wholemsg = (n.wholemsg === "true"); + + node._inputNodes = []; // collection of nodes that want to receive events + node._clients = {}; + // match absolute url + node.isServer = !/^ws{1,2}:\/\//i.test(node.path); + node.closing = false; + node.tls = n.tls; + + function startconn() { // Connect to remote endpoint + node.tout = null; + var prox, noprox; + if (process.env.http_proxy) { prox = process.env.http_proxy; } + if (process.env.HTTP_PROXY) { prox = process.env.HTTP_PROXY; } + if (process.env.no_proxy) { noprox = process.env.no_proxy.split(","); } + if (process.env.NO_PROXY) { noprox = process.env.NO_PROXY.split(","); } + + var noproxy = false; + if (noprox) { + for (var i in noprox) { + if (node.path.indexOf(noprox[i].trim()) !== -1) { noproxy=true; } + } + } + + var agent = undefined; + if (prox && !noproxy) { + agent = new HttpsProxyAgent(prox); + } + + var options = {}; + if (agent) { + options.agent = agent; + } + if (node.tls) { + var tlsNode = RED.nodes.getNode(node.tls); + if (tlsNode) { + tlsNode.addTLSOptions(options); + } + } + var socket = new ws(node.path,options); + socket.setMaxListeners(0); + node.server = socket; // keep for closing + handleConnection(socket); + } + + function handleConnection(/*socket*/socket) { + var id = (1+Math.random()*4294967295).toString(16); + if (node.isServer) { + node._clients[id] = socket; + node.emit('opened',{count:Object.keys(node._clients).length,id:id}); + } + socket.on('open',function() { + if (!node.isServer) { + node.emit('opened',{count:'',id:id}); + } + }); + socket.on('close',function() { + if (node.isServer) { + delete node._clients[id]; + node.emit('closed',{count:Object.keys(node._clients).length,id:id}); + } else { + node.emit('closed',{count:'',id:id}); + } + if (!node.closing && !node.isServer) { + clearTimeout(node.tout); + node.tout = setTimeout(function() { startconn(); }, 3000); // try to reconnect every 3 secs... bit fast ? + } + }); + socket.on('message',function(data,flags) { + node.handleEvent(id,socket,'message',data,flags); + }); + socket.on('error', function(err) { + node.emit('erro',{err:err,id:id}); + if (!node.closing && !node.isServer) { + clearTimeout(node.tout); + node.tout = setTimeout(function() { startconn(); }, 3000); // try to reconnect every 3 secs... bit fast ? + } + }); + } + + if (node.isServer) { + activeListenerNodes++; + if (!serverUpgradeAdded) { + RED.server.on('upgrade', handleServerUpgrade); + serverUpgradeAdded = true + } + + var path = RED.settings.httpNodeRoot || "/"; + path = path + (path.slice(-1) == "/" ? "":"/") + (node.path.charAt(0) == "/" ? node.path.substring(1) : node.path); + node.fullPath = path; + + if (listenerNodes.hasOwnProperty(path)) { + node.error(RED._("websocket.errors.duplicate-path",{path: node.path})); + return; + } + listenerNodes[node.fullPath] = node; + var serverOptions = { + noServer: true + } + if (RED.settings.webSocketNodeVerifyClient) { + serverOptions.verifyClient = RED.settings.webSocketNodeVerifyClient; + } + // Create a WebSocket Server + node.server = new ws.Server(serverOptions); + node.server.setMaxListeners(0); + node.server.on('connection', handleConnection); + } + else { + node.closing = false; + startconn(); // start outbound connection + } + + node.on("close", function() { + if (node.isServer) { + delete listenerNodes[node.fullPath]; + node.server.close(); + node._inputNodes = []; + activeListenerNodes--; + // if (activeListenerNodes === 0 && serverUpgradeAdded) { + // RED.server.removeListener('upgrade', handleServerUpgrade); + // serverUpgradeAdded = false; + // } + + + } + else { + node.closing = true; + node.server.close(); + if (node.tout) { + clearTimeout(node.tout); + node.tout = null; + } + } + }); + } + RED.nodes.registerType("websocket-listener",WebSocketListenerNode); + RED.nodes.registerType("websocket-client",WebSocketListenerNode); + + WebSocketListenerNode.prototype.registerInputNode = function(/*Node*/handler) { + this._inputNodes.push(handler); + } + + WebSocketListenerNode.prototype.removeInputNode = function(/*Node*/handler) { + this._inputNodes.forEach(function(node, i, inputNodes) { + if (node === handler) { + inputNodes.splice(i, 1); + } + }); + } + + WebSocketListenerNode.prototype.handleEvent = function(id,/*socket*/socket,/*String*/event,/*Object*/data,/*Object*/flags) { + var msg; + if (this.wholemsg) { + try { + msg = JSON.parse(data); + if (typeof msg !== "object" && !Array.isArray(msg) && (msg !== null)) { + msg = { payload:msg }; + } + } + catch(err) { + msg = { payload:data }; + } + } else { + msg = { + payload:data + }; + } + msg._session = {type:"websocket",id:id}; + for (var i = 0; i < this._inputNodes.length; i++) { + this._inputNodes[i].send(msg); + } + } + + WebSocketListenerNode.prototype.broadcast = function(data) { + if (this.isServer) { + for (let client in this._clients) { + if (this._clients.hasOwnProperty(client)) { + try { + this._clients[client].send(data); + } catch(err) { + this.warn(RED._("websocket.errors.send-error")+" "+client+" "+err.toString()) + } + } + } + } + else { + try { + this.server.send(data); + } catch(err) { + this.warn(RED._("websocket.errors.send-error")+" "+err.toString()) + } + } + } + + WebSocketListenerNode.prototype.reply = function(id,data) { + var session = this._clients[id]; + if (session) { + try { + session.send(data); + } + catch(e) { // swallow any errors + } + } + } + + function WebSocketInNode(n) { + RED.nodes.createNode(this,n); + this.server = (n.client)?n.client:n.server; + var node = this; + this.serverConfig = RED.nodes.getNode(this.server); + if (this.serverConfig) { + this.serverConfig.registerInputNode(this); + // TODO: nls + this.serverConfig.on('opened', function(event) { + node.status({ + fill:"green",shape:"dot",text:RED._("websocket.status.connected",{count:event.count}), + event:"connect", + _session: {type:"websocket",id:event.id} + }); + }); + this.serverConfig.on('erro', function(event) { + node.status({ + fill:"red",shape:"ring",text:"common.status.error", + event:"error", + _session: {type:"websocket",id:event.id} + }); + }); + this.serverConfig.on('closed', function(event) { + var status; + if (event.count > 0) { + status = {fill:"green",shape:"dot",text:RED._("websocket.status.connected",{count:event.count})}; + } else { + status = {fill:"red",shape:"ring",text:"common.status.disconnected"}; + } + status.event = "disconnect"; + status._session = {type:"websocket",id:event.id} + node.status(status); + }); + } else { + this.error(RED._("websocket.errors.missing-conf")); + } + this.on('close', function() { + if (node.serverConfig) { + node.serverConfig.removeInputNode(node); + } + node.status({}); + }); + } + RED.nodes.registerType("websocket in",WebSocketInNode); + + function WebSocketOutNode(n) { + RED.nodes.createNode(this,n); + var node = this; + this.server = (n.client)?n.client:n.server; + this.serverConfig = RED.nodes.getNode(this.server); + if (!this.serverConfig) { + return this.error(RED._("websocket.errors.missing-conf")); + } + else { + // TODO: nls + this.serverConfig.on('opened', function(event) { + node.status({ + fill:"green",shape:"dot",text:RED._("websocket.status.connected",{count:event.count}), + event:"connect", + _session: {type:"websocket",id:event.id} + }); + }); + this.serverConfig.on('erro', function(event) { + node.status({ + fill:"red",shape:"ring",text:"common.status.error", + event:"error", + _session: {type:"websocket",id:event.id} + }) + }); + this.serverConfig.on('closed', function(event) { + var status; + if (event.count > 0) { + status = {fill:"green",shape:"dot",text:RED._("websocket.status.connected",{count:event.count})}; + } else { + status = {fill:"red",shape:"ring",text:"common.status.disconnected"}; + } + status.event = "disconnect"; + status._session = {type:"websocket",id:event.id} + node.status(status); + }); + } + this.on("input", function(msg, nodeSend, nodeDone) { + var payload; + if (this.serverConfig.wholemsg) { + var sess; + if (msg._session) { sess = JSON.stringify(msg._session); } + delete msg._session; + payload = JSON.stringify(msg); + if (sess) { msg._session = JSON.parse(sess); } + } + else if (msg.hasOwnProperty("payload")) { + if (!Buffer.isBuffer(msg.payload)) { // if it's not a buffer make sure it's a string. + payload = RED.util.ensureString(msg.payload); + } + else { + payload = msg.payload; + } + } + if (payload) { + if (msg._session && msg._session.type == "websocket") { + node.serverConfig.reply(msg._session.id,payload); + } else { + node.serverConfig.broadcast(payload,function(error) { + if (!!error) { + node.warn(RED._("websocket.errors.send-error")+inspect(error)); + } + }); + } + } + nodeDone(); + }); + this.on('close', function() { + node.status({}); + }); + } + RED.nodes.registerType("websocket out",WebSocketOutNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/31-tcpin.html b/packages/connector/packages/node_modules/@node-red/nodes/core/network/31-tcpin.html new file mode 100644 index 0000000..6029d61 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/31-tcpin.html @@ -0,0 +1,263 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-template-name="tcp in"> + <div class="form-row"> + <label for="node-input-server"><i class="fa fa-dot-circle-o"></i> <span data-i18n="tcpin.label.type"></span></label> + <select id="node-input-server" style="width:120px; margin-right:5px;"> + <option value="server" data-i18n="tcpin.type.listen"></option> + <option value="client" data-i18n="tcpin.type.connect"></option> + </select> + <span data-i18n="tcpin.label.port"></span> <input type="text" id="node-input-port" style="width:65px"> + </div> + <div class="form-row hidden" id="node-input-host-row" style="padding-left: 110px;"> + <span data-i18n="tcpin.label.host"></span> <input type="text" id="node-input-host" placeholder="localhost" style="width: 60%;"> + </div> + + <div class="form-row"> + <label><i class="fa fa-sign-out"></i> <span data-i18n="tcpin.label.output"></span></label> + <select id="node-input-datamode" style="width:110px;"> + <option value="stream" data-i18n="tcpin.output.stream"></option> + <option value="single" data-i18n="tcpin.output.single"></option> + </select> + <select id="node-input-datatype" style="width:140px;"> + <option value="buffer" data-i18n="tcpin.output.buffer"></option> + <option value="utf8" data-i18n="tcpin.output.string"></option> + <option value="base64" data-i18n="tcpin.output.base64"></option> + </select> + <span data-i18n="tcpin.label.payload"></span> + </div> + + <div id="node-row-newline" class="form-row hidden" style="padding-left:110px;"> + <span data-i18n="tcpin.label.delimited"></span> <input type="text" id="node-input-newline" style="width:110px;"> + </div> + + <div class="form-row"> + <label for="node-input-topic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label> + <input type="text" id="node-input-topic" data-i18n="[placeholder]common.label.topic"> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('tcp in',{ + category: 'network', + color:"Silver", + defaults: { + name: {value:""}, + server: {value:"server",required:true}, + host: {value:"",validate:function(v) { return (this.server == "server")||v.length > 0;} }, + port: {value:"",required:true,validate:RED.validators.number()}, + datamode:{value:"stream"}, + datatype:{value:"buffer"}, + newline:{value:""}, + topic: {value:""}, + base64: {/*deprecated*/ value:false,required:true} + }, + inputs:0, + outputs:1, + icon: "bridge-dash.svg", + label: function() { + return this.name || "tcp:"+(this.host?this.host+":":"")+this.port; + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + var updateOptions = function() { + var sockettype = $("#node-input-server").val(); + if (sockettype == "client") { + $("#node-input-host-row").show(); + } else { + $("#node-input-host-row").hide(); + } + var datamode = $("#node-input-datamode").val(); + var datatype = $("#node-input-datatype").val(); + if (datamode == "stream") { + if (datatype == "utf8") { + $("#node-row-newline").show(); + } else { + $("#node-row-newline").hide(); + } + } else { + $("#node-row-newline").hide(); + } + }; + updateOptions(); + $("#node-input-server").change(updateOptions); + $("#node-input-datatype").change(updateOptions); + $("#node-input-datamode").change(updateOptions); + } + }); +</script> + + +<script type="text/x-red" data-template-name="tcp out"> + <div class="form-row"> + <label for="node-input-beserver"><i class="fa fa-dot-circle-o"></i> <span data-i18n="tcpin.label.type"></span></label> + <select id="node-input-beserver" style="width:150px; margin-right:5px;"> + <option value="server" data-i18n="tcpin.type.listen"></option> + <option value="client" data-i18n="tcpin.type.connect"></option> + <option value="reply" data-i18n="tcpin.type.reply"></option> + </select> + <span id="node-input-port-row"><span data-i18n="tcpin.label.port"></span> <input type="text" id="node-input-port" style="width: 65px"></span> + </div> + + <div class="form-row hidden" id="node-input-host-row" style="padding-left: 110px;"> + <span data-i18n="tcpin.label.host"></span> <input type="text" id="node-input-host" style="width: 60%;"> + </div> + + <div class="form-row hidden" id="node-input-end-row"> + <label>&nbsp;</label> + <input type="checkbox" id="node-input-end" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-input-end" style="width: 70%;"><span data-i18n="tcpin.label.close-connection"></span></label> + </div> + + <div class="form-row"> + <label>&nbsp;</label> + <input type="checkbox" id="node-input-base64" placeholder="base64" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-input-base64" style="width: 70%;"><span data-i18n="tcpin.label.decode-base64"></span></label> + </div> + + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('tcp out',{ + category: 'network', + color:"Silver", + defaults: { + host: {value:"",validate:function(v) { return (this.beserver != "client")||v.length > 0;} }, + port: {value:"",validate:function(v) { return (this.beserver == "reply")||RED.validators.number()(v); } }, + beserver: {value:"client",required:true}, + base64: {value:false,required:true}, + end: {value:false,required:true}, + name: {value:""} + }, + inputs:1, + outputs:0, + icon: "bridge-dash.svg", + align: "right", + label: function() { + return this.name || "tcp:"+(this.host?this.host+":":"")+this.port; + }, + labelStyle: function() { + return (this.name)?"node_label_italic":""; + }, + oneditprepare: function() { + var updateOptions = function() { + var sockettype = $("#node-input-beserver").val(); + if (sockettype == "reply") { + $("#node-input-port-row").hide(); + $("#node-input-host-row").hide(); + $("#node-input-end-row").hide(); + } else { + $("#node-input-port-row").show(); + $("#node-input-end-row").show(); + } + + if (sockettype == "client") { + $("#node-input-host-row").show(); + } else { + $("#node-input-host-row").hide(); + } + }; + updateOptions(); + $("#node-input-beserver").change(updateOptions); + } + }); +</script> + + +<script type="text/x-red" data-template-name="tcp request"> + <div class="form-row"> + <label for="node-input-server"><i class="fa fa-globe"></i> <span data-i18n="tcpin.label.server"></span></label> + <input type="text" id="node-input-server" placeholder="ip.address" style="width:45%"> + <span data-i18n="tcpin.label.port"></span> + <input type="text" id="node-input-port" style="width:60px"> + </div> + <div class="form-row"> + <label for="node-input-out"><i class="fa fa-sign-out"></i> <span data-i18n="tcpin.label.return"></span></label> + <select type="text" id="node-input-out" style="width:54%;"> + <option value="time" data-i18n="tcpin.return.timeout"></option> + <option value="char" data-i18n="tcpin.return.character"></option> + <option value="count" data-i18n="tcpin.return.number"></option> + <option value="sit" data-i18n="tcpin.return.never"></option> + <option value="immed" data-i18n="tcpin.return.immed"></option> + </select> + <input type="text" id="node-input-splitc" style="width:50px;"> + <span id="node-units"></span> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('tcp request',{ + category: 'network', + color:"Silver", + defaults: { + server: {value:""}, + port: {value:"",validate:RED.validators.regex(/^(\d*|)$/)}, + out: {value:"time",required:true}, + splitc: {value:"0",required:true}, + name: {value:""} + }, + inputs:1, + outputs:1, + icon: "bridge-dash.svg", + label: function() { + return this.name || "tcp:"+(this.server?this.server+":":"")+this.port; + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + var previous = null; + $("#node-input-out").on('focus', function () { previous = this.value; }).on("change", function() { + if (previous === null) { previous = $("#node-input-out").val(); } + if ($("#node-input-out").val() == "char") { + if (previous != "char") { $("#node-input-splitc").val("\\n"); } + $("#node-units").text(""); + } + else if ($("#node-input-out").val() == "time") { + if (previous != "time") { $("#node-input-splitc").val("0"); } + $("#node-units").text(RED._("node-red:tcpin.label.ms")); + } + else if ($("#node-input-out").val() == "immed") { + if (previous != "immed") { $("#node-input-splitc").val(" "); } + $("#node-units").text(""); + } + else if ($("#node-input-out").val() == "count") { + if (previous != "count") { $("#node-input-splitc").val("12"); } + $("#node-units").text(RED._("node-red:tcpin.label.chars")); + } + else { + if (previous != "sit") { $("#node-input-splitc").val(" "); } + $("#node-units").text(""); + } + }); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/31-tcpin.js b/packages/connector/packages/node_modules/@node-red/nodes/core/network/31-tcpin.js new file mode 100644 index 0000000..e52e9c3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/31-tcpin.js @@ -0,0 +1,699 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var reconnectTime = RED.settings.socketReconnectTime||10000; + var socketTimeout = RED.settings.socketTimeout||null; + const msgQueueSize = RED.settings.tcpMsgQueueSize || 1000; + const Denque = require('denque'); + var net = require('net'); + + var connectionPool = {}; + + /** + * Enqueue `item` in `queue` + * @param {Denque} queue - Queue + * @param {*} item - Item to enqueue + * @private + * @returns {Denque} `queue` + */ + const enqueue = (queue, item) => { + // drop msgs from front of queue if size is going to be exceeded + if (queue.length === msgQueueSize) { queue.shift(); } + queue.push(item); + return queue; + }; + + /** + * Shifts item off front of queue + * @param {Deque} queue - Queue + * @private + * @returns {*} Item previously at front of queue + */ + const dequeue = queue => queue.shift(); + + function TcpIn(n) { + RED.nodes.createNode(this,n); + this.host = n.host; + this.port = n.port * 1; + this.topic = n.topic; + this.stream = (!n.datamode||n.datamode=='stream'); /* stream,single*/ + this.datatype = n.datatype||'buffer'; /* buffer,utf8,base64 */ + this.newline = (n.newline||"").replace("\\n","\n").replace("\\r","\r"); + this.base64 = n.base64; + this.server = (typeof n.server == 'boolean')?n.server:(n.server == "server"); + this.closing = false; + this.connected = false; + var node = this; + var count = 0; + + if (!node.server) { + var buffer = null; + var client; + var reconnectTimeout; + var end = false; + var setupTcpClient = function() { + node.log(RED._("tcpin.status.connecting",{host:node.host,port:node.port})); + node.status({fill:"grey",shape:"dot",text:"common.status.connecting"}); + var id = (1+Math.random()*4294967295).toString(16); + client = net.connect(node.port, node.host, function() { + buffer = (node.datatype == 'buffer') ? Buffer.alloc(0) : ""; + node.connected = true; + node.log(RED._("tcpin.status.connected",{host:node.host,port:node.port})); + node.status({fill:"green",shape:"dot",text:"common.status.connected"}); + }); + client.setKeepAlive(true,120000); + connectionPool[id] = client; + + client.on('data', function (data) { + if (node.datatype != 'buffer') { + data = data.toString(node.datatype); + } + if (node.stream) { + var msg; + if ((node.datatype) === "utf8" && node.newline !== "") { + buffer = buffer+data; + var parts = buffer.split(node.newline); + for (var i = 0; i<parts.length-1; i+=1) { + msg = {topic:node.topic, payload:parts[i]}; + msg._session = {type:"tcp",id:id}; + node.send(msg); + } + buffer = parts[parts.length-1]; + } else { + msg = {topic:node.topic, payload:data}; + msg._session = {type:"tcp",id:id}; + node.send(msg); + } + } else { + if ((typeof data) === "string") { + buffer = buffer+data; + } else { + buffer = Buffer.concat([buffer,data],buffer.length+data.length); + } + } + }); + client.on('end', function() { + if (!node.stream || (node.datatype == "utf8" && node.newline !== "" && buffer.length > 0)) { + var msg = {topic:node.topic, payload:buffer}; + msg._session = {type:"tcp",id:id}; + if (buffer.length !== 0) { + end = true; // only ask for fast re-connect if we actually got something + node.send(msg); + } + buffer = null; + } + }); + client.on('close', function() { + delete connectionPool[id]; + node.connected = false; + node.status({fill:"red",shape:"ring",text:"common.status.disconnected"}); + if (!node.closing) { + if (end) { // if we were asked to close then try to reconnect once very quick. + end = false; + reconnectTimeout = setTimeout(setupTcpClient, 20); + } + else { + node.log(RED._("tcpin.errors.connection-lost",{host:node.host,port:node.port})); + reconnectTimeout = setTimeout(setupTcpClient, reconnectTime); + } + } else { + if (node.doneClose) { node.doneClose(); } + } + }); + client.on('error', function(err) { + node.log(err); + }); + } + setupTcpClient(); + + this.on('close', function(done) { + node.doneClose = done; + this.closing = true; + if (client) { client.destroy(); } + clearTimeout(reconnectTimeout); + if (!node.connected) { done(); } + }); + } + else { + var server = net.createServer(function (socket) { + socket.setKeepAlive(true,120000); + if (socketTimeout !== null) { socket.setTimeout(socketTimeout); } + var id = (1+Math.random()*4294967295).toString(16); + var fromi; + var fromp; + connectionPool[id] = socket; + count++; + node.status({ + text:RED._("tcpin.status.connections",{count:count}), + event:"connect", + ip:socket.remoteAddress, + port:socket.remotePort, + _session: {type:"tcp",id:id} + }); + + var buffer = (node.datatype == 'buffer') ? Buffer.alloc(0) : ""; + socket.on('data', function (data) { + if (node.datatype != 'buffer') { + data = data.toString(node.datatype); + } + if (node.stream) { + var msg; + if ((typeof data) === "string" && node.newline !== "") { + buffer = buffer+data; + var parts = buffer.split(node.newline); + for (var i = 0; i<parts.length-1; i+=1) { + msg = {topic:node.topic, payload:parts[i], ip:socket.remoteAddress, port:socket.remotePort}; + msg._session = {type:"tcp",id:id}; + node.send(msg); + } + buffer = parts[parts.length-1]; + } else { + msg = {topic:node.topic, payload:data, ip:socket.remoteAddress, port:socket.remotePort}; + msg._session = {type:"tcp",id:id}; + node.send(msg); + } + } + else { + if ((typeof data) === "string") { + buffer = buffer+data; + } else { + buffer = Buffer.concat([buffer,data],buffer.length+data.length); + } + fromi = socket.remoteAddress; + fromp = socket.remotePort; + } + }); + socket.on('end', function() { + if (!node.stream || (node.datatype === "utf8" && node.newline !== "")) { + if (buffer.length > 0) { + var msg = {topic:node.topic, payload:buffer, ip:fromi, port:fromp}; + msg._session = {type:"tcp",id:id}; + node.send(msg); + } + buffer = null; + } + }); + socket.on('timeout', function() { + node.log(RED._("tcpin.errors.timeout",{port:node.port})); + socket.end(); + }); + socket.on('close', function() { + delete connectionPool[id]; + count--; + node.status({ + text:RED._("tcpin.status.connections",{count:count}), + event:"disconnect", + ip:socket.remoteAddress, + port:socket.remotePort, + _session: {type:"tcp",id:id} + + }); + }); + socket.on('error',function(err) { + node.log(err); + }); + }); + + server.on('error', function(err) { + if (err) { + node.error(RED._("tcpin.errors.cannot-listen",{port:node.port,error:err.toString()})); + } + }); + + server.listen(node.port, function(err) { + if (err) { + node.error(RED._("tcpin.errors.cannot-listen",{port:node.port,error:err.toString()})); + } else { + node.log(RED._("tcpin.status.listening-port",{port:node.port})); + node.on('close', function() { + for (var c in connectionPool) { + if (connectionPool.hasOwnProperty(c)) { + connectionPool[c].end(); + connectionPool[c].unref(); + } + } + node.closing = true; + server.close(); + node.log(RED._("tcpin.status.stopped-listening",{port:node.port})); + }); + } + }); + } + } + RED.nodes.registerType("tcp in",TcpIn); + + + function TcpOut(n) { + RED.nodes.createNode(this,n); + this.host = n.host; + this.port = n.port * 1; + this.base64 = n.base64; + this.doend = n.end || false; + this.beserver = n.beserver; + this.name = n.name; + this.closing = false; + this.connected = false; + var node = this; + + if (!node.beserver||node.beserver=="client") { + var reconnectTimeout; + var client = null; + var end = false; + + var setupTcpClient = function() { + node.log(RED._("tcpin.status.connecting",{host:node.host,port:node.port})); + node.status({fill:"grey",shape:"dot",text:"common.status.connecting"}); + client = net.connect(node.port, node.host, function() { + node.connected = true; + node.log(RED._("tcpin.status.connected",{host:node.host,port:node.port})); + node.status({fill:"green",shape:"dot",text:"common.status.connected"}); + }); + client.setKeepAlive(true,120000); + client.on('error', function (err) { + node.log(RED._("tcpin.errors.error",{error:err.toString()})); + }); + client.on('end', function (err) { + node.status({}); + node.connected = false; + }); + client.on('close', function() { + node.status({fill:"red",shape:"ring",text:"common.status.disconnected"}); + node.connected = false; + client.destroy(); + if (!node.closing) { + if (end) { + end = false; + reconnectTimeout = setTimeout(setupTcpClient,20); + } + else { + node.log(RED._("tcpin.errors.connection-lost",{host:node.host,port:node.port})); + reconnectTimeout = setTimeout(setupTcpClient,reconnectTime); + } + } else { + if (node.doneClose) { node.doneClose(); } + } + }); + } + setupTcpClient(); + + node.on("input", function(msg,nodeSend,nodeDone) { + if (node.connected && msg.payload != null) { + if (Buffer.isBuffer(msg.payload)) { + client.write(msg.payload); + } else if (typeof msg.payload === "string" && node.base64) { + client.write(Buffer.from(msg.payload,'base64')); + } else { + client.write(Buffer.from(""+msg.payload)); + } + if (node.doend === true) { + end = true; + if (client) { node.status({}); client.destroy(); } + } + } + nodeDone(); + }); + + node.on("close", function(done) { + node.doneClose = done; + this.closing = true; + if (client) { client.destroy(); } + clearTimeout(reconnectTimeout); + if (!node.connected) { done(); } + }); + + } + else if (node.beserver == "reply") { + node.on("input",function(msg, nodeSend, nodeDone) { + if (msg._session && msg._session.type == "tcp") { + var client = connectionPool[msg._session.id]; + if (client) { + if (Buffer.isBuffer(msg.payload)) { + client.write(msg.payload); + } else if (typeof msg.payload === "string" && node.base64) { + client.write(Buffer.from(msg.payload,'base64')); + } else { + client.write(Buffer.from(""+msg.payload)); + } + } + } + else { + for (var i in connectionPool) { + if (Buffer.isBuffer(msg.payload)) { + connectionPool[i].write(msg.payload); + } else if (typeof msg.payload === "string" && node.base64) { + connectionPool[i].write(Buffer.from(msg.payload,'base64')); + } else { + connectionPool[i].write(Buffer.from(""+msg.payload)); + } + } + } + nodeDone(); + }); + } + else { + var connectedSockets = []; + node.status({text:RED._("tcpin.status.connections",{count:0})}); + var server = net.createServer(function (socket) { + socket.setKeepAlive(true,120000); + if (socketTimeout !== null) { socket.setTimeout(socketTimeout); } + node.log(RED._("tcpin.status.connection-from",{host:socket.remoteAddress, port:socket.remotePort})); + connectedSockets.push(socket); + node.status({text:RED._("tcpin.status.connections",{count:connectedSockets.length})}); + socket.on('timeout', function() { + node.log(RED._("tcpin.errors.timeout",{port:node.port})); + socket.end(); + }); + socket.on('close',function() { + node.log(RED._("tcpin.status.connection-closed",{host:socket.remoteAddress, port:socket.remotePort})); + connectedSockets.splice(connectedSockets.indexOf(socket),1); + node.status({text:RED._("tcpin.status.connections",{count:connectedSockets.length})}); + }); + socket.on('error',function() { + node.log(RED._("tcpin.errors.socket-error",{host:socket.remoteAddress, port:socket.remotePort})); + connectedSockets.splice(connectedSockets.indexOf(socket),1); + node.status({text:RED._("tcpin.status.connections",{count:connectedSockets.length})}); + }); + }); + + node.on("input", function(msg, nodeSend, nodeDone) { + if (msg.payload != null) { + var buffer; + if (Buffer.isBuffer(msg.payload)) { + buffer = msg.payload; + } else if (typeof msg.payload === "string" && node.base64) { + buffer = Buffer.from(msg.payload,'base64'); + } else { + buffer = Buffer.from(""+msg.payload); + } + for (var i = 0; i < connectedSockets.length; i += 1) { + if (node.doend === true) { connectedSockets[i].end(buffer); } + else { connectedSockets[i].write(buffer); } + } + } + nodeDone(); + }); + + server.on('error', function(err) { + if (err) { + node.error(RED._("tcpin.errors.cannot-listen",{port:node.port,error:err.toString()})); + } + }); + + server.listen(node.port, function(err) { + if (err) { + node.error(RED._("tcpin.errors.cannot-listen",{port:node.port,error:err.toString()})); + } else { + node.log(RED._("tcpin.status.listening-port",{port:node.port})); + node.on('close', function() { + for (var c in connectedSockets) { + if (connectedSockets.hasOwnProperty(c)) { + connectedSockets[c].end(); + connectedSockets[c].unref(); + } + } + server.close(); + node.log(RED._("tcpin.status.stopped-listening",{port:node.port})); + }); + } + }); + } + } + RED.nodes.registerType("tcp out",TcpOut); + + + function TcpGet(n) { + RED.nodes.createNode(this,n); + this.server = n.server; + this.port = Number(n.port); + this.out = n.out; + this.splitc = n.splitc; + + if (this.out === "immed") { this.splitc = -1; this.out = "time"; } + if (this.out !== "char") { this.splitc = Number(this.splitc); } + else { + if (this.splitc[0] == '\\') { + this.splitc = parseInt(this.splitc.replace("\\n",0x0A).replace("\\r",0x0D).replace("\\t",0x09).replace("\\e",0x1B).replace("\\f",0x0C).replace("\\0",0x00)); + } // jshint ignore:line + if (typeof this.splitc == "string") { + if (this.splitc.substr(0,2) == "0x") { + this.splitc = parseInt(this.splitc); + } + else { + this.splitc = this.splitc.charCodeAt(0); + } + } // jshint ignore:line + } + + var node = this; + + var clients = {}; + + this.on("input", function(msg, nodeSend, nodeDone) { + var i = 0; + if ((!Buffer.isBuffer(msg.payload)) && (typeof msg.payload !== "string")) { + msg.payload = msg.payload.toString(); + } + + var host = node.server || msg.host; + var port = node.port || msg.port; + + // Store client information independently + // the clients object will have: + // clients[id].client, clients[id].msg, clients[id].timeout + var connection_id = host + ":" + port; + if (connection_id !== node.last_id) { + node.status({}); + node.last_id = connection_id; + } + clients[connection_id] = clients[connection_id] || { + msgQueue: new Denque(), + connected: false, + connecting: false + }; + enqueue(clients[connection_id].msgQueue, {msg:msg,nodeSend:nodeSend, nodeDone: nodeDone}); + clients[connection_id].lastMsg = msg; + + if (!clients[connection_id].connecting && !clients[connection_id].connected) { + var buf; + if (this.out == "count") { + if (this.splitc === 0) { buf = Buffer.alloc(1); } + else { buf = Buffer.alloc(this.splitc); } + } + else { buf = Buffer.alloc(65536); } // set it to 64k... hopefully big enough for most TCP packets.... but only hopefully + + clients[connection_id].client = net.Socket(); + if (socketTimeout !== null) { clients[connection_id].client.setTimeout(socketTimeout);} + + if (host && port) { + clients[connection_id].connecting = true; + clients[connection_id].client.connect(port, host, function() { + //node.log(RED._("tcpin.errors.client-connected")); + node.status({fill:"green",shape:"dot",text:"common.status.connected"}); + if (clients[connection_id] && clients[connection_id].client) { + clients[connection_id].connected = true; + clients[connection_id].connecting = false; + let event; + while (event = dequeue(clients[connection_id].msgQueue)) { + clients[connection_id].client.write(event.msg.payload); + event.nodeDone(); + } + if (node.out === "time" && node.splitc < 0) { + clients[connection_id].connected = clients[connection_id].connecting = false; + clients[connection_id].client.end(); + delete clients[connection_id]; + node.status({}); + } + } + }); + } + else { + node.warn(RED._("tcpin.errors.no-host")); + } + + clients[connection_id].client.on('data', function(data) { + if (node.out === "sit") { // if we are staying connected just send the buffer + if (clients[connection_id]) { + const msg = clients[connection_id].lastMsg || {}; + msg.payload = data; + nodeSend(RED.util.cloneMessage(msg)); + } + } + // else if (node.splitc === 0) { + // clients[connection_id].msg.payload = data; + // node.send(clients[connection_id].msg); + // } + else { + for (var j = 0; j < data.length; j++ ) { + if (node.out === "time") { + if (clients[connection_id]) { + // do the timer thing + if (clients[connection_id].timeout) { + i += 1; + buf[i] = data[j]; + } + else { + clients[connection_id].timeout = setTimeout(function () { + if (clients[connection_id]) { + clients[connection_id].timeout = null; + const msg = clients[connection_id].lastMsg || {}; + msg.payload = Buffer.alloc(i+1); + buf.copy(msg.payload,0,0,i+1); + nodeSend(msg); + if (clients[connection_id].client) { + node.status({}); + clients[connection_id].client.destroy(); + delete clients[connection_id]; + } + } + }, node.splitc); + i = 0; + buf[0] = data[j]; + } + } + } + // count bytes into a buffer... + else if (node.out == "count") { + buf[i] = data[j]; + i += 1; + if ( i >= node.splitc) { + if (clients[connection_id]) { + const msg = clients[connection_id].lastMsg || {}; + msg.payload = Buffer.alloc(i); + buf.copy(msg.payload,0,0,i); + nodeSend(msg); + if (clients[connection_id].client) { + node.status({}); + clients[connection_id].client.destroy(); + delete clients[connection_id]; + } + i = 0; + } + } + } + // look for a char + else { + buf[i] = data[j]; + i += 1; + if (data[j] == node.splitc) { + if (clients[connection_id]) { + const msg = clients[connection_id].lastMsg || {}; + msg.payload = Buffer.alloc(i); + buf.copy(msg.payload,0,0,i); + nodeSend(msg); + if (clients[connection_id].client) { + node.status({}); + clients[connection_id].client.destroy(); + delete clients[connection_id]; + } + i = 0; + } + } + } + } + } + }); + + clients[connection_id].client.on('end', function() { + //console.log("END"); + node.status({fill:"grey",shape:"ring",text:"common.status.disconnected"}); + if (clients[connection_id] && clients[connection_id].client) { + clients[connection_id].connected = clients[connection_id].connecting = false; + clients[connection_id].client = null; + } + }); + + clients[connection_id].client.on('close', function() { + //console.log("CLOSE"); + if (clients[connection_id]) { + clients[connection_id].connected = clients[connection_id].connecting = false; + } + + var anyConnected = false; + + for (var client in clients) { + if (clients[client].connected) { + anyConnected = true; + break; + } + } + if (node.doneClose && !anyConnected) { + clients = {}; + node.doneClose(); + } + }); + + clients[connection_id].client.on('error', function() { + //console.log("ERROR"); + node.status({fill:"red",shape:"ring",text:"common.status.error"}); + node.error(RED._("tcpin.errors.connect-fail") + " " + connection_id, msg); + if (clients[connection_id] && clients[connection_id].client) { + clients[connection_id].client.destroy(); + delete clients[connection_id]; + } + }); + + clients[connection_id].client.on('timeout',function() { + //console.log("TIMEOUT"); + if (clients[connection_id]) { + clients[connection_id].connected = clients[connection_id].connecting = false; + node.status({fill:"grey",shape:"dot",text:"tcpin.errors.connect-timeout"}); + //node.warn(RED._("tcpin.errors.connect-timeout")); + if (clients[connection_id].client) { + clients[connection_id].connecting = true; + clients[connection_id].client.connect(port, host, function() { + clients[connection_id].connected = true; + clients[connection_id].connecting = false; + node.status({fill:"green",shape:"dot",text:"common.status.connected"}); + }); + } + } + }); + } + else if (!clients[connection_id].connecting && clients[connection_id].connected) { + if (clients[connection_id] && clients[connection_id].client) { + let event = dequeue(clients[connection_id].msgQueue) + clients[connection_id].client.write(event.msg.payload); + event.nodeDone(); + } + } + }); + + this.on("close", function(done) { + node.doneClose = done; + for (var cl in clients) { + if (clients[cl].hasOwnProperty("client")) { + clients[cl].client.destroy(); + } + } + node.status({}); + + // this is probably not necessary and may be removed + var anyConnected = false; + for (var c in clients) { + if (clients[c].connected) { + anyConnected = true; + break; + } + } + if (!anyConnected) { clients = {}; } + done(); + }); + + } + RED.nodes.registerType("tcp request",TcpGet); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/32-udp.html b/packages/connector/packages/node_modules/@node-red/nodes/core/network/32-udp.html new file mode 100644 index 0000000..ed867ae --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/32-udp.html @@ -0,0 +1,231 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!-- The Input Node --> +<script type="text/x-red" data-template-name="udp in"> + <div class="form-row"> + <label for="node-input-port"><i class="fa fa-sign-in"></i> <span data-i18n="udp.label.listen"></span></label> + <select id="node-input-multicast" style='width:70%'> + <option value="false" data-i18n="udp.udpmsgs"></option> + <option value="true" data-i18n="udp.mcmsgs"></option> + </select> + </div> + <div class="form-row node-input-group"> + <label for="node-input-group"><i class="fa fa-list"></i> <span data-i18n="udp.label.group"></span></label> + <input type="text" id="node-input-group" placeholder="225.0.18.83"> + </div> + <div class="form-row node-input-iface"> + <label for="node-input-iface"><i class="fa fa-random"></i> <span data-i18n="udp.label.interface"></span></label> + <input type="text" id="node-input-iface" data-i18n="[placeholder]udp.placeholder.interfaceprompt"> + </div> + <div class="form-row"> + <label for="node-input-port"><i class="fa fa-sign-in"></i> <span data-i18n="udp.label.onport"></span></label> + <input type="text" id="node-input-port" style="width:80px"> + &nbsp;&nbsp;<span data-i18n="udp.label.using"></span> <select id="node-input-ipv" style="width:80px"> + <option value="udp4">ipv4</option> + <option value="udp6">ipv6</option> + </select> + </div> + <div class="form-row"> + <label for="node-input-datatype"><i class="fa fa-sign-out"></i> <span data-i18n="udp.label.output"></span></label> + <select id="node-input-datatype" style="width:70%;"> + <option value="buffer" data-i18n="udp.output.buffer"></option> + <option value="utf8" data-i18n="udp.output.string"></option> + <option value="base64" data-i18n="udp.output.base64"></option> + </select> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-tips"><span data-i18n="udp.tip.in"></span></div> + <div class="form-tips" id="udpporttip"><span data-i18n="[html]udp.tip.port"></span></div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('udp in',{ + category: 'network', + color:"Silver", + defaults: { + name: {value:""}, + iface: {value:""}, + port: {value:"",required:true,validate:RED.validators.number()}, + ipv: {value:"udp4"}, + multicast: {value:"false"}, + group: {value:"",validate:function(v) { return (this.multicast !== "true")||v.length > 0;} }, + datatype: {value:"buffer",required:true} + }, + inputs:0, + outputs:1, + icon: "bridge-dash.svg", + label: function() { + if (this.multicast=="false") { + return this.name||"udp "+this.port; + } + else { + return this.name||"udp "+(this.group+":"+this.port); + } + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + $("#node-input-multicast").on("change", function() { + var id = $("#node-input-multicast").val(); + if (id == "false") { + $(".node-input-group").hide(); + $(".node-input-iface").hide(); + } + else { + $(".node-input-group").show(); + $(".node-input-iface").show(); + } + }); + $("#node-input-multicast").change(); + + var porttip = this._("udp.tip.port"); + var alreadyused = this._("udp.errors.alreadyused"); + var portsInUse = {}; + $.getJSON('udp-ports/'+this.id,function(data) { + portsInUse = data || {}; + $('#udpporttip').html(porttip + data); + }); + $("#node-input-port").on("change", function() { + var portnew = $("#node-input-port").val(); + if (portsInUse.hasOwnProperty($("#node-input-port").val())) { + RED.notify(alreadyused+" "+$("#node-input-port").val(),"warn"); + } + }); + } + }); +</script> + + +<!-- The Output Node --> +<script type="text/x-red" data-template-name="udp out"> + <div class="form-row"> + <label for="node-input-port"><i class="fa fa-envelope"></i> <span data-i18n="udp.label.send"></span></label> + <select id="node-input-multicast" style="width:40%"> + <option value="false" data-i18n="udp.udpmsg"></option> + <option value="broad" data-i18n="udp.bcmsg"></option> + <option value="multi" data-i18n="udp.mcmsg"></option> + </select> + <span data-i18n="udp.label.toport"></span> <input type="text" id="node-input-port" style="width:70px"> + </div> + <div class="form-row node-input-addr"> + <label for="node-input-addr" id="node-input-addr-label"><i class="fa fa-list"></i> <span data-i18n="udp.label.address"></span></label> + <input type="text" id="node-input-addr" data-i18n="[placeholder]udp.placeholder.address" style="width:50%;"> + <select id="node-input-ipv" style="width:70px"> + <option value="udp4">ipv4</option> + <option value="udp6">ipv6</option> + </select> + </div> + <div class="form-row node-input-iface"> + <label for="node-input-iface"><i class="fa fa-random"></i> <span data-i18n="udp.label.interface"></span></label> + <input type="text" id="node-input-iface" data-i18n="[placeholder]udp.placeholder.interface"> + </div> + <div class="form-row"> + <label for="node-input-outport-type">&nbsp;</label> + <select id="node-input-outport-type"> + <option id="node-input-outport-type-random" value="random" data-i18n="udp.bind.random"></option> + <option value="fixed" data-i18n="udp.bind.local"></option> + </select> + <input type="text" id="node-input-outport" style="width:70px;"> + </div> + <div class="form-row"> + <label>&nbsp;</label> + <input type="checkbox" id="node-input-base64" style="display:inline-block; width:auto; vertical-align:top;"> + <label for="node-input-base64" style="width:70%;"><span data-i18n="udp.label.decode-base64"></span></label> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-tips"><span data-i18n="[html]udp.tip.out"></span></div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('udp out',{ + category: 'network', + color:"Silver", + defaults: { + name: {value:""}, + addr: {value:""}, + iface: {value:""}, + port: {value:""}, + ipv: {value:"udp4"}, + outport: {value:""}, + base64: {value:false,required:true}, + multicast: {value:"false"} + }, + inputs:1, + outputs:0, + icon: "bridge-dash.svg", + align: "right", + label: function() { + return this.name||"udp "+(this.addr+":"+this.port); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + var addresslabel = this._("udp.label.address"); + var addressph = this._("udp.placeholder.address"); + var grouplabel = this._("udp.label.group"); + var bindrandom = this._("udp.bind.random"); + var bindtarget = this._("udp.bind.target"); + + var type = this.outport===""?"random":"fixed"; + $("#node-input-outport-type").val(type); + + $("#node-input-outport-type").on("change", function() { + var type = $(this).val(); + if (type == "random") { + $("#node-input-outport").val("").hide(); + } else { + $("#node-input-outport").show(); + } + }); + $("#node-input-outport-type").change(); + + $("#node-input-multicast").on("change", function() { + var id = $("#node-input-multicast").val(); + if (id === "multi") { + $(".node-input-iface").show(); + $("#node-input-addr-label").html('<i class="fa fa-list"></i> ' + grouplabel); + $("#node-input-addr")[0].placeholder = '225.0.18.83'; + } + else if (id === "broad") { + $(".node-input-iface").hide(); + $("#node-input-addr-label").html('<i class="fa fa-list"></i> ' + addresslabel); + $("#node-input-addr")[0].placeholder = '255.255.255.255'; + } + else { + $(".node-input-iface").hide(); + $("#node-input-addr-label").html('<i class="fa fa-list"></i> ' + addresslabel); + $("#node-input-addr")[0].placeholder = addressph; + } + var type = $(this).val(); + if (type == "false") { + $("#node-input-outport-type-random").html(bindrandom); + } else { + $("#node-input-outport-type-random").html(bindtarget); + } + }); + $("#node-input-multicast").change(); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/32-udp.js b/packages/connector/packages/node_modules/@node-red/nodes/core/network/32-udp.js new file mode 100644 index 0000000..60e9bec --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/32-udp.js @@ -0,0 +1,276 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var os = require('os'); + var dgram = require('dgram'); + var udpInputPortsInUse = {}; + + // The Input Node + function UDPin(n) { + RED.nodes.createNode(this,n); + this.group = n.group; + this.port = n.port; + this.datatype = n.datatype; + this.iface = n.iface || null; + this.multicast = n.multicast; + this.ipv = n.ipv || "udp4"; + var node = this; + + if (node.iface && node.iface.indexOf(".") === -1) { + try { + if ((os.networkInterfaces())[node.iface][0].hasOwnProperty("scopeid")) { + if (node.ipv === "udp4") { + node.iface = (os.networkInterfaces())[node.iface][1].address; + } else { + node.iface = (os.networkInterfaces())[node.iface][0].address; + } + } + else { + if (node.ipv === "udp4") { + node.iface = (os.networkInterfaces())[node.iface][0].address; + } else { + node.iface = (os.networkInterfaces())[node.iface][1].address; + } + } + } + catch(e) { + node.warn(RED._("udp.errors.ifnotfound",{iface:node.iface})); + node.iface = null; + } + } + + var opts = {type:node.ipv, reuseAddr:true}; + if (process.version.indexOf("v0.10") === 0) { opts = node.ipv; } + var server; + + if (!udpInputPortsInUse.hasOwnProperty(node.port)) { + server = dgram.createSocket(opts); // default to udp4 + server.bind(node.port, function() { + if (node.multicast == "true") { + server.setBroadcast(true); + server.setMulticastLoopback(false); + try { + server.setMulticastTTL(128); + server.addMembership(node.group,node.iface); + if (node.iface) { node.status({text:n.iface+" : "+node.iface}); } + node.log(RED._("udp.status.mc-group",{group:node.group})); + } catch (e) { + if (e.errno == "EINVAL") { + node.error(RED._("udp.errors.bad-mcaddress")); + } else if (e.errno == "ENODEV") { + node.error(RED._("udp.errors.interface")); + } else { + node.error(RED._("udp.errors.error",{error:e.errno})); + } + } + } + }); + udpInputPortsInUse[node.port] = server; + } + else { + node.log(RED._("udp.errors.alreadyused",{port:node.port})); + server = udpInputPortsInUse[node.port]; // re-use existing + if (node.iface) { node.status({text:n.iface+" : "+node.iface}); } + } + + server.on("error", function (err) { + if ((err.code == "EACCES") && (node.port < 1024)) { + node.error(RED._("udp.errors.access-error")); + } else { + node.error(RED._("udp.errors.error",{error:err.code})); + } + server.close(); + }); + + server.on('message', function (message, remote) { + var msg; + if (node.datatype =="base64") { + msg = { payload:message.toString('base64'), fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port }; + } else if (node.datatype =="utf8") { + msg = { payload:message.toString('utf8'), fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port }; + } else { + msg = { payload:message, fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port }; + } + node.send(msg); + }); + + server.on('listening', function () { + var address = server.address(); + node.log(RED._("udp.status.listener-at",{host:node.iface||address.address,port:address.port})); + + }); + + node.on("close", function() { + try { + if (node.multicast == "true") { server.dropMembership(node.group); } + server.close(); + node.log(RED._("udp.status.listener-stopped")); + } catch (err) { + //node.error(err); + } + if (udpInputPortsInUse.hasOwnProperty(node.port)) { + delete udpInputPortsInUse[node.port]; + } + node.status({}); + }); + + } + RED.httpAdmin.get('/udp-ports/:id', RED.auth.needsPermission('udp-ports.read'), function(req,res) { + res.json(Object.keys(udpInputPortsInUse)); + }); + RED.nodes.registerType("udp in",UDPin); + + + + // The Output Node + function UDPout(n) { + RED.nodes.createNode(this,n); + //this.group = n.group; + this.port = n.port; + this.outport = n.outport||""; + this.base64 = n.base64; + this.addr = n.addr; + this.iface = n.iface || null; + this.multicast = n.multicast; + this.ipv = n.ipv || "udp4"; + var node = this; + + if (node.iface && node.iface.indexOf(".") === -1) { + try { + if ((os.networkInterfaces())[node.iface][0].hasOwnProperty("scopeid")) { + if (node.ipv === "udp4") { + node.iface = (os.networkInterfaces())[node.iface][1].address; + } else { + node.iface = (os.networkInterfaces())[node.iface][0].address; + } + } + else { + if (node.ipv === "udp4") { + node.iface = (os.networkInterfaces())[node.iface][0].address; + } else { + node.iface = (os.networkInterfaces())[node.iface][1].address; + } + } + } + catch(e) { + node.warn(RED._("udp.errors.ifnotfound",{iface:node.iface})); + node.iface = null; + } + } + + var opts = {type:node.ipv, reuseAddr:true}; + + var sock; + var p = this.outport || this.port || "0"; + node.tout = setTimeout(function() { + if (udpInputPortsInUse[p]) { + sock = udpInputPortsInUse[p]; + node.log(RED._("udp.status.re-use",{outport:node.outport,host:node.addr,port:node.port})); + if (node.iface) { node.status({text:n.iface+" : "+node.iface}); } + } + else { + sock = dgram.createSocket(opts); // default to udp4 + if (node.multicast != "false") { + sock.bind(node.outport, function() { // have to bind before you can enable broadcast... + sock.setBroadcast(true); // turn on broadcast + sock.setMulticastLoopback(false); // turn off loopback + if (node.multicast == "multi") { + try { + sock.setMulticastTTL(128); + sock.addMembership(node.addr,node.iface); // Add to the multicast group + if (node.iface) { node.status({text:n.iface+" : "+node.iface}); } + node.log(RED._("udp.status.mc-ready",{iface:node.iface,outport:node.outport,host:node.addr,port:node.port})); + } catch (e) { + if (e.errno == "EINVAL") { + node.error(RED._("udp.errors.bad-mcaddress")); + } else if (e.errno == "ENODEV") { + node.error(RED._("udp.errors.interface")); + } else { + node.error(RED._("udp.errors.error",{error:e.errno})); + } + } + } else { + node.log(RED._("udp.status.bc-ready",{outport:node.outport,host:node.addr,port:node.port})); + } + }); + } else if ((node.outport !== "") && (!udpInputPortsInUse[node.outport])) { + sock.bind(node.outport); + node.log(RED._("udp.status.ready",{outport:node.outport,host:node.addr,port:node.port})); + } else { + node.log(RED._("udp.status.ready-nolocal",{host:node.addr,port:node.port})); + } + sock.on("error", function(err) { + // Any async error will also get reported in the sock.send call. + // This handler is needed to ensure the error marked as handled to + // prevent it going to the global error handler and shutting node-red + // down. + }); + udpInputPortsInUse[p] = sock; + } + + node.on("input", function(msg, nodeSend, nodeDone) { + if (msg.hasOwnProperty("payload")) { + var add = node.addr || msg.ip || ""; + var por = node.port || msg.port || 0; + if (add === "") { + node.warn(RED._("udp.errors.ip-notset")); + nodeDone(); + } else if (por === 0) { + node.warn(RED._("udp.errors.port-notset")); + nodeDone(); + } else if (isNaN(por) || (por < 1) || (por > 65535)) { + node.warn(RED._("udp.errors.port-invalid")); + nodeDone(); + } else { + var message; + if (node.base64) { + message = Buffer.from(msg.payload, 'base64'); + } else if (msg.payload instanceof Buffer) { + message = msg.payload; + } else { + message = Buffer.from(""+msg.payload); + } + sock.send(message, 0, message.length, por, add, function(err, bytes) { + if (err) { + node.error("udp : "+err,msg); + } + message = null; + nodeDone(); + }); + } + } + }); + }, 75); + + node.on("close", function() { + if (node.tout) { clearTimeout(node.tout); } + try { + if (node.multicast == "multi") { sock.dropMembership(node.group); } + sock.close(); + node.log(RED._("udp.status.output-stopped")); + } catch (err) { + //node.error(err); + } + if (udpInputPortsInUse.hasOwnProperty(p)) { + delete udpInputPortsInUse[p]; + } + node.status({}); + }); + } + RED.nodes.registerType("udp out",UDPout); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/network/lib/mqtt.js b/packages/connector/packages/node_modules/@node-red/nodes/core/network/lib/mqtt.js new file mode 100644 index 0000000..c472f01 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/network/lib/mqtt.js @@ -0,0 +1,257 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +var util = require("util"); +var mqtt = require("mqtt"); +var events = require("events"); + +util.log("[warn] nodes/core/io/lib/mqtt.js is deprecated and will be removed in a future release of Node-RED. Please report this usage to the Node-RED mailing list."); + +//var inspect = require("util").inspect; + +//var Client = module.exports.Client = function( + +var port = 1883; +var host = "localhost"; + +function MQTTClient(port,host) { + this.port = port||1883; + this.host = host||"localhost"; + this.messageId = 1; + this.pendingSubscriptions = {}; + this.inboundMessages = {}; + this.lastOutbound = (new Date()).getTime(); + this.lastInbound = (new Date()).getTime(); + this.connected = false; + + this._nextMessageId = function() { + this.messageId += 1; + if (this.messageId > 0xFFFF) { + this.messageId = 1; + } + return this.messageId; + } + events.EventEmitter.call(this); +} +util.inherits(MQTTClient, events.EventEmitter); + +MQTTClient.prototype.connect = function(options) { + if (!this.connected) { + var self = this; + options = options||{}; + self.options = options; + self.options.keepalive = options.keepalive||15; + self.options.clean = self.options.clean||true; + self.options.protocolId = 'MQIsdp'; + self.options.protocolVersion = 3; + + self.client = mqtt.createConnection(this.port,this.host,function(err,client) { + if (err) { + self.connected = false; + clearInterval(self.watchdog); + self.connectionError = true; + //util.log('[mqtt] ['+self.uid+'] connection error 1 : '+inspect(err)); + self.emit('connectionlost',err); + return; + } + client.on('close',function(e) { + //util.log('[mqtt] ['+self.uid+'] on close'); + clearInterval(self.watchdog); + if (!self.connectionError) { + if (self.connected) { + self.connected = false; + self.emit('connectionlost',e); + } else { + self.emit('disconnect'); + } + } + }); + client.on('error',function(e) { + //util.log('[mqtt] ['+self.uid+'] on error : '+inspect(e)); + clearInterval(self.watchdog); + if (self.connected) { + self.connected = false; + self.emit('connectionlost',e); + } + }); + client.on('connack',function(packet) { + if (packet.returnCode === 0) { + self.watchdog = setInterval(function(self) { + var now = (new Date()).getTime(); + + //util.log('[mqtt] ['+self.uid+'] watchdog '+inspect({connected:self.connected,connectionError:self.connectionError,pingOutstanding:self.pingOutstanding,now:now,lastOutbound:self.lastOutbound,lastInbound:self.lastInbound})); + + if (now - self.lastOutbound > self.options.keepalive*500 || now - self.lastInbound > self.options.keepalive*500) { + if (self.pingOutstanding) { + //util.log('[mqtt] ['+self.uid+'] watchdog pingOustanding - disconnect'); + try { + self.client.disconnect(); + } catch (err) { + } + } else { + //util.log('[mqtt] ['+self.uid+'] watchdog pinging'); + self.lastOutbound = (new Date()).getTime(); + self.lastInbound = (new Date()).getTime(); + self.pingOutstanding = true; + self.client.pingreq(); + } + } + + },self.options.keepalive*500,self); + self.pingOutstanding = false; + self.lastInbound = (new Date()).getTime() + self.lastOutbound = (new Date()).getTime() + self.connected = true; + self.connectionError = false; + self.emit('connect'); + } else { + self.connected = false; + self.emit('connectionlost'); + } + }); + client.on('suback',function(packet) { + self.lastInbound = (new Date()).getTime() + var topic = self.pendingSubscriptions[packet.messageId]; + self.emit('subscribe',topic,packet.granted[0]); + delete self.pendingSubscriptions[packet.messageId]; + }); + client.on('unsuback',function(packet) { + self.lastInbound = (new Date()).getTime() + var topic = self.pendingSubscriptions[packet.messageId]; + self.emit('unsubscribe',topic); + delete self.pendingSubscriptions[packet.messageId]; + }); + client.on('publish',function(packet) { + self.lastInbound = (new Date()).getTime(); + if (packet.qos < 2) { + var p = packet; + self.emit('message',p.topic,p.payload,p.qos,p.retain); + } else { + self.inboundMessages[packet.messageId] = packet; + this.lastOutbound = (new Date()).getTime() + self.client.pubrec(packet); + } + if (packet.qos == 1) { + this.lastOutbound = (new Date()).getTime() + self.client.puback(packet); + } + }); + + client.on('pubrel',function(packet) { + self.lastInbound = (new Date()).getTime() + var p = self.inboundMessages[packet.messageId]; + if (p) { + self.emit('message',p.topic,p.payload,p.qos,p.retain); + delete self.inboundMessages[packet.messageId]; + } + self.lastOutbound = (new Date()).getTime() + self.client.pubcomp(packet); + }); + + client.on('puback',function(packet) { + self.lastInbound = (new Date()).getTime() + // outbound qos-1 complete + }); + + client.on('pubrec',function(packet) { + self.lastInbound = (new Date()).getTime() + self.lastOutbound = (new Date()).getTime() + self.client.pubrel(packet); + }); + client.on('pubcomp',function(packet) { + self.lastInbound = (new Date()).getTime() + // outbound qos-2 complete + }); + client.on('pingresp',function(packet) { + //util.log('[mqtt] ['+self.uid+'] received pingresp'); + self.lastInbound = (new Date()).getTime() + self.pingOutstanding = false; + }); + + this.lastOutbound = (new Date()).getTime() + this.connectionError = false; + client.connect(self.options); + }); + } +} + +MQTTClient.prototype.subscribe = function(topic,qos) { + var self = this; + if (self.connected) { + var options = { + subscriptions:[{topic:topic,qos:qos}], + messageId: self._nextMessageId() + }; + this.pendingSubscriptions[options.messageId] = topic; + this.lastOutbound = (new Date()).getTime(); + self.client.subscribe(options); + self.client.setPacketEncoding('binary'); + } +} +MQTTClient.prototype.unsubscribe = function(topic) { + var self = this; + if (self.connected) { + var options = { + unsubscriptions:[topic], + messageId: self._nextMessageId() + }; + this.pendingSubscriptions[options.messageId] = topic; + this.lastOutbound = (new Date()).getTime() + self.client.unsubscribe(options); + } +} + +MQTTClient.prototype.publish = function(topic,payload,qos,retain) { + var self = this; + if (self.connected) { + + if (!Buffer.isBuffer(payload)) { + if (typeof payload === "object") { + payload = JSON.stringify(payload); + } else if (typeof payload !== "string") { + payload = ""+payload; + } + } + var options = { + topic: topic, + payload: payload, + qos: qos||0, + retain:retain||false + }; + if (options.qos !== 0) { + options.messageId = self._nextMessageId(); + } + this.lastOutbound = (new Date()).getTime() + self.client.publish(options); + } +} + +MQTTClient.prototype.disconnect = function() { + var self = this; + if (this.connected) { + this.connected = false; + try { + this.client.disconnect(); + } catch(err) { + } + } +} +MQTTClient.prototype.isConnected = function() { + return this.connected; +} +module.exports.createClient = function(port,host) { + var mqtt_client = new MQTTClient(port,host); + return mqtt_client; +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.html b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.html new file mode 100644 index 0000000..d42e702 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.html @@ -0,0 +1,112 @@ + +<script type="text/x-red" data-template-name="csv"> + <div class="form-row"> + <label for="node-input-temp"><i class="fa fa-list"></i> <span data-i18n="csv.label.columns"></span></label> + <input type="text" id="node-input-temp" data-i18n="[placeholder]csv.placeholder.columns"> + </div> + <div class="form-row"> + <label for="node-input-select-sep"><i class="fa fa-text-width"></i> <span data-i18n="csv.label.separator"></span></label> + <select style="width:150px" id="node-input-select-sep"> + <option value="," data-i18n="csv.separator.comma"></option> + <option value="\t" data-i18n="csv.separator.tab"></option> + <option value=" " data-i18n="csv.separator.space"></option> + <option value=";" data-i18n="csv.separator.semicolon"></option> + <option value=":" data-i18n="csv.separator.colon"></option> + <option value="#" data-i18n="csv.separator.hashtag"></option> + <option value="" data-i18n="csv.separator.other"></option> + </select> + <input style="width:40px;" type="text" id="node-input-sep" pattern="."> + </div> + + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <hr align="middle"/> + <div class="form-row"> + <label style="width:100%;"><span data-i18n="csv.label.c2o"></span></label> + </div> + <div class="form-row" style="padding-left:20px;"> + <label><i class="fa fa-sign-in"></i> <span data-i18n="csv.label.input"></span></label> + <span data-i18n="csv.label.skip-s"></span>&nbsp;<input type="text" id="node-input-skip" style="width:30px; height:25px;"/>&nbsp;<span data-i18n="csv.label.skip-e"></span><br/> + <label>&nbsp;</label> + <input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-hdrin"><label style="width:auto; margin-top:7px;" for="node-input-hdrin"><span data-i18n="csv.label.firstrow"></span></label><br/> + <label>&nbsp;</label> + <input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-strings"><label style="width:auto; margin-top:7px;" for="node-input-strings"><span data-i18n="csv.label.usestrings"></span></label><br/> + </div> + <div class="form-row" style="padding-left:20px;"> + <label><i class="fa fa-sign-out"></i> <span data-i18n="csv.label.output"></span></label> + <select type="text" id="node-input-multi" style="width:250px;"> + <option value="one" data-i18n="csv.output.row"></option> + <option value="mult" data-i18n="csv.output.array"></option> + </select> + </div> + <div class="form-row" style="margin-top:20px"> + <label style="width:100%;"><span data-i18n="csv.label.o2c"></span></label> + </div> + <div class="form-row" style="padding-left:20px;"> + <label><i class="fa fa-sign-in"></i> <span data-i18n="csv.label.output"></span></label> + <input style="width:20px; vertical-align:top; margin-right:5px;" type="checkbox" id="node-input-hdrout"><label style="width:auto;" for="node-input-hdrout"><span data-i18n="csv.label.includerow"></span></span> + </div> + <div class="form-row" style="padding-left:20px;"> + <label></label> + <label style="width:auto; margin-right:10px;" for="node-input-ret"><span data-i18n="csv.label.newline"></span></label> + <select style="width:150px;" id="node-input-ret"> + <option value='\n' data-i18n="csv.newline.linux"></option> + <option value='\r' data-i18n="csv.newline.mac"></option> + <option value='\r\n' data-i18n="csv.newline.windows"></option> + </select> + </div> +</script> + + +<script type="text/javascript"> + RED.nodes.registerType('csv',{ + category: 'parser', + color:"#DEBD5C", + defaults: { + name: {value:""}, + sep: {value:',',required:true,validate:RED.validators.regex(/^.{1,2}$/)}, + //quo: {value:'"',required:true}, + hdrin: {value:""}, + hdrout: {value:""}, + multi: {value:"one",required:true}, + ret: {value:'\\n'}, + temp: {value:""}, + skip: {value:"0"}, + strings: {value:true} + }, + inputs:1, + outputs:1, + icon: "parser-csv.svg", + label: function() { + return this.name||"csv"; + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + if (this.strings === undefined) { this.strings = true; $("#node-input-strings").prop('checked', true); } + if (this.skip === undefined) { this.skip = 0; $("#node-input-skip").val("0");} + $("#node-input-skip").spinner({ min:0 }); + if (this.sep == "," || this.sep == "\\t" || this.sep == ";" || this.sep == ":" || this.sep == " " || this.sep == "#") { + $("#node-input-select-sep").val(this.sep); + $("#node-input-sep").hide(); + } else { + $("#node-input-select-sep").val(""); + $("#node-input-sep").val(this.sep); + $("#node-input-sep").show(); + } + $("#node-input-select-sep").on("change", function() { + var v = $("#node-input-select-sep").val(); + $("#node-input-sep").val(v); + if (v == "") { + $("#node-input-sep").val(""); + $("#node-input-sep").show().focus(); + } else { + $("#node-input-sep").hide(); + } + }); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js new file mode 100644 index 0000000..290b159 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js @@ -0,0 +1,266 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + function CSVNode(n) { + RED.nodes.createNode(this,n); + this.template = (n.temp || "").split(","); + this.sep = (n.sep || ',').replace("\\t","\t").replace("\\n","\n").replace("\\r","\r"); + this.quo = '"'; + this.ret = (n.ret || "\n").replace("\\n","\n").replace("\\r","\r"); + this.winflag = (this.ret === "\r\n"); + this.lineend = "\n"; + this.multi = n.multi || "one"; + this.hdrin = n.hdrin || false; + this.hdrout = n.hdrout || false; + this.goodtmpl = true; + this.skip = parseInt(n.skip || 0); + this.store = []; + this.parsestrings = n.strings; + if (this.parsestrings === undefined) { this.parsestrings = true; } + var tmpwarn = true; + var node = this; + + // pass in an array of column names to be trimed, de-quoted and retrimed + var clean = function(col) { + for (var t = 0; t < col.length; t++) { + col[t] = col[t].trim(); // remove leading and trailing whitespace + if (col[t].charAt(0) === '"' && col[t].charAt(col[t].length -1) === '"') { + // remove leading and trailing quotes (if they exist) - and remove whitepace again. + col[t] = col[t].substr(1,col[t].length -2).trim(); + } + } + if ((col.length === 1) && (col[0] === "")) { node.goodtmpl = false; } + else { node.goodtmpl = true; } + return col; + } + node.template = clean(node.template); + + this.on("input", function(msg) { + if (msg.hasOwnProperty("payload")) { + if (typeof msg.payload == "object") { // convert object to CSV string + try { + var ou = ""; + if (node.hdrout) { + ou += node.template.join(node.sep) + node.ret; + } + if (!Array.isArray(msg.payload)) { msg.payload = [ msg.payload ]; } + for (var s = 0; s < msg.payload.length; s++) { + if ((Array.isArray(msg.payload[s])) || (typeof msg.payload[s] !== "object")) { + if (typeof msg.payload[s] !== "object") { msg.payload = [ msg.payload ]; } + for (var t = 0; t < msg.payload[s].length; t++) { + if (!msg.payload[s][t] && (msg.payload[s][t] !== 0)) { msg.payload[s][t] = ""; } + if (msg.payload[s][t].toString().indexOf(node.quo) !== -1) { // add double quotes if any quotes + msg.payload[s][t] = msg.payload[s][t].toString().replace(/"/g, '""'); + msg.payload[s][t] = node.quo + msg.payload[s][t].toString() + node.quo; + } + else if (msg.payload[s][t].toString().indexOf(node.sep) !== -1) { // add quotes if any "commas" + msg.payload[s][t] = node.quo + msg.payload[s][t].toString() + node.quo; + } + } + ou += msg.payload[s].join(node.sep) + node.ret; + } + else { + if ((node.template.length === 1) && (node.template[0] === '')) { + /* istanbul ignore else */ + if (tmpwarn === true) { // just warn about missing template once + node.warn(RED._("csv.errors.obj_csv")); + tmpwarn = false; + } + ou = ""; + for (var p in msg.payload[0]) { + /* istanbul ignore else */ + if (msg.payload[0].hasOwnProperty(p)) { + /* istanbul ignore else */ + if (typeof msg.payload[0][p] !== "object") { + var q = "" + msg.payload[0][p]; + if (q.indexOf(node.quo) !== -1) { // add double quotes if any quotes + q = q.replace(/"/g, '""'); + ou += node.quo + q + node.quo + node.sep; + } + else if (q.indexOf(node.sep) !== -1) { // add quotes if any "commas" + ou += node.quo + q + node.quo + node.sep; + } + else { ou += q + node.sep; } // otherwise just add + } + } + } + ou = ou.slice(0,-1) + node.ret; + } + else { + for (var t=0; t < node.template.length; t++) { + if (node.template[t] === '') { + ou += node.sep; + } + else { + var p = RED.util.ensureString(RED.util.getMessageProperty(msg,"payload["+s+"]['"+node.template[t]+"']")); + /* istanbul ignore else */ + if (p === "undefined") { p = ""; } + if (p.indexOf(node.quo) !== -1) { // add double quotes if any quotes + p = p.replace(/"/g, '""'); + ou += node.quo + p + node.quo + node.sep; + } + else if (p.indexOf(node.sep) !== -1) { // add quotes if any "commas" + ou += node.quo + p + node.quo + node.sep; + } + else { ou += p + node.sep; } // otherwise just add + } + } + ou = ou.slice(0,-1) + node.ret; // remove final "comma" and add "newline" + } + } + } + msg.payload = ou; + if (msg.payload !== '') { node.send(msg); } + } + catch(e) { node.error(e,msg); } + } + else if (typeof msg.payload == "string") { // convert CSV string to object + try { + var f = true; // flag to indicate if inside or outside a pair of quotes true = outside. + var j = 0; // pointer into array of template items + var k = [""]; // array of data for each of the template items + var o = {}; // output object to build up + var a = []; // output array is needed for multiline option + var first = true; // is this the first line + var line = msg.payload; + var linecount = 0; + var tmp = ""; + var reg = /^[-]?(?!E)(?!0\d)\d*\.?\d*(E-?\+?)?\d+$/i; + if (msg.hasOwnProperty("parts")) { + linecount = msg.parts.index; + if (msg.parts.index > node.skip) { first = false; } + } + + // For now we are just going to assume that any \r or \n means an end of line... + // got to be a weird csv that has singleton \r \n in it for another reason... + + // Now process the whole file/line + for (var i = 0; i < line.length; i++) { + if (first && (linecount < node.skip)) { + if (line[i] === "\n") { linecount += 1; } + continue; + } + if ((node.hdrin === true) && first) { // if the template is in the first line + if ((line[i] === "\n")||(line[i] === "\r")||(line.length - i === 1)) { // look for first line break + if (line.length - i === 1) { tmp += line[i]; } + node.template = clean(tmp.split(node.sep)); + first = false; + } + else { tmp += line[i]; } + } + else { + if (line[i] === node.quo) { // if it's a quote toggle inside or outside + f = !f; + if (line[i-1] === node.quo) { + if (f === false) { k[j] += '\"'; } + } // if it's a quotequote then it's actually a quote + //if ((line[i-1] !== node.sep) && (line[i+1] !== node.sep)) { k[j] += line[i]; } + } + else if ((line[i] === node.sep) && f) { // if it is the end of the line then finish + if (!node.goodtmpl) { node.template[j] = "col"+(j+1); } + if ( node.template[j] && (node.template[j] !== "") && (k[j] !== "" ) ) { + if ( (node.parsestrings === true) && reg.test(k[j]) ) { k[j] = parseFloat(k[j]); } + o[node.template[j]] = k[j]; + } + j += 1; + k[j] = ""; + } + else if ((line[i] === "\n") || (line[i] === "\r")) { // handle multiple lines + //console.log(j,k,o,k[j]); + if (!node.goodtmpl) { node.template[j] = "col"+(j+1); } + if ( node.template[j] && (node.template[j] !== "") && (k[j] !== "") ) { + if ( (node.parsestrings === true) && reg.test(k[j]) ) { k[j] = parseFloat(k[j]); } + else { k[j].replace(/\r$/,''); } + o[node.template[j]] = k[j]; + } + if (JSON.stringify(o) !== "{}") { // don't send empty objects + a.push(o); // add to the array + } + j = 0; + k = [""]; + o = {}; + f = true; // reset in/out flag ready for next line. + } + else { // just add to the part of the message + k[j] += line[i]; + } + } + } + // Finished so finalize and send anything left + //console.log(j,k,o,k[j]); + if (!node.goodtmpl) { node.template[j] = "col"+(j+1); } + if ( node.template[j] && (node.template[j] !== "") && (k[j] !== "") ) { + if ( (node.parsestrings === true) && reg.test(k[j]) ) { k[j] = parseFloat(k[j]); } + else { k[j].replace(/\r$/,''); } + o[node.template[j]] = k[j]; + } + if (JSON.stringify(o) !== "{}") { // don't send empty objects + a.push(o); // add to the array + } + var has_parts = msg.hasOwnProperty("parts"); + if (node.multi !== "one") { + msg.payload = a; + if (has_parts) { + if (JSON.stringify(o) !== "{}") { + node.store.push(o); + } + if (msg.parts.index + 1 === msg.parts.count) { + msg.payload = node.store; + delete msg.parts; + node.send(msg); + node.store = []; + } + } + else { + node.send(msg); // finally send the array + } + } + else { + var len = a.length; + for (var i = 0; i < len; i++) { + var newMessage = RED.util.cloneMessage(msg); + newMessage.payload = a[i]; + if (!has_parts) { + newMessage.parts = { + id: msg._msgid, + index: i, + count: len + }; + } + else { + newMessage.parts.index -= node.skip; + newMessage.parts.count -= node.skip; + if (node.hdrin) { // if we removed the header line then shift the counts by 1 + newMessage.parts.index -= 1; + newMessage.parts.count -= 1; + } + } + node.send(newMessage); + } + } + node.linecount = 0; + } + catch(e) { node.error(e,msg); } + } + else { node.warn(RED._("csv.errors.csv_js")); } + } + else { node.send(msg); } // If no payload - just pass it on. + }); + } + RED.nodes.registerType("csv",CSVNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-HTML.html b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-HTML.html new file mode 100644 index 0000000..8fa714c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-HTML.html @@ -0,0 +1,64 @@ + +<script type="text/x-red" data-template-name="html"> + <div class="form-row"> + <label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="common.label.property"></span></label> + <input type="text" id="node-input-property" style="width:70%"> + </div> + <div class="form-row"> + <label for="node-input-tag"><i class="fa fa-filter"></i> <span data-i18n="html.label.select"></span></label> + <input type="text" id="node-input-tag" placeholder="h1"> + </div> + <div class="form-row"> + <label for="node-input-ret"><i class="fa fa-sign-out"></i> <span data-i18n="html.label.output"></span></label> + <select id="node-input-ret" style="width:70%"> + <option value="html" data-i18n="html.output.html"></option> + <option value="text" data-i18n="html.output.text"></option> + <option value="attr" data-i18n="html.output.attr"></option> + <!-- <option value="val">return the value from a form element</option> --> + </select> + </div> + <div class="form-row"> + <label for="node-input-as">&nbsp;</label> + <select id="node-input-as" style="width:70%"> + <option value="single" data-i18n="html.format.single"></option> + <option value="multi" data-i18n="html.format.multi"></option> + </select> + </div> + <div class="form-row"> + <label for="node-input-outproperty">&nbsp;</label> + <span data-i18n="html.label.in" style="padding-left:8px; padding-right:2px; vertical-align:-1px;"></span> <input type="text" id="node-input-outproperty" style="width:64%"> + </div> + <br/> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" style="width:70%" data-i18n="[placeholder]common.label.name"> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('html',{ + category: 'parser', + color:"#DEBD5C", + defaults: { + name: {value:""}, + property: {value:"payload"}, + outproperty: {value:"payload"}, + tag: {value:""}, + ret: {value:"html"}, + as: {value:"single"} + }, + inputs:1, + outputs:1, + icon: "parser-html.svg", + label: function() { + return this.name||this.tag||"html"; + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + $("#node-input-property").typedInput({default:'msg',types:['msg']}); + $("#node-input-outproperty").typedInput({default:'msg',types:['msg']}); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-HTML.js b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-HTML.js new file mode 100644 index 0000000..0a24be3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-HTML.js @@ -0,0 +1,84 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var cheerio = require('cheerio'); + + function CheerioNode(n) { + RED.nodes.createNode(this,n); + this.property = n.property||"payload"; + this.outproperty = n.outproperty||this.property||"payload"; + this.tag = n.tag; + this.ret = n.ret || "html"; + this.as = n.as || "single"; + var node = this; + this.on("input", function(msg) { + var value = RED.util.getMessageProperty(msg,node.property); + if (value !== undefined) { + var tag = node.tag; + if (msg.hasOwnProperty("select")) { tag = node.tag || msg.select; } + try { + var $ = cheerio.load(value); + var pay = []; + var count = 0; + $(tag).each(function() { + count++; + }); + var index = 0; + $(tag).each(function() { + if (node.as === "multi") { + var pay2 = null; + if (node.ret === "html") { pay2 = cheerio.load($(this).html().trim()).xml(); } + if (node.ret === "text") { pay2 = $(this).text(); } + if (node.ret === "attr") { pay2 = this.attribs; } + //if (node.ret === "val") { pay2 = $(this).val(); } + /* istanbul ignore else */ + if (pay2) { + var new_msg = RED.util.cloneMessage(msg); + RED.util.setMessageProperty(new_msg,node.outproperty,pay2); + new_msg.parts = { + id: msg._msgid, + index: index, + count: count, + type: "string", + ch: "" + }; + node.send(new_msg); + } + } + if (node.as === "single") { + if (node.ret === "html") { pay.push( cheerio.load($(this).html().trim()).xml() ); } + if (node.ret === "text") { pay.push( $(this).text() ); } + if (node.ret === "attr") { pay.push( this.attribs ); } + //if (node.ret === "val") { pay.push( $(this).val() ); } + } + index++; + }); + if (node.as === "single") { // Always return an array - even if blank + RED.util.setMessageProperty(msg,node.outproperty,pay); + node.send(msg); + } + } + catch (error) { + node.error(error.message,msg); + } + } + else { node.send(msg); } // If no payload - just pass it on. + }); + } + RED.nodes.registerType("html",CheerioNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-JSON.html b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-JSON.html new file mode 100644 index 0000000..67323b2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-JSON.html @@ -0,0 +1,62 @@ + +<script type="text/x-red" data-template-name="json"> + <div class="form-row"> + <label for="node-input-action"><i class="fa fa-dot-circle-o"></i> <span data-i18n="json.label.action"></span></label> + <select style="width:70%" id="node-input-action"> + <option value="" data-i18n="json.label.actions.toggle"></option> + <option value="str" data-i18n="json.label.actions.str"></option> + <option value="obj" data-i18n="json.label.actions.obj"></option> + </select> + </div> + <div class="form-row"> + <label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="json.label.property"></span></label> + <input type="text" id="node-input-property" style="width:70%;"/> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <hr align="middle"/> + <div class="form-row node-json-to-json-options"> + <label style="width:100%;"><span data-i18n="json.label.o2j"></span></label> + </div> + <div class="form-row node-json-to-json-options" style="padding-left: 20px;"> + <input style="width:20px; vertical-align:top; margin-right: 5px;" type="checkbox" id="node-input-pretty"><label style="width: auto;" for="node-input-pretty" data-i18n="json.label.pretty"></span> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('json',{ + category: 'parser', + color:"#DEBD5C", + defaults: { + name: {value:""}, + property: {value:"payload",required:true}, + action: {value:""}, + pretty: {value:false} + }, + inputs:1, + outputs:1, + icon: "parser-json.svg", + label: function() { + return this.name||"json"; + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + if (this.property === undefined) { + $("#node-input-property").val("payload"); + } + $("#node-input-property").typedInput({default:'msg',types:['msg']}); + $("#node-input-action").on("change", function() { + if (this.value === "" || this.value === "str") { + $(".node-json-to-json-options").show(); + } else { + $(".node-json-to-json-options").hide(); + } + }); + $("#node-input-action").change(); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-JSON.js b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-JSON.js new file mode 100644 index 0000000..6611877 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-JSON.js @@ -0,0 +1,127 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + const Ajv = require('ajv'); + const ajv = new Ajv({allErrors: true, schemaId: 'auto'}); + ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-04.json')); + ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json')); + + function JSONNode(n) { + RED.nodes.createNode(this,n); + this.indent = n.pretty ? 4 : 0; + this.action = n.action||""; + this.property = n.property||"payload"; + this.schema = null; + this.compiledSchema = null; + + var node = this; + + this.on("input", function(msg) { + var validate = false; + if (msg.schema) { + // If input schema is different, re-compile it + if (JSON.stringify(this.schema) != JSON.stringify(msg.schema)) { + try { + this.compiledSchema = ajv.compile(msg.schema); + this.schema = msg.schema; + } catch(e) { + this.schema = null; + this.compiledSchema = null; + node.error(RED._("json.errors.schema-error-compile"), msg); + return; + } + } + validate = true; + } + var value = RED.util.getMessageProperty(msg,node.property); + if (value !== undefined) { + if (typeof value === "string") { + if (node.action === "" || node.action === "obj") { + try { + RED.util.setMessageProperty(msg,node.property,JSON.parse(value)); + if (validate) { + if (this.compiledSchema(msg[node.property])) { + delete msg.schema; + node.send(msg); + } else { + msg.schemaError = this.compiledSchema.errors; + node.error(`${RED._("json.errors.schema-error")}: ${ajv.errorsText(this.compiledSchema.errors)}`, msg); + } + } else { + node.send(msg); + } + } + catch(e) { node.error(e.message,msg); } + } else { + // If node.action is str and value is str + if (validate) { + if (this.compiledSchema(JSON.parse(msg[node.property]))) { + delete msg.schema; + node.send(msg); + } else { + msg.schemaError = this.compiledSchema.errors; + node.error(`${RED._("json.errors.schema-error")}: ${ajv.errorsText(this.compiledSchema.errors)}`, msg); + } + } else { + node.send(msg); + } + } + } + else if ((typeof value === "object") || (typeof value === "boolean") || (typeof value === "number")) { + if (node.action === "" || node.action === "str") { + if (!Buffer.isBuffer(value)) { + try { + if (validate) { + if (this.compiledSchema(value)) { + RED.util.setMessageProperty(msg,node.property,JSON.stringify(value,null,node.indent)); + delete msg.schema; + node.send(msg); + } else { + msg.schemaError = this.compiledSchema.errors; + node.error(`${RED._("json.errors.schema-error")}: ${ajv.errorsText(this.compiledSchema.errors)}`, msg); + } + } else { + RED.util.setMessageProperty(msg,node.property,JSON.stringify(value,null,node.indent)); + node.send(msg); + } + } + catch(e) { node.error(RED._("json.errors.dropped-error")); } + } + else { node.warn(RED._("json.errors.dropped-object")); } + } else { + // If node.action is obj and value is object + if (validate) { + if (this.compiledSchema(value)) { + delete msg.schema; + node.send(msg); + } else { + msg.schemaError = this.compiledSchema.errors; + node.error(`${RED._("json.errors.schema-error")}: ${ajv.errorsText(this.compiledSchema.errors)}`, msg); + } + } else { + node.send(msg); + } + } + } + else { node.warn(RED._("json.errors.dropped")); } + } + else { node.send(msg); } // If no property - just pass it on. + }); + } + RED.nodes.registerType("json",JSONNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-XML.html b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-XML.html new file mode 100644 index 0000000..46ca965 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-XML.html @@ -0,0 +1,49 @@ + +<script type="text/x-red" data-template-name="xml"> + <div class="form-row"> + <label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="common.label.property"></span></label> + <input type="text" id="node-input-property" style="width:70%;"/> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <hr align="middle"/> + <div class="form-row"> + <label style="width:100%;"><span data-i18n="xml.label.x2o"></span></label> + </div> + <div class="form-row" style="padding-left: 20px;"> + <label style="width:250px;" for="node-input-attr" data-i18n="xml.label.represent"></label> <input type="text" id="node-input-attr" style="text-align:center; width:40px" placeholder="$"> + </div> + <div class="form-row" style="padding-left: 20px;"> + <label style="width:250px;" for="node-input-chr" data-i18n="xml.label.prefix"></label> <input type="text" id="node-input-chr" style="text-align:center; width:40px" placeholder="_"> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('xml',{ + category: 'parser', + color:"#DEBD5C", + defaults: { + name: {value:""}, + property: {value:"payload",required:true}, + attr: {value:""}, + chr: {value:""} + }, + inputs:1, + outputs:1, + icon: "parser-xml.svg", + label: function() { + return this.name||"xml"; + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + if (this.property === undefined) { + $("#node-input-property").val("payload"); + } + $("#node-input-property").typedInput({default:'msg',types:['msg']}); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-XML.js b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-XML.js new file mode 100644 index 0000000..3bfd381 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-XML.js @@ -0,0 +1,47 @@ + +module.exports = function(RED) { + "use strict"; + var xml2js = require('xml2js'); + var parseString = xml2js.parseString; + + function XMLNode(n) { + RED.nodes.createNode(this,n); + this.attrkey = n.attr; + this.charkey = n.chr; + this.property = n.property||"payload"; + var node = this; + this.on("input", function(msg) { + var value = RED.util.getMessageProperty(msg,node.property); + if (value !== undefined) { + var options; + if (typeof value === "object") { + options = {renderOpts:{pretty:false}}; + if (msg.hasOwnProperty("options") && typeof msg.options === "object") { options = msg.options; } + options.async = false; + var builder = new xml2js.Builder(options); + value = builder.buildObject(value, options); + RED.util.setMessageProperty(msg,node.property,value); + node.send(msg); + } + else if (typeof value == "string") { + options = {}; + if (msg.hasOwnProperty("options") && typeof msg.options === "object") { options = msg.options; } + options.async = true; + options.attrkey = node.attrkey || options.attrkey || '$'; + options.charkey = node.charkey || options.charkey || '_'; + parseString(value, options, function (err, result) { + if (err) { node.error(err, msg); } + else { + value = result; + RED.util.setMessageProperty(msg,node.property,value); + node.send(msg); + } + }); + } + else { node.warn(RED._("xml.errors.xml_js")); } + } + else { node.send(msg); } // If no property - just pass it on. + }); + } + RED.nodes.registerType("xml",XMLNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-YAML.html b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-YAML.html new file mode 100644 index 0000000..403f40a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-YAML.html @@ -0,0 +1,37 @@ + +<script type="text/x-red" data-template-name="yaml"> + <div class="form-row"> + <label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="common.label.property"></span></label> + <input type="text" id="node-input-property" style="width:70%;"/> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('yaml',{ + category: 'parser', + color:"#DEBD5C", + defaults: { + property: {value:"payload",required:true}, + name: {value:""} + }, + inputs:1, + outputs:1, + icon: "parser-yaml.svg", + label: function() { + return this.name||"yaml"; + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + if (this.property === undefined) { + $("#node-input-property").val("payload"); + } + $("#node-input-property").typedInput({default:'msg',types:['msg']}); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-YAML.js b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-YAML.js new file mode 100644 index 0000000..1a34fdd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/parsers/70-YAML.js @@ -0,0 +1,39 @@ + +module.exports = function(RED) { + "use strict"; + var yaml = require('js-yaml'); + function YAMLNode(n) { + RED.nodes.createNode(this,n); + this.property = n.property||"payload"; + var node = this; + this.on("input", function(msg) { + var value = RED.util.getMessageProperty(msg,node.property); + if (value !== undefined) { + if (typeof value === "string") { + try { + value = yaml.load(value); + RED.util.setMessageProperty(msg,node.property,value); + node.send(msg); + } + catch(e) { node.error(e.message,msg); } + } + else if (typeof value === "object") { + if (!Buffer.isBuffer(value)) { + try { + value = yaml.dump(value); + RED.util.setMessageProperty(msg,node.property,value); + node.send(msg); + } + catch(e) { + node.error(RED._("yaml.errors.dropped-error")); + } + } + else { node.warn(RED._("yaml.errors.dropped-object")); } + } + else { node.warn(RED._("yaml.errors.dropped")); } + } + else { node.send(msg); } // If no payload - just pass it on. + }); + } + RED.nodes.registerType("yaml",YAMLNode); +}; diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/17-split.html b/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/17-split.html new file mode 100644 index 0000000..eccd336 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/17-split.html @@ -0,0 +1,325 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/html" data-template-name="split"> + <div class="form-row"><span data-i18n="[html]split.intro"></span></div> + <div class="form-row"><span data-i18n="[html]split.strBuff"></span></div> + <div class="form-row"> + <label for="node-input-splt" style="padding-left:10px; margin-right:-10px;" data-i18n="split.splitUsing"></label> + <input type="text" id="node-input-splt" style="width:70%"> + <input type="hidden" id="node-input-spltType"> + </div> + <div class="form-row"> + <input type="checkbox" id="node-input-stream" style="margin-left:10px; vertical-align:top; width:auto;"> + <label for="node-input-stream" style="width:auto;" data-i18n="split.stream"></label> + </div> + <div class="form-row"><span data-i18n="[html]split.array"></span></div> + <div class="form-row"> + <label for="node-input-arraySplt" style="padding-left:10px; margin-right:-10px;" data-i18n="split.splitUsing"></label> + <input type="text" id="node-input-arraySplt" style="width:70%"> + <input type="hidden" id="node-input-arraySpltType"> + </div> + <div class="form-row"><span data-i18n="[html]split.object"></span></div> + <div class="form-row" style="padding-left: 10px"><span data-i18n="[html]split.objectSend"></span></div> + <div class="form-row"> + <input type="checkbox" id="node-input-addname-cb" style="margin-left:10px; vertical-align:baseline; width:auto;"> + <label for="node-input-addname-cb" style="width:auto;" data-i18n="split.addname"></label> + <input type="text" id="node-input-addname" style="width:70%"> + </div> + <hr/> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('split',{ + category: 'sequence', + color:"#E2D96E", + defaults: { + name: {value:""}, + splt: {value:"\\n"}, + spltType: {value:"str"}, + arraySplt: {value:1}, + arraySpltType: {value:"len"}, + stream: {value:false}, + addname: {value:""} + }, + inputs:1, + outputs:1, + icon: "split.svg", + label: function() { + return this.name||this._("split.split"); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + $("#node-input-splt").typedInput({ + default: 'str', + typeField: $("#node-input-spltType"), + types:[ + 'str', + 'bin', + {value:"len", label:RED._("node-red:split.splitLength"),validate:/^\d+$/} + ] + }); + if (this.arraySplt === undefined) { + $("#node-input-arraySplt").val(1); + } + $("#node-input-arraySplt").typedInput({ + default: 'len', + typeField: $("#node-input-arraySpltType"), + types:[ + {value:"len", label:RED._("node-red:split.splitLength"),validate:/^\d+$/} + ] + }); + $("#node-input-addname").typedInput({ + typeField: $("#node-input-fnameType"), + types:['msg'] + }); + + $("#node-input-addname-cb").on("change", function() { + $("#node-input-addname").prop('disabled',!this.checked); + }) + if (this.addname === "") { + $("#node-input-addname-cb").prop('checked',false); + $("#node-input-addname").val('topic'); + } else { + $("#node-input-addname-cb").prop('checked',true); + } + $("#node-input-addname-cb").change(); + }, + oneditsave: function() { + if (!$("#node-input-addname-cb").prop('checked')) { + $("#node-input-addname").val(''); + } + } + }); +</script> + + +<script type="text/html" data-template-name="join"> + <div class="form-row"> + <label data-i18n="join.mode.mode"></label> + <select id="node-input-mode" style="width:200px;"> + <option value="auto" data-i18n="join.mode.auto"></option> + <option value="custom" data-i18n="join.mode.custom"></option> + <option value="reduce" data-i18n="join.mode.reduce"></option> + </select> + </div> + <div class="node-row-custom"> + <div class="form-row node-row-property"> + <label data-i18n="join.combine"> </label> + <input type="text" id="node-input-property" style="width:70%;"> + <input type="hidden" id="node-input-propertyType"> + </div> + <div class="form-row"> + <label data-i18n="join.create"></label> + <select id="node-input-build" style="width:70%;"> + <option value="string" data-i18n="join.type.string"></option> + <option value="buffer" data-i18n="join.type.buffer"></option> + <option value="array" data-i18n="join.type.array"></option> + <option value="object" data-i18n="join.type.object"></option> + <option value="merged" data-i18n="join.type.merged"></option> + </select> + </div> + <div class="form-row node-row-key"> + <label style="vertical-align:top; margin-top:7px; width:auto; margin-right: 5px;" data-i18n="join.using"></label> + <div style="display:inline-block"> + <input type="text" id="node-input-key" style="width:220px;"> <span data-i18n="join.key"></span> + </div> + </div> + <div class="form-row node-row-joiner"> + <label for="node-input-joiner" data-i18n="join.joinedUsing"></label> + <input type="text" id="node-input-joiner" style="width:70%"> + <input type="hidden" id="node-input-joinerType"> + </div> + <div class="form-row node-row-trigger" id="trigger-row"> + <label style="width:auto;" data-i18n="join.send"></label> + <ul> + <li> + <label style="width:280px;" for="node-input-count" data-i18n="join.afterCount"></label> <input id="node-input-count" data-i18n="[placeholder]join.count" type="text" style="width:75px;"> + </li> + <li class="node-row-accumulate" style="list-style-type:none;"> + <input type="checkbox" id="node-input-accumulate" style="display:inline-block; width:20px; margin-left:20px; vertical-align:top;"> <label style="width: auto" for="node-input-accumulate" data-i18n="join.subsequent"></label> + </li> + <li> + <label style="width:280px;" for="node-input-timeout" data-i18n="join.afterTimeout"></label> <input id="node-input-timeout" data-i18n="[placeholder]join.seconds" type="text" style="width:75px;"> + </li> + <li> + <label style="width:auto; padding-top:6px;" data-i18n="[html]join.complete"></label> + </li> + </ul> + </div> + </div> + <div class="node-row-reduce"> + <div class="form-row"> + <label for="node-input-reduceExp" data-i18n="join.reduce.exp" style="margin-left:10px;"></label> + <input type="text" id="node-input-reduceExp" data-i18n="[placeholder]join.reduce.exp-value" style="width:65%"> + </div> + <div class="form-row"> + <label for="node-input-reduceInit" data-i18n="join.reduce.init" style="margin-left:10px;"></label> + <input type="text" id="node-input-reduceInit" data-i18n="[placeholder]join.reduce.init" style="width:65%"> + <input type="hidden" id="node-input-reduceInitType"> + </div> + <div class="form-row"> + <label for="node-input-reduceFixup" data-i18n="join.reduce.fixup" style="margin-left:10px;"></label> + <input type="text" id="node-input-reduceFixup" data-i18n="[placeholder]join.reduce.exp-value" style="width:65%"> + </div> + <div class="form-row"> + <label>&nbsp;</label> + <input type="checkbox" id="node-input-reduceRight" style="display:inline-block; width:auto; vertical-align:top; margin-left:10px;"> + <label for="node-input-reduceRight" style="width:70%;" data-i18n="join.reduce.right" style="margin-left:10px;"/> + </div> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-tips form-tips-auto hide" data-i18n="[html]join.tip"></div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('join',{ + category: 'sequence', + color:"#E2D96E", + defaults: { + name: {value:""}, + mode: {value:"auto"}, + build: { value:"string"}, + property: { value:"payload", validate:RED.validators.typedInput("propertyType")}, + propertyType: { value:"msg"}, + key: {value:"topic"}, + joiner: { value:"\\n"}, + joinerType: { value:"str"}, + accumulate: { value:"false" }, + timeout: {value:""}, + count: {value:""}, + reduceRight: {value:false}, + reduceExp: {value:undefined}, + reduceInit: {value:undefined}, + reduceInitType: {value:undefined}, + reduceFixup: {value:undefined} + }, + inputs:1, + outputs:1, + icon: "join.svg", + label: function() { + return this.name||this._("join.join"); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + var node = this; + + $("#node-input-mode").on("change", function(e) { + var val = $(this).val(); + $(".node-row-custom").toggle(val==='custom'); + $(".node-row-reduce").toggle(val==='reduce'); + $(".form-tips-auto").toggle((val==='auto') || (val==='reduce')); + if (val === "auto") { + $("#node-input-accumulate").attr('checked', false); + } + else if (val === "custom") { + $("#node-input-build").change(); + } + else if (val === "reduce") { + var jsonata_or_empty = { + value: "jsonata", + label: "expression", + icon: "red/images/typedInput/expr.png", + validate: function(v) { + try{ + if(v !== "") { + jsonata(v); + } + return true; + } + catch(e){ + return false; + } + }, + expand:function() { + var that = this; + RED.editor.editExpression({ + value: this.value().replace(/\t/g,"\n"), + complete: function(v) { + that.value(v.replace(/\n/g,"\t")); + } + }) + } + }; + $("#node-input-reduceExp").typedInput({types:[jsonata_or_empty]}); + $("#node-input-reduceInit").typedInput({ + default: 'num', + types:['flow','global','str','num','bool','json','bin','date','jsonata','env'], + typeField: $("#node-input-reduceInitType") + }); + $("#node-input-reduceFixup").typedInput({types:[jsonata_or_empty]}); + } + }); + + $("#node-input-build").on("change", function(e) { + var val = $(this).val(); + $(".node-row-key").toggle(val==='object'); + $(".node-row-accumulate").toggle(val==='object' || val==='merged'); + $(".node-row-joiner").toggle(val==='string' || val==='buffer'); + $(".node-row-trigger").toggle(val!=='auto'); + if (val === 'string' || val==='buffer') { + $("#node-input-property").typedInput('types',['msg']); + $("#node-input-joiner").typedInput("show"); + } else { + $("#node-input-property").typedInput('types', ['msg', { + value: "full", + label: RED._("node-red:join.completeMessage"), + hasValue: false + }]); + } + }); + + $("#node-input-joiner").typedInput({ + default: 'str', + typeField: $("#node-input-joinerType"), + types:['str', 'bin'] + }); + + $("#node-input-property").typedInput({ + typeField: $("#node-input-propertyType"), + types: ['msg', { + value: "full", + label: RED._("node-red:join.completeMessage"), + hasValue: false + }] + }); + + $("#node-input-key").typedInput({ + types:['msg'] + }); + + $("#node-input-build").change(); + $("#node-input-mode").change(); + }, + oneditsave: function() { + var build = $("#node-input-build").val(); + if (build !== 'object' && build !== 'merged') { + $("#node-input-accumulate").prop("checked",false); + } + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/17-split.js b/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/17-split.js new file mode 100644 index 0000000..ced6375 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/17-split.js @@ -0,0 +1,691 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + + function sendArray(node,msg,array) { + for (var i = 0; i < array.length-1; i++) { + msg.payload = array[i]; + msg.parts.index = node.c++; + if (node.stream !== true) { msg.parts.count = array.length; } + node.send(RED.util.cloneMessage(msg)); + } + if (node.stream !== true) { + msg.payload = array[i]; + msg.parts.index = node.c++; + msg.parts.count = array.length; + node.send(RED.util.cloneMessage(msg)); + node.c = 0; + } + else { node.remainder = array[i]; } + } + + function SplitNode(n) { + RED.nodes.createNode(this,n); + var node = this; + node.stream = n.stream; + node.spltType = n.spltType || "str"; + node.addname = n.addname || ""; + try { + if (node.spltType === "str") { + this.splt = (n.splt || "\\n").replace(/\\n/g,"\n").replace(/\\r/g,"\r").replace(/\\t/g,"\t").replace(/\\e/g,"\e").replace(/\\f/g,"\f").replace(/\\0/g,"\0"); + } else if (node.spltType === "bin") { + var spltArray = JSON.parse(n.splt); + if (Array.isArray(spltArray)) { + this.splt = Buffer.from(spltArray); + } else { + throw new Error("not an array"); + } + this.spltBuffer = spltArray; + } else if (node.spltType === "len") { + this.splt = parseInt(n.splt); + if (isNaN(this.splt) || this.splt < 1) { + throw new Error("invalid split length: "+n.splt); + } + } + this.arraySplt = (n.arraySplt === undefined)?1:parseInt(n.arraySplt); + if (isNaN(this.arraySplt) || this.arraySplt < 1) { + throw new Error("invalid array split length: "+n.arraySplt); + } + } catch(err) { + this.error("Invalid split property: "+err.toString()); + return; + } + node.c = 0; + node.buffer = Buffer.from([]); + this.on("input", function(msg) { + if (msg.hasOwnProperty("payload")) { + if (msg.hasOwnProperty("parts")) { msg.parts = { parts:msg.parts }; } // push existing parts to a stack + else { msg.parts = {}; } + msg.parts.id = RED.util.generateId(); // generate a random id + delete msg._msgid; + if (typeof msg.payload === "string") { // Split String into array + msg.payload = (node.remainder || "") + msg.payload; + msg.parts.type = "string"; + if (node.spltType === "len") { + msg.parts.ch = ""; + msg.parts.len = node.splt; + var count = msg.payload.length/node.splt; + if (Math.floor(count) !== count) { + count = Math.ceil(count); + } + if (node.stream !== true) { + msg.parts.count = count; + node.c = 0; + } + var pos = 0; + var data = msg.payload; + for (var i=0; i<count-1; i++) { + msg.payload = data.substring(pos,pos+node.splt); + msg.parts.index = node.c++; + pos += node.splt; + node.send(RED.util.cloneMessage(msg)); + } + node.remainder = data.substring(pos); + if ((node.stream !== true) || (node.remainder.length === node.splt)) { + msg.payload = node.remainder; + msg.parts.index = node.c++; + node.send(RED.util.cloneMessage(msg)); + node.remainder = ""; + } + } + else { + var a = []; + if (node.spltType === "bin") { + if (!node.spltBufferString) { + node.spltBufferString = node.splt.toString(); + } + a = msg.payload.split(node.spltBufferString); + msg.parts.ch = node.spltBuffer; // pass the split char to other end for rejoin + } else if (node.spltType === "str") { + a = msg.payload.split(node.splt); + msg.parts.ch = node.splt; // pass the split char to other end for rejoin + } + sendArray(node,msg,a); + } + } + else if (Array.isArray(msg.payload)) { // then split array into messages + msg.parts.type = "array"; + var count = msg.payload.length/node.arraySplt; + if (Math.floor(count) !== count) { + count = Math.ceil(count); + } + msg.parts.count = count; + var pos = 0; + var data = msg.payload; + msg.parts.len = node.arraySplt; + for (var i=0; i<count; i++) { + msg.payload = data.slice(pos,pos+node.arraySplt); + if (node.arraySplt === 1) { + msg.payload = msg.payload[0]; + } + msg.parts.index = i; + pos += node.arraySplt; + node.send(RED.util.cloneMessage(msg)); + } + } + else if ((typeof msg.payload === "object") && !Buffer.isBuffer(msg.payload)) { + var j = 0; + var l = Object.keys(msg.payload).length; + var pay = msg.payload; + msg.parts.type = "object"; + for (var p in pay) { + if (pay.hasOwnProperty(p)) { + msg.payload = pay[p]; + if (node.addname !== "") { + msg[node.addname] = p; + } + msg.parts.key = p; + msg.parts.index = j; + msg.parts.count = l; + node.send(RED.util.cloneMessage(msg)); + j += 1; + } + } + } + else if (Buffer.isBuffer(msg.payload)) { + var len = node.buffer.length + msg.payload.length; + var buff = Buffer.concat([node.buffer, msg.payload], len); + msg.parts.type = "buffer"; + if (node.spltType === "len") { + var count = buff.length/node.splt; + if (Math.floor(count) !== count) { + count = Math.ceil(count); + } + if (node.stream !== true) { + msg.parts.count = count; + node.c = 0; + } + var pos = 0; + msg.parts.len = node.splt; + for (var i=0; i<count-1; i++) { + msg.payload = buff.slice(pos,pos+node.splt); + msg.parts.index = node.c++; + pos += node.splt; + node.send(RED.util.cloneMessage(msg)); + } + node.buffer = buff.slice(pos); + if ((node.stream !== true) || (node.buffer.length === node.splt)) { + msg.payload = node.buffer; + msg.parts.index = node.c++; + node.send(RED.util.cloneMessage(msg)); + node.buffer = Buffer.from([]); + } + } + else { + var count = 0; + if (node.spltType === "bin") { + msg.parts.ch = node.spltBuffer; + } else if (node.spltType === "str") { + msg.parts.ch = node.splt; + } + var pos = buff.indexOf(node.splt); + var end; + while (pos > -1) { + count++; + end = pos+node.splt.length; + pos = buff.indexOf(node.splt,end); + } + count++; + if (node.stream !== true) { + msg.parts.count = count; + node.c = 0; + } + var i = 0, p = 0; + pos = buff.indexOf(node.splt); + while (pos > -1) { + msg.payload = buff.slice(p,pos); + msg.parts.index = node.c++; + node.send(RED.util.cloneMessage(msg)); + i++; + p = pos+node.splt.length; + pos = buff.indexOf(node.splt,p); + } + if ((node.stream !== true) && (p < buff.length)) { + msg.payload = buff.slice(p,buff.length); + msg.parts.index = node.c++; + msg.parts.count = node.c++; + node.send(RED.util.cloneMessage(msg)); + } + else { + node.buffer = buff.slice(p,buff.length); + } + } + } + //else { } // otherwise drop the message. + } + }); + } + RED.nodes.registerType("split",SplitNode); + + + var _maxKeptMsgsCount; + + function maxKeptMsgsCount(node) { + if (_maxKeptMsgsCount === undefined) { + var name = "nodeMessageBufferMaxLength"; + if (RED.settings.hasOwnProperty(name)) { + _maxKeptMsgsCount = RED.settings[name]; + } + else { + _maxKeptMsgsCount = 0; + } + } + return _maxKeptMsgsCount; + } + + function applyReduce(exp, accum, msg, index, count, done) { + exp.assign("I", index); + exp.assign("N", count); + exp.assign("A", accum); + RED.util.evaluateJSONataExpression(exp, msg, done); + } + + function exp_or_undefined(exp) { + if((exp === "") || + (exp === null)) { + return undefined; + } + return exp + } + + + function reduceMessageGroup(node,msgs,exp,fixup,count,accumulator,done) { + var msg = msgs.shift(); + exp.assign("I", msg.parts.index); + exp.assign("N", count); + exp.assign("A", accumulator); + RED.util.evaluateJSONataExpression(exp, msg, (err,result) => { + if (err) { + return done(err); + } + if (msgs.length === 0) { + if (fixup) { + fixup.assign("N", count); + fixup.assign("A", result); + RED.util.evaluateJSONataExpression(fixup, {}, (err, result) => { + if (err) { + return done(err); + } + node.send({payload: result}); + done(); + }); + } else { + node.send({payload: result}); + done(); + } + } else { + reduceMessageGroup(node,msgs,exp,fixup,count,result,done); + } + }); + } + function reduceAndSendGroup(node, group, done) { + var is_right = node.reduce_right; + var flag = is_right ? -1 : 1; + var msgs = group.msgs; + try { + RED.util.evaluateNodeProperty(node.exp_init, node.exp_init_type, node, {}, (err,accum) => { + var reduceExpression = node.reduceExpression; + var fixupExpression = node.fixupExpression; + var count = group.count; + msgs.sort(function(x,y) { + var ix = x.parts.index; + var iy = y.parts.index; + if (ix < iy) {return -flag;} + if (ix > iy) {return flag;} + return 0; + }); + reduceMessageGroup(node, msgs,reduceExpression,fixupExpression,count,accum,(err,result) => { + if (err) { + done(err); + return; + } else { + done(); + } + }) + }); + } catch(err) { + done(new Error(RED._("join.errors.invalid-expr",{error:err.message}))); + } + } + + function reduceMessage(node, msg, done) { + if (msg.hasOwnProperty('parts')) { + var parts = msg.parts; + var pending = node.pending; + var pending_count = node.pending_count; + var gid = msg.parts.id; + var count; + if (!pending.hasOwnProperty(gid)) { + if(parts.hasOwnProperty('count')) { + count = msg.parts.count; + } + pending[gid] = { + count: count, + msgs: [] + }; + } + var group = pending[gid]; + var msgs = group.msgs; + if (parts.hasOwnProperty('count') && (group.count === undefined)) { + group.count = parts.count; + } + msgs.push(msg); + pending_count++; + var completeProcess = function(err) { + if (err) { + return done(err); + } + node.pending_count = pending_count; + var max_msgs = maxKeptMsgsCount(node); + if ((max_msgs > 0) && (pending_count > max_msgs)) { + node.pending = {}; + node.pending_count = 0; + done(RED._("join.too-many")); + return; + } + return done(); + } + if (msgs.length === group.count) { + delete pending[gid]; + pending_count -= msgs.length; + reduceAndSendGroup(node, group, completeProcess) + } else { + completeProcess(); + } + } else { + node.send(msg); + done(); + } + } + + function JoinNode(n) { + RED.nodes.createNode(this,n); + this.mode = n.mode||"auto"; + this.property = n.property||"payload"; + this.propertyType = n.propertyType||"msg"; + if (this.propertyType === 'full') { + this.property = "payload"; + } + this.key = n.key||"topic"; + this.timer = (this.mode === "auto") ? 0 : Number(n.timeout || 0)*1000; + this.count = Number(n.count || 0); + this.joiner = n.joiner||""; + this.joinerType = n.joinerType||"str"; + + this.reduce = (this.mode === "reduce"); + if (this.reduce) { + this.exp_init = n.reduceInit; + this.exp_init_type = n.reduceInitType; + var exp_reduce = n.reduceExp; + var exp_fixup = exp_or_undefined(n.reduceFixup); + this.reduce_right = n.reduceRight; + try { + this.reduceExpression = RED.util.prepareJSONataExpression(exp_reduce, this); + this.fixupExpression = (exp_fixup !== undefined) ? RED.util.prepareJSONataExpression(exp_fixup, this) : undefined; + } catch(e) { + this.error(RED._("join.errors.invalid-expr",{error:e.message})); + return; + } + } + + if (this.joinerType === "str") { + this.joiner = this.joiner.replace(/\\n/g,"\n").replace(/\\r/g,"\r").replace(/\\t/g,"\t").replace(/\\e/g,"\e").replace(/\\f/g,"\f").replace(/\\0/g,"\0"); + } else if (this.joinerType === "bin") { + var joinArray = JSON.parse(n.joiner || "[]"); + if (Array.isArray(joinArray)) { + this.joiner = Buffer.from(joinArray); + } else { + throw new Error("not an array"); + } + } + + this.build = n.build || "array"; + this.accumulate = n.accumulate || "false"; + + this.output = n.output || "stream"; + this.pending = {}; + this.pending_count = 0; + + //this.topic = n.topic; + var node = this; + var inflight = {}; + + var completeSend = function(partId) { + var group = inflight[partId]; + if (group.timeout) { clearTimeout(group.timeout); } + if ((node.accumulate !== true) || group.msg.hasOwnProperty("complete")) { delete inflight[partId]; } + if (group.type === 'array' && group.arrayLen > 1) { + var newArray = []; + group.payload.forEach(function(n) { + newArray = newArray.concat(n); + }) + group.payload = newArray; + } + else if (group.type === 'buffer') { + var buffers = []; + var bufferLen = 0; + if (group.joinChar !== undefined) { + var joinBuffer = Buffer.from(group.joinChar); + for (var i=0; i<group.payload.length; i++) { + if (i > 0) { + buffers.push(joinBuffer); + bufferLen += joinBuffer.length; + } + if (!Buffer.isBuffer(group.payload[i])) { + group.payload[i] = Buffer.from(group.payload[i]); + } + buffers.push(group.payload[i]); + bufferLen += group.payload[i].length; + } + } + else { + bufferLen = group.bufferLen; + buffers = group.payload; + } + group.payload = Buffer.concat(buffers,bufferLen); + } + + if (group.type === 'string') { + var groupJoinChar = group.joinChar; + if (typeof group.joinChar !== 'string') { + groupJoinChar = group.joinChar.toString(); + } + RED.util.setMessageProperty(group.msg,node.property,group.payload.join(groupJoinChar)); + } + else { + if (node.propertyType === 'full') { + group.msg = RED.util.cloneMessage(group.msg); + } + RED.util.setMessageProperty(group.msg,node.property,group.payload); + } + if (group.msg.hasOwnProperty('parts') && group.msg.parts.hasOwnProperty('parts')) { + group.msg.parts = group.msg.parts.parts; + } + else { + delete group.msg.parts; + } + delete group.msg.complete; + node.send(RED.util.cloneMessage(group.msg)); + } + + var pendingMessages = []; + var activeMessage = null; + // In reduce mode, we must process messages fully in order otherwise + // groups may overlap and cause unexpected results. The use of JSONata + // means some async processing *might* occur if flow/global context is + // accessed. + var processReduceMessageQueue = function(msg) { + if (msg) { + // A new message has arrived - add it to the message queue + pendingMessages.push(msg); + if (activeMessage !== null) { + // The node is currently processing a message, so do nothing + // more with this message + return; + } + } + if (pendingMessages.length === 0) { + // There are no more messages to process, clear the active flag + // and return + activeMessage = null; + return; + } + + // There are more messages to process. Get the next message and + // start processing it. Recurse back in to check for any more + var nextMsg = pendingMessages.shift(); + activeMessage = true; + reduceMessage(node, nextMsg, err => { + if (err) { + node.error(err,nextMsg); + } + activeMessage = null; + processReduceMessageQueue(); + }) + } + + this.on("input", function(msg) { + try { + var property; + if (node.mode === 'auto' && (!msg.hasOwnProperty("parts")||!msg.parts.hasOwnProperty("id"))) { + node.warn("Message missing msg.parts property - cannot join in 'auto' mode") + return; + } + + if (node.propertyType == "full") { + property = msg; + } + else { + try { + property = RED.util.getMessageProperty(msg,node.property); + } catch(err) { + node.warn("Message property "+node.property+" not found"); + return; + } + } + + var partId; + var payloadType; + var propertyKey; + var targetCount; + var joinChar; + var arrayLen; + var propertyIndex; + if (node.mode === "auto") { + // Use msg.parts to identify all of the group information + partId = msg.parts.id; + payloadType = msg.parts.type; + targetCount = msg.parts.count; + joinChar = msg.parts.ch; + propertyKey = msg.parts.key; + arrayLen = msg.parts.len; + propertyIndex = msg.parts.index; + } + else if (node.mode === 'reduce') { + return processReduceMessageQueue(msg); + } + else { + // Use the node configuration to identify all of the group information + partId = "_"; + payloadType = node.build; + targetCount = node.count; + joinChar = node.joiner; + if (n.count === "" && msg.hasOwnProperty('parts')) { + targetCount = msg.parts.count || 0; + } + if (node.build === 'object') { + propertyKey = RED.util.getMessageProperty(msg,node.key); + } + } + + if (msg.hasOwnProperty("reset")) { if (inflight[partId]) { delete inflight[partId] }; return; } + + if ((payloadType === 'object') && (propertyKey === null || propertyKey === undefined || propertyKey === "")) { + if (node.mode === "auto") { + node.warn("Message missing 'msg.parts.key' property - cannot add to object"); + } + else { + if (msg.hasOwnProperty('complete')) { + if (inflight[partId]) { + inflight[partId].msg.complete = msg.complete; + completeSend(partId); + } + } + else { + node.warn("Message missing key property 'msg."+node.key+"' - cannot add to object") + } + } + return; + } + + if (!inflight.hasOwnProperty(partId)) { + if (payloadType === 'object' || payloadType === 'merged') { + inflight[partId] = { + currentCount:0, + payload:{}, + targetCount:targetCount, + type:"object", + msg:RED.util.cloneMessage(msg) + }; + } + else { + inflight[partId] = { + currentCount:0, + payload:[], + targetCount:targetCount, + type:payloadType, + msg:RED.util.cloneMessage(msg) + }; + if (payloadType === 'string') { + inflight[partId].joinChar = joinChar; + } else if (payloadType === 'array') { + inflight[partId].arrayLen = arrayLen; + } else if (payloadType === 'buffer') { + inflight[partId].bufferLen = 0; + inflight[partId].joinChar = joinChar; + } + } + if (node.timer > 0) { + inflight[partId].timeout = setTimeout(function() { + completeSend(partId) + }, node.timer) + } + } + + var group = inflight[partId]; + if (payloadType === 'buffer') { + if (property !== undefined) { + if (Buffer.isBuffer(property) || (typeof property === "string") || Array.isArray(property)) { + inflight[partId].bufferLen += property.length; + } + else { + node.error(RED._("join.errors.invalid-type",{error:(typeof property)}),msg); + return; + } + } + } + if (payloadType === 'object') { + group.payload[propertyKey] = property; + group.currentCount = Object.keys(group.payload).length; + } else if (payloadType === 'merged') { + if (Array.isArray(property) || typeof property !== 'object') { + if (!msg.hasOwnProperty("complete")) { + node.warn("Cannot merge non-object types"); + } + } else { + for (propertyKey in property) { + if (property.hasOwnProperty(propertyKey) && propertyKey !== '_msgid') { + group.payload[propertyKey] = property[propertyKey]; + } + } + group.currentCount = Object.keys(group.payload).length; + //group.currentCount++; + } + } else { + if (!isNaN(propertyIndex)) { + group.payload[propertyIndex] = property; + group.currentCount++; + } else { + if (property !== undefined) { + group.payload.push(property); + group.currentCount++; + } + } + } + group.msg = Object.assign(group.msg, msg); + var tcnt = group.targetCount; + if (msg.hasOwnProperty("parts")) { tcnt = group.targetCount || msg.parts.count; } + if ((tcnt > 0 && group.currentCount >= tcnt) || msg.hasOwnProperty('complete')) { + completeSend(partId); + } + } + catch(err) { + console.log(err.stack); + } + }); + + this.on("close", function() { + for (var i in inflight) { + if (inflight.hasOwnProperty(i)) { + clearTimeout(inflight[i].timeout); + } + } + }); + } + RED.nodes.registerType("join",JoinNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/18-sort.html b/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/18-sort.html new file mode 100644 index 0000000..cf3fa24 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/18-sort.html @@ -0,0 +1,119 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-template-name="sort"> + + <div class="form-row"> + <label for="node-input-target"><i class="fa fa-dot-circle-o"></i> <span data-i18n="sort.target"></span></label> + <input type="text" id="node-input-target" style="width:70%;"> + <input type="hidden" id="node-input-targetType"> + </div> + + <div class="node-row-sort-msg-key"> + <div class="form-row"> + <label for="node-input-msgKey"><i class="fa fa-filter"></i> <span data-i18n="sort.key"></span></label> + <input type="text" id="node-input-msgKey" style="width:70%;"> + <input type="hidden" id="node-input-msgKeyType"> + </div> + </div> + + <div class="node-row-sort-seq-key"> + <div class="form-row"> + <label for="node-input-seqKey"><i class="fa fa-filter"></i> <span data-i18n="sort.key"></span></label> + <input type="text" id="node-input-seqKey" style="width:70%;"> + <input type="hidden" id="node-input-seqKeyType"> + </div> + </div> + + <div class="form-row"> + <label><i class="fa fa-random"></i> <span data-i18n="sort.order"></span></label> + <select id="node-input-order" style="width:200px;"> + <option value="ascending" data-i18n="sort.ascending"></option> + <option value="descending" data-i18n="sort.descending"></option> + </select> + </div> + + <div class="form-row" id="node-as_num"> + <label>&nbsp;</label> + <input type="checkbox" id="node-input-as_num" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-input-as_num" style="width: 70%;" data-i18n="sort.as-number"></label> + </div> + + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('sort',{ + category: 'sequence', + color:"#E2D96E", + defaults: { + name: { value:"" }, + order: { value:"ascending" }, + as_num: { value:false }, + target: { value:"payload" }, + targetType: { value:"msg" }, + msgKey: { value:"payload" }, + msgKeyType: { value:"elem" }, + seqKey: { value:"payload" }, + seqKeyType: { value:"msg" } + }, + inputs:1, + outputs:1, + icon: "sort.svg", + label: function() { + return this.name||this._("sort.sort"); + }, + labelStyle: function() { + return this.name ? "node_label_italic" : ""; + }, + oneditprepare: function() { + var seq = { + value: "seq", + label: RED._("node-red:sort.seq"), + hasValue: false + }; + var elem = { + value: "elem", + label: RED._("node-red:sort.elem"), + hasValue: false + }; + $("#node-input-target").typedInput({ + default:'msg', + typeField: $("#node-input-targetType"), + types:['msg', seq] + }); + $("#node-input-msgKey").typedInput({ + default:'elem', + typeField: $("#node-input-msgKeyType"), + types:[elem, 'jsonata'] + }); + $("#node-input-seqKey").typedInput({ + default:'msg', + typeField: $("#node-input-seqKeyType"), + types:['msg', 'jsonata'] + }); + $("#node-input-target").on("change", function(e) { + var val = $("#node-input-target").typedInput('type'); + $(".node-row-sort-msg-key").toggle(val === "msg"); + $(".node-row-sort-seq-key").toggle(val === "seq"); + }); + $("#node-input-target").change(); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/18-sort.js b/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/18-sort.js new file mode 100644 index 0000000..c330801 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/18-sort.js @@ -0,0 +1,251 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + + var _max_kept_msgs_count; + + function max_kept_msgs_count(node) { + if (_max_kept_msgs_count === undefined) { + var name = "nodeMessageBufferMaxLength"; + if (RED.settings.hasOwnProperty(name)) { + _max_kept_msgs_count = RED.settings[name]; + } + else { + _max_kept_msgs_count = 0; + } + } + return _max_kept_msgs_count; + } + + // function get_context_val(node, name, dval) { + // var context = node.context(); + // var val = context.get(name); + // if (val === undefined) { + // context.set(name, dval); + // return dval; + // } + // return val; + // } + + function SortNode(n) { + RED.nodes.createNode(this, n); + var node = this; + var pending = {};//get_context_val(node, 'pending', {}) + var pending_count = 0; + var pending_id = 0; + var order = n.order || "ascending"; + var as_num = n.as_num || false; + var target_prop = n.target || "payload"; + var target_is_prop = (n.targetType === 'msg'); + var key_is_exp = target_is_prop ? (n.msgKeyType === "jsonata") : (n.seqKeyType === "jsonata"); + var key_prop = n.seqKey || "payload"; + var key_exp = target_is_prop ? n.msgKey : n.seqKey; + + if (key_is_exp) { + try { + key_exp = RED.util.prepareJSONataExpression(key_exp, this); + } + catch (e) { + node.error(RED._("sort.invalid-exp",{message:e.toString()})); + return; + } + } + var dir = (order === "ascending") ? 1 : -1; + var conv = as_num ? function(x) { return Number(x); } + : function(x) { return x; }; + + function generateComparisonFunction(key) { + return function(x, y) { + var xp = conv(key(x)); + var yp = conv(key(y)); + if (xp === yp) { return 0; } + if (xp > yp) { return dir; } + return -dir; + }; + } + + function sortMessageGroup(group) { + var promise; + var msgs = group.msgs; + if (key_is_exp) { + var evaluatedDataPromises = msgs.map(msg => { + return new Promise((resolve,reject) => { + RED.util.evaluateJSONataExpression(key_exp, msg, (err, result) => { + if (err) { + reject(RED._("sort.invalid-exp",{message:err.toString()})); + } else { + resolve({ + item: msg, + sortValue: result + }) + } + }); + }) + }); + promise = Promise.all(evaluatedDataPromises).then(evaluatedElements => { + // Once all of the sort keys are evaluated, sort by them + var comp = generateComparisonFunction(elem=>elem.sortValue); + return evaluatedElements.sort(comp).map(elem=>elem.item); + }); + } else { + var key = function(msg) { + return ; + } + var comp = generateComparisonFunction(msg => RED.util.getMessageProperty(msg, key_prop)); + try { + msgs.sort(comp); + } + catch (e) { + return; // not send when error + } + promise = Promise.resolve(msgs); + } + return promise.then(msgs => { + for (var i = 0; i < msgs.length; i++) { + var msg = msgs[i]; + msg.parts.index = i; + node.send(msg); + } + }); + } + + function sortMessageProperty(msg) { + var data = RED.util.getMessageProperty(msg, target_prop); + if (Array.isArray(data)) { + if (key_is_exp) { + // key is an expression. Evaluated the expression for each item + // to get its sort value. As this could be async, need to do + // it first. + var evaluatedDataPromises = data.map(elem => { + return new Promise((resolve,reject) => { + RED.util.evaluateJSONataExpression(key_exp, elem, (err, result) => { + if (err) { + reject(RED._("sort.invalid-exp",{message:err.toString()})); + } else { + resolve({ + item: elem, + sortValue: result + }) + } + }); + }) + }) + return Promise.all(evaluatedDataPromises).then(evaluatedElements => { + // Once all of the sort keys are evaluated, sort by them + // and reconstruct the original message item with the newly + // sorted values. + var comp = generateComparisonFunction(elem=>elem.sortValue); + data = evaluatedElements.sort(comp).map(elem=>elem.item); + RED.util.setMessageProperty(msg, target_prop,data); + return true; + }) + } else { + var comp = generateComparisonFunction(elem=>elem); + try { + data.sort(comp); + } catch (e) { + return Promise.resolve(false); + } + return Promise.resolve(true); + } + } + return Promise.resolve(false); + } + + function removeOldestPending() { + var oldest; + var oldest_key; + for(var key in pending) { + if (pending.hasOwnProperty(key)) { + var item = pending[key]; + if((oldest === undefined) || + (oldest.seq_no > item.seq_no)) { + oldest = item; + oldest_key = key; + } + } + } + if(oldest !== undefined) { + delete pending[oldest_key]; + return oldest.msgs.length; + } + return 0; + } + + function processMessage(msg) { + if (target_is_prop) { + sortMessageProperty(msg).then(send => { + if (send) { + node.send(msg); + } + }).catch(err => { + node.error(err,msg); + }); + return; + } + var parts = msg.parts; + if (!parts || !parts.hasOwnProperty("id") || !parts.hasOwnProperty("index")) { + return; + } + var gid = parts.id; + if (!pending.hasOwnProperty(gid)) { + pending[gid] = { + count: undefined, + msgs: [], + seq_no: pending_id++ + }; + } + var group = pending[gid]; + var msgs = group.msgs; + msgs.push(msg); + if (parts.hasOwnProperty("count")) { + group.count = parts.count; + } + pending_count++; + if (group.count === msgs.length) { + delete pending[gid] + sortMessageGroup(group).catch(err => { + node.error(err,msg); + }); + pending_count -= msgs.length; + } else { + var max_msgs = max_kept_msgs_count(node); + if ((max_msgs > 0) && (pending_count > max_msgs)) { + pending_count -= removeOldestPending(); + node.error(RED._("sort.too-many"), msg); + } + } + } + + this.on("input", function(msg) { + processMessage(msg); + }); + + this.on("close", function() { + for(var key in pending) { + if (pending.hasOwnProperty(key)) { + node.log(RED._("sort.clear"), pending[key].msgs[0]); + delete pending[key]; + } + } + pending_count = 0; + }); + } + + RED.nodes.registerType("sort", SortNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/19-batch.html b/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/19-batch.html new file mode 100644 index 0000000..418ac60 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/19-batch.html @@ -0,0 +1,170 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/html" data-template-name="batch"> + <div class="form-row"> + <label for="node-input-mode"><span data-i18n="batch.mode.label"></span></label> + <select type="text" id="node-input-mode" style="width: 300px;"> + <option value="count" data-i18n="batch.mode.num-msgs"></option> + <option value="interval" data-i18n="batch.mode.interval"></option> + <option value="concat" data-i18n="batch.mode.concat"></option> + </select> + </div> + + <div class="node-row-msg-count"> + <div class="form-row node-row-count"> + <label style="margin-left: 10px; width: 175px;" for="node-input-count" data-i18n="batch.count.label"></label> + <input type="text" id="node-input-count" style="width: 50px;"> + </div> + </div> + + <div class="node-row-msg-overlap"> + <div class="form-row node-row-overlap"> + <label style="margin-left: 10px; width: 175px;" for="node-input-overlap" data-i18n="batch.count.overlap"></label> + <input type="text" id="node-input-overlap" style="width: 50px;"> + </div> + </div> + + <div class="node-row-msg-interval"> + <div class="form-row node-row-interval"> + <label style="margin-left: 10px; width: 175px;" for="node-input-interval"> <span data-i18n="batch.interval.label"></span></label> + <input type="text" id="node-input-interval" style="width: 50px;"> + <span data-i18n="batch.interval.seconds"></span> + </div> + <div class="form-row"> + <input type="checkbox" id="node-input-allowEmptySequence" style="margin-left:20px; margin-right: 10px; vertical-align:top; width:auto;"> + <label for="node-input-allowEmptySequence" style="width:auto;" data-i18n="batch.interval.empty"></label> + </div> + </div> + + <div class="node-row-msg-concat"> + <div class="form-row"> + <label data-i18n="batch.concat.topics-label"></label> + <div class="form-row node-input-topics-container-row"> + <ol id="node-input-topics-container"></ol> + </div> + </div> + </div> + + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + +</script> + +<script type="text/javascript"> + RED.nodes.registerType("batch",{ + category: "sequence", + color:"#E2D96E", + defaults: { + name: {value:""}, + mode: {value:"count"}, + count: {value:10,validate:function(v) { return RED.validators.number(v) && (v >= 1); }}, + overlap: {value:0,validate:function(v) { return RED.validators.number(v) && (v >= 0); }}, + interval: {value:10,validate:function(v) { return RED.validators.number(v) && (v >= 1); }}, + allowEmptySequence: {value:false}, + topics: {value:[{topic:""}]} + }, + inputs:1, + outputs:1, + icon: "batch.svg", + label: function() { + return this.name||this._("batch.batch");; + }, + labelStyle: function() { + return this.name ? "node_label_italic" : ""; + }, + oneditprepare: function() { + var node = this; + var topic_str = node._("batch.concat.topic"); + + function resizeTopics(topic) { + var newWidth = topic.width(); + topic.find('.red-ui-typedInput') + .typedInput("width",newWidth-15); + } + + $("#node-input-topics-container") + .css('min-height','150px').css('min-width','430px') + .editableList({ + addItem: function(container, i, opt) { + if (!opt.hasOwnProperty('topic')) { + opt.topic = ""; + } + var row = $('<div/>').appendTo(container); + var valueField = $('<input/>',{ + class:"node-input-topic-value", + type:"text", + style:"margin-left: 5px;" + }).appendTo(row) + .typedInput({default:'str', types:['str']}); + valueField.typedInput('value', opt.topic); + valueField.typedInput('type', 'str'); + valueField.attr('placeholder', topic_str); + resizeTopics(container); + }, + resizeItem: resizeTopics, + sortable: true, + removable: true + }); + + $("#node-input-count").spinner({min:1}); + $("#node-input-overlap").spinner({min:0}); + $("#node-input-interval").spinner({min:1}); + $("#node-input-mode").on("change", function(e) { + var val = $(this).val(); + $(".node-row-msg-count").toggle(val==="count"); + $(".node-row-msg-overlap").toggle(val==="count"); + $(".node-row-msg-interval").toggle(val==="interval"); + $(".node-row-msg-concat").toggle(val==="concat"); + if (val==="concat") { + var topics = node.topics; + var container = $("#node-input-topics-container"); + container.editableList('empty'); + for (var i = 0; i < topics.length; i++) { + var topic = topics[i]; + container.editableList('addItem', topic); + } + } + }); + }, + oneditsave: function() { + var topics = $("#node-input-topics-container").editableList('items'); + var node = this; + node.topics = []; + topics.each(function(i) { + var topicData = $(this).data('data'); + var topic = $(this); + var vf = topic.find(".node-input-topic-value"); + var value = vf.typedInput('value'); + var type = vf.typedInput('type'); + var r = {topic:value}; + node.topics.push(r); + }); + }, + oneditresize: function(size) { + var rows = $("#dialog-form>div:not(.node-input-topics-container-row)"); + var height = size.height; + for (var i = 0; i < rows.length; i++) { + height -= $(rows[i]).outerHeight(true); + } + var editorRow = $("#dialog-form>div.node-input-topics-container-row"); + height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom"))); + $("#node-input-topics-container").editableList('height',height); + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/19-batch.js b/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/19-batch.js new file mode 100644 index 0000000..495862a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/sequence/19-batch.js @@ -0,0 +1,246 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + + var _max_kept_msgs_count = undefined; + + function max_kept_msgs_count(node) { + if (_max_kept_msgs_count === undefined) { + var name = "nodeMessageBufferMaxLength"; + if (RED.settings.hasOwnProperty(name)) { + _max_kept_msgs_count = RED.settings[name]; + } + else { + _max_kept_msgs_count = 0; + } + } + return _max_kept_msgs_count; + } + + function send_msgs(node, msgs, clone_msg) { + var count = msgs.length; + var msg_id = msgs[0]._msgid; + for (var i = 0; i < count; i++) { + var msg = clone_msg ? RED.util.cloneMessage(msgs[i]) : msgs[i]; + if (!msg.hasOwnProperty("parts")) { + msg.parts = {}; + } + var parts = msg.parts; + parts.id = msg_id; + parts.index = i; + parts.count = count; + node.send(msg); + } + } + + function send_interval(node, allow_empty_seq) { + let msgs = node.pending; + if (msgs.length > 0) { + send_msgs(node, msgs, false); + node.pending = []; + } + else { + if (allow_empty_seq) { + let mid = RED.util.generateId(); + let msg = { + payload: null, + parts: { + id: mid, + index: 0, + count: 1 + } + }; + node.send(msg); + } + } + } + + function is_complete(pending, topic) { + if (pending.hasOwnProperty(topic)) { + var p_topic = pending[topic]; + var gids = p_topic.gids; + if (gids.length > 0) { + var gid = gids[0]; + var groups = p_topic.groups; + var group = groups[gid]; + return (group.count === group.msgs.length); + } + } + return false; + } + + function get_msgs_of_topic(pending, topic) { + var p_topic = pending[topic]; + var groups = p_topic.groups; + var gids = p_topic.gids; + var gid = gids[0]; + var group = groups[gid]; + return group.msgs; + } + + function remove_topic(pending, topic) { + var p_topic = pending[topic]; + var groups = p_topic.groups; + var gids = p_topic.gids; + var gid = gids.shift(); + delete groups[gid]; + } + + function try_concat(node, pending) { + var topics = node.topics; + for (var topic of topics) { + if (!is_complete(pending, topic)) { + return; + } + } + var msgs = []; + for (var topic of topics) { + var t_msgs = get_msgs_of_topic(pending, topic); + msgs = msgs.concat(t_msgs); + } + for (var topic of topics) { + remove_topic(pending, topic); + } + send_msgs(node, msgs, true); + node.pending_count -= msgs.length; + } + + function add_to_topic_group(pending, topic, gid, msg) { + if (!pending.hasOwnProperty(topic)) { + pending[topic] = { groups: {}, gids: [] }; + } + var p_topic = pending[topic]; + var groups = p_topic.groups; + var gids = p_topic.gids; + if (!groups.hasOwnProperty(gid)) { + groups[gid] = { msgs: [], count: undefined }; + gids.push(gid); + } + var group = groups[gid]; + group.msgs.push(msg); + if ((group.count === undefined) && + msg.parts.hasOwnProperty('count')) { + group.count = msg.parts.count; + } + } + + function concat_msg(node, msg) { + var topic = msg.topic; + if(node.topics.indexOf(topic) >= 0) { + if (!msg.hasOwnProperty("parts") || + !msg.parts.hasOwnProperty("id") || + !msg.parts.hasOwnProperty("index") || + !msg.parts.hasOwnProperty("count")) { + node.error(RED._("batch.no-parts"), msg); + return; + } + var gid = msg.parts.id; + var pending = node.pending; + add_to_topic_group(pending, topic, gid, msg); + node.pending_count++; + var max_msgs = max_kept_msgs_count(node); + if ((max_msgs > 0) && (node.pending_count > max_msgs)) { + node.pending = {}; + node.pending_count = 0; + node.error(RED._("batch.too-many"), msg); + } + try_concat(node, pending); + } + } + + function BatchNode(n) { + RED.nodes.createNode(this,n); + var node = this; + var mode = n.mode || "count"; + + node.pending_count = 0; + if (mode === "count") { + var count = Number(n.count || 1); + var overlap = Number(n.overlap || 0); + var is_overlap = (overlap > 0); + if (count <= overlap) { + node.error(RED._("batch.count.invalid")); + return; + } + node.pending = []; + this.on("input", function(msg) { + var queue = node.pending; + queue.push(msg); + node.pending_count++; + if (queue.length === count) { + send_msgs(node, queue, is_overlap); + node.pending = + (overlap === 0) ? [] : queue.slice(-overlap); + node.pending_count = 0; + } + var max_msgs = max_kept_msgs_count(node); + if ((max_msgs > 0) && (node.pending_count > max_msgs)) { + node.pending = []; + node.pending_count = 0; + node.error(RED._("batch.too-many"), msg); + } + }); + this.on("close", function() { + node.pending_count = 0; + node.pending = []; + }); + } + else if (mode === "interval") { + var interval = Number(n.interval || "0") *1000; + var allow_empty_seq = n.allowEmptySequence; + node.pending = [] + var timer = setInterval(function() { + send_interval(node, allow_empty_seq); + node.pending_count = 0; + }, interval); + this.on("input", function(msg) { + node.pending.push(msg); + node.pending_count++; + var max_msgs = max_kept_msgs_count(node); + if ((max_msgs > 0) && (node.pending_count > max_msgs)) { + node.pending = []; + node.pending_count = 0; + node.error(RED._("batch.too-many"), msg); + } + }); + this.on("close", function() { + clearInterval(timer); + node.pending = []; + node.pending_count = 0; + }); + } + else if(mode === "concat") { + node.topics = (n.topics || []).map(function(x) { + return x.topic; + }); + node.pending = {}; + this.on("input", function(msg) { + concat_msg(node, msg); + }); + this.on("close", function() { + node.pending = {}; + node.pending_count = 0; + }); + } + else { + node.error(RED._("batch.unexpected")); + } + } + + RED.nodes.registerType("batch", BatchNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/storage/10-file.html b/packages/connector/packages/node_modules/@node-red/nodes/core/storage/10-file.html new file mode 100644 index 0000000..5487920 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/storage/10-file.html @@ -0,0 +1,320 @@ + +<script type="text/html" data-template-name="file"> + <div class="form-row node-input-filename"> + <label for="node-input-filename"><i class="fa fa-file"></i> <span data-i18n="file.label.filename"></span></label> + <input id="node-input-filename" type="text"> + </div> + <div class="form-row"> + <label for="node-input-overwriteFile"><i class="fa fa-random"></i> <span data-i18n="file.label.action"></span></label> + <select type="text" id="node-input-overwriteFile" style="width: 250px;"> + <option value="false" data-i18n="file.action.append"></option> + <option value="true" data-i18n="file.action.overwrite"></option> + <option value="delete" data-i18n="file.action.delete"></option> + </select> + </div> + <div class="form-row form-row-file-write-options"> + <label>&nbsp;</label> + <input type="checkbox" id="node-input-appendNewline" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-input-appendNewline" style="width: 70%;"><span data-i18n="file.label.addnewline"></span></label> + </div> + <div class="form-row form-row-file-write-options"> + <label>&nbsp;</label> + <input type="checkbox" id="node-input-createDir" style="display: inline-block; width: auto; vertical-align: top;"> + <label for="node-input-createDir" style="width: 70%;"><span data-i18n="file.label.createdir"></span></label> + </div> + <div class="form-row form-row-file-encoding"> + <label for="node-input-encoding"><i class="fa fa-flag"></i> <span data-i18n="file.label.encoding"></span></label> + <select type="text" id="node-input-encoding" style="width: 250px;"> + </select> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-tips"><span data-i18n="file.tip"></span></div> +</script> + +<script type="text/html" data-template-name="file in"> + <div class="form-row"> + <label for="node-input-filename"><i class="fa fa-file"></i> <span data-i18n="file.label.filename"></span></label> + <input id="node-input-filename" type="text" data-i18n="[placeholder]file.label.filename"> + </div> + <div class="form-row"> + <label for="node-input-format"><i class="fa fa-sign-out"></i> <span data-i18n="file.label.outputas"></span></label> + <select id="node-input-format" style="width: 250px;"> + <option value="utf8" data-i18n="file.output.utf8"></option> + <option value="lines" data-i18n="file.output.lines"></option> + <option value="" data-i18n="file.output.buffer"></option> + <option value="stream" data-i18n="file.output.stream"></option> + </select> + </div> + <div class="form-row" id="encoding-spec"> + <label for="node-input-encoding"><i class="fa fa-flag"></i> <span data-i18n="file.label.encoding"></span></label> + <select type="text" id="node-input-encoding" style="width: 250px;"> + </select> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div class="form-tips"><span data-i18n="file.tip"></span></div> +</script> + +<script type="text/javascript"> +(function(){ + var encodings = [ + [ "file.encoding.native", + "utf8", + "ucs2", + "utf-16le", + "ascii", + "binary", + "base64", + "hex" + ], + [ "file.encoding.unicode", + "utf-16be", + ], + [ "file.encoding.japanese", + "Shift_JIS", + "Windows-31j", + "Windows932", + "EUC-JP" + ], + [ "file.encoding.chinese", + "GB2312", + "GBK", + "GB18030", + "Windows936", + "EUC-CN" + ], + [ "file.encoding.korean", + "KS_C_5601", + "Windows949", + "EUC-KR" + ], + [ "file.encoding.taiwan", + "Big5", + "Big5-HKSCS", + "Windows950" + ], + [ "file.encoding.windows", + "cp874", + "cp1250", + "cp1251", + "cp1252", + "cp1253", + "cp1254", + "cp1255", + "cp1256", + "cp1257", + "cp1258" + ], + [ "file.encoding.iso", + "ISO-8859-1", + "ISO-8859-2", + "ISO-8859-3", + "ISO-8859-4", + "ISO-8859-5", + "ISO-8859-6", + "ISO-8859-7", + "ISO-8859-8", + "ISO-8859-9", + "ISO-8859-10", + "ISO-8859-11", + "ISO-8859-12", + "ISO-8859-13", + "ISO-8859-14", + "ISO-8859-15", + "ISO-8859-16" + ], + [ "file.encoding.ibm", + "cp437", + "cp737", + "cp775", + "cp808", + "cp850", + "cp852", + "cp855", + "cp856", + "cp857", + "cp858", + "cp860", + "cp861", + "cp866", + "cp869", + "cp922", + "cp1046", + "cp1124", + "cp1125", + "cp1129", + "cp1133", + "cp1161", + "cp1162", + "cp1163" + ], + [ "file.encoding.mac", + "maccroatian", + "maccyrillic", + "macgreek", + "maciceland", + "macroman", + "macromania", + "macthai", + "macturkish", + "macukraine", + "maccenteuro", + "macintosh" + ], + [ "file.encoding.koi8", + "koi8-r", + "koi8-u", + "koi8-ru", + "koi8-t" + ], + [ "file.encoding.misc", + "armscii8", + "rk1048", + "tcvn", + "georgianacademy", + "georgianps", + "pt154", + "viscii", + "iso646cn", + "iso646jp", + "hproman8", + "tis620" + ] + ]; + + RED.nodes.registerType('file',{ + category: 'storage', + defaults: { + name: {value:""}, + filename: {value:""}, + appendNewline: {value:true}, + createDir: {value:false}, + overwriteFile: {value:"false"}, + encoding: {value:"none"} + }, + color:"BurlyWood", + inputs:1, + outputs:1, + icon: "file-out.svg", + label: function() { + if (this.overwriteFile === "delete") { + return this.name||this._("file.label.deletelabel",{file:this.filename}); + } else { + return this.name||this.filename||this._("file.label.filelabel"); + } + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + var node = this; + var encSel = $("#node-input-encoding"); + var label = node._("file.encoding.none"); + $("<option/>", { + value: "none", + label: label + }).text(label).appendTo(encSel); + encodings.forEach(function(item) { + if(Array.isArray(item)) { + var group = $("<optgroup/>", { + label: node._(item[0]) + }).appendTo(encSel); + for (var i = 1; i < item.length; i++) { + var enc = item[i]; + $("<option/>", { + value: enc, + label: enc + }).text(enc).appendTo(group); + } + } + else { + $("<option/>", { + value: item, + label: item + }).text(item).appendTo(encSel); + } + }); + encSel.val(node.encoding); + $("#node-input-overwriteFile").on("change",function() { + if (this.value === "delete") { + $(".form-row-file-write-options").hide(); + $(".form-row-file-encoding").hide(); + } else { + $(".form-row-file-write-options").show(); + $(".form-row-file-encoding").show(); + } + }); + } + }); + + RED.nodes.registerType('file in',{ + category: 'storage', + defaults: { + name: {value:""}, + filename: {value:""}, + format: {value:"utf8"}, + chunk: {value:false}, + sendError: {value: false}, + encoding: {value: "none"} + }, + color:"BurlyWood", + inputs:1, + outputs:1, + outputLabels: function(i) { + var l = this._(((this.format === "utf8")||(this.format === "lines")) ? "file.label.utf8String" : "file.label.binaryBuffer"); + return ( l + (((this.format === "lines")||(this.format === "stream")) ? "s" : "") ); + }, + icon: "file-in.svg", + label: function() { + return this.name||this.filename||this._("file.label.filelabel"); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + var node = this; + var encSel = $("#node-input-encoding"); + var label = node._("file.encoding.none"); + $("<option/>", { + value: "none", + label: label + }).text(label).appendTo(encSel); + encodings.forEach(function(item) { + if(Array.isArray(item)) { + var group = $("<optgroup/>", { + label: node._(item[0]) + }).appendTo(encSel); + for (var i = 1; i < item.length; i++) { + var enc = item[i]; + $("<option/>", { + value: enc, + label: enc + }).text(enc).appendTo(group); + } + } + else { + $("<option/>", { + value: item, + label: item + }).text(item).appendTo(encSel); + } + }); + encSel.val(node.encoding); + $("#node-input-format").on("change",function() { + var format = $("#node-input-format").val(); + if ((format === "utf8") || (format === "lines")) { + $("#encoding-spec").show(); + } + else { + $("#encoding-spec").hide(); + } + }); + } + }); +})(); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/storage/10-file.js b/packages/connector/packages/node_modules/@node-red/nodes/core/storage/10-file.js new file mode 100644 index 0000000..54ce557 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/storage/10-file.js @@ -0,0 +1,368 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var fs = require("fs-extra"); + var os = require("os"); + var path = require("path"); + var iconv = require("iconv-lite") + + function encode(data, enc) { + if (enc !== "none") { + return iconv.encode(data, enc); + } + return Buffer.from(data); + } + + function decode(data, enc) { + if (enc !== "none") { + return iconv.decode(data, enc); + } + return data.toString(); + } + + function FileNode(n) { + // Write/delete a file + RED.nodes.createNode(this,n); + this.filename = n.filename; + this.appendNewline = n.appendNewline; + this.overwriteFile = n.overwriteFile.toString(); + this.createDir = n.createDir || false; + this.encoding = n.encoding || "none"; + var node = this; + node.wstream = null; + node.msgQueue = []; + node.closing = false; + node.closeCallback = null; + + function processMsg(msg,nodeSend, done) { + var filename = node.filename || msg.filename || ""; + if ((!node.filename) && (!node.tout)) { + node.tout = setTimeout(function() { + node.status({fill:"grey",shape:"dot",text:filename}); + clearTimeout(node.tout); + node.tout = null; + },333); + } + if (filename === "") { + node.warn(RED._("file.errors.nofilename")); + done(); + } else if (node.overwriteFile === "delete") { + fs.unlink(filename, function (err) { + if (err) { + node.error(RED._("file.errors.deletefail",{error:err.toString()}),msg); + } else { + if (RED.settings.verbose) { + node.log(RED._("file.status.deletedfile",{file:filename})); + } + nodeSend(msg); + } + done(); + }); + } else if (msg.hasOwnProperty("payload") && (typeof msg.payload !== "undefined")) { + var dir = path.dirname(filename); + if (node.createDir) { + try { + fs.ensureDirSync(dir); + } catch(err) { + node.error(RED._("file.errors.createfail",{error:err.toString()}),msg); + done(); + return; + } + } + + var data = msg.payload; + if ((typeof data === "object") && (!Buffer.isBuffer(data))) { + data = JSON.stringify(data); + } + if (typeof data === "boolean") { data = data.toString(); } + if (typeof data === "number") { data = data.toString(); } + if ((node.appendNewline) && (!Buffer.isBuffer(data))) { data += os.EOL; } + var buf = encode(data, node.encoding); + if (node.overwriteFile === "true") { + var wstream = fs.createWriteStream(filename, { encoding:'binary', flags:'w', autoClose:true }); + node.wstream = wstream; + wstream.on("error", function(err) { + node.error(RED._("file.errors.writefail",{error:err.toString()}),msg); + done(); + }); + wstream.on("open", function() { + wstream.end(buf, function() { + nodeSend(msg); + done(); + }); + }) + return; + } + else { + // Append mode + var recreateStream = !node.wstream || !node.filename; + if (node.wstream && node.wstreamIno) { + // There is already a stream open and we have the inode + // of the file. Check the file hasn't been deleted + // or deleted and recreated. + try { + var stat = fs.statSync(filename); + // File exists - check the inode matches + if (stat.ino !== node.wstreamIno) { + // The file has been recreated. Close the current + // stream and recreate it + recreateStream = true; + node.wstream.end(); + delete node.wstream; + delete node.wstreamIno; + } + } catch(err) { + // File does not exist + recreateStream = true; + node.wstream.end(); + delete node.wstream; + delete node.wstreamIno; + } + } + if (recreateStream) { + node.wstream = fs.createWriteStream(filename, { encoding:'binary', flags:'a', autoClose:true }); + node.wstream.on("open", function(fd) { + try { + var stat = fs.statSync(filename); + node.wstreamIno = stat.ino; + } catch(err) { + } + }); + node.wstream.on("error", function(err) { + node.error(RED._("file.errors.appendfail",{error:err.toString()}),msg); + done(); + }); + } + if (node.filename) { + // Static filename - write and reuse the stream next time + node.wstream.write(buf, function() { + nodeSend(msg); + done(); + }); + } else { + // Dynamic filename - write and close the stream + node.wstream.end(buf, function() { + nodeSend(msg); + delete node.wstream; + delete node.wstreamIno; + done(); + }); + } + } + } + else { + done(); + } + } + + function processQueue(queue) { + var event = queue[0]; + processMsg(event.msg, event.send, function() { + event.done(); + queue.shift(); + if (queue.length > 0) { + processQueue(queue); + } + else if (node.closing) { + closeNode(); + } + }); + } + + this.on("input", function(msg,nodeSend,nodeDone) { + var msgQueue = node.msgQueue; + msgQueue.push({ + msg: msg, + send: nodeSend, + done: nodeDone + }) + if (msgQueue.length > 1) { + // pending write exists + return; + } + try { + processQueue(msgQueue); + } + catch (e) { + node.msgQueue = []; + if (node.closing) { + closeNode(); + } + throw e; + } + }); + + function closeNode() { + if (node.wstream) { node.wstream.end(); } + if (node.tout) { clearTimeout(node.tout); } + node.status({}); + var cb = node.closeCallback; + node.closeCallback = null; + node.closing = false; + if (cb) { + cb(); + } + } + + this.on('close', function(done) { + if (node.closing) { + // already closing + return; + } + node.closing = true; + if (done) { + node.closeCallback = done; + } + if (node.msgQueue.length > 0) { + // close after queue processed + return; + } + else { + closeNode(); + } + }); + } + RED.nodes.registerType("file",FileNode); + + + function FileInNode(n) { + // Read a file + RED.nodes.createNode(this,n); + this.filename = n.filename; + this.format = n.format; + this.chunk = false; + this.encoding = n.encoding || "none"; + if (n.sendError === undefined) { + this.sendError = true; + } else { + this.sendError = n.sendError; + } + if (this.format === "lines") { this.chunk = true; } + if (this.format === "stream") { this.chunk = true; } + var node = this; + + this.on("input",function(msg, nodeSend, nodeDone) { + var filename = (node.filename || msg.filename || "").replace(/\t|\r|\n/g,''); + if (!node.filename) { + node.status({fill:"grey",shape:"dot",text:filename}); + } + if (filename === "") { + node.warn(RED._("file.errors.nofilename")); + nodeDone(); + } + else { + msg.filename = filename; + var lines = Buffer.from([]); + var spare = ""; + var count = 0; + var type = "buffer"; + var ch = ""; + if (node.format === "lines") { + ch = "\n"; + type = "string"; + } + var hwm; + var getout = false; + + var rs = fs.createReadStream(filename) + .on('readable', function () { + var chunk; + var hwm = rs._readableState.highWaterMark; + while (null !== (chunk = rs.read())) { + if (node.chunk === true) { + getout = true; + if (node.format === "lines") { + spare += decode(chunk, node.encoding); + var bits = spare.split("\n"); + for (var i=0; i < bits.length - 1; i++) { + var m = { + payload:bits[i], + topic:msg.topic, + filename:msg.filename, + parts:{index:count, ch:ch, type:type, id:msg._msgid} + } + count += 1; + nodeSend(m); + } + spare = bits[i]; + } + if (node.format === "stream") { + var m = { + payload:chunk, + topic:msg.topic, + filename:msg.filename, + parts:{index:count, ch:ch, type:type, id:msg._msgid} + } + count += 1; + if (chunk.length < hwm) { // last chunk is smaller that high water mark = eof + getout = false; + m.parts.count = count; + } + nodeSend(m); + } + } + else { + lines = Buffer.concat([lines,chunk]); + } + } + }) + .on('error', function(err) { + node.error(err, msg); + if (node.sendError) { + var sendMessage = RED.util.cloneMessage(msg); + delete sendMessage.payload; + sendMessage.error = err; + nodeSend(sendMessage); + } + nodeDone(); + }) + .on('end', function() { + if (node.chunk === false) { + if (node.format === "utf8") { + msg.payload = decode(lines, node.encoding); + } + else { msg.payload = lines; } + nodeSend(msg); + } + else if (node.format === "lines") { + var m = { payload: spare, + topic:msg.topic, + parts: { + index: count, + count: count+1, + ch: ch, + type: type, + id: msg._msgid + } + }; + nodeSend(m); + } + else if (getout) { // last chunk same size as high water mark - have to send empty extra packet. + var m = { parts:{index:count, count:count, ch:ch, type:type, id:msg._msgid} }; + nodeSend(m); + } + nodeDone(); + }); + } + }); + this.on('close', function() { + node.status({}); + }); + } + RED.nodes.registerType("file in",FileInNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/storage/23-watch.html b/packages/connector/packages/node_modules/@node-red/nodes/core/storage/23-watch.html new file mode 100644 index 0000000..587eee7 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/storage/23-watch.html @@ -0,0 +1,53 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-template-name="watch"> + <div class="form-row node-input-filename"> + <label for="node-input-files"><i class="fa fa-file"></i> <span data-i18n="watch.label.files"></span></label> + <input id="node-input-files" type="text" tabindex="1" data-i18n="[placeholder]watch.placeholder.files"> + </div> + <div class="form-row"> + <label>&nbsp;</label> + <input type="checkbox" id="node-input-recursive" style="display:inline-block; width:auto; vertical-align:top;"> + <label for="node-input-recursive" style="width:70%;"> <span data-i18n="watch.label.recursive"></span></label> + </div> + <div class="form-row"> + <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> + <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> + </div> + <div id="node-input-tip" class="form-tips"><span data-i18n="watch.tip"></span></div> +</script> + +<script type="text/javascript"> + RED.nodes.registerType('watch',{ + category: 'storage', + defaults: { + name: {value:""}, + files: {value:"",required:true}, + recursive: {value:""} + }, + color:"BurlyWood", + inputs:0, + outputs:1, + icon: "watch.svg", + label: function() { + return this.name||this.files||this._("watch.watch"); + }, + labelStyle: function() { + return this.name?"node_label_italic":""; + } + }); +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/core/storage/23-watch.js b/packages/connector/packages/node_modules/@node-red/nodes/core/storage/23-watch.js new file mode 100644 index 0000000..e43317b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/core/storage/23-watch.js @@ -0,0 +1,91 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + "use strict"; + var Notify = require("fs.notify"); + var fs = require("fs"); + var path = require("path"); + + var getAllDirs = function (dir, filelist) { + filelist = filelist || []; + fs.readdirSync(dir).forEach(file => { + if (fs.statSync(path.join(dir, file)).isDirectory() ) { + filelist.push(path.join(dir, file)); + getAllDirs(path.join(dir, file), filelist); + } + }); + return filelist; + } + + function WatchNode(n) { + RED.nodes.createNode(this,n); + + this.recursive = n.recursive || false; + this.files = (n.files || "").split(","); + for (var f=0; f < this.files.length; f++) { + this.files[f] = this.files[f].trim(); + } + this.p = (this.files.length === 1) ? this.files[0] : JSON.stringify(this.files); + var node = this; + + if (node.recursive) { + for (var fi in node.files) { + if (node.files.hasOwnProperty(fi)) { + node.files = node.files.concat(getAllDirs( node.files[fi])); + } + } + } + + var notifications = new Notify(node.files); + notifications.on('change', function (file, event, fpath) { + var stat; + try { + if (fs.statSync(fpath).isDirectory()) { fpath = path.join(fpath,file); } + stat = fs.statSync(fpath); + } catch(e) { } + var type = "none"; + var msg = { payload:fpath, topic:node.p, file:file, filename:fpath }; + if (stat) { + if (stat.isFile()) { type = "file"; msg.size = stat.size; } + else if (stat.isBlockDevice()) { type = "blockdevice"; } + else if (stat.isCharacterDevice()) { type = "characterdevice"; } + else if (stat.isSocket()) { type = "socket"; } + else if (stat.isFIFO()) { type = "fifo"; } + else if (stat.isDirectory()) { + type = "directory"; + if (node.recursive) { + notifications.add([fpath]); + notifications.add(getAllDirs(fpath)); + } + } + else { type = "n/a"; } + } + msg.type = type; + node.send(msg); + }); + + notifications.on('error', function (error, fpath) { + var msg = { payload:fpath }; + node.error(error,msg); + }); + + this.close = function() { + notifications.close(); + } + } + RED.nodes.registerType("watch",WatchNode); +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/alert.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/alert.svg new file mode 100644 index 0000000..4337fb4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/alert.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-216.74 -415.04) scale(.62143)" fill="#fff"><path d="M371.3 683.97l1.61-1.61H389l1.61 1.61-3.219 40.23-3.218 3.218h-6.437l-3.219-3.218z"/><rect x="372.91" y="735.47" width="16.092" height="16.092" ry="3.017" color="#000"/></g></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/arduino.png b/packages/connector/packages/node_modules/@node-red/nodes/icons/arduino.png new file mode 100644 index 0000000..43e7d4b Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/nodes/icons/arduino.png differ diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/arrow-in.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/arrow-in.svg new file mode 100644 index 0000000..de75fbe --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/arrow-in.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M18 5v12H7v26h11v12l14-25z" fill="#fff"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/batch.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/batch.svg new file mode 100644 index 0000000..5b33280 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/batch.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><g fill="#fff" stroke-width=".612"><path d="M34.001 27.987l-4 .004v3.997l4-.01M40.001 27.987l-4 .004v3.997l4-.01M26.001 29.987l-7-7.986v15.986M34.001 13.987l-4 .004v3.997l4-.01M40.001 13.987l-4 .004v3.997l4-.01M34.001 41.988l-4 .003v3.997l4-.01M40.001 41.988l-4 .003v3.997l4-.01M8.001 27.987l-4 .004v3.997l4-.01M14.001 27.987l-4 .004v3.997l4-.01M8.001 19.987l-4 .004v3.997l4-.01M14.001 19.987l-4 .004v3.997l4-.01M8.001 35.987l-4 .004v3.997l4-.01M14.001 35.987l-4 .004v3.997l4-.01"/></g></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/bluetooth.png b/packages/connector/packages/node_modules/@node-red/nodes/icons/bluetooth.png new file mode 100644 index 0000000..1967b06 Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/nodes/icons/bluetooth.png differ diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/bridge-dash.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/bridge-dash.svg new file mode 100644 index 0000000..7c09d97 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/bridge-dash.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M19.924 6.61c4.372 5.433 7.182 13.893 7.182 23.397 0 9.493-2.804 17.946-7.167 23.379m-4.294-38.39c5.645 9.417 7.172 20.944.024 29.993m-4.36-21.661c1.338 1.459 2.215 3.906 2.215 6.68 0 2.571-.755 4.863-1.931 6.346" fill="none" stroke="#fff" stroke-dasharray="14.096, 3.524" stroke-width="3.524"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/bridge.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/bridge.svg new file mode 100644 index 0000000..1112a46 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/bridge.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M19.924 6.61c4.372 5.433 7.182 13.893 7.182 23.397 0 9.493-2.804 17.946-7.167 23.379m-4.294-38.39c5.645 9.417 7.172 20.944.024 29.993m-4.36-21.661c1.338 1.459 2.215 3.906 2.215 6.68 0 2.571-.755 4.863-1.931 6.346" fill="none" stroke="#fff" stroke-width="3.224"/></svg> \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/cog.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/cog.svg new file mode 100644 index 0000000..8cd81c5 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/cog.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M20 12a18 18 0 0 0-3.494.36l-1.428 5.715-5.06-3.036a18 18 0 0 0-4.946 4.917l3.045 5.078-5.765 1.442A18 18 0 0 0 2 30a18 18 0 0 0 .345 3.434l5.775 1.444-3.072 5.12a18 18 0 0 0 4.893 4.924l5.137-3.083 1.455 5.82A18 18 0 0 0 20 48a18 18 0 0 0 3.47-.353l1.452-5.807 5.128 3.076a18 18 0 0 0 4.905-4.913l-3.074-5.124 5.783-1.446A18 18 0 0 0 38 30a18 18 0 0 0-.367-3.529l-5.75-1.437 3.041-5.069a18 18 0 0 0-4.937-4.928l-5.065 3.038-1.433-5.728A18 18 0 0 0 20 12zm0 9a9 9 0 0 1 9 9 9 9 0 0 1-9 9 9 9 0 0 1-9-9 9 9 0 0 1 9-9z" color="#000" fill="#fff" opacity=".98" style="isolation:auto;mix-blend-mode:normal"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/comment.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/comment.svg new file mode 100644 index 0000000..73ccaec --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/comment.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M36.19 28.6c0 6.088-7.289 11.024-16.28 11.024a23.98 23.98 0 0 1-2.982-.185c-1.272-.159-7.933 7.526-13.113 6.53.18-2.004 8.18-6.004 5.87-8.79C5.993 35.16 3.63 32.066 3.63 28.6c0-6.088 7.289-11.024 16.28-11.024 8.991 0 16.28 4.936 16.28 11.024z" fill="#fff" stroke="#bababa" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" style="isolation:auto;mix-blend-mode:normal"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/db.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/db.svg new file mode 100644 index 0000000..ae60229 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/db.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-355 -704.36)"><ellipse transform="matrix(1.2868 0 0 1.9263 -64.444 -607.56)" cx="341.25" cy="688.61" rx="9.84" ry="3.25" color="#000" fill="#fff"/><path d="M387.32 750.48c0 1.949-5.669 5.879-12.662 5.879s-12.662-3.93-12.662-5.879v-27.043c0 1.949 5.669 6.242 12.662 6.242s12.662-4.293 12.662-6.242v27.043" color="#000" fill="#fff"/></g></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/debug.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/debug.svg new file mode 100644 index 0000000..927680e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/debug.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M10.004 14.499h20M10.004 46.503h20M10.004 22.5h20M10.004 30.501h20M10.004 38.502h20" stroke="#fff" stroke-width="2.9997000000000003"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/envelope.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/envelope.svg new file mode 100644 index 0000000..1376430 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/envelope.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><g fill="#fff"><path d="M20 32.96l-18-18h36z"/><path d="M2 20.36l18 18 18-18v26.1H2z"/></g></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/feed.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/feed.svg new file mode 100644 index 0000000..8df6973 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/feed.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><g fill="#b85c5c" stroke="#000"><path color="#000" d="M-.01-.004h39.998v60H-.01z" fill="none" stroke="none"/><g transform="translate(-450.266 -585.37)"><rect x="464.27" y="625.37" width="12" height="12" ry="2.4" color="#000" fill="#fff" stroke="none"/><g fill="none" stroke="#fff" stroke-width="4"><path d="M461.27 618.87l5.5-2.5h7l5.5 2.5M459.27 608.87l5.5-2.5h11l5.5 2.5M457.27 598.87l5.5-2.5h15l5.5 2.5"/></g></g></g></svg> \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/file-in.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/file-in.svg new file mode 100644 index 0000000..4004d8c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/file-in.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path color="#000" fill="none" d="M0-.04h40v60H0z"/><g fill="#fff"><path d="M5 9.96h14v16h9v7H18v10h10v7H5z"/><path d="M22 9.96l13 13H22z"/><path d="M28 25.96h7v6l5 6-4.987 6-.013 6h-7l10-12z" fill-rule="evenodd"/></g></svg> \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/file-out.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/file-out.svg new file mode 100644 index 0000000..ed2420a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/file-out.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path color="#000" fill="none" d="M0-.04h40v60H0z"/><g fill="#fff"><path d="M5 9.96h14v16h16v24H5v-7h5v7l10-12-10-12v7H5z"/><path d="M22 9.96l13 13H22z"/></g><path d="M5 30.96H0v14h5v-2H2v-10h3z" fill="#fff" fill-rule="evenodd"/></svg> \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/file.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/file.svg new file mode 100644 index 0000000..8edc658 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/file.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><g fill="#fff"><path d="M5 10h14v16h16v24H5z"/><path d="M22 10l13 13H22z"/></g></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/function.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/function.svg new file mode 100644 index 0000000..04bebc3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/function.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M30.999 31.005v-3h-6.762s.812-12.397 1.162-14 .597-3.35 2.628-3.103 1.971 3.103 1.971 3.103l4.862-.016s-.783-3.984-2.783-5.984-7.946-1.7-9.633.03c-1.687 1.73-2.302 5.065-2.597 6.422-.588 4.5-.854 9.027-1.248 13.547h-8.6v3H18.1s-.812 12.398-1.162 14-.597 3.35-2.628 3.103-1.972-3.102-1.972-3.102l-4.862.015s.783 3.985 2.783 5.985c2 2 7.946 1.699 9.634-.031 1.687-1.73 2.302-5.065 2.597-6.422.587-4.5.854-9.027 1.248-13.547z" fill="#fff"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/hash.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/hash.svg new file mode 100644 index 0000000..a8ac048 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/hash.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><g fill="#fff" stroke-width=".857"><path d="M17.997 8.998l-5.972.072-4.028 43.928 5.914.072z"/><path d="M6 16.999l-1 6 31 1 1-6z"/><path d="M31.996 8.998l-5.971.072-4.029 43.928 5.914.072z"/><path d="M3.998 37.004l-1 6 31 1 1-6z"/></g></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/inject.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/inject.svg new file mode 100644 index 0000000..841c6c2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/inject.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M18 5v12H7v9h15v-7l6 11-6 12v-8H7v9h11v12l14-25z" fill="#fff"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/join.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/join.svg new file mode 100644 index 0000000..0f7fd92 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/join.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M40.001 39.99l-.032-19.955-11.967.017v19.983l12-.046M8.001 28.027l-4 .004v3.997l4-.01M14.001 28.027l-4 .004v3.997l4-.01M25.001 30.027l-7-7.986v15.986M8.001 20.027l-4 .004v3.996l4-.01M14.001 20.027l-4 .004v3.996l4-.01M8.001 36.027l-4 .004v3.997l4-.01M14.001 36.027l-4 .004v3.997l4-.01" fill="#fff" stroke-width=".612"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/leveldb.png b/packages/connector/packages/node_modules/@node-red/nodes/icons/leveldb.png new file mode 100644 index 0000000..55760c7 Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/nodes/icons/leveldb.png differ diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/light.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/light.svg new file mode 100644 index 0000000..09d1ac9 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/light.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(.78737 0 0 .78793 -271.294 -529.99)" stroke="#fff" fill="none"><ellipse transform="matrix(1.4924 0 0 1.4616 -59.491 -343.46)" cx="287.75" cy="715.86" rx="10.75" ry="12" color="#000" stroke-width="4.071"/><path d="M362.5 717.86v15.5c6.371 2.128 8.712 2.003 15 0v-15.5" stroke-linejoin="round" stroke-width="5.01"/><path d="M366.5 717.86l1-12h5l1 12" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.006"/></g></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/link-out.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/link-out.svg new file mode 100644 index 0000000..2503488 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/link-out.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M7 38.98v3.983h11v12l13-23H19l-.463.017c-1.28 4.048-5.066 6.983-9.537 6.983zm12-11.017h12l-13-23v12H7V20.9l2 .064c4.467 0 8.25 2.93 9.534 6.972zM6.95 24.22a6 6 0 1 1-.083 11.456" fill="#fff" style="isolation:auto;mix-blend-mode:normal"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/mongodb.png b/packages/connector/packages/node_modules/@node-red/nodes/icons/mongodb.png new file mode 100644 index 0000000..3a1fc11 Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/nodes/icons/mongodb.png differ diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/mouse.png b/packages/connector/packages/node_modules/@node-red/nodes/icons/mouse.png new file mode 100644 index 0000000..5d324d2 Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/nodes/icons/mouse.png differ diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/parser-csv.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/parser-csv.svg new file mode 100644 index 0000000..fff9b50 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/parser-csv.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M26.001 7.034l-22 .043v45.958h32v-36zm-14.838 14h2.838v15.001h-3V25.738c-1.027.96-2.606 1.114-4 1.574V24.76c.734-.24 1.53-.706 2.39-1.373.861-.673 1.452-1.457 1.772-2.351zm15.948 0c1.448 0 2.824.392 3.65 1.173.828.78 1.24 1.751 1.24 2.912 0 .66-.12 1.29-.36 1.89a7.143 7.143 0 0 1-1.05 1.872c-.34.433-.952 1.057-1.84 1.87-.886.815-1.687 1.355-1.927 1.622-.233.267-.423.408-.57.662h5.748v3H21.98c.107-.987.427-2.192.96-3.072.534-.887 1.825-2.06 3.4-3.522 1.267-1.18 1.972-1.982 2.259-2.402.387-.58.402-1.154.402-1.721 0-.627.008-1.108-.332-1.441-.333-.34-1.035-.51-1.629-.51-.587 0-1.053.178-1.4.531-.347.354-.546 1.316-.6 2.137h-3.039c.167-1.548.928-3.315 1.809-3.989.88-.673 1.98-1.011 3.3-1.011zM17.002 33.036h3v1.928c0 .814-.073 1.455-.213 1.922-.14.473-.407.898-.8 1.271-.387.374-.88.666-1.481.88l-.549-1.161c.567-.187.969-.443 1.21-.77.24-.327.367-.503.38-1.07h-1.547z" fill="#fff" stroke="none" stroke-width=".612"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/parser-html.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/parser-html.svg new file mode 100644 index 0000000..66c7436 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/parser-html.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M26.001 7.034l-22 .043v45.958h32v-36zm-13 13l3 2-6 8 6 8.001-3 2-7-10zm13 0l7 10-7 10.001-3-2 6-8-6-8z" fill="#fff" stroke="none" stroke-width=".612"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/parser-json.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/parser-json.svg new file mode 100644 index 0000000..e93ab5d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/parser-json.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M26.001 7.034l-22 .043v45.958h32v-36zm-9.17 10.002h1.197v3.11c-.974 0-2.1.057-2.381.17a1.146 1.146 0 0 0-.606.493c-.131.217-.197.593-.197 1.131 0 .546-.04 1.583-.119 3.11-.044.858-.158 1.556-.342 2.093-.184.53-.421.968-.71 1.315-.281.347-.716.705-1.303 1.078.517.295.939.642 1.263 1.04.334.391.588.869.764 1.433.175.563.29 1.318.342 2.263a86.9 86.9 0 0 1 .092 2.756c0 .573.07.972.21 1.198.14.225.35.395.631.507.29.122 1.408.182 2.356.182v3.121H16.83c-1.185 0-2.093-.095-2.725-.285a3.69 3.69 0 0 1-1.604-.924 3.3 3.3 0 0 1-.869-1.613c-.149-.633-.224-1.634-.224-3.004 0-1.596-.07-2.633-.21-3.11-.192-.693-.487-1.187-.882-1.482-.386-.303-2.509-.539-3.316-.582v-3c.64-.035 2.649-.19 2.974-.346.324-.156.605-.417.842-.781.237-.373.398-.836.486-1.39.07-.417.106-1.143.106-2.175 0-1.682.08-2.852.238-3.511.158-.668.443-1.201.855-1.6.413-.408 1.012-.729 1.801-.963.535-.156 3.677-.234 2.527-.234zm5.157 0h1.197c1.15 0 1.993.078 2.528.234.79.234 1.388.555 1.8.963.413.399.698.932.856 1.6.158.659.238 1.83.238 3.511 0 1.032.036 1.758.106 2.174.087.555.25 1.018.486 1.39.237.365.517.626.842.782.324.156 2.333.311 2.973.346v3c-.807.043-2.93.278-3.315.582-.395.295-.69.789-.883 1.482-.14.477-.209 1.514-.209 3.11 0 1.37-.075 2.37-.224 3.004-.15.641-.44 1.18-.87 1.613a3.69 3.69 0 0 1-1.603.924c-.632.19-3.909.285-2.725.285h-1.197v-3.121c.947 0 2.066-.06 2.356-.182.28-.112.49-.282.63-.508.14-.225.211-.625.211-1.197 0-.399.03-1.316.092-2.756.053-.945.166-1.7.342-2.264.175-.563.43-1.041.764-1.431a4.434 4.434 0 0 1 1.263-1.041c-.587-.373-1.022-.731-1.302-1.078-.29-.347-.527-.786-.711-1.315-.185-.537-.298-1.235-.342-2.094-.08-1.526-.12-2.563-.12-3.109 0-.538-.065-.914-.197-1.13a1.146 1.146 0 0 0-.605-.495c-.28-.113-1.407-.17-2.38-.17z" fill="#fff" stroke="none" stroke-width=".612"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/parser-xml.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/parser-xml.svg new file mode 100644 index 0000000..66c7436 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/parser-xml.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M26.001 7.034l-22 .043v45.958h32v-36zm-13 13l3 2-6 8 6 8.001-3 2-7-10zm13 0l7 10-7 10.001-3-2 6-8-6-8z" fill="#fff" stroke="none" stroke-width=".612"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/parser-yaml.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/parser-yaml.svg new file mode 100644 index 0000000..f0a23ce --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/parser-yaml.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M26.001 6.987l-22 .043v45.958h32V16.987zM10.567 19.362h5.352c.768 0 1.282.104 1.543.313.273.208.41.573.41 1.093 0 .521-.163.886-.488 1.094-.313.209-.892.313-1.739.313h-.644l4.726 8.477 4.903-8.477h-.801c-.703 0-1.191-.104-1.465-.313-.273-.208-.41-.573-.41-1.094 0-.546.117-.918.352-1.113.234-.195.826-.293 1.777-.293h3.594c.99 0 1.62.104 1.894.313.287.195.43.56.43 1.093 0 .521-.143.886-.43 1.094-.273.209-.8.313-1.582.313h-.312l-6.64 11.387v6.211h2.85c1.003 0 1.641.098 1.915.293.286.182.43.534.43 1.055 0 .534-.144.905-.43 1.113-.274.195-.834.293-1.68.293h-9.277c-.847 0-1.406-.098-1.68-.293-.273-.208-.41-.58-.41-1.113 0-.521.15-.873.45-1.055.312-.195.95-.293 1.913-.293h2.832V33.29l-6.504-11.114h-.332c-.781 0-1.315-.104-1.601-.312-.287-.209-.43-.573-.43-1.094 0-.482.117-.833.351-1.055.248-.234.626-.351 1.133-.351z" fill="#fff" stroke="none" stroke-width=".612"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/range.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/range.svg new file mode 100644 index 0000000..51be7a4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/range.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M8.003 42.007h5v-18h-5zM8.003 20.006h5v-5h-5zM25 52.007h8v-29h-8zM25 15.01h8v-8h-8z" fill="#fff" stroke="none"/><path d="M15.819 15.639l6.293-2.517M15.19 42.385l7.236 3.775" fill="none" stroke="#fff" stroke-width="1.25862"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/redis.png b/packages/connector/packages/node_modules/@node-red/nodes/icons/redis.png new file mode 100644 index 0000000..92e82fd Binary files /dev/null and b/packages/connector/packages/node_modules/@node-red/nodes/icons/redis.png differ diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/rpi.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/rpi.svg new file mode 100644 index 0000000..33aa12e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/rpi.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><g fill="#fff" stroke-width=".138"><path d="M20.21 20.98c2.096-.023 4.694 1.562 4.683 3.058-.01 1.32-1.824 2.39-4.667 2.37-2.784-.034-4.656-1.344-4.65-2.623.005-1.053 2.271-2.866 4.634-2.805zM13.07 21.87c.469-.009.954.028 1.449.111 1.458.245-6.99 7.623-7.12 5.977-.116-3.756 2.39-6.027 5.671-6.088zM26.91 21.99c3.28.061 5.787 2.33 5.67 6.086-.13 1.645-8.577-5.73-7.119-5.975a7.83 7.83 0 0 1 1.449-.111zM25.76 26.59c1.56.143 3.143 1.08 4.175 2.643 1.652 2.5 1.27 5.656-.855 7.048-2.125 1.392-5.185.492-6.837-2.008-1.652-2.5-1.269-5.656.855-7.048.797-.522 1.725-.72 2.662-.635zM14.7 26.84c.937-.086 1.865.113 2.661.635 2.125 1.392 2.508 4.548.856 7.048-1.652 2.5-4.712 3.397-6.837 2.005-2.124-1.392-2.507-4.545-.855-7.045 1.032-1.563 2.614-2.5 4.175-2.643zM33.05 29.6a.728.728 0 0 1 .204.026c3.806 2.173 3.145 7.01 1.092 8.66-1.808.804-3.29-8.653-1.296-8.686zM6.95 29.73c1.994.033.512 9.49-1.296 8.687-2.053-1.651-2.714-6.486 1.092-8.66a.738.738 0 0 1 .204-.027zM20.3 36.23c2.832-.014 5.141 2.093 5.156 4.704v.049c.015 2.61-2.269 4.738-5.1 4.752-2.832.014-5.141-2.09-5.156-4.701a2.996 2.996 0 0 1 0-.051c-.015-2.611 2.268-4.74 5.1-4.753zM31.66 38.02c.4-.011.777.102 1.115.364.91.907 1.443 4.32-.15 6.366-2.195 3.045-5.165 3.164-6.272 2.316-1.157-1.092-.274-4.482 1.313-6.34 1.361-1.538 2.793-2.675 3.994-2.706zM8.65 38.74c1.29.055 2.836 1.076 4.099 2.54 1.466 1.768 2.135 4.872.91 5.788-1.157.698-3.968.409-5.967-2.463-1.347-2.409-1.175-4.86-.229-5.58a2.07 2.07 0 0 1 1.187-.285zM20.35 47.21c2.06-.09 4.824.663 4.83 1.662.033.97-2.508 3.163-4.967 3.12-2.547.11-5.045-2.085-5.012-2.846-.038-1.116 3.102-1.987 5.149-1.936zM35.13 11.03c-.569 7.356-7.409 14.128-11.629 6.971 1.363-1.52 3.853-3.306 8.133-5.513-3.33 1.132-6.335 2.64-8.85 4.716-5.838-4.296 4.734-9.675 12.346-6.174z"/><path d="M5.42 11.03c.569 7.356 7.409 14.128 11.629 6.971-1.363-1.52-3.853-3.306-8.133-5.513 3.33 1.132 6.335 2.64 8.85 4.716 5.838-4.296-4.734-9.675-12.346-6.174z"/></g></svg> \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/serial.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/serial.svg new file mode 100644 index 0000000..b07af81 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/serial.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M4.5 47.5h4l.04-34.995L19.5 12.5v35h11v-35h5" fill="none" stroke="#fff" stroke-linecap="square" stroke-width="5"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/sort.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/sort.svg new file mode 100644 index 0000000..bfb34d1 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/sort.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M20.001 19.955l-7.5-8.178-7.5 8.178h5v28h5v-28zM35.001 39.955l-7.5 8.177-7.5-8.177h5v-28h5v28z" fill="#fff" stroke-width=".531"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/split.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/split.svg new file mode 100644 index 0000000..56e0786 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/split.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M16.001 39.99l-.032-19.957-11.968.017v19.983l12-.045M34.001 28.027l-4 .004v3.997l4-.01M40.001 28.027l-4 .004v3.997l4-.01M27.001 30.027l-7-7.986v15.986M34.001 20.027l-4 .004v3.997l4-.01M40.001 20.027l-4 .004v3.997l4-.01M34.001 36.027l-4 .004v3.997l4-.01M40.001 36.027l-4 .004v3.997l4-.01" fill="#fff" stroke-width=".612"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/status.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/status.svg new file mode 100644 index 0000000..ec92644 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/status.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M0 30h9l3.5-10 5 25 5.125-30L27.5 40 31 30h9" fill="none" stroke="#fff" stroke-miterlimit="6.5" stroke-width="4"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/subflow.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/subflow.svg new file mode 100644 index 0000000..2eef4f7 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/subflow.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M25 25.94h7c.58 0 1-.42 1-1v-2c0-.58-.42-1-1-1h-7c-.58 0-1 .42-1 1v2c0 .58.42 1 1 1zm-17 12h7c.58 0 1-.42 1-1v-2c0-.58-.42-1-1-1H8c-.58 0-1 .42-1 1v2c0 .58.42 1 1 1zm-.416 11C5.624 48.94 4 47.315 4 45.356V14.522c0-1.96 1.625-3.582 3.584-3.582h24.832c1.96 0 3.584 1.623 3.584 3.582v30.834c0 1.96-1.625 3.584-3.584 3.584zM32 36.94H19c0 2.19-1.81 4-4 4H7v4.416c0 .35.235.584.584.584h24.832c.35 0 .584-.235.584-.584v-8.417zm1-2v-6h-8c-2.19 0-4-1.81-4-4h-1c-4.333-.002-8.667.004-13 0v6h8c2.19 0 4 1.81 4 4h13zm0-16v-4.418c0-.35-.235-.582-.584-.582H7.584c-.35 0-.584.233-.584.582v8.417c4.333.002 8.667.001 13 .001h1c0-2.19 1.81-4 4-4h8z" color="#000" fill="#fff"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/swap.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/swap.svg new file mode 100644 index 0000000..e004e8b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/swap.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><g fill="#fff"><path d="M12.787 26.432L9.5 18.003h-4.5v-5h8l2.286 6.286m5.357 14.286l3.357 8.428h4v-8l7 10.5-7 10.5v-8h-7.5l-2.357-6.286"/><path d="M13.001 47.003l10.857-29h4.143v8l7-10.5-7-10.5v8h-7.5l-11 29h-4.5v5z"/></g></svg> \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/switch.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/switch.svg new file mode 100644 index 0000000..639d468 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/switch.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M5.001 27.006v6l10.12-.014 3.023 7.728 2.357 6.286h7.5v8l7-10.5-7-10.5v8h-4l-3.357-8.429c-.475-1.267-.93-2.435-1.295-3.601l4.51-11.97H28v8l7-10.5-7-10.5v8h-7.5L15.098 27z" fill="#fff" stroke="none"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/template.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/template.svg new file mode 100644 index 0000000..f8cf412 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/template.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M30.041 47.91v3.485h-1.5q-6.027 0-8.084-1.79-2.033-1.792-2.033-7.14V36.68q0-3.655-1.307-5.058-1.306-1.404-4.743-1.404h-1.476v-3.46h1.476q3.46 0 4.743-1.38 1.307-1.404 1.307-5.01v-5.808q0-5.349 2.033-7.116 2.057-1.79 8.083-1.79h1.501v3.46h-1.646q-3.412 0-4.453 1.065-1.04 1.065-1.04 4.477v6.002q0 3.8-1.114 5.518-1.089 1.719-3.75 2.324 2.685.653 3.775 2.371 1.089 1.719 1.089 5.494v6.002q0 3.412 1.04 4.477t4.453 1.065z" fill="#fff" stroke="#fff" stroke-width=".719"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/timer.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/timer.svg new file mode 100644 index 0000000..fd7d3f4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/timer.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><g color="#000" transform="translate(-540 -987.36)"><path d="M565.43 1001.9c6.562 2.089 11.316 8.233 11.316 15.488 0 8.975-7.275 16.25-16.25 16.25s-16.25-7.275-16.25-16.25c0-2.802.71-5.438 1.958-7.74" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="3" style="isolation:auto;mix-blend-mode:normal"/><circle cx="560" cy="1001.4" r="1.5" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="3" style="isolation:auto;mix-blend-mode:normal"/><path d="M560 1014.4c-1.206 0-11-10.999-12.354-9.975S557 1016.148 557 1017.4s1.36 3 3 3 3-1.361 3-3-1.794-3-3-3z" fill="#fff"/></g></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/trigger.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/trigger.svg new file mode 100644 index 0000000..c132985 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/trigger.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M4.5 47.46h4l.04-34.995 10.96-.005v35h16" stroke="#fff" stroke-linecap="square" stroke-width="5" fill="none"/></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/watch.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/watch.svg new file mode 100644 index 0000000..e6411fd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/watch.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-355 -704.36)"><circle transform="translate(-43.091 -44.752) scale(.81818)" cx="505.5" cy="941.86" r="14.5" color="#000" fill="none" stroke="#fff" stroke-width="4"/><path d="M377.62 737.86l8.877 15.5" fill="none" stroke="#fff" stroke-linecap="round" stroke-width="6"/></g></svg> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/icons/white-globe.svg b/packages/connector/packages/node_modules/@node-red/nodes/icons/white-globe.svg new file mode 100644 index 0000000..63679c8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/icons/white-globe.svg @@ -0,0 +1 @@ +<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M20 12a18 18 0 0 0-14.246 7.033l2.527.844 1.983-1.797 4.89-3.715.99.93-4.085 1.918-.063 2.416 3.22-.805c.95-.68 1.899-1.364 2.849-2.045l-.249-2.29h1.364c1.506-.517 3.013-1.032 4.52-1.548l1.341 1.325-.351 1.957-2.043-.186 1.982 2.662-2.477 1.858v-1.61l-2.29.123c-.868.66-1.735 1.322-2.602 1.983l-.371 3.343-3.096.497-1.053 2.414.494.496 1.178-.31 1.238-1.425 2.106.371 1.113 1.239c1.569.691 3.139 1.382 4.707 2.074H11.068l-1.672 1.455-.31 2.662 1.797 2.85 4.582.867.99 2.662-.371 3.096 2.105 1.61 3.281.31L25 43.158l.37-1.61.56-2.044c.495-.495.988-.991 1.484-1.486l.125-1.67-2.85-1.672-1.484-2.168 1.547.496 2.416 2.414 2.351-1.3.186-2.663-2.414-.371.123-1.332h4.644l1.424 2.2c.578.309 1.157.617 1.735.927l-.249-3.127h1.239l1.3 3.437.405-1.42A18 18 0 0 0 38 30a18 18 0 0 0-18-18zM2.957 33.809l-.518.043a18 18 0 0 0 2.676 6.238c.21-.628.418-1.256.627-1.885v-2.29L5 34.242l-2.043-.434zm25.527 12.049l-5.496 1.889a18 18 0 0 0 5.496-1.889z" color="#000" fill="#fff" style="isolation:auto;mix-blend-mode:normal"/></svg> \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/nodes/index.js b/packages/connector/packages/node_modules/@node-red/nodes/index.js new file mode 100644 index 0000000..baae7e0 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/index.js @@ -0,0 +1,17 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +modules.exports = false diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/20-inject.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/20-inject.html new file mode 100644 index 0000000..958698b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/20-inject.html @@ -0,0 +1,38 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="inject"> + <p> Injiziert eine Nachricht manuell oder in regelmäßigen Intervallen in einen Nachrichtenflow. + Bei den Nutzdaten kann es sich um eine Vielzahl von Typen handeln, einschließlich Zeichenfolgen, JavaScript-Objekte oder die aktuelle Zeit. </p> + <h3> Ausgaben </h3> + <dl class="message-properties"> + <dt> Nutzdaten <span class="property-type"> verschiedene Tyoen </span> </dt> + <dd> Die konfigurierten Nutzdaten der Nachricht. </dd> + <dt class="optional"> Topic <span class="property-type"> Zeichenfolge </span> </dt> + <dd> Eine optionale Eigenschaft, die im Node konfiguriert werden kann. </dd> + </dl> + <h3> Details </h3> + <p> Der Inject-Node kann einen Flow mit einem bestimmten Nutzdatenwert starten. + Der Standard-Payload ist die aktuelle Zeit als Zeitstempel seit dem 1. Januar 1970 in Millisekunden. </p> + <p> Der Node unterstützt auch die Injektion von Zeichenfolgen, Zahlen, Boolescher Daten, JavaScript-Objekten oder flow/globalen Kontextwerten. </p> + <p> Der Node wird standardmäßig manuell ausgelöst, indem Sie im Editor auf seine Schaltfläche klicken. Er kann auch in regelmäßigen Abständen oder nach einem Zeitplan injizieren. </p> + <p> Er kann auch so konfiguriert werden, dass er jedes Mal, wenn der Flow gestartet wird einen Wert injiziert. </p> + <p> Das maximale <i> Intervall </i> , das angegeben werden kann, beträgt etwa 596 Stunden/24 Tage. Wenn Sie jedoch Intervalle grösser als 24h verwenden wollen, sollten Sie einen Scheduler-Node verwenden, der mit Stromausfällen und Neustarts besser umgehen kann. </p> + <p> <b> Hinweis </b>: Die Optionen <i> "Intervall zwischen den Zeiten" </i> und <i> "Zu einem bestimmten Zeitpunkt" </i> verwenden das Standardcron-System. + Dies bedeutet, dass 20 Minuten bedeuten, dass der Event in der nächsten Stunde, 20 Minuten nach der Stunde und 40 Minuten nach der Stunde - aber nicht in 20 Minuten Zeit. + Wenn Sie alle 20 Minuten ab sofort verwenden möchten, verwenden Sie die Option <i> "interval" </i> . </p> + <p> <b> Hinweis </b>: Um eine neue Zeile in eine Zeichenfolge einzuschließen, müssen Sie einen Funktions-Node verwenden, um die Nutzdaten zu erstellen. </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/21-debug.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/21-debug.html new file mode 100644 index 0000000..3152363 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/21-debug.html @@ -0,0 +1,32 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="debug"> + <p> Zeigt die ausgewählten Nachrichteneigenschaften auf der Registerkarte "Debug" und + optional im Laufzeitprotokoll an. Standardmäßig wird <code>msg.payload</code> angezeigt. </p> + <h3> Details </h3> + <p> Die Registerkarte "Debug" bietet eine strukturierte Sicht der Nachrichten an + wodurch die ihre Struktur leichter zu verstehen ist. </p> + <p> JavaScript-Objekte und -Arrays können nach Bedarf ausgeblendet und eingeblendet werden. + Bufferobjekte können, wenn möglich, als Rohdaten oder als Zeichenfolge angezeigt werden. </p> + <p> Neben jeder Nachricht enthält die Registerkarte "Debug" Informationen über den Zeitpunkt, + zu dem die Nachricht empfangen wurde, den Node, der sie gesendet hat, und den Typ der Nachricht. + Wenn Sie auf die ID des Quellen-Nodes klicken, wird dieser Node innerhalb des Arbeitsbereichs angezeigt. </p> + <p> Die Schaltfläche auf dem Node kann verwendet werden, um die Ausgabe zu aktivieren oder zu inaktivieren. + Es wird empfohlen, alle Debug-Nodes, die nicht verwendet werden, zu inaktivieren oder zu entfernen. </p> + <p> Der Node kann auch so konfiguriert werden, dass er alle Nachrichten an das Laufzeitprotokoll sendet, + oder dass er kurze (32 Zeichen) an den Statustext unter dem Debug-Node sendet. </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/25-catch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/25-catch.html new file mode 100644 index 0000000..3f34bd4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/25-catch.html @@ -0,0 +1,41 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="catch"> + <p> Fängt Fehler von Nodes auf derselben Registerkarte ab. </p> + <h3> Ausgaben </h3> + <dl class="message-properties"> + <dt> error.message <span class="property-type"> Zeichenfolge </span> </dt> + <dd> die Fehlernachricht. </dd> + <dt> error.source.id <span class="property-type"> Zeichenfolge </span> </dt> + <dd> Die ID des Nodes, der den Fehler ausgelöst hat. </dd> + <dt> error.source.type <span class="property-type"> Zeichenfolge </span> </dt> + <dd> Der Typ des Nodes, der den Fehler ausgelöst hat. </dd> + <dt> error.source.name <span class="property-type"> Zeichenfolge </span> </dt> + <dd> Der Name des Nodes (falls festgelegt), der den Fehler ausgelöst hat. </dd> + </dl> + <h3> Details </h3> + <p> Wenn ein Node bei der Verarbeitung einer Nachricht einen Fehler auslöst, wird der Flow in der Regel + angehalten. Dieser Node kann verwendet werden, um diese Fehler abzufangen und sie mit einem + dedizierten Flow zu bearbeiten. </p> + <p> Der Node fängt standardmäßig Fehler ab, die von einem beliebigen Node auf derselben Registerkarte ausgelöst werden. Alternativ + kann er an einen bestimmten Node gebunden werden. </p> + <p> Wenn ein Fehler ausgelöst wird, empfangen alle übereinstimmenden Fehlerabfang-Node die Nachricht. </p> + <p> Wenn ein Fehler in einem Subflow ausgelöst wird, wird der Fehler von einem Fehlerabfang-Node + innerhalb des Subflows abgefangen. Wenn keine vorhanden sind, wird zu dem Tab geleitet, + in der sich die Subflow-Instanz befindet. </p> + <p> Wenn die Nachricht bereits über eine Eigenschaft <code>error</code> verfügt, wird sie nach <code>_error</code> kopiert. </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/25-status.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/25-status.html new file mode 100644 index 0000000..c0b7f23 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/25-status.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="status"> + <p> Berichtet Statusnachrichten von anderen Node auf derselben Registerkarte. </p> + <h3> Ausgaben </h3> + <dl class="message-properties"> + <dt> status.text <span class="property-type"> Zeichenfolge </span> </dt> + <dd> Statustext </dd> + <dt> status.source.type <span class="property-type"> Zeichenfolge </span> </dt> + <dd> Der Typ des Nodes, der den Status gemeldet hat </dd> + <dt> status.source.id <span class="property-type"> Zeichenfolge </span> </dt> + <dd> Die ID des Nodes, der den Status gemeldet hat. </dd> + <dt> status.source.name <span class="property-type"> Zeichenfolge </span> </dt> + <dd> Der Name des Nodes (falls gesetzt), der den Status gemeldet hat. </dd> + </dl> + <h3> Details </h3> + <p> Dieser Node erzeugt keine <code>Nutzdaten</code>. </p> + <p> Standardmäßig meldet der Node den Status für alle Node auf derselben Registerkarte. + Er kann so konfiguriert werden, dass der Status für einzelne Nodes selektiv gemeldet wird. </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/60-link.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/60-link.html new file mode 100644 index 0000000..3698b82 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/60-link.html @@ -0,0 +1,37 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="link in"> + <p> Erstellt virtuelle Verbindungen zwischen Flows. </p> + <h3> Details </h3> + <p> Der Node kann mit jedem beliebigen <code>Link-out</code> Node auf einer beliebigen Registerkarte verbunden werden. + Sobald sie verbunden sind, verhalten sie sich so, als wären sie direkt verbunden. </p> + <p> Die Verbindungen zwischen Verknüpfungs-Node werden nur angezeigt, wenn ein Verknüpfungs-Node ausgewählt ist. + Wenn Verbindungen zu anderen Registerkarten vorhanden sind, wird ein virtueller Node angezeigt, auf den geklickt werden kann, + um zur entsprechenden Registerkarte zu springen. </p> + <p> <b> Hinweis: </b> Links können nicht in einem Subflow erstellt oder aus einem Subflow heraus erstellt werden. </p> +</script> + +<script type="text/x-red" data-help-name="link out"> + <p> Erstellt virtuelle Verbindungen zwischen Flows. </p> + <h3> Details </h3> + <p> Der Node kann mit jedem beliebigen <code>Link-out</code> Node auf einer beliebigen Registerkarte verbunden werden. + Sobald sie verbunden sind, verhalten sie sich so, als wären sie direkt verbunden. </p> + <p> Die Verbindungen zwischen Verknüpfungs-Node werden nur angezeigt, wenn ein Verknüpfungs-Node ausgewählt ist. + Wenn Verbindungen zu anderen Registerkarten vorhanden sind, wird ein virtueller Node angezeigt, auf den geklickt werden kann, + um zur entsprechenden Registerkarte zu springen. </p> + <p> <b> Hinweis: </b> Links können nicht in einem Subflow erstellt oder aus einem Subflow heraus erstellt werden. </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/90-comment.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/90-comment.html new file mode 100644 index 0000000..89368f5 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/90-comment.html @@ -0,0 +1,22 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="comment"> + <p>Ein Node, der zur Kommentierung der Flows verwendet werden kann.</p> + <h3>Details</h3> + <p>Das Textfeld des Node akzeptiert die Markdown Syntax. Der eingegebene Text wird dann in diesem Informations Panel angezeigt. + </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/98-unknown.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/98-unknown.html new file mode 100644 index 0000000..30bfa8e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/common/98-unknown.html @@ -0,0 +1,28 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="unknown"> + <p>Dieser Node ist von einem Typ, der in der aktuellen Node-RED Installation unbekannt ist.</p> + <h3>Details</h3> + <p><i>Wenn der Flow im aktuellen Zustand eingesetzt wird, bleibt die Konfiguration erhalten + aber der Flow wird nicht starten bis der vermisste Node Typ installiert ist.</i></p> + <p>Benutzen Sie die <code>Menu - Palette anpassen</code> Option um nach Nodes zu suchen und sie zu installieren + oder verwenden Sie <b>npm install &lt;module&gt;</b> um die vermissten Module zu installieren. + Starten Sie danach Node-RED neu und importieren Sie die Node erneut.</p> + <p>Es ist möglich, dass der Nodetyp bereits installiert ist, aber bestimmte Abhängigkeiten vermisst werden. + Prüfen Sie das Node-RED Protokoll auf Fehlernachrichten in Bezug auf den vermissten Nodetyp.</p> + <p>Andernfalls kontaktieren Sie den Author des Flows um Informationen über den vermissten Nodetyp zu bekommen.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/10-function.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/10-function.html new file mode 100644 index 0000000..90e524c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/10-function.html @@ -0,0 +1,55 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="function"> + <p> Ein JavaScript-Funktionsblock, der für die Nachrichten ausgeführt werden soll, die vom Node empfangen werden. </p> + <p> Die Nachrichten werden als JavaScript-Objekt mit dem Namen <code>msg</code> übergeben. </p> + <p> Er erwartet eine Eigenschaft <code> msg.payload </code> , die den Hauptteil der Nachricht enthält. </p> + <p> Die Funktion wird erwartet, dass ein Nachrichtenobjekt (oder mehrere Nachrichtenobjekte) zurückgegeben werden, kann aber + auch nichts zurückzugeben, um einen Flow zu stoppen. </p> + <h3> Details </h3> + <p> Siehe <a target="_blank" href="http://nodered.org/docs/writing-functions.html"> Onlinedokumentation </a> für weitere Informationen + zum Schreiben von Funktionen. </p> + <h4> Nachrichten senden </h4> + <p> Die Funktion kann die Nachrichten zurückgeben, die sie an die nächsten Node inm Flow weitergeben möchte + oder kann <code>node.send (msg)</code> aufrufen. </p> + <p> Es kann Folgendes zurückgeben/senden: </p> + <ul> + <li> Ein einzelnes Nachrichtenobjekt-übergeben an Node, die mit der ersten Ausgabe verbunden sind </li> + <li> ein Array von Nachrichtenobjekten, die an Nodes übergeben werden, die mit den entsprechenden Ausgaben verbunden sind </li> + </ul> + <p> Wenn ein Element des Arrays selbst ein Array von Nachrichten ist, werden mehrere Nachrichten an die entsprechende Ausgabe gesendet. </p> + <p> Wenn null zurückgegeben wird, entweder durch sich selbst oder als Element des Arrays, wird die Nachricht nicht weitergegeben. </p> + <h4> Protokollierung und Fehlerbehandlung </h4> + <p>Um alle Informationen zu protokollieren oder einen Fehler zu melden, sind die folgenden Funktionen verfügbar: </p> + <ul> + <li> <code>node.log ("Protokollnachricht")</code> </li> + <li> <code>node.warn (" Warning")</code> </li> + <li> <code>node.error ("Error")</code> </li> + </ul> + </p> + <p> Der Catch-Node kann auch zur Bearbeitung von Fehlern verwendet werden. So rufen Sie einen Catch-Node auf: + Übergeben Sie <code>msg</code> als zweites Argument an <code>node.error</code>:</p> + <pre>node.error ("Error" ,msg);</pre> + <h4> Auf Node-Informationen zugreifen </h4> + <p> Im Funktionsblock können die ID und der Name des Nodes mit den folgenden Eigenschaften referenziert werden: </p> + <ul> + <li> <code>node.id</code> - ID des Nodes </li> + <li> <code>node.name</code> - Name des Nodes </li> + </ul> + <h4> Umgebungsvariablen verwenden </h4> + <p> Auf Umgebungsvariablen kann mit <code>env.get ("MY_ENV_VAR")</code> zugegriffen werden. </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/10-switch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/10-switch.html new file mode 100644 index 0000000..fcc2c6a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/10-switch.html @@ -0,0 +1,50 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="switch"> + <p>Weiterleitung von Nachrichten basierend auf den Werten ihrer Eigenschaften oder der Position der Sequenz.</p> + <h3>Details</h3> + <p>Wenn eine Nachricht ankommt, wertet der Node jede der definierten Regeln aus + und leitet die Nachricht an die entsprechenden Ausgänge der übereinstimmenden Regeln weiter.</p> + <p>Optional kann der Node so eingestellt werden, dass er die Auswertung von Regeln einstellt, + sobald er eine passende Regel findet.</p> + <p>Die Regeln können anhand einer einzelnen Nachrichteneigenschaft, + einer Flow- oder globalen Kontext-Eigenschaft oder dem Ergebniss eines JSONata-Ausdrucks ausgewertet werden.</p> + <h4>Regeln</h4> + <p>Es gibt vier Regeltypen:</p> + <ol> + <li><b>Value</b> Regeln werden gegen die konfigurierte Eigenschaft ausgewertet.</li> + <li><b>Sequence</b> Regeln können auf Nachrichtenfolgen verwendet werden, + wie sie beispielsweise durch den Split-Node erzeugt werden.</li> + <li>Es kann ein JSONata <b>Expression</b> bereitgestellt werden, + der anhand der gesamten Nachricht bewertet wird und eine Übereinstimmung erzeugt, + wenn der Ausdruck einen wahren Wert zurückgibt.</li> + <li>Eine <b>Andernfalls</b> Regel kann verwendet werden, um eine Übereinstimmung herzustellen, + wenn keine der vorhergehenden Regeln übereinstimmt.</li> + </ol> + <h4>Bemerkungen</h4> + <p>Die <code>is true/false</code> und <code>is null</code> Regeln führen strenge Vergleiche mit diesen Typen durch. + Sie konvertieren nicht zwischen den Typen.</p> + <p>Die <code>is empty</code>Regel passt nur für Strings, Arrays und Buffer, die eine Länge von 0 haben + oder Objekte, die keine Eigenschaften haben aber nicht für <code>null</code> oder <code>undefiniert</code>.</p> + <h4>Behandlung von Nachrichtenfolgen</h4> + <p>Standardmäßig ändert der Node nicht die Eigenschaft <code>msg.parts</code> für Nachrichten, + die Teil einer Sequenz sind.</p> + <p>Die Option <b>Nachrichtenfolgen neu erstellen</b> kann aktiviert werden, um neue Nachrichtenfolgen für jede passende Regel zu generieren. + In diesem Modus puffert der Node die gesamte eingehende Sequenz, bevor er die neuen Sequenzen weiter sendet. + Mit der Laufzeiteinstellung <code>nodeMessageBufferMaxLength</code> kann begrenzt werden, + wie viele Nachrichten im Node zwischengespeichert werden sollen.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/15-change.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/15-change.html new file mode 100644 index 0000000..b78dd0f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/15-change.html @@ -0,0 +1,38 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="change"> + <p>Setzen, Ändern, Löschen oder Verschieben von Eigenschaften einer Nachricht, eines Flow-Kontextes oder eines globalen Kontextes.</p> + <p>Der Node kann mehrere Regeln angeben, die in der Reihenfolge ihrer Definition angewendet werden.</p> + <h3>Details</h3> + <p>Die verfügbaren Operationen sind:</p> + <dl class="message-properties"> + <dt>Setze</dt> + <dd>Setzt eine Eigenschaft. Der Wert kann eine Vielzahl von verschiedenen Typen sein + oder aus einer bestehenden Nachricht oder einer Kontext-Eigenschaft übernommen werden.</dd> + <dt>Ändere</dt> + <dd>Suchen und Ersetzen von Teilen der Eigenschaft. Wenn reguläre Ausdrücke aktiviert sind, + kann die Eigenschaft "Ersetzen mit" sogenante Capture groups beinhalten, z.B. <code>$1</code>. + Ersetzen ändert den Typ nur, wenn eine vollständige Übereinstimmung vorliegt.</dd> + <dt>Löschen</dt> + <dd>Löscht eine Eigenschaft.</dd> + <dt>Verschiebe</dt> + <dd>Verschiebt eine Eigneschft oder benennt sie um.</dd> + </dl> + <p>Der Typ "expression" verwendet die Abfrage- und Ausdruckssprache + <a href="http://jsonata.org/" target="_new">JSONata</a>. + </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/16-range.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/16-range.html new file mode 100644 index 0000000..73935d1 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/16-range.html @@ -0,0 +1,37 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="range"> + <p>Ordnet einen numerischen Wert einem anderen Bereich zu..</p> + <h3>Eingaben</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">Zahl</span></dt> + <dd>Der Payload <i>muss</i> eine Zahl sein. + Alles andere wird versucht als Zahl interpretiert zu werden und abgelehnt, wenn das fehlschlägt.</dd> + </dl> + <h3>Ausgaben</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">Zahl</span></dt> + <dd>Der Wert, der dem neuen Bereich zugeordnet ist.</dd> + </dl> + <h3>Details</h3> + <p>Dieser Node skaliert den empfangenen Wert linear. + Standardmäßig ist das Ergebnis nicht auf den im Node definierten Bereich beschränkt.</p> + <p><i>Skalieren und begrenzen auf den Zielbereich</i> bedeutet, + dass das Ergebnis niemals außerhalb des im Ergebnisbereich angegebenen Bereichs liegt.</p> + <p><Skalieren und Umhüllen innerhalb des Zielbereichs</i> bedeutet, + dass das Ergebnis innerhalb des Ergebnisbereichs umgepackt wird.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/80-template.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/80-template.html new file mode 100644 index 0000000..e3d58d2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/80-template.html @@ -0,0 +1,53 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="template"> + <p> Legt eine Eigenschaft fest, die auf der bereitgestellten Vorlage basiert. </p> + <h3> Eingaben </h3> + <dl class="message-properties"> + <dt> msg <span class="property-type"> Objekt </span> </dt> + <dd> Ein msg Objekt, das Informationen zum Füllen der Vorlage enthält. </dd> + <dt class="optional"> template <span class="property-type">Zeichenfolge</span> </dt> + <dd> Eine Schablone, die aus msg.payload gefüllt werden soll. Falls es nicht in der Editieranzeige konfiguriert ist, kann + kann es als Eigenschaft von msg gesetzt werden. </dd> + </dl> + <h3> Ausgaben </h3> + <dl class="message-properties"> + <dt> msg <span class="property-type"> Objekt </span> </dt> + <dd> Eine Nachricht die durch Verbindung der konfigurierten Vorlage mit den Eigenschaften aus der eingehenden Nachricht gebildet wird. </dd> + </dl> + <h3> Details </h3> + <p> Die Vorlage verwendet standardmäßig das <i> <a href="http://mustache.github.io/mustache.5.html" target="_blank"> mustache </a> </i> + Format, das kann aber bei Bedarf ausgeschaltet werden. </p> + <p> Beispiel: Wenn eine Vorlage von: + <pre> Hallo {{payload.name}}. Heute ist {{date}} </pre> + <p> eine Nachricht empfangt, die folgendes enthält: + <pre>{ + date: "Montag", + payload: { + name: "Fred" + } +}</pre> + <p> wird die resultierende Nachrich wie folgt sein: + <pre> Hallo Fred. Heute ist Montag </pre> + <p> Es ist möglich, eine Eigenschaft aus dem Flowkontext oder dem globalen Kontext zu verwenden. + Verwenden Sie einfach <code>{{flow.name}}</code> oder + <code>{{global.name}}</code> oder für den persistenten Speicher <code>store</code> verwenden <code>{{flow[store].name}}</code> oder + <code>{{global[store].name}}</code>. + <p> <b>Hinweis: </b> Standardmäßig wird <i>mustache</i> alle HTML-Entitäten in den Werten die es ersetzt mit Escape behandeln. + Um dies zu verhindern, verwenden Sie <code>{{{triple}}}</code> Klammern. + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/89-delay.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/89-delay.html new file mode 100644 index 0000000..499d6da --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/89-delay.html @@ -0,0 +1,45 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="delay"> + <p> Verzögert jede Nachricht, die den Node durchläuft oder begrenzt die Geschwindigkeit, mit der sie übergeben werden können. </p> + <h3> Eingaben </h3> + <dl class="message-properties"> + <dt class="optional"> delay <span class="property-type"> Zahl </span> </dt> + <dd> Legt die Verzögerung (in Millisekunden) fest, die auf die Nachricht angewendet werden soll. Dies + Option gilt nur, wenn der Node so konfiguriert ist, dass er Nachrichten zulässt, + die das konfigurierte Standardverzögerungsintervall überschreiben. </dd> + <dt class="optional"> zurücksetzen </dt> + <dd> Wenn für die empfangene Nachricht diese Eigenschaft auf einen beliebigen Wert gesetzt ist, werden alle + ausstehende Nachrichten gelöscht, die vom Node noch gehalten werden. </dd> + <dt class="optional"> Flush </dt> + <dd> Wenn für die empfangene Nachricht diese Eigenschaft auf einen beliebigen Wert gesetzt ist, werden alle + ausstehende Nachrichten, die vom noch Node gehalten werden, sofort gesendet. </dd> + </dl> + <h3> Details </h3> + <p> Wenn das Verzögerungsintervall für die Verzögerung von Nachrichten konfiguriert ist, kann es sich um einen festen Wert, + einen Zufallswert innerhalb eines Bereichs oder einen dynamisch für jede Nachricht festgelegten Wert handeln. </p> + <p> Bei der Konfiguration von Begrenzungen werden die Nachrichten über den konfigurierten Zeitraum verteilt. + Der Status zeigt die Anzahl der Nachrichten an, die sich derzeit in der Warteschlange befinden. + Zwíschenzeitlich entreffende Nachrichten können gegebenenfalls verworfen werden.</p> + </p> + <p> Die Ratenbegrenzung kann auf alle Nachrichten angewendet werden + oder sie werden gemäß des Wertes von <code>msg.topic</code> gruppiert. + Bei der Gruppierung werden zwíschenzeitlich eintreffende Nachrichten automatisch gelöscht. + In jedes Zeitintervall kann der Node entweder die aktuellste Nachricht für alle Themen + oder die neueste Nachricht für das nächste Topic freigeben. + </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/89-trigger.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/89-trigger.html new file mode 100644 index 0000000..0f4953c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/89-trigger.html @@ -0,0 +1,44 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="trigger"> + <p> Wenn der Trigger ausgelöst wird, kann eine Nachricht gesendet werden und dann optional eine weitere Nachricht , + sofern der Trigger nicht verlängert oder zurückgesetzt wird. </p> + + <h3> Eingaben </h3> + <dl class="message-properties"> + <dt class="optional"> reset </dt> + <dd> Wenn eine Nachricht mit dieser Eigenschaft empfangen wird, wird jeder aktuelle Zeitlimit oder Wiederholung + zrückgesetzt und es wird keine Nachricht ausgelöst. </dd> + </dl> + + <h3> Details </h3> + <p> Dieser Node kann verwendet werden, um ein Zeitlimit in einem Flow zu erstellen. Wenn er eine Nachricht empfängt, wird + standardmäßig wird eine Nachricht mit einer <code>payload</code> von <code>1</code> versandt. + Anschließend wartet er 250 ms, bevor er eine zweite Nachricht mit einer <code>payload</code> von <code>0</code> sendet. + Dies kann beispielsweise zum Blinken einer LED verwendet werden, die an einen Raspberry Pi GPIO-Pin angeschlossen ist.</p> + <p> Die Nutzdaten jeder gesendeten Nachricht können für eine Vielzahl von Werten konfiguriert werden, + einschließlich der Option, nichts zu senden. Wenn Sie beispielsweise die Anfangsnachricht auf <i>nichts</i> setzen und + Auswahl der Option zum Erweitern des Zeitgebers mit jeder empfangenen Nachricht dann wird der Node als Überwachungszeitgeber agieren + und nur dann eine Nachricht senden, wenn innerhalb des konfigurierten Erweiterungszeitraums keine Nachricht empfangen wird. </p> + <p> Wenn der Node auf den Typ <i>Zeichenfolge</i> gesetzt ist, unterstützt der Node die Syntax der Mustache-Vorlage. </p> + <p> Wenn der Node eine Nachricht mit einer Eigenschaft <code>reset</code> oder einer <code>payload</code> die mit dem Wert in der + Node-Konfiguration übereinstimmt, wird jede beliebige Zeitlimitüberschreitung oder Wiederholung gelöscht, + die sich derzeit in Bearbeitung befindet und es wird keine Nachricht ausgelöst. </p> + <p> Der Node kann so konfiguriert werden, dass er eine Nachricht in einem regulären Intervall sendet, + bis er durch eine empfangene Nachricht zurückgesetzt wird. </p> + <p> Optional kann der Node so konfiguriert werden, dass er Nachrichten für jedes <code>msg.topic</code> als separate Datenströme behandelt. </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/90-exec.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/90-exec.html new file mode 100644 index 0000000..9541309 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/function/90-exec.html @@ -0,0 +1,83 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="exec"> + <p> Führt einen Systembefehl aus und gibt seine Ausgabe zurück. </p> + <p> Der Node kann so konfiguriert werden, dass er entweder wartet, bis der Befehl abgeschlossen ist, + oder die Ausgabe so sendet wie der Befehl sie generiert. </p> + <p> Der Befehl, der ausgeführt wird, kann im Node konfiguriert oder von der empfangenen Nachricht übergeben werden. </p> + + <h3> Eingaben </h3> + <dl class="message-properties"> + <dt class="optional">payload<span class="property-type"> Zeichenfolge </span> </dt> + <dd> wird an den ausgeführten Befehl angehängt </dd> + <dt class="optional"> kill <span class="property-type"> Zeichenfolge </span> </dt> + <dd> Der Typ des Kill-Signals, das einen vorhandenen exec-Node-Prozess gesendet wird. </dd> + <dt class="optional"> pid <span class="property-type"> Zahl|Zeichenfolge </span> </dt> + <dd> Die Prozess-ID eines vorhandenen exec-Node-Prozesses, der beendet werden soll. </dd> + </dl> + + <h3> Ausgaben </h3> + <ol class="node-ports"> + <li> Standardausgabe + <dl class="message-properties"> + <dt> payload <span class="property-type"> Zeichenfolge </span> </dt> + <dd> die Standardausgabe des Befehls. </dd> + </dl> + <dl class="message-properties"> + <dt> rc <span class="property-type"> Objekt </span> </dt> + <dd> Eine Kopie des Rückkehrcodeobjekts (auch an Port 3 verfügbar) - nur im Ausführungsmodus verfügbar </dd> + </dl> + </li> + <li> Standardfehler + <dl class="message-properties"> + <dt> payload <span class="property-type"> Zeichenfolge </span> </dt> + <dd> Standardfehlerausgabe des Befehls. </dd> + </dl> + <dl class="message-properties"> + <dt> rc <span class="property-type"> Objekt </span> </dt> + <dd> Eine Kopie des Rückkehrcodeobjekts (auch an Port 3 verfügbar) - nur im Ausführungsmodus verfügbar </dd> + </dl> + </li> + <li> Rückkehrcode + <dl class="message-properties"> + <dt> payload <span class="property-type"> Objekt </span> </dt> + <dd> ein Objekt, das den Rückkehrcode und gegebenfals <code>Nachricht</code>, <code>Signal</code> Eigenschaften enthält. </dd> + </dl> + </li> + </ol> + <h3> Details </h3> + <p> Standardmäßig verwendet der Systemaufruf <code>exec</code> , der den Befehl aufruft, darauf wartet, dass er ausgeführt wird und anschließend + gibt dessen Ausgabe zurück. Ein erfolgreicher Befehl sollte z. B. den Rückkehrcode <code>{ code: 0 }</code> haben. </p> + <p> Optional kann stattdessen <code>spawn</code> verwendet werden, wodurch die Ausgaben von Standardausgabe und Standardfehler zurückgegeben werden während + der Befehl ausgeführt wird, in der Regel Zeile für Zeile. Nach Abschluss des Befehles gibt sie ein Objekt + am 3. Port zurück. Ein erfolgreicher Befehl sollte z. B. <code>{ code: 0 }</code> zurückgeben. </p> + <p> Fehler können zusätzliche Informationen über den dritten Port als <code>msg.payload</code> zurückgeben, + z. B. eine <code>message</code> Zeichenfolge oder <code>Signal</code> zeichenfolge. </p> + <p> Der Befehl, der ausgeführt wird, ist innerhalb des Nodes definiert, mit einer Option zum Anhängen von <code> msg.payload </code> + und einer weiteren Gruppe von Parametern. </p> + <p> Befehle oder Parameter mit Leerzeichen müssen in Anführungszeichen eingeschlossen werden: <code> "Dies ist ein einzelner Parameter" </code> </p> + <p> Die zurückgegebenen <code>Nutzdaten</code> sind in der Regel ein <i>string</i>, es sei denn, es werden nicht UTF8-Zeichen erkannt, in denen + falls es sich um einen <i>Buffer</i> handelt. </p> + <p> Das Statussymbol und die PID des Nodes werden angezeigt, während der Node aktiv ist. Änderungen an dieser Funktion können vom Node <code> Status </code> gelesen werden. </p> + <h4> Prozesse beenden </h4> + <p> Wird <code>msg.kill</code> gesendet, wird ein einzelner aktiver Prozess beendet. <code>msg.kill</code> sollte eine Zeichenfolge sein, die + Der Typ des Signals, der gesendet werden soll, z. B. <code>SIGINT</code>, <code>SIGQUIT</code> oder <code>SIGHUP</code>. + Der Standardwert ist <code>SIGTERM</code> , wenn er auf eine leere Zeichenfolge gesetzt ist. </p> + <p> Wenn der Node mehr als einen Prozess ausführt, muss <code>msg.pid</code> ebenfalls mit dem Wert der zu ermordenen PID festgelegt werden. </p> + <p> Wenn ein Wert im Feld <code>Zeitlimit</code> angegeben wird, wird der Prozess automatisch beendet, wenn der Prozess nicht abgeschlossen ist, wenn die angegebene Anzahl von Sekunden abgelaufen ist. </p> + <p> Tipp: Wenn Sie eine Python-App ausführen, müssen Sie möglicherweise den Parameter <code>-u</code> verwenden, um die Ausgabe zu stoppen, die gepuffert wird. </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/messages.json b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/messages.json new file mode 100644 index 0000000..c36c309 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/messages.json @@ -0,0 +1,858 @@ +{ + "common" : { + "label" : { + "payload" : "Nutzdaten", + "topic" : "Topic", + "name" : "Name", + "username" : "Benutzername", + "password" : "Kennwort", + "property" : "Eigenschaft" + }, + "status" : { + "connected" : "verbunden", + "not-connected" : "nicht verbunden ", + "disconnected" : "Verbindung getrennt", + "connecting" : "Verbindung wird hergestellt", + "error" : "Fehler", + "ok" : "OK" + }, + "notification" : { + "error" : "<strong> Fehler </strong>: __message__", + "errors" : { + "not-deployed" : "Node nicht vorhanden", + "no-response" : "Keine Antwort vom Server", + "unexpected" : "Unerwarteter Fehler (__status__) __message__" + } + }, + "errors" : { + "nooverride" : "Warnung: Nachrichten-Eigenschaften können die Eigenschaften des festgelegten Nodes nicht mehr außer Kraft setzen. Siehe Bit.ly/nr-override-msg-props" + } + }, + "inject" : { + "inject" : "Injizieren", + "repeat" : "Wiederholen = __repeat__", + "crontab" : "Crontab = __crontab__", + "stopped" : "Gestoppt", + "failed" : "Injizieren fehlgeschlagen: __error__", + "label" : { + "repeat" : "Wiederholen" + }, + "timestamp" : "timestamp", + "none" : "keine", + "interval" : "Intervall", + "interval-time" : "Intervall zwischen den Uhrzeiten", + "time" : "zu einem bestimmten Zeitpunkt", + "seconds" : "Sekunden", + "minutes" : "Minuten", + "hours" : "Stunden", + "between" : "zwischen", + "previous" : "vorheriger Wert", + "at" : "bei", + "and" : "und", + "every" : "alle", + "days" : [ "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag" ], + "on" : "am", + "onstart" : "Einmal nach der Injektion", + "onceDelay" : "Sekunden, dann", + "tip" : "<b> Hinweis: </b> \"Intervall zwischen den Uhrzeiten\" und \"zu einem bestimmten Zeitpunkt\" verwendet \"cron\". <br/> \"Intervall\" sollte weniger als 596 Stunden betragen. <br/> Siehe Informationsfenster für Details.", + "success" : "Erfolgreich injiziert: __label__", + "errors" : { + "failed" : "Injizieren fehlgeschlagen, siehe Protokoll für Details", + "toolong" : "Intervall zu groß" + } + }, + "catch" : { + "catch" : "Catch: all", + "catchNodes" : "Catch: __number__", + "label" : { + "source" : "Catch-Fehler von", + "node" : "Node", + "type" : "Typ", + "selectAll" : "Alle auswählen", + "sortByLabel" : "Sortieren nach Bezeichnung", + "sortByType" : "Sortieren nach Typ" + }, + "scope" : { + "all" : "allen Nodes", + "selected" : "ausgewählten Nodes" + } + }, + "status" : { + "status" : "Status: alle", + "statusNodes" : "Status: __number__", + "label" : { + "source" : "Berichtsstatus von", + "node" : "Node", + "type" : "Typ", + "selectAll" : "Alle auswählen", + "sortByLabel" : "Sortieren nach Bezeichnung", + "sortByType" : "Sortieren nach Typ" + }, + "scope" : { + "all" : "allen Nodes", + "selected" : "ausgewählten Nodes" + } + }, + "debug" : { + "output" : "Ausgabe", + "msgprop" : "Nachrichteneigenschaft", + "msgobj" : "Volles Nachrichten-Objekt", + "to" : "Ziel", + "debtab" : "Debug, Registerkarte", + "tabcon" : "Debug-Registerkarte und -Konsole", + "toSidebar" : "Debugfenster", + "toConsole" : "Systemkonsole", + "toStatus" : "Node-Status (32 Zeichen)", + "severity" : "Ebene", + "notification" : { + "activated" : "Erfolgreich aktiviert: __label__", + "deactivated" : "Erfolgreich inaktiviert: __label__" + }, + "sidebar" : { + "label" : "Debugging", + "name" : "Debugnachrichten", + "filterAll" : "Alle Nodes", + "filterSelected" : "Ausgewählte Nodes", + "filterCurrent" : "Aktueller Fluss", + "debugNodes" : "Debug-Nodes", + "clearLog" : "Protokoll löschen", + "openWindow" : "In neuem Fenster öffnen" + }, + "messageMenu" : { + "collapseAll" : "Alle Pfade ausblenden", + "clearPinned" : "Angeheftete Pfade löschen", + "filterNode" : "Diesen Node filtern", + "clearFilter" : "Filter löschen" + } + }, + "link" : { + "linkIn" : "eingehende Verbindung", + "linkOut" : "ausgehende Verbindung" + }, + "tls" : { + "tls" : "TLS-Konfiguration", + "label" : { + "use-local-files" : "Schlüssel und Zertifikate aus lokalen Dateien verwenden", + "upload" : "Hochladen", + "cert" : "Zertifikat", + "key" : "Privater Schlüssel", + "passphrase" : "Passwort", + "ca" : "CA-Zertifikat", + "verify-server-cert" : "Serverzertifikat überprüfen", + "servername" : "Servername" + }, + "placeholder" : { + "cert" : "Pfad zu Zertifikat (PEM-Format)", + "key" : "Pfad zum privaten Schlüssel (PEM-Format)", + "ca" : "Pfad zu CA-Zertifikat (PEM-Format)", + "passphrase" : "Verschlüsselungstext für privaten Schlüssel (optional)", + "servername" : "zur Verwendung mit SNI" + }, + "error" : { + "missing-file" : "Es wurde keine Zertifikats-/Schlüsseldatei angegeben." + } + }, + "exec" : { + "exec" : "Ausführen", + "spawn" : "Ausführen in neuem Prozess", + "label" : { + "command" : "Befehl", + "append" : "Anfügen", + "timeout" : "Zeitlimit", + "timeoutplace" : "optional", + "return" : "Ausgabe", + "seconds" : "Sekunden" + }, + "placeholder" : { + "extraparams" : "zusätzliche Eingabeparameter" + }, + "opt" : { + "exec" : "wartet bis der Befehl vollständig ausgeführt wurde", + "spawn" : "während der Befehl ausgeführt wird (spawn)" + }, + "oldrc" : "Ausgabe im alten Stil verwenden (Kompatibilitätsmodus)" + }, + "function" : { + "function" : "", + "label" : { + "function" : "Funktion", + "outputs" : "Ausgänge" + }, + "error" : { + "inputListener" : "Das Empfangsprogramm kann nicht zum 'input' -Ereignis in Funktion hinzugefügt werden.", + "non-message-returned" : "Funktion hat versucht, eine Nachricht vom Typ __type__ zu senden" + } + }, + "template" : { + "template" : "Vorlage", + "label" : { + "template" : "Vorlage", + "property" : "Eigenschaft festlegen", + "format" : "Syntaxhervorhebung", + "syntax" : "Format", + "output" : "Ausgabe als", + "mustache" : "Mustache-Vorlage", + "plain" : "Klartext", + "json" : "Parsed JSON", + "yaml" : "Parsed YAML", + "none" : "keine" + }, + "templatevalue" : "Dies sind die Nutzdaten: { { payload } }!" + }, + "delay" : { + "action" : "Aktion", + "for" : "Für", + "delaymsg" : "Jede Nachricht verzögern", + "delayfixed" : "Feste Verzögerung", + "delayvarmsg" : "Verzögerung mit msg.delay bestimmen", + "randomdelay" : "Zufällige Verzögerung", + "limitrate" : "Geschwindigkeitslimit", + "limitall" : "Alle Nachrichten", + "limittopic" : "Für jedes msg.topic", + "fairqueue" : "Jedes Topic im Gegenzug senden", + "timedqueue" : "Alle Themen senden", + "milisecs" : "Milisekunden", + "secs" : "Sekunden", + "sec" : "Zweiter", + "mins" : "Minuten", + "min" : "Minute", + "hours" : "Stunden", + "hour" : "Stunde", + "days" : "Tage", + "day" : "Tag", + "between" : "Zwischen", + "and" : "&", + "rate" : "Satz", + "msgper" : "msg (s) pro", + "dropmsg" : "Zwischennachrichten löschen", + "label" : { + "delay" : "Verzögerung", + "variable" : "Variable", + "limit" : "Begrenzung", + "limitTopic" : "Grenzwert, Topic", + "random" : "Zufall", + "units" : { + "second" : { + "plural" : "Sekunden", + "singular" : "Sekunde" + }, + "minute" : { + "plural" : "Minuten", + "singular" : "Minute" + }, + "hour" : { + "plural" : "Stunden", + "singular" : "Stunde" + }, + "day" : { + "plural" : "Tage", + "singular" : "Tag" + } + } + }, + "error" : { + "buffer" : "Buffer hat 1000 Nachrichten überschritten", + "buffer1" : "Der Buffer hat 10000 Nachrichten überschritten." + } + }, + "trigger" : { + "send" : "Senden", + "then" : "dann", + "then-send" : "dann senden", + "output" : { + "string" : "die Zeichenfolge", + "number" : "die Zahl", + "existing" : "das vorhandene Nachrichtenobjekt", + "original" : "das ursprüngliche Nachrichtenobjekt", + "latest" : "das neueste Nachrichtenobjekt", + "nothing" : "nichts" + }, + "wait-reset" : "warten auf Zurücksetzen", + "wait-for" : "warten auf", + "wait-loop" : "erneut senden aller", + "for" : "Handhabung", + "bytopics" : "für jeden <code>msg.topic</code> Wert unabhängig", + "alltopics" : "alle Nachrichten", + "duration" : { + "ms" : "Millisek.", + "s" : "Sekunden", + "m" : "Minuten", + "h" : "Stunden" + }, + "extend" : " Verlängerung der Verzögerung bei Eingang neuer Nachricht", + "label" : { + "trigger" : "Auslöser", + "trigger-block" : "Auslöser & Block", + "trigger-loop" : "alle erneut senden", + "reset" : "Setzen Sie den Auslöser zurück, wenn:", + "resetMessage" : "msg.reset gesetzt ist oder ", + "resetPayload" : "msg.payload ist gleich" , + "resetprompt" : "optional" + } + }, + "comment" : { + "comment" : "Kommentar" + }, + "unknown" : { + "label" : { + "unknown" : "unbekannt" + }, + "tip" : "<p> Dieser Node ist ein Typ, der Ihrer Installation von Node-RED unbekannt ist. </p> <p> <i> Wenn Sie mit dem Node in diesem Status deployen, wird die Konfiguration beibehalten, aber der Fluss wird erst gestartet, wenn der fehlende Typ installiert ist. </i> </p> <p> Weitere Informationen finden Sie in der Info-Seitenleiste für. Weitere Hilfe </p>" + }, + "mqtt" : { + "label" : { + "broker" : "Server", + "example" : "z. B. lokaler_Host", + "qos" : "QoS", + "retain" : "Retain", + "clientid" : "Client-ID", + "port" : "Port", + "keepalive" : "Keepalive-Zeit (en)", + "cleansession" : "Bereinigte Sitzung verwenden", + "use-tls" : "Sichere Verbindung (SSL/TLS) aktivieren", + "tls-config" : "TLS-Konfiguration", + "verify-server-cert" : "Serverzertifikat überprüfen", + "compatmode" : "Traditionelle MQTT 3.1-Unterstützung verwenden" + }, + "sections-label" : { + "birth-message" : "Nachricht über Verbindungsaufbau ", + "will-message" : "Nachricht über unerwarteten Abschaltung", + "close-message" : "Nachricht bevor die Verbindung beendet wird" + }, + "tabs-label" : { + "connection" : "Verbindung", + "security" : "Sicherheit", + "messages" : "Nachrichten" + }, + "placeholder" : { + "clientid" : "Leerer Wert für automatische Generierung", + "clientid-nonclean" : "Muss für nicht bereinigte Sitzungen festgelegt werden.", + "will-topic" : "inaktivieren wenn leer", + "birth-topic" : "inaktivieren wenn leer", + "close-topic" : "inaktivieren wenn leer" + }, + "state" : { + "connected" : "Verbindung zum Broker __broker__ hergestellt.", + "disconnected" : "Verbindung zum Broker __broker__ wurde beendet.", + "connect-failed" : "Verbindung zum Broker __broker__ konnte nicht hergestellt werden." + }, + "retain" : "Retain", + "true" : "Wahr", + "false" : "Falsch", + "tip" : "Tipp: Behalten Sie das Topic \"Artikel\", \"qos\" oder \"retain\" bei, wenn Sie diese über die Eigenschaft \"msg\" festlegen", + "errors" : { + "not-defined" : "Topic nicht definiert", + "missing-config" : "Fehlende Brokerkonfiguration", + "invalid-topic" : "Ungültiges Topic angegeben", + "nonclean-missingclientid" : "Keine Client-ID-Gruppe unter Verwendung einer bereinigten Sitzung" + } + }, + "httpin" : { + "label" : { + "method" : "Methode", + "url" : "URL", + "doc" : "Docs", + "return" : "Rückgabe", + "upload" : "Dateiuploads akzeptieren?", + "status" : "Statuscode", + "headers" : "Kopfzeilen", + "other" : "andere" + }, + "setby" : "-durch msg.method festgelegt-", + "basicauth" : "Basisauthentifizierung verwenden", + "use-tls" : "Sichere Verbindung (SSL/TLS) aktivieren", + "tls-config" : "TLS-Konfiguration", + "utf8" : "eine UTF-8-Zeichenfolge", + "binary" : "einen binären Buffer", + "json" : "ein analysiertes JSON-Objekt", + "tip" : { + "in" : "Die URL ist relativ zu ", + "res" : "Die an diesen Node gesendeten Nachrichten <b> müssen </b> von einem <i> http-Input </i> -Node stammen", + "req" : "Tipp: Wenn die JSON-Syntaxanalyse fehlschlägt, wird die abgerufene Zeichenfolge als-ist zurückgegeben." + }, + "httpreq" : "HTTP-Anforderung", + "errors" : { + "not-created" : "http-in-Node kann nicht erstellt werden, wenn httpNodeRoot auf 'false' gesetzt ist.", + "missing-path" : "Fehlendes Pfad", + "no-response" : "Kein Antwortobjekt", + "json-error" : "JSON-Parsing-Fehler", + "no-url" : "Keine URL angegeben", + "deprecated-call" : "Nicht weiter unterstützter Aufruf von __method__", + "invalid-transport" : "Nicht-http-Transport angefordert" + }, + "status" : { + "requesting" : "anfordern" + } + }, + "websocket" : { + "label" : { + "type" : "Typ", + "path" : "Pfad", + "url" : "URL" + }, + "listenon" : "Empfangsbereit", + "connectto" : "Verbinden mit", + "sendrec" : "Senden/Empfangen", + "payload" : "Nutzdaten", + "message" : "gesamte Nachricht", + "tip" : { + "path1" : "Standardmäßig enthält <code> Nutzdaten </code> die Daten, die über einen Websocket gesendet oder von einem Websocket empfangen werden. Der Listener kann so konfiguriert werden, dass er das gesamte Nachrichtenobjekt als eine JSON-formatierte Zeichenfolge sendet oder empfängt.", + "path2" : "Dieser Pfad ist relativ zu ", + "url1" : "URL sollte ws: &#47; & #47; oder wss: &#47; & #47; Schema verwenden und auf einen vorhandenen Websocket-Listener verweisen.", + "url2" : "Standardmäßig enthält <code> Nutzdaten </code> die Daten, die über einen Websocket gesendet oder von einem Websocket empfangen werden. Der Client kann so konfiguriert werden, dass er das gesamte Nachrichtenobjekt als eine JSON-formatierte Zeichenfolge sendet oder empfängt." + }, + "status" : { + "connected" : "verbunden __count__", + "connected_plural" : "verbunden __count__" + }, + "errors" : { + "connect-error" : "Bei der WS-Verbindung ist ein Fehler aufgetreten: ", + "send-error" : "Beim Senden ist ein Fehler aufgetreten: ", + "missing-conf" : "Fehlende Serverkonfiguration" + } + }, + "watch" : { + "watch" : "Überwachung", + "label" : { + "files" : "Datei (en)", + "recursive" : "Unterverzeichnisse rekursiv überwachen" + }, + "placeholder" : { + "files" : "Durch Komma getrennte Liste von Dateien und/oder Verzeichnissen" + }, + "tip" : "Unter Windows müssen Sie doppelte Backslashes \\\\ in beliebigen Verzeichnisnamen verwenden." + }, + "tcpin" : { + "label" : { + "type" : "Typ", + "output" : "Ausgabe", + "port" : "Port", + "host" : "auf Host", + "payload" : "Payload (en)", + "delimited" : "begrenzt durch", + "close-connection" : "Schließen Sie die Verbindung, nachdem jede Nachricht gesendet wurde?", + "decode-base64" : "Nachricht aus Base64 dekodierien?", + "server" : "Server", + "return" : "Rückgabe", + "ms" : "ms", + "chars" : "Chars" + }, + "type" : { + "listen" : "Empfangsbereit", + "connect" : "Verbinden mit", + "reply" : "Auf TCP antworten" + }, + "output" : { + "stream" : "Datenstrom von", + "single" : "Single", + "buffer" : "Buffer", + "string" : "Zeichenfolge", + "base64" : "Base64-Zeichenfolge" + }, + "return" : { + "timeout" : "nach einem festen Zeitlimit von", + "character" : "wenn folgendes Zeichen empfangen wird", + "number" : "eine festgelegte Anzahl von Zeichen", + "never" : "keine Rückgabe - Verbindung wird offen gehalten", + "immed" : "sofort - Wartet nicht auf Antwort." + }, + "status" : { + "connecting" : "Verbindung zu __host__: __port__", + "connected" : "Verbindung zu __host__: __port__", + "listening-port" : "empfangsbereit an Port __port__", + "stopped-listening" : "Empfangsbereitschaft an Port gestoppt", + "connection-from" : "Verbindung von __host__: __port__", + "connection-closed" : "Verbindung geschlossen von __host__: __port__", + "connections" : "__count__connection", + "connections_plural" : "__count__connections" + }, + "errors" : { + "connection-lost" : "Verbindung verloren zu __host__: __port__", + "timeout" : "Zeitlimit für geschlossenen Socket-Port __port__", + "cannot-listen" : "Port __port__ kann nicht empfangsbereit sein. Fehler: __error__", + "error" : "Fehler: __error__", + "socket-error" : "Socketfehler von __host__: __port__", + "no-host" : "Host und/oder Port nicht festgelegt", + "connect-timeout" : "Verbindungszeitlimit", + "connect-fail" : "Verbindung fehlgeschlagen" + } + }, + "udp" : { + "label" : { + "listen" : "Empfangsbereit", + "onport" : "an Port", + "using" : "verwenden", + "output" : "Ausgabe", + "group" : "Gruppe", + "interface" : "Lokal IF", + "send" : "Schicken Sie eine", + "toport" : "an Port", + "address" : "Adresse", + "decode-base64" : "Dekodiere Base64-kodierte Nutzdaten?" + }, + "placeholder" : { + "interface" : "(optional) lokale Schnittstelle oder Adresse, an die gebunden werden soll", + "interfaceprompt" : "(optional) lokale Schnittstelle oder Adresse, an die gebunden werden soll", + "address" : "Ziel-IP" + }, + "udpmsgs" : "udp-Nachrichten", + "mcmsgs" : "Multicastnachrichten", + "udpmsg" : "udp-Nachricht", + "bcmsg" : "Broadcastnachricht", + "mcmsg" : "Multicastnachricht", + "output" : { + "buffer" : "ein Buffer", + "string" : "eine Zeichenfolge", + "base64" : "Eine Base64-codierte Zeichenfolge" + }, + "bind" : { + "random" : "an zufälliger lokaler Port binden", + "local" : "Bindung an lokalen Port", + "target" : "Bindung an Zielport" + }, + "tip" : { + "in" : "Tipp: Stellen Sie sicher, dass Ihre Firewall die Daten in zulässt.", + "out" : "Tipp: Lassen Sie die Adresse und den Port leer, wenn Sie mit <code> msg.ip </code> und <code> msg.port </code> festlegen möchten.", + "port" : "Ports, die bereits verwendet werden: " + }, + "status" : { + "listener-at" : "udp listener at __host__: __port__", + "mc-group" : "udp Multicastgruppe __Gruppe__", + "listener-stopped" : "udp-Listener gestoppt", + "output-stopped" : "udp-Ausgabe gestoppt", + "mc-ready" : "udp multicast ready: __iface__: __outport__-> __host__: __port__", + "bc-ready" : "udp broadcast ready: __outport__-> __host__: __port__", + "ready" : "udp ready: __outport__-> __host__: __port__", + "ready-nolocal" : "udp bereit: __host__: __port__", + "re-use" : "udp re-use socket: __outport__-> __host__: __port__" + }, + "errors" : { + "access-error" : "UDP-Zugriffsfehler, Sie benötigen möglicherweise Rootzugriff für Ports unter 1024", + "error" : "Fehler: __error__", + "bad-mcaddress" : "Ungültige Multicastadresse", + "interface" : "Sie müssen die IP-Adresse der erforderlichen Schnittstelle sein.", + "ip-notset" : "udp: ip-Adresse nicht festgelegt", + "port-notset" : "udp: Port nicht festgelegt", + "port-invalid" : "udp: Portnummer nicht gültig", + "alreadyused" : "udp: Port __port__ wird bereits verwendet", + "ifnotfound" : "udp: interface __iface__ nicht gefunden" + } + }, + "switch" : { + "switch" : "Switch", + "label" : { + "property" : "Eigenschaft", + "rule" : "Regel", + "repair" : "Nachrichtenfolgen erneut erstellen" + }, + "and" : "und", + "checkall" : "Alle Regeln überprüfen", + "stopfirst" : "Nach erster Übereinstimmung stoppen", + "ignorecase" : "Groß-/Kleinschreibung ignorieren", + "rules" : { + "btwn" : "liegt zwischen", + "cont" : "enthält", + "regex" : "Übereinstimmungen mit regex", + "true" : "ist wahr", + "false" : "ist falsch", + "null" : "ist null", + "nnull" : "ist nicht null", + "istype" : "ist vom Typ", + "empty" : "ist leer", + "nempty" : "ist nicht leer", + "head" : "Header", + "tail" : "Trailer", + "index" : "Index zwischen", + "exp" : "JSONata Ausdruck", + "else" : "Andernfalls" + }, + "errors" : { + "invalid-expr" : "Ungültiger JSONata Ausdruck: __error__", + "too-many" : "Zu viele anstehende Nachrichten im Switch-Node" + } + }, + "change" : { + "label" : { + "rules" : "Regeln", + "rule" : "Regel", + "set" : "setze __property__", + "change" : "__property__ ändern", + "delete" : "__property__ löschen", + "move" : "bewege __property__", + "changeCount" : "Ändern: __count__rules", + "regex" : "Reguläre Ausdrücke verwenden" + }, + "action" : { + "set" : "Festlegen", + "change" : "Ändern", + "delete" : "Löschen", + "move" : "Bewegen", + "to" : "bis", + "search" : "Suchen nach", + "replace" : "Ersetzen durch" + }, + "errors" : { + "invalid-from" : "Ungültiges 'from' Merkmal: __error__", + "invalid-json" : "Ungültiges 'to' JSON Merkmal", + "invalid-expr" : "Ungültiger JSONata Ausdruck: __error__" + } + }, + "range" : { + "range" : "Bereich", + "label" : { + "action" : "Aktion", + "inputrange" : "von einem Eingabebereich", + "resultrange" : "in einen Zielbereich", + "from" : "von", + "to" : "bis", + "roundresult" : "Runde das Ergebnis auf die nächste ganze Zahl?" + }, + "placeholder" : { + "min" : "z. B. 0", + "maxin" : "z. B. 99", + "maxout" : "z. B. 255" + }, + "scale" : { + "payload" : "Skaliere die Nachrichteneigenschaft", + "limit" : "Skalieren und Begrenzen auf den Zielbereich", + "wrap" : "Skaliere und Einhüllen innerhalb des Zielbereichs" + }, + "tip" : "Tipp: Dieser Node funktioniert NUR mit Zahlen.", + "errors" : { + "notnumber" : "Keine Zahl" + } + }, + "csv" : { + "label" : { + "columns" : "Spalten", + "separator" : "Trennzeichen", + "c2o" : "Optionen für CSV-zu-Objekt", + "o2c" : "Objekt-zu-CSV-Optionen", + "input" : "Eingabe", + "skip-s" : "Zuerst überspringen", + "skip-e" : "Zeilen", + "firstrow" : "erste Zeile enthält Spaltennamen", + "output" : "Ausgabe", + "includerow" : "Spaltennamenszeile einschließen", + "newline" : "Zeilenneuerzeile" + }, + "placeholder" : { + "columns" : "durch Kommas getrennte Spaltennamen" + }, + "separator" : { + "comma" : "Komma", + "tab" : "Tabulatorzunge", + "space" : "Leerzeichen", + "semicolon" : "Semikolon", + "colon" : "Doppelpunkt", + "hashtag" : "hashtag", + "other" : "andere ..." + }, + "output" : { + "row" : "eine Nachricht pro Zeile", + "array" : "eine einzelne Nachricht [ Array]" + }, + "newline" : { + "linux" : "Linux (\\n)", + "mac" : "Mac (\\r)", + "windows" : "Windows (\\r \\n)" + }, + "errors" : { + "csv_js" : "Dieser Node verarbeitet nur CSV-Zeichenfolgen oder JS-Objekte.", + "obj_csv" : "Es wurde keine Spaltenschablone für Objekt-> CSV angegeben." + } + }, + "html" : { + "label" : { + "select" : "Selektor", + "output" : "Ausgabe", + "in" : "in" + }, + "output" : { + "html" : "den HTML-Inhalt der Elemente", + "text" : "nur der Textinhalt der Elemente", + "attr" : "ein Objekt mit allen Attributen der Elemente" + }, + "format" : { + "single" : "als einzelne Nachricht mit einem Array", + "multi" : "als mehrere Nachrichten, eine für jedes Element" + } + }, + "json" : { + "errors" : { + "dropped-object" : "Ignorierte Nicht-Objekt-Nutzdaten", + "dropped" : "Ignorierter nicht unterstützter Nutzdatentyp", + "dropped-error" : "Fehler beim Konvertieren der Nutzdaten", + "schema-error" : "JSON-Schema-Fehler", + "schema-error-compile" : "JSON-Schema-Fehler: Schema konnte nicht kompiliert werden" + }, + "label" : { + "o2j" : "Objekt zu JSON-Optionen", + "pretty" : "JSON-Zeichenfolge formatieren", + "action" : "Aktion", + "property" : "Eigenschaft", + "actions" : { + "toggle" : "Konvertieren zwischen JSON-Zeichenfolge und Objekt", + "str" : "Immer in JSON-Zeichenfolge konvertieren", + "obj" : "Immer in JavaScript-Objekt konvertieren" + } + } + }, + "yaml" : { + "errors" : { + "dropped-object" : "Ignorierte Nicht-Objekt-Nutzdaten", + "dropped" : "Ignorierter nicht unterstützter Nutzdatentyp", + "dropped-error" : "Fehler beim Konvertieren der Nutzdaten" + } + }, + "xml" : { + "label" : { + "represent" : "Eigenschaftsname für XML-Tagattribute", + "prefix" : "Eigenschaftsname für Tagtextinhalt", + "advanced" : "Erweiterte Optionen", + "x2o" : "Optionen für XML zu Objekt" + }, + "errors" : { + "xml_js" : "Dieser Node verarbeitet nur XML-Zeichenfolgen oder JS-Objekte." + } + }, + "file" : { + "label" : { + "filename" : "Name der Datei", + "action" : "Aktion", + "addnewline" : "Neue Zeile (\\n) zu den einzelnen Nutzdaten hinzufügen?", + "createdir" : "Verzeichnis erstellen, wenn es nicht vorhanden ist?", + "outputas" : "Ausgabe", + "breakchunks" : "In Chunks aufbrechen", + "breaklines" : "In Linien aufbrechen", + "filelabel" : "Datei", + "sendError" : "Nachricht bei Fehler senden (traditioneller Modus)", + "deletelabel" : "__file__ löschen" + }, + "action" : { + "append" : "an Datei anhängen", + "overwrite" : "Datei überschreiben", + "delete" : "Datei löschen" + }, + "output" : { + "utf8" : "eine einzelne utf8-Zeichenfolge", + "buffer" : "ein einzelnes Bufferobjekt", + "lines" : "ein Nachricht pro Zeile", + "stream" : "ein Datenstrom von Buffers" + }, + "status" : { + "wrotefile" : "in Datei geschrieben: __file__", + "deletedfile" : "gelöschte Datei: __file__", + "appendedfile" : "an Datei angefügt: __file__" + }, + "errors" : { + "nofilename" : "Kein Dateiname angegeben", + "invaliddelete" : "Warnung: Ungültiges Löschen. Bitte verwenden Sie im Konfigurationsdialog eine bestimmte Löschoption.", + "deletefail" : "Fehler beim Löschen der Datei: __error__", + "writefail" : "Schreiben in Datei fehlgeschlagen: __error__", + "appendfail" : "Anhängen an Datei fehlgeschlagen: __error__", + "createfail" : "Fehler beim Erstellen der Datei: __error__" + }, + "tip" : "Tipp: Der Dateiname muss ein absoluter Pfad sein. Andernfalls wird er relativ zum Arbeitsverzeichnis des Node-RED-Prozesses verwendet." + }, + "split" : { + "split" : "aufteilen", + "intro" : "Trennen Sie <code> msg.payload </code> basierend auf dem Typ:", + "object" : "<b> Objekt </b>", + "objectSend" : "Eine Nachricht für jedes Schlüssel/Wert-Paar senden", + "strBuff" : "<b> Zeichenfolge </b> / <b> Buffer </b>", + "array" : "<b> Array </b>", + "splitUsing" : "Trennen mit", + "splitLength" : "Feste Länge von", + "stream" : "Behandeln als Strom von Nachrichten", + "addname" : "Schlüssel kopieren nach " + }, + "join" : { + "join" : "Join", + "mode" : { + "mode" : "Modus", + "auto" : "Automatisch", + "merge" : "Sequenzen zusammenführen", + "reduce" : "Reihenfolge bestimmen", + "custom" : "Manuell" + }, + "combine" : "Kombiniere alle", + "create" : "und erstelle", + "type" : { + "string" : "eine Zeichenfolge", + "array" : "ein Array", + "buffer" : "ein Buffer", + "object" : "ein Schlüssel/Wert-Objekt", + "merged" : "ein zusammengefasstes Objekt" + }, + "using" : "mit dem Wert von", + "key" : "als Schlüssel", + "joinedUsing" : "verbunden mit", + "send" : "Senden Sie die Nachricht:", + "afterCount" : "nach einer Reihe von Nachrichtenteilen", + "count" : "Zähler", + "subsequent" : "und jede nachfolgende Nachricht.", + "afterTimeout" : "nach Zeitlimitüberschreitung von", + "seconds" : "Sekunden", + "complete" : "Nach einer Nachricht mit der gesetzten Eigenschaft <code>msg.complete</code>", + "tip" : "Dieser Modus setzt voraus, dass dieser Node entweder mit einem <i> split </i> Node verbunden ist oder dass die empfangenen Nachrichten über eine ordnungsgemäß konfigurierte Eigenschaft <code> msg.parts </code> verfügen.", + "too-many" : "Zu viele anstehende Nachrichten im Verknüpfungs-Node", + "merge" : { + "topics-label" : "Zusammengemiedene Themen", + "topics" : "Themen", + "topic" : "Topic", + "on-change" : "Zusammengefügte Nachricht bei Ankunft eines neuen Topics senden" + }, + "reduce" : { + "exp" : "Zusammenfassen durch", + "exp-value" : "Ausdruck", + "init" : "Anfangswert", + "right" : "In umgekehrter Reihenfolge auswerten (letzter auf den ersten)", + "fixup" : "Fix-up" + }, + "errors" : { + "invalid-expr" : "Ungültiger JSONata-Ausdruck: __error__" + } + }, + "sort" : { + "sort" : "sortieren", + "target" : "Sortieren", + "seq" : "Nachrichtenfolge", + "key" : "Schlüssel", + "elem" : "Elementwert", + "order" : "Sortierung", + "ascending" : "aufsteigend", + "descending" : "absteigend", + "as-number" : "als Zahl", + "invalid-exp" : "Ungültiger JSONata-Ausdruck in Sortier-Node: __message__", + "too-many" : "Zu viele anstehende Nachrichten in Sortier-Node", + "clear" : "Anstehende Nachricht in Sortier-Node löschen" + }, + "batch" : { + "batch" : "Batch", + "mode" : { + "label" : "Modus", + "num-msgs" : "Gruppieren nach Anzahl der Nachrichten", + "interval" : "Gruppieren nach Zeitintervall", + "concat" : "Sequenzen katalogisieren" + }, + "count" : { + "label" : "Anzahl der Nachrichten", + "overlap" : "Überlappung", + "count" : "Zähler", + "invalid" : "Ungültige Anzahl und Überlappung" + }, + "interval" : { + "label" : "Intervall", + "seconds" : "Sekunden", + "empty" : "Leere Nachricht senden, wenn keine Nachricht eingeht" + }, + "concat" : { + "topics-label" : "Topics", + "topic" : "Topic" + }, + "too-many" : "Zu viele anstehende Nachrichten im Stapel-Node", + "unexpected" : "Unerwarteter Modus", + "no-parts" : "Keine Teileeigenschaft in Nachricht" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/05-tls.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/05-tls.html new file mode 100644 index 0000000..5f61660 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/05-tls.html @@ -0,0 +1,19 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="tls-config"> + <p>Konfigurationsoptionen für TLS Verbindungen.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/06-httpproxy.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/06-httpproxy.html new file mode 100644 index 0000000..228da48 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/06-httpproxy.html @@ -0,0 +1,23 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http proxy"> + <p>Konfigurationsoptionen für den HTTP Proxy.</p> + + <h3>Details</h3> + <p>Wenn auf ein Host verwended wird, der in der Liste der zu ignorierenden Hosts aufgeführt ist, + wird kein Proxy benutzt.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/10-mqtt.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/10-mqtt.html new file mode 100644 index 0000000..9572a74 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/10-mqtt.html @@ -0,0 +1,83 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="mqtt in"> + <p> Stellt eine Verbindung zu einem MQTT-Broker her und subskribiert Nachrichten zu dem angegebenen Topic. </p> + <h3> Ausgaben </h3> + <dl class="message-properties"> + <dt> payload <span class="property-type"> Zeichenfolge | Buffer </span> </dt> + <dd> eine Zeichenfolge, sofern sie nicht als binärer Buffer erkannt wird. </dd> + <dt> topic <span class="property-type"> Zeichenfolge </span> </dt> + <dd> Das MQTT-Topic verwendet <code>/</code> als Trennzeichen für die Hierarchie. </dd> + <dt> qos <span class="property-type"> Zahl </span> </dt> + <dd> 0: fire und forget 1: mindestens einmal 2: einmal und nur einmal. </dd> + <dt> retain <span class="property-type"> boolean </span> </dt> + <dd> true gibt an, dass die Nachricht retained wurde und älter sein kann. </dd> + </dl> + <h3> Details </h3> + Das Subscribete Topic kann MQTT-Platzhalterzeichen, + für eine Ebene, # für mehrere Ebenen umfassen. </p> + <p> Dieser Node erfordert eine Verbindung zu einem MQTT-Broker, der über die Auswahlliste selektiert werden kann. + Eine neue Konfiguration wird durch Klicken auf das Stiftsymbol erstellt. </p> + <p> Mehrere MQTT-Nodes (in oder out) können bei Bedarf dieselbe Brokerverbindung nutzen. </p> +</script> + +<script type="text/x-red" data-help-name="mqtt out"> + <p>Stellt eine Verbindung zu einem MQTT-Broker her und publiziert Nachrichten.</p> + <h3>Eingaben</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">Zeichenfolge | Buffer</span></dt> + <dd>die meisten Benutzer präferieren einfach Textnachrichten aber es können auch binäre Buffer publiziert werden.</dd> + <dt class="optional">topic <span class="property-type">string</span></dt> + <dd> Das MQTT-Topic zu dem publiziert wird. Es verwendet <code>/</code> als Trennzeichen für die Hierarchie.</dd> + + <dt class="optional">qos <span class="property-type">number</span></dt> + <dd>0: fire und forget 1: mindestens einmal 2: einmal und nur einmal. Default 0.</dd> + + <dt class="optional">retain <span class="property-type">boolean</span></dt> + <dd>Wenn dieser Wert auf <code>true</code> gesetzt ist, wird die Nachricht auf dem Broker gehalten. Default false.</dd> + </dl> + <h3>Details</h3> + <code> msg.payload </code> wird als Nutzdaten der zu veröffentlichenden Nachricht verwendet. + Wenn er ein Objekt enthält, wird es in eine JSON-Zeichenfolge konvertiert, bevor es gesendet wird. + Wenn er einen binären Buffer enthält, wird die Nachricht unverändert veröffentlicht. </p> + <p> Das verwendete Topic kann im Node konfiguriert werden oder, falls es leer gelassen wird, + durch <code>msg.topic</code> festgelegt werden. </p> + <p> Ebenso können die QoS- und retain-Werte im Node konfiguriert werden oder, falls vorhanden, + durch <code>msg.qos</code> bzw. <code>msg.retain</code> festgelegt werden. + Sie können eine zuvor auf einem Topic auf dem Broker retainte Nachricht löschen, + indem eine leere Nachricht an dieses Topic gesendet wird und die Markierung 'retain' gesetzt ist.</p> + <p>Dieser Node erfordert eine Verbindung zu einem MQTT-Broker, der über die Auswahlliste selektiert werden kann. + Eine neue Konfiguration wird durch Klicken auf das Stiftsymbol erstellt.</p> + <p>Mehrere MQTT-Nodes (in oder out) können bei Bedarf dieselbe Brokerverbindung nutzen.</p> +</script> + +<script type="text/x-red" data-help-name="mqtt-broker"> + <p> Konfiguration für eine Verbindung zu einem MQTT-Broker. </p> + <p> Diese Konfiguration erstellt eine Verbindung zu einem Broker, die anschließend von den + Nodes <code>MQTT In</code> und <code>MQTT Out</code> verwendet werden. </p> + <p> Der Node generiert eine beliebige Client-ID, falls sie nicht definiert ist und der Node für die Verwendung + einer bereinigten Sitzung (Clean Session) konfiguriert ist. Wenn eine Client-ID festgelegt ist, + muss sie für den Broker, zu dem Sie eine Verbindung herstellen, eindeutig sein. </p> + <h3> Nachricht bei Verbindungsaufbau </h3> + <p> Dies ist eine Nachricht, die vom Broker in dem konfigurierten Topic veröffentlicht wird, wenn die Verbindung hergestellt wurde. </p> + <h3> Nachricht bei Verbindungsbeendigung </h3> + <p> Dies ist eine Nachricht, die vom Broker in dem konfigurierten Topic veröffentlicht wird, wenn die Verbindung normal geschlossen wird - + entweder durch erneute Implementierung des Nodes oder durch Herunterfahren von Node-RED. </p> + <h3> Nachricht bei unerwarteter Verbindungsbeendigung</h3> + <p> Dies ist eine Nachricht, die vom Broker in dem konfigurierten Topic veröffentlicht wird, + wenn die Verbindung unerwartet geschlossen wird + <h3> WebSockets </h3> + <p> Der Node kann für die Verwendung einer WebSocket-Verbindung konfiguriert werden. + Dazu wird im Server-Feld eine vollständigen URI für die Verbindung angegeben. Beispiel: </p> + <pre> ws://example.com:4000/mqtt </pre> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/21-httpin.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/21-httpin.html new file mode 100644 index 0000000..e38e9f1 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/21-httpin.html @@ -0,0 +1,97 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http in"> + <p>Erstellt einen HTTP Endpunkt zur Erzeugung von Web Services.</p> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>Nutzdaten</dt> + <dd>Für eine GET-Anforderung ist ein Objekt mit beliebigen Parametern der Abfragezeichenfolge oder der + Hauptteil (Body) der HTTP-Anforderung enthalten</dd> + <dt>req<span class="property-type">Objekt</span></dt> + <dd>Ein HTTP Anforderungsobjekt. Dieses Objekt enthält mehrere Eigenschaften, + die Informationen zu der Anforderung bereitstellen. + <ul> + <li><code>body</code> - Der Hauptteil der eingehenden Anforderung. Das Format hängt von der Anforderung ab.</li> + <li><code>headers</code> - ein Objekt, dass den HTTP Header enthält.</li> + <li><code>query</code> - ein Objekt, dass die Anfrage Parameter enthält.</li> + <li><code>params</code> - ein Objekt, dass die Routing Parameter enthält</li> + <li><code>cookies</code> - ein Objekt, dass die Cookies der Anfrage enthät..</li> + <li><code>files</code> - wenn die Funktion aktieviert ist, enthält dieses Objekt alle Dateien, + die mit der POST-Anforderung gesendet wurden.</li> + </ul> + </dd> + <dt>res<span class="property-type">Objekt</span></dt> + <dd>Ein HTTP-Antwortobjekt. Diese Eigenschaft sollte nicht direkt verwendet werden. + Der <code>HTTP Response</code> Node dokumentiert, wie auf eine Anforderung reagiert wird. + Diese Eigenschaft muss an die Nachricht angehängt bleiben, die an den Antwort-Node übergeben wird.</dd> + </dl> + <h3>Details</h3> + <p> Der Node ist auf dem konfigurierten Pfad für Anforderungen eines bestimmten Typs empfangsbereit. + Der Pfad kann vollständig angegeben werden, z. B. <code>/user</code> oder benannte Parameter beinhalten, + die einen beliebigen Wert akzeptieren, z. B. <code>/user/:name</code>. + Wenn benannte Parameter verwendet werden, kann auf ihren tatsachlichen Wert über <code> msg.req.params</code> + zugegriffen werden. </p> + <p> Für Anforderungen, die einen Hauptteil enthalten, wie z.B. POST oder PUT, wird der Inhalt der + Anforderung über <code>msg.payload</code> verfügbar gemacht.</p> + <p> Wenn der Inhaltstyp der Anforderung ermittelt werden kann, wird der Hauptteil syntaktisch analysiert. + Wenn zum Beispiel <code> application/json</code> erkannt wurde, die Darstellung in der JavaScript-Objekt Notation. </p> + <p> <b> Hinweis:</b> Dieser Node sendet keine Antwort an die Anforderung. Der Flow + muss einen code>HTTP Response</code> Node enthalten, um die Anforderung abzuschließen. </p> +</script> + +<script type="text/x-red" data-help-name="http response"> + <p>Sendet Antworten auf Anforderungen, die von einem code>HTTP In</code> Node empfangen wurden. </p> + <h3>Eingaben</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">Zeichenfolge</span> </dt> + <dd>Der Hauptteil der Antwort.</dd> + <dt class="optional">statusCode<span class="property-type">Zahl</span> </dt> + <dd>Wenn festgelegt wird diese als Antwortstatuscode verwendet. Standardwert: 200. </dd> + <dt class="optional">Header<span class="property-type">Objekt</span> </dt> + <dd> Wenn festgelegt enthält es die HTTP-Header, die in die Antwort mit eingeschlossen werden sollen. </dd> + <dt class="optional">Cookies<span class="property-type">Objekt</span> </dt> + <dd> Wenn festgelegt kann es zum Setzen oder Löschen von Cookies verwendet werden. </dd> + </dl> + <h3>Details</h3> + <p>Der <code>StatusCode</code> und die <code>Header</code> können auch innerhalb des Node gesetzt werden. + Wenn eine Eigenschaft innerhalb des Nodes festgelegt wird, + kann sie nicht durch die entsprechende Nachrichteneigenschaft überschrieben werden.</p> + <h4>Behandlung von Cookies</h4> + <p> Die Eigenschaft <code>Cookies</code> muss ein Objekt mit Name/Wert-Paaren sein. + Bei dem Wert kann es sich entweder um eine Zeichenfolge handeln, um den Wert des Cookies mit Standardwert festzulegen + oder es kann ein Objekt mit Optionen sein. <p> + <p> Im folgenden Beispiel werden zwei Cookies festgelegt - einer mit dem Namen <code>name</code> mit + einem Wert von <code>nick</code> und der andere als <code>session</code> mit einem Wert von + <code>1234</code> und einer festgelegten Ablaufzeit von 15 Minuten. </p> + <pre> +msg.cookies = { + name: 'nick', + session: { + value: '1234', + maxAge: 900000 + } } </pre> + <p>Die gültigen Optionen sind: </p> + <ul> + <li><code>Domäne</code> -(Zeichenfolge) Domänenname für das Cookie </li> + <li><code>expires</code> -(Datum) Ablaufzeit in GMT. Wenn Sie keinen Wert angeben oder auf 0 setzen, wird ein Sitzungscookie erstellt. </li> + <li><code>maxAge</code> -(Zeichenfolge) Ablaufzeit in Bezug auf die aktuelle Zeit in Millisekunden </li> + <li><code>Pfad</code> -(String) Pfad für das Cookie. Standardwert: / </li> + <li><code>value</code> -(String) der Wert, der für das Cookie verwendet werden soll </li> + </ul> + <p> Um ein Cookie zu löschen, setzen Sie seinen <code>value</code> auf <code>null</code>. </p> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/21-httprequest.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/21-httprequest.html new file mode 100644 index 0000000..2238549 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/21-httprequest.html @@ -0,0 +1,86 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http request"> + <p>Sendet HTTP-Anforderungen und gibt die Antwort zurück.</p> + + <h3>Eingaben</h3> + <dl class="message-properties"> + <dt class="optional">url <span class="property-type">String</span></dt> + <dd>Wenn nicht im Node konfiguriert, setzt diese optionale Eigenschaft die URL der Anforderung.</dd> + <dt class="optional">method <span class="property-type">String</span></dt> + <dd>Wenn nicht im Node konfiguriert, setzt diese optionale Eigenschaft die HTTP-Methode der Anforderung. + Muss einer von <code>GET</code>, <code>PUT</code>, <code>POST</code>, <code>PATCH</code> oder <code>DELETE</code> sein.</dd> + <dt class="optional">headers <span class="property-type">Objekt</span></dt> + <dd>Setzt die HTTP-Header der Anforderung.</dd> + <dt class="optional">cookies <span class="property-type">Objekt</span></dt> + <dd>Wenn gesetzt, kann es verwendet werden, um Cookies mit der Anforderung zu senden.</dd> + <dt class="optional">payload</dt> + <dd>Wird als Hauptteil der Anforderung gesendet.</dd> + <dt class="optional">rejectUnauthorized</dt> + <dd>Wenn auf <code>false</code> gesetzt, können Anforderungen an https-Sites gesendet werden, die selbst signierte Zertifikate verwenden.</dd> + <dt class="optional">followRedirects</dt> + <dd>Wenn auf <code>false</code> gesetzt, wird ein folgendes Redirect (HTTP 301) verhindert. + In der Standardeinstellung ist <code>true</code>.</dd> + <dt class="optional">requestTimeout</dt> + <dd>Wenn dieser Wert auf eine positive Zahl eingestellt ist, + wird damit der global eingestellte Parameter <code>httpRequestTimeout</code> überschrieben.</dd> + </dl> + <h3>Ausgaben</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">String | Objekt | Buffer</span></dt> + <dd>Der Hauptteil der Antwort. Der Node kann konfiguriert werden, um den Hauptteil als String zurückzugeben, + zu versuchen, ihn als JSON-String zu analysieren oder ihn als binären Buffer zu belassen.</dd> + <dt>statusCode <span class="property-type">Zahl</span></dt> + <dd>Der Statuscode der Antwort oder der Fehlercode, wenn die Anforderung nicht abgeschlossen werden konnte.</dd> + <dt>headers <span class="property-type">Objekt</span></dt> + <dd>Ein Objekt, das die HTTP-Header der Antwort enthält.</dd> + <dt>responseUrl <span class="property-type">String</span></dt> + <dd>Falls während der Bearbeitung der Anforderung Umleitungen aufgetreten sind, ist diese Eigenschaft die letzte umgelenkte URL. + Andernfalls die URL der ursprünglichen Anforderung.</dd> + <dt>responseCookies <span class="property-type">Objekt</span></dt> + <dd>Wenn die Antwort Cookies enthält, ist dieses Element ein Objekt von Namen/Wertpaaren für jedes Cookie.</dd> + </dl> + <h3>Details</h3> + <p>Wenn innerhalb des Nodes konfiguriert, kann die URL-Eigenschaft + <a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache-style</a> Tags enthalten. + Diese ermöglicht es, die URL aus den Werten der eingehenden Nachricht aufzubauen. + Wenn die URL beispielsweise auf <code>example.com/{{{topic}}}</code> gesetzt ist, + wird der Wert von <code>msg.topic</code> automatisch eingefügt. + Die Verwendung von {{{....}} hindert den Mustache am Escaping von Zeichen wie / & etc.</p> + <p><b>Note</b>: Wenn Node-RED hinter einem Proxy läuft, sollte die Umgebungsvariable <code>http_proxy=...</code> gesetzt + und Node-RED neu gestartet werden, oder eine Proxy Konfiguration wird verwendet. + Wenn die Proxy-Konfiguration verwendet wird, hat diese Konfiguration Vorrang vor der Umgebungsvariablen.</p> + <h4>Verwendung mehrerer HTTP-Anforderungs-Node</h4> + <p>Um mehr als einen dieser Node im gleichen Flow verwenden zu können, + ist Vorsicht bei der Verwendung der Eigenschaft <code>msg.headers</code> geboten + Der erste Node setzt diese Eigenschaft mit dem Antwortheader. + Der nächste Node verwendet dann diese Header für seine Anfrage - diese sind aber in der Regel nicht die Richtigen. + Wenn die Eigenschaft <code>msg.headers</code> zwischen den Nodes unverändert bleibt, wird sie vom zweiten Node ignoriert. + Um benutzerdefinierte Header festzulegen, sollte <code>msg.headers</code> zuerst gelöscht + oder auf ein leeres Objekt gesetzt werden: <code>{}</code>.</p> + <h4>Behandlung von Cookies</h4> + <p>Die an den Node übergebene Eigenschaft <code>cookies</code> muss ein Objekt von Name/Wert Paaren sein. + Der Wert kann entweder ein String sein, um den Wert des Cookies zu setzen, + oder es kann ein Objekt mit einer einzigen <code>value</code> Eigenschaft sein.<p> + <p>Alle von der Anforderung zurückgegebenen Cookies werden unter der Eigenschaft <code>responseCookies</code> zurückgegeben.</p> + <h4>Behandlung von Content-Typen</h4> + <p>Wenn <code>msg.payload</code> ein Objekt ist, setzt der Node automatisch den Inhaltstyp der Anforderung + auf <code>application/json</code> und kodiert den Hauptteil als solchen.</p> + <p>Um die Anforderung als Formulardaten zu kodieren, + sollte <code>msg.headers["content-type"]</code> auf <code>application/x-wwww-form-urlencoded</code> gesetzt werden.</p> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/22-websocket.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/22-websocket.html new file mode 100644 index 0000000..5aa5cf8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/22-websocket.html @@ -0,0 +1,66 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="websocket in"> + <p>WebSocket Eingangs-Node.</p> + <p>Standardmäßig befinden sich die vom WebSocket empfangenen Daten in <code>msg.payload</code>. + Der Socket kann konfiguriert werden, um einen korrekt gebildeten JSON-String zu erwarten, + in diesem Fall wird er das JSON analysieren und das resultierende Objekt als gesamte Nachricht senden.</p> +</script> + +<script type="text/x-red" data-help-name="websocket out"> + <p>WebSocket Ausgabe-Node.</p> + <p>Standardmäßig wird <code>msg.payload</code> über den WebSocket gesendet. + Der Socket kann so konfiguriert werden, dass er das gesamte <code>msg</code> Objekt als JSON-String kodiert und über den WebSocket sendet.</p> + + <p>Wenn die an diesem Node ankommende Nachricht an einem WebSocket-Eingangs-Node begann, + wird die Nachricht an den Client zurückgesendet, der den Flow ausgelöst hat. + Andernfalls wird die Nachricht an alle verbundenen Clients gesendet..</p> + <p>Wenn eine Nachricht, die an einem WebSocket-Eingangsnoten gestartet wurde, an alle verbunden Clients gesendet werden soll, + muss die Eigenschaft <code>msg._session</code> innerhalb des Flow gelöscht werden.</p> +</script> + +<script type="text/x-red" data-help-name="websocket-listener"> + <p>Dieser Konfigurations-Node erstellt einen WebSocket Server-Endpunkt unter Verwendung des angegebenen Pfades.</p> +</script> + +<!-- WebSocket Client configuration node --> +<script type="text/x-red" data-template-name="websocket-client"> + <div class="form-row"> + <label for="node-config-input-path"><i class="fa fa-bookmark"></i> <span data-i18n="websocket.label.url"></span></label> + <input id="node-config-input-path" type="text" placeholder="ws://example.com/ws"> + </div> + <div class="form-row node-config-row-tls hide"> + <label for="node-config-input-tls" data-i18n="httpin.tls-config"></label> + <input type="text" id="node-config-input-tls"> + </div> + + <div class="form-row"> + <label for="node-config-input-wholemsg" data-i18n="websocket.sendrec"></label> + <select type="text" id="node-config-input-wholemsg" style="width: 70%;"> + <option value="false" data-i18n="websocket.payload"></option> + <option value="true" data-i18n="websocket.message"></option> + </select> + </div> + <div class="form-tips"> + <p><span data-i18n="[html]websocket.tip.url1"></span></p> + <span data-i18n="[html]websocket.tip.url2"></span> + </div> +</script> + +<script type="text/x-red" data-help-name="websocket-client"> + <p>Dieser Konfigurations-Node verbindet einen WebSocket-Client mit der angegebenen URL.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/31-tcpin.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/31-tcpin.html new file mode 100644 index 0000000..2b22418 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/31-tcpin.html @@ -0,0 +1,45 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="tcp in"> + <p>Bietet eine Auswahl an TCP-Eingängen. Kann sich entweder mit einem entfernten TCP-Port verbinden oder eingehende Verbindungen akzeptieren.</p> + <p><b>Note: </b>Auf einigen Systemen benötigen Sie möglicherweise Root- oder Administratorzugriff, um + Ports unter 1024 und/oder Broadcast nutzen zu können.</p> +</script> + +<script type="text/x-red" data-help-name="tcp out"> + <p>Bietet eine Auswahl an TCP-Ausgängen. Kann sich entweder mit einem entfernten TCP-Port verbinden, + eingehende Verbindungen akzeptieren oder auf Nachrichten antworten, die von einem TCP-In-Node empfangen werden.</p> + <p>Nur der Inhalt von <code>msg.payload</code> wird gesendet.</p> + <p>Wenn <code>msg.payload</code> einen String beinhaltet, die eine Base64-Kodierung von binären + Daten darstellt, wird die <code>Dekodiere Base64</codes> Option dazu führen, + dass sie wieder in Binärdaten umgewandelt wird bevor sie verschickt werden.</p> + <p>Wenn <code>msg._session</code> nicht vorhanden ist, wird der Payload an <b>alle</b> alle verbundenen Clients gesendet.</p> + <p><b>Note: </b>Auf einigen Systemen benötigen Sie möglicherweise Root- oder Administratorzugriff, um + Ports unter 1024 und/oder Broadcast nutzen zu können.</p> +</script> + +<script type="text/x-red" data-help-name="tcp request"> + <p>Ein einfacher TCP-Anforderungs-Node - sendet die <code>msg.payload</code> an einen Server-TCP-Port und erwartet eine Antwort.</p> + <p>Verbindet sich, sendet die "Anforderung" und liest die "Antwort". Der Node wartet entweder auf eine vorgegebene Anzahl von + Zeichen in einen festen Buffer, auf ein bestimmtes Zeichen oder einen festen Timeout ab der ersten Antwort, + bevor er die Verbindug schliesst und die Daten an den Flow zurück gibt. + Alternativ hält der Node die Verbindung ständig offen. </p> + <p>Die Antwort wird in <code>msg.payload</code> als Buffer ausgegeben, so dass sie unter Umständen mit einer + <code> .toString()>/code> Funktion umgewandelt werden müssen.</p> + <p>Wenn <code>tcp host</code> oder <code>port</code> leer gelassen werden, + müssen diese mit den Eigenschaften <code>msg.host</code> und <code>msg.port</code> übergeben werden.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/32-udp.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/32-udp.html new file mode 100644 index 0000000..2abc6cb --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/network/32-udp.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="udp in"> + <p>Ein UDP-Eingangs-Node, der eine <code>msg.payload</code> erzeugt, die einen + Buffer, Strings oder base64-kodierter String enthält. Multicast wird unterstützt.</p> + <p>Über die Eigenschaften <code>msg.ip</code> und <code>msg.port</code> kann auf die Werte der + IP Addresse und des Ports zugegriffen werden, von dem die Nachtricht empfangen wurde.</p> + <p><b>Note</b>: Auf einigen Systemen benötigen Sie möglicherweise Root- oder Administratorzugriff, um + Ports unter 1024 und/oder Broadcast nutzen zu können.</p> +</script> + +<script type="text/x-red" data-help-name="udp out"> + <p>Dieser Node sendet <code>msg.payload</code> an den angegebenen UDP-Host und Port. Multicast wird unterstützt.</p> + <p>Sie können <code>msg.ip</code> und <code>msg.port</code> verwenden, um die Zielwerte festzulegen, + aber die statisch im Node konfigurierten Werte haben Vorrang.</p> + <p>Wenn Sie Broadcast auswählen, stellen Sie entweder die Adresse auf die lokale Broadcast-IP-Adresse + oder versuchen Sie es mit 255.255.255.255, was die globale Broadcast-Adresse ist.</p> + <p><b>Note</b>: Auf einigen Systemen benötigen Sie möglicherweise Root- oder Administratorzugriff, um + Ports unter 1024 und/oder Broadcast nutzen zu können.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/parsers/70-CSV.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/parsers/70-CSV.html new file mode 100644 index 0000000..1dd5b71 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/parsers/70-CSV.html @@ -0,0 +1,47 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="csv"> + <p>Konvertiert zwischen einem CSV-formatierten String und ihrer JavaScript-Objektdarstellung in beide Richtungen.</p> + <h3>Eingaben</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">Objekt | Array | String</span></dt> + <dd>Ein JavaScript Objekt, Array oder CSV String.</dd> + </dl> + <h3>Ausgaben</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">Objekt | Array | String</span></dt> + <dd> + <ul> + <li>Wenn die Eingabe ein String ist, wird versucht sie als CSV zu analysieren und + es wird für jede Zeile ein JavaScript-Objekt mit Schlüssel/Wertpaaren erstellt. + Der Node sendet dann entweder eine Nachricht für jede Zeile oder eine einzelne Nachricht mit einem Array von Objekten.</li> + <li>Wenn die Eingabe ein JavaScript-Objekt ist, wird versucht ein CSV-String zu erzeugen.</li> + <li>Wenn die Eingabe ein Array mit einfachen Werten ist, wird ein einzeiliger CSV-String erstellt.</li> + <li>Wenn die Eingabe ein Array von Arrays oder ein Array von Objekten ist, wird ein mehrzeiliger CSV-String erstellt.</li> + </ul> + </dd> + </dl> + <h3>Details</h3> + <p>Die Spaltenvorlage kann eine geordnete Liste von Spaltennamen enthalten. Bei der Konvertierung von CSV in ein Objekt werden die + Spaltennamen als Eigenschaftsname verwendet. Alternativ können die Spaltennamen auch aus der ersten Zeile des CSV übernommen werden.</p> + <p>Bei der Konvertierung nach CSV wird die Spaltenvorlage verwendet, um festzustellen, + welche Eigenschaften aus dem Objekt in welcher Reihenfolge extrahiert werden sollen.</p> + <p>Wenn die Eingabe ein Array ist, wird die Spaltenvorlage nur verwendet, um optional eine Reihe von Spaltentiteln zu erzeugen.</p> + <p>Der Node kann eine mehrteilige Eingabe akzeptieren, solange die Eigenschaft <code>parts</code> korrekt gesetzt ist.</p> + <p>Wenn mehrere Nachrichten ausgeben werden, sind ihre <code>parts</code>-Eigenschaft festgelegt und sie bilden eine vollständige Nachrichtensequenz.</p> + <p><b>Note:</b> die Spaltenvorlage muss kommagetrennt sein - auch wenn für die Daten ein anderes Trennzeichen gewählt wird.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/parsers/70-HTML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/parsers/70-HTML.html new file mode 100644 index 0000000..fb6b446 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/parsers/70-HTML.html @@ -0,0 +1,37 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="html"> + <p>Extrahiert unter Verwendung eines CSS-Selektors Elemente aus einem HTML-Dokument, das sich in <code>msg.payload</code> befindet.</p> + <h3>Eingaben</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">String</span></dt> + <dd>der html-String, aus der Elemente extrahiert werden sollen.</dd> + <dt class="optional">select <span class="property-type">String</span></dt> + <dd>wenn nicht im Edit-Panel konfiguriert, kann der Selektor als Eigenschaft der Nachricht übergeben werden.</dd> +</dl> + <h3>Ausgaben</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">Array | String</span></dt> + <dd>das Ergebnis kann entweder eine einzelne Nachricht mit eine, Payload sein, das ein Array der übereinstimmenden Elemente enthält + oder mehrere Nachrichten, die jeweils ein passendes Element enthalten. + Wenn mehrere Nachrichten gesendet werden, haben sie auch <code>parts</code> gesetzt.</dd> + </dl> + <h3>Details</h3> + <p>Dieser Node unterstützt eine Kombination aus CSS- und jQuery-Selektoren. Siehe die + <a href="https://github.com/fb55/CSSselect#user-content-supported-selectors" target="_blank">css-select Dokumentation</a> + für weitere Informationen über die unterstützte Syntax.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/parsers/70-JSON.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/parsers/70-JSON.html new file mode 100644 index 0000000..1c2311a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/parsers/70-JSON.html @@ -0,0 +1,51 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="json"> + <p>Konvertiert zwischen einem JSON-String und seiner JavaScript-Objektdarstellung in beide Richtungen.</p> + <h3>Eingaben</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">Objekt | String</span></dt> + <dd>Ein JavaScript Objekt oder ein String.</dd> + <dt>schema<span class="property-type">Objekt</span></dt> + <dd>Ein optionales JSON Schema Objekt gegen das das JSON Objekt validiert wird.</dd> + </dl> + <h3>Ausgaben</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">Objekt | String</span></dt> + <dd> + <ul> + <li>Wenn die Eingabe ein JSON-String ist, wird versucht ihn in ein JavaScript-Objekt zu parsen..</li> + <li>Wenn die Eingabe ein JavaScript-Objekt ist, wird ein JSON-String erstellt. Der String kann optional gut formatiert werden.</li> + </ul> + </dd> + <dt>schemaError<span class="property-type">Array</span></dt> + <dd>Wenn die JSON-Schemavalidierung fehlschlägt, wird für den <code>Catch</code> Node eine <code>schemaError</code> Eigenschaft erstellt, + die ein Array von Fehlern enthält.</dd> + </dl> + <h3>Details</h3> + <p>Standardmäßig arbeitet der Node mit <code>msg.payload</code>, kann aber so konfiguriert werden, dass eine beliebige + Nachrichteneigenschaft konvertiert wird.</p> + <p>Der Node kann auch konfiguriert werden, um eine bestimmte Kodierung sicherzustellen, anstatt zwischen den beiden umzuschalten. + Dies kann z.B. mit dem <code>HTTP In</code> Node benutzt werden, um sicherzustellen, dass der Payload ein analysiertes Objekt ist, + auch wenn eine eingehende Anfrage seinen Inhaltstyp nicht korrekt eingestellt hat, damit der <code>HTTP In</code> Node + die Konvertierung durchführen kann.</p> + <p>Wenn der Node so konfiguriert ist, dass die Eigenschaft als String kodiert wird, und es einen String empfängt, + werden keine weiteren Prüfungen der Eigenschaft durchgeführt. + Es wird weder prüfen, ob der String ein gültiges JSON enthält noch wird er ihn neu formatieren, wenn die Format-Option ausgewählt ist.</p> + <p>Für weitere Details über das JSON-Schema + können Sie die <a href="http://json-schema.org/latest/json-schema-validation.html">Spezifikation</a> einsehen.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/parsers/70-XML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/parsers/70-XML.html new file mode 100644 index 0000000..2b9d172 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/parsers/70-XML.html @@ -0,0 +1,52 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="xml"> + <p>Konvertiert zwischen einem XML-String und seiner JavaScript-Objektdarstellung - in beiden Richtungen.</p> + <h3>Eingaben</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">Objekt | String</span></dt> + <dd>Ein JavaScript Objekt oder ein XML String.</dd> + </dl> + <h3>Ausgaben</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">Objekt | String</span></dt> + <dd> + <ul> + <li>Wenn die Eingabe ein String ist, wird versucht sie als XML zu analysieren und daraus ein JavaScript-Objekt zu erstellen.</li> + <li>Wenn die Eingabe ein JavaScript-Objekt ist, wird versucht ein XML-String zu erstellen.</li> + </ul> + </dd> + <dt class="optional">Optionen <span class="property-type">Objekt</span></dt> + <dd>This optional property can be used to pass in any of the options supported by the underlying + library used to convert to and from XML. See <a href="https://github.com/Leonidas-from-XIV/node-xml2js/blob/master/README.md#options" target="_blank">the xml2js docs</a> + for more information.</dd> + </dl> + <h3>Details</h3> + <p>Bei der Konvertierung zwischen XML und einem Objekt werden standardmäßig alle XML-Attribute als Eigenschaft namens <code>$</code> hinzugefügt. + Jeder Textinhalt wird als Eigenschaft namens <code>_</code> hinzugefügt. + Diese Eigenschaftsnamen können in der Node-Konfiguration angegeben werden.</p> + <p>Zum Beispiel wird das folgende XML wie dargestellt konvertiert:</p> + <pre>&lt;p class="tag"&gt;Hello World&lt;/p&gt;</pre> + <pre>{ + "p": { + "$": { + "class": "tag" + }, + "_": "Hello World" + } +}</pre> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/parsers/70-YAML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/parsers/70-YAML.html new file mode 100644 index 0000000..3d42494 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/parsers/70-YAML.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="yaml"> + <p>Konvertiert zwischen einer YAML-formatierten String und ihrer JavaScript-Objektdarstellung in beide Richtungen.</p> + <h3>Eingaben</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">Objekt | String</span></dt> + <dd>Ein JavaScript Objekt oder ein YAML String.</dd> + </dl> + <h3>Ausgaben</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">Objekt | String</span></dt> + <dd> + <ul> + <li>Wenn die Eingabe ein YAML-String ist, wird versucht ihn in ein JavaScript-Objekt zu parsen.</li> + <li>Wenn die Eingabe ein JavaScript-Objekt ist, wird ein YAML-String erstellt.</li> + </ul> + </dd> + </dl> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/sequence/17-split.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/sequence/17-split.html new file mode 100644 index 0000000..eaa3f7d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/sequence/17-split.html @@ -0,0 +1,162 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="split"> + <p>Teilt eine Nachricht in eine Folge von Nachrichten auf.</p> + + <h3>Eingaben</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">Objekt | String | Array | Buffer</span></dt> + <dd>Das Verhalten des Nodes wird durch den Typ der <code>msg.payload</code> bestimmt: + <ul> + <li><b>String</b>/<b>Buffer</b> - die Nachricht wird anhand des angegebenen Zeichens (Standard: <code>\n</code>), + der Buffersequenz oder in feste Längen aufgeteilt.</li> + <li><b>Array</b> - die Nachricht wird entweder in einzelne Array-Elemente oder Arrays mit fester Länge aufgeteilt.</li> + <li><b>Objekt</b> - es wird für jedes Schlüssel-Wert-Paar des Objekts eine Nachricht gesendet.</li> + </ul> + </dd> + </dl> + <h3>Ausgaben</h3> + <dl class="message-properties"> + <dt>parts<span class="property-type">Objekt</span></dt> + <dd>Diese Eigenschaft enthält Informationen darüber, wie die Nachricht von der ursprünglichen Nachricht getrennt wurde. + Wenn sie an einen Node <b>join</b> übergeben werden, + kann die Sequenz wieder zu einer einzigen Nachricht zusammengefasst werden. + Diese Eigenschaft hat die folgenden Eigenschaften: + <ul> + <li><code>id</code> - ein Identifikator für die Gruppe der Nachrichten</li> + <li><code>index</code> - die Position innerhalb der Gruppep</li> + <li><code>count</code> - falls bekannt, die Gesamtzahl der Nachrichten in der Gruppe. Siehe dazu unten "Streaming-Modus".</li> + <li><code>type</code> - die Art der Nachricht - string/array/object/buffer</li> + <li><code>ch</code> - für ein String oder einen Buffer, die Daten, die für das Aufteilen der Nachricht verwendet wurden, entweder als String oder als Array von Bytes.</li> + <li><code>key</code> - für ein Objekt, den Schlüssel der Eigenschaft, aus der diese Nachricht erstellt wurde. Der Node kann konfiguriert werden, um diesen Wert auch in andere Nachrichteneigenschaften zu kopieren, wie z.B. <code>msg.topic</code>.</li> + <li><code>len</code> - die Länge jeder Nachricht, wenn sie durch einen Wert fester Länge aufgeteilt wird.</li> + </ul> + </dd> + </dl> + <h3>Details</h3> + <p>Dieser Node macht es einfach, einen Flow zu erstellen, der gemeinsame Aktionen über eine Sequenz von Nachrichten ausführt, + bevor er den Node <b>join</b> verwendet und die Sequenz zu einer einzigen Nachricht neu kombiniert.</p> + <p>Es verwendet die Eigenschaft <code>msg.parts</code>, um die einzelnen Teile einer Sequenz zu verfolgen.</p> + <h4>Streaming Modus</h4> + <p>Der Node kann auch zum Wiederaufbereiten eines Nachrichtenstroms verwendet werden. + So kann beispielsweise ein serielles Gerät, das <code><newline/code>-terminierte Befehle sendet, + eine einzelne Nachricht mit einem Teilbefehl am Ende liefern. + Im Streaming-Modus teilt dieser Node eine Nachricht auf und sendet jedes komplette Segment. + Befindet er sich am Ende eines Teilsegments, hält der Node es fest und wird es der nächsten empfangenen Nachricht voranstellen. + </p> + <p>Wenn der Node in diesem Modus arbeitet, setzt er die Eigenschaft <code>msg.parts.count</code> nicht, da er nicht weiß, wie viele Nachrichten im Stream zu erwarten sind. + Das bedeutet, dass er nicht mit dem <b>join</b> Node im Automatikmodus verwendet werden kann.</p> +</script> + +<script type="text/x-red" data-help-name="join"> + <p>Verbindet Sequenzen von Nachrichten zu einer einzigen Nachricht.</p> + <p>Es sind drei Modi verfügbar:</p> + <dl> + <dt>automatisch</dt> + <dd>Wenn es mit dem Node <b>split</b> gepaart wird, verbindet es automatisch die Nachrichten, um die durchgeführte Aufteilung rückgängig zu machen.</dd> + <dt>manual</dt> + <dd>Die Sequenzen von Nachrichten können auf verschiedene Weise verknüpft werden.</dd> + <dt>Reihenfolge reduzieren</dt> + <dd>Einen Ausdruck auf alle Nachrichten in einer Sequenz anwenden, um sie auf eine einzige Nachricht zu reduzieren.</dd> + </dl> + <h3>Eingaben</h3> + <dl class="message-properties"> + <dt class="optional">parts<span class="property-type">Objekt</span></dt> + <dd>Um automatisch einer Nachrichtensequenz beizutreten, sollten sie alle über diese Eigenschaft verfügen. + Der Node <b>split</b> erzeugt diese Eigenschaft, sie kann aber manuell erstellt werden. + Es hat die folgenden Eigenschaften: + <ul> + <li><code>id</code> - ein Identifikator für die Gruppe der Nachrichten</li> + <li><code>index</code> - die Position innerhalb der Gruppep</li> + <li><code>count</code> - fie Gesamtzahl der Nachrichten in der Gruppe.</li> + <li><code>type</code> - die Art der Nachricht - string/array/object/buffer</li> + <li><code>ch</code> - für ein String oder einen Buffer, die Daten, die für das Aufteilen der Nachricht verwendet wurden, entweder als String oder als Array von Bytes.</li> + <li><code>key</code> - für ein Objekt, den Schlüssel der Eigenschaft, aus der diese Nachricht erstellt wurde.</li> + <li><code>len</code> - die Länge jeder Nachricht, wenn sie durch einen Wert fester Länge aufgeteilt wird.</li> + </ul> + </dd> + <dt class="optional">complete</dt> + <dd>Wenn gesetzt, sendet der Node seine Ausgangsnachricht im aktuellen Zustand.</dd> + </dl> + <h3>Details</h3> + + <h4>Automatischer Modus</h4> + <p>Der automatische Modus verwendet die Eigenschaft <code>parts</code> der eingehenden Nachrichten, um festzulegen, + wie die Sequenz verknüpft werden soll. + Dies ermöglicht es ihm, die Aktion eines <b>split</b>-Nodes automatisch rückgängig zu machen. + </p> + <h4>Manueller Modus</h4> + <p>Wenn der Node für die Zusammenführung im manuellen Modus konfiguriert ist, + kann er Sequenzen von Nachrichten zu einer Reihe von verschiedenen Ergebnissen zusammenfügen:</p> + <ul> + <li>ein <b>String </b> oder <b>Buffer</b> - erstellt durch Verbinden der ausgewählten Eigenschaft + jeder Nachricht mit den angegebenen Join-Zeichen oder dem angegebenen Buffer.</li> + <li>ein <b>Array</b> - erstellt durch Hinzufügen jeder ausgewählten Eigenschaft oder einer ganzen Nachricht zum Ausgangsarray.</li> + <li>ein <b>Schlüssel/Wert-Objekt</b> - erstellt durch Verwendung einer Eigenschaft jeder Nachricht, um den Schlüssel zu bestimmen, + unter dem der gewünschte Wert gespeichert ist.</li> + <li>ein <b>zusammengefügtes Objekt</b> - erstellt durch Zusammenführen der Eigenschaft jeder Nachricht unter einem einzigen Objekt.</li> + </ul> + <p>Die anderen Eigenschaften der Ausgangsnachricht werden aus der letzten empfangenen Nachricht entnommen, bevor das Ergebnis gesendet wird.</p> + <p>Mit <i>count</i> kann angegeben werden, wie viele Nachrichten vor dem Erzeugen der Ausgabemeldung empfangen werden sollen. + Bei Objektausgaben kann der Node nach Erreichen dieser Anzahl konfiguriert werden, + um für jede nachfolgende empfangene Nachricht eine Nachricht zu senden.</p> + <p>Ein <i>Timeout</i> kann so eingestellt werden, dass das Senden einer neuen Nachricht mit dem ausgelöst wird, was bisher empfangen wurde.</p> + <p>Wenn eine Nachricht mit der Eigenschaft <b>msg.complete</b> empfangen wird, wird die Ausgabemeldung finalisiert und gesendet. + Dadurch wird die Zählung aller Teile zurückgesetzt.</p> + <p>Wenn eine Nachricht mit der Eigenschaft <b>msg.reset</b> empfangen wird, wird die teilweise vollständige Nachricht gelöscht und nicht gesendet. + Dadurch wird die Zählung aller Teile zurückgesetzt.</p> + + <h4>Reduktion der Sequenz Modus</h4> + <p>Wenn sie so konfiguriert sind, dass sie sich im Reduktionsmodus befinden, wird auf jede Nachricht in einer Sequenz ein Ausdruck angewendet + und das Ergebnis zu einer einzigen Nachricht zusammengefasst.</p> + + <dl class="message-properties"> + <dt>Anfangswert</dt> + <dd>Der Anfangswert des kumulierten Wertes (<code>$A</code>).</dd> + <dt>Reduktionsausdruck</dt> + <dd>Ein JSONata-Ausdruck, der für jede Nachricht in der Sequenz aufgerufen wird. + Das Ergebnis wird als kumulierter Wert an den nächsten Aufruf des Ausdrucks übergeben. + Im Ausdruck können die folgenden speziellen Variablen verwendet werden: + <ul> + <li><code>$A</code>: der kumulierte Wert, </li> + <li><code>$I</code>: Index der Nachricht innerhalb der Squenz, </li> + <li><code>$N</code>: Anzahl der Nachrichten in der Sequenz.</li> + </ul> + </dd> + <dt>Fix-up Ausdruck</dt> + <dd>Ein optionaler JSONata-Ausdruck, der angewendet wird, nachdem der Reduzierungsausdruck auf alle Nachrichten in der Sequenz angewendet wurde. + Im Ausdruck können folgende spezielle Variablen verwendet werden: + <ul> + <li><code>$A</code>: der kumulierte Wert, </li> + <li><code>$N</code>: Anzahl der Nachrichten in der Sequenz.</li> + </ul> + </dd> + <p>Standardmäßig wird der Reduktionsausdruck in der Reihenfolge von der ersten bis zur letzten Nachricht der Sequenz angewendet. + Er kann optional in umgekehrter Reihenfolge angewendet werden.</p> + </dl> + <p><b>Beispiel:</b> Die folgenden Einstellungen berechnen bei einer Folge von Zahlenwerten den Mittelwert: + <ul> + <li><b>Reduce expression</b>: <code>$A+payload</code></li> + <li><b>Initial value</b>: <code>0</code></li> + <li><b>Fix-up expression</b>: <code>$A/$N</code></li> + </ul> + </p> + <h4>Speichern von Nachrichtens</h4> + <p>Dieser Node puffert Nachrichten intern, um sequenzübergreifend zu arbeiten. + Mit der Laufzeiteinstellung <code>nodeMessageBufferMaxLength</code> kann begrenzt werden, + wie viele Nachrichten im Node zwischengespeichert werden sollen.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/sequence/18-sort.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/sequence/18-sort.html new file mode 100644 index 0000000..d2351fb --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/sequence/18-sort.html @@ -0,0 +1,45 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="sort"> + <p>Eine Funktion, die die Nachrichteneigenschaft oder eine Folge von Nachrichten sortiert.</p> + <p>Wenn der Node konfiguriert ist, um die Nachrichteneigenschaft zu sortieren, + sortiert er Array-Daten, auf die von der angegebenen Nachrichteneigenschaft verwiesen wird.</p> + <p>Wenn der Node konfiguriert ist, um eine Folge von Nachrichten zu sortieren, ordnet er die Nachrichten neu.</p> + <p>Die Sortierreihenfolge kann sein:</p> + <ul> + <li><b>aufsteigend</b>,</li> + <li><b>absteigend</b>.</li> + </ul> + <p>Für Zahlen kann die numerische Reihenfolge durch ein Kontrollkästchen festgelegt werden.</p> + <p>Der Sortierschlüssel kann ein Elementwert oder ein JSONata-Ausdruck zum Sortieren des Eigenschaftswerts + oder eine Nachrichteneigenschaft oder ein JSONata-Ausdruck zum Sortieren einer Nachrichtensequenz sein.<p> + <p>Beim Sortieren einer Nachrichtenfolge verlässt sich der SortierNode auf die empfangenen Nachrichten, bei denen <code>msg.parts</code> gesetzt ist. + Der Split-Node erzeugt diese Eigenschaft, kann aber manuell angelegt werden. Es hat die folgenden Eigenschaften:</p> + <p> + <ul> + <li><code>id</code> - ein Identifikator für die Gruppe der Nachrichten</li> + <li><code>index</code> - die Position innerhalb einer Gruppe</li> + <li><code>count</code> - die Anzahl von Nachrichten in einer Gruppe</li> + </ul> + </p> + <p><b>Note:</b> Dieser Node speichert intern Nachrichten für seinen Betrieb. Um einen unerwarteten Speicherverbrauch zu vermeiden, kann die maximale Anzahl der gespeicherten Nachrichten angegeben werden. + Standardmäßig ist die Anzahl der Nachrichten nicht begrenzt. + <ul> + <li>Es kann die Eigenschaft <code>nodeMessageBufferMaxLength</code> in der Datei <b>settings.js</b> gesetzt werden.</li> + </ul> + </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/sequence/19-batch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/sequence/19-batch.html new file mode 100644 index 0000000..e16815b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/sequence/19-batch.html @@ -0,0 +1,42 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="batch"> + <p>Erstellt Sequenzen von Nachrichten nach verschiedenen Regeln.</p> + <h3>Details</h3> + <p>Es gibt drei Modi für die Erstellung von Nachrichtensequenzen:</p> + <dl> + <dt>Anzahl der Nachrichten</dt> + <dd>Die Nachrichten werden zu Sequenzen einer bestimmten Länge gruppiert. Die Option <b>Überlappung</b>> + gibt an, wie viele Nachrichten vom Ende einer Sequenz am Anfang der nächsten Sequenz wiederholt werden sollen.</dd> + + <dt>Zeitintervall</dt> + <dd>Gruppiert Nachrichten, die innerhalb des angegebenen Intervalls eingehen. Wenn keine Nachrichten + innerhalb des Intervalls ankommen, kann der Node optional eine leere Nachricht senden.</dd> + + <dt>Sequenzesn verketten/dt> + <dd>Erzeugt eine Nachrichtensequenz durch die Verkettung eingehender Sequenzen. Jede Nachricht muss eine <code>msg.topic</code> + und eine <code>msg.parts</code> Eigenschaft haben, um die Sequenz identifizieren zu können. + Der Node ist mit einer Liste von <code>topic</code> konfiguriert, + mit der die Reihnmefolge der Verkettung der Sequenzen definiert wird. + </dd> + + </dl> + <h4>Speichern der Nachrichten</h4> + <p>Dieser Node puffert Nachrichten intern, um sequenzübergreifend arbeiten zu können. Die Laufzeiteinstellung + <code>nodeMessageBufferMaxLength</code> kann verwendet werden, um die Anzahl der Nachrichten zu begrenzen + die vom Node gepuffert werden.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/storage/10-file.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/storage/10-file.html new file mode 100644 index 0000000..964b41c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/storage/10-file.html @@ -0,0 +1,72 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="file"> + <p>Schreibt <code>msg.payload</code> in eine Datei, wobei entweder der vorhandene Inhalt hinzugefügt oder ersetzt wird. + Alternativ kann die Datei auch gelöscht werden.</p> + <h3>Eingaben</h3> + <dl class="message-properties"> + <dt class="optional">filename <span class="property-type">String</span></dt> + <dd>Wenn nicht im Node konfiguriert, legt diese optionale Eigenschaft den Namen der zu aktualisierenden Datei fest.</dd> + </dl> + <h3>Ausgaben</h3> + <p>Nach Abschluss des Schreibvorgangs wird die Eingangsnachricht an den Ausgangsport gesendet.</p> + <h3>Details</h3> + <p>Jeder Nachrichten-Payload wird am Ende der Datei hinzugefügt und optional dazwischen ein Zeilenumbruchzeichen.</p> + <p>Wenn <code>msg.filename</code> verwendet wird, wird die Datei nach jedem Schreiben geschlossen. + Für eine optimale Leistung verwenden Sie einen festen Dateinamen.</p> + <p>Es kann konfiguriert werden, dass die gesamte Datei überschrieben wird und nicht angehängt wird. Zum Beispiel + beim Schreiben von Binärdaten in eine Datei wie bei einem Bild, sollte diese Option verwendet werden + und die Option, einen Zeilenumbruch anzuhängen, sollte deaktiviert sein.</p> + <p>Alternativ kann dieser Node konfiguriert werden, um die Datei zu löschen.</p> +</script> + +<script type="text/x-red" data-help-name="file in"> + <p>Reads the contents of a file as either a string or binary buffer.</p> + <h3>Inputs</h3> + <dl class="message-properties"> + <dt class="optional">filename <span class="property-type">string</span></dt> + <dd>if not set in the node configuration, this property sets the filename to read.</dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">string | buffer</span></dt> + <dd>The contents of the file as either a string or binary buffer.</dd> + <dt class="optional">filename <span class="property-type">string</span></dt> + <dd>If not configured in the node, this optional property sets the name of the file to be read.</dd> + <dt class="optional">error <span class="property-type">object</span></dt> + <dd><i>deprecated</i>: If enabled in the node, when the node hits an error + reading the file, it will send a message with no <code>payload</code> + and this <code>error</code> property set to the error details. This + mode of behaviour is deprecated and not enabled by default for new + instances of the node. See below for more information.</dd> + </dl> + <h3>Details</h3> + <p>The filename should be an absolute path, otherwise it will be relative to + the working directory of the Node-RED process.</p> + <p>On Windows, path separators may need to be escaped, for example: <code>\\Users\\myUser</code>.</p> + <p>Optionally, a text file can be split into lines, outputting one message per line, or a binary file + split into smaller buffer chunks - the chunk size being operating system dependant, but typically 64k (Linux/Mac) or 41k (Windows).</p> + <p>When split into multiple messages, each message will have a <code>parts</code> + property set, forming a complete message sequence.</p> + <h4>Legacy error handling</h4> + <p>Before Node-RED 0.17, if this node hit an error whilst reading the file, it would + send a message with no <code>msg.payload</code> and <code>msg.error</code> set to the + details of the error. This is a deprecated mode of behaviour for the node that new + instances will not do. If required, this mode can be re-enabled within the node + configuration.</p> + <p>Errors should be caught and handled using a Catch node.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/de/storage/23-watch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/storage/23-watch.html new file mode 100644 index 0000000..5f52756 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/de/storage/23-watch.html @@ -0,0 +1,29 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="watch"> + <p>Überwacht ein Verzeichnis oder eine Datei auf Änderungen.</p> + <p>Es kann eine kommagetrennte Liste von Verzeichnissen und/oder Dateien eingeben werden. + Es müssen Anführungszeichen "...." um alle Einträge gesetzt werden, die Leerzeichen enthalten.</p> + <p>Unter Windows muss in allen Verzeichnisnamen doppelte Backslashes \\\ verwendet werden.</p> + <p>Der vollständige Dateiname der tatsächlich geänderten Datei wird in <code>msg.payload</code> und <code>msg.filename</code> eingetragen, + während eine stringifizierte Version der Überwachungsliste in <code>msg.topic</code> zurückgegeben wird.</p> + <p><code>msg.file</code> enthält nur den kurzen Dateinamen der geänderten Datei. <code>msg.type</code> hat den Typ des geänderten Elements, + normalerweise <i>file</i> oder <i>directory</i>, während <code>msg.size</code> die Dateigröße in Bytes enthält.</p> + <p>Natürlich ist unter Linux <i>alles</i> eine Datei und kann somit beobachtet werden...</p> + <p><b>Note: </b>Das Verzeichnis oder die Datei muss vorhanden sein, um beobachtet zu werden. Wenn die Datei + oder das Verzeichnis gelöscht wird, kann es nicht mehr überwacht werden, auch wenn es wieder neu erstellt wird.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/20-inject.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/20-inject.html new file mode 100644 index 0000000..6e37fd4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/20-inject.html @@ -0,0 +1,40 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="inject"> +<p>Injects a message into a flow either manually or at regular intervals. The message +payload can be a variety of types, including strings, JavaScript objects or the current time.</p> +<h3>Outputs</h3> +<dl class="message-properties"> + <dt>payload<span class="property-type">various</span></dt> + <dd>The configured payload of the message.</dd> + <dt class="optional">topic <span class="property-type">string</span></dt> + <dd>An optional property that can be configured in the node.</dd> +</dl> +<h3>Details</h3> +<p>The Inject node can initiate a flow with a specific payload value. +The default payload is a timestamp of the current time in millisecs since January 1st, 1970.</p> +<p>The node also supports injecting strings, numbers, booleans, JavaScript objects, or flow/global context values.</p> +<p>By default, the node is triggered manually by clicking on its button within the editor. It can also be set to +inject at regular intervals or according to a schedule.</p> +<p>It can also be configured to inject once each time the flows are started.</p> +<p>The maximum <i>Interval</i> that can be specified is about 596 hours / 24 days. However if you are looking at intervals +greater than one day you should consider using a scheduler node that can cope with power outages and restarts.</p> +<p><b>Note</b>: The <i>"Interval between times"</i> and <i>"at a specific time"</i> options use the standard cron system. +This means that 20 minutes will be at the next hour, 20 minutes past and 40 minutes past - not in 20 minutes time. +If you want every 20 minutes from now - use the <i>"interval"</i> option.</p> +<p><b>Note</b>: To include a newline in a string you must use a Function node to create the payload.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/21-debug.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/21-debug.html new file mode 100644 index 0000000..fe9017f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/21-debug.html @@ -0,0 +1,26 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="debug"> + <p>Displays selected message properties in the debug sidebar tab and optionally the runtime log. By default it displays <code>msg.payload</code>, but can be configured to display any property, the full message or the result of a JSONata expression.</p> + <h3>Details</h3> + <p>The debug sidebar provides a structured view of the messages it is sent, making it easier to understand their structure.</p> + <p>JavaScript objects and arrays can be collapsed and expanded as required. Buffer objects can be displayed as raw data or as a string if possible.</p> + <p>Alongside each message, the debug sidebar includes information about the time the message was received, the node that sent it and the type of the message. + Clicking on the source node id will reveal that node within the workspace.</p> + <p>The button on the node can be used to enable or disable its output. It is recommended to disable or remove any Debug nodes that are not being used.</p> + <p>The node can also be configured to send all messages to the runtime log, or to send short (32 characters) to the status text under the debug node.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/24-complete.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/24-complete.html new file mode 100644 index 0000000..d73f8e1 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/24-complete.html @@ -0,0 +1,29 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="complete"> + <p>Trigger a flow when another node completes its handling of a message.</p> + <h3>Details</h3> + <p>If a node tells the runtime when it has finished handling a message, + this node can be used to trigger a second flow.</p> + <p>For example, this can be used alongside a node with no output port, + such as the Email sending node, to continue the flow.</p> + <p>This node must be configured to handle the event for selected nodes in the + flow. Unlike the Catch node, it does not provide a 'handle all' mode automatically + applies to all nodes in the flow.</p> + <p>Not all nodes will trigger this event - it will depend on whether they + have been implemented to support this feature as introduced in Node-RED 1.0.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/25-catch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/25-catch.html new file mode 100644 index 0000000..49897fe --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/25-catch.html @@ -0,0 +1,42 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="catch"> + <p>Catch errors thrown by nodes on the same tab.</p> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>error.message <span class="property-type">string</span></dt> + <dd>the error message.</dd> + <dt>error.source.id <span class="property-type">string</span></dt> + <dd>the id of the node that threw the error.</dd> + <dt>error.source.type <span class="property-type">string</span></dt> + <dd>the type of the node that threw the error.</dd> + <dt>error.source.name <span class="property-type">string</span></dt> + <dd>the name, if set, of the node that threw the error.</dd> + </dl> + <h3>Details</h3> + <p>If a node throws an error whilst handling a message, the flow will typically + halt. This node can be used to catch those errors and handle them with a + dedicated flow.</p> + <p>By default, the node will catch errors thrown by any node on the same tab. Alternatively + it can be targetted at specific nodes, or configured to only catch errors that + have not already been caught by a 'targeted' catch node.</p> + <p>When an error is thrown, all matching catch nodes will receive the message.</p> + <p>If an error is thrown within a subflow, the error will get handled by any + catch nodes within the subflow. If none exists, the error will be propagated + up to the tab the subflow instance is on.</p> + <p>If the message already has a <code>error</code> property, it is copied to <code>_error</code>.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/25-status.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/25-status.html new file mode 100644 index 0000000..9651441 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/25-status.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="status"> + <p>Report status messages from other nodes on the same tab.</p> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>status.text <span class="property-type">string</span></dt> + <dd>the status text.</dd> + <dt>status.source.type <span class="property-type">string</span></dt> + <dd>the type of the node that reported status.</dd> + <dt>status.source.id <span class="property-type">string</span></dt> + <dd>the id of the node that reported status.</dd> + <dt>status.source.name <span class="property-type">string</span></dt> + <dd>the name, if set, of the node that reported status.</dd> + </dl> + <h3>Details</h3> + <p>This node does not produce a <code>payload</code>.</p> + <p>By default the node reports status for all nodes on the same workspace tab. + It can be configured to selectively report status for individual nodes.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/60-link.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/60-link.html new file mode 100644 index 0000000..b0545a3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/60-link.html @@ -0,0 +1,37 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="link in"> + <p>Create virtual wires between flows.</p> + <h3>Details</h3> + <p>The node can be connected to any <code>link out</code> node that exists on any tab. + Once connected, they behave as if they were wired together.</p> + <p>The wires between link nodes are only displayed when a link node is selected. + If there are any wires to other tabs, a virtual node is shown that can be clicked + on to jump to the appropriate tab.</p> + <p><b>Note: </b>Links cannot be created going into, or out of, a subflow.</p> +</script> + +<script type="text/x-red" data-help-name="link out"> + <p>Create virtual wires between flows.</p> + <h3>Details</h3> + <p>The node can be connected to any <code>link in</code> node that exists on any tab. + Once connected, they behave as if they were wired together.</p> + <p>The wires between link nodes are only displayed when a link node is selected. + If there are any wires to other tabs, a virtual node is show that can be clicked + on to jump to the appropriate tab.</p> + <p><b>Note: </b>Links cannot be created going into, or out of, a subflow.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/90-comment.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/90-comment.html new file mode 100644 index 0000000..1667930 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/90-comment.html @@ -0,0 +1,22 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="comment"> + <p>A node you can use to add comments to your flows.</p> + <h3>Details</h3> + <p>The edit panel will accept Markdown syntax. The text will be rendered into + this information side panel.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/98-unknown.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/98-unknown.html new file mode 100644 index 0000000..0e8f405 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/common/98-unknown.html @@ -0,0 +1,28 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="unknown"> + <p>This node is a type unknown to your installation of Node-RED.</p> + <h3>Details</h3> + <p><i>If you deploy with the node in this state, its configuration will be preserved, but + the flow will not start until the missing type is installed.</i></p> + <p>Use the <code>Menu - Manage Palette</code> option + to search for and install nodes, or <b>npm install &lt;module&gt;</b> to + install, any missing modules and restart Node-RED and reimport the nodes.</p> + <p>It is possible this node type is already installed, but is missing a dependency. Check the Node-RED start-up + log for any error messages associated with the missing node type.</p> + <p>Otherwise, you should contact the author of the flow to obtain a copy of the missing node type.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html new file mode 100644 index 0000000..7bc99cc --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html @@ -0,0 +1,58 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="function"> + <p>A JavaScript function block to run against the messages being received by the node.</p> + <p>The messages are passed in as a JavaScript object called <code>msg</code>.</p> + <p>By convention it will have a <code>msg.payload</code> property containing + the body of the message.</p> + <p>The function is expected to return a message object (or multiple message objects), but can choose + to return nothing in order to halt a flow.</p> + <h3>Details</h3> + <p>See the <a target="_blank" href="http://nodered.org/docs/writing-functions.html">online documentation</a> + for more information on writing functions.</p> + <h4>Sending messages</h4> + <p>The function can either return the messages it wants to pass on to the next nodes + in the flow, or can call <code>node.send(messages)</code>.</p> + <p>It can return/send:</p> + <ul> + <li>a single message object - passed to nodes connected to the first output</li> + <li>an array of message objects - passed to nodes connected to the corresponding outputs</li> + </ul> + <p>If any element of the array is itself an array of messages, multiple + messages are sent to the corresponding output.</p> + <p>If null is returned, either by itself or as an element of the array, no + message is passed on.</p> + <h4>Logging and Error Handling</h4> + <p>To log any information, or report an error, the following functions are available:</p> + <ul> + <li><code>node.log("Log message")</code></li> + <li><code>node.warn("Warning")</code></li> + <li><code>node.error("Error")</code></li> + </ul> + </p> + <p>The Catch node can also be used to handle errors. To invoke a Catch node, + pass <code>msg</code> as a second argument to <code>node.error</code>:</p> + <pre>node.error("Error",msg);</pre> + <h4>Accessing Node Information</h4> + <p>In the function block, id and name of the node can be referenced using the following properties:</p> + <ul> + <li><code>node.id</code> - id of the node</li> + <li><code>node.name</code> - name of the node</li> + </ul> + <h4>Using environment variables</h4> + <p>Environment variables can be accessed using <code>env.get("MY_ENV_VAR")</code>.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/10-switch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/10-switch.html new file mode 100644 index 0000000..fb9af2a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/10-switch.html @@ -0,0 +1,51 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="switch"> + <p>Route messages based on their property values or sequence position.</p> + <h3>Details</h3> + <p>When a message arrives, the node will evaluate each of the defined rules + and forward the message to the corresponding outputs of any matching rules.</p> + <p>Optionally, the node can be set to stop evaluating rules once it finds one + that matches.</p> + <p>The rules can be evaluated against an individual message property, a flow or global + context property, environment variable or the result of a JSONata expression.</p> + <h4>Rules</h4> + <p>There are four types of rule:</p> + <ol> + <li><b>Value</b> rules are evaluated against the configured property</li> + <li><b>Sequence</b> rules can be used on message sequences, such as those + generated by the Split node</li> + <li>A JSONata <b>Expression</b> can be provided that will be evaluated + against the whole message and will match if the expression returns + a true value.</li> + <li>An <b>Otherwise</b> rule can be used to match if none of the preceeding + rules have matched.</li> + </ol> + <h4>Notes</h4> + <p>The <code>is true/false</code> and <code>is null</code> rules perform strict + comparisons against those types. They do not convert between types.</p> + <p>The <code>is empty</code> rule passes for Strings, Arrays and Buffers that have + a length of 0, or Objects that have no properties. It does not pass for <code>null</code> + or <code>undefined</code> values.</p> + <h4>Handling message sequences</h4> + <p>By default, the node does not modify the <code>msg.parts</code> property of messages + that are part of a sequence.</p> + <p>The <b>recreate message sequences</b> option can be enabled to generate new message sequences + for each rule that matches. In this mode, the node will buffer the entire incoming + sequence before sending the new sequences on. The runtime setting <code>nodeMessageBufferMaxLength</code> + can be used to limit how many messages nodes will buffer.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/15-change.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/15-change.html new file mode 100644 index 0000000..cb84708 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/15-change.html @@ -0,0 +1,39 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="change"> + <p>Set, change, delete or move properties of a message, flow context or global context.</p> + <p>The node can specify multiple rules that will be applied in the order they are defined.</p> + <h3>Details</h3> + <p>The available operations are:</p> + <dl class="message-properties"> + <dt>Set</dt> + <dd>set a property. The value can be a variety of different types, or + can be taken from an existing message or context property.</dd> + <dt>Change</dt> + <dd>search &amp; replace parts of the property. If regular expressions + are enabled, the "replace with" property can include capture groups, for + example <code>$1</code>. Replace will only change the type if there + is a complete match.</dd> + <dt>Delete</dt> + <dd>delete a property.</dd> + <dt>Move</dt> + <dd>move or rename a property.</dd> + </dl> + <p>The "expression" type uses the <a href="http://jsonata.org/" target="_new">JSONata</a> + query and expression language. + </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/16-range.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/16-range.html new file mode 100644 index 0000000..16ea0d7 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/16-range.html @@ -0,0 +1,44 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="range"> + <p>Maps a numeric value to a different range.</p> + <h3>Inputs</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">number</span></dt> + <dd>The payload <i>must</i> be a number. Anything else will try to be + parsed into a number and rejected if that fails.</dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">number</span></dt> + <dd>The value mapped to the new range.</dd> + </dl> + <h3>Details</h3> + <p>This node will linearly scale the received value. By default, the result + is not constrained to the range defined in the node.</p> + <p><i>Scale and limit to target range</i> means that the result will never be outside + the range specified within the target range.</p> + <p><i>Scale and wrap within the target range</i> means that the result will + be wrapped within the target range.</p> + <p>For example an input 0 - 10 mapped to 0 - 100.</p> + <table style="outline-width:#888 solid thin"> + <tr><th width="80px">mode</th><th width="80px">input</th><th width="80px">output</th></tr> + <tr><td><center>scale</center></td><td><center>12</center></td><td><center>120</center></td></tr> + <tr><td><center>limit</center></td><td><center>12</center></td><td><center>100</center></td></tr> + <tr><td><center>wrap</center></td><td><center>12</center></td><td><center>20</center></td></tr> + </table> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/80-template.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/80-template.html new file mode 100644 index 0000000..1e541c6 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/80-template.html @@ -0,0 +1,51 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="template"> + <p>Sets a property based on the provided template.</p> + <h3>Inputs</h3> + <dl class="message-properties"> + <dt>msg <span class="property-type">object</span></dt> + <dd>A msg object containing information to populate the template.</dd> + <dt class="optional">template <span class="property-type">string</span></dt> + <dd>A template to be populated from msg.payload. If not configured in the edit panel, + this can be set as a property of msg.</dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>msg <span class="property-type">object</span></dt> + <dd>a msg with a property set by populating the configured template with properties from the incoming msg.</dd> + </dl> + <h3>Details</h3> + <p>By default this uses the <i><a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache</a></i> + format, but this can be switched off if required.</p> + <p>For example, when a template of: + <pre>Hello {{payload.name}}. Today is {{date}}</pre> + <p>receives a message containing: + <pre>{ + date: "Monday", + payload: { + name: "Fred" + } +}</pre> + <p>The resulting property will be: + <pre>Hello Fred. Today is Monday</pre> + <p>It is possible to use a property from the flow context or global context. Just use <code>{{flow.name}}</code> or + <code>{{global.name}}</code>, or for persistable store <code>store</code> use <code>{{flow[store].name}}</code> or + <code>{{global[store].name}}</code>. + <p><b>Note: </b>By default, <i>mustache</i> will escape any non-alphanumeric or HTML entities in the values it substitutes. + To prevent this, use <code>{{{triple}}}</code> braces. +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/89-delay.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/89-delay.html new file mode 100644 index 0000000..d6977a3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/89-delay.html @@ -0,0 +1,45 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="delay"> + <p>Delays each message passing through the node or limits the rate at which they can pass.</p> + <h3>Inputs</h3> + <dl class="message-properties"> + <dt class="optional">delay <span class="property-type">number</span></dt> + <dd>Sets the delay, in milliseconds, to be applied to the message. This + option only applies if the node is configured to allow the message to + override the configured default delay interval.</dd> + <dt class="optional">reset</dt> + <dd>If the received message has this property set to any value, all + outstanding messages held by the node are cleared without being sent.</dd> + <dt class="optional">flush</dt> + <dd>If the received message has this property set to any value, all + outstanding messages held by the node are sent immediately.</dd> + </dl> + <h3>Details</h3> + <p>When configured to delay messages, the delay interval can be a fixed value, + a random value within a range or dynamically set for each message.</p> + <p>When configured to rate limit messages, their delivery is spread across + the configured time period. The status shows the number of messages currently in the queue. + It can optionally discard intermediate messages as they arrive.</p> + </p> + <p>The rate limiting can be applied to all messages, or group them according to + their <code>msg.topic</code> value. When grouping, intermerdiate messages are + automatically dropped. At each time interval, the node can either release + the most recent message for all topics, or release the most recent message + for the next topic. + </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/89-trigger.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/89-trigger.html new file mode 100644 index 0000000..836cabc --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/89-trigger.html @@ -0,0 +1,45 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="trigger"> + <p>When triggered, can send a message, and then optionally a second message, unless extended or reset.</p> + + <h3>Inputs</h3> + <dl class="message-properties"> + <dt class="optional">reset</dt> + <dd>If a message is received with this property, any timeout or repeat + currently in progress will be cleared and no message triggered.</dd> + </dl> + + <h3>Details</h3> + <p>This node can be used to create a timeout within a flow. By default, when + it receives a message, it sends on a message with a <code>payload</code> of <code>1</code>. + It then waits 250ms before sending a second message with a <code>payload</code> of <code>0</code>. + This could be used, for example, to blink an LED attached to a Raspberry Pi GPIO pin.</p> + <p>The payloads of each message sent can be configured to a variety of values, including + the option to not send anything. For example, setting the initial message to <i>nothing</i> and + selecting the option to extend the timer with each received message, the node will + act as a watchdog timer; only sending a message if nothing is received within the + set interval.</p> + <p>If set to a <i>string</i> type, the node supports the mustache template syntax.</p> + <p>If the node receives a message with a <code>reset</code> property, or a <code>payload</code> + that matches that configured in the node, any timeout or repeat currently in + progress will be cleared and no message triggered.</p> + <p>The node can be configured to resend a message at a regular interval until it + is reset by a received message.</p> + <p>Optionally, the node can be configured to treat messages with <code>msg.topic</code> as if they + are separate streams.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/90-exec.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/90-exec.html new file mode 100644 index 0000000..69447bc --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/function/90-exec.html @@ -0,0 +1,83 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="exec"> + <p>Runs a system command and returns its output.</p> + <p>The node can be configured to either wait until the command completes, or to + send its output as the command generates it.</p> + <p>The command that is run can be configured in the node or provided by the received + message.</p> + + <h3>Inputs</h3> + <dl class="message-properties"> + <dt class="optional">payload <span class="property-type">string</span></dt> + <dd>if configured to do so, will be appended to the executed command.</dd> + <dt class="optional">kill <span class="property-type">string</span></dt> + <dd>the type of kill signal to send an existing exec node process.</dd> + <dt class="optional">pid <span class="property-type">number|string</span></dt> + <dd>the process ID of an existing exec node process to kill.</dd> + </dl> + + <h3>Outputs</h3> + <ol class="node-ports"> + <li>Standard output + <dl class="message-properties"> + <dt>payload <span class="property-type">string</span></dt> + <dd>the standard output of the command.</dd> + </dl> + <dl class="message-properties"> + <dt>rc <span class="property-type">object</span></dt> + <dd>exec mode only, a copy of the return code object (also available on port 3)</dd> + </dl> + </li> + <li>Standard error + <dl class="message-properties"> + <dt>payload <span class="property-type">string</span></dt> + <dd>the standard error of the command.</dd> + </dl> + <dl class="message-properties"> + <dt>rc <span class="property-type">object</span></dt> + <dd>exec mode only, a copy of the return code object (also available on port 3)</dd> + </dl> + </li> + <li>Return code + <dl class="message-properties"> + <dt>payload <span class="property-type">object</span></dt> + <dd>an object containing the return code, and possibly <code>message</code>, <code>signal</code> properties.</dd> + </dl> + </li> + </ol> + <h3>Details</h3> + <p>By default uses the <code>exec</code> system call which calls the command, waits for it to complete, and then + returns the output. For example a successful command should have a return code of <code>{ code: 0 }</code>.</p> + <p>Optionally can use <code>spawn</code> instead, which returns the output from stdout and stderr + as the command runs, usually one line at a time. On completion it then returns an object + on the 3rd port. For example, a successful command should return <code>{ code: 0 }</code>.</p> + <p>Errors may return extra information on the 3rd port <code>msg.payload</code>, such as a <code>message</code> string, + <code>signal</code> string.</p> + <p>The command that is run is defined within the node, with an option to append <code>msg.payload</code> and a further set of parameters.</p> + <p>Commands or parameters with spaces should be enclosed in quotes - <code>"This is a single parameter"</code></p> + <p>The returned <code>payload</code> is usually a <i>string</i>, unless non-UTF8 characters are detected, in which + case it is a <i>buffer</i>.</p> + <p>The node&apos;s status icon and PID will be visible while the node is active. Changes to this can be read by the <code>Status</code> node.</p> + <h4>Killing processes</h4> + <p>Sending <code>msg.kill</code> will kill a single active process. <code>msg.kill</code> should be a string containing + the type of signal to be sent, for example, <code>SIGINT</code>, <code>SIGQUIT</code> or <code>SIGHUP</code>. + Defaults to <code>SIGTERM</code> if set to an empty string.</p> + <p>If the node has more than one process running then <code>msg.pid</code> must also be set with the value of the PID to be killed.</p> + <p>If a value is provided in the <code>Timeout</code> field then, if the process has not completed when the specified number of seconds has elapsed, the process will be killed automatically</p> + <p>Tip: if running a Python app you may need to use the <code>-u</code> parameter to stop the output being buffered.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/messages.json b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/messages.json new file mode 100644 index 0000000..24c8000 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/messages.json @@ -0,0 +1,942 @@ +{ + "common": { + "label": { + "payload": "Payload", + "topic": "Topic", + "name": "Name", + "username": "Username", + "password": "Password", + "property": "Property", + "selectNodes": "Select nodes...", + "expand": "Expand" + }, + "status": { + "connected": "connected", + "not-connected": "not connected", + "disconnected": "disconnected", + "connecting": "connecting", + "error": "error", + "ok": "OK" + }, + "notification": { + "error": "<strong>Error</strong>: __message__", + "errors": { + "not-deployed": "node not deployed", + "no-response": "no response from server", + "unexpected": "unexpected error (__status__) __message__" + } + }, + "errors": { + "nooverride": "Warning: msg properties can no longer override set node properties. See bit.ly/nr-override-msg-props" + } + }, + "inject": { + "inject": "inject", + "repeat": "repeat = __repeat__", + "crontab": "crontab = __crontab__", + "stopped": "stopped", + "failed": "Inject failed: __error__", + "label": { + "repeat": "Repeat", + "flow": "flow context", + "global": "global context", + "str": "string", + "num": "number", + "bool": "boolean", + "json": "object", + "bin": "buffer", + "date": "timestamp", + "env": "env variable", + "object": "object", + "string": "string", + "boolean": "boolean", + "number": "number", + "Array": "Array", + "invalid": "Invalid JSON Object" + }, + "timestamp": "timestamp", + "none": "none", + "interval": "interval", + "interval-time": "interval between times", + "time": "at a specific time", + "seconds": "seconds", + "minutes": "minutes", + "hours": "hours", + "between": "between", + "previous": "previous value", + "at": "at", + "and": "and", + "every": "every", + "days": [ + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + "Sunday" + ], + "on": "on", + "onstart": "Inject once after", + "onceDelay": "seconds, then", + "tip": "<b>Note:</b> \"interval between times\" and \"at a specific time\" will use cron.<br/>\"interval\" should be 596 hours or less.<br/>See info box for details.", + "success": "Successfully injected: __label__", + "errors": { + "failed": "inject failed, see log for details", + "toolong": "Interval too large" + } + }, + "catch": { + "catch": "catch: all", + "catchNodes": "catch: __number__", + "catchUncaught": "catch: uncaught", + "label": { + "source": "Catch errors from", + "selectAll": "select all", + "uncaught": "Ignore errors handled by other Catch nodes" + }, + "scope": { + "all": "all nodes", + "selected": "selected nodes" + } + }, + "status": { + "status": "status: all", + "statusNodes": "status: __number__", + "label": { + "source": "Report status from", + "sortByType": "sort by type" + }, + "scope": { + "all": "all nodes", + "selected": "selected nodes" + } + }, + "complete": { + "completeNodes": "complete: __number__" + }, + "debug": { + "output": "Output", + "none": "None", + "invalid-exp": "Invalid JSONata expression: __error__", + "msgprop": "message property", + "msgobj": "complete msg object", + "to": "To", + "debtab": "debug tab", + "tabcon": "debug tab and console", + "toSidebar": "debug window", + "toConsole": "system console", + "toStatus": "node status (32 characters)", + "severity": "Level", + "notification": { + "activated": "Successfully activated: __label__", + "deactivated": "Successfully deactivated: __label__" + }, + "sidebar": { + "label": "debug", + "name": "Debug messages", + "filterAll": "all nodes", + "filterSelected": "selected nodes", + "filterCurrent": "current flow", + "debugNodes": "Debug nodes", + "clearLog": "Clear log", + "filterLog": "Filter log", + "openWindow": "Open in new window", + "copyPath": "Copy path", + "copyPayload": "Copy value", + "pinPath": "Pin open" + }, + "messageMenu": { + "collapseAll": "Collapse all paths", + "clearPinned": "Clear pinned paths", + "filterNode": "Filter this node", + "clearFilter": "Clear filter" + } + }, + "link": { + "linkIn": "link in", + "linkOut": "link out" + }, + "tls": { + "tls": "TLS configuration", + "label": { + "use-local-files": "Use key and certificates from local files", + "upload": "Upload", + "cert": "Certificate", + "key": "Private Key", + "passphrase": "Passphrase", + "ca": "CA Certificate", + "verify-server-cert":"Verify server certificate", + "servername": "Server Name" + }, + "placeholder": { + "cert":"path to certificate (PEM format)", + "key":"path to private key (PEM format)", + "ca":"path to CA certificate (PEM format)", + "passphrase":"private key passphrase (optional)", + "servername":"for use with SNI" + }, + "error": { + "missing-file": "No certificate/key file provided" + } + }, + "exec": { + "exec": "exec", + "spawn": "spawn", + "label": { + "command": "Command", + "append": "Append", + "timeout": "Timeout", + "timeoutplace": "optional", + "return": "Output", + "seconds": "seconds", + "stdout": "stdout", + "stderr": "stderr", + "retcode": "return code" + }, + "placeholder": { + "extraparams": "extra input parameters" + }, + "opt": { + "exec": "when the command is complete - exec mode", + "spawn": "while the command is running - spawn mode" + }, + "oldrc": "Use old style output (compatibility mode)" + }, + "function": { + "function": "", + "label": { + "function": "Function", + "outputs": "Outputs" + }, + "error": { + "inputListener":"Cannot add listener to 'input' event within Function", + "non-message-returned":"Function tried to send a message of type __type__" + } + }, + "template": { + "template": "template", + "label": { + "template": "Template", + "property": "Property", + "format": "Syntax Highlight", + "syntax": "Format", + "output": "Output as", + "mustache": "Mustache template", + "plain": "Plain text", + "json": "Parsed JSON", + "yaml": "Parsed YAML", + "none": "none" + }, + "templatevalue": "This is the payload: {{payload}} !" + }, + "delay": { + "action": "Action", + "for": "For", + "delaymsg": "Delay each message", + "delayfixed": "Fixed delay", + "delayvarmsg": "Override delay with msg.delay", + "randomdelay": "Random delay", + "limitrate": "Rate Limit", + "limitall": "All messages", + "limittopic": "For each msg.topic", + "fairqueue": "Send each topic in turn", + "timedqueue": "Send all topics", + "milisecs": "Milliseconds", + "secs": "Seconds", + "sec": "Second", + "mins": "Minutes", + "min": "Minute", + "hours": "Hours", + "hour": "Hour", + "days": "Days", + "day": "Day", + "between": "Between", + "and": "&", + "rate": "Rate", + "msgper": "msg(s) per", + "dropmsg": "drop intermediate messages", + "label": { + "delay": "delay", + "variable": "variable", + "limit": "limit", + "limitTopic": "limit topic", + "random": "random", + "units" : { + "second": { + "plural" : "Seconds", + "singular": "Second" + }, + "minute": { + "plural" : "Minutes", + "singular": "Minute" + }, + "hour": { + "plural" : "Hours", + "singular": "Hour" + }, + "day": { + "plural" : "Days", + "singular": "Day" + } + } + }, + "error": { + "buffer": "buffer exceeded 1000 messages", + "buffer1": "buffer exceeded 10000 messages" + } + }, + "trigger": { + "send": "Send", + "then": "then", + "then-send": "then send", + "output": { + "string": "the string", + "number": "the number", + "existing": "the existing msg object", + "original": "the original msg object", + "latest": "the latest msg object", + "nothing": "nothing" + }, + "wait-reset": "wait to be reset", + "wait-for": "wait for", + "wait-loop": "resend it every", + "for": "Handling", + "bytopics": "each msg.topic independently", + "alltopics": "all messages", + "duration": { + "ms": "Milliseconds", + "s": "Seconds", + "m": "Minutes", + "h": "Hours" + }, + "extend": " extend delay if new message arrives", + "label": { + "trigger": "trigger", + "trigger-block": "trigger & block", + "trigger-loop": "resend every", + "reset": "Reset the trigger if:", + "resetMessage":"msg.reset is set", + "resetPayload":"msg.payload equals", + "resetprompt": "optional" + } + }, + "comment": { + "comment": "comment" + }, + "unknown": { + "label": { + "unknown": "unknown" + }, + "tip": "<p>This node is a type unknown to your installation of Node-RED.</p><p><i>If you deploy with the node in this state, it's configuration will be preserved, but the flow will not start until the missing type is installed.</i></p><p>See the Info side bar for more help</p>" + }, + "mqtt": { + "label": { + "broker": "Server", + "example": "e.g. localhost", + "output": "Output", + "qos": "QoS", + "retain": "Retain", + "clientid": "Client ID", + "port": "Port", + "keepalive": "Keep alive time (s)", + "cleansession": "Use clean session", + "use-tls": "Enable secure (SSL/TLS) connection", + "tls-config":"TLS Configuration", + "verify-server-cert":"Verify server certificate", + "compatmode": "Use legacy MQTT 3.1 support" + }, + "sections-label":{ + "birth-message": "Message sent on connection (birth message)", + "will-message":"Message sent on an unexpected disconnection (will message)", + "close-message":"Message sent before disconnecting (close message)" + }, + "tabs-label": { + "connection": "Connection", + "security": "Security", + "messages": "Messages" + }, + "placeholder": { + "clientid": "Leave blank for auto generated", + "clientid-nonclean":"Must be set for non-clean sessions", + "will-topic": "Leave blank to disable will message", + "birth-topic": "Leave blank to disable birth message", + "close-topic": "Leave blank to disable close message" + }, + "state": { + "connected": "Connected to broker: __broker__", + "disconnected": "Disconnected from broker: __broker__", + "connect-failed": "Connection failed to broker: __broker__" + }, + "retain": "Retain", + "output": { + "buffer": "a Buffer", + "string": "a String", + "base64": "a Base64 encoded string", + "auto": "auto-detect (string or buffer)", + "json": "a parsed JSON object" + }, + "true": "true", + "false": "false", + "tip": "Tip: Leave topic, qos or retain blank if you want to set them via msg properties.", + "errors": { + "not-defined": "topic not defined", + "missing-config": "missing broker configuration", + "invalid-topic": "Invalid topic specified", + "nonclean-missingclientid": "No client ID set, using clean session", + "invalid-json-string": "Invalid JSON string", + "invalid-json-parse": "Failed to parse JSON string" + } + }, + "httpin": { + "label": { + "method": "Method", + "url": "URL", + "doc": "Docs", + "return": "Return", + "upload": "Accept file uploads?", + "status": "Status code", + "headers": "Headers", + "other": "other", + "paytoqs" : "Append msg.payload as query string parameters", + "utf8String": "UTF8 string", + "binaryBuffer": "binary buffer", + "jsonObject": "parsed JSON object", + "authType": "Type", + "bearerToken": "Token" + }, + "setby": "- set by msg.method -", + "basicauth": "Use authentication", + "use-tls": "Enable secure (SSL/TLS) connection", + "tls-config":"TLS Configuration", + "basic": "basic authentication", + "digest": "digest authentication", + "bearer": "bearer authentication", + "use-proxy": "Use proxy", + "persist": "Enable connection keep-alive", + "proxy-config": "Proxy Configuration", + "use-proxyauth": "Use proxy authentication", + "noproxy-hosts": "Ignore hosts", + "utf8": "a UTF-8 string", + "binary": "a binary buffer", + "json": "a parsed JSON object", + "tip": { + "in": "The url will be relative to ", + "res": "The messages sent to this node <b>must</b> originate from an <i>http input</i> node", + "req": "Tip: If the JSON parse fails the fetched string is returned as-is." + }, + "httpreq": "http request", + "errors": { + "not-created": "Cannot create http-in node when httpNodeRoot set to false", + "missing-path": "missing path", + "no-response": "No response object", + "json-error": "JSON parse error", + "no-url": "No url specified", + "deprecated-call":"Deprecated call to __method__", + "invalid-transport":"non-http transport requested", + "timeout-isnan": "Timeout value is not a valid number, ignoring", + "timeout-isnegative": "Timeout value is negative, ignoring", + "invalid-payload": "Invalid payload" + }, + "status": { + "requesting": "requesting" + } + }, + "websocket": { + "label": { + "type": "Type", + "path": "Path", + "url": "URL" + }, + "listenon": "Listen on", + "connectto": "Connect to", + "sendrec": "Send/Receive", + "payload": "payload", + "message": "entire message", + "tip": { + "path1": "By default, <code>payload</code> will contain the data to be sent over, or received from a websocket. The listener can be configured to send or receive the entire message object as a JSON formatted string.", + "path2": "This path will be relative to ", + "url1": "URL should use ws:&#47;&#47; or wss:&#47;&#47; scheme and point to an existing websocket listener.", + "url2": "By default, <code>payload</code> will contain the data to be sent over, or received from a websocket. The client can be configured to send or receive the entire message object as a JSON formatted string." + }, + "status": { + "connected": "connected __count__", + "connected_plural": "connected __count__" + }, + "errors": { + "connect-error": "An error occurred on the ws connection: ", + "send-error": "An error occurred while sending: ", + "missing-conf": "Missing server configuration", + "duplicate-path": "Cannot have two WebSocket listeners on the same path: __path__" + } + }, + "watch": { + "watch": "watch", + "label": { + "files": "File(s)", + "recursive": "Watch sub-directories recursively" + }, + "placeholder": { + "files": "Comma-separated list of files and/or directories" + }, + "tip": "On Windows you must use double back-slashes \\\\ in any directory names." + }, + "tcpin": { + "label": { + "type": "Type", + "output": "Output", + "port": "port", + "host": "at host", + "payload": "payload(s)", + "delimited": "delimited by", + "close-connection": "Close connection after each message is sent?", + "decode-base64": "Decode Base64 message?", + "server": "Server", + "return": "Return", + "ms": "ms", + "chars": "chars" + }, + "type": { + "listen": "Listen on", + "connect": "Connect to", + "reply": "Reply to TCP" + }, + "output": { + "stream": "stream of", + "single": "single", + "buffer": "Buffer", + "string": "String", + "base64": "Base64 String" + }, + "return": { + "timeout": "after a fixed timeout of", + "character": "when character received is", + "number": "a fixed number of chars", + "never": "never - keep connection open", + "immed": "immediately - don't wait for reply" + }, + "status": { + "connecting": "connecting to __host__:__port__", + "connected": "connected to __host__:__port__", + "listening-port": "listening on port __port__", + "stopped-listening": "stopped listening on port", + "connection-from": "connection from __host__:__port__", + "connection-closed": "connection closed from __host__:__port__", + "connections": "__count__ connection", + "connections_plural": "__count__ connections" + + }, + "errors": { + "connection-lost": "connection lost to __host__:__port__", + "timeout": "timeout closed socket port __port__", + "cannot-listen": "unable to listen on port __port__, error: __error__", + "error": "error: __error__", + + "socket-error": "socket error from __host__:__port__", + "no-host": "Host and/or port not set", + "connect-timeout": "connect timeout", + "connect-fail": "connect failed" + } + }, + "udp": { + "label": { + "listen": "Listen for", + "onport": "on Port", + "using": "using", + "output": "Output", + "group": "Group", + "interface": "Local IF", + "send": "Send a", + "toport": "to port", + "address": "Address", + "decode-base64": "Decode Base64 encoded payload?" + }, + "placeholder": { + "interface": "(optional) local interface or address to bind to", + "interfaceprompt": "(optional) local interface or address to bind to", + "address": "destination ip" + }, + "udpmsgs": "udp messages", + "mcmsgs": "multicast messages", + "udpmsg": "udp message", + "bcmsg": "broadcast message", + "mcmsg": "multicast message", + "output": { + "buffer": "a Buffer", + "string": "a String", + "base64": "a Base64 encoded string" + }, + "bind": { + "random": "bind to random local port", + "local": "bind to local port", + "target": "bind to target port" + }, + "tip": { + "in": "Tip: Make sure your firewall will allow the data in.", + "out": "Tip: leave address and port blank if you want to set using <code>msg.ip</code> and <code>msg.port</code>.", + "port": "Ports already in use: " + }, + "status": { + "listener-at": "udp listener at __host__:__port__", + "mc-group": "udp multicast group __group__", + "listener-stopped": "udp listener stopped", + "output-stopped": "udp output stopped", + "mc-ready": "udp multicast ready: __iface__:__outport__ -> __host__:__port__", + "bc-ready": "udp broadcast ready: __outport__ -> __host__:__port__", + "ready": "udp ready: __outport__ -> __host__:__port__", + "ready-nolocal": "udp ready: __host__:__port__", + "re-use": "udp re-use socket: __outport__ -> __host__:__port__" + }, + "errors": { + "access-error": "UDP access error, you may need root access for ports below 1024", + "error": "error: __error__", + "bad-mcaddress": "Bad Multicast Address", + "interface": "Must be ip address of the required interface", + "ip-notset": "udp: ip address not set", + "port-notset": "udp: port not set", + "port-invalid": "udp: port number not valid", + "alreadyused": "udp: port __port__ already in use", + "ifnotfound": "udp: interface __iface__ not found" + } + }, + "switch": { + "switch": "switch", + "label": { + "property": "Property", + "rule": "rule", + "repair": "recreate message sequences" + }, + "previous": "previous value", + "and": "and", + "checkall": "checking all rules", + "stopfirst": "stopping after first match", + "ignorecase": "ignore case", + "rules": { + "btwn": "is between", + "cont": "contains", + "regex": "matches regex", + "true": "is true", + "false": "is false", + "null": "is null", + "nnull": "is not null", + "istype": "is of type", + "empty": "is empty", + "nempty": "is not empty", + "head": "head", + "tail": "tail", + "index": "index between", + "exp": "JSONata exp", + "else": "otherwise", + "hask": "has key" + }, + "errors": { + "invalid-expr": "Invalid JSONata expression: __error__", + "too-many": "too many pending messages in switch node" + } + }, + "change": { + "label": { + "rules": "Rules", + "rule": "rule", + "set": "set __property__", + "change": "change __property__", + "delete": "delete __property__", + "move": "move __property__", + "changeCount": "change: __count__ rules", + "regex": "Use regular expressions" + }, + "action": { + "set": "Set", + "change": "Change", + "delete": "Delete", + "move": "Move", + "to": "to", + "search": "Search for", + "replace": "Replace with" + }, + "errors": { + "invalid-from": "Invalid 'from' property: __error__", + "invalid-json": "Invalid 'to' JSON property", + "invalid-expr": "Invalid JSONata expression: __error__" + } + }, + "range": { + "range": "range", + "label": { + "action": "Action", + "inputrange": "Map the input range", + "resultrange": "to the target range", + "from": "from", + "to": "to", + "roundresult": "Round result to the nearest integer?" + }, + "placeholder": { + "min": "e.g. 0", + "maxin": "e.g. 99", + "maxout": "e.g. 255" + }, + "scale": { + "payload": "Scale the message property", + "limit": "Scale and limit to the target range", + "wrap": "Scale and wrap within the target range" + }, + "tip": "Tip: This node ONLY works with numbers.", + "errors": { + "notnumber": "Not a number" + } + }, + "csv": { + "label": { + "columns": "Columns", + "separator": "Separator", + "c2o": "CSV to Object options", + "o2c": "Object to CSV options", + "input": "Input", + "skip-s": "Skip first", + "skip-e": "lines", + "firstrow": "first row contains column names", + "output": "Output", + "includerow": "include column name row", + "newline": "Newline", + "usestrings": "parse numerical values" + }, + "placeholder": { + "columns": "comma-separated column names" + }, + "separator": { + "comma": "comma", + "tab": "tab", + "space": "space", + "semicolon": "semicolon", + "colon": "colon", + "hashtag": "hashtag", + "other": "other..." + }, + "output": { + "row": "a message per row", + "array": "a single message [array]" + }, + "newline": { + "linux": "Linux (\\n)", + "mac": "Mac (\\r)", + "windows": "Windows (\\r\\n)" + }, + "errors": { + "csv_js": "This node only handles CSV strings or js objects.", + "obj_csv": "No columns template specified for object -> CSV." + } + }, + "html": { + "label": { + "select": "Selector", + "output": "Output", + "in": "in" + }, + "output": { + "html": "the html content of the elements", + "text": "only the text content of the elements", + "attr": "an object of any attributes of the elements" + }, + "format": { + "single": "as a single message containing an array", + "multi": "as multiple messages, one for each element" + } + }, + "json": { + "errors": { + "dropped-object": "Ignored non-object payload", + "dropped": "Ignored unsupported payload type", + "dropped-error": "Failed to convert payload", + "schema-error": "JSON Schema error", + "schema-error-compile": "JSON Schema error: failed to compile schema" + }, + "label": { + "o2j": "Object to JSON options", + "pretty": "Format JSON string", + "action": "Action", + "property": "Property", + "actions": { + "toggle": "Convert between JSON String & Object", + "str":"Always convert to JSON String", + "obj":"Always convert to JavaScript Object" + } + } + }, + "yaml": { + "errors": { + "dropped-object": "Ignored non-object payload", + "dropped": "Ignored unsupported payload type", + "dropped-error": "Failed to convert payload" + } + }, + "xml": { + "label": { + "represent": "Property name for XML tag attributes", + "prefix": "Property name for tag text content", + "advanced": "Advanced options", + "x2o": "XML to Object options" + }, + "errors": { + "xml_js": "This node only handles xml strings or js objects." + } + }, + "file": { + "label": { + "filename": "Filename", + "action": "Action", + "addnewline": "Add newline (\\n) to each payload?", + "createdir": "Create directory if it doesn't exist?", + "outputas": "Output", + "breakchunks": "Break into chunks", + "breaklines": "Break into lines", + "filelabel": "file", + "sendError": "Send message on error (legacy mode)", + "encoding": "Encoding", + "deletelabel": "delete __file__", + "utf8String": "UTF8 string", + "binaryBuffer": "binary buffer" + }, + "action": { + "append": "append to file", + "overwrite": "overwrite file", + "delete": "delete file" + }, + "output": { + "utf8": "a single utf8 string", + "buffer": "a single Buffer object", + "lines": "a msg per line", + "stream": "a stream of Buffers" + }, + "status": { + "wrotefile": "wrote to file: __file__", + "deletedfile": "deleted file: __file__", + "appendedfile": "appended to file: __file__" + }, + "encoding": { + "none": "default", + "native": "Native", + "unicode": "Unicode", + "japanese": "Japanese", + "chinese": "Chinese", + "korean": "Korean", + "taiwan": "Taiwan/Hong Kong", + "windows": "Windows codepages", + "iso": "ISO codepages", + "ibm": "IBM codepages", + "mac": "Mac codepages", + "koi8": "KOI8 codepages", + "misc": "Miscellaneous" + }, + "errors": { + "nofilename": "No filename specified", + "invaliddelete": "Warning: Invalid delete. Please use specific delete option in config dialog.", + "deletefail": "failed to delete file: __error__", + "writefail": "failed to write to file: __error__", + "appendfail": "failed to append to file: __error__", + "createfail": "failed to create file: __error__" + }, + "tip": "Tip: The filename should be an absolute path, otherwise it will be relative to the working directory of the Node-RED process." + }, + "split": { + "split": "split", + "intro":"Split <code>msg.payload</code> based on type:", + "object":"<b>Object</b>", + "objectSend":"Send a message for each key/value pair", + "strBuff":"<b>String</b> / <b>Buffer</b>", + "array":"<b>Array</b>", + "splitUsing":"Split using", + "splitLength":"Fixed length of", + "stream":"Handle as a stream of messages", + "addname":" Copy key to " + }, + "join": { + "join": "join", + "mode": { + "mode": "Mode", + "auto": "automatic", + "merge": "merge sequences", + "reduce": "reduce sequence", + "custom": "manual" + }, + "combine": "Combine each", + "completeMessage": "complete message", + "create": "to create", + "type": { + "string": "a String", + "array": "an Array", + "buffer": "a Buffer", + "object": "a key/value Object", + "merged": "a merged Object" + }, + "using": "using the value of", + "key": "as the key", + "joinedUsing": "joined using", + "send": "Send the message:", + "afterCount": "After a number of message parts", + "count": "count", + "subsequent": "and every subsequent message.", + "afterTimeout": "After a timeout following the first message", + "seconds": "seconds", + "complete": "After a message with the <code>msg.complete</code> property set", + "tip": "This mode assumes this node is either paired with a <i>split</i> node or the received messages will have a properly configured <code>msg.parts</code> property.", + "too-many": "too many pending messages in join node", + "merge": { + "topics-label": "Merged Topics", + "topics": "topics", + "topic": "topic", + "on-change": "Send merged message on arrival of a new topic" + }, + "reduce": { + "exp": "Reduce exp", + "exp-value": "exp", + "init": "Initial value", + "right": "Evaluate in reverse order (last to first)", + "fixup": "Fix-up exp" + }, + "errors": { + "invalid-expr": "Invalid JSONata expression: __error__", + "invalid-type": "Cannot join __error__ to buffer" + } + }, + "sort" : { + "sort": "sort", + "target" : "Sort", + "seq" : "message sequence", + "key" : "Key", + "elem" : "element value", + "order" : "Order", + "ascending" : "ascending", + "descending" : "descending", + "as-number" : "as number", + "invalid-exp" : "Invalid JSONata expression in sort node: __message__", + "too-many" : "Too many pending messages in sort node", + "clear" : "clear pending message in sort node" + }, + "batch" : { + "batch": "batch", + "mode": { + "label" : "Mode", + "num-msgs" : "Group by number of messages", + "interval" : "Group by time interval", + "concat" : "Concatenate sequences" + }, + "count": { + "label" : "Number of messages", + "overlap" : "Overlap", + "count" : "count", + "invalid" : "Invalid count and overlap" + }, + "interval": { + "label" : "Interval", + "seconds" : "seconds", + "empty" : "send empty message when no message arrives" + }, + "concat": { + "topics-label": "Topics", + "topic" : "topic" + }, + "too-many" : "too many pending messages in batch node", + "unexpected" : "unexpected mode", + "no-parts" : "no parts property in message" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/05-tls.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/05-tls.html new file mode 100644 index 0000000..08c4bca --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/05-tls.html @@ -0,0 +1,19 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="tls-config"> + <p>Configuration options for TLS connections.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/06-httpproxy.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/06-httpproxy.html new file mode 100644 index 0000000..b17012e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/06-httpproxy.html @@ -0,0 +1,22 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http proxy"> + <p>Configuration options for HTTP proxy.</p> + + <h3>Details</h3> + <p>When accessing to the host in the ignored host list, no proxy will be used.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/10-mqtt.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/10-mqtt.html new file mode 100644 index 0000000..94c9c09 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/10-mqtt.html @@ -0,0 +1,84 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="mqtt in"> +<p>Connects to a MQTT broker and subscribes to messages from the specified topic.</p> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">string | buffer</span></dt> + <dd>a string unless detected as a binary buffer.</dd> + <dt>topic <span class="property-type">string</span></dt> + <dd>the MQTT topic, uses / as a hierarchy separator.</dd> + <dt>qos <span class="property-type">number</span> </dt> + <dd>0, fire and forget - 1, at least once - 2, once and once only.</dd> + <dt>retain <span class="property-type">boolean</span></dt> + <dd>true indicates the message was retained and may be old.</dd> + </dl> + <h3>Details</h3> + The subscription topic can include MQTT wildcards, + for one level, # for multiple levels.</p> + <p>This node requires a connection to a MQTT broker to be configured. This is configured by clicking + the pencil icon.</p> + <p>Several MQTT nodes (in or out) can share the same broker connection if required.</p> +</script> + +<script type="text/x-red" data-help-name="mqtt out"> + <p>Connects to a MQTT broker and publishes messages.</p> + <h3>Inputs</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">string | buffer</span></dt> + <dd> the payload to publish. If this property is not set, no message will be sent. To send a blank message, set this property to an empty String.</dd> + + <dt class="optional">topic <span class="property-type">string</span></dt> + <dd> the MQTT topic to publish to.</dd> + + <dt class="optional">qos <span class="property-type">number</span></dt> + <dd>0, fire and forget - 1, at least once - 2, once and once only. Default 0.</dd> + + <dt class="optional">retain <span class="property-type">boolean</span></dt> + <dd>set to true to retain the message on the broker. Default false.</dd> + </dl> + <h3>Details</h3> + <code>msg.payload</code> is used as the payload of the published message. + If it contains an Object it will be converted to a JSON string before being sent. + If it contains a binary Buffer the message will be published as-is.</p> + <p>The topic used can be configured in the node or, if left blank, can be set by <code>msg.topic</code>.</p> + <p>Likewise the QoS and retain values can be configured in the node or, if left + blank, set by <code>msg.qos</code> and <code>msg.retain</code> respectively. To clear a previously + retained topic from the broker, send a blank message to that topic with the retain flag set.</p> + <p>This node requires a connection to a MQTT broker to be configured. This is configured by clicking + the pencil icon.</p> + <p>Several MQTT nodes (in or out) can share the same broker connection if required.</p> +</script> + +<script type="text/x-red" data-help-name="mqtt-broker"> + <p>Configuration for a connection to an MQTT broker.</p> + <p>This configuration will create a single connection to the broker which can + then be reused by <code>MQTT In</code> and <code>MQTT Out</code> nodes.</p> + <p>The node will generate a random Client ID if one is not set and the + node is configured to use a Clean Session connection. If a Client ID is set, + it must be unique to the broker you are connecting to.</p> + <h4>Birth Message</h4> + <p>This is a message that will be published on the configured topic whenever the + connection is established.</p> + <h4>Close Message</h4> + <p>This is a message that will be published on the configured topic before the + connection is closed normally, either by re-deploying the node, or by shutting down.</p> + <h4>Will Message</h4> + <p>This is a message that will be published by the broker in the event the node + unexpectedly loses its connection.</p> + <h4>WebSockets</h4> + <p>The node can be configured to use a WebSocket connection. To do so, the Server + field should be configured with a full URI for the connection. For example:</p> + <pre>ws://example.com:4000/mqtt</pre> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/21-httpin.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/21-httpin.html new file mode 100644 index 0000000..3d91f83 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/21-httpin.html @@ -0,0 +1,100 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http in"> + <p>Creates an HTTP end-point for creating web services.</p> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>payload</dt> + <dd>For a GET request, contains an object of any query string parameters. + Otherwise, contains the body of the HTTP request.</dd> + <dt>req<span class="property-type">object</span></dt> + <dd>An HTTP request object. This object contains multiple properties that + provide information about the request. + <ul> + <li><code>body</code> - the body of the incoming request. The format + will depend on the request.</li> + <li><code>headers</code> - an object containing the HTTP request headers.</li> + <li><code>query</code> - an object containing any query string parameters.</li> + <li><code>params</code> - an object containing any route parameters.</li> + <li><code>cookies</code> - an object containing the cookies for the request.</li> + <li><code>files</code> - if enabled within the node, an object containing + any files uploaded as part of a POST request.</li> + </ul> + </dd> + <dt>res<span class="property-type">object</span></dt> + <dd>An HTTP response object. This property should not be used directly; + the <code>HTTP Response</code> node documents how to respond to a request. + This property must remain attached to the message passed to the response node.</dd> + </dl> + <h3>Details</h3> + <p>The node will listen on the configured path for requests of a particular type. + The path can be fully specified, such as <code>/user</code>, or include + named parameters that accept any value, such as <code>/user/:name</code>. + When named parameters are used, their actual value in a request can be accessed under <code>msg.req.params</code>.</p> + <p>For requests that include a body, such as a POST or PUT, the contents of + the request is made available as <code>msg.payload</code>.</p> + <p>If the content type of the request can be determined, the body will be parsed to + any appropriate type. For example, <code>application/json</code> will be parsed to + its JavaScript object representation.</p> + <p><b>Note:</b> this node does not send any response to the request. The flow + must include an HTTP Response node to complete the request.</p> +</script> + +<script type="text/x-red" data-help-name="http response"> + <p>Sends responses back to requests received from an HTTP Input node.</p> + + <h3>Inputs</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">string</span></dt> + <dd>The body of the response.</dd> + <dt class="optional">statusCode <span class="property-type">number</span></dt> + <dd>If set, this is used as the response status code. Default: 200.</dd> + <dt class="optional">headers <span class="property-type">object</span></dt> + <dd>If set, provides HTTP headers to include in the response.</dd> + <dt class="optional">cookies <span class="property-type">object</span></dt> + <dd>If set, can be used to set or delete cookies.</dd> + </dl> + <h3>Details</h3> + <p>The <code>statusCode</code> and <code>headers</code> can also be set within + the node itself. If a property is set within the node, it cannot be overridden + by the corresponding message property.</p> + <h4>Cookie handling</h4> + <p>The <code>cookies</code> property must be an object of name/value pairs. + The value can be either a string to set the value of the cookie with default + options, or it can be an object of options.<p> + <p>The following example sets two cookies - one called <code>name</code> with + a value of <code>nick</code>, the other called <code>session</code> with a + value of <code>1234</code> and an expiry set to 15 minutes.</p> + <pre> +msg.cookies = { + name: 'nick', + session: { + value: '1234', + maxAge: 900000 + } +}</pre> + <p>The valid options include:</p> + <ul> + <li><code>domain</code> - (String) domain name for the cookie</li> + <li><code>expires</code> - (Date) expiry date in GMT. If not specified or set to 0, creates a session cookie</li> + <li><code>maxAge</code> - (String) expiry date as relative to the current time in milliseconds</li> + <li><code>path</code> - (String) path for the cookie. Defaults to /</li> + <li><code>value</code> - (String) the value to use for the cookie</li> + </ul> + <p>To delete a cookie, set its <code>value</code> to <code>null</code>.</p> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/21-httprequest.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/21-httprequest.html new file mode 100644 index 0000000..3daf92f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/21-httprequest.html @@ -0,0 +1,96 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http request"> + <p>Sends HTTP requests and returns the response.</p> + + <h3>Inputs</h3> + <dl class="message-properties"> + <dt class="optional">url <span class="property-type">string</span></dt> + <dd>If not configured in the node, this optional property sets the url of the request.</dd> + <dt class="optional">method <span class="property-type">string</span></dt> + <dd>If not configured in the node, this optional property sets the HTTP method of the request. + Must be one of <code>GET</code>, <code>PUT</code>, <code>POST</code>, <code>PATCH</code> or <code>DELETE</code>.</dd> + <dt class="optional">headers <span class="property-type">object</span></dt> + <dd>Sets the HTTP headers of the request.</dd> + <dt class="optional">cookies <span class="property-type">object</span></dt> + <dd>If set, can be used to send cookies with the request.</dd> + <dt class="optional">payload</dt> + <dd>Sent as the body of the request.</dd> + <dt class="optional">rejectUnauthorized</dt> + <dd>If set to <code>false</code>, allows requests to be made to https sites that use + self signed certificates.</dd> + <dt class="optional">followRedirects</dt> + <dd>If set to <code>false</code> prevent following Redirect (HTTP 301).<code>true</code> by default</dd> + <dt class="optional">requestTimeout</dt> + <dd>If set to a positive number of milliseconds, will override the globally set <code>httpRequestTimeout</code> parameter.</dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">string | object | buffer</span></dt> + <dd>The body of the response. The node can be configured to return the body + as a string, attempt to parse it as a JSON string or leave it as a + binary buffer.</dd> + <dt>statusCode <span class="property-type">number</span></dt> + <dd>The status code of the response, or the error code if the request could not be completed.</dd> + <dt>headers <span class="property-type">object</span></dt> + <dd>An object containing the response headers.</dd> + <dt>responseUrl <span class="property-type">string</span></dt> + <dd>In case any redirects occurred while processing the request, this property is the final redirected url. + Otherwise, the url of the original request.</dd> + <dt>responseCookies <span class="property-type">object</span></dt> + <dd>If the response includes cookies, this propery is an object of name/value pairs for each cookie.</dd> + <dt>redirectList <span class="property-type">array</span></dt> + <dd>If the request was redirected one or more times, the accumulated information will be added to this property. `location` is the next redirect destination. `cookies` is the cookies returned from the redirect source.</dd> + </dl> + <h3>Details</h3> + <p>When configured within the node, the URL property can contain <a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache-style</a> tags. These allow the + url to be constructed using values of the incoming message. For example, if the url is set to + <code>example.com/{{{topic}}}</code>, it will have the value of <code>msg.topic</code> automatically inserted. + Using {{{...}}} prevents mustache from escaping characters like / & etc.</p> + <p>The node can optionally automatically encode <code>msg.payload</code> as query string parameters for a GET request, in which case <code>msg.payload</code> has to be an object.</p> + <p><b>Note</b>: If running behind a proxy, the standard <code>http_proxy=...</code> environment variable should be set and Node-RED restarted, or use Proxy Configuration. If Proxy Configuration was set, the configuration take precedence over environment variable.</p> + <h4>Using multiple HTTP Request nodes</h4> + <p>In order to use more than one of these nodes in the same flow, care must be taken with + the <code>msg.headers</code> property. The first node will set this property with + the response headers. The next node will then use those headers for its request - this + is not usually the right thing to do. If <code>msg.headers</code> property is left unchanged + between nodes, it will be ignored by the second node. To set custom headers, <code>msg.headers</code> + should first be deleted or reset to an empty object: <code>{}</code>. + <h4>Cookie handling</h4> + <p>The <code>cookies</code> property passed to the node must be an object of name/value pairs. + The value can be either a string to set the value of the cookie or it can be an + object with a single <code>value</code> property.<p> + <p>Any cookies returned by the request are passed back under the <code>responseCookies</code> property.</p> + <h4>Content type handling</h4> + <p>If <code>msg.payload</code> is an Object, the node will automatically set the content type + of the request to <code>application/json</code> and encode the body as such.</p> + <p>To encode the request as form data, <code>msg.headers["content-type"]</code> should be set to <code>application/x-www-form-urlencoded</code>.</p> + <h4>File Upload</h4> + <p>To perform a file upload, <code>msg.headers["content-type"]</code> should be set to <code>multipart/form-data</code> + and the <code>msg.payload</code> passed to the node must be an object with the following structure:</p> + <pre><code>{ + "KEY": { + "value": FILE_CONTENTS, + "options": { + "filename": "FILENAME" + } + } +}</code></pre> + <p>The values of <code>KEY</code>, <code>FILE_CONTENTS</code> and <code>FILENAME</code> + should be set to the appropriate values.</p> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/22-websocket.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/22-websocket.html new file mode 100644 index 0000000..8e814c6 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/22-websocket.html @@ -0,0 +1,43 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="websocket in"> + <p>WebSocket input node.</p> + <p>By default, the data received from the WebSocket will be in <code>msg.payload</code>. + The socket can be configured to expect a properly formed JSON string, in which + case it will parse the JSON and send on the resulting object as the entire message.</p> +</script> + +<script type="text/x-red" data-help-name="websocket out"> + <p>WebSocket out node.</p> + <p>By default, <code>msg.payload</code> will be sent over the WebSocket. The socket + can be configured to encode the entire <code>msg</code> object as a JSON string and send that + over the WebSocket.</p> + + <p>If the message arriving at this node started at a WebSocket In node, the message + will be sent back to the client that triggered the flow. Otherwise, the message + will be broadcast to all connected clients.</p> + <p>If you want to broadcast a message that started at a WebSocket In node, you + should delete the <code>msg._session</code> property within the flow.</p> +</script> + +<script type="text/x-red" data-help-name="websocket-listener"> + <p>This configuration node creates a WebSocket Server endpoint using the specified path.</p> +</script> + +<script type="text/x-red" data-help-name="websocket-client"> + <p>This configuration node connects a WebSocket client to the specified URL.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/31-tcpin.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/31-tcpin.html new file mode 100644 index 0000000..173f003 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/31-tcpin.html @@ -0,0 +1,45 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/html" data-help-name="tcp in"> + <p>Provides a choice of TCP inputs. Can either connect to a remote TCP port, + or accept incoming connections.</p> + <p><b>Note: </b>On some systems you may need root or administrator access + to access ports below 1024.</p> +</script> + +<script type="text/html" data-help-name="tcp out"> + <p>Provides a choice of TCP outputs. Can either connect to a remote TCP port, + accept incoming connections, or reply to messages received from a TCP In node.</p> + <p>Only the <code>msg.payload</code> is sent.</p> + <p>If <code>msg.payload</code> is a string containing a Base64 encoding of binary + data, the Base64 decoding option will cause it to be converted back to binary + before being sent.</p> + <p>If <code>msg._session</code> is not present the payload is + sent to <b>all</b> connected clients.</p> + <p><b>Note: </b>On some systems you may need root or administrator access + to access ports below 1024.</p> +</script> + +<script type="text/html" data-help-name="tcp request"> + <p>A simple TCP request node - sends the <code>msg.payload</code> to a server tcp port and expects a response.</p> + <p>Connects, sends the "request", and reads the "response". It can either count a number of + returned characters into a fixed buffer, match a specified character before returning, + wait a fixed timeout from first reply and then return, sit and wait for data, or send then close the connection + immediately, without waiting for a reply.</p> + <p>The response will be output in <code>msg.payload</code> as a buffer, so you may want to .toString() it.</p> + <p>If you leave tcp host or port blank they must be set by using the <code>msg.host</code> and <code>msg.port</code> properties in every message sent to the node.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/32-udp.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/32-udp.html new file mode 100644 index 0000000..09e6aef --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/network/32-udp.html @@ -0,0 +1,31 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="udp in"> + <p>A UDP input node, that produces a <code>msg.payload</code> containing a + Buffer, string, or base64 encoded string. Supports multicast.</p> + <p>It also provides <code>msg.ip</code> and <code>msg.port</code> set to the + ip address and port from which the message was received.</p> + <p><b>Note</b>: On some systems you may need root or administrator access to use + ports below 1024 and/or broadcast.</p> +</script> + +<script type="text/x-red" data-help-name="udp out"> + <p>This node sends <code>msg.payload</code> to the designated UDP host and port. Supports multicast.</p> + <p>You may also use <code>msg.ip</code> and <code>msg.port</code> to set the destination values, but the statically configured values have precedence.</p> + <p>If you select broadcast either set the address to the local broadcast ip address, or maybe try 255.255.255.255, which is the global broadcast address.</p> + <p><b>Note</b>: On some systems you may need to be root to use ports below 1024 and/or broadcast.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/parsers/70-CSV.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/parsers/70-CSV.html new file mode 100644 index 0000000..8bae66e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/parsers/70-CSV.html @@ -0,0 +1,45 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="csv"> + <p>Converts between a CSV formatted string and its JavaScript object representation, in either direction.</p> + <h3>Inputs</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | array | string</span></dt> + <dd>A JavaScript object, array or CSV string.</dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | array | string</span></dt> + <dd> + <ul> + <li>If the input is a string it tries to parse it as CSV and creates a JavaScript object of key/value pairs for each line. + The node will then either send a message for each line, or a single message containing an array of objects.</li> + <li>If the input is a JavaScript object it tries to build a CSV string.</li> + <li>If the input is an array of simple values, it builds a single line CSV string.</li> + <li>If the input is an array of arrays, or an array of objects, a multiple-line CSV string is created.</li> + </ul> + </dd> + </dl> + <h3>Details</h3> + <p>The column template can contain an ordered list of column names. When converting CSV to an object, the column names + will be used as the property names. Alternatively, the column names can be taken from the first row of the CSV.</p> + <p>When converting to CSV, the column template is used to identify which properties to extract from the object and in what order.</p> + <p>If the input is an array then the columns template is only used to optionally generate a row of column titles.</p> + <p>The node can accept a multi-part input as long as the <code>parts</code> property is set correctly.</p> + <p>If outputting multiple messages they will have their <code>parts</code> property set and form a complete message sequence.</p> + <p><b>Note:</b> the column template must be comma separated - even if a different separator is chosen for the data.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/parsers/70-HTML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/parsers/70-HTML.html new file mode 100644 index 0000000..b923166 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/parsers/70-HTML.html @@ -0,0 +1,36 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="html"> + <p>Extracts elements from an html document held in <code>msg.payload</code> using a CSS selector.</p> + <h3>Inputs</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">string</span></dt> + <dd>the html string from which to extract elements.</dd> + <dt class="optional">select <span class="property-type">string</span></dt> + <dd>if not configured in the edit panel the selector can be set as a property of msg.</dd> +</dl> + <h3>Output</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">array | string</span></dt> + <dd>the result can be either a single message with a payload containing an array of the matched elements, or multiple + messages that each contain a matched element. If multiple messages are sent they will also have <code>parts</code> set.</dd> + </dl> + <h3>Details</h3> + <p>This node supports a combination of CSS and jQuery selectors. See the + <a href="https://github.com/fb55/CSSselect#user-content-supported-selectors" target="_blank">css-select documentation</a> for more information + on the supported syntax.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/parsers/70-JSON.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/parsers/70-JSON.html new file mode 100644 index 0000000..972b4be --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/parsers/70-JSON.html @@ -0,0 +1,53 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="json"> + <p>Converts between a JSON string and its JavaScript object representation, in either direction.</p> + <h3>Inputs</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | string</span></dt> + <dd>A JavaScript object or JSON string.</dd> + <dt>schema<span class="property-type">object</span></dt> + <dd>An optional JSON Schema object to validate the payload against. + The property will be deleted before the <code>msg</code> is sent to the next node.</dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | string</span></dt> + <dd> + <ul> + <li>If the input is a JSON string it tries to parse it to a JavaScript object.</li> + <li>If the input is a JavaScript object it creates a JSON string. The string can optionally be well-formatted.</li> + </ul> + </dd> + <dt>schemaError<span class="property-type">array</span></dt> + <dd>If JSON schema validation fails, the catch node will have a <code>schemaError</code> property + containing an array of errors.</dd> + </dl> + <h3>Details</h3> + <p>By default, the node operates on <code>msg.payload</code>, but can be configured + to convert any message property.</p> + <p>The node can also be configured to ensure a particular encoding instead of toggling + between the two. This can be used, for example, with the <code>HTTP In</code> + node to ensure the payload is a parsed object even if an incoming request + did not set its content-type correctly for the HTTP In node to do the conversion.</p> + <p>If the node is configured to ensure the property is encoded as a String and it + receives a String, no further checks will be made of the property. It will + not check the String is valid JSON nor will it reformat it if the format option + is selected.</p> + <p>For more details about JSON Schema you can consult the specification + <a href="http://json-schema.org/latest/json-schema-validation.html">here</a>.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/parsers/70-XML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/parsers/70-XML.html new file mode 100644 index 0000000..089d4a0 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/parsers/70-XML.html @@ -0,0 +1,51 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="xml"> + <p>Converts between an XML string and its JavaScript object representation, in either direction.</p> + <h3>Inputs</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | string</span></dt> + <dd>A JavaScript object or XML string.</dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | string</span></dt> + <dd> + <ul> + <li>If the input is a string it tries to parse it as XML and creates a JavaScript object.</li> + <li>If the input is a JavaScript object it tries to build an XML string.</li> + </ul> + </dd> + <dt class="optional">options <span class="property-type">object</span></dt> + <dd>This optional property can be used to pass in any of the options supported by the underlying + library used to convert to and from XML. See <a href="https://github.com/Leonidas-from-XIV/node-xml2js/blob/master/README.md#options" target="_blank">the xml2js docs</a> + for more information.</dd> + </dl> + <h3>Details</h3> + <p>When converting between XML and an object, any XML attributes are added as a property named <code>$</code> by default. + Any text content is added as a property named <code>_</code>. These property names can be specified in the node configuration.</p> + <p>For example, the following XML will be converted as shown:</p> + <pre>&lt;p class="tag"&gt;Hello World&lt;/p&gt;</pre> + <pre>{ + "p": { + "$": { + "class": "tag" + }, + "_": "Hello World" + } +}</pre> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/parsers/70-YAML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/parsers/70-YAML.html new file mode 100644 index 0000000..1eada07 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/parsers/70-YAML.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="yaml"> + <p>Converts between a YAML formatted string and its JavaScript object representation, in either direction.</p> + <h3>Inputs</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | string</span></dt> + <dd>A JavaScript object or YAML string.</dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | string</span></dt> + <dd> + <ul> + <li>If the input is a YAML string it tries to parse it to a JavaScript object.</li> + <li>If the input is a JavaScript object it creates a YAML string.</li> + </ul> + </dd> + </dl> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/sequence/17-split.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/sequence/17-split.html new file mode 100644 index 0000000..c9c3e30 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/sequence/17-split.html @@ -0,0 +1,166 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/html" data-help-name="split"> + <p>Splits a message into a sequence of messages.</p> + + <h3>Inputs</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | string | array | buffer</span></dt> + <dd>The behaviour of the node is determined by the type of <code>msg.payload</code>: + <ul> + <li><b>string</b>/<b>buffer</b> - the message is split using the specified character (default: <code>\n</code>), buffer sequence or into fixed lengths.</li> + <li><b>array</b> - the message is split into either individual array elements, or arrays of a fixed-length.</li> + <li><b>object</b> - a message is sent for each key/value pair of the object.</li> + </ul> + </dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>parts<span class="property-type">object</span></dt> + <dd>This property contains information about how the message was split from + the original message. If passed to the <b>join</b> node, the sequence can be + reassembled into a single message. The property has the following properties: + <ul> + <li><code>id</code> - an identifier for the group of messages</li> + <li><code>index</code> - the position within the group</li> + <li><code>count</code> - if known, the total number of messages in the group. See 'streaming mode' below.</li> + <li><code>type</code> - the type of message - string/array/object/buffer</li> + <li><code>ch</code> - for a string or buffer, the data used to the split the message as either the string or an array of bytes</li> + <li><code>key</code> - for an object, the key of the property this message was created from. The node can be configured to also copy this value to another message properties, such as <code>msg.topic</code>.</li> + <li><code>len</code> - the length of each message when split using a fixed length value</li> + </ul> + </dd> + </dl> + <h3>Details</h3> + <p>This node makes it easy to create a flow that performs common actions across + a sequence of messages before, using the <b>join</b> node, recombining the + sequence into a single message.</p> + <p>It uses the <code>msg.parts</code> property to track the individual parts + of a sequence.</p> + <h4>Streaming mode</h4> + <p>The node can also be used to reflow a stream of messages. For example, a + serial device that sends newline-terminated commands may deliver a single message + with a partial command at its end. In 'streaming mode', this node will split + a message and send each complete segment. If there is a partial segment at the end, + the node will hold on to it and prepend it to the next message that is received. + </p> + <p>When operating in this mode, the node will not set the <code>msg.parts.count</code> + property as it does not know how many messages to expect in the stream. This + means it cannot be used with the <b>join</b> node in its automatic mode</p> +</script> + +<script type="text/html" data-help-name="join"> + <p>Joins sequences of messages into a single message.</p> + <p>There are three modes available:</p> + <dl> + <dt>automatic</dt> + <dd>When paired with the <b>split</b> node, it will automatically join the messages to reverse the split that was performed.</dd> + <dt>manual</dt> + <dd>Join sequences of messages in a variety of ways.</dd> + <dt>reduce sequence</dt> + <dd>Apply an expression against all messages in a sequence to reduce it to a single message.</dd> + </dl> + <h3>Inputs</h3> + <dl class="message-properties"> + <dt class="optional">parts<span class="property-type">object</span></dt> + <dd>To automatically join a sequence of messages, they should all have + this property set. The <b>split</b> node generates this property but it + can be manually created. It has the following properties: + <ul> + <li><code>id</code> - an identifier for the group of messages</li> + <li><code>index</code> - the position within the group</li> + <li><code>count</code> - the total number of messages in the group</li> + <li><code>type</code> - the type of message - string/array/object/buffer</li> + <li><code>ch</code> - for a string or buffer, the data used to the split the message as either the string or an array of bytes</li> + <li><code>key</code> - for an object, the key of the property this message was created from</li> + <li><code>len</code> - the length of each message when split using a fixed length value</li> + </ul> + </dd> + <dt class="optional">complete</dt> + <dd>If set, the node will append the payload, and then send the output message in its current state. + If you don't wish to append the payload, delete it from the msg.</dd> + </dl> + <h3>Details</h3> + + <h4>Automatic mode</h4> + <p>Automatic mode uses the <code>parts</code> property of incoming messages to + determine how the sequence should be joined. This allows it to automatically + reverse the action of a <b>split</b> node. + + <h4>Manual mode</h4> + <p>When configured to join in manual mode, the node is able to join sequences + of messages into a number of different results:</p> + <ul> + <li>a <b>string</b> or <b>buffer</b> - created by joining the selected property of each message with the specified join characters or buffer.</li> + <li>an <b>array</b> - created by adding each selected property, or entire message, to the output array.</li> + <li>a <b>key/value object</b> - created by using a property of each message to determine the key under which + the required value is stored.</li> + <li>a <b>merged object</b> - created by merging the property of each message under a single object.</li> + </ul> + <p>The other properties of the output message are taken from the last message received before the result is sent.</p> + <p>A <i>count</i> can be set for how many messages should be received before generating the output message. + For object outputs, once this count has been reached, the node can be configured to send a message for each subsequent message + received.</p> + <p>A <i>timeout</i> can be set to trigger sending the new message using whatever has been received so far.</p> + <p>If a message is received with the <b>msg.complete</b> property set, the output message is finalised and sent. + This resets any part counts.</p> + <p>If a message is received with the <b>msg.reset</b> property set, the partly complete message is deleted and not sent. + This resets any part counts.</p> + + <h4>Reduce Sequence mode</h4> + <p>When configured to join in reduce mode, an expression is applied to each + message in a sequence and the result accumulated to produce a single message.</p> + + <dl class="message-properties"> + <dt>Initial value</dt> + <dd>The initial value of the accumulated value (<code>$A</code>).</dd> + <dt>Reduce expression</dt> + <dd>A JSONata expression that is called for each message in the sequence. + The result is passed to the next call of the expression as the accumulated value. + In the expression, the following special variables can be used: + <ul> + <li><code>$A</code>: the accumulated value, </li> + <li><code>$I</code>: index of the message in the sequence, </li> + <li><code>$N</code>: number of messages in the sequence.</li> + </ul> + </dd> + <dt>Fix-up expression</dt> + <dd>An optional JSONata expression that is applied after the reduce expression + has been applied to all messages in the sequence. + In the expression, following special variables can be used: + <ul> + <li><code>$A</code>: the accumulated value, </li> + <li><code>$N</code>: number of messages in the sequence.</li> + </ul> + </dd> + <p>By default, the reduce expression is applied in order, from the first + to the last message of the sequence. It can optionally be applied in + reverse order.</p> + </dl> + <p><b>Example:</b> the following settings, given a sequence of numeric values, + calculates the average value: + <ul> + <li><b>Reduce expression</b>: <code>$A+payload</code></li> + <li><b>Initial value</b>: <code>0</code></li> + <li><b>Fix-up expression</b>: <code>$A/$N</code></li> + </ul> + </p> + <h4>Storing messages</h4> + <p>This node will buffer messages internally in order to work across sequences. The + runtime setting <code>nodeMessageBufferMaxLength</code> can be used to limit how many messages nodes + will buffer.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/sequence/18-sort.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/sequence/18-sort.html new file mode 100644 index 0000000..84484c2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/sequence/18-sort.html @@ -0,0 +1,41 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="sort"> + <p>A function that sorts message property or a sequence of messages.</p> + <p>When configured to sort message property, the node sorts array data pointed to by specified message property.</p> + <p>When configured to sort a sequence of messages, it will reorder the messages.</p> + <p>The sorting order can be:</p> + <ul> + <li><b>ascending</b>,</li> + <li><b>descending</b>.</li> + </ul> + <p>For numbers, numerical ordering can be specified by a checkbox.</p> + <p>Sort key can be element value or JSONata expression for sorting property value, or message property or JSONata expression for sorting a message sequence.<p> + <p>When sorting a message sequence, the sort node relies on the received messages to have <code>msg.parts</code> set. The split node generates this property, but can be manually created. It has the following properties:</p> + <p> + <ul> + <li><code>id</code> - an identifier for the group of messages</li> + <li><code>index</code> - the position within the group</li> + <li><code>count</code> - the total number of messages in the group</li> + </ul> + </p> + <p><b>Note:</b> This node internally keeps messages for its operation. In order to prevent unexpected memory usage, maximum number of messages kept can be specified. Default is no limit on number of messages. + <ul> + <li><code>nodeMessageBufferMaxLength</code> property set in <b>settings.js</b>.</li> + </ul> + </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/sequence/19-batch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/sequence/19-batch.html new file mode 100644 index 0000000..3a7d24f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/sequence/19-batch.html @@ -0,0 +1,42 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="batch"> + <p>Creates sequences of messages based on various rules.</p> + <h3>Details</h3> + <p>There are three modes for creating message sequences:</p> + <dl> + <dt>Number of messages</dt> + <dd>groups messages into sequences of a given length. The <b>overlap</b> + option specifies how many messages at the end of one sequence should be + repeated at the start of the next sequence.</dd> + + <dt>Time interval</dt> + <dd>groups messages that arrive within the specified interval. If no messages + arrive within the interval, the node can optionally send on an empty message.</dd> + + <dt>Concatenate Sequences</dt> + <dd>creates a message sequence by concatenating incoming sequences. Each message + must have a <code>msg.topic</code> property and a <code>msg.parts</code> property + identifying its sequence. The node is configured with a list of <code>topic</code> + values to identify the order sequences are concatenated. + </dd> + </dl> + <h4>Storing messages</h4> + <p>This node will buffer messages internally in order to work across sequences. The + runtime setting <code>nodeMessageBufferMaxLength</code> can be used to limit how many messages nodes + will buffer.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/storage/10-file.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/storage/10-file.html new file mode 100644 index 0000000..fe2bbc3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/storage/10-file.html @@ -0,0 +1,63 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/html" data-help-name="file"> + <p>Writes <code>msg.payload</code> to a file, either adding to the end or replacing the existing content. + Alternatively, it can delete the file.</p> + <h3>Inputs</h3> + <dl class="message-properties"> + <dt class="optional">filename <span class="property-type">string</span></dt> + <dd>If not configured in the node, this optional property sets the name of the file to be updated.</dd> + </dl> + <h3>Output</h3> + <p>On completion of write, input message is sent to output port.</p> + <h3>Details</h3> + <p>Each message payload will be added to the end of the file, optionally appending + a newline (\n) character between each one.</p> + <p>If <code>msg.filename</code> is used the file will be closed after every write. + For best performance use a fixed filename.</p> + <p>It can be configured to overwrite the entire file rather than append. For example, + when writing binary data to a file, such as an image, this option should be used + and the option to append a newline should be disabled.</p> + <p>Encoding of data written to a file can be specified from list of encodings.</p> + <p>Alternatively, this node can be configured to delete the file.</p> +</script> + +<script type="text/html" data-help-name="file in"> + <p>Reads the contents of a file as either a string or binary buffer.</p> + <h3>Inputs</h3> + <dl class="message-properties"> + <dt class="optional">filename <span class="property-type">string</span></dt> + <dd>if not set in the node configuration, this property sets the filename to read.</dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">string | buffer</span></dt> + <dd>The contents of the file as either a string or binary buffer.</dd> + <dt class="optional">filename <span class="property-type">string</span></dt> + <dd>If not configured in the node, this optional property sets the name of the file to be read.</dd> + </dl> + <h3>Details</h3> + <p>The filename should be an absolute path, otherwise it will be relative to + the working directory of the Node-RED process.</p> + <p>On Windows, path separators may need to be escaped, for example: <code>\\Users\\myUser</code>.</p> + <p>Optionally, a text file can be split into lines, outputting one message per line, or a binary file + split into smaller buffer chunks - the chunk size being operating system dependant, but typically 64k (Linux/Mac) or 41k (Windows).</p> + <p>When split into multiple messages, each message will have a <code>parts</code> + property set, forming a complete message sequence.</p> + <p>Encoding of input data can be specified from list of encodings if output format is string.</p> + <p>Errors should be caught and handled using a Catch node.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/storage/23-watch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/storage/23-watch.html new file mode 100644 index 0000000..4a28cfc --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/en-US/storage/23-watch.html @@ -0,0 +1,30 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="watch"> + <p>Watches a directory or file for changes.</p> + <p>You can enter a list of comma separated directories and/or files. You will + need to put quotes "..." around any that have spaces in.</p> + <p>On Windows you must use double back-slashes \\ in any directory names.</p> + <p>The full filename of the file that actually changed is put into <code>msg.payload</code> and <code>msg.filename</code>, + while a stringified version of the watch list is returned in <code>msg.topic</code>.</p> + <p><code>msg.file</code> contains just the short filename of the file that changed. + <code>msg.type</code> has the type of thing changed, usually <i>file</i> or <i>directory</i>, + while <code>msg.size</code> holds the file size in bytes.</p> + <p>Of course in Linux, <i>everything</i> is a file and thus can be watched...</p> + <p><b>Note: </b>The directory or file must exist in order to be watched. If the file + or directory gets deleted it may no longer be monitored even if it gets re-created.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/20-inject.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/20-inject.html new file mode 100644 index 0000000..4294711 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/20-inject.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="inject"> +<p>手動もしくは一定間隔でメッセージをフローに注入します。メッセージのペイロードには、文字列、JavaScriptオブジェクト、現在の時刻など、さまざまな値を指定できます。</p> +<h3>出力</h3> +<dl class="message-properties"> + <dt>payload<span class="property-type">各種</span></dt> + <dd>指定したメッセージペイロード。</dd> + <dt class="optional">topic <span class="property-type">文字列</span></dt> + <dd>任意で指定可能なプロパティ。</dd> +</dl> +<h3>詳細</h3> +<p>injectノードを用いることで、指定したペイロード値を用いてフローを開始できます。デフォルトのペイロード値は現在時刻のタイムスタンプを1970年1月1日からの経過ミリ秒で表現した値です。</p> +<p>文字列、数値、真偽値、JavaScriptオブジェクト、フロー/グローバルコンテキストの値などの送出も可能です。</p> +<p> デフォルト設定では、エディタ内に表示されるボタンをクリックすることで、ノードを手動で起動できます。指定間隔もしくはスケジュールに従ってメッセージを送出するように設定することも可能です。</p> +<p>また、フロー開始の際に一度だけメッセージを送出させることもできます。</p> +<p>「<i>時間間隔</i>」に指定可能な値の最大値は、約596時間(もしくは24日)です。一日より長い間隔を扱いたい場合は、電源停止や再起動にも対応可能なスケジューラノードの利用を検討すると良いでしょう。</p> +<p><b>注</b>:「<i>指定した時間間隔、日時</i>」と「<i>指定した日時</i>」オプションは標準的なcronシステムを内部で利用します。したがって「20分」という指定は、その時点から20分後ではなく、毎時きっかり、20分、40分を意味します。現時刻から20分毎を指定するには「<i>指定した時間間隔</i>」オプションを用います。</p> +<p><b>注</b>: 文字列に改行を含めたい場合は、functionノードを使ってペイロードを設定してください。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/21-debug.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/21-debug.html new file mode 100644 index 0000000..13c0976 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/21-debug.html @@ -0,0 +1,26 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="debug"> + <p>サイドバーの「デバッグ」タブに、選択したメッセージプロパティの値を表示します。設定により、ランタイムログへの出力も可能です。デフォルトの表示対象は<code>msg.payload</code>ですが、設定により、指定したプロパティ、メッセージ全体、もしくは、JSONata式の評価結果を出力できます。</p> + <h3>詳細</h3> + <p>「デバッグ」サイドバーは受け取ったメッセージの階層構造を表示する機能を備えます。この機能によりメッセージの構造を容易に理解できます。</p> + <p>JavaScriptオブジェクトと配列は必要に応じて折り畳んだり展開したりできます。バッファオブジェクトを生データとして表示したり、表現可能な場合に文字列として表示したりすることも可能です。</p> + <p>メッセージを受信した時刻、送信ノード、メッセージの型に関する情報を「デバッグ」サイドバーに表示されたメッセージに付随して表示します。送信元ノードのIDを選択すると、ワークスペース内の対応ノードを確認できます。</p> + <p>出力の有効/無効はノード上のボタンで切り替えられます。フロー上で未使用のdebugノードは、無効化するか削除することを推奨します。</p> + <p>全てのメッセージをランタイムログに送付、もしくは、(32文字の)短いデータをdebugノードの下のステータステキストに表示することも可能です。</p> +</script> + diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/24-complete.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/24-complete.html new file mode 100644 index 0000000..2cb3004 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/24-complete.html @@ -0,0 +1,24 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="complete"> + <p>他のノードにおけるメッセージ処理の完了を受けてフローを開始します。</p> + <h3>詳細</h3> + <p>ノードからランタイムに対してメッセージ処理の完了が通知されると、本ノードによって次のフローを開始できます。</p> + <p>本ノードは出力ポートを持たないノードと共に用いる場合などに有用です。例えば、Email送信ノードで送信後にフローを起動する場合がこれに当たります。</p> + <p>このノードはフロー内で選択したノードに対するイベントを処理するように設定します。Catchノードとは異なり、「全てのノード」モードを指定して、フロー中の全てのノードを対象とすることはできません。</p> + <p>全てのノードで本ノードのイベント処理を開始するわけではありません。Node-RED 1.0で導入した本機能を対象ノードがサポートしている必要があります。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/25-catch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/25-catch.html new file mode 100644 index 0000000..65777dd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/25-catch.html @@ -0,0 +1,36 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="catch"> + <p>同じタブ内のノードが送出したエラーをキャッチします。</p> + <h3>出力</h3> + <dl class="message-properties"> + <dt>error.message <span class="property-type">文字列</span></dt> + <dd>エラーメッセージ</dd> + <dt>error.source.id <span class="property-type">文字列</span></dt> + <dd>エラーを送出したノードのID</dd> + <dt>error.source.type <span class="property-type">文字列</span></dt> + <dd>エラーを送出したノードの種別</dd> + <dt>error.source.name <span class="property-type">文字列</span></dt> + <dd>エラーを送出したノードの名称(設定されている場合)</dd> + </dl> + <h3>詳細</h3> + <p>メッセージの処理中にノードがエラーを送出した場合、フロー実行は基本的に停止します。このノードを使うと、エラーをキャッチして対応するフローで処理させることができます。</p> + <p>デフォルトでは、同じタブの全てのノードが送出したエラーをキャッチします。特定のノードをキャッチ対象とするか、対象catchノードで補足されていないエラーのみ補足するように指定することも可能です。</p> + <p>エラー発生時には、マッチするすべてのcatchノードがメッセージを受け取ります。</p> + <p>サブフロー内でエラーが送出された場合、まずサブフロー内のcatchノードで処理されます。対応するノードが存在しない場合には、そのサブフローが配置されたタブにエラーを伝播して処理します。</p> + <p>メッセージが<code>error</code>プロパティを持っている場合、元の<code>error</code>は<code>_error</code>へコピーします。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/25-status.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/25-status.html new file mode 100644 index 0000000..aa8c68d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/25-status.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="status"> + <p>同じタブ内のノードのステータスメッセージを取得します。</p> + <h3>出力</h3> + <dl class="message-properties"> + <dt>status.text <span class="property-type">文字列</span></dt> + <dd>ステータス文字列</dd> + <dt>status.source.type <span class="property-type">文字列</span></dt> + <dd>ステータスを表示したノードの種別</dd> + <dt>status.source.id <span class="property-type">文字列</span></dt> + <dd>ステータスを表示したノードのID</dd> + <dt>status.source.name <span class="property-type">文字列</span></dt> + <dd>ステータスを表示したノードの名称(設定されている場合)</dd> + </dl> + <h3>詳細</h3> + <p>このノードは<code>payload</code>を設定しません。</p> + <p>デフォルトでは、同じワークスペースタブ内の全てのノードのステータスを取得します。特定のノードのステータスを取得対象とすることも可能です。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/60-link.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/60-link.html new file mode 100644 index 0000000..72f9f7c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/60-link.html @@ -0,0 +1,31 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="link in"> + <p>フロー間に仮想的なリンクを作成します。</p> + <h3>詳細</h3> + <p>任意のタブ上に存在する<code>link out</code>ノードに接続できます。この接続はあたかも直接リンクしたかのように動作します。</p> + <p>linkノード間のリンクはlinkノードを選択した場合にのみ表示されます。他のタブへのリンクがある場合には、仮想的なノードを表示します。この仮想的ノードをクリックすると、対応するタブに移動できます。</p> + <p><b>注: </b>サブフローの外から中、もしくは、中から外へのリンクを作成することはできません。</p> +</script> + +<script type="text/x-red" data-help-name="link out"> + <p>フロー間に仮想的なリンクを作成します。</p> + <h3>詳細</h3> + <p>任意のタブ上に存在する<code>link in</code>ノードに接続できます。この接続はあたかも直接リンクしたかのように動作します。</p> + <p>linkノード間のリンクはlinkノードを選択した場合にのみ表示されます。他のタブへのリンクがある場合には、仮想的なノードを表示します。この仮想的ノードをクリックすると、対応するタブに移動できます。</p> + <p><b>注: </b>サブフローの外から中、もしくは、中から外へのリンクを作成することはできません。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/90-comment.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/90-comment.html new file mode 100644 index 0000000..a2d5dbb --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/90-comment.html @@ -0,0 +1,21 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="comment"> + <p>フローにコメントを記述するために利用します。</p> + <h3>詳細</h3> + <p>編集パネルはMarkdown形式を記入可能です。入力したテキストは、「情報」サイドパネルに表示されます。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/98-unknown.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/98-unknown.html new file mode 100644 index 0000000..312fbc7 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/common/98-unknown.html @@ -0,0 +1,24 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="unknown"> + <p>インストールされたNode-REDが認識できない種別のノードです。</p> + <h3>詳細</h3> + <p><i>この種別のノードをデプロイした場合、設定は保持されますが、足りないノードをインストールするまでフローを開始することはできません。</i></p> + <p><code>メニュー - パレットの管理</code>を使ってノードの検索とインストールを行うか、<b>npm install &lt;モジュール&gt;</b>で不足モジュールのインストールを行ってNode-REDを再起動した後、ノードを再インポートしてください。</p> + <p>この種別のノードがインストール済みであるが依存ライブラリがインストールされていないケースもあります。Node-REDの起動ログを参照して不足ノードに関連したエラーメッセージをチェックすると良いでしょう。</p> + <p>それでも解決しない場合、フローの作者に依頼して不足ノードのコピーを入手してください。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/10-function.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/10-function.html new file mode 100644 index 0000000..12eb75e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/10-function.html @@ -0,0 +1,51 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="function"> + <p>受信メッセージに対して処理を行うJavaScriptコード(関数の本体)を定義します。</p> + <p>入力メッセージは<code>msg</code>という名称のJavaScriptオブジェクトで受け渡されます。</p> + <p><code>msg</code>オブジェクトは<code>msg.payload</code>プロパティにメッセージ本体を保持するのが慣例です。</p> + <p>通常、コードはメッセージオブジェクト(もしくは複数のメッセージオブジェクト)を返却します。後続フローの実行を停止したい場合は、オブジェクトを返却しなくてもかまいません。</p> + <h3>詳細</h3> + <p>コードの書き方の詳細については、<a target="_blank" href="http://nodered.org/docs/writing-functions.html">オンラインドキュメント</a>を参照してください。</p> + <h4>メッセージの送信</h4> + <p>フロー内の次ノードにメッセージを渡すためには、メッセージを返却するか<code>node.send(messages)</code>を呼び出します。</p> + <p>返却/sendの対象は次のとおりです:</p> + <ul> + <li>単一メッセージオブジェクト - 最初の出力に接続されたノードに渡されます</li> + <li>メッセージオブジェクトの配列 - 対応する出力に接続されたノードに渡されます</li> + </ul> + <p>配列要素が配列の場合には、複数のメッセージを対応する出力に送出します。</p> + <p>返却方法が単一値か配列要素かにかかわらず、返却値がnullの場合メッセージの送出は行いません。</p> + <h4>ログ出力とエラー処理</h4> + <p>ログ情報の出力、エラー出力を行うには以下の関数を用います:</p> + <ul> + <li><code>node.log("ログメッセージ")</code></li> + <li><code>node.warn("警告")</code></li> + <li><code>node.error("エラー")</code></li> + </ul> + </p> + <p>catchノードを用いてエラー処理が可能です。catchノードで処理させるためには、<code>msg</code>を<code>node.error</code>の第二引数として渡します:</p> + <pre>node.error("エラー",msg);</pre> + <h4>ノード情報の参照</h4> + <p>コード中ではノードのIDおよび名前を以下のプロパティで参照できます:</p> + <ul> + <li><code>node.id</code> - ノードのID</li> + <li><code>node.name</code> - ノードの名称</li> + </ul> + <h4>環境変数の利用</h4> + <p>環境変数は<code>env.get("MY_ENV_VAR")</code>により参照できます。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/10-switch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/10-switch.html new file mode 100644 index 0000000..91ed9a7 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/10-switch.html @@ -0,0 +1,39 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="switch"> + <p>プロパティの値によってメッセージの振り分けを行います。</p> + <h3>詳細</h3> + <p>受信したメッセージに対し、指定されたルールを順に評価し、マッチしたルールに対応する出力ポートにメッセージを送出します。</p> + <p>最初にルールがマッチしたところで評価を止めることも可能です。</p> + <p>評価ルールには、メッセージプロパティ、フローコンテキスト/グローバルコンテキストのプロパティ、環境変数、JSONata式の評価結果が利用できます。</p> + <h4>ルール</h4> + <p>振り分けルールは以下の4つに分類されます。</p> + <ol> + <li><b>値(value)</b>ルール - 指定したプロパティに対して評価</li> + <li><b>列(sequence)</b>ルール - メッセージ列に対して適用(メッセージ列はsplitノードなどで生成)</li> + <li><b>JSONata式</b> - メッセージ全体に対して評価を行い、結果が真の場合にマッチ</li> + <li><b>その他</b> - これより前のルールにマッチするものがなかった場合に適用</li> + </ol> + + <h4>注釈</h4> + <p><code>is true/false</code>と<code>is null</code>のルールは、型に対して厳密な比較を行います。型変換した上での比較はしません。</p> + <p><code>is empty</code>のルールは、長さ0の文字列・配列・バッファ、またはプロパティを持たないオブジェクトを出力します。<code>null</code>や<code>undefined</code>は出力しません。</p> + + <h4>メッセージ列の扱い</h4> + <p>switchノードは入力メッセージの列に関する情報を保持する<code>msg.parts</code>をデフォルトでは変更しません。</p> + <p>「<b>メッセージ列の補正</b>」オプションを指定すると、マッチした各ルールに対して新しいメッセージ列を生成します。このモードでは、switchノードは新たなメッセージ列を送信する前に、入力メッセージ列全体を内部に蓄積します。<b>settings.js</b>の<code>nodeMessageBufferMaxLength</code>を設定すると、蓄積するメッセージ数を制限できます。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/15-change.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/15-change.html new file mode 100644 index 0000000..bdcf792 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/15-change.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="change"> + <p>メッセージ、フローコンテキスト、グローバルコンテキストのプロパティを変更、削除、移動します。</p> + <p>ルールを複数指定した場合、定義した順に適用します。</p> + <h3>詳細</h3> + <p>利用可能な処理</p> + <dl class="message-properties"> + <dt>代入</dt> + <dd>プロパティをセットします。設定値には、さまざまな型の値、メッセージやコンテキストの既存プロパティを利用できます。<dd> + <dt>置換</dt> + <dd>プロパティに対して検索と置換を行います。正規表現を指定した場合、「置換後の文字列」には<code>$1</code>のようなキャプチャグループが指定できます。置換処理では、ルールが完全マッチの場合のみプロパティの型を変更できます。</dd> + <dt>削除</dt> + <dd>プロパティを削除します。</dd> + <dt>移動</dt> + <dd>プロパティの移動または名前の変更を行います。</dd> + </dl> + <p>「JSONata式」には<a href="http://jsonata.org/" target="_new">JSONata</a>言語を指定できます。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/16-range.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/16-range.html new file mode 100644 index 0000000..b1294f6 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/16-range.html @@ -0,0 +1,47 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="range"> + <p>数値を異なる範囲の値に変換します。</p> + <h3>入力</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">数値</span></dt> + <dd>数値を指定します。数値以外を指定した場合は、数値に変換します。変換不能な場合はエラーとなります。</dd> + </dl> + <h3>出力</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">数値</span></dt> + <dd>新しい範囲に変換した結果の値。</dd> + </dl> + <h3>詳細</h3> + <p>このノードは受け取った数値を線形スケーリングします。デフォルトでは、結果の値はノードに設定した範囲内に限定しません。</p> + <p>「<i>入力値の範囲外の値を最小値/最大値として拡大/縮小</i>」を指定すると、値が指定した範囲外の値にならないようにします。</p> + <p>「<i>入力値の範囲外の値を範囲幅で割った余りとし拡大/縮小</i>」を指定すると、結果を範囲幅で折り返します。</p> + <p>例: 入力値0 - 10を0 - 100に変換</p> + <table style="outline-width:#888 solid thin"> + <tr><th width="80px">モード</th><th width="80px">入力</th><th width="80px">出力</th></tr> + <tr><td><center>scale</center></td><td><center>12</center></td><td><center>120</center></td></tr> + <tr><td><center>limit</center></td><td><center>12</center></td><td><center>100</center></td></tr> + <tr><td><center>wrap</center></td><td><center>12</center></td><td><center>20</center></td></tr> + </table> + <br/> + モード:<br/> + <ul> + <li>scale: msg.payloadの値を拡大/縮小</li> + <li>limit: 入力値の範囲外の値を最小値/最大値とし拡大/縮小</li> + <li>wrap: 入力値の範囲外の値を範囲幅で割った余りとし拡大/縮小</li> + </ul> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/80-template.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/80-template.html new file mode 100644 index 0000000..802c268 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/80-template.html @@ -0,0 +1,49 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="template"> + <p>テンプレートに基づいてプロパティを設定します。</p> + <h3>入力</h3> + <dl class="message-properties"> + <dt>msg <span class="property-type">オブジェクト</span></dt> + <dd>テンプレートを生成するための情報を含むメッセージオブジェクト</dd> + <dt class="optional">template <span class="property-type">文字列</span></dt> + <dd><code>msg.payload</code>を生成するためのテンプレート。編集パネルでテンプレートを設定しない場合に、出力メッセージとして利用します</dd> + </dl> + <h3>出力</h3> + <dl class="message-properties"> + <dt>msg <span class="property-type">オブジェクト</span></dt> + <dd>指定したテンプレートと入力メッセージのプロパティから生成した値を設定したメッセージ</dd> + </dl> + <h3>詳細</h3> + <p>このノードは<i><a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache</a></i>形式をデフォルトで利用しますが、使用しないようにすることもできます。</p> + <p>例えば、 + <pre>こんにちは{{payload.name}}さん。今日は{{date}}です。</pre> + <p>というテンプレートに対して、 + <pre>{ + date: "月曜日", + payload: { + name: "山田" + } +}</pre> + <p>というメッセージを受信した場合、</p> + <pre>こんにちは山田さん。今日は月曜日です。</pre> + <p>というプロパティが生成されます。</p> + <p>フローコンテキストもしくはグローバルコンテキストのプロパティ値を使うこともできます。それぞれ、<code>{{flow.名前}}</code>もしくは<code>{{global.名前}}</code>を用います。もしくは、パーシスタブルストア(<code>store</code>)に対しては、<code>{{flow[store].名前}}</code>もしくは + <code>{{global[store].名前}}</code>を用います。 +</p> + <p><b>注: </b>デフォルトでは、<i>mustache</i>形式は置換対象のHTML要素をエスケープします。これを抑止するには<code>{{{三重}}}</code>括弧形式を使います。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/89-delay.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/89-delay.html new file mode 100644 index 0000000..ed5046f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/89-delay.html @@ -0,0 +1,32 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="delay"> + <p>ノードを通過するメッセージを遅延もしくは流量を制限します。</p> + <h3>入力</h3> + <dl class="message-properties"> + <dt class="optional">delay <span class="property-type">数値</span></dt> + <dd>メッセージの遅延時間をミリ秒単位で設定します。これはノードの設定でデフォルトの遅延時間を上書きできるようノードを設定した場合にのみ適用します。</dd> + <dt class="optional">reset</dt> + <dd>受信メッセージでこのプロパティを任意の値に設定すると、ノードが保持する全ての未送信メッセージをクリアします。</dd> + <dt class="optional">flush</dt> + <dd>受信メッセージでこのプロパティを任意の値に設定すると、ノードが保持する全ての未送信メッセージを直ちに送信します。</dd> + </dl> + <h3>詳細</h3> + <p>メッセージを遅延させるように設定する場合、遅延時間は固定値、範囲内の乱数値、メッセージ毎の動的な指定値のいずれかを指定できます。</p> + <p>流量制御する場合、メッセージは指定した時間間隔内に分散して送信します。キューに残っているメッセージ数はノードのステータスに表示されます。受け取った中間メッセージを破棄することも可能です。</p> + <p>流量制御は全てのメッセージに適用することも、<code>msg.topic</code>値でグループ化して適用することも可能です。グループ化すると、中間メッセージは自動的に破棄されます。時間間隔毎に全てのトピックの最新メッセージを送信するか、次のトピックの最新メッセージを送信するかを指定できます。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/89-trigger.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/89-trigger.html new file mode 100644 index 0000000..51ab465 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/89-trigger.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="trigger"> + <p>メッセージを受信すると、別のメッセージの送信を行います。延長もしくは初期化が指定されていない場合には、2つ目のメッセージを送信することもできます。</p> + + <h3>入力</h3> + <dl class="message-properties"> + <dt class="optional">reset</dt> + <dd>このプロパティを持つメッセージを受け取ると、仕掛かり中の待機や繰り返しをクリアしメッセージの送信は行いません。</dd> + </dl> + + <h3>詳細</h3> + <p>フロー内でタイムアウトを作成するのに利用します。メッセージを受け取ると、デフォルトでは<code>payload</code>に<code>1</code>を設定して送信します。送信後250ms待機し、<code>payload</code>を<code>0</code>に設定した2つ目のメッセージを送信します。この機能は、例えばRaspberry PiのGPIOピンに接続したLEDを点滅させるために活用できます。</p> + <p>各送信メッセージのペイロードはさまざまな種類の値に設定できます。再送信データなしとすることも可能です。例えば、再送信データを「<i>なし</i>」とし、メッセージを受け取った時に遅延を延長することを選択した場合、triggerノードは監視タイマとして動作します。すなわち、指定間隔内にメッセージを受信しない場合にメッセージを送信します。</p> + <p>ペイロードに<i>文字列</i>を指定する場合、mustache形式のテンプレートが利用できます。</p> + <p><code>reset</code>プロパティを持つメッセージを受信した場合、もしくは、<code>payload</code>が設定した値にマッチする場合、仕掛かり中の待機や繰り返しをクリアしメッセージの送信は行いません。</p> + <p>受信メッセージでリセットするまで一定間隔でメッセージを再送するように指定することもできます。</p> + <p><code>msg.topic</code>毎に別のストリームとして扱うように設定することも可能です。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/90-exec.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/90-exec.html new file mode 100644 index 0000000..7eb75b1 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/function/90-exec.html @@ -0,0 +1,74 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="exec"> + <p>システムのコマンドを実行し出力を返します。</p> + <p>コマンドの完了まで待つか、コマンドが出力を行う毎にメッセージを出力するかを指定できます。</p> + <p>実行対象のコマンドは、ノードの設定もしくは受信メッセージで指定します。</p> + + <h3>入力</h3> + <dl class="message-properties"> + <dt class="optional">payload <span class="property-type">文字列</span></dt> + <dd>実行コマンドの最後に追加するよう設定できます</dd> + <dt class="optional">kill <span class="property-type">文字列</span></dt> + <dd>execノードのプロセスに対して送るシグナルの種別を指定します</dd> + <dt class="optional">pid <span class="property-type">数値|文字列</span></dt> + <dd>シグナル送信対象のexecノードのプロセスIDを指定します</dd> + </dl> + + <h3>出力</h3> + <ol class="node-ports"> + <li>標準出力(stdout) + <dl class="message-properties"> + <dt>payload <span class="property-type">文字列</span></dt> + <dd>コマンドの標準出力</dd> + </dl> + <dl class="message-properties"> + <dt>rc <span class="property-type">オブジェクト</span></dt> + <dd>返却コードオブジェクト(3番目の端子でも受取り可能)のコピー(execモードのみ)</dd> + </dl> + </li> + <li>標準エラー出力(stderr) + <dl class="message-properties"> + <dt>payload <span class="property-type">文字列</span></dt> + <dd>コマンドの標準エラー出力</dd> + </dl> + <dl class="message-properties"> + <dt>rc <span class="property-type">オブジェクト</span></dt> + <dd>返却コードオブジェクト(3番目の端子でも受取り可能)のコピー(execモードのみ)</dd> + </dl> + </li> + <li>返却コード(return code) + <dl class="message-properties"> + <dt>payload <span class="property-type">オブジェクト</span></dt> + <dd>リターンコード、<code>message</code>、<code>signal</code>プロパティを含むオブジェクト(<code>message</code>、<code>signal</code>は利用可能な場合)</dd> + </dl> + </li> + </ol> + <h3>詳細</h3> + <p>デフォルトでは、<code>exec</code>システムコールを用いてコマンドを呼び出してその完了を待ち、出力を返します。例えば、コマンドの実行が成功した場合には、<code>{ code: 0 }</code>と言う返却値を返します。</p> + <p><code>spawn</code>を使ってコマンドを実行し、標準出力および標準エラー出力へ出力を返すようにすることもできます。この場合、通常1行毎に値を返します。コマンドの実行が完了すると、3番目の端子にオブジェクトを出力します。例えば、コマンドの実行が成功した場合には、<code>{ code: 0 }</code>という返却値を返します。</p> + <p>エラー発生時には、3番目の端子の<code>msg.payload</code>に<code>message</code>、<code>signal</code>など付加情報を返します。</p> + <p>実行対象のコマンドはノード設定で定義します。<code>msg.payload</code>や追加引数をコマンドに追加することもできます。</p> + <p>コマンドもしくはパラメータが空白を含む場合には、引用符で囲みます。- <code>"これは一つのパラメータです"</code></p> + <p>返却する<code>payload</code>は通常<i>文字列</i>ですが、UTF8文字以外が存在すると<i>バッファ</i>となります。</p> + <p>ノードが実行中の場合、ステータスアイコンとPIDを表示します。この状態変化は<code>Status</code>ノードで検知できます。</p> + <h4>プロセスの停止</h4> + <p><code>msg.kill</code>を受信すると、実行中のプロセスを停止することができます。<code>msg.kill</code>には送出するシグナルの種別を指定します。例えば、<code>SIGINT</code>、<code>SIGQUIT</code>、<code>SIGHUP</code>などです。空の文字列を指定した場合には、<code>SIGTERM</code>を指定したものとみなします。</p> + <p>ノードが1つ以上のプロセスを実行している場合、<code>msg.pid</code>に停止対象のPIDを指定しなければなりません。</p> + <p><code>タイムアウト</code>フィールドに値を指定すると、指定した秒数以内にコマンドが完了しない場合、プロセスを自動的に停止します。</p> + <p>ヒント: Pythonアプリケーションを実行する場合、<code>-u</code>を指定すると出力がバッファされるのを抑止できます。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/messages.json b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/messages.json new file mode 100644 index 0000000..be11bc5 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/messages.json @@ -0,0 +1,940 @@ +{ + "common": { + "label": { + "payload": "ペイロード", + "topic": "トピック", + "name": "名前", + "username": "ユーザ名", + "password": "パスワード", + "property": "プロパティ", + "selectNodes": "ノードを選択...", + "expand": "展開" + }, + "status": { + "connected": "接続済", + "not-connected": "未接続", + "disconnected": "切断", + "connecting": "接続中", + "error": "エラー", + "ok": "OK" + }, + "notification": { + "error": "<strong>エラー</strong>: __message__", + "errors": { + "not-deployed": "ノードがデプロイされていません", + "no-response": "サーバの応答がありません", + "unexpected": "想定外のエラー (__status__) __message__" + } + }, + "errors": { + "nooverride": "警告: メッセージで設定したプロパティは、ノードのプロパティを上書きできません。詳細はbit.ly/nr-override-msg-propsを参照してください。" + } + }, + "inject": { + "inject": "inject", + "repeat": "repeat = __repeat__", + "crontab": "crontab = __crontab__", + "stopped": "stopped", + "failed": "inject失敗: __error__", + "label": { + "repeat": "繰り返し", + "flow": "フローコンテクスト", + "global": "グローバルコンテクスト", + "str": "文字列", + "num": "数値", + "bool": "真偽値", + "json": "オブジェクト", + "bin": "バッファ", + "date": "タイムスタンプ", + "env": "環境変数", + "object": "オブジェクト", + "string": "文字列", + "boolean": "真偽値", + "number": "数値", + "Array": "配列", + "invalid": "不正なJSON" + }, + "timestamp": "タイムスタンプ", + "none": "なし", + "interval": "指定した時間間隔", + "interval-time": "指定した時間間隔、日時", + "time": "指定した日時", + "seconds": "秒", + "minutes": "分", + "hours": "時間", + "between": "時刻", + "previous": "前回の値", + "at": "時刻", + "and": "~", + "every": "時間間隔", + "days": [ + "月曜日", + "火曜日", + "水曜日", + "木曜日", + "金曜日", + "土曜日", + "日曜日" + ], + "on": "曜日", + "onstart": "Node-RED起動の", + "onceDelay": "秒後、以下を行う", + "tip": "<b>注釈:</b> 「指定した時間間隔、日時」と「指定した日時」はcronを使用します。<br/>「時間間隔」には596時間より小さな値を指定します。<br/>詳細はノードの「情報」を確認してください。", + "success": "inject処理を実行しました: __label__", + "errors": { + "failed": "inject処理が失敗しました。詳細はログを確認してください。", + "toolong": "時間間隔が大き過ぎます" + } + }, + "catch": { + "catch": "catch: 全て", + "catchNodes": "catch: __number__", + "catchUncaught": "catch: 未補足", + "label": { + "source": "エラー取得元", + "selectAll": "全て選択", + "uncaught": "Catchノードで処理済みのエラーを無視" + }, + "scope": { + "all": "全てのノード", + "selected": "選択したノード" + } + }, + "status": { + "status": "status: 全て", + "statusNodes": "status: __number__", + "label": { + "source": "状態取得元", + "sortByType": "型で並べ替え" + }, + "scope": { + "all": "全てのノード", + "selected": "選択したノード" + } + }, + "complete": { + "completeNodes": "complete: __number__" + }, + "debug": { + "output": "対象", + "none": "無し", + "invalid-exp": "JSONata式が不正: __error__", + "msgprop": "メッセージプロパティ", + "msgobj": "msgオブジェクト全体", + "to": "出力先", + "debtab": "デバッグタブ", + "tabcon": "デバッグタブとコンソール", + "toSidebar": "デバッグウィンドウ", + "toConsole": "システムコンソール", + "toStatus": "ノード状態 (32 文字)", + "severity": "Level", + "notification": { + "activated": "有効化しました: __label__", + "deactivated": "無効化しました: __label__" + }, + "sidebar": { + "label": "デバッグ", + "name": "デバッグメッセージ", + "filterAll": "全てのフロー", + "filterSelected": "選択したノード", + "filterCurrent": "現在のフロー", + "debugNodes": "debugノード", + "clearLog": "ログを削除", + "filterLog": "ログのフィルタリング", + "openWindow": "新しいウィンドウで開く", + "copyPath": "パスをコピー", + "copyPayload": "値をコピー", + "pinPath": "展開を固定" + }, + "messageMenu": { + "collapseAll": "全パスを折りたたむ", + "clearPinned": "選択したパス", + "filterNode": "ノードをフィルタ", + "clearFilter": "フィルタを初期化" + } + }, + "link": { + "linkIn": "link in", + "linkOut": "link out" + }, + "tls": { + "tls": "TLS設定", + "label": { + "use-local-files": "ローカルファイルの秘密鍵と証明書を使用", + "upload": "ファイル", + "cert": "証明書", + "key": "秘密鍵", + "passphrase": "パスフレーズ", + "ca": "CA証明書", + "verify-server-cert": "サーバ証明書を確認", + "servername": "サーバ名" + }, + "placeholder": { + "cert": "証明書(PEM形式)のパス", + "key": "秘密鍵(PEM形式)のパス", + "ca": "CA証明書(PEM形式)のパス", + "passphrase": "秘密鍵のパスフレーズ (任意)", + "servername": "SNIで使用" + }, + "error": { + "missing-file": "証明書と秘密鍵のファイルが設定されていません" + } + }, + "exec": { + "exec": "exec", + "spawn": "spawn", + "label": { + "command": "コマンド", + "append": "引数", + "timeout": "タイムアウト", + "timeoutplace": "任意", + "return": "出力", + "seconds": "秒", + "stdout": "標準出力", + "stderr": "標準エラー出力", + "retcode": "返却コード" + }, + "placeholder": { + "extraparams": "追加引数" + }, + "opt": { + "exec": "コマンド終了時 - execモード", + "spawn": "コマンド実行中 - spawnモード" + }, + "oldrc": "旧型式の出力を使用(互換モード)" + }, + "function": { + "function": "", + "label": { + "function": "コード", + "outputs": "出力数" + }, + "error": { + "inputListener": "コード内で'input'イベントのリスナを設定できません", + "non-message-returned": "Functionノードが __type__ 型のメッセージ送信を試みました" + } + }, + "template": { + "template": "template", + "label": { + "template": "テンプレート", + "property": "プロパティ", + "format": "構文", + "syntax": "形式", + "output": "出力形式", + "mustache": "Mustacheテンプレート", + "plain": "平文", + "json": "JSON", + "yaml": "YAML", + "none": "なし" + }, + "templatevalue": "This is the payload: {{payload}} !" + }, + "delay": { + "action": "動作", + "for": "時間", + "delaymsg": "メッセージの遅延", + "delayfixed": "指定した時間遅延", + "delayvarmsg": "msg.delay に遅延を設定", + "randomdelay": "ランダム時間の遅延", + "limitrate": "メッセージの流量制限", + "limitall": "全てのメッセージ", + "limittopic": "msg.topic毎", + "fairqueue": "指定した時間後にキュー先頭のトピックのメッセージを出力", + "timedqueue": "指定した時間後にキューにある全トピックのメッセージを出力", + "milisecs": "ミリ秒", + "secs": "秒", + "sec": "秒", + "mins": "分", + "min": "分", + "hours": "時間", + "hour": "時間", + "days": "日", + "day": "日", + "between": "頻度", + "and": "回/", + "rate": "流量", + "msgper": "メッセージ/", + "dropmsg": "中間メッセージを削除", + "label": { + "delay": "delay", + "variable": "variable", + "limit": "limit", + "limitTopic": "limit topic", + "random": "random", + "units": { + "second": { + "plural": "秒", + "singular": "秒" + }, + "minute": { + "plural": "分", + "singular": "分" + }, + "hour": { + "plural": "時間", + "singular": "時間" + }, + "day": { + "plural": "日", + "singular": "日" + } + } + }, + "error": { + "buffer": "バッファ上限の1000メッセージを超えました", + "buffer1": "バッファ上限の10000メッセージを超えました" + } + }, + "trigger": { + "send": "送信データ", + "then": "送信後の処理", + "then-send": "再送信データ", + "output": { + "string": "文字列", + "number": "数値", + "existing": "存在するmsgオブジェクト", + "original": "元のmsgオブジェクト", + "latest": "最新のmsgオブジェクト", + "nothing": "なし" + }, + "wait-reset": "初期化されるまで待機", + "wait-for": "指定した時間待機", + "wait-loop": "指定した時間間隔毎に送信を繰り返す", + "for": "処理対象", + "bytopics": "msg.topic毎", + "alltopics": "全メッセージ", + "duration": { + "ms": "ミリ秒", + "s": "秒", + "m": "分", + "h": "時間" + }, + "extend": " 新たなメッセージを受け取った時に遅延を延長", + "label": { + "trigger": "trigger", + "trigger-block": "trigger & block", + "trigger-loop": "resend every", + "reset": "初期化条件:", + "resetMessage": "msg.resetを設定", + "resetPayload": "msg.payloadが次の値", + "resetprompt": "任意" + } + }, + "comment": { + "comment": "comment" + }, + "unknown": { + "label": { + "unknown": "unknown" + }, + "tip": "<p>現在のNode-RED環境では、本ノードの型が不明です。</p><p><i>現在の状態で本ノードをデプロイすると設定は保存されますが、不明なノードがインストールされるまでフローは実行されません。</i></p><p>詳細はノードの「情報」を参照してください。</p>" + }, + "mqtt": { + "label": { + "broker": "サーバ", + "example": "例) localhost", + "output": "出力", + "qos": "QoS", + "retain": "保持", + "clientid": "クライアント", + "port": "ポート", + "keepalive": "キープアライブ時間", + "cleansession": "セッションの初期化", + "use-tls": "SSL/TLS接続を使用", + "tls-config": "TLS設定", + "verify-server-cert": "サーバの証明書を確認", + "compatmode": "旧MQTT 3.1のサポート" + }, + "sections-label": { + "birth-message": "接続時の送信メッセージ(Birthメッセージ)", + "will-message": "予期しない切断時の送信メッセージ(Willメッセージ)", + "close-message": "切断前の送信メッセージ(Closeメッセージ)" + }, + "tabs-label": { + "connection": "接続", + "security": "セキュリティ", + "messages": "メッセージ" + }, + "placeholder": { + "clientid": "IDを自動生成する場合は、無記入にしてください", + "clientid-nonclean": "新規ではないセッションを設定してください", + "will-topic": "Willメッセージを無効化する場合は、無記入にしてください", + "birth-topic": "Birthメッセージを無効化する場合は、無記入にしてください", + "close-topic": "Closeメッセージを無効化する場合は、無記入にしてください" + }, + "state": { + "connected": "ブローカへ接続しました: __broker__", + "disconnected": "ブローカから切断されました: __broker__", + "connect-failed": "ブローカへの接続に失敗しました: __broker__" + }, + "retain": "保持", + "output": { + "buffer": "バイナリバッファ", + "string": "文字列", + "base64": "Base64文字列", + "auto": "自動判定(文字列もしくはバイナリバッファ)", + "json": "JSONオブジェクト" + }, + "true": "する", + "false": "しない", + "tip": "注釈: トピックやQoSをメッセージのプロパティを用いて設定する場合は、無記入にしてください。", + "errors": { + "not-defined": "トピックが設定されていません", + "missing-config": "ブローカが設定されていません", + "invalid-topic": "不正なトピックが設定されています", + "nonclean-missingclientid": "「セッションの初期化」使用時に、クライアントIDが設定されていません", + "invalid-json-string": "不正なJSON文字列", + "invalid-json-parse": "JSON文字列のパースに失敗しました" + } + }, + "httpin": { + "label": { + "method": "メソッド", + "url": "URL", + "doc": "Docs", + "return": "出力形式", + "upload": "ファイルのアップロード", + "status": "状態コード", + "headers": "ヘッダ", + "other": "その他", + "paytoqs": "msg.payloadをクエリパラメータに追加", + "utf8String": "UTF8文字列", + "binaryBuffer": "バイナリバッファ", + "jsonObject": "JSONオブジェクト", + "authType": "種別", + "bearerToken": "トークン" + }, + "setby": "- msg.methodに定義 -", + "basicauth": "認証を使用", + "use-tls": "SSL/TLS接続を有効化", + "tls-config": "TLS設定", + "basic": "Basic認証", + "digest": "Digest認証", + "bearer": "Bearer認証", + "use-proxy": "プロキシを使用", + "persist": "コネクションkeep-aliveを有効化", + "proxy-config": "プロキシ設定", + "use-proxyauth": "プロキシ認証を使用", + "noproxy-hosts": "例外ホスト", + "utf8": "UTF8文字列", + "binary": "バイナリバッファ", + "json": "JSONオブジェクト", + "tip": { + "in": "URLは相対パスになります。", + "res": "本ノードに送付するメッセージは、<i>http input</i>ノードを起点としてください。", + "req": "注釈: JSONの構文解析に失敗した場合は、取得した文字列をそのまま出力します。" + }, + "httpreq": "http request", + "errors": { + "not-created": "httpNodeRootにfalseが設定されている時は、http-inノードを作成できません", + "missing-path": "パスが設定されていません", + "no-response": "応答がありません", + "json-error": "JSONの構文解析エラー", + "no-url": "URLが設定されていません", + "deprecated-call": "非推奨の呼び出しです __method__", + "invalid-transport": "httpでないトランスポートが要求されました", + "timeout-isnan": "タイムアウト値が数値ではないため無視します", + "timeout-isnegative": "タイムアウト値が負数のため無視します", + "invalid-payload": "不正なペイロード" + }, + "status": { + "requesting": "要求中" + } + }, + "websocket": { + "label": { + "type": "種類", + "path": "パス", + "url": "URL" + }, + "listenon": "待ち受け", + "connectto": "接続", + "sendrec": "送信/受信", + "payload": "ペイロードを送信/受信", + "message": "メッセージ全体を送信/受信", + "tip": { + "path1": "標準では <code>payload</code> がwebsocketから送信、受信されるデータを持ちます。クライアントはJSON形式の文字列としてメッセージ全体を送信、受信するよう設定できます。", + "path2": "This path will be relative to ", + "url1": "URLには ws:&#47;&#47; または wss:&#47;&#47; スキーマを使用して、存在するwebsocketリスナを設定してください。", + "url2": "標準では <code>payload</code> がwebsocketから送信、受信されるデータを持ちます。クライアントはJSON形式の文字列としてメッセージ全体を送信、受信するよう設定できます。" + }, + "status": { + "connected": "接続数 __count__", + "connected_plural": "接続数 __count__" + }, + "errors": { + "connect-error": "ws接続でエラーが発生しました: ", + "send-error": "送信中にエラーが発生しました: ", + "missing-conf": "サーバ設定が不足しています", + "duplicate-path": "同じパスに対して2つのWebSocketリスナは指定できません: __path__" + } + }, + "watch": { + "watch": "watch", + "label": { + "files": "ファイル", + "recursive": "サブディレクトリを再帰的に監視" + }, + "placeholder": { + "files": "複数のファイルやディレクトリはコンマ区切りで入力" + }, + "tip": "Windowsの場合は、ディレクトリの区切り文字として2つのバックスラッシュ \\\\ を使用してください。" + }, + "tcpin": { + "label": { + "type": "種類", + "output": "出力", + "port": "ポート", + "host": "ホスト", + "payload": "のペイロード", + "delimited": "区切り文字", + "close-connection": "メッセージを送信するたびに接続を切断", + "decode-base64": "Base64メッセージの復号", + "server": "サーバ", + "return": "戻り値", + "ms": "ミリ秒", + "chars": "文字" + }, + "type": { + "listen": "待ち受け", + "connect": "接続", + "reply": "TCP応答" + }, + "output": { + "stream": "ストリーム", + "single": "単一", + "buffer": "バイナリバッファ", + "string": "文字列", + "base64": "Base64文字列" + }, + "return": { + "timeout": "指定時間後", + "character": "指定文字の受信時", + "number": "指定数の文字列", + "never": "なし - 接続を維持", + "immed": "即時 - 応答を待たない" + }, + "status": { + "connecting": "__host__:__port__ へ接続しています", + "connected": "__host__:__port__ へ接続しました", + "listening-port": "ポート __port__ にて接続を待ち受けています", + "stopped-listening": "ポートの待ち受けを停止しました", + "connection-from": "__host__:__port__ から接続されました", + "connection-closed": "__host__:__port__ からの接続が切断されました", + "connections": "接続数 __count__", + "connections_plural": "接続数 __count__" + }, + "errors": { + "connection-lost": "__host__:__port__ への接続が失われました", + "timeout": "ポート __port__ のソケットがタイムアウトにより切断されました", + "cannot-listen": "ポート __port__ の待ち受けができません エラー: __error__", + "error": "エラー: __error__", + "socket-error": "__host__:__port__ にてソケットのエラーが生じました", + "no-host": "ホスト名またはポートが設定されていません", + "connect-timeout": "接続がタイムアウトしました", + "connect-fail": "接続に失敗しました" + } + }, + "udp": { + "label": { + "listen": "待ち受け", + "onport": "ポート", + "using": "種類", + "output": "出力", + "group": "グループ", + "interface": "ローカルIP", + "send": "送信", + "toport": "ポート", + "address": "アドレス", + "decode-base64": "Base64形式のペイロードを復号" + }, + "placeholder": { + "interface": "(任意) 使用するローカルインターフェイスもしくはアドレス", + "interfaceprompt": "(任意) 使用するローカルインターフェイスもしくはアドレス", + "address": "宛先IPアドレス" + }, + "udpmsgs": "UDPメッセージ", + "mcmsgs": "マルチキャストメッセージ", + "udpmsg": "UDPメッセージ", + "bcmsg": "ブロードキャストメッセージ", + "mcmsg": "マルチキャストメッセージ", + "output": { + "buffer": "バイナリバッファ", + "string": "文字列", + "base64": "Base64文字列" + }, + "bind": { + "random": "ローカルポートをランダムに使用", + "local": "ローカルポートを使用", + "target": "指定したポートを使用" + }, + "tip": { + "in": "注釈: ファイアウォールが通信を許可しているか確認してください。", + "out": "注釈: <code>msg.ip</code> や <code>msg.port</code> を用いて設定する場合は、「アドレス」や「ポート」を無記入にしてください。", + "port": "既にポートが使用されています: " + }, + "status": { + "listener-at": "udpノードが __host__:__port__ にて接続を待ち受けています", + "mc-group": "udpノードがグループ __group__ へマルチキャストしました", + "listener-stopped": "udpノードが待ち受けを停止しました", + "output-stopped": "udpノードが出力を停止しました", + "mc-ready": "udpノードはマルチキャストの準備ができています: __iface__:__outport__ -> __host__:__port__", + "bc-ready": "udpノードはブロードキャストの準備ができています: __outport__ -> __host__:__port__", + "ready": "udpノードは準備ができています: __outport__ -> __host__:__port__", + "ready-nolocal": "udpノードは準備ができています: __host__:__port__", + "re-use": "udp再利用ソケット: __outport__ -> __host__:__port__" + }, + "errors": { + "access-error": "UDP接続エラー 管理者権限で1024未満のポート番号にアクセスできる必要があります", + "error": "エラー: __error__", + "bad-mcaddress": "マルチキャストアドレスが不正です", + "interface": "インターフェイスのIPアドレスを設定する必要があります", + "ip-notset": "udp: IPアドレスが設定されていません", + "port-notset": "udp: ポートが設定されていません", + "port-invalid": "udp: ポート番号が不正です", + "alreadyused": "udp: 既に__port__番ポートが使用されています", + "ifnotfound": "udp: インターフェイス __iface__ がありません" + } + }, + "switch": { + "switch": "switch", + "label": { + "property": "プロパティ", + "rule": "条件", + "repair": "メッセージ列の補正" + }, + "previous": "前回の値", + "and": "~", + "checkall": "全ての条件を適用", + "stopfirst": "最初に合致した条件で終了", + "ignorecase": "大文字、小文字を区別しない", + "rules": { + "btwn": "is between", + "cont": "contains", + "regex": "matches regex", + "true": "is true", + "false": "is false", + "null": "is null", + "nnull": "is not null", + "istype": "is of type", + "empty": "is empty", + "nempty": "is not empty", + "head": "head", + "tail": "tail", + "index": "index between", + "exp": "JSONata式", + "else": "その他", + "hask": "has key" + }, + "errors": { + "invalid-expr": "不正な表現: __error__", + "too-many": "switchノード内で保持しているメッセージが多すぎます" + } + }, + "change": { + "label": { + "rules": "ルール", + "rule": "ルール", + "set": "set __property__", + "change": "change __property__", + "delete": "delete __property__", + "move": "move __property__", + "changeCount": "change: __count__ rules", + "regex": "正規表現を使用" + }, + "action": { + "set": "値の代入", + "change": "値の置換", + "delete": "値の削除", + "move": "値の移動", + "to": "対象の値", + "search": "検索する文字列", + "replace": "置換後の文字列" + }, + "errors": { + "invalid-from": "操作対象のプロパティが不正: __error__", + "invalid-json": "対象の値のJSONプロパティが不正", + "invalid-expr": "JSONata式が不正: __error__" + } + }, + "range": { + "range": "range", + "label": { + "action": "動作", + "inputrange": "入力値の範囲", + "resultrange": "出力値の範囲", + "from": "最小値", + "to": "最大値", + "roundresult": "小数値を四捨五入し整数値へ変換" + }, + "placeholder": { + "min": "例) 0", + "maxin": "例) 99", + "maxout": "例) 255" + }, + "scale": { + "payload": "msg.payloadの値を拡大/縮小", + "limit": "入力値の範囲外の値を最小値/最大値とし拡大/縮小", + "wrap": "入力値の範囲外の値を範囲幅で割った余りとし拡大/縮小" + }, + "tip": "注釈: 本ノードは、数値のみ扱うことができます。", + "errors": { + "notnumber": "数値ではありません" + } + }, + "csv": { + "label": { + "columns": "列名", + "separator": "区切り文字", + "c2o": "CSVからオブジェクトへ変換", + "o2c": "オブジェクトからCSVへ変換", + "input": "入力", + "skip-s": "最初の", + "skip-e": "行を無視する", + "firstrow": "1行目に列名を含む", + "output": "出力", + "includerow": "1行目を列名とする", + "newline": "改行コード", + "usestrings": "数値を変換する" + }, + "placeholder": { + "columns": "コンマ区切りで列名を入力" + }, + "separator": { + "comma": "コンマ", + "tab": "タブ", + "space": "空白", + "semicolon": "セミコロン", + "colon": "コロン", + "hashtag": "ハッシュタグ", + "other": "その他..." + }, + "output": { + "row": "行毎にメッセージを分割", + "array": "配列化した1つのメッセージ" + }, + "newline": { + "linux": "Linux (\\n)", + "mac": "Mac (\\r)", + "windows": "Windows (\\r\\n)" + }, + "errors": { + "csv_js": "本ノードが処理できる形式は、CSV文字列またはJSONのみです", + "obj_csv": "オブジェクトをCSVへ変換する際の列名が設定されていません" + } + }, + "html": { + "label": { + "select": "抽出する要素", + "output": "出力", + "in": "対象:" + }, + "output": { + "html": "要素内のHTML", + "text": "要素のテキストのみ", + "attr": "要素の全ての属性" + }, + "format": { + "single": "配列化した1つのメッセージ", + "multi": "要素毎の複数のメッセージ" + } + }, + "json": { + "errors": { + "dropped-object": "オブジェクト形式でないペイロードを無視しました", + "dropped": "対応していない形式のペイロードを無視しました", + "dropped-error": "ペイロードの変換処理が失敗しました", + "schema-error": "JSONスキーマエラー", + "schema-error-compile": "JSONスキーマエラー: スキーマのコンパイルが失敗しました" + }, + "label": { + "o2j": "オブジェクトからJSONへ変換", + "pretty": "JSON文字列フォーマット", + "action": "動作", + "property": "プロパティ", + "actions": { + "toggle": "JSON文字列とオブジェクト間の相互変換", + "str": "常にJSON文字列に変換", + "obj": "常にJavaScriptオブジェクトに変換" + } + } + }, + "yaml": { + "errors": { + "dropped-object": "オブジェクト形式でないペイロードを無視しました", + "dropped": "対応していない形式のペイロードを無視しました", + "dropped-error": "ペイロードの変換処理が失敗しました" + } + }, + "xml": { + "label": { + "represent": "XMLタグ属性を次のプロパティ名として表現", + "prefix": "文字列を参照するための接頭辞", + "advanced": "詳細設定", + "x2o": "XMLからオブジェクトへ変換" + }, + "errors": { + "xml_js": "本ノードは、XML形式の文字列またはJSONのみ処理します" + } + }, + "file": { + "label": { + "filename": "ファイル名", + "action": "動作", + "addnewline": "メッセージの入力のたびに改行を追加", + "createdir": "ディレクトリが存在しない場合は作成", + "outputas": "出力形式", + "breakchunks": "チャンクへ分割", + "breaklines": "行へ分割", + "filelabel": "file", + "sendError": "エラーメッセージを送信(互換モード)", + "encoding": "文字コード", + "deletelabel": "delete __file__", + "utf8String": "UTF8文字列", + "binaryBuffer": "バイナリバッファ" + }, + "action": { + "append": "ファイルへ追記", + "overwrite": "ファイルを上書き", + "delete": "ファイルを削除" + }, + "output": { + "utf8": "文字列", + "buffer": "バイナリバッファ", + "lines": "行毎のメッセージ", + "stream": "バッファのストリーム" + }, + "status": { + "wrotefile": "ファイルへ書き込みました: __file__", + "deletedfile": "ファイルを削除しました: __file__", + "appendedfile": "ファイルへ追記しました: __file__" + }, + "encoding": { + "none": "デフォルト", + "native": "ネイティブ", + "unicode": "UNICODE", + "japanese": "日本", + "chinese": "中国", + "korean": "韓国", + "taiwan": "台湾/香港", + "windows": "Windowsコードページ", + "iso": "ISOコードページ", + "ibm": "IBMコードページ", + "mac": "Macコードページ", + "koi8": "KOI8コードページ", + "misc": "その他" + }, + "errors": { + "nofilename": "ファイル名が設定されていません", + "invaliddelete": "警告: 削除が無効です。設定ダイアログで特定の削除設定を使用してください", + "deletefail": "ファイルの削除処理が失敗しました: __error__", + "writefail": "ファイルの書き込み処理が失敗しました: __error__", + "appendfail": "ファイルの追記処理が失敗しました: __error__", + "createfail": "ファイルの作成処理が失敗しました: __error__" + }, + "tip": "注釈: 「ファイル名」にフルパスを設定しない場合は、Node-REDプロセスの実行ディレクトリからの相対パスとなります。" + }, + "split": { + "split": "split", + "intro": "型に基づいて <code>msg.payload</code> を分割:", + "object": "<b>オブジェクト</b>", + "objectSend": "各key/valueペアのメッセージを送信", + "strBuff": "<b>文字列</b> / <b>バッファ</b>", + "array": "<b>配列</b>", + "splitUsing": "分割", + "splitLength": "固定長", + "stream": "メッセージのストリームとして処理", + "addname": " keyのコピー先" + }, + "join": { + "join": "join", + "mode": { + "mode": "動作", + "auto": "自動", + "merge": "列のマージ", + "reduce": "列の集約", + "custom": "手動" + }, + "combine": "結合", + "completeMessage": "メッセージ全体", + "create": "出力", + "type": { + "string": "文字列", + "array": "配列", + "buffer": "バッファ", + "object": "key/valueオブジェクト", + "merged": "結合オブジェクト" + }, + "using": "使用する値", + "key": "をキーとして使用", + "joinedUsing": "連結文字", + "send": "メッセージ送信:", + "afterCount": "指定数のメッセージパーツを受信後", + "count": "合計値", + "subsequent": "後続のメッセージ毎", + "afterTimeout": "最初のメッセージ受信からのタイムアウト後", + "seconds": "秒", + "complete": "<code>msg.complete</code> プロパティが設定されたメッセージ受信後", + "tip": "このモードでは、本ノードが <i>split</i> ノードと組となるか、 <code>msg.parts</code> プロパティが設定されたメッセージを受け取ることが前提となります。", + "too-many": "joinノード内部で保持しているメッセージが多すぎます", + "merge": { + "topics-label": "対象トピック", + "topics": "トピック", + "topic": "トピック", + "on-change": "新規トピックを受け取るとメッセージを送信する" + }, + "reduce": { + "exp": "集約式", + "exp-value": "式", + "init": "初期値", + "right": "評価を逆順に行う (最後から最初)", + "fixup": "最終調整式" + }, + "errors": { + "invalid-expr": "JSONata式が不正: __error__", + "invalid-type": "__error__ をバッファに連結できません" + } + }, + "sort": { + "sort": "sort", + "target": "対象", + "seq": "メッセージ列", + "key": "キー", + "elem": "要素の値", + "order": "順序", + "ascending": "昇順", + "descending": "降順", + "as-number": "数値として比較", + "invalid-exp": "sortノードで不正なJSONata式が指定されました: __message__", + "too-many": "sortノードの未処理メッセージの数が許容数を超えました", + "clear": "sortノードの未処理メッセージを破棄しました" + }, + "batch": { + "batch": "batch", + "mode": { + "label": "モード", + "num-msgs": "メッセージ数でグループ化", + "interval": "時間間隔でグループ化", + "concat": "列の結合" + }, + "count": { + "label": "メッセージ数", + "overlap": "オーバラップ", + "count": "数", + "invalid": "メッセージ数とオーバラップ数が不正" + }, + "interval": { + "label": "時間間隔", + "seconds": "秒", + "empty": "メッセージを受信しない場合、空のメッセージを送信" + }, + "concat": { + "topics-label": "トピック", + "topic": "トピック" + }, + "too-many": "batchノード内で保持しているメッセージが多すぎます", + "unexpected": "想定外のモード", + "no-parts": "メッセージにpartsプロパティがありません" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/05-tls.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/05-tls.html new file mode 100644 index 0000000..89b86c9 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/05-tls.html @@ -0,0 +1,19 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="tls-config"> + <p>TLS接続のためのオプション設定</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/06-httpproxy.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/06-httpproxy.html new file mode 100644 index 0000000..03beddb --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/06-httpproxy.html @@ -0,0 +1,22 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http proxy"> + <p>プロキシのためのオプション設定</p> + + <h3>詳細</h3> + <p>例外ホストに設定したホストにアクセスする際には、プロキシを使用しません。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/10-mqtt.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/10-mqtt.html new file mode 100644 index 0000000..c4a3ce0 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/10-mqtt.html @@ -0,0 +1,74 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="mqtt in"> +<p>MQTTブローカに接続し、指定したトピックのメッセージをサブスクライブ(購読)します。</p> + <h3>出力</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">文字列 | バッファ</span></dt> + <dd>バイナリバッファでない場合は文字列</dd> + <dt>topic <span class="property-type">文字列</span></dt> + <dd>MQTTのトピック。/を階層の区切りに使用する</dd> + <dt>qos <span class="property-type">数値</span> </dt> + <dd>0: 最大1度到着, 1: 一度以上到着, 2: 1度のみ到着</dd> + <dt>retain <span class="property-type">真偽値</span></dt> + <dd>真の場合、メッセージを保持。メッセージが古い値の場合があります。</dd> + </dl> + <h3>詳細</h3> + <p>購読トピックにはMQTTのワイルドカード(+: 1レベル, #: 複数レベル)を含めることができます。</p> + <p>このノードの利用のためには、MQTTブローカへの接続設定が必要です。この設定は鉛筆アイコンをクリックすることで行えます。</p> + <p>MQTT(inおよびout)ノードはブローカへの接続設定を必要に応じて共有できます。</p> +</script> + +<script type="text/x-red" data-help-name="mqtt out"> + <p>MQTTブローカに接続し、メッセージをパブリッシュ(発行)します。</p> + <h3>入力</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">文字列 | バッファ</span></dt> + <dd>発行するペイロード。プロパティが設定されていない場合には、メッセージは送信されません。空のメッセージを送信するには、プロパティに空文字列を設定します。</dd> + + <dt class="optional">topic <span class="property-type">文字列</span></dt> + <dd>発行対象のMQTTトピック</dd> + + <dt class="optional">qos <span class="property-type">数値</span></dt> + <dd>0: 最大一度到着, 1: 一度以上到着, 2: 一度のみ到着。デフォルトは0です。</dd> + + <dt class="optional">retain <span class="property-type">真偽値</span></dt> + <dd>真の場合、メッセージをブローカに保持します。デフォルトは偽です。</dd> + </dl> + <h3>詳細</h3> + <p><code>msg.payload</code>を発行するメッセージのペイロードとして用います。ペイロードがオブジェクトの場合、送信の際にJSON文字列に変換します。ペイロードがバイナリバッファの場合、そのまま送信します。</p> + <p>発行に利用するトピックはノードに設定するか、もしくは、<code>msg.topic</code>で指定します。</p> + <p>同様に、QoSとretainもノードの設定、もしくは、ノードの設定が空の場合には、それぞれ<code>msg.qos</code>および<code>msg.retain</code>で指定できます。以前ブローカに保存したトピックをクリアするには、retainフラグを設定して当該トピックに空のメッセージを発行します。</p> + <p>このノードの利用のためには、MQTTブローカへの接続設定が必要です。この設定は鉛筆アイコンをクリックすることで行えます。</p> + <p>MQTT(inおよびout)ノードはブローカへの接続設定を必要に応じて共有できます。</p> +</script> + +<script type="text/x-red" data-help-name="mqtt-broker"> + <p>MQTTブローカへの接続設定</p> + <p>ブローカへの接続設定を作成します。設定は<code>MQTT In</code>および<code>MQTT Out</code>ノードで再利用できます。</p> + <p>ノードにクライアントIDを設定しておらずセッションの初期化を設定している場合、ランダムなクライアントIDを生成します。クライアントIDを設定する場合、接続先のブローカで一意となるようにしてください。</p> + <h4>Birthメッセージ</h4> + <p>接続を確立した際に、設定したトピックに対して発行するメッセージ</p> + <h4>Closeメッセージ</h4> + <p>接続が正常に終了する前に、ノードの再デプロイまたはシャットダウンした場合に、設定したトピックに対して発行するメッセージ</p> + <h4>Willメッセージ</h4> + <p>予期せず接続が切断された場合にブローカが発行するメッセージ</p> + <h4>WebSocket</h4> + <p>WebSocketによる接続を行うように設定できます。WebSocketを利用するには、サーバフィールドに接続先のURIを完全な形式で記述します。以下に例を示します。</p> + <pre>ws://example.com:4000/mqtt</pre> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/21-httpin.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/21-httpin.html new file mode 100644 index 0000000..3f9ce07 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/21-httpin.html @@ -0,0 +1,81 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http in"> + <p>HTTPエンドポイントを作成し、Webサービスを構成します。</p> + <h3>出力</h3> + <dl class="message-properties"> + <dt>payload</dt> + <dd>GETリクエストの場合、クエリパラメータからなるオブジェクト。それ以外の場合、HTTPリクエストの本体を指します。</dd> + <dt>req<span class="property-type">オブジェクト</span></dt> + <dd>HTTPリクエストオブジェクト。オブジェクトはリクエストの情報に関する複数のプロパティを含みます。 + <ul> + <li><code>body</code> - リクエスト本体。形式はリクエストに依存します</li> + <li><code>headers</code> - HTTPリクエストヘッダを含むオブジェクト</li> + <li><code>query</code> - クエリパラメータを含むオブジェクト</li> + <li><code>params</code> - ルーティングパラメータを含むオブジェクト</li> + <li><code>cookies</code> - リクエストのクッキーを含むオブジェクト</li> + <li><code>files</code> - POSTリクエストでファイルのアップロードが設定で有効化されている場合、アップロード対象のファイル</li> + </ul> + </dd> + <dt>res<span class="property-type">オブジェクト</span></dt> + <dd>HTTPレスポンスオブジェクト。このプロパティを直接利用することは推奨しません。リクエストの処理方法については<code>HTTP Response</code>ノードのドキュメントを参照してください。このプロパティはresponseノードに渡すメッセージに付けたままとしてください。</dd> + </dl> + <h3>詳細</h3> + <p>このノードは設定で指定したパスとリクエスト種別でリクエストを待ち受けます。パス指定は完全に指定する形式(例: <code>/user</code>)、もしくは、任意の値を受け付ける名前付きパラメータを含む形式(例: <code>/user/:name</code>)のいずれでも構いません。名前付きパラメータを指定する場合、リクエストで指定された実際の値は<code>msg.req.params</code>から参照できます。</p> + <p>POSTやPUTのようにリクエストボディを含むリクエストの場合、リクエストの内容は<code>msg.payload</code>で参照できます。</p> + <p>リクエストの要素タイプが識別可能な場合には、リクエストボディを適切な形式に変換します。例えば、<code>application/json</code>はJavaScriptオブジェクトに変換します。</p> + <p><b>注:</b> このノードはリクエストに対するレスポンスの送信は行いません。リクエストを処理するにはフローにHTTP Responseノードを含めてください。</p> +</script> + +<script type="text/x-red" data-help-name="http response"> + <p>HTTP Inノードで受け付けたリクエストに対するレスポンスを送り返します。</p> + + <h3>入力</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">文字列</span></dt> + <dd>レスポンス本体</dd> + <dt class="optional">statusCode <span class="property-type">数値</span></dt> + <dd>設定するとレスポンスのステータスコードとします。デフォルト: 200</dd> + <dt class="optional">headers <span class="property-type">オブジェクト</span></dt> + <dd>設定するとレスポンスのHTTPヘッダとします</dd> + <dt class="optional">cookies <span class="property-type">オブジェクト</span></dt> + <dd>設定するとクッキーを設定もしくは削除するために使用します</dd> + </dl> + <h3>詳細</h3> + <p><code>statusCode</code>と<code>headers</code>はノードの設定で指定することも可能です。ノードの設定でプロパティを指定した場合には、対応するメッセージプロパティは使用しません。</p> + <h4>クッキーの処理</h4> + <p><code>cookies</code>はキー/値の組からなるオブジェクトとします。値にはデフォルトオプションを使ってクッキーの値として設定する文字列、もしくは、オプションを含むオブジェクトを指定できます。</p> + <p>以下の例では2つのクッキーを設定しています。1つ目は<code>name</code>でその値は<code>nick</code>、2つ目は<code>session</code>で値は<code>1234</code>、有効期限として15分を指定しています。</p> + <pre> +msg.cookies = { + name: 'nick', + session: { + value: '1234', + maxAge: 900000 + } +}</pre> + <p>有効なオプションには以下があります。</p> + <ul> + <li><code>domain</code> - (文字列) クッキーのドメイン指定</li> + <li><code>expires</code> - (日時) GMT表現での有効期限。未指定もしくは0を指定した場合、セッション終了まで有効</li> + <li><code>maxAge</code> - (文字列) 現時刻からの経過ミリ秒で表した有効期限</li> + <li><code>path</code> - (文字列) クッキーのパス。デフォルトは「/」</li> + <li><code>value</code> - (文字列) クッキーの値</li> + </ul> + <p>クッキーを削除するには、<code>value</code>に<code>null</code>を設定します。</p> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/21-httprequest.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/21-httprequest.html new file mode 100644 index 0000000..e87bb75 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/21-httprequest.html @@ -0,0 +1,77 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http request"> + <p>HTTPリクエストを送信し、レスポンスを返します。</p> + + <h3>入力</h3> + <dl class="message-properties"> + <dt class="optional">url <span class="property-type">文字列</span></dt> + <dd>ノードの設定で指定していない場合、このプロパティでリクエストのurlを設定します。</dd> + <dt class="optional">method <span class="property-type">文字列</span></dt> + <dd>ノードの設定で指定していない場合、このプロパティでリクエストに用いるHTTPメソッドを設定します。<code>GET</code>, <code>PUT</code>, <code>POST</code>, <code>PATCH</code>, <code>DELETE</code>のいずれかを指定してください。</dd> + <dt class="optional">headers <span class="property-type">オブジェクト</span></dt> + <dd>リクエストのHTTPヘッダを指定します。</dd> + <dt class="optional">cookies <span class="property-type">オブジェクト</span></dt> + <dd>設定すると、リクエストと共にクッキーを送ることができます。</dd> + <dt class="optional">payload</dt> + <dd>リクエストボディとして送るデータ</dd> + <dt class="optional">rejectUnauthorized</dt> + <dd><code>false</code>をセットすると、自己署名証明書を使用するhttpsサイトへのリクエストを許可します。</dd> + <dt class="optional">followRedirects</dt> + <dd><code>false</code>をセットすると、リダイレクトを行いません。デフォルトは<code>true</code>です。</dd> + <dt class="optional">requestTimeout</dt> + <dd>正のミリ秒数をセットすると、 グローバルに設定された<code>httpRequestTimeout</code>パラメータを上書きします。</dd> + </dl> + <h3>出力</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">文字列 | オブジェクト | バッファ</span></dt> + <dd>レスポンスボディ。返却するボディデータを文字列、JSON文字列として解釈した結果、バイナリバッファのままのいずれにするかを、ノード設定により指定できます。</dd> + <dt>statusCode <span class="property-type">数値</span></dt> + <dd>レスポンスのステータスコード、もしくは、リクエストが完了しなかった場合のエラーコード。</dd> + <dt>headers <span class="property-type">オブジェクト</span></dt> + <dd>レスポンスヘッダを含むオブジェクト</dd> + <dt>responseUrl <span class="property-type">文字列</span></dt> + <dd>リクエストの処理時にリダイレクトが発生した場合、このプロパティが最後にリダイレクトされたURLを表します。リダイレクトが起こらなかった場合、最初リクエストのURLを表します。</dd> + <dt>responseCookies <span class="property-type">オブジェクト</span></dt> + <dd>レスポンスがクッキーを含む場合、このプロパティは各クッキーの名前/値を含むオブジェクトを表します。</dd> + <dt>redirectList <span class="property-type">配列</span></dt> + <dd>リクエストが一回以上リダイレクトされた場合は、このプロパティに情報が蓄積されます。`location`は、リダイレクト先を示します。`cookies`は、リダイレクト元から返されたクッキー情報です。</dd> + </dl> + <h3>詳細</h3> + <p>ノードの設定でurlプロパティを指定する場合、<a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache形式</a>のタグを含めることができます。これにより、URLを入力メッセージの値から構成することができます。例えば、urlが<code>example.com/{{{topic}}}</code>の場合、<code>msg.topic</code>の値による置き換えを自動的に行います。{{{...}}}表記を使うと、/、&といった文字をmustacheがエスケープするのを抑止できます。</p> + <p><b>注</b>: proxyサーバを利用している場合、環境変数<code>http_proxy=...</code>を設定してNode-REDを再起動するか、あるいはノードの設定でプロキシを設定してください。もしノードの設定でプロキシを設定した場合、環境変数よりもこちらの設定が優先されます。</p> + <h4>複数のHTTPリクエストノードの利用</h4> + <p>同一フローで本ノードを複数利用するためには、<code>msg.headers</code>プロパティの扱いに注意しなくてはなりません。例えば、最初のノードがレスポンスヘッダにこのプロパティを設定し、次のノードがこのプロパティをリクエストヘッダに利用するというのは一般的には期待する動作ではありません。<code>msg.headers</code>プロパティをノード間で変更しないままとすると、2つ目のノードで無視されることになります。カスタムヘッダを設定するためには、<code>msg.headers</code>をまず削除もしくは空のオブジェクト<code>{}</code>にリセットします。 + <h4>クッキーの扱い</h4> + <p>ノードに<code>cookies</code>プロパティを渡す場合、その値はキー/値ペアからなるオブジェクトとしてください。値にはクッキーの値として設定する文字列、もしくは、単一の<code>value</code>プロパティを含むオブジェクトを指定できます。</p> + <p>リクエストに対して返却されたクッキーは<code>responseCookies</code>プロパティに格納されます。</p> + <h4>要素タイプの扱い</h4> + <p><code>msg.payload</code>がオブジェクトの場合、リクエストの要素タイプを<code>msg.payload</code>に自動的に設定し、ボディーをJSONに変換します。</p> + <p>リクエストをフォームデータにエンコードするには、<code>msg.headers["content-type"]</code>を<code>application/x-www-form-urlencoded</code>に設定します。</p> + <h4>ファイルのアップロード</h4> + <p><code>msg.headers["content-type"]</code>に<code>multipart/form-data</code>を指定するとファイルをアップロードできます。この際、ノードの<code>msg.payload</code>に渡されるデータは以下の構造を持ったオブジェクトとします:</p> + <pre><code>{ + "KEY": { + "value": FILE_CONTENTS, + "options": { + "filename": "FILENAME" + } + } +}</code></pre> + <p><code>KEY</code>, <code>FILE_CONTENTS</code> および <code>FILENAME</code>には適切な値を設定してください。</p> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/22-websocket.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/22-websocket.html new file mode 100644 index 0000000..13dacd7 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/22-websocket.html @@ -0,0 +1,36 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="websocket in"> + <p>WebSocket入力ノード</p> + <p>デフォルトでは、WebSocketにより受信したデータは<code>msg.payload</code>に格納します。ソケットはJSON形式の文字列を待ち受けるように設定することができます。JSON形式の文字列を受け付けると、オブジェクトへの変換を行い、メッセージ全体として送信します。</p> +</script> + +<script type="text/x-red" data-help-name="websocket out"> + <p>WebSocket出力ノード</p> + <p>デフォルトでは、<code>msg.payload</code>をWebSocket経由で送信します。ソケットは<code>msg</code>全体をJSON文字列にエンコードしてWebSocketを介して送信することもできます。</p> + + <p>このノードが受信したメッセージがWebSocket Inノードが生成したものである場合、メッセージはフローを起動したクライアントに送り返されます。それ以外の場合、メッセージは接続している全てのクライアントにブロードキャストされます。</p> + <p>WebSocket Inノードが生成したメッセージをブロードキャストしたい場合には、フロー中で<code>msg._session</code>プロパティを削除します。</p> +</script> + +<script type="text/x-red" data-help-name="websocket-listener"> + <p>この設定ノードはパスを指定してWebSocketサーバのエンドポイントを作成します。</p> +</script> + +<script type="text/x-red" data-help-name="websocket-client"> + <p>この設定ノードは指定したURLにWebSocketクライアントを接続します。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/31-tcpin.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/31-tcpin.html new file mode 100644 index 0000000..efe82cb --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/31-tcpin.html @@ -0,0 +1,35 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="tcp in"> + <p>TCPからの入力を行います。リモートTCPポートに接続するか、外部からのコネクションを受け付けます。</p> + <p><b>注: </b>1024番より小さな番号のポートをアクセスするにはrootもしくはadministrator権限が必要なシステムもあります。</p> +</script> + +<script type="text/x-red" data-help-name="tcp out"> + <p>TCPへの出力を行います。リモートTCPポートへ接続、外部からのコネクションの受け付け、もしくは、TCP Inノードで受け付けたメッセージへのリプライを行います。</p> + <p><code>msg.payload</code>のみが送信対象となります。</p> + <p><code>msg.payload</code>がバイナリデータをBase64エンコーディングの文字列に変換したものの場合、Base64デコードオプションを指定するとデータをバイナリに変換して送信します。</p> + <p><code>msg._session</code>が存在しない場合、接続している<b>全ての</b>クライアントに送信します。</p> + <p><b>注: </b>1024番より小さな番号のポートをアクセスするにはrootもしくはadministrator権限が必要なシステムもあります。</p> +</script> + +<script type="text/x-red" data-help-name="tcp request"> + <p>シンプルなTCPリクエストノード。<code>msg.payload</code>をサーバのTCPポートに送信し、レスポンスを待ちます。</p> + <p>サーバに接続、"リクエスト"送信、"レスポンス"受信を行います。固定長の文字数、指定文字へのマッチ、最初のリプライの到着から指定した時間待つ、データの到着待ち、データ送信を行いリプライを待たず接続を即時解除、などから動作を選択できます。</p> + <p>レスポンスはバッファ形式で<code>msg.payload</code>に出力されます。文字列として扱いには、.toString()を使用してください。</p> + <p>TCPホストのポート番号設定を空にした場合、<code>msg.host</code>および<code>msg.port</code>プロパティを設定しなくてはなりません。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/32-udp.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/32-udp.html new file mode 100644 index 0000000..ec07a86 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/network/32-udp.html @@ -0,0 +1,28 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="udp in"> + <p>UDP入力ノード。<code>msg.payload</code>にバッファ、文字列、もしくは、Base64エンコーディング文字列を生成します。マルチキャストをサポートしています。</p> + <p><code>msg.ip</code>と<code>msg.port</code>に受信したメッセージのIPアドレスとポートを設定します。</p> + <p><b>注</b>: 1024番より小さな番号のポートへのアクセス、ブロードキャストを行うにはrootもしくはadministrator権限が必要なシステムもあります。</p> +</script> + +<script type="text/x-red" data-help-name="udp out"> + <p><code>msg.payload</code>を指定したUDPのホストとポートに送信します。マルチキャストをサポートします。</p> + <p><code>msg.ip</code>と<code>msg.port</code>に接続先を設定できますが、ノード設定の方が優先されます。</p> + <p>ブロードキャストを行うには、アドレスをローカルブロードキャストIPアドレスに設定するか、グローバルブロードキャストアドレスである255.255.255.255を試してください。</p> + <p><b>注</b>: 1024番より小さな番号のポートへのアクセス、ブロードキャストを行うにはrootもしくはadministrator権限が必要なシステムもあります。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/parsers/70-CSV.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/parsers/70-CSV.html new file mode 100644 index 0000000..101ef39 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/parsers/70-CSV.html @@ -0,0 +1,44 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="csv"> + <p>CSV形式の文字列とそのJavaScriptオブジェクト表現の間で双方向の変換を行います。</p> + <h3>入力</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">オブジェクト | 配列 | 文字列</span></dt> + <dd>JavaScriptオブジェクト、配列、CSV文字列のいずれか</dd> + </dl> + <h3>出力</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">オブジェクト | 配列 | 文字列</span></dt> + <dd> + <ul> + <li>入力が文字列の場合、CSVとして解釈し、CSVの各行をキー/バリューとしたJavaScriptオブジェクトを生成します。 + 各行毎にメッセージを送信するかオブジェクトの配列からなる一つのメッセージを送信するかを選択できます。</li> + <li>入力がJavaScriptオブジェクトの場合、CSV文字列への変換を行います。</li> + <li>入力が基本型の配列の場合、1行のCSV文字列へ変換します。</li> + <li>入力が配列の配列、もしくは、オブジェクトの配列の場合、複数行のCSV文字列へ変換します。</li> + </ul> + </dd> + </dl> + <h3>詳細</h3> + <p>「列名」にカラム名のリストを指定することができます。CSVからオブジェクトに変換を行う際、カラム名をプロパティ名として使用します。「列名」の代わりに、CSVデータの1行目にカラム名を含めることもできます。</p> + <p>CSVへの変換を行う際には、オブジェクトから取り出すべきプロパティとその順序を「列名」を参照して決めます。</p> + <p>入力が配列の場合には、「列名」はカラム名を表す行の出力指定がされた場合だけ用います。</p> + <p><code>parts</code>プロパティが正しく設定されている場合、メッセージ列を入力として受け付けます。</p> + <p>CSVを複数のメッセージに変換して出力する場合、出力がメッセージ列となるよう<code>parts</code>プロパティを設定します。</p> + <p><b>注:</b> カンマ以外の区切り文字を設定した場合であっても、「列名」はカンマ区切りとしてください。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/parsers/70-HTML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/parsers/70-HTML.html new file mode 100644 index 0000000..eb7b00d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/parsers/70-HTML.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="html"> + <p><code>msg.payload</code>に格納したHTMLドキュメントからCSSセレクタを使用して要素を取り出します。</p> + <h3>入力</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">文字列</span></dt> + <dd>要素を取り出すHTML文字列</dd> + <dt class="optional">select <span class="property-type">文字列</span></dt> + <dd>編集パネルでセレクタを指定していない場合、メッセージのプロパティとして設定できます</dd> + </dl> + <h3>出力</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">配列 | 文字列</span></dt> + <dd>結果は、ペイロードにマッチした要素の配列を含む単一メッセージ、もしくは、マッチした要素毎のメッセージのいずれかを選択できます。複数メッセージを送信する場合、メッセージには<code>parts</code>を設定します</dd> + </dl> + <h3>詳細</h3> + <p>このノードはCSSおよびjQueryセレクタの組み合わせをサポートします。利用可能な構文の詳細については<a href="https://github.com/fb55/CSSselect#user-content-supported-selectors" target="_blank">css-select documentation</a>を参照してください。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/parsers/70-JSON.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/parsers/70-JSON.html new file mode 100644 index 0000000..8059578 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/parsers/70-JSON.html @@ -0,0 +1,43 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="json"> + <p>JSON文字列とJavaScriptオブジェクトとの間で相互変換を行います。</p> + <h3>入力</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">オブジェクト | 文字列</span></dt> + <dd>JavaScriptオブジェクトもしくはJSON文字列</dd> + <dt>schema<span class="property-type">オブジェクト</span></dt> + <dd>JSONの検証に利用するJSONスキーマ。設定されていない場合は検証を行いません。</dd> + </dl> + <h3>出力</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">オブジェクト | 文字列</span></dt> + <dd> + <ul> + <li>入力が文字列の場合、JSONとして解釈し、JavaScriptオブジェクトに変換します。</li> + <li>入力がJavaScriptオブジェクトの場合、JSON文字列に変換します。JSON文字列は整形することも可能です。</li> + </ul> + </dd> + <dt>schemaError<span class="property-type">配列</span></dt> + <dd>JSONの検証でエラーが発生した場合、Catchノードを利用し、エラーを配列として<code>schemaError</code>プロパティから取得することができます。</dd> + </dl> + <h3>詳細</h3> + <p>デフォルトの変換対象は<code>msg.payload</code>ですが、他のメッセージプロパティを変換対象とすることも可能です。</p> + <p>双方向の変換を自動選択するのではなく、特定の変換のみ行うように設定できます。この機能は、例えば、<code>HTTP In</code>ノードに対するリクエストがcontent-typeを正しく設定していない場合であっても、JSONノードによる変換結果がJavaScriptオブジェクトであることを保証するために利用します。</p> + <p>JSON文字列への変換が指定されている場合、受信した文字列に対してさらなるチェックは行いません。すなわち、文字列がJSONとして正しいかどうかの検査や、整形オプションを指定していたとしても整形処理を実施しません。</p> + <p>JSONスキーマの詳細については、<a href="http://json-schema.org/latest/json-schema-validation.html">こちら</a>を参照してください。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/parsers/70-XML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/parsers/70-XML.html new file mode 100644 index 0000000..240fb5f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/parsers/70-XML.html @@ -0,0 +1,49 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="xml"> + <p>XML文字列とJavaScriptオブジェクトとの間で相互変換を行います。</p> + <h3>入力</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">オブジェクト | 文字列</span></dt> + <dd>JavaScriptオブジェクトもしくはXML文字列</dd> + </dl> + <h3>出力</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">オブジェクト | 文字列</span></dt> + <dd> + <ul> + <li>入力が文字列の場合、XMLとして解釈し、JavaScriptオブジェクトに変換します。</li> + <li>入力がJavaScriptオブジェクトの場合、XML文字列に変換します。</li> + </ul> + </dd> + <dt class="optional">options <span class="property-type">オブジェクト</span></dt> + <dd>内部で用いているXMLへの変換ライブラリに対してオプションを渡すことができます。詳しくは<a href="https://github.com/Leonidas-from-XIV/node-xml2js/blob/master/README.md#options" target="_blank">the xml2js docs</a>を参照してください。</dd> + </dl> + <h3>詳細</h3> + <p>XMLとオブジェクトの間での変換を行う場合、デフォルトでは、XML属性は<code>$</code>という名称のプロパティに追加します。 + テキストの内容は<code>_</code>という名前のプロパティに追加します。これらのプロパティ名はノードの設定で変更できます。</p> + <p>例として以下のXMLの変換結果を示します。</p> + <pre>&lt;p class="tag"&gt;Hello World&lt;/p&gt;</pre> + <pre>{ + "p": { + "$": { + "class": "tag" + }, + "_": "Hello World" + } +}</pre> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/parsers/70-YAML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/parsers/70-YAML.html new file mode 100644 index 0000000..6dd8d28 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/parsers/70-YAML.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="yaml"> + <p>YAML形式の文字列とJavaScriptオブジェクトの間で相互変換を行います。</p> + <h3>入力</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">オブジェクト | 文字列</span></dt> + <dd>JavaScriptオブジェクトもしくはYAML形式文字列</dd> + </dl> + <h3>出力</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">オブジェクト | 文字列</span></dt> + <dd> + <ul> + <li>入力がYAML形式の文字列の場合、JavaScriptオブジェクトに変換します。</li> + <li>入力がJavaScriptオブジェクトの場合、YAML形式の文字列に変換します。</li> + </ul> + </dd> + </dl> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/sequence/17-split.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/sequence/17-split.html new file mode 100644 index 0000000..dbe89d7 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/sequence/17-split.html @@ -0,0 +1,137 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/html" data-help-name="split"> + <p>メッセージをメッセージ列に分割します。</p> + + <h3>入力</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">オブジェクト | 文字列 | 配列 | バッファ</span></dt> + <dd><code>msg.payload</code>の型によってノードの動作が異なります。 + <ul> + <li><b>文字列</b>/<b>バッファ</b> - 指定された文字列 (デフォルト: <code>\n</code>)、バッファ列、もしくは固定の長さによりメッセージを分割します。</li> + <li><b>配列</b> - メッセージを配列要素毎もしくは固定の長さの配列に分割します。</li> + <li><b>オブジェクト</b> - キー/値の各組に対してメッセージを送信します。</li> + </ul> + </dd> + </dl> + <h3>出力</h3> + <dl class="message-properties"> + <dt>parts<span class="property-type">オブジェクト</span></dt> + <dd>元のメッセージをどのように分割したかに関する情報をこのプロパティに保持します。例えば、<b>join</b>ノードに渡すことで、メッセージ列を一つのメッセージに再構成することができます。<code>parts</code>プロパティは次のプロパティを含みます。 + <ul> + <li><code>id</code> - メッセージグループの識別子</li> + <li><code>index</code> - グループ内の位置</li> + <li><code>count</code> - 既知の場合、グループ内のメッセージ数を設定。下記「ストリームモード」を参照</li> + <li><code>type</code> - メッセージの型 - 文字列/配列/オブジェクト/バッファ</li> + <li><code>ch</code> - 文字列もしくはバッファの場合、メッセージを分割するのに用いた文字列もしくはバイト配列</li> + <li><code>key</code> - オブジェクトの場合、メッセージ生成元のキー。 +ノードの設定によりキーを<code>msg.topic</code>など他のメッセージプロパティにコピーすることもできます。</li> + <li><code>len</code> - メッセージを固定の長さで分割した場合の長さ。</li> + </ul> + </dd> + </dl> + <h3>詳細</h3> + <p>このノードは、メッセージ列を構成するメッセージに対して共通処理を行い、<b>join</b>ノードで一つのメッセージに纏めるようなフローを作成する際に有用です。</p> + <p><code>msg.parts</code>プロパティを用いて元のメッセージとメッセージ列との対応関係を記憶します。</p> + <h4>ストリームモード</h4> + <p>このノードはメッセージ列を再構成して送信する際にも有用です。例えば、改行終端のコマンドを送信するようなシリアルデバイスでは、メッセージの最後のコマンド部分が途切れたメッセージを送出する場合があります。「ストリームモード」を用いることで、完結した個別コマンドにメッセージを分割することができます。入力メッセージの最後に未完部分がある場合、<b>split</b>ノードは未完部分を記憶しておいて、次に受信したメッセージの先頭に付加します。</p> + <p>このモードで処理する際には、メッセージ数を予め知ることができないため、<code>msg.parts.count</code>プロパティは設定されません。従って、<b>join</b>ノードの「自動モード」と組み合わせることはできません。</p> +</script> + +<script type="text/html" data-help-name="join"> + <p>メッセージ列を結合して一つのメッセージにします。</p> + <p>メッセージの結合には次の3つのモードが利用できます。</p> + <dl> + <dt>自動</dt> + <dd><b>split</b>ノードと組み合わせると、splitと逆にメッセージを結合する処理を行います。</dd> + <dt>手動</dt> + <dd>メッセージ列をさまざまな方法で結合します。</dd> + <dt>列の集約</dt> + <dd>メッセージ列に対して指定した式を適用し、1つのメッセージに集約します。</dd> + </dl> + <h3>入力</h3> + <dl class="message-properties"> + <dt class="optional">parts<span class="property-type">オブジェクト</span></dt> + <dd>自動的にメッセージ列を結合するには、全メッセージがこのプロパティを持っていなければなりません。<b>split</b>ノードでこのプロパティを生成することが可能ですが、独自に生成しても構いません。<code>parts</code>プロパティは以下のプロパティを含みます。 + <ul> + <li><code>id</code> - メッセージグループの識別子</li> + <li><code>index</code> - グループ内の順番</li> + <li><code>count</code> - グループを構成するメッセージの数</li> + <li><code>type</code> - メッセージの型 - string/array/object/buffer</li> + <li><code>ch</code> - 文字列もしくはバッファの場合、メッセージを分割するのに用いた文字列もしくはバイト配列</li> + <li><code>key</code> - オブジェクトの場合、メッセージ生成元のキー</li> + <li><code>len</code> - メッセージを固定の長さで分割した場合の長さ</li> + </ul> + </dd> + <dt class="optional">complete</dt> + <dd>設定されている場合、本ノードはペイロードを追加し、保持しているメッセージを送信します。ペイロードを追加したくない場合は、msgから削除してください。</dd> + </dl> + <h3>詳細</h3> + + <h4>自動モード</h4> + <p>自動モードでは、入力メッセージの<code>parts</code>プロパティを用いてメッセージ列を結合します。このモードは<b>split</b>ノードの処理の逆を自動的に行います。</p> + + <h4>手動モード</h4> + <p>手動モードでは、メッセージ列をさまざまな結果に結合できます。</p> + <ul> + <li><b>文字列</b>もしくは<b>バッファ</b> - 指定した文字列もしくはバッファ値を区切りとして各メッセージの指定プロパティを結合</li> + <li><b>配列</b> - 指定プロパティもしくはメッセージ全体を要素とする配列</li> + <li><b>key/valueオブジェクト</b> - 入力メッセージの指定プロパティの値をキーとして、プロパティ値をストアしたオブジェクト</li> + <li><b>統合オブジェクト</b> - 各メッセージのプロパティを一つのオブジェクトに統合</li> + </ul> + <p>出力メッセージのその他のプロパティはメッセージを送信する直前のメッセージをコピーします。</p> + <p>「<i>合計値</i>」には出力メッセージを送信する前に受信すべきメッセージ数を指定します。オブジェクト出力の場合、この合計値に達すると後続メッセージの到着毎にメッセージを出力するように設定することもできます。</p> + <p>「<i>秒</i>」には新規メッセージを送信するまでの経過時間を設定します。</p> + <p><code>msg.complete</code>プロパティを設定したメッセージを受信すると、出力メッセージを送信します。この時、メッセージ列の数をリセットします。</p> + <p><code>msg.reset</code>プロパティを設定したメッセージを受信すると、部分的に受信済みのメッセージを破棄します。これらのメッセージは送信されません。この時、メッセージ列の数をリセットします。</p> + + <h4>列の集約モード</h4> + <p>列の集約モードを選択すると、メッセージ列を構成する各々のメッセージに対して式を適用し、集約した値を用いて一つのメッセージを構成します。</p> + <dl class="message-properties"> + <dt>初期値</dt> + <dd> + 集約の初期値(<code>$A</code>) + </dd> + <dt>集約式</dt> + <dd>メッセージグループを構成する各メッセージに適用するJSONata式。 + 式の評価結果は次回の呼び出しの際に集約値として渡します。 + <ul> + <li><code>$A</code> 集約値</li> + <li><code>$I</code> グループ内のメッセージの順番</li> + <li><code>$N</code> グループ内のメッセージ数</li> + </ul> + </dd> + <dt>最終調整式</dt> + <dd>メッセージグループの集約が完了した後で適用されるJSONata式。任意で指定可能です。式中では以下の特殊変数を参照できます。 + <ul> + <li><code>$A</code> 集約値</li> + <li><code>$N</code> グループ内のメッセージ数</li> + </ul> + </dd> + <p>メッセージグループのメッセージに対し、デフォルトでは集約式は最初のメッセージから最後のメッセージに対し順に適用します。指定により適用を逆順にすることも可能です。</p> + </dl> + <p><b>例:</b> 以下の設定で、数値のメッセージ列に対して平均値を計算します。 + <ul> + <li><b>集約式</b>: <code>$A+payload</code></li> + <li><b>初期値</b>: <code>0</code></li> + <li><b>最終調整式</b>: <code>$A/$N</code></li> + </ul> + </p> + + <h4>メッセージの蓄積</h4> + <p>このノードの処理ではメッセージ列の処理のためメッセージを内部に蓄積します。<code>nodeMessageBufferMaxLength</code>を指定することで蓄積するメッセージの最大値を制限することができます。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/sequence/18-sort.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/sequence/18-sort.html new file mode 100644 index 0000000..8bb6b34 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/sequence/18-sort.html @@ -0,0 +1,40 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="sort"> + <p>メッセージ列もしくは配列型のペイロードをソートします。</p> + <p><b>split</b>ノードと組み合わせてメッセージの並べ替えを行うことができます。</p> + <p>ソート順序は以下が指定可能です。</p> + <ul> + <li><b>昇順</b></li> + <li><b>降順</b></li> + </ul> + <p>数値による並べ替えを選択することもできます。</p> + <p>メッセージの並べ替えを行うためのソートキーは<code>payload</code>プロパティもしくはJSONata式が利用できます。配列型ペイロードのソートキーには、要素値もしくはJSONata式が利用できます。</p> + <p>sortノードの処理では受信したメッセージが<code>msg.parts</code>プロパティを持っていることを想定しています。splitノードでこのプロパティを生成することが可能ですが、独自に生成しても構いません。<code>parts</code>プロパティは以下のプロパティを含みます。</p> + <p> + <ul> + <li><code>id</code> - メッセージグループの識別子</li> + <li><code>index</code> - グループ内の順番</li> + <li><code>count</code> - グループを構成するメッセージの数</li> + </ul> + </p> + <p><b>注:</b> このノードの処理ではメッセージを内部に蓄積します。以下により蓄積するメッセージの最大数を指定することで、予期しないメモリ使用量の増大を防ぐことができます。デフォルトではメッセージ数を制限しません。 + <ul> + <li><b>settings.js</b>の<code>nodeMessageBufferMaxLength</code>プロパティ</li> + </ul> + </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/sequence/19-batch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/sequence/19-batch.html new file mode 100644 index 0000000..41cef36 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/sequence/19-batch.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="batch"> + <p>指定したルールによりメッセージ列を生成します。</p> + <h3>詳細</h3> + <p>メッセージ列の生成には以下の3つのモードが利用できます。</p> + <dl> + <dt>入力メッセージ数でグループ化</dt> + <dd>入力メッセージを指定した長さのメッセージ列にグループ化します。メッセージ列の最後の部分を次のメッセージ列の先頭で繰り返すメッセージ数を「<b>オーバラップ</b>」で指定できます。</dd> + + <dt>入力間隔(秒)でグループ化</dt> + <dd>指定時間間隔内に受信した入力メッセージをメッセージ列にグループ化します。指定した時間内にメッセージを受信しない場合に空のメッセージを送信するように設定することもできます。</dd> + + <dt>メッセージグループの結合</dt> + <dd>入力メッセージ列を結合し、1つのメッセージ列にします。メッセージ列の識別のため、各メッセージは<code>msg.topic</code>プロパティと<code>msg.parts</code>プロパティを持っていなければなりません。メッセージ列の結合順は、<code>topic</code>値のリストとしてbatchノードに指定します。 + </dd> + </dl> + <h4>メッセージの蓄積</h4> + <p>このノードの処理ではメッセージ列の処理のためメッセージを内部に蓄積します。<b>settings.js</b>の<code>nodeMessageBufferMaxLength</code>を指定することで蓄積するメッセージの最大値を制限することができます。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/storage/10-file.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/storage/10-file.html new file mode 100644 index 0000000..21d4af9 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/storage/10-file.html @@ -0,0 +1,55 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/html" data-help-name="file"> + <p><code>msg.payload</code>をファイルに書き出します。書き出しは、ファイルの最後に追記もしくは既存の内容の置き換えを選択できます。この他、ファイルの削除を行うことも可能です。</p> + <h3>入力</h3> + <dl class="message-properties"> + <dt class="optional">filename <span class="property-type">文字列</span></dt> + <dd>対象ファイル名をノードに設定していない場合、このプロパティでファイルを指定できます</dd> + </dl> + <h3>出力</h3> + <p>書き込みの完了時、入力メッセージを出力端子に送出します。</p> + <h3>詳細</h3> + <p>入力メッセージのペイロードをファイルの最後に追記します。改行(\n)を各データの最後に追加することもできます。</p> + <p><code>msg.filename</code>を使う場合、書き込みを行う毎にファイルをクローズします。より良い性能を得るためにはファイル名をノードに設定してください。</p> + <p>追記を行う代わりに、ファイル全体を上書きするように設定することもできます。例えば、画像のようなバイナリデータをファイルに書き出す場合は、このオプションを指定し、改行を追記するオプションを指定しないようにします。</p> + <p>ファイル出力の際のエンコーディングは、エンコーディングリストから選択できます。</p> + <p>この他、ファイルの削除を行うことも可能です。</p> +</script> + +<script type="text/html" data-help-name="file in"> + <p>ファイルの内容を文字列もしくはバイナリバッファとして読み出します。</p> + <h3>入力</h3> + <dl class="message-properties"> + <dt class="optional">filename <span class="property-type">文字列</span></dt> + <dd>読み出し対象のファイル名をノードに設定していない場合、このプロパティでファイルを指定できます</dd> + </dl> + <h3>出力</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">文字列 | バッファ</span></dt> + <dd>ファイルの内容を文字列もしくはバッファで表現します</dd> + <dt class="optional">filename <span class="property-type">文字列</span></dt> + <dd>読み出し対象のファイル名をノードに設定していない場合、このプロパティでファイルを指定します</dd> + </dl> + <h3>詳細</h3> + <p>ファイルネームは絶対パスでの指定を推奨します。絶対パスを指定しない場合は、Node-REDプロセスのワーキングディレクトリからの相対パスとして扱います。</p> + <p>Windowsではパスの区切り文字を(例えば、<code>\\ユーザー\\名前</code>のように)エスケープする必要があります。</p> + <p>テキストファイルの場合、行毎に分割して各々メッセージを送信することができます。また、バイナリファイルの場合、小さな塊のバッファに分割して送信できます。バッファの分割単位はオペレーティングシステム依存ですが、一般に64k(Linux/Mac)もしくは41k(Windows)です。</p> + <p>複数のメッセージに分割する場合、各メッセージには<code>parts</code>プロパティが設定され、メッセージ列を構成します。</p> + <p>出力形式が文字列の場合、入力データのエンコーディングをエンコーディングリストから選択できます。</p> + <p>エラーはcatchノードで補足して処理することを推奨します。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/storage/23-watch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/storage/23-watch.html new file mode 100644 index 0000000..45f658c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ja/storage/23-watch.html @@ -0,0 +1,25 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="watch"> + <p>ディレクトリもしくはファイルの変化を検知します。</p> + <p>カンマ区切りでディレクトリおよびファイルのリストを指定します。空白を含む場合は、引用符で"..."のように囲んでください。</p> + <p>Windowsでは、2重バックスラッシュ\\をディレクトリ名に使用します。</p> + <p>実際に変化したファイルのフルパス名を<code>msg.payload</code>に、検知対象リストの文字列を<code>msg.topic</code>に返します。</p> + <p><code>msg.file</code>は変化したファイルのファイル名を表します。<code>msg.type</code>は変化した対象の種別(<i>file</i>もしくは<i>directory</i>)を、<code>msg.size</code>はファイルサイズ(バイト数)を表します。</p> + <p>Linuxではファイルとして表されるもの<i>全て</i>が、検知対象にできます。</p> + <p><b>注: </b>検知対象のディレクトリもしくはファイルは存在していなくてはなりません。対象ファイルもしくはディレクトリが削除された場合、再作成されても検知対象から外れたままです。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/20-inject.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/20-inject.html new file mode 100644 index 0000000..254b542 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/20-inject.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="inject"> +<p>수동, 혹은 일정간격으로 메세지를 플로우에 주입합니다. 메세지의 페이로드에는 문자열, JavaScript오브젝트, 현재시각 등 다양한 값을 지정할 수 있습니다.</p> +<h3>출력</h3> +<dl class="message-properties"> + <dt>페이로드<span class="property-type">각종</span></dt> + <dd>지정한 메세지 페이로드</dd> + <dt class="optional">topic <span class="property-type">문자열</span></dt> + <dd>임의로 지정가능한 프로퍼티</dd> +</dl> +<h3>상세</h3> +<p>inject노드를 사용하여, 지정한 페이로드값을 이용하여 플로우를 시작할 수 있습니다. 페이로드의 기본값은 현재시각의 타임스탬프를 1970년 1월 1일부터 경과한 밀리초로 표현한 값입니다.</p> +<p>문자열, 수치, 논리값, JavaScript오브젝트, 플로우/글로벌 컨텍스트 값 등을 송출할 수도 있습니다.</p> +<p>기본값 설정으로는 에디터 내에 표시되는 버튼을 클릭하여, 노드를 수동으로 움직일 수 있습니다. 지정된 간격, 혹은 스케쥴에 따라 메세지를 송출하도록 설정할 수도 있습니다.</p> +<p>또한, 플로우를 시작할 때에 한 번만 메세지를 송출시킬 수도 있습니다.</p> +<p>'<i>시간간격</i>'으로 지정가능한 값의 최대치는, 약 596시간(혹은 24일)입니다. 24시간보다 긴 간격을 다루고 싶을 경우에는, 전원정지나 재시작에도 대응 가능한 스케쥴러노드의 이용을 검토하시는게 좋습니다.</p> +<p><b>주</b>:'<i>지정한 시간간격, 일시</i>'와 '<i>지정한 일시</i>'옵션은 표준적인 cron시스템을 내부에서 이용합니다. 따라서, '20분'으로 지정하면, 그 시점에서 20분 후가 아닌, 매 시 정확히 20분, 40분을 의미합니다. '현 시각에서 20분마다'를 지정하려면 '<i>지정한 시간간격</i>'' 옵션을 이용합니다.</p> +<p><b>주</b>: 문자열에 줄 바꿈을 포함하고 싶은 경우에는, function노드를 사용하여 페이로드를 지정 해 주세요.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/21-debug.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/21-debug.html new file mode 100644 index 0000000..22395c4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/21-debug.html @@ -0,0 +1,25 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="debug"> + <p>사이브바의 '디버그'탭에 선택한 메세지 프로퍼티의 값을 표시합니다. 설정에 의해, 랜덤로그로 출력도 가능합니다. 기본값의 표시대상은 <code>msg.payload</code>이지만, 설정에 의해 지정한 프로퍼티, 메세지 전체, 혹은 JSONata식의 평가결과를 출력할 수 있습니다.</p> + <h3>상세</h3> + <p>'디버그'사이드바는 받은 메시지의 계층구조를 표시하는 기능을 갖추고 있습니다. 이 기능으로 메시지의 구조를 쉽게 이해할 수 있습니다.</p> + <p>JavaScript오브젝트와 배열은 필요에 따라 접거나 펼칠 수 있습니다. 버퍼 오브젝트 데이터를 표시하거나, 표현가능한 경우에는 문자열로 표시할 수도 있습니다.</p> + <p>메세지를 받은 시각, 송신 노드, 메시지 타입에 관한 정보를 '디버그'사이드바에 표시된 메세지에 부수적으로 표시합니다. 송신한 노드의 ID를 선택하면, 워크스페이스내의 대응하는 노드를 확인할 수 있습니다.</p> + <p>출력의 유효/무효는 노드상의 버튼으로 전환할 수 있습니다. 플로우상에서 미사용중인 debug노드는, 무효화 하거나 삭제할 것을 권장합니다.</p> + <p>모든 메세지를 런타임 로그에 보내거나, 짧은(32자) 데이터를 debug노드 아래의 스테이터스텍스트에 표시할 수 있습니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/25-catch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/25-catch.html new file mode 100644 index 0000000..4cd49ff --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/25-catch.html @@ -0,0 +1,36 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="catch"> + <p>같은 탭내의 노드가 송출한 에러를 캐치합니다.</p> + <h3>출력</h3> + <dl class=message-properties> + <dt>error.message <span class="property-type">문자열</span></dt> + <dd>에러 메세지</dd> + <dt>error.source.id <span class="property-type">문자열</span></dt> + <dd>에러를 보낸 노드의 ID</dd> + <dt>error.source.type <span class="property-type">문자열</span></dt> + <dd>에러를 보낸 노드의 종류</dd> + <dt>error.source.name <span class="property-type">문자열</span></dt> + <dd>에러를 송출한 노드의 명칭(설정되어 있는 경우)</dd> + </dl> + <h3>상세</h3> + <p>메시지 처리중에 노드가 에러를 송출했을 경우, 플로우 실행은 기본적으로 정지합니다. 이 노드를 사용하면, 에러를 캐치하고 대응하는 플로우로 처리시킬 수 있습니다. + <p>기본값으로는, 같은 탭의 모든 노드가 송출한 에러를 캐치합니다. 특정 노드를 캐치대상으로 하거나 대상 catch노드에서 보충되지 않은 에러만 보충하도록 지정하는 것도 가능합니다. + <p>에러발생시에는 매치되는 모든 catch 노드가 메시지를 받습니다. + <p>서브플로우내에서 에러가 송출된 경우, 우선 서브플로우 내의 catch노드로 처리됩니다. 대응하는 노드가 존재하지 않을 경우에는 그 서브플로가 배치된 탭에 에러를 전파하여 처리합니다. + <p>메시지가<code>error</code>프로퍼티를 가지고 있는 경우, 원래의 <code>error</code>는 <code>_error</code>로 복사합니다. +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/25-status.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/25-status.html new file mode 100644 index 0000000..fa36d43 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/25-status.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="status"> + <p>같은 탭내 노드의 스테이터스 메시지를 취득합니다.</p> + <h3>출력</h3> + <dl class="message-properties"> + <dt>status.text <span class="property-type">문자열</span></dt> + <dd>스테이터스 문자열</dd> + <dt>status.source.type <span class="property-type">문자열</span></dt> + <dd>스테이터스를 표시한 노드의 종류</dd> + <dt>status.source.id <span class="property-type">문자열</span></dt> + <dd>스테이터스를 표시한 노드의 ID</dd> + <dt>status.source.name <span class="property-type">문자열</span></dt> + <dd>스테이터스를 표시한 노드의 명칭(설정되어 있는 경우)</dd> + </dl> + <h3>상세</h3> + <p>이 노드는 <code>payload</code>를 설정하지 않습니다.</p> + <p>기본값으로는, 같은 워크스페이스 탭내의 모든 노드의 스테이터스를 취득합니다. 특정 노드의 스테이터스를 취득 대상으로 설정할 수도 있습니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/60-link.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/60-link.html new file mode 100644 index 0000000..74aa414 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/60-link.html @@ -0,0 +1,23 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="link in"> + <p>플로우간에 가상의 링크를 작성합니다.</p> + <h3>상세</h3> + <p>임의의 탭상에 존재하는 <code>link out</code>노드에 접속할 수 있습니다. 이 접속은 마치 직접 링크한 것 처럼 작동합니다.</p> + <p>link노드간의 링크는 link노드를 선택한 경우에만 표시됩니다. 다른 탭으로의 링크가 있을 경우에는, 가상의 노드를 표시합니다. 이 가상의 노드를 클릭하면, 대응되는 탭으로 이동할 수 있습니다.</p> + <p><b>주: </b>서브플로우 밖에서 안으로, 혹은 안에서 밖으로의 링크는 작성할 수 없습니다.</p> +</script> \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/90-comment.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/90-comment.html new file mode 100644 index 0000000..814bb63 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/90-comment.html @@ -0,0 +1,21 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="comment"> + <p>플로우에 코멘트를 기술하기 위해 이용합니다.</p> + <h3>상세</h3> + <p>편집패널은 Markdown형식으로 기입가능 합니다. 입력한 텍스트는 '정보'사이드패널에 표시됩니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/98-unknown.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/98-unknown.html new file mode 100644 index 0000000..83868af --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/common/98-unknown.html @@ -0,0 +1,24 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="unknown"> + <p>설치된 Node-RED가 인식할 수 없는 종류의 노드입니다.</p> + <h3>상세</h3> + <p><i>이 종류의 노드를 배포한 경우, 설정은 유지되지만 부족한 노드를 설치할 때 까지 플로우를 시작할 수 없습니다.</i></p> + <p><code>메뉴 - 팔렛트 관리</code>를 사용하여 노드를 검색하여 설치하거나, <b>npm install &lt;모듈&gt;</b>으로 부족한 모듈을 설치하고 Node-RED를 재시작한 후, 노드를 다시 가져와야 합니다.</p> + <p>이 종류의 노드가 이미 설치되었지만, 라이브러리가 설치되지 않은 케이스도 있습니다. Node-RED의 로그를 참조하여 부족한 노드에 관련된 에러메세지를 확인하는게 좋습니다.</p> + <p>그래도 해결되지 않는 경우, 플로우 제작자에게 의뢰하여 부족한 노드의 복사본을 입수하여 주십시오.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/10-function.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/10-function.html new file mode 100644 index 0000000..813fb95 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/10-function.html @@ -0,0 +1,51 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="function"> + <p>수신 메시지에 대해서 처리를 실시하는 JavaScript코드(함수의 본체)를 정의합니다.</p> + <p>입력 메시지는 <code>msg</code>라는 명칭의 JavaScript 객체로 전달됩니다.</p> + <p><code>msg</code>오브젝트는<code>msg.payload</code>프로퍼티에 메시지 본체를 유지하는 것이 관례입니다.</p> + <p>보통 코드는 메시지 오브젝트(혹은 여러 메시지 객체)를 반환합니다.후속 플로우의 실행을 정지하고 싶은 경우에는, 오브젝트를 반환하지 않아도 상관없습니다.</p> + <h3>상세</h3> + <p>코드 쓰는 방식에 대한 자세한 내용은, <a target="_blank" href="http://nodered.org/docs/writing-functions.html">공식 홈페이지</a>를 참조해 주세요.</p> + <h4>메세지 송신</h4> + <p>플로우 내의 다음 노드에 메세지를 전달하기 위해서는, 메세지를 반환하거나, <code>node.send(messages)</code>를 호출합니다.</p> + <p>반환/send 대상은 다음과 같습니다:</p> + <ul> + <li>단일 메세지 오브젝트 - 첫 출력에 접속된 노드에 전해집니다</li> + <li>메세지 오브젝트의 배열 - 대응하는 출력에 접속된 노드에 전해집니다</li> + </ul> + <p>배열요소가 배열인 경우에는, 복수의 메세지에 대응하는 출력에 송출합니다.</p> + <p>반환방법이 단일값인지 배열오소인지 상관없이, 반환값이 null인 경우 메세지를 송출하지 않습니다.</p> + <h4>로그 출력과 에러처리</h4> + <p>로그 정보의 출력, 에러출력을 실행하려면 아래의 함수를 이용합니다:</p> + <ul> + <li><code>node.log("로그메세지")</code></li> + <li><code>node.warn("경고")</code></li> + <li><code>node.error("에러")</code></li> + </ul> + </p> + <p>catch노드를 이용하여 에러를 처리할 수 있습니다. catch노드로 처리하기 위해서는, <code>msg</code>를 <code>node.error</code>의 제2 인수로 전달합니다:</p> + <pre>node.error("에러",msg);</pre> + <h4>노드 정보 참조</h4> + <p>코드안에서 노드의 ID및 이름을 아래의 프로퍼티로 참조할 수 있습니다:</p> + <ul> + <li><code>node.id</code> - 노드 ID</li> + <li><code>node.name</code> - 노드의 별칭</li> + </ul> + <h4>환경변수의 이용</h4> + <p>환경변수는 <code>env.get("MY_ENV_VAR")</code>로 참조할 수 있습니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/10-switch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/10-switch.html new file mode 100644 index 0000000..99b8869 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/10-switch.html @@ -0,0 +1,39 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="switch"> + <p>프로퍼티 값에 의해 메세지를 분류합니다.</p> + <h3>상세</h3> + <p>수신한 메세지에 대해, 지정된 룰을 순서대로 평가하여 매치된 룰에 대응하는 출력포트에 메세지를 송출합니다.</p> + <p>처음에 룰이 매치된 시점에서 평가를 멈추는 것도 가능합니다.</p> + <p>평가 룰에는, 메세지 프로퍼티, 플로우/글로벌 컨텍스트 프로퍼티, JSONata식의 평가결과를 이용할 수 있습니다.</p> + <h4>룰</h4> + <p>분류 룰은 아래의 4개로 나뉩니다.</p> + <ol> + <li><b>값(value)</b>룰 - 지정된 프로퍼티에 대해 평가</li> + <li><b>열(sequence)</b>룰 - 메세지 열에 대해 적용(메세지열을 split노드 등으로 생성)</li> + <li><b>JSONata식</b> - 메세지 전체에 대해 평가를 수행하여, 결과가 true인 경우에 매치</li> + <li><b>그 외</b> - 이 전의 룰에 매치되는 것이 없는 경우에 적용</li> + </ol> + + <h4>주석</h4> + <p><code>is true/false</code>와 <code>is null</code> 룰은, 타입에 대해 엄밀한 비교를 수행합니다. 타입 변환한 상태에서 비교는 하지 않습니다.</p> + <p><code>is empty</code> 룰은, 길이 0의 문자열/배열/버퍼/프로퍼티를 갖지않는 오브젝트를 출력합니다. <code>null</code>나 <code>undefined</code>는 출력하지 않습니다.</p> + + <h4>메세지 열의 취급</h4> + <p>switch노드는 입력메세지 열에 관한 정보를 유지하는 <code>msg.parts</code>를 기본값으로는 변경하지 않습니다.</p> + <p>'<b>메세지 열의 보정</b>' 옵션을 지정하면, 매치한 각 룰에 대해 새로운 메세지를 생성합니다. 이 모드에서는, switch노드는 새로운 메세지열을 송신하기 전에, 입력메세지를 내부에 축적합니다. <b>settings.js</b>의 <code>nodeMessageBufferMaxLength</code>를 설장하면, 축적할 메세지 수를 제한할 수 있습니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/15-change.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/15-change.html new file mode 100644 index 0000000..f971f0a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/15-change.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="change"> + <p>메세지, 플로우컨텍스트, 글로벌컨텍스트의 프로퍼티를 변경, 삭제, 이동합니다.</p> + <p>룰을 여러개 지정한 경우, 정의된 순으로 적용됩니다.</p> + <h3>상세</h3> + <p>이용가능한 처리</p> + <dl class="message-properties"> + <dt>대입</dt> + <dd>프로퍼티를 셋팅합니다. 설정값에는, 다양한 타입의 값, 메세지나 컨텍스트의 기존 프로퍼티를 이용할 수 있습니다.<dd> + <dt>치환</dt> + <dd>프로퍼티에 대해 검색과 치환을 수행합니다. 정규표현을 지정한 경우, '치환 후의 문자열'에는 <code>$1</code>와 같은 캡쳐그룹을 지정할 수 있습니다. 치환처리에서는, 룰이 완전히 매치된 경우에만 프로퍼티를 변경할 수 있습니다.</dd> + <dt>삭제</dt> + <dd>프로퍼티를 삭제합니다.</dd> + <dt>이동</dt> + <dd>프로퍼티의 이동 또는 이름변경을 수행합니다.</dd> + </dl> + <p>'JSONata식'에는 <a href="http://jsonata.org/" target="_new">JSONata</a>언어를 지정할 수 있습니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/16-range.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/16-range.html new file mode 100644 index 0000000..5fd179b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/16-range.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="range"> + <p>수치를 다른 범위 값으로 변환합니다.</p> + <h3>입력</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">수치</span></dt> + <dd>수치를 지정합니다. 수치이외를 지정한 경우에는, 수치로 변환합니다. 변환할 수 없는 경우에는 에러가 발생합니다.</dd> + </dl> + <h3>출력</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">수치</span></dt> + <dd>새로운 범위로 변환한 결과 값.</dd> + </dl> + <h3>상세</h3> + <p>이 노드는 받은 수치를 선형스케일링 합니다. 기본값으로는, 결과 값은 노드에 설정한 범위내로 한정하지 않습니다.</p> + <p>'<i>입력값의 범위외의 값을 최소값/최대값으로 확대/축소</i>'를 지정하면, 값이 지정된 범위 밖의 값으로 변하지 않도록 합니다.</p> + <p>'<i>입력값의 범위외의 값을 범위폭으로 나눈 나머지로 해서 확대/축소</i>'를 지정하면, 결과를 범위폭으로 나눕니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/80-template.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/80-template.html new file mode 100644 index 0000000..7415b63 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/80-template.html @@ -0,0 +1,49 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="template"> + <p>템플릿에 기초하여 프로퍼티를 설정합니다.</p> + <h3>입력</h3> + <dl class="message-properties"> + <dt>msg <span class="property-type">오브젝트</span></dt> + <dd>템플릿을 생성하기 위한 정보를 포함한 메세지 오브젝트</dd> + <dt class="optional">template <span class="property-type">문자열</span></dt> + <dd><code>msg.payload</code>를 생성하기 위한 템플릿. 편집패널에서 템플릿을 설정하지 않은 경우에는, 출력메세지로 이용합니다.</dd> + </dl> + <h3>출력</h3> + <dl class="message-properties"> + <dt>msg <span class="property-type">오브젝트</span></dt> + <dd>지정한 템플릿과 입력메세지의 프로퍼티로 생성된 값을 설정한 메세지</dd> + </dl> + <h3>상세</h3> + <p>이 노드는 <i><a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache</a></i>형식을 기본값으로 이용하지만, 사용하지 않도록 설정할 수도 있습니다.</p> + <p>예를 들면, + <pre>안녕하세요, {{payload.name}}씨. 오늘은 {{date}}입니다.</pre> + <p>라는 템플릿에 대해, + <pre>{ + date: "월요일", + payload: { + name: "홍길동" + } +}</pre> + <p>이라는 메세지를 수신한 경우,</p> + <pre>안녕하세요, 홍길동씨. 오늘은 월요일입니다.</pre> + <p>라는 프로퍼티가 생성됩니다.</p> + <p>플로우 컨텍스트 혹은 글로벌 컨텍스트의 프로퍼티값을 사용할 수도 있습니다. 각각, <code>{{flow.이름}}</code>혹은 <code>{{global.이름}}</code>을 사용합니다. 또는, 퍼시스터블스토어(<code>store</code>)에 대해서는, <code>{{flow[store].이름}}</code>혹은 + <code>{{global[store].이름}}</code>을 사용합니다. +</p> + <p><b>주: </b>기본값으로는, <i>mustache</i>형식은 치환대상인 HTML요소를 이스케이프합니다. 이것을 방지하기 위해서는 <code>{{{3중}}}</code>괄호형식을 사용해야 합니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/89-delay.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/89-delay.html new file mode 100644 index 0000000..f890ec8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/89-delay.html @@ -0,0 +1,30 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="delay"> + <p>노드를 통과하는 메세지를 지연, 혹은 유량을 제한합니다.</p> + <h3>입력</h3> + <dl class="message-properties"> + <dt class="optional">delay <span class="property-type">수치</span></dt> + <dd>메세지의 지연시간을 밀리초 단위로 설정합니다. 이것은 노드 설정에서 기본값의 지연시간을 덮어쓸 수 있도록 노드를 설정한 경우에만 적용됩니다.</dd> + <dt class="optional">reset</dt> + <dd>수신메세지에서 이 프로퍼티를 임의의 값으로 설정하면, 노드가 유지하는 모든 미송신 메세지를 클리어합니다.</dd> + </dl> + <h3>상세</h3> + <p>메세지를 지연시키도록 설정한 경우, 지연시간은 고정값, 범위내의 난수값, 메세지 마다의 동적인 지정값 중 하나를 지정할 수 있습니다.</p> + <p>유량을 제한할 경우, 메세지는 지정된 시간간격내에 분산되어 송신합니다. 큐에 남은 메세지 수는 노드의 스테이터스에 표시됩니다. 받은 중간 메세지를 파기할 수도 있습니다.</p> + <p>유량제한은 모든 메세지에 적용할 수도, <code>msg.topic</code>값으로 그룹화하여 적용할 수도 있습니다. 그룹화하면, 중간메세지는 자동적으로 파기됩니다. 시간간격별로 모든 토픽의 최신메세지를 송신할지, 다음 토픽의 최신메세지를 송신할지 지정할 수 있습니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/89-trigger.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/89-trigger.html new file mode 100644 index 0000000..e89aac5 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/89-trigger.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="trigger"> + <p>메세지를 송신하면, 다른 메세지를 송신합니다. 지연 혹은 초기화가 지정되있지 않은 경우에는, 다음 2번째 메세지를 송신할 수 도 있습니다.</p> + + <h3>입력</h3> + <dl class="message-properties"> + <dt class="optional">reset</dt> + <dd>이 프로퍼티를 갖는 메세지를 받으면, 준비중인 대기나 반복을 클리어하여 메세지 송신은 실행되지 않습니다.</dd> + </dl> + + <h3>상세</h3> + <p>플로우 내에서 타임아웃을 작성하는데 이용합니다. 메세지를 받으면 기본값으로는 <code>payload</code>에 <code>1</code>을 설정하여 송신합니다. 송신후 250ms 대기하고 <code>payload</code>를 <code>0</code>에 설정한 2번째 메세지를 송신합니다. 이 기능은, 예를 들어 Raspberry Pi의 GPIO핀에 접속한 LED를 조작할때에 활동할 수 있습니다.</p> + <p>각 송신메세지의 페이로드는 다양한 종류의 값으로 설정할 수 있습니다. 재송신 데이터없음으로 하는 것도 가능합니다. 예를 들면, 재송신 데이터를 '<i>없음</i>'으로 하고, 메세지를 받았을 때에 지연을 연장하는 것으로 선택한 경우, trigger노드는 감시타이머로써 작동합니다. 즉, 지정한 간격내에 메세지를 수신하지 않은 경우에 메세지를 송신합니다.</p> + <p>페이로드에 <i>문자열</i>을 지정한 경우, mustache형식의 템플릿을 이용할 수 있습니다.</p> + <p><code>reset</code>프로퍼티를 갖는 메세지를 수신한 경우, 혹은 <code>payload</code>가 기정한 값에 매치하는 경우, 준비중인 대기나 반복을 클리어 하여 메세지 송신은 실행되지 않습니다.</p> + <p>수신메세지에서 리셋할 때까지 일정간격으로 메세지를 재송신하도록 지정할 수도 있습니다.</p> + <p><code>msg.topic</code>마다 다른 스트림으로 취급되도록 설정하는 것도 가능합니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/90-exec.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/90-exec.html new file mode 100644 index 0000000..eaeb12b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/function/90-exec.html @@ -0,0 +1,74 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="exec"> + <p>시스템 커맨드를 실행하여 출력을 반환합니다.</p> + <p>커맨드 완료까지 기다릴지, 커맨드가 출력을 실행할 때 마다 메세지를 출력할지 지정할 수 있습니다.</p> + <p>실행대상의 커맨드는, 노드의 설정 혹은 수신메세지에서 지정합니다.</p> + + <h3>입력</h3> + <dl class="message-properties"> + <dt class="optional">payload <span class="property-type">문자열</span></dt> + <dd>실행할 커맨의 마지막에 추가하도록 설정할 수 있습니다</dd> + <dt class="optional">kill <span class="property-type">문자열</span></dt> + <dd>exec노드의 프로세스에 보낼 시그널 종류를 지정합니다</dd> + <dt class="optional">pid <span class="property-type">수치|문자열</span></dt> + <dd>시그널 송신대상의 exec노드의 프로세스 ID를 지정합니다</dd> + </dl> + + <h3>출력</h3> + <ol class="node-ports"> + <li>표준출력(stdout) + <dl class="message-properties"> + <dt>payload <span class="property-type">문자열</span></dt> + <dd>커맨드의 표준출력</dd> + </dl> + <dl class="message-properties"> + <dt>rc <span class="property-type">문자열</span></dt> + <dd>반환코드 문자열(3번째 단자에서도 취득가능)의 복사(exec모드에서 만)</dd> + </dl> + </li> + <li>표준에러 출력(stderr) + <dl class="message-properties"> + <dt>payload <span class="property-type">문자열</span></dt> + <dd>커맨드의 표준에러 출력</dd> + </dl> + <dl class="message-properties"> + <dt>rc <span class="property-type">문자열</span></dt> + <dd>반환코드 문자열(3번째 단자에서도 취득가능)의 복사(exec모드에서 만)</dd> + </dl> + </li> + <li>반환코드(return code) + <dl class="message-properties"> + <dt>payload <span class="property-type">오브젝트</span></dt> + <dd>리턴코드, <code>message</code>, <code>signal</code>프로퍼티를 포함하는 오브젝트(<code>message</code>, <code>signal</code>는 이용가능한 경우)</dd> + </dl> + </li> + </ol> + <h3>상세</h3> + <p>기본값으로는, <code>exec</code>시스템콜을 사용하여 커맨드를 호출하여 완료를 기다리고, 출력을 반환합니다. Ω예를 들면, 커맨드의 실행이 성공한 경우에는, <code>{ code: 0 }</code>라는 반환값을 반환합니다.</p> + <p><code>spawn</code>를 사용하여 커맨드를 실행하고, 표준출력 및 표준에러출력을 반환하도록 할 수도 있습니다. 이 경우, 통상 1행 마다 값을 반환합니다. 커맨드의 실행이 완료되면, 3번째 단자에 오브젝트를 출력합니다. 예를 들면, 커맨드의 실행이 성공한 경우에는, <code>{ code: 0 }</code>라는 값을 반환합니다.</p> + <p>에러 발생시에는, 3번째 단자의 <code>msg.payload</code>에 <code>message</code>, <code>signal</code>등 부가정보를 반환합니다.</p> + <p>실행대상의 커맨드는 노드설정에서 정의합니다. <code>msg.payload</code>나 추가인수를 커맨드에 추가할 수도 있습니다.</p> + <p>커맨드 혹은 파라미터가 공백을 포함하는 경우에는, 앞뒤에 인용부를 붙입니다. - <code>"이것은 하나의 파라미터 입니다"</code></p> + <p>반환할 <code>payload</code>는 보통 <i>문자열</i>이자만, UTF8문자가 아닌 문자가 존재하면<i>버퍼</i>가 됩니다.</p> + <p>노드가 실행중인 경우, 스테이터스 아이콘과 PID를 표시합니다. 이 상태변화는 <code>Status</code>노드에서 감시할 수 있습니다.</p> + <h4>프로세스 정지</h4> + <p><code>msg.kill</code>을 수신하면, 실행중인 프로세스를 정지할 수 있습니다. <code>msg.kill</code>에는 송출할 시그널 종류를 지정합니다. 예를 들면, <code>SIGINT</code>, <code>SIGQUIT</code>, <code>SIGHUP</code>등 입니다. 빈 문자열을 지정한 경우에는, <code>SIGTERM</code>을 지정한 것으로 간주됩니다.</p> + <p>노드가 1개이상의 프로세스를 실행하고 있는 경우, <code>msg.pid</code>에 정지대상의 PID를 지정해야 합니다.</p> + <p><code>타임아웃</code>필드에 값을 지정하면, 지정한 초 이내에 커맨드가 완료되지 않는 경우, 프로세스를 자동적으로 정지합니다.</p> + <p>힌트: Python어플리케이션을 실행할 경우, <code>-u</code>를 지정하면 출력이 버퍼되는 것을 방지할 수 있습니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/messages.json b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/messages.json new file mode 100644 index 0000000..d87b2c0 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/messages.json @@ -0,0 +1,925 @@ +{ + "common": { + "label": { + "payload": "페이로드", + "topic": "토픽", + "name": "이름", + "username": "유저", + "password": "패스워드", + "property": "프로퍼티" + }, + "status": { + "connected": "접속됨", + "not-connected": "미접속", + "disconnected": "절단", + "connecting": "접속중", + "error": "에러", + "ok": "OK" + }, + "notification": { + "error": "<strong>에러</strong>: __message__", + "errors": { + "not-deployed": "노드가 배포되지 않았습니다", + "no-response": "서버의 응답이 없습니다", + "unexpected": "예상치 못한 에러 (__status__) __message__" + } + }, + "errors": { + "nooverride": "경고:메세지에서 설정한 프로퍼티는, 노드의 프로퍼티를 덮어쓸 수 없습니다.자세한 사항은 bit.ly/nr-override-msg-props를 참조해 주세요." + } + }, + "inject": { + "inject": "inject", + "repeat": "repeat = __repeat__", + "crontab": "crontab = __crontab__", + "stopped": "stopped", + "failed": "inject실패: __error__", + "label": { + "repeat": "반복", + "flow": "플로우 컨텍스트", + "global": "글로벌 컨텍스트", + "str": "문자열", + "num": "수치", + "bool": "진위값", + "json": "오브젝트", + "bin": "버퍼", + "date": "타임스탬프", + "env": "환경변수", + "object": "오브젝트", + "string": "문자열", + "boolean": "진위값", + "number": "수치", + "Array": "배열", + "invalid": "올바르지 않은 JSON" + }, + "timestamp": "타임스탬프", + "none": "없음", + "interval": "지정한 시간간격", + "interval-time": "지정한 시간간격, 일시", + "time": "지정한 일시", + "seconds": "초", + "minutes": "분", + "hours": "시간", + "between": "시각", + "previous": "이전의 값", + "at": "시각", + "and": "~", + "every": "시간각격", + "days": [ + "월요일", + "화요일", + "수요일", + "목요일", + "금요일", + "토요일", + "일요일" + ], + "on": "요일", + "onstart": "Node-RED시작의", + "onceDelay": "초 후, 아래를 시행", + "tip": "<b>주석:</b> '지정한 시간간격, 일시'와 '지정한 일시'는 cron을 사용합니다. <br/>'시간간격'에는 596시간 보다 작은 값을 지정합니다.<br/>자세한 사항은 노드의 '정보'를 확인해 주세요.", + "success": "inject처리를 실행했습니다: __label__", + "errors": { + "failed": "inject처리를 실패했습니다. 자세한사항은 로그를 확인해 주세요.", + "toolong": "시간간격이 너무 큽니다." + } + }, + "catch": { + "catch": "catch: 모두", + "catchNodes": "catch: __number__", + "catchUncaught": "catch: 미보충", + "label": { + "source": "에러 취득처", + "selectAll": "모두 선택", + "uncaught": "Catch노드로 처리된 에러를 무시" + }, + "scope": { + "all": "모든 노드", + "selected": "선택한 노드" + } + }, + "status": { + "status": "status: 모두", + "statusNodes": "status: __number__", + "label": { + "source": "상태취득처", + "sortByType": "타입순으로 정렬" + }, + "scope": { + "all": "모든 노드", + "selected": "선택한 노드" + } + }, + "debug": { + "output": "대상", + "none": "없음", + "invalid-exp": "JSONata식이 올바르지 않음: __error__", + "msgprop": "메세지 프로퍼티", + "msgobj": "msg오브젝트 전체", + "to": "출력대상", + "debtab": "디버그 탭", + "tabcon": "디버그 탭과 콘솔", + "toSidebar": "디버그 창", + "toConsole": "시스템 콘솔", + "toStatus": "노드 상태(32자)", + "severity": "레벨", + "notification": { + "activated": "유효화 했습니다: __label__", + "deactivated": "무효화 했습니다: __label__" + }, + "sidebar": { + "label": "디버그", + "name": "디버그 메세지", + "filterAll": "모든 플로우", + "filterSelected": "선택한 노드", + "filterCurrent": "현재의 플로우", + "debugNodes": "debug노드", + "clearLog": "로그를 삭제", + "filterLog": "로그 필터링", + "openWindow": "새 창에서 열기" + }, + "messageMenu": { + "collapseAll": "모든 패스 접기", + "clearPinned": "선택한 패스", + "filterNode": "노드를 필터", + "clearFilter": "필터를 초기화" + } + }, + "link": { + "linkIn": "link in", + "linkOut": "link out" + }, + "tls": { + "tls": "TLS설정", + "label": { + "use-local-files": "로컬파일의 비밀키와 인증서를 사용", + "upload": "파일", + "cert": "인증서", + "key": "비밀키", + "passphrase": "패스 프레이즈", + "ca": "CA인증서", + "verify-server-cert": "서버인증서를 확인", + "servername": "서버명" + }, + "placeholder": { + "cert": "인증서(PEM형식) 패스", + "key": "비밀키(PEM형식) 패스", + "ca": "CA인증서(PEM형식) 패스", + "passphrase": "비밀키 패스프레이즈 (임의)", + "servername": "SNI로 사용" + }, + "error": { + "missing-file": "인증서와 비밀키 파일이 설정되지 않았습니다" + } + }, + "exec": { + "exec": "exec", + "spawn": "spawn", + "label": { + "command": "커맨드", + "append": "인수", + "timeout": "타임아웃", + "timeoutplace": "임의", + "return": "출력", + "seconds": "초", + "stdout": "표준 출력", + "stderr": "표준에러 출력", + "retcode": "반환 코드" + }, + "placeholder": { + "extraparams": "추가 인수" + }, + "opt": { + "exec": "커맨드 종료시 - exec모드", + "spawn": "커맨드 실행 중 - spawn모드" + }, + "oldrc": "구 형식의 출력를 사용(호환 모드)" + }, + "function": { + "function": "", + "label": { + "function": "코드", + "outputs": "출력 수" + }, + "error": { + "inputListener": "코드 내에서'input'이벤트의 리스터를 설정할 수 없습니다", + "non-message-returned": "Function노드가 __type__ 타입의 메세지송신을 시도했습니다" + } + }, + "template": { + "template": "template", + "label": { + "template": "템플릿", + "property": "프로퍼티", + "format": "구문", + "syntax": "형식", + "output": "출력형식", + "mustache": "Mustache템플릿", + "plain": "평분", + "json": "JSON", + "yaml": "YAML", + "none": "없음" + }, + "templatevalue": "This is the payload: {{payload}} !" + }, + "delay": { + "action": "동작", + "for": "시간", + "delaymsg": "메세지 지연", + "delayfixed": "지정한 시간 지연", + "delayvarmsg": "msg.delay에 지연을 설정", + "randomdelay": "랜덤 지연", + "limitrate": "메세지의 유량제한", + "limitall": "모든 메세지", + "limittopic": "msg.topic 마다", + "fairqueue": "지정한 시간 후에 큐 선두의 토픽 메세지를 출력", + "timedqueue": "지정한 시간 후에 큐에 있는 모든 토픽 메세지를 출력", + "milisecs": "밀리초", + "secs": "초", + "sec": "초", + "mins": "분", + "min": "분", + "hours": "시간", + "hour": "시간", + "days": "일", + "day": "일", + "between": "빈도", + "and": "번/", + "rate": "유량", + "msgper": "메세지/", + "dropmsg": "중간 메세지를 삭제", + "label": { + "delay": "delay", + "variable": "variable", + "limit": "limit", + "limitTopic": "limit topic", + "random": "random", + "units": { + "second": { + "plural": "초", + "singular": "초" + }, + "minute": { + "plural": "분", + "singular": "분" + }, + "hour": { + "plural": "시간", + "singular": "시간" + }, + "day": { + "plural": "일", + "singular": "일" + } + } + }, + "error": { + "buffer": "버퍼 상한의 1000메세지를 넘었습니다", + "buffer1": "버퍼 상한의 10000메세지를 넘었습니다" + } + }, + "trigger": { + "send": "송신 데이터", + "then": "송신후의 처리", + "then-send": "재송신 데이터", + "output": { + "string": "문자열", + "number": "수치", + "existing": "존재하는 msg오브젝트", + "original": "원래의 msg오브젝트", + "latest": "최신 msg오브젝트", + "nothing": "없음" + }, + "wait-reset": "초기화될 때 까지 대기", + "wait-for": "지정한 시간 대기", + "wait-loop": "지정한 시간 간격마다 송신을 반복", + "for": "처리대상", + "bytopics": "msg.topic 마다", + "alltopics": "모든 메세지", + "duration": { + "ms": "밀리초", + "s": "초", + "m": "분", + "h": "시간" + }, + "extend": "새로운 메세지를 받았을 때 지연을 연장", + "label": { + "trigger": "trigger", + "trigger-block": "trigger & block", + "trigger-loop": "resend every", + "reset": "초기화 조건:", + "resetMessage": "msg.reset을 설정", + "resetPayload": "msg.payload가 다음 값", + "resetprompt": "임의" + } + }, + "comment": { + "comment": "comment" + }, + "unknown": { + "label": { + "unknown": "unknown" + }, + "tip": "<p>현재의 Node-RED환경에서는 이 노드의 타입을 알 수 없습니다.</p><p><i>현재의 상태에서 이 노드를 배포하면 설정은 보존되지만, 해당 노드가 설치될 때 까지 플로우는 실행되지 않습니다.</i></p><p>자세한 사항은 노드의 '정보'를 참조해 주세요.</p>" + }, + "mqtt": { + "label": { + "broker": "서버", + "example": "예) localhost", + "output": "출력", + "qos": "QoS", + "retain": "보존", + "clientid": "클라이언트", + "port": "포트", + "keepalive": "킵 얼라이브 시간", + "cleansession": "세션 초기화", + "use-tls": "SSL/TLS접속을 사용", + "tls-config": "TLS설정", + "verify-server-cert": "서버인증서를 확인", + "compatmode": "구 MQTT 3.1서포트" + }, + "sections-label": { + "birth-message": "접속시의 송신메세지(Birth메세지)", + "will-message": "예기치 않은 절단시의 송신메세지(Will메세지)", + "close-message": "절단 전의 송신메세지(Close메세지)" + }, + "tabs-label": { + "connection": "접속", + "security": "세큐리티", + "messages": "메세지" + }, + "placeholder": { + "clientid": "ID를 자동생성하는 경우에는, 기입하지 않습니다", + "clientid-nonclean": "신규가 아닌 세션을 설정해 주세요", + "will-topic": "Will메세지를 무효화하는 경우에는, 기입하지 않습니다", + "birth-topic": "Birth메세지를 무효화하는 경우에는, 기입하지 않습니다", + "close-topic": "Close메세지를 무효화하는 경우에는, 기입하지 않습니다" + }, + "state": { + "connected": "브로커에 접속했습니다: __broker__", + "disconnected": "브로커에서 절단되었습니다: __broker__", + "connect-failed": "브로커에 접속에 실패했습니다: __broker__" + }, + "retain": "보존", + "output": { + "buffer": "바이너리 버퍼", + "string": "문자열", + "base64": "Base64문자열", + "auto": "자동판정(문자열혹은 바이너리버퍼)", + "json": "JSON오브젝트" + }, + "true": "한다", + "false": "하지않는다", + "tip": "주석: 토픽이나 QoS를 메세지의 프로퍼티를 사용하여 설정하는 경우에는, 기입하지 않습니다.", + "errors": { + "not-defined": "토픽이 설정되지 않았습니다", + "missing-config": "브로커가 설정되지 않았습니다", + "invalid-topic": "올바르지 않은 토픽이 설정되어 있습니다", + "nonclean-missingclientid": "’세션 초기화’사용시에,클라이언트ID가 설정되지 않았습니다", + "invalid-json-string": "올바르지 않은 JSON문자열", + "invalid-json-parse": "JSON문자열의 퍼스에 실패했습니다" + } + }, + "httpin": { + "label": { + "method": "메소드", + "url": "URL", + "doc": "Docs", + "return": "출력형식", + "upload": "파일 업로드", + "status": "상태코드", + "headers": "헤더", + "other": "그 외", + "paytoqs" : "msg.payload를 쿼리 파라미터에 추가", + "utf8String": "UTF8문자열", + "binaryBuffer": "바이너리 버퍼", + "jsonObject": "JSON오브젝트", + "authType": "종류별", + "bearerToken": "토큰" + }, + "setby": "- msg.method에 정의 -", + "basicauth": "인증을 사용", + "use-tls": "SSL/TLS접속을 유효화", + "tls-config": "TLS설정", + "basic": "Basic인증", + "digest": "Digest인증", + "bearer": "Bearer인증", + "use-proxy": "프록시를 사용", + "proxy-config": "프록시 설정", + "use-proxyauth": "프록시인증을 사용", + "noproxy-hosts": "예외 호스트", + "utf8": "UTF8문자열", + "binary": "바이너리 버퍼", + "json": "JSON오브젝트", + "tip": { + "in": "URL은 상대 패스가 됩니다.", + "res": "이 노드에 보내지는 메세지는, <i>http input</i>노드를 기점으로 해 주세요.", + "req": "주석: JSON의 구문해석에 실패한 경우에는, 취득한 문자열을 그대로 출력합니다." + }, + "httpreq": "http request", + "errors": { + "not-created": "httpNodeRoot에 false가설정되었을 때에는,http-in노드를 작성할 수 없습니다", + "missing-path": "패스가 설정되지 않았습니다", + "no-response": "응답이 없습니다", + "json-error": "JSON의 구분해석 에러", + "no-url": "URL가 설정되지 않았습니다", + "deprecated-call": "권장하지 않는 호출입니다 __method__", + "invalid-transport": "http가 아닌 트랜스포트가 요구되었습니다", + "timeout-isnan": "타임아웃값이 수치가 아니기 때문에 무시합니다", + "timeout-isnegative": "타임아웃값이 음수이기 때문에 무시합니다", + "invalid-payload": "올바르지 않은 페이로드" + }, + "status": { + "requesting": "요구중" + } + }, + "websocket": { + "label": { + "type": "종류", + "path": "패스", + "url": "URL" + }, + "listenon": "대기", + "connectto": "접속", + "sendrec": "송신/수신", + "payload": "페이로드를 송신/수신", + "message": "메세지 전체를 송신/수신", + "tip": { + "path1": "표준으로는 <code>payload</code> 가 websocket에서 송신, 수신된 데이터를 기다립니다. 클라이언트는 JSON형식의 문자열로 메세지전체를 송신, 수신하도록 설정할 수 있습니다.", + "path2": "This path will be relative to ", + "url1": "URL에는 ws:&#47;&#47; 또는 wss:&#47;&#47; 스키마를 사용하여, 존재하는 websocket리스너를 설정해 주세요.", + "url2": "표준으로는 <code>payload</code> 가 websocket에서 송신,수신될 데이터를 기다립니다.클라이언트는 JSON형식의 문자열로 메세지전체를 송신, 수신하도록 설정할 수 있습니다." + }, + "status": { + "connected": "접속 수 __count__", + "connected_plural": "접속 수 __count__" + }, + "errors": { + "connect-error": "ws접속에서 에러가 발생했습니다: ", + "send-error": "송신중 에러가 발생했습니다: ", + "missing-conf": "서버설정이 부족합니다", + "duplicate-path": "같은 패스에 대해 2개의 WebSocket리스너는 지정할 수 없습니다: __path__" + } + }, + "watch": { + "watch": "watch", + "label": { + "files": "파일", + "recursive": "서브디렉토리를 재귀적으로 감시" + }, + "placeholder": { + "files": "복수의 파일이나 디렉토리는 콤마로 나누어 입력" + }, + "tip": "Windows인 경우, 디렉토리를 나누는 문자로 2개의 백슬래쉬 \\\\ 를 사용해 주세요." + }, + "tcpin": { + "label": { + "type": "종류", + "output": "출력", + "port": "포트", + "host": "호스트", + "payload": "의 페이로드", + "delimited": "나누는 문자", + "close-connection": "메세지를 송신할 때마다 접속을 절단", + "decode-base64": "Base64메세지의 복호", + "server": "서버", + "return": "반환값", + "ms": "밀리초", + "chars": "문자" + }, + "type": { + "listen": "대기", + "connect": "접속", + "reply": "TCP응답" + }, + "output": { + "stream": "스트림", + "single": "단일", + "buffer": "바이너리 버퍼", + "string": "문자열", + "base64": "Base64문자열" + }, + "return": { + "timeout": "지정시간 후", + "character": "지정문자의 수신時", + "number": "지정 개수의 문자열", + "never": "없음 - 접속을 유지", + "immed": "즉시 - 응답을 기다리지 않음" + }, + "status": { + "connecting": "__host__:__port__ 에 접속하고 있습니다", + "connected": "__host__:__port__ 에 접속했습니다", + "listening-port": "포트 __port__ 에서 접속을 기다리고 있습니다", + "stopped-listening": "포트의 대기를 정지했습니다", + "connection-from": "__host__:__port__ 에서 접속되었습니다", + "connection-closed": "__host__:__port__ 에서의 접속이 절단되었습니다", + "connections": "접속 수 __count__", + "connections_plural": "접속 수 __count__" + }, + "errors": { + "connection-lost": "__host__:__port__ 으로의 접속이 소실되었습니다", + "timeout": "포트 __port__ 의 소켓이 타임아웃에 의해 절단되었습니다", + "cannot-listen": "포트 __port__ 의 대기를 할 수 없습니다 에러: __error__", + "error": "에러: __error__", + "socket-error": "__host__:__port__ 에서 소켓의 에러가 발생했습니다", + "no-host": "호스트명 혹은 포트가 설정되지 않았습니다", + "connect-timeout": "접속이 타임아웃 됐습니다", + "connect-fail": "접속에 실패했습니다" + } + }, + "udp": { + "label": { + "listen": "대기", + "onport": "포트", + "using": "종류", + "output": "출력", + "group": "그룹", + "interface": "로컬IP", + "send": "송신", + "toport": "포트", + "address": "어드레스", + "decode-base64": "Base64형식의 페이로드를 복호" + }, + "placeholder": { + "interface": "(임의) 사용할 로컬인터페이스 혹은 어드레스", + "interfaceprompt": "(임의) 사용할 로컬인터페이스 혹은 어드레스", + "address": "수신IP어드레스" + }, + "udpmsgs": "UDP메세지", + "mcmsgs": "멀티캐스트 메세지", + "udpmsg": "UDP메세지", + "bcmsg": "브로드캐스트 메세지", + "mcmsg": "멀티캐스트 메세지", + "output": { + "buffer": "바이너리 버퍼", + "string": "문자열", + "base64": "Base64문자열" + }, + "bind": { + "random": "로컬포트를 랜덤하게 사용", + "local": "로컬포트를 사용", + "target": "지정한포트를 사용" + }, + "tip": { + "in": "주석: 방화벽이 통신을 허가하고 있는지 확인해 주세요.", + "out": "주석: <code>msg.ip</code>나 <code>msg.port</code> 를 사용하여 설정하는 경우에는,’어드레스’나 ’포트’를 기입하지 않습니다.", + "port": "이미 포트가 사용중 입니다: " + }, + "status": { + "listener-at": "udp노드가 __host__:__port__ 에서 접속을 기다리고 있습니다", + "mc-group": "udp노드가 그룹 __group__ 에 멀티캐스트 했습니다", + "listener-stopped": "udp노드가 대기를 정지했습니다", + "output-stopped": "udp노드가 출력을 정지했습니다", + "mc-ready": "udp노드는 멀티캐스트 준비가 끝났습니다: __iface__:__outport__ -> __host__:__port__", + "bc-ready": "udp노드는 브로드캐스트 준비가 끝났습니다: __outport__ -> __host__:__port__", + "ready": "udp노드는 준비되었습니다: __outport__ -> __host__:__port__", + "ready-nolocal": "udp노드는 준비되었습니다: __host__:__port__", + "re-use": "udp재이용 소켓: __outport__ -> __host__:__port__" + }, + "errors": { + "access-error": "UDP접속에러 관리자 권한으로 1024미만의 포트번호에 액세스할 필요가 있습니다", + "error": "에러: __error__", + "bad-mcaddress": "멀티캐스트어드레스가 올바르지 않습니다", + "interface": "인터페이스의 IP어드레스를 설정할 필요가 있습니다 ", + "ip-notset": "udp: IP어드레스가 설정되지 않았습니다", + "port-notset": "udp: 포트가 설정되지 않았습니다", + "port-invalid": "udp: 포트번호가 올바르지 않습니다", + "alreadyused": "udp: 이미 __port__번 포트가 사용중 입니다", + "ifnotfound": "udp: 인터페이스 __iface__ 가 없습니다" + } + }, + "switch": { + "switch": "switch", + "label": { + "property": "프로퍼티", + "rule": "조건", + "repair": "메세지열의 보정" + }, + "and": "~", + "checkall": "모든 조건을 적용", + "stopfirst": "처음 맞은 조건으로 종료", + "ignorecase": "대문자, 소문자를 구별하지 않음", + "rules": { + "btwn": "is between", + "cont": "contains", + "regex": "matches regex", + "true": "is true", + "false": "is false", + "null": "is null", + "nnull": "is not null", + "istype": "is of type", + "empty": "is empty", + "nempty": "is not empty", + "head": "head", + "tail": "tail", + "index": "index between", + "exp": "JSONata식", + "else": "그 외" + }, + "errors": { + "invalid-expr": "올바르지 않은 표현: __error__", + "too-many": "switch노드 내에서 보존하고 있는 메세지가 너무 많습니다" + } + }, + "change": { + "label": { + "rules": "룰", + "rule": "룰", + "set": "set __property__", + "change": "change __property__", + "delete": "delete __property__", + "move": "move __property__", + "changeCount": "change: __count__ rules", + "regex": "정규표현를 사용" + }, + "action": { + "set": "값의 대입", + "change": "값의 치환", + "delete": "값의 삭제", + "move": "값의 이동", + "to": "대상의 값", + "search": "검색할 문자열", + "replace": "치환 후의 문자열" + }, + "errors": { + "invalid-from": "조작대상의 프로퍼티가 올바르지 않음: __error__", + "invalid-json": "대상 값의 JSON프로퍼티가 올바르지 않음", + "invalid-expr": "JSONata식이 올바르지 않음: __error__" + } + }, + "range": { + "range": "range", + "label": { + "action": "동작", + "inputrange": "입력값의 범위", + "resultrange": "출력값의 범위", + "from": "최소값", + "to": "최대값", + "roundresult": "작은 수치를 반올림하여 정수치로 변환" + }, + "placeholder": { + "min": "예) 0", + "maxin": "예) 99", + "maxout": "예) 255" + }, + "scale": { + "payload": "msg.payload의 값을 확대/축소", + "limit": "입력값의 범위외의 값을 최소값/최대값으로 해서 확대/축소", + "wrap": "입력값의 범위외의 값을 범위폭으로 나눈 나머지로 해서 확대/축소" + }, + "tip": "주석: 이 노드는, 수치만 다룰 수 있습니다.", + "errors": { + "notnumber": "수치가 아닙니다" + } + }, + "csv": { + "label": { + "columns": "열 이름", + "separator": "나누는 문자", + "c2o": "CSV에서 오브젝트로 변환", + "o2c": "오브젝트에서 CSV로 변환", + "input": "입력", + "skip-s": "처음의", + "skip-e": "행을 무시한다", + "firstrow": "첫번째 행에 열 이름을 포함", + "output": "출력", + "includerow": "첫번째 행을 열 이름으로 함", + "newline": "줄바꿈 코드" + }, + "placeholder": { + "columns": "콤마로 나누어 열 이름을 입력" + }, + "separator": { + "comma": "콤마", + "tab": "탭", + "space": "공백", + "semicolon": "세미콜론", + "colon": "콜론", + "hashtag": "해쉬태그", + "other": "그 외..." + }, + "output": { + "row": "행마다 메세지를 분할", + "array": "배열화 한 1개의 메세지" + }, + "newline": { + "linux": "Linux (\\n)", + "mac": "Mac (\\r)", + "windows": "Windows (\\r\\n)" + }, + "errors": { + "csv_js": "이 노드가 처리할 수 있는 형식은, CSV문자열 혹은 JSON뿐 입니다", + "obj_csv": "오브젝트를 CSV로 변환할 때의 열 이름이 설정되지 않았습니다" + } + }, + "html": { + "label": { + "select": "추출할 요소", + "output": "출력", + "in": "대상:" + }, + "output": { + "html": "요소 내의 HTML", + "text": "요소의 텍스트만", + "attr": "요소의 모든 속성" + }, + "format": { + "single": "배열화 한 1개의 메세지", + "multi": "요소마다의 복수의 메세지" + } + }, + "json": { + "errors": { + "dropped-object": "오브젝트형식이 아닌 페이로드를 무시했습니다", + "dropped": "대응하지 않는 형식의 페이로드를 무시했습니다", + "dropped-error": "페이로드의 변환처리가 실패했습니다", + "schema-error": "JSON스키마 에러", + "schema-error-compile": "JSON스키마에러: 스키마의 컴파일에 실패했습니다" + }, + "label": { + "o2j": "오브젝트에서 JSON로 변환", + "pretty": "JSON문자열 형식", + "action": "동작", + "property": "프로퍼티", + "actions": { + "toggle": "JSON문자열과 오브젝트간의 상호변환", + "str": "항상 JSON문자열로 변환", + "obj": "항상 JavaScript오브젝트로 변환" + } + } + }, + "yaml": { + "errors": { + "dropped-object": "오브젝트형식이 아닌 페이로드를 무시했습니다", + "dropped": "대응하지 않는 형식의 페이로드를 무시했습니다", + "dropped-error": "페이로드의 변환처리에 실패했습니다" + } + }, + "xml": { + "label": { + "represent": "XML태그속성을 다음 프로퍼티명으로 표현", + "prefix": "문자열를 참조하기 위한 접두사", + "advanced": "상세설정", + "x2o": "XML에서 오브젝트로 변환" + }, + "errors": { + "xml_js": "이 노드는, XML형식의 문자열 혹은 JSON만 처리합니다" + } + }, + "file": { + "label": { + "filename": "파일명", + "action": "동작", + "addnewline": "메세지의 입력마다 줄바꿈을 추가", + "createdir": "디렉토리가 존재하지 않는 경우에 작성", + "outputas": "출력형식", + "breakchunks": "청크로 분할", + "breaklines": "행으로 분할", + "filelabel": "file", + "sendError": "에러메세지를 송신(호환모드)", + "deletelabel": "delete __file__", + "utf8String": "UTF8문자열", + "binaryBuffer": "바이너리 버퍼" + }, + "action": { + "append": "파일에 추가", + "overwrite": "파일을 덮어쓰기", + "delete": "파일을 삭제" + }, + "output": { + "utf8": "문자열", + "buffer": "바이너리 버퍼", + "lines": "행 마다의 메세지", + "stream": "버퍼의 스트림" + }, + "status": { + "wrotefile": "파일에 작성했습니다: __file__", + "deletedfile": "파일을 삭제했습니다: __file__", + "appendedfile": "파일에 추가했습니다: __file__" + }, + "encoding": { + "none": "기본값", + "native": "네이티브", + "unicode": "UNICODE", + "japanese": "일본", + "chinese": "중국", + "korean": "한국", + "taiwan": "대만/홍콩", + "windows": "Windows코드 페이지", + "iso": "ISO코드 페이지", + "ibm": "IBM코드 페이지", + "mac": "Mac코드 페이지", + "koi8": "KOI8코드 페이지", + "misc": "그 외" + }, + "errors": { + "nofilename": "파일명이 설정되지 않았습니다", + "invaliddelete": "경고: 삭제가 무효합니다. 설정 다이얼로그에서 특정 삭제설정을 사용해 주세요", + "deletefail": "파일의 삭제처리에 실패했습니다: __error__", + "writefail": "파일의 작성처리에 실패했습니다: __error__", + "appendfail": "파일의 추가처리에 실패했습니다: __error__", + "createfail": "파일의 작성처리에 실패했습니다: __error__" + }, + "tip": "주석: ’파일명’에 풀패스를 설정하지 않는 경우에는, Node-RED프로세스 실행디렉토리에서의 상대패스가 됩니다." + }, + "split": { + "split": "split", + "intro": "타입에 따라 <code>msg.payload</code> 를 분할:", + "object": "<b>오브젝트</b>", + "objectSend": "각 key/value쌍의 메세지를 송신", + "strBuff": "<b>문자열</b> / <b>버퍼</b>", + "array": "<b>배열</b>", + "splitUsing": "분할", + "splitLength": "고정장", + "stream": "메세지의 스트림로써 처리", + "addname": " key의 복사처" + }, + "join": { + "join": "join", + "mode": { + "mode": "동작", + "auto": "자동", + "merge": "열의 결합", + "reduce": "열의 집약", + "custom": "수동" + }, + "combine": "결합", + "create": "출력", + "type": { + "string": "문자열", + "array": "배열", + "buffer": "버퍼", + "object": "key/value오브젝트", + "merged": "결합 오브젝트" + }, + "using": "사용할 값", + "key": "를 키로써 사용", + "joinedUsing": "連結문자", + "send": "메세지송신:", + "afterCount": "지정수의 메세지파트를 수신 후", + "count": "합계값", + "subsequent": "후속 메세지마다", + "afterTimeout": "첫 메세지수신부터 타임아웃 후", + "seconds": "초", + "complete": "<code>msg.complete</code> 프로퍼티가 설정된 메세지수신 후", + "tip": "해당 모드에서는, 이 노드가 <i>split</i> 노드와 짝이 되거나, <code>msg.parts</code> 프로퍼티가 설정된 메세지를 수신하는 것을 전제로 합니다.", + "too-many": "join노드내부에서 보존하고 있는 메세지가 너무 많습니다", + "merge": { + "topics-label": "대상토픽", + "topics": "토픽", + "topic": "토픽", + "on-change": "신규토픽을 받으면 메세지를 송신한다" + }, + "reduce": { + "exp": "집약식", + "exp-value": "식", + "init": "초기값", + "right": "평가를 역순으로 행함 (마지막에서 처음으로)", + "fixup": "최종조정식" + }, + "errors": { + "invalid-expr": "JSONata식이 올바르지 않음: __error__" + } + }, + "sort": { + "sort": "sort", + "target": "대상", + "seq": "메세지열", + "key": "키", + "elem": "요소의 값", + "order": "순서", + "ascending": "오름차순", + "descending": "내림차순", + "as-number": "수치로써 비교", + "invalid-exp": "sort노드에서 올바르지 않은 JSONata식이 지정되었습니다: __message__", + "too-many": "sort노드의 처리되지 않은 메세지 수가 허용수를 넘었습니다", + "clear": "sort노드의 처리되지 않는 메세지를 파기했습니다" + }, + "batch": { + "batch": "batch", + "mode": { + "label": "모드", + "num-msgs": "메세지수로 그룹화", + "interval": "시간간격으로 그룹화", + "concat": "열의 결합" + }, + "count": { + "label": "메세지수", + "overlap": "오버랩", + "count": "수", + "invalid": "메세지수와 오버랩수가 올바르지 않음" + }, + "interval": { + "label": "시간간격", + "seconds": "초", + "empty": "메세지를 수신하지 않는 경우, 빈 메세지를 송신" + }, + "concat": { + "topics-label": "토픽", + "topic": "토픽" + }, + "too-many": "batch노드 내에서 보존하고 있는 메세지가 너무 많습니다", + "unexpected": "상정할 수 없는 모드", + "no-parts": "메세지에 parts프로퍼티가 없습니다" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/05-tls.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/05-tls.html new file mode 100644 index 0000000..d800f14 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/05-tls.html @@ -0,0 +1,19 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="tls-config"> + <p>TLS접속을 위한 옵션 설정</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/06-httpproxy.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/06-httpproxy.html new file mode 100644 index 0000000..4357c7f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/06-httpproxy.html @@ -0,0 +1,22 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http proxy"> + <p>프록시를 위한 옵션 설정</p> + + <h3>상세</h3> + <p>예외 호스트에 설정된 호스트에 액세스할 때에는, 프록시를 사용하지 않습니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/10-mqtt.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/10-mqtt.html new file mode 100644 index 0000000..613941c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/10-mqtt.html @@ -0,0 +1,74 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="mqtt in"> +<p>MQTT브로커에 접속하여, 지정한 토픽의 메세지를 서브스크랩(구독)합니다.</p> + <h3>출력</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">문자열 | 버퍼</span></dt> + <dd>바이너리버퍼가 아닌 경우에는 문자열</dd> + <dt>topic <span class="property-type">문자열</span></dt> + <dd>MQTT의 토픽. /로 계층을 구분한다</dd> + <dt>qos <span class="property-type">수치</span> </dt> + <dd>0: 최대 1번 도착, 1: 1번 이상 도착, 2: 1번만 도착</dd> + <dt>retain <span class="property-type">진위값</span></dt> + <dd>true일 경우, 메세지를 유지. 메세지가 오래된 값인 경우가 있습니다.</dd> + </dl> + <h3>상세</h3> + <p>구독토픽에는 MQTT의 와일드카드(+: 1레벨, #: 복수레벨)을 포함할 수 있습니다.</p> + <p>이 노드를 이용하기 위해서는 MQTT브로커로의 접속설정이 필요합니다. 연필아이콘을 클릭하여 설정할 수 있습니다.</p> + <p>MQTT(in 및 out)노드는 브로커로의 접속설정을 필요에 따라 공유할 수 있습니다.</p> +</script> + +<script type="text/x-red" data-help-name="mqtt out"> + <p>MQTT브로커에 접속하여, 메세지를 퍼블리쉬(발행) 합니다.</p> + <h3>입력</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">문자열 | 버퍼</span></dt> + <dd>보통 단순한 텍스트형식의 페이로드가 사용되지만, 바이너리버퍼를 발행하는 것도 가능합니다.</dd> + + <dt class="optional">topic <span class="property-type">문자열</span></dt> + <dd>발생대상의 MQTT토픽</dd> + + <dt class="optional">qos <span class="property-type">수치</span></dt> + <dd>0: 최대 1번 도착, 1: 1번 이상 도착, 2: 1번만 도착. 기본값은 0입니다.</dd> + + <dt class="optional">retain <span class="property-type">진위값</span></dt> + <dd>true일 경우, 메세지를 브로커에 유지합니다. 기본값은 false입니다.</dd> + </dl> + <h3>상세</h3> + <p><code>msg.payload</code>를 발행하는 메세지의 페이로드로 이용됩니다. 페이로드가 오브젝트인 경우, 송신할 때에 JSON문자열로 변환합니다. 페이로드가 바이너리버퍼인 경우, 그대로 송신합니다.</p> + <p>발행에 이용하는 토픽은 노드에 설정하거나, <code>msg.topic</code>으로 지정합니다.</p> + <p>이와 같이, QoS와 retain도 노드 설정, 혹은 노드의 설정이 공란일 경우에는, 각각 <code>msg.qos</code> 및 <code>msg.retain</code>으로 지정할 수 있습니다. 앞서 브로커에 보존한 토픽을 클리어 하려면, retain플래그를 설정하여 해당 토픽에 빈 메세지를 발행합니다.</p> + <p>이 노드를 이용하기 위해서는 MQTT브로커로의 접속설정이 필요합니다. 연필아이콘을 클릭하여 설정할 수 있습니다.</p> + <p>MQTT(in 및 out)노드는 브로커로의 접속설정을 필요에 따라 공유할 수 있습니다.</p> +</script> + +<script type="text/x-red" data-help-name="mqtt-broker"> + <p>MQTT브로커로의 접속설정</p> + <p>브로커로의 접속설정을 작성합니다. 설정은 <code>MQTT In</code> 및 <code>MQTT Out</code>노드로 재이용할 수 있습니다.</p> + <p>노드에 클라이언트 ID를 설정하지 않고 세션의 초기화를 설정하고 있는 경우, 랜덤한 클라이언트 ID를 생성합니다. 클라이언트 ID를 설정할 경우, 접속처의 브로커로 통일되게 해주세요.</p> + <h4>Birth메세지</h4> + <p>접속을 확립했을 때, 설정한 토픽에 대하여 발행되는 메세지</p> + <h4>Close메세지</h4> + <p>접속이 정상적으로 종료되기 전에, 노드의 재배포 혹은 셧다운 되었을 경우에, 설정된 토픅에 대하여 발행하는 메세지</p> + <h4>Will메세지</h4> + <p>예기치 못한 접속이 절단되었을 경우에, 브로커가 발행하는 메세지</p> + <h4>WebSocket</h4> + <p>WebSocket에 의한 접속을 실행하도록 설정할 수 있습니다. WebSocket을 이용하려면, 서버필드에 접속처 URI를 완전한 형식으로 기입합니다. 아래에 그 예시를 표시합니다.</p> + <pre>ws://example.com:4000/mqtt</pre> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/21-httpin.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/21-httpin.html new file mode 100644 index 0000000..680b28a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/21-httpin.html @@ -0,0 +1,81 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http in"> + <p>HTTP 엔드 포인트를 작성하여 Web 서비스를 구성합니다.</p> + <h3>출력</h3> + <dl class="message-properties"> + <dt>payload</dt> + <dd>GET리퀘스트의 경우, 쿼리 파라미터로 구성된 오브젝트. 그 이외의 경우, HTTP 리퀘스트의 본체를 가리킵니다.</dd> + <dt>req<span class="property-type">오브젝트</span></dt> + <dd>HTTP 리퀘스트 오브젝트. 오브젝트는 리퀘스트의 정보에 관한 복수의 속성을 포함합니다. + <ul> + <li><code>body</code> - リ리퀘스트 본체. 형식은 리퀘스트에 의존합니다</li> + <li><code>headers</code> - HTTP 리퀘스트 헤더를 포함한 오브젝트</li> + <li><code>query</code> - 쿼리 파라미터를 포함한 오브젝트</li> + <li><code>params</code> - 루팅 파라미터를 포함한 오브젝트</li> + <li><code>cookies</code> - 리퀘스트 쿠키를 포함한 오브젝트</li> + <li><code>files</code> - POST리퀘스트에서 파일의 업로드가 설정으로 유효화 되어 있는 경우, 업로드 대상 파일</li> + </ul> + </dd> + <dt>res<span class="property-type">오브젝트</span></dt> + <dd>HTTP 리스폰스 오브젝트. 이 프로퍼티를 직접 이용하는 것은 권장하지 않습니다. 리퀘스트의 처리 방법에 대해서는 <code>HTTP Response</code>ノ노드의 문서를 참조해 주세요.이 프로퍼티는 response노드에 전하는 메세지에 붙인 상태로 두십시오.</dd> + </dl> + <h3>상세</h3> + <p>이 노드는 설정으로 지정한 패스와 리퀘스트종류로 리퀘스트를 기다립니다. 패스 지정은 완전하게 지정하는 형식(예: <code>/user</code>), 혹은 임의의 값을 대기하는 이름있는 파라미터를 포함한 형식(예: <code>/user/:name</code>) 어떤 것도 상관없습니다. 이름있는 파라미터를 지정한 경우, 리퀘스트에서 지정한 실제 값은 <code>msg.req.params</code>로 참조할 수 있습니다.</p> + <p>POST나 PUT처럼 리퀘스트바디를 포함한 리퀘스트의 경우, 리퀘스트 내용은 <code>msg.payload</code>로 참조할 수 있습니다.</p> + <p>리퀘스트의 요소타입이 식별가능한 경우에는, 리퀘스트바디를 적절한 형식으로 변환합니다. 예를 들면, <code>application/json</code>은 JavaScript오브젝트로 변환합니다.</p> + <p><b>주:</b> 이 노드는 리퀘스트에 대한 레스폰스 송신을 하지 않습니다. 리퀘스트를 처리하기 위해서는 플로우에 HTTP Response노드를 포함해 주십시오.</p> +</script> + +<script type="text/x-red" data-help-name="http response"> + <p>HTTP In노드에서 받은 리퀘스트에 대한 레스폰스를 반환합니다.</p> + + <h3>입력</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">문자열</span></dt> + <dd>레스폰스 본체</dd> + <dt class="optional">statusCode <span class="property-type">수치</span></dt> + <dd>설정하면 레스폰스의 스테이터스 코드로 합니다. 기본값 : 200</dd> + <dt class="optional">headers <span class="property-type">오브젝트</span></dt> + <dd>설정하면 레스폰스의 HTTP헤더로 합니다.</dd> + <dt class="optional">cookies <span class="property-type">오브젝트</span></dt> + <dd>설정하면 쿠키를 설정 혹은 삭제하기 위해 사용합니다.</dd> + </dl> + <h3>상세</h3> + <p><code>statusCode</code>와 <code>headers</code>는 노드의 설정에서 지정할 수도 있습니다. 노드설정에서 프로퍼티를 지정한 경우에는, 대응하는 메세지 프로퍼티는 사용하지 않습니다.</p> + <h4>쿠키 처리</h4> + <p><code>cookies</code>는 키/값 으로 구성된 오브젝트 입니다. 값에는 기본옵션을 사용하여 쿠키값으로 설장할 문자열, 혹은 옵션을 포함한 오브젝트를 지정할 수 있습니다.</p> + <p>아래의 예에서는 2개의 쿠키를 설정하고 있습니다. 1번째는 <code>name</code>으로 그 값은 <code>nick</code>, 2번째는 <code>session</code>으로 값은 <code>1234</code>, 유효기간으로 15분을 지정하고 있습니다.</p> + <pre> +msg.cookies = { + name: 'nick', + session: { + value: '1234', + maxAge: 900000 + } +}</pre> + <p>유효한 옵션은 아래와 같습니다.</p> + <ul> + <li><code>domain</code> - (문자열) 쿠키의 도메인 지정</li> + <li><code>expires</code> - (일시) GMT표현으로 된 유효기한. 미지정 혹은 0으로 지정한 경우, 세션종료시 까지 유효</li> + <li><code>maxAge</code> - (문자열) 현 시각으로 부터 경과된 밀리초로 표현된 유효기한</li> + <li><code>path</code> - (문자열) 쿠키의 패스. 기본값은 '/'</li> + <li><code>value</code> - (문자열) 쿠키 값</li> + </ul> + <p>쿠키를 삭제하려면, <code>value</code>에 <code>null</code>을 설정합니다.</p> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/21-httprequest.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/21-httprequest.html new file mode 100644 index 0000000..674faad --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/21-httprequest.html @@ -0,0 +1,75 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http request"> + <p>HTTP리퀘스트를 송신하여, 리스폰스를 반환합니다.</p> + + <h3>입력</h3> + <dl class="message-properties"> + <dt class="optional">url <span class="property-type">문자열</span></dt> + <dd>노드 설정해서 지정하지 않은 경우, 이 프로퍼티로 리퀘스트의 url을 설정합니다.</dd> + <dt class="optional">method <span class="property-type">문자열</span></dt> + <dd>노드 설정해서 지정하지 않은 경우, 이 프로퍼티로 리퀘스트에 사용할 HTTP메소드를 설정합니다. <code>GET</code>, <code>PUT</code>, <code>POST</code>, <code>PATCH</code>, <code>DELETE</code>중 하나를 지정해 주세요.</dd> + <dt class="optional">headers <span class="property-type">오브젝트</span></dt> + <dd>리퀘스트의 HTTP헤더를 지정합니다.</dd> + <dt class="optional">cookies <span class="property-type">오브젝트</span></dt> + <dd>설정하면, 리퀘스트와 함께 쿠키를 보낼 수 있습니다.</dd> + <dt class="optional">payload</dt> + <dd>리퀘스트바디로써 보내는 데이터데이터</dd> + <dt class="optional">rejectUnauthorized</dt> + <dd><code>false</code>를 셋팅하면, 자기서명증명서를 사용하는 https사이트로의 리퀘스트를 허가합니다.</dd> + <dt class="optional">followRedirects</dt> + <dd><code>false</code>를 셋팅하면, 리다이렉트 하지않습니다. 기본값은 <code>true</code>입니다.</dd> + </dl> + <h3>출력</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">문자열 | 오브젝트 | 버퍼</span></dt> + <dd>리스폰스바디. 반환할 바디데이터를 문자열, JSON문자열로써 해석한 결과, 바이너리버퍼 그대로, 어떤 것으로 할지를 노드설정에 의해 지정할 수 있습니다.</dd> + <dt>statusCode <span class="property-type">수치</span></dt> + <dd>리스폰스의 스테이터스코드 혹은 리퀘스트가 완료되지 않은 경우의 에러코드.</dd> + <dt>headers <span class="property-type">오브젝트</span></dt> + <dd>리스폰스헤더를 포함하는 오브젝트</dd> + <dt>responseUrl <span class="property-type">문자열</span></dt> + <dd>리퀘스트 처리시에 리다이렉트가 발생한 경우, 이 프로퍼티가 마지막으로 리다이렉트된 URL을 표시합니다. 리다이렉트가 일어나지 않았을 경우, 첫 리퀘스트URL을 표시합니다.</dd> + <dt>responseCookies <span class="property-type">오브젝트</span></dt> + <dd>리스폰스가 쿠키르 포함하는 경우, 이 프로퍼티는 각 쿠키의 이름/값을 포함하는 오브젝트를 표시합니다.</dd> + <dt>redirectList <span class="property-type">배열</span></dt> + <dd>리퀘스트가 1번이상 리다이렉트된 경우, 이 프로퍼티에 정보가 축적됩니다. `location`은, 리다이렉트처를 나타냅니다. `cookies`는, 리다이렉트가 시작된 곳에서 반환된 쿠키정보입니다.</dd> + </dl> + <h3>상세</h3> + <p>노드 설정에서 url프로퍼티를 지정할 경우, <a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache형식</a>의 태그를 포함할 수 있습니다. 이로 인해, URL을 입력메세지 값으로 구성할 수 있습니다. 예를 들면, url이 <code>example.com/{{{topic}}}</code>인 경우, <code>msg.topic</code>의 값에 의한 치환작업을 자동적으로 실행합니다. {{{...}}}표기를 사용하면, /, &이라는 문자를 mustache가 이스케이프 하는 것을 막을 수 있습니다.</p> + <p><b>주</b>: proxy서버를 이용하고 있는 경우, 환경변수 <code>http_proxy=...</code>를 설정하여 Node-RED를 재시작하거나, 혹은 노드 설정에서 프록시를 설정해 주십시오. 만약 노드 설정에서 프록시를 설정한 경우, 환경변수 보다 이쪽의 설정이 우선시 됩니다.</p> + <h4>복수의 HTTP리퀘스트 노드 이용</h4> + <p>같은 플로우에서 이 노드를 여러개 사용하기 위해서는, <code>msg.headers</code>프로퍼티의 취급에 주의해야 합니다. 예를 들면, 첫 노드가 리스폰스헤더에 이 프로퍼티를 설정하고, 다음 노드가 이 프로퍼티를 리퀘스트헤더에 이용하는 것은 일반적으로 기대되는 작동법이 아닙니다. <code>msg.headers</code>프로퍼티를 노드간에서 변경하지 않았다면, 2번째 노드에서 무시됩니다. 커스텀헤더를 설정하기 위해서는, <code>msg.headers</code>를 먼저 삭제 혹은 빈 오브젝트<code>{}</code>로 리셋합니다. + <h4>쿠키의 취급</h4> + <p>노드에 <code>cookies</code>프로퍼티를 전달할 경우, 그 값은 키/값 쌍으로 된 오브젝트로 해 주십시오. 값에는 쿠키값으로 설정할 문자열, 혹은 단일의 <code>value</code>프로퍼티를 포함하는 오브젝트를 지정할 수 있습니다.</p> + <p>리퀘스트에 대해 반환된 쿠키는 <code>responseCookies</code>프로퍼티에 격납됩니다.</p> + <h4>요소 타입의 취급</h4> + <p><code>msg.payload</code>가 오브젝트인 경우, 리퀘스트의 요소 타입을 <code>msg.payload</code>에 자동적으로 설정하고, 바디ー를 JSON으로 변환합니다.</p> + <p>리퀘스트를 양식데이터로 인코딩 할 때에는, <code>msg.headers["content-type"]</code>を<code>application/x-www-form-urlencoded</code>으로 설정합니다.</p> + <h4>파일 업로드</h4> + <p><code>msg.headers["content-type"]</code>に<code>multipart/form-data</code>을 지정하면 파이러을 업로드 할 수 있습니다. 이 때, 노드의 <code>msg.payload</code>에 전달되는 데이터는 아래의 구조를 갖는 오브젝트로 합니다:</p> + <pre><code>{ + "KEY": { + "value": FILE_CONTENTS, + "options": { + "filename": "FILENAME" + } + } +}</code></pre> + <p><code>KEY</code>, <code>FILE_CONTENTS</code> 및 <code>FILENAME</code>에는 적절한 값을 설정해 주세요.</p> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/22-websocket.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/22-websocket.html new file mode 100644 index 0000000..09949bf --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/22-websocket.html @@ -0,0 +1,36 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="websocket in"> + <p>WebSocket입력 노드</p> + <p>기본값으로는, WebSocket에 의해 수신한 데이터는 <code>msg.payload</code>에 격납됩니다. 소켓은 JSON형식의 문자열을 대기하도록 설정할 수 있습니다. JSON형식의 문자열을 받으면, 오브젝트로 변환하여 메세지 전체로서 송신합니다.</p> +</script> + +<script type="text/x-red" data-help-name="websocket out"> + <p>WebSocket출력 노드</p> + <p>기본값으로는, <code>msg.payload</code>를 WebSocket경유로 송신합니다. 소켓은 <code>msg</code>전체를 JSON문자열로 인코딩하여 WebSocket을 통해 송신할 수 있습니다.</p> + + <p>이 노드가 수신한 메세지가 WebSocket In노드가 생성한 것일 경우, 메세지는 플로우를 작동한 클라이언트에게 반환됩니다. 그 이외의 경우, 메세지는 접속하고 있는 모든 클라이언트에게 브로드캐스트 됩니다.</p> + <p>WebSocket In노드가 생성한 메세지를 브로드캐스트하고 싶은 경우에는, 플로우 안에서 <code>msg._session</code>프로퍼티를 삭제합니다.</p> +</script> + +<script type="text/x-red" data-help-name="websocket-listener"> + <p>이 설정노드는 패스를 지정하여 WebSocket서버의 엔드포인트를 작성합니다.</p> +</script> + +<script type="text/x-red" data-help-name="websocket-client"> + <p>이 설정노드는 지정한 URL에 WebSocket클라이언트를 접속합니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/31-tcpin.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/31-tcpin.html new file mode 100644 index 0000000..1c665bb --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/31-tcpin.html @@ -0,0 +1,35 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="tcp in"> + <p>TCP로 부터의 입력을 수행합니다. 리모트 TCP포트에 접속하거나, 외부로부터의 접속을 접수합니다.</p> + <p><b>주: </b>1024번 보다 작은 번호의 포트를 액세스 하기 위해서는 root 혹은 administrator권한이 필요한 시스템도 있습니다.</p> +</script> + +<script type="text/x-red" data-help-name="tcp out"> + <p>TCP로의 출력을 수행합니다. 리모트 TCP포트로 접속, 외부로부터의 접속을 접수, 혹은 TCP In노드에서 받은 메세지로의 리플라이를 수행합니다.</p> + <p><code>msg.payload</code>만이 송신대상입니다.</p> + <p><code>msg.payload</code>가 바이너리데이터를 Base64인코딩의 문자열로 변환한 것일 경우, Base64디코딩 옵션을 지정하면 데이터를 바이너리로 변환하여 송신합니다.</p> + <p><code>msg._session</code>가 존재하지 않는 경우, 접속하고 있는 <b>모든</b> 클라이언트에게 송신합니다.</p> + <p><b>주: </b>1024번 보다 작은 번호의 포트를 액세스 하기 위해서는 root 혹은 administrator권한이 필요한 시스템도 있습니다.</p> +</script> + +<script type="text/x-red" data-help-name="tcp request"> + <p>간단한 TCP리퀘스트 노드. <code>msg.payload</code>를 서버의 TCP포트에 송신하여, 리스폰스를 기다립니다.</p> + <p>서버접속, "리퀘스트"송신, "리스폰스"수신을 수행합니다. 고정장의 문자수나 지정문자로의 매치, 첫 리플라이의 도착으로 부터 지정된 시간동안 대기, 데이터 도착 대기, 데이터 송신을 수행하여 리플라이를 기다리지 않고 접속을 즉시 삭제, 등의 동작을 선택할 수 있습니다.</p> + <p>리스폰스는 버퍼형식으로 <code>msg.payload</code>에 출력됩니다. 문자열로서 취급하기 위해서는, .toString()을 사용해 주세요.</p> + <p>TCP호스트의 포트번호설정을 공백으로 설정한 경우, <code>msg.host</code> 및 <code>msg.port</code>프로퍼티를 설정해야 합니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/32-udp.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/32-udp.html new file mode 100644 index 0000000..f6a5889 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/network/32-udp.html @@ -0,0 +1,28 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="udp in"> + <p>UDP입력 노드. <code>msg.payload</code>에 버퍼, 문자열, 혹은 Base64인코딩 문자열을 생성합니다. 멀티캐스트를 지원합니다.</p> + <p><code>msg.ip</code>와 <code>msg.port</code>에 수신된 메세지의 IP주소와 포트를 설정합니다.</p> + <p><b>주: </b>1024번 보다 작은 번호의 포트를 액세스, 브로드캐스트 하기 위해서는 root 혹은 administrator권한이 필요한 시스템도 있습니다.</p> +</script> + +<script type="text/x-red" data-help-name="udp out"> + <p><code>msg.payload</code>를 지정된 UDP 호스트와 포트에 송신합니다. 멀티캐스트를 지원합니다.</p> + <p><code>msg.ip</code>와 <code>msg.port</code>에 접속처를 설정할수 있지만, 노드설정이 우선시 됩니다.</p> + <p>브로드캐스트를 수행하기 위해서는, 주소를 로컬 브로드캐스트 IP주소로 설정하거나, 글로벌 브로드캐스트인 255.255.255.255를 시험해 주세요.</p> + <p><b>주: </b>1024번 보다 작은 번호의 포트를 액세스, 브로드캐스트 하기 위해서는 root 혹은 administrator권한이 필요한 시스템도 있습니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-CSV.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-CSV.html new file mode 100644 index 0000000..7286375 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-CSV.html @@ -0,0 +1,44 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="csv"> + <p>CSV형식의 문자열과 그 JavaScript오브젝트 표현의 사이에서 쌍방향의 변환을 수행합니다.</p> + <h3>입력</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">오브젝트 | 배열 | 문자열</span></dt> + <dd>JavaScript오브젝트, 배열, CSV문자열 중 하나</dd> + </dl> + <h3>출력</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">오브젝트 | 배열 | 문자열</span></dt> + <dd> + <ul> + <li>입력이 문자열인 경우, CSV로서 해석하여 CSV의 각 행을 키/값으로 구성된 JavaScript오브젝트를 생성합니다. + 각 행마다 메세지를 송신할지, 오브젝트의 배열로 된 하나의 메세지를 송신할지를 선택할 수 있습니다.</li> + <li>입력이 JavaScript오브젝트인 경우, CSV문자열로의 변환을 수행합니다.</li> + <li>입력이 기본형인 배열의 경우, 1행의 CSV문자열로 변환합니다.</li> + <li>입력이 배열의 배열, 혹은 오브젝트의 배열인 경우, 복수행의 CSV문자열로 변환합니다.</li> + </ul> + </dd> + </dl> + <h3>상세</h3> + <p>'열 이름'에 컬럼명의 리스트를 지정할 수 있습니다. CSV에서 오브젝트로 변환을 수행할 때, 컬럼명을 프로퍼티명으로 사용합니다. '열 이름'대신에 CSV데이터의 첫번째 행에 컬럼명을 포함시킬 수 도 있습니다.</p> + <p>CSV로의 변환을 수행할 때에는, 오브젝트에서 취득해야 할 프로퍼티와 그 순서를 '열 이름'을 참조하여 결정합니다.</p> + <p>입력이 배열인 경우에는, '열 이름'은 컬럼명을 나타내는 행의 출력이 지정된 경우에만 사용합니다.</p> + <p><code>parts</code>프로퍼티가 정확하게 설정되어 있는 경우, 메세지열을 입력으로 접수합니다.</p> + <p>CSV를 복수의 메세지로 변환하여 출력할 경우, 출력이 메세지열이 되도록 <code>parts</code>프로퍼티를 설정합니다.</p> + <p><b>주:</b> 콤마 이외의 구분문자를 설정한 경우여도, '열 이름'은 콤마로 구분해 주세요.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-HTML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-HTML.html new file mode 100644 index 0000000..6988c12 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-HTML.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="html"> + <p><code>msg.payload</code>에 격납한 HTML다큐멘트에서 CSS셀렉터를 사용하여 요소를 추출합니다.</p> + <h3>입력</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">문자열</span></dt> + <dd>요소를 추출할 HTML문자열</dd> + <dt class="optional">select <span class="property-type">문자열</span></dt> + <dd>편집패널에서 셀렉터를 지정하지 않은 경우, 메세지의 프로퍼티로서 설정할 수 있습니다.</dd> + </dl> + <h3>출력</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">배열 | 문자열</span></dt> + <dd>결과는, 페이로드에 매치된 요소의 배열을 포함하는 단일 메세지, 혹은 매치된 요소 마다의 메세지 중 하나를 선택할 수 있습니다. 복수의 메세지를 송신하는 경우, 메세지에는 <code>parts</code>를 설정합니다.</dd> + </dl> + <h3>상세</h3> + <p>이 노드는 CSS 및 jQuery셀렉터의 조합을 지원합니다. 이용가능한 구문의 자세한 사항은 <a href="https://github.com/fb55/CSSselect#user-content-supported-selectors" target="_blank">css-select documentation</a>를 참조해 주세요.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-JSON.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-JSON.html new file mode 100644 index 0000000..05bd295 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-JSON.html @@ -0,0 +1,43 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="json"> + <p>JSON문자열과 JavaScript오브젝트과의 사이에서 상호변환을 수행합니다.</p> + <h3>입력</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">오브젝트 | 문자열</span></dt> + <dd>JavaScript오브젝트 혹은 JSON문자열</dd> + <dt>schema<span class="property-type">오브젝트</span></dt> + <dd>JSON의 검증에 이용할 JSON스키머. 설정되지 않은 경우에는 검증을 수행하지 않습니다.</dd> + </dl> + <h3>출력</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">오브젝트 | 문자열</span></dt> + <dd> + <ul> + <li>입력이 문자열인 경우, JSON으로 해석하여, JavaScript오브젝틀로 변환합니다.</li> + <li>입력이 JavaScript오브젝트인 경우, JSON문자열로 변환합니다. JSON문자열은 성형하는 것도 가능합니다.</li> + </ul> + </dd> + <dt>schemaError<span class="property-type">배열</span></dt> + <dd>JSON의 검증에서 에러가 발생한 경우, Catch노드를 이용하여 에러를 배열로서 <code>schemaError</code>프로퍼티에서 취득할 수 있습니다.</dd> + </dl> + <h3>상세</h3> + <p>기본값의 변환대상은 <code>msg.payload</code>이지만, 다른 메세지 프로퍼티를 변환대상으로 할 수도 있습니다.</p> + <p>쌍방향의 변환을 자동선택하는 것이 아닌, 특정한 변환만 수행하도록 설정할 수 있습니다. 예를 들면, <code>HTTP In</code>노드에 대한 리퀘스트가 content-type을 정확하게 설정하고 있지 않는 경우여도, JSON노드에 의한 변환결과가 JavaScript오브젝트인 것을 보증하기위해 이용합니다.</p> + <p>JSON문자열로의 변환이 지정되지 않았을 경우, 수신된 문자열에 대해 더 이상의 체크를 하지 않습니다. 즉, 문자열이 JSON으로써 정확한지에 대한 검사나, 성형옵션을 지정하였더라도 성형처리를 실시하지 않습니다.</p> + <p>JSON스키머의 자세한 사항은, <a href="http://json-schema.org/latest/json-schema-validation.html">여기</a>를 참조해주세요.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-XML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-XML.html new file mode 100644 index 0000000..1156a3a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-XML.html @@ -0,0 +1,49 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="xml"> + <p>XML문자열과 JavaScript오브젝트와의 사이에서 상호변환을 수행합니다.</p> + <h3>입력</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">오브젝트 | 문자열</span></dt> + <dd>JavaScript오브젝트 혹은 XML문자열</dd> + </dl> + <h3>출력</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">오브젝트 | 문자열</span></dt> + <dd> + <ul> + <li>입력이 문자열인 경우, XML로써 해석하여 JavaScript오브젝트로 변환합니다.</li> + <li>입력이 JavaScript오브젝트인 경우, XML문자열로 변환합니다.</li> + </ul> + </dd> + <dt class="optional">options <span class="property-type">오브젝트</span></dt> + <dd>내부에서 사용중인 XML로의 변환 라이브러리에 대해 옵션을 전달할 수 있습니다. 자세한 사항은 <a href="https://github.com/Leonidas-from-XIV/node-xml2js/blob/master/README.md#options" target="_blank">the xml2js docs</a>를 참조해 주세요.</dd> + </dl> + <h3>상세</h3> + <p>XML와 오브젝트의 사이에서의 변환을 수행할 경우, 기본값으로는 XML속성은 <code>$</code>이라는 명칭의 프로퍼티에 추가합니다. + 텍스트의 내용은 <code>_</code>라는 이름의 프로퍼티에 추가합니다. 이러한 프로퍼티명은 노드의 설정에서 변경가능합니다.</p> + <p>예로 아래의 XML의 변환결과를 표시합니다.</p> + <pre>&lt;p class="tag"&gt;Hello World&lt;/p&gt;</pre> + <pre>{ + "p": { + "$": { + "class": "tag" + }, + "_": "Hello World" + } +}</pre> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-YAML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-YAML.html new file mode 100644 index 0000000..8af9321 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/parsers/70-YAML.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="yaml"> + <p>YAML형식의 문자열과 JavaScript오브젝트 사이에서 상호변환을 수행합니다.</p> + <h3>입력</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">오브젝트 | 문자열</span></dt> + <dd>JavaScript오브젝트 혹은 YAML형식문자열</dd> + </dl> + <h3>출력</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">오브젝트 | 문자열</span></dt> + <dd> + <ul> + <li>입력이 YAML형식의 문자열인 경우, JavaScript오브젝트로 변환합니다.</li> + <li>입력이 JavaScript오브젝트인 경우, YAML형식의 문자열로 변환합니다.</li> + </ul> + </dd> + </dl> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/sequence/17-split.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/sequence/17-split.html new file mode 100644 index 0000000..6b29071 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/sequence/17-split.html @@ -0,0 +1,138 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="split"> + <p>메세지를 메세지열로 분할합니다.</p> + + <h3>입력</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">오브젝트 | 문자열 | 배열 | 버퍼</span></dt> + <dd><code>msg.payload</code>の타입에 의해 노드의 동작이 다릅니다. + <ul> + <li><b>문자열</b>/<b>버퍼</b> - 지정된 문자열 (기본값: <code>\n</code>), 버퍼열, 혹은 고정된 길이에 의해 메세지를 분할합니다.</li> + <li><b>배열</b> - 메세지을 배열요소마다 혹은 고정된 길이의 배열로 분할합니다.</li> + <li><b>오브젝트</b> - 키/값의 각 조합에 대해 메세지를 송신합니다.</li> + </ul> + </dd> + </dl> + <h3>출력</h3> + <dl class="message-properties"> + <dt>parts<span class="property-type">오브젝트</span></dt> + <dd>원래 메세지를 어떻게 분할했는지에 관한 정보를 이 프로퍼티에 유지합니다. 예를 들면, <b>join</b>노드에 전하여, 메세지열을 하나의 메세지로 재구성할 수 있습니다. <code>parts</code>프로퍼티는 다음 프로퍼티를 포함합니다. + <ul> + <li><code>id</code> - 메세지그룹의 식별자</li> + <li><code>index</code> - 그룹 내의 위치</li> + <li><code>count</code> - 이미 알고 있는 경우, 그룹 내의 메세지수를 설정. 아래의 '스트림모드'를 참조</li> + <li><code>type</code> - 메세지 타입 - 문자열/배열/오브젝트/버퍼</li> + <li><code>ch</code> - 문자열 혹은 버퍼인 경우, 메세지를 분할하기 위해 사용한 문자열 혹은 바이트배열</li> + <li><code>key</code> - 오브젝트인 경우, 메세지가 생성된 부분의 키. +노드의 설정에 의해 키를 <code>msg.topic</code>등 다른 메세지프로퍼티로 복사할 수도 있습니다.</li> + <li><code>len</code> - 메세지를 고정된 길이로 분할한 경우의 길이.</li> + </ul> + </dd> + </dl> + <h3>상세</h3> + <p>이 노드는, 메세지열을 구성하는 메세지에 대해 공통 처리를 수행하고, <b>join</b>노드에서 하나의 메세지로 정리하는 플로우를 작성할 때에 유용합니다.</p> + <p><code>msg.parts</code>프로퍼티를 사용하여 원래의 메세지와 메세지열과의 대응관계를 기억합니다.</p> + <h4>스트림모드</h4> + <p>이 노드는 메세지열을 재구성하여 송신할 때에도 유용합니다. 예를 들면, 줄 바꿈 마지막의 커맨드를 송신하는 시리얼 디바이스에서는, 메세지의 마지막 커맨드부분이 끊어진 메세지를 송출하는 경우가 있습니다. '스트림모드'를 사용하여, 완결된 개별 커맨드에 메세지를 분할할 수 있습니다. 입력메세지 마지막에 미완성 부분이 있는 경우, <b>split</b>노드는 미완성부분을 기억하고, 다음에 수신한 메세지 앞부분에 추가합니다.</p> + <p>이 모드에서 처리할 때에는, 메세지 수를 미리 알 수 없기 때문에, <code>msg.parts.count</code>프로퍼티는 설정되지 않습니다. 따라서, <b>join</b>노드의 '자동모드'와 조합할 수 없습니다.</p> +</script> + + +<script type="text/x-red" data-help-name="join"> + <p>메세지열를 결합하여 하나의 메세지로 만듭니다.</p> + <p>메세지의 결합에는 다음 3개의 모드를 이용할 수 있습니다.</p> + <dl> + <dt>자동</dt> + <dd><b>split</b>노드와 조합하여, split과 역으로 메세지를 결합하는 처리를 수행합니다.</dd> + <dt>수동</dt> + <dd>메세지열을 다양한 방법으로 결합합니다.</dd> + <dt>열의 집약</dt> + <dd>메세지열에 대해 지정한 식을 적용하여, 하나의 메세지로 집약합니다.</dd> + </dl> + <h3>입력</h3> + <dl class="message-properties"> + <dt class="optional">parts<span class="property-type">오브젝트</span></dt> + <dd>자동적으로 메세지열을 결합하기 위해서는, 모든 메세지가 이 프로퍼티를 갖고 있어야합니다. <b>split</b>노드로 이 프로퍼티를 생성할 수 있지만, 독자적으로 생성해도 무관합니다. <code>parts</code>프로퍼티는 아래의 프로퍼티를 포함합니다. + <ul> + <li><code>id</code> - 메세지그룹의 식별자</li> + <li><code>index</code> - 그룹 내의 순서</li> + <li><code>count</code> - 그룹을 구성하는 메세지 수</li> + <li><code>type</code> - 메세지 타입 - string/array/object/buffer</li> + <li><code>ch</code> - 문자열 혹은 버퍼인 경우, 메세지를 분할할 때 사용한 문자열 혹은 바이트배열</li> + <li><code>key</code> - 오브젝트인 경우, 메세지가 생성된 부분의 키</li> + <li><code>len</code> - 메세지를 고정된 길이로 분할한 경우의 길이</li> + </ul> + </dd> + <dt class="optional">complete</dt> + <dd>설정되어 있는 경우, 유지하고 있는 메세지를 결합하여 송신합니다.</dd> + </dl> + <h3>상세</h3> + + <h4>자동모드</h4> + <p>자동모드에서는, 입력메세지의 <code>parts</code>프로퍼티를 이용하여 메세지열을 결합합니다. 이 모드는 <b>split</b>노드의 처리의 역을 자동적으로 수행합니다.</p> + + <h4>수동모드</h4> + <p>수동모드에서는, 메세지열을 다양한 결과로 결합할 수 있습니다.</p> + <ul> + <li><b>문자열</b>혹은 <b>버퍼</b> - 지정한 문자열 혹은 버퍼값을 기준으로 나누어 각 메세지의 지정된 프로퍼티를 결합</li> + <li><b>배열</b> - 지정프로퍼티 혹은 메세지 전체를 요소로 하는 배열</li> + <li><b>key/value오브젝트</b> - 입력메세지의 지정된 프로퍼티 값을 키로 하여, 프로퍼티값을 스토어한 오브젝트</li> + <li><b>통합오브젝트</b> - 각 메세지의 프로퍼티를 하나의 오브젝트로 통합</li> + </ul> + <p>출력메세지의 그 외의 프로퍼티는 메세지를 송신하기 직전의 메세지를 복사합니다.</p> + <p>'<i>합계값</i>'에는 출력메세지를 송신하기 전에 수신해야 할 메세지 수를 지정합니다. 오브젝트 출력인 경우, 이 합계값에 달하면 후속 메세지가 도착할 때 마다 메세지를 출력하도록 설정할 수도 있습니다.</p> + <p>'<i>초</i>'에는 신규 메세지를 송신하기 까지의 경과시간을설정합니다.</p> + <p><code>msg.complete</code>프로퍼티를 설정한 메세지를 수신하면, 출력메세지를 송신합니다. 이 때, 메세지열 수를 리셋합니다.</p> + <p><code>msg.reset</code>프로퍼티를 설정한 메세지를 수신하면, 부분적으로 수신된 메세지를 파기합니다. 이러한 메세지는 송신되지 않습니다. 이 때, 메세지열 수를 리셋합니다.</p> + + <h4>열의 집약모드</h4> + <p>열의 집약모드를 선택하면, 메세지열을 구성하는 각각의 메세지에 대해 식을 적용햐여, 집약한 값을 이용하여 하나의 메세지를 구성합니다.</p> + <dl class="message-properties"> + <dt>초기값</dt> + <dd> + 집약의 초기값(<code>$A</code>) + </dd> + <dt>집약식</dt> + <dd>메세지그룹을 구성하는 각 메세지에 적용되는 JSONata식. + 식의 평가결과는 다음 호출때에 집약값으로 전달합니다. + <ul> + <li><code>$A</code> 집약값</li> + <li><code>$I</code> 그룹 내의 메세지 순서</li> + <li><code>$N</code> 그룹 내의 메세지 수</li> + </ul> + </dd> + <dt>최종조정식</dt> + <dd>메세지그룹의 집약이 완료된 후에 적용되는 JSONata식. 임의로 지정가능 합니다. 식에는 아래의 특수변수를 참조할 수 있습니다. + <ul> + <li><code>$A</code> 집약값</li> + <li><code>$N</code> 그룹 내의 메세지 수</li> + </ul> + </dd> + <p>메세지그룹의 메세지에 대해, 기본값으로는 집약식은 처음 메세지로 부터 마지막 메세지에 대해 순서대로 적용됩니다. 적용을 역순으로 하는 것도 가능합니다.</p> + </dl> + <p><b>예:</b> 아래의 설정으로, 수 값의 메세지열에 대해 평균값을 계산합니다. + <ul> + <li><b>집약식</b>: <code>$A+payload</code></li> + <li><b>초기값</b>: <code>0</code></li> + <li><b>최종조정식</b>: <code>$A/$N</code></li> + </ul> + </p> + + <h4>메세지의 축적</h4> + <p>이 노드의 처리에서는 메세지열의 처리를 위해 메세지를 내부에 축적합니다. <code>nodeMessageBufferMaxLength</code>를 지정하여 축적할 메세지의 최대값을 제한할 수 있습니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/sequence/18-sort.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/sequence/18-sort.html new file mode 100644 index 0000000..d05c253 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/sequence/18-sort.html @@ -0,0 +1,40 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="sort"> + <p>메세지 열 혹은 배열형의 페이로드를 정렬합니다.</p> + <p><b>split</b>노드와 조합하여 메세지의 순서를 정렬할 수 있습니다.</p> + <p>아래의 정렬순서를 지정할 수 있습니다.</p> + <ul> + <li><b>오름차순</b></li> + <li><b>내림차순</b></li> + </ul> + <p>수치에 의한 정렬을 선택할 수도 있습니다.</p> + <p>메세지의 정렬을 수행하기 위한 정렬키는 <code>payload</code>프로퍼티 혹은 JSONata식을 이용할 수 있습니다. 배열형 페이로드의 정렬키에는, 요소값 혹은 JSONata식을 이용할 수 있습니다.</p> + <p>sort노드의 처리에서는 수신한 메세지가 <code>msg.parts</code>프로퍼티를 갖고있는 것을 상정하고 있습니다. split노드로 이 프로퍼티를 생성할 수 있지만, 독자적으로 생성해도 무관합니다. <code>parts</code>프로퍼티는 아래의 프로퍼티를 포함합니다.</p> + <p> + <ul> + <li><code>id</code> - 메세지 그룹의 식별자</li> + <li><code>index</code> - 그룹내의 순서</li> + <li><code>count</code> - 그룹을 구성하는 메세지의 수</li> + </ul> + </p> + <p><b>주:</b> 이 노드의 처리에서는 메세지를 내부에 축적합니다. 축적할 메세지의 최대값을 지정하여, 예기치 못한 메모리사용량의 증대를 막을수 있습니다. 기본값으로는 메세지 수를 제한하지 않습니다. + <ul> + <li><b>settings.js</b>의 <code>nodeMessageBufferMaxLength</code>프로퍼티</li> + </ul> + </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/sequence/19-batch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/sequence/19-batch.html new file mode 100644 index 0000000..b228724 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/sequence/19-batch.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="batch"> + <p>지정한 룰에 의해 메세지열을 생성합니다.</p> + <h3>상세</h3> + <p>메세지열의 생성에는 아래의 3가지 모드를 이용할 수 있습니다.</p> + <dl> + <dt>입력 메세지 수로 그룹화</dt> + <dd>입력 메세지를 지정한 길이의 메세지열로 그룹화 합니다. 메세지열의 마지막 부분을 다음 메세지열의 앞에서 반복하는 메세지 수를 '<b>오버랩</b>'으로 지정할 수 있습니다.</dd> + + <dt>입력간격(초)로 그룹화</dt> + <dd>지정한 시간간격내에 수신한 입력 메세지를 메세지열로 그룹화 합니다. 지정한 시간내에 메세지를 수신하지 않은 경우에, 공백의 메세지를 송신하도록 설정할 수도 있습니다.</dd> + + <dt>메세지 그룹의 결합</dt> + <dd>입력 메세지를 결합하여, 하나의 메세지열로 만듭니다. 메세지열의 식별을 위해, 각 메세지는 <code>msg.topic</code>프로퍼티와 <code>msg.parts</code>프로퍼티를 갖고 있어야 합니다. 메세지열의 결합순은, <code>topic</code>값의 리스트로 하여 batch노드에 지정합니다. + </dd> + </dl> + <h4>메세지의 축적</h4> + <p>이 노드의 처리에서는 메세지열의 처리를 위해 메세지를 내부에 축적합니다. <b>settings.js</b>의 <code>nodeMessageBufferMaxLength</code>를 지정하여 축적할 메세지의 최대수를 제한할 수 있습니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/storage/10-file.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/storage/10-file.html new file mode 100644 index 0000000..4f22308 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/storage/10-file.html @@ -0,0 +1,59 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="file"> + <p><code>msg.payload</code>를 파일로 내보냅니다. 내보내기는, 파일의 마지막에 추기 혹은 기존 내용의 치환을 선택할 수 있습니다. 또한, 파일을 삭제하는 것도 가능합니다.</p> + <h3>입력</h3> + <dl class="message-properties"> + <dt class="optional">filename <span class="property-type">문자열</span></dt> + <dd>대상 파일명을 노드에 설정하지않은 경우, 이 프로퍼티로 파일을 지정할 수 있습니다</dd> + </dl> + <h3>출력</h3> + <p>작성 완료시, 입력메세지를 출력단자로 송출합니다합니다.</p> + <h3>상세</h3> + <p>입력메세지의 페이로드를 파일의 마지막에 추가합니다. 줄 바꿈(\n)을 각 데이터의 마지막에 추가할 수도 있습니다.</p> + <p><code>msg.filename</code>을 사용하는 경우, 작성을 수행할 때 마다 파일을 클로즈 합니다. 보다 좋은 성능을 얻기 위해서는 파일명을 노드에 설정해 주세요.</p> + <p>추가하는 대신에, 파일전체를 덮어쓰기 하도록 설정할 수도 있습니다. 예를 들면, 이미지와 같은 바이너리 데이터를 파일로 작성하는 경우에는, 이 옵션을 지정하여, 줄 바꿈을 추가하는 옵션을 지정하지 않도록 합니다.</p> + <p>파일을 출력할 때의 인코딩은, 인코딩리스트에서 선택할 수 있습니다.</p> + <p>또한, 파일을 삭제할 수도 있습니다.</p> +</script> + +<script type="text/x-red" data-help-name="file in"> + <p>파일 내용을 문자열 혹은 바이너리버퍼로 불러옵니다.</p> + <h3>입력</h3> + <dl class="message-properties"> + <dt class="optional">filename <span class="property-type">문자열</span></dt> + <dd>불러올 대상 파일명을 노드에 설정하지않은 경우, 이 프로퍼티에서 파일을 지정할 수 있습니다</dd> + </dl> + <h3>출력</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">문자열 | 버퍼</span></dt> + <dd>파일 내용을 문자열 혹은 버퍼로 표현합니다</dd> + <dt class="optional">filename <span class="property-type">문자열</span></dt> + <dd>불러올 대상 파일명을 노드에 설정하지않은 경우, 이 프로퍼티에서 파일을 지정합니다</dd> + <dt class="optional">error <span class="property-type">오브젝트</span></dt> + <dd><i>비권장</i>: 설정에서 유효로 한 경우, 파일을 불러올 때에 에러가 발생하면 <code>payload</code>을 갖지 않고 <code>error</code>프로퍼티에 에러의 상세정보를 설정한 메세지를 송신합니다. 이 동작모드는 권장하지 않으며, 새로운 노드를 사용할 때의 기본값으로는 무효로 하고 있습니다. 자세한 사항은 아래를 참조해 주세요.</dd> + </dl> + <h3>상세</h3> + <p>파일이름은 절대패스에서 지정할 것을 권장합니다. 절대패스를 지정하지 않는 경우에는, Node-RED프로세스의 워킹디렉토리로부터의 상대패스로서 취급합니다.</p> + <p>Windows에서는 패스를 나누는 문자를(예를 들면, <code>\\유저\\이름</code>과 같이)이스케이프 할 필요가 있습니다.</p> + <p>텍스트파일인 경우, 행 마다 분할하여 각각 메세지를 송신할 수 있습니다. 또, 바이너리파일인 경우, 작은 덩어리의 버퍼로 분할하여 송신할 수 있습니다. 버퍼의 분할단위는 오퍼레이팅시스템에 의존하지만, 일반적으로 64k(Linux/Mac) 혹은 41k(Windows)입니다.</p> + <p>복수의 메세지로 분할하는 경우, 각 메세지에는 <code>parts</code>프로퍼티가 설정되어, 메세지열을 구성합니다.</p> + <p>주력형식이 문자열인 경우, 입력데이터의 인코딩을 인코딩리스트로부터 선택할 수 있습니다.</p> + <h4>구식의 에러 처리</h4> + <p>Node-RED 0.17보다 이전의 버젼에서는, 파일을 불러올 때에 에러가 발생하면 <code>payload</code>를 갖지않고 <code>error</code>프로퍼티에 에러의 상세정보를 설정한 메세지를 송신합니다. 이 동작모드는 권장하지 않으며, 새로운 노드를 사용할 때의 기본값으로는 무효로 하고 있습니다. 노드설정으로, 필요에 따라 이 모드를 유효화 할 수 있습니다.</p> + <p>에러는 Catch노드로 보충하여 처리할것을 권장합니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/storage/23-watch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/storage/23-watch.html new file mode 100644 index 0000000..f51ac08 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/ko/storage/23-watch.html @@ -0,0 +1,25 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="watch"> + <p>디렉토리 혹은 파일의 변화를 감지합니다.</p> + <p>콤마로 나누어 디렉토리 및 파일 리스트를 지정합니다. 공백을 포함하는 경우, 인용부를 이용해 "..." 형태로 만들어 주세요.</p> + <p>Windows에서는, 2중 백슬래쉬\\를 디렉토리 이름으로 사용합니다.</p> + <p>실제로 변경된 파일의 풀패스명을 <code>msg.payload</code>으로, 감지대상 리스트의 문자열을 <code>msg.topic</code>으로 반환합니다.</p> + <p><code>msg.file</code>은 변경된 파일의 파일명을 나타냅니다. <code>msg.type</code>은 변경된 대상의 종류(<i>file</i> 혹은 <i>directory</i>)를, <code>msg.size</code>는 파일사이즈(바이트 수)를 나타냅니다.</p> + <p>Linux에서는 파일로 표현되는 <i>전부</i>를 감지대상으로 할 수 있습니다.</p> + <p><b>주: </b>감지대상인 디렉토리 혹은 파일은 존재해야 합니다. 대상 파일 혹은 디렉토리가 삭제된 경우, 다시 작성되어도 감지대상에서 제외됩니다.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/20-inject.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/20-inject.html new file mode 100644 index 0000000..78b2180 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/20-inject.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="inject"> +<p>手动或定期得将消息注入流中。消息的有效荷载可以为多种类型,包括字符串,JavaScript对象或当前时间。</p> +<h3>输出</h3> +<dl class="message-properties"> + <dt>payload<span class="property-type">various</span></dt> + <dd>指定的消息的有效荷载。</dd> + <dt class="optional">topic <span class="property-type">字符串</span></dt> + <dd>可以在节点中配置的可选属性。</dd> +</dl> +<h3>详细</h3> +<p>通过使用特定的有效荷载,注入节点可以启动流。默认有效荷载是当前时间的时间戳(以毫秒为单位,自1970年1月1日起)。</p> +<p>该节点还支持注入字符串,数字,布尔值,JavaScript对象或流/全局上下文值。</p> +<p>默认情况下,节点可以通过在编辑器中单击节点按钮来手动触发。同时也可以被设置为定期或按计划注入。</p> +<p>另一个可选的设置是在每次启动流时注入一次。</p> +<p>可以指定的最大<i>间隔</i>约为596小时/24天。 但是,如果对于间隔超过一天的那些间隔,建议您使用scheduler节点来应对断电或重启。</p> +<p><b>注意</b>:选项<i>“时间间隔” </i>和<i>“特定时间” </i>使用了标准cron系统。这意味着因此“20分钟”并不表示在此之后20分钟,而是每小时的20分钟,40分钟。如果您希望设定为从现在开始的每20分钟,那么请使用<i>“间隔” </i>选项。</p> +<p><b>注意</b>: 如果您想在字符串中包含换行符,必须使用“功能”节点创建有效荷载。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/21-debug.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/21-debug.html new file mode 100644 index 0000000..e3137c5 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/21-debug.html @@ -0,0 +1,25 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="debug"> + <p>在“调试”侧边栏选项卡和运行时日志中显示选定的消息属性。 默认情况下,它会显示<code>msg.payload</code>的值,但您也可以将其设置成显示任意属性,完整消息或JSONata表达式的结果。</p> + <h3>详细</h3> + <p>调试侧边栏会提供已发消息的结构化视图,方便您查询消息的结构。</p> + <p>JavaScript对象和数组可以根据需要来折叠或扩展。缓冲区对象可以显示为原始数据,也可以显示为字符串。</p> + <p>对任意条消息,调试侧边栏还会显示接收消息的时间,发送消息的节点以及消息类型等信息。单击源节点ID将在工作区中显示该节点。</p> + <p>节点上的按钮可用于启用或禁用其输出。建议禁用或删除所有未使用的调试节点。</p> + <p>还可以通过配置节点,将所有消息发送到运行时的日志,或将简短的数据(32个字符内)在调试节点下的状态文本上显示。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/24-complete.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/24-complete.html new file mode 100644 index 0000000..e69ebc6 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/24-complete.html @@ -0,0 +1,24 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="complete"> + <p>当另一个节点完成对消息的处理时触发流。</p> + <h3>详细</h3> + <p>如果一个节点通知运行时它已完成消息的处理,该节点可用于触发第二个流。</p> + <p>这个节点可以与没有输出端口的节点一起使用,例如在使用电子邮件发送节点来发送邮件后触发一个流。</p> + <p>此节点只能被设置为处理流中某个所选节点的事件。与Catch节点不同,您不能指定“所有节点”模式并以流中的所有节点为目标。</p> + <p>并非所有节点都会触发此事件。这取决于它们是否支持于Node-RED 1.0中引入的此功能。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/25-catch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/25-catch.html new file mode 100644 index 0000000..5b2b4c3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/25-catch.html @@ -0,0 +1,36 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="catch"> + <p>捕获由同一标签页上的节点引发的错误。</p> + <h3>输出</h3> + <dl class="message-properties"> + <dt>error.message <span class="property-type">字符串</span></dt> + <dd>错误消息。</dd> + <dt>error.source.id <span class="property-type">字符串</span></dt> + <dd>引发错误的节点的ID。</dd> + <dt>error.source.type <span class="property-type">字符串</span></dt> + <dd>引发错误的节点的类型。</dd> + <dt>error.source.name <span class="property-type">字符串</span></dt> + <dd>引发错误的节点的名称。(如果已设置)</dd> + </dl> + <h3>详细</h3> + <p>如果节点在处理消息时抛出错误,则流程通常会停止。该节点可用于捕获那些错误并通过专用流程进行处理。</p> + <p>默认情况下,该节点将捕获同一标签页上任何节点抛出的错误。或者,它可以针对特定节点,或配置为仅捕获另一个“目标”捕获节点尚未捕获的错误。</p> + <p>当错误发生时,所有匹配的catch节点都会收到错误消息。</p> + <p>如果在子流中发送了错误,则该错误将由子流中的任意捕获节点处理。如果子流中不存在捕获节点,则那错误将被传播到子流实例所在的标签页。</p> + <p>如果消息已经具有<code>error</code>属性,则将该<code>error</code>复制为<code>_error</code>。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/25-status.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/25-status.html new file mode 100644 index 0000000..7d9504c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/25-status.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="status"> + <p>获取在同一标签页上的其他节点的状态消息。</p> + <h3>输出</h3> + <dl class="message-properties"> + <dt>status.text <span class="property-type">字符串</span></dt> + <dd>状态文本。</dd> + <dt>status.source.type <span class="property-type">字符串</span></dt> + <dd>报告状态的节点的类型。</dd> + <dt>status.source.id <span class="property-type">字符串</span></dt> + <dd>报告状态的节点的ID。</dd> + <dt>status.source.name <span class="property-type">字符串</span></dt> + <dd>报告状态的节点的名称(如果已设置)。</dd> + </dl> + <h3>详细</h3> + <p>该节点不包含<code>有效荷载</code>。</p> + <p>默认情况下,节点会获取同一工作空间标签页上报告所有节点的状态。可以通过配置来设定目标节点。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/60-link.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/60-link.html new file mode 100644 index 0000000..6f2bc5f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/60-link.html @@ -0,0 +1,31 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="link in"> + <p>在流之间创建虚拟连线。</p> + <h3>详细</h3> + <p>该节点可以连接到任何标签页上存在的任何<code>link out</code>节点。连接后,它们的行为就像连接在一起。</p> + <p>仅当选择链接节点时,才会显示链接节点之间的链接。如果有指向另一个选项卡的链接,则显示一个虚拟节点。单击该虚拟节点将带您到相应的选项卡。</p> + <p><b>注意:</b>无法创建进入或离开子流的链接。</p> +</script> + +<script type="text/x-red" data-help-name="link out"> + <p>在流之间创建虚拟连线。</p> + <h3>详细</h3> + <p>该节点可以连接到任何标签页上存在的任何<code>link in</code>节点。连接后,它们的行为就像连接在一起。</p> + <p>仅当选择链接节点时,才会显示链接节点之间的链接。如果有指向另一个选项卡的链接,则显示一个虚拟节点。单击该虚拟节点将带您到相应的选项卡。</p> + <p><b>注意:</b>无法创建进入或离开子流的链接。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/90-comment.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/90-comment.html new file mode 100644 index 0000000..f98577f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/90-comment.html @@ -0,0 +1,21 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="comment"> + <p>可用于向流添加注释的节点。</p> + <h3>详细</h3> + <p>编辑面板接受Markdown语法。输入的文本将在信息侧面板中显示。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/98-unknown.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/98-unknown.html new file mode 100644 index 0000000..108e192 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/common/98-unknown.html @@ -0,0 +1,24 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="unknown"> + <p>您安装的Node-RED无法识别该节点的类型。</p> + <h3>详细</h3> + <p><i>如果在此状态下部署节点,其配置会被保存。但是在安装缺少的类型之前,流不会开始。</i></p> + <p>使用<code> Menu-Manage Palette </code>选项来搜索并安装节点,或者使用<b>npm install &lt;module&gt;</b>来安装所有缺少的节点,并重新启动Node-Red来导入这些节点。</p> + <p>另一种可能是,您已经安装了此节点类型,但是缺少必须的依赖项。您应检查Node-RED的启动日志中是否有与缺少节点有关的错误消息。</p> + <p>以上方法都不适用时,您可以联系该流的作者以获取缺少的节点类型的副本。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/10-function.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/10-function.html new file mode 100644 index 0000000..035ccc8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/10-function.html @@ -0,0 +1,51 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="function"> + <p>定义对接收到的消息进行处理的JavaScript代码(函数的主体)。</p> + <p>输入消息在名为<code>msg</code>的JavaScript对象中传递。</p> + <p>通常,<code>msg</code>对象将消息正文保留在<code>msg.payload</code>属性中。</p> + <p>该函数一般会返回一个消息对象(或多个消息对象),但也可以为了停止流而什么都不返回。</p> + <h3>详细</h3> + <p>请参见<a target="_blank" href="http://nodered.org/docs/writing-functions.html">在线文档</a>来获得更多有关编写函数的信息。</p> + <h4>传送消息</h4> + <p>要将消息传递到流中的下一个节点,请返回消息或调用<code>node.send(messages)</code>。</p> + <p>它将返回/send:</p> + <ul> + <li>单个消息对象 - 传递给连接到第一个输出的节点</li> + <li>消息对象数组,传递给连接到相应输出的节点</li> + </ul> + <p>如果数组元素是数组,则将多个消息发送到相应的输出。</p> + <p>无论return方法是单个值还是数组元素,如果返回值为null,则不会发送任何消息。</p> + <h4>日志输出和错误处理</h4> + <p>使用以下功能输出日志信息和输出错误:</p> + <ul> + <li><code>node.log("Log message")</code></li> + <li><code>node.warn("Warning")</code></li> + <li><code>node.error("Error")</code></li> + </ul> + </p> + <p>使用catch节点可以进行错误处理。 要由catch节点处理,请将<code>msg</code>作为<code>node.error</code>的第二个参数传递:</p> + <pre>node.error("Error",msg);</pre> + <h4>访问节点信息</h4> + <p>您可以使用以下属性来在代码中引用节点ID和名称:</p> + <ul> + <li><code>node.id</code> - 节点的ID</li> + <li><code>node.name</code> - 节点的名称</li> + </ul> + <h4>使用环境变量</h4> + <p>环境变量可以通过<code>env.get("MY_ENV_VAR")</code>来进行访问。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/10-switch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/10-switch.html new file mode 100644 index 0000000..7ad25c2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/10-switch.html @@ -0,0 +1,37 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="switch"> + <p>按属性值来分配消息的传送路线。</p> + <h3>详细</h3> + <p>根据接收到的消息评估指定的规则,然后将消息发送到与匹配的规则相对应的输出端口。</p> + <p>可以将节点设置为一旦发现一个匹配的规则,则停止后续的匹配。</p> + <p>对于评估规则,可以使用消息属性,流上下文/全局上下文属性,环境变量和JSONata表达式的评估结果。</p> + <h4>规则</h4> + <p>有四种规则:</p> + <ol> + <li><b>值</b>根据配置的属性评估规则</li> + <li><b>顺序</b>可用于消息序列的规则,例如由“拆分”节点生成的规则</li> + <li><b>JSONata表达式</b>评估整个消息,如果结果为真,则匹配。</li> + <li><b>其他</b>上述规则都不匹配时适用</li> + </ol> + <h4>注释</h4> + <p><code>is true/false</code>与<code>is null</code> 规则将对类型进行严格的匹配。匹配之前的类型转化不会发生。</p> + <p><code>is empty</code>规则与零字节的字符串,数组,缓冲区或没有属性的对象相匹配。与<code>null</code>或者<code>undefined</code>等不匹配。</p> + <h4>处理消息序列</h4> + <p>默认情况下,节点不会修改<code>msg.parts</code>属性。</p> + <p>可以启用<b>重建消息序列</b>选项来为每条匹配的规则生成新的消息序列。在这种模式下,节点将在发送新序列之前对整个传入序列进行缓存。运行时的设定<code>nodeMessageBufferMaxLength</code>可以用来限制可缓存的消息数目。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/15-change.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/15-change.html new file mode 100644 index 0000000..fcba3fe --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/15-change.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="change"> + <p>设置,更改,删除或移动消息,流上下文或全局上下文的属性。</p> + <p>如果指定了多个规则,则将按定义的顺序来应用它们。</p> + <h3>详细</h3> + <p>可用的操作有:</p> + <dl class="message-properties"> + <dt>设置</dt> + <dd>设置一个属性。该值可以是多种不同类型,也可以从现有消息或上下文属性中获取。</dd> + <dt>置换</dt> + <dd>搜索并替换属性。 如果启用了正则表达式,则可以为“replace with”属性指定捕获组,例如<code>$1</code>。 在替换过程中,仅当规则完全匹配时才能更改属性类型。</dd> + <dt>删除</dt> + <dd>删除一个属性</dd> + <dt>移动</dt> + <dd>移动或者重命名一个属性</dd> + </dl> + <p>类型"expression"使用<a href="http://jsonata.org/" target="_new">JSONata</a>语言。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/16-range.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/16-range.html new file mode 100644 index 0000000..b5d2d03 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/16-range.html @@ -0,0 +1,40 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="range"> + <p>将数值映射为另一个区间的数值</p> + <h3>输入</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">数值</span></dt> + <dd>有效荷载<i>一定</i>得是一个数值. 否则则会映射失败。</dd> + </dl> + <h3>输出</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">数值</span></dt> + <dd>被映射到新区间的数值。</dd> + </dl> + <h3>详细</h3> + <p>该节点将线性缩放所接收到的数值。在默认情况下,结果不限于节点中定义的范围。</p> + <p><i>缩放并限制到目标范围</i>表示结果永远不会超出目标范围内指定的范围。</p> + <p><i>在目标范围内缩放并折叠</i>表示结果将会被限制(折叠)在目标范围内。</p> + <p>例如,输入0-10映射到0-100。</p> + <table style="outline-width:#888 solid thin"> + <tr><th width="80px">模式</th><th width="80px">输入</th><th width="80px">输出</th></tr> + <tr><td><center>scale</center></td><td><center>12</center></td><td><center>120</center></td></tr> + <tr><td><center>limit</center></td><td><center>12</center></td><td><center>100</center></td></tr> + <tr><td><center>wrap</center></td><td><center>12</center></td><td><center>20</center></td></tr> + </table> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/80-template.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/80-template.html new file mode 100644 index 0000000..938a778 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/80-template.html @@ -0,0 +1,46 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="template"> + <p>根据提供的模板设置属性。</p> + <h3>输入</h3> + <dl class="message-properties"> + <dt>msg <span class="property-type">object</span></dt> + <dd>一个msg对象,其中包含着用于填充模板的信息。</dd> + <dt class="optional">template <span class="property-type">string</span></dt> + <dd>由<code>msg.payload</code>填充的模板。如果未在编辑面板中配置,则可以将设为msg的属性。</dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>msg <span class="property-type">object</span></dt> + <dd>由来自传入msg的属性来填充已配置的模板后输出的带有属性的msg。</dd> + </dl> + <h3>详细</h3> + <p>默认情况下使用<i><a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache</a></i>格式。如有需要也可以切换其他格式。</p> + <p>例如: + <pre>Hello {{payload.name}}. Today is {{date}}</pre> + <p>receives a message containing: + <pre>{ + date: "Monday", + payload: { + name: "Fred" + } +}</pre> + <p>输出的消息将会是: + <pre>Hello Fred. Today is Monday</pre> + <p>也可以使用流上下文或全局上下文中的属性:<code>{{flow.name}}</code>或者<code>{{global.name}}</code>,或者为了持久储存<code>store</code>,可以使用<code>{{flow[store].name}}</code>或<code>{{global[store].name}}</code>。 + <p><b>注意:</b>默认情况下,<i>mustache</i>将在其替换的值中转义任何非字母数字或HTML实体。为了防止这种情况,请使用<code>{{{triple}}}</code>大括号。 +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/89-delay.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/89-delay.html new file mode 100644 index 0000000..690bdda --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/89-delay.html @@ -0,0 +1,32 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="delay"> + <p>对通过节点的消息进行延迟发送或限制。</p> + <h3>输入</h3> + <dl class="message-properties"> + <dt class="optional">delay <span class="property-type">数值</span></dt> + <dd>设置要应用于消息的延迟(以毫秒为单位)。仅当节点配置为允许消息去覆盖配置的默认延迟间隔时,此选项才适用。</dd> + <dt class="optional">reset</dt> + <dd>如果接收到的消息将此属性设置为任何值,则将清空该节点保留的所有的未发送消息。</dd> + <dt class="optional">flush</dt> + <dd>如果接收到的消息的此属性设置为任何值,则将立即发送该节点保留的所有未发送消息。</dd> + </dl> + <h3>详细</h3> + <p>当配置为延迟发送消息时,延迟间隔可以是一个固定值,一个范围内的随机值或为每个消息动态设置。</p> + <p>当配置为对消息进行限制时,它们的传递将分散在配置的时间段内。状态显示队列中当前的消息数。可以选择在中间消息到达时丢弃它们。</p> + <p>速率限制可以应用于所有消息,也可以根据<code>msg.topic</code>的值来进行分组。分组时,中间消息将会被自动删除。在每个时间间隔,节点可以释放所有主题的最新消息,或释放下一个主题的最新消息。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/89-trigger.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/89-trigger.html new file mode 100644 index 0000000..5f27a50 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/89-trigger.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="trigger"> + <p>触发后,将会发送一条消息。如果被拓展或重置,则可以选择发送第二条消息。</p> + + <h3>输入</h3> + <dl class="message-properties"> + <dt class="optional">reset</dt> + <dd>如果收到带有此属性的消息,则将清除当前正在进行的任何超时或重复,且不会触发任何消息。</dd> + </dl> + + <h3>详细</h3> + <p>该节点可用于在流中创建一个超时。 默认情况下,当它收到一条消息时,它将发送一条带有<code>1</code>的有效荷载的消息。然后它将等待250毫秒,再发送第二条消息,其有效荷载为<code>0</code>。这可以用于使连接到Raspberry Pi GPIO引脚的LED闪烁等例子上。</p> + <p>可以将发送的每个消息的有效荷载配置为各种值,包括不发送任何内容的选项。例如,将初始消息设置为<i>nothing</i>,然后选择将计时器与每个收到的消息一起扩展的选项,则该节点将充当看门狗计时器;仅在设置的间隔内未收到任何消息时才发送消息。</p> + <p>如果设置为<i>字符串</i>类型,则该节点支持<i>mustache</i>模板语法。</p> + <p>如果节点收到具有<code>reset</code>属性或与节点中配置的匹配的<code>有效荷载</code>的消息,则将清除当前正在进行的任何超时或重复,并且不会触发任何消息。</p> + <p>可以将节点配置为以固定的时间间隔重新发送消息,直到被收到的消息重置为止。</p> + <p>(可选)可以将节点配置为将带有<code>msg.topic</code>的消息视为独立的流。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/90-exec.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/90-exec.html new file mode 100644 index 0000000..27c4211 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/function/90-exec.html @@ -0,0 +1,74 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="exec"> + <p>运行系统命令并返回其输出。</p> + <p>可以将节点配置为等待命令完成,或者在命令生成时发送其输出。</p> + <p>运行的命令可以在节点中配置,也可以由收到的消息提供。</p> + + <h3>输入</h3> + <dl class="message-properties"> + <dt class="optional">payload <span class="property-type">字符串</span></dt> + <dd>如果这样配置,则将被附加到执行命令中。</dd> + <dt class="optional">kill <span class="property-type">字符串</span></dt> + <dd>指定发送到现有的exec节点进程的kill信号类型。</dd> + <dt class="optional">pid <span class="property-type">数值|字符串</span></dt> + <dd>要杀死的现有exec节点进程的进程ID</dd> + </dl> + + <h3>输出</h3> + <ol class="node-ports"> + <li>标准输出(stdout) + <dl class="message-properties"> + <dt>payload <span class="property-type">字符串</span></dt> + <dd>命令的标准输出。</dd> + </dl> + <dl class="message-properties"> + <dt>rc <span class="property-type">object</span></dt> + <dd>(仅执行模式)一个返回代码对象的副本(在端口3上也可用)</dd> + </dl> + </li> + <li>标准error输出(stderr) + <dl class="message-properties"> + <dt>payload <span class="property-type">字符串</span></dt> + <dd>命令的标准错误输出。</dd> + </dl> + <dl class="message-properties"> + <dt>rc <span class="property-type">object</span></dt> + <dd>(仅执行模式)一个返回代码对象的副本(在端口3上也可用)</dd> + </dl> + </li> + <li>返回代码 + <dl class="message-properties"> + <dt>payload <span class="property-type">object</span></dt> + <dd>一个包含返回代码以及<code>message</code>,<code>signal</code>属性的对象。</dd> + </dl> + </li> + </ol> + <h3>详细</h3> + <p>默认情况下,使用<code>exec</code>系统调用来调用命令,等待命令完成,然后返回输出。例如,成功的命令的返回码应为<code>{code:0}</code>。</p> + <p>(可选)可以选择使用<code>spawn</code>代替,它会在命令运行时从stdout和stderr返回输出,通常一次一行。完成后,它将在第三个端口上返回一个对象。例如,成功的命令应返回<code>{code:0}</code>。</p> + <p>错误可能会在第三个端口<code>msg.payload</code>上返回额外的信息,例如<code>message</code>字符串,<code>signal</code>字符串。</p> + <p>运行的命令是在节点内定义的,带有附加<code>msg.payload</code>的选项和另外一组参数。</p> + <p>带空格的命令或参数应该用引号引起来:<code>“这是一个参数”</code></p> + <p>返回的<code>有效荷载</code>通常是<i>字符串</i>类型,除非检测到非UTF8字符,在这种情况下,它会是<i>buffer</i>类型。</p> + <p>节点处于活动状态时,该节点的状态图标和PID将可见。对此更改可以通过<code>Status</code>节点读取。</p> + <h4>杀死进程</h4> + <p>发送<code>msg.kill</code>将杀死一个活动进程。<code>msg.kill</code>应该是包含要发送的信号类型的字符串,例如<code>SIGINT</code>,<code>SIGQUIT</code>或<code>SIGHUP</code>。如果设置为空字符串,则默认为<code>SIGTERM</code>。</p> + <p>如果节点有多个进程在运行,则还必须设置<code>msg.pid</code>并设置要杀死的PID的值。</p> + <p>如果<code>超时</code>字段提供了一个值,则如果在指定的秒数过去后进程尚未完成,则该进程将自动终止。</p> + <p>提示:如果运行Python应用程序,则可能需要使用<code>-u</code>参数来停止对输出进行缓存。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/messages.json b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/messages.json new file mode 100644 index 0000000..4fc5dc4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/messages.json @@ -0,0 +1,941 @@ +{ + "common": { + "label": { + "payload": "内容", + "topic": "主题", + "name": "名称", + "username": "用户名", + "password": "密码", + "property": "属性", + "selectNodes": "选择节点...", + "expand": "扩展" + }, + "status": { + "connected": "已连接", + "not-connected": "未连接", + "disconnected": "已断开", + "connecting": "连接中", + "error": "错误", + "ok": "确定" + }, + "notification": { + "error": "<strong>错误</strong>: __message__", + "errors": { + "not-deployed": "节点未部署", + "no-response": "服务器无反应", + "unexpected": "发生意外错误 (__status__) __message__" + } + }, + "errors": { + "nooverride": "警告: 信息的属性已经不可以改写节点的属性. 详情参考 bit.ly/nr-override-msg-props" + } + }, + "inject": { + "inject": "注入", + "repeat": "重复 = __repeat__", + "crontab": "crontab = __crontab__", + "stopped": "停止", + "failed": "注入失败: __error__", + "label": { + "repeat": "重复", + "flow": "流上下午", + "global": "全局上下文", + "str": "字符串", + "num": "数值", + "bool": "布尔值", + "json": "JSON对象", + "bin": "buffer", + "date": "时间戳", + "env": "环境变量", + "object": "对象", + "string": "字符串", + "boolean": "布尔值", + "number": "数值", + "Array": "数组", + "invalid": "无效的JSON对象" + }, + "timestamp": "时间戳", + "none": "无", + "interval": "周期性执行", + "interval-time": "指定时间段周期性执行", + "time": "指定时间", + "seconds": "秒", + "minutes": "分钟", + "hours": "小时", + "between": "介于", + "previous": "之前数值", + "at": "在", + "and": "至", + "every": "每隔", + "days": [ + "星期一", + "星期二", + "星期三", + "星期四", + "星期五", + "星期六", + "星期天" + ], + "on": "在", + "onstart": "立刻执行于", + "onceDelay": "秒后, 此后", + "tip": "<b>注意:</b> \"指定时间段周期性执行\" 和 \"指定时间\" 会使用cron系统.<br/> 详情查看信息页.", + "success": "成功注入: __label__", + "errors": { + "failed": "注入失败, 请查看日志", + "toolong": "周期过长" + } + }, + "catch": { + "catch": "捕获:所有节点", + "catchNodes": "捕获:__number__个节点", + "catchUncaught": "捕获:未捕获", + "label": { + "source": "捕获范围", + "selectAll": "全选", + "uncaught": "忽略其他捕获节点处理的错误" + }, + "scope": { + "all": "所有节点", + "selected": "指定节点" + } + }, + "status": { + "status": "报告所有节点状态", + "statusNodes": "报告__number__个节点状态", + "label": { + "source": "报告状态范围", + "sortByType": "按类型排序" + }, + "scope": { + "all": "所有节点", + "selected": "指定节点" + } + }, + "complete": { + "completeNodes": "完成: __number__个节点" + }, + "debug": { + "output": "输出", + "none": "None", + "invalid-exp": "无效的JSONata表达式: __error__", + "msgprop": "信息属性", + "msgobj": "完整信息", + "to": "目标", + "debtab": "调试窗口", + "tabcon": "调试窗口及Console", + "toSidebar": "调试窗口", + "toConsole": "Console", + "toStatus": "节点状态 (32位字符)", + "severity": "级别", + "notification": { + "activated": "成功激活: __label__", + "deactivated": "成功取消: __label__" + }, + "sidebar": { + "label": "调试窗口", + "name": "名称", + "filterAll": "所有节点", + "filterSelected": "已选节点", + "filterCurrent": "当前流程", + "debugNodes": "调试节点", + "clearLog": "清空日志", + "filterLog": "过滤日志", + "openWindow": "在新窗口打开", + "copyPath": "复制路径", + "copyPayload": "复制值", + "pinPath": "固定展开" + }, + "messageMenu": { + "collapseAll": "折叠所有路径", + "clearPinned": "清空已固定路径", + "filterNode": "过滤此节点", + "clearFilter": "清空过滤条件" + } + }, + "link": { + "linkIn": "输入", + "linkOut": "输出" + }, + "tls": { + "tls": "TLS设置", + "label": { + "use-local-files": "使用本地密匙及证书文件", + "upload": "上传", + "cert": "证书", + "key": "私钥", + "passphrase": "密码", + "ca": "CA证书", + "verify-server-cert":"验证服务器证书", + "servername": "服务器名" + }, + "placeholder": { + "cert":"证书路径 (PEM 格式)", + "key":"私钥路径 (PEM 格式)", + "ca":"CA证书路径 (PEM 格式)", + "passphrase":"私钥密码 (可选)", + "servername":"用于SNI" + }, + "error": { + "missing-file": "未提供证书/密钥文件" + } + }, + "exec": { + "exec": "exec", + "spawn": "spawn", + "label": { + "command": "命令", + "append": "追加", + "timeout": "超时", + "timeoutplace": "可选填", + "return": "输出", + "seconds": "秒", + "stdout": "标准输出", + "stderr": "标准错误输出", + "retcode": "返回码" + }, + "placeholder": { + "extraparams": "额外的输入参数" + }, + "opt": { + "exec": "当命令完成时 - exec模式", + "spawn": "当命令进行时 - spawn模式" + }, + "oldrc": "使用旧式输出 (兼容模式)" + }, + "function": { + "function": "函数", + "label": { + "function": "函数", + "outputs": "输出" + }, + "error": { + "inputListener":"无法在函数中监听对'注入'事件", + "non-message-returned":"函数节点尝试返回类型为 __type__ 的信息" + } + }, + "template": { + "template": "模板", + "label": { + "template": "模版", + "property": "属性", + "format": "语法高亮", + "syntax": "格式", + "output": "输出为", + "mustache": "Mustache 模版", + "plain": "纯文本", + "json": "JSON", + "yaml": "YAML", + "none": "无" + }, + "templatevalue": "这是有效载荷: {{payload}} !" + }, + "delay": { + "action": "行为设置", + "for": "时长", + "delaymsg": "延迟每一条信息", + "delayfixed": "固定延迟时间", + "delayvarmsg": "允许msg.delay复写延迟时长", + "randomdelay": "随机延迟", + "limitrate": "限制信息速率", + "limitall": "所有信息", + "limittopic": "每一个msg.topic", + "fairqueue": "依次发送每一个topic", + "timedqueue": "发所有topic", + "milisecs": "毫秒", + "secs": "秒", + "sec": "秒", + "mins": "分", + "min": "分", + "hours": "小时", + "hour": "小时", + "days": "天", + "day": "天", + "between": "介于", + "and": "至", + "rate": "速度", + "msgper": "信息 每", + "dropmsg": "不传输中间信息", + "label": { + "delay": "延迟", + "variable": "变量", + "limit": "限制", + "limitTopic": "限制主题", + "random": "随机", + "units" : { + "second": { + "plural" : "秒", + "singular": "秒" + }, + "minute": { + "plural" : "分钟", + "singular": "分钟" + }, + "hour": { + "plural" : "小时", + "singular": "小时" + }, + "day": { + "plural" : "天", + "singular": "天" + } + } + }, + "error": { + "buffer": "缓冲了超过 1000 条信息", + "buffer1": "缓冲了超过 10000 条信息" + } + }, + "trigger": { + "send": "发送", + "then": "然后", + "then-send": "然后发送", + "output": { + "string": "字符串", + "number": "数字", + "existing": "现有信息对象", + "original": "原本信息对象", + "latest": "最新信息对象", + "nothing": "无" + }, + "wait-reset": "等待被重置", + "wait-for": "等待", + "wait-loop": "周期性重发", + "for": "处理", + "bytopics": "每个msg.topic", + "alltopics": "所有消息", + "duration": { + "ms": "毫秒", + "s": "秒", + "m": "分钟", + "h": "小时" + }, + "extend": " 如有新信息,延长延迟", + "label": { + "trigger": "触发", + "trigger-block": "触发并阻止", + "trigger-loop": "周期性重发", + "reset": "重置触发节点条件 如果:", + "resetMessage":"msg.reset已设置", + "resetPayload":"msg.payload等于", + "resetprompt": "可选填" + } + }, + "comment": { + "comment": "注释" + }, + "unknown": { + "label": { + "unknown": "未知" + }, + "tip": "<p>此节点是您安装,但Node-RED所不知道的类型。</p><p><i>如果在此状态下部署节点,那么它的配置将被保留,但是流程将不会启动,直到安装缺少的类型。</i></p><p>有关更多帮助,请参阅信息侧栏</p>" + }, + "mqtt": { + "label": { + "broker": "服务端", + "example": "比如:本地主机", + "output": "输出", + "qos": "QoS", + "retain": "保持", + "clientid": "客户端ID", + "port": "端口", + "keepalive": "Keepalive计时(秒)", + "cleansession": "使用新的会话", + "use-tls": "使用安全连接 (SSL/TLS)", + "tls-config":"TLS 设置", + "verify-server-cert":"验证服务器证书", + "compatmode": "使用旧式MQTT 3.1支持" + }, + "sections-label":{ + "birth-message": "连接时发送的消息(出生消息)", + "will-message":"意外断开连接时的发送消息(Will消息)", + "close-message":"断开连接前发送的消息(关闭消息)" + }, + "tabs-label": { + "connection": "连接", + "security": "安全", + "messages": "消息" + }, + "placeholder": { + "clientid": "留白则自动生成", + "clientid-nonclean":"如非新会话,必须设置客户端ID", + "will-topic": "留白将禁止Will信息", + "birth-topic": "留白将禁止Birth信息", + "close-topic": "留白以禁用关闭消息" + }, + "state": { + "connected": "已连接到服务端: __broker__", + "disconnected": "已断开与服务端 __broker__ 的链接", + "connect-failed": "与服务端 __broker__ 的连接失败" + }, + "retain": "保留", + "output": { + "buffer": "Buffer", + "string": "字符串", + "base64": "Base64编码字符串", + "auto": "自动检测 (字符串或buffer)", + "json": "解析的JSON对象" + }, + "true": "是", + "false": "否", + "tip": "提示: 若希望通过msg属性对topic(信息), qos及retain(保留)进行设置, 则将上述项留白", + "errors": { + "not-defined": "主题未设置", + "missing-config": "未设置服务端", + "invalid-topic": "主题无效", + "nonclean-missingclientid": "客户端ID未设定,使用新会话", + "invalid-json-string": "无效的JSON字符串", + "invalid-json-parse": "无法解析JSON字符串" + } + }, + "httpin": { + "label": { + "method": "请求方式", + "url": "URL", + "doc": "文档", + "return": "返回", + "upload": "接受文件上传?", + "status": "状态码", + "headers": "头", + "other": "其他", + "paytoqs" : "将msg.payload附加为查询字符串参数", + "utf8String": "UTF8格式的字符串", + "binaryBuffer": "二进制buffer", + "jsonObject": "解析的JSON对象", + "authType": "类型", + "bearerToken": "Token" + }, + "setby": "- 用 msg.method 设定 -", + "basicauth": "基本认证", + "use-tls": "使用安全连接 (SSL/TLS) ", + "tls-config":"TLS 设置", + "basic": "基本认证", + "digest": "摘要认证", + "bearer": "bearer认证", + "use-proxy": "使用代理服务器", + "persist": "对连接启用keep-alive", + "proxy-config": "代理服务器设置", + "use-proxyauth": "使用代理身份验证", + "noproxy-hosts": "代理例外", + "utf8": "UTF-8 字符串", + "binary": "二进制数据", + "json": "JSON对象", + "tip": { + "in": "相对URL", + "res": "发送到此节点的消息<b>必须</b>来自<i>http input</i>节点", + "req": "提示:如果JSON解析失败,则获取的字符串将按原样返回." + }, + "httpreq": "http 请求", + "errors": { + "not-created": "当httpNodeRoot为否时,无法创建http-in节点", + "missing-path": "无路径", + "no-response": "无响应对象", + "json-error": "JSON 解析错误", + "no-url": "未设定 URL", + "deprecated-call":"__method__方法已弃用", + "invalid-transport":"非HTTP传输请求", + "timeout-isnan": "超时值不是有效数字,忽略", + "timeout-isnegative": "超时值为负,忽略", + "invalid-payload": "无效的有效载荷" + }, + "status": { + "requesting": "请求中" + } + }, + "websocket": { + "label": { + "type": "类型", + "path": "路径", + "url": "URL" + }, + "listenon": "监听", + "connectto": "连接", + "sendrec": "发送/接受", + "payload": "有效载荷", + "message": "完整信息", + "tip": { + "path1": "默认情况下,<code>payload</code>将包含要发送或从Websocket接收的数据。侦听器可以配置为以JSON格式的字符串发送或接收整个消息对象.", + "path2": "这条路径将相对于 ", + "url1": "URL 应该使用ws:&#47;&#47;或者wss:&#47;&#47;方案并指向现有的websocket侦听器.", + "url2": "默认情况下,<code>payload</code> 将包含要发送或从Websocket接收的数据。可以将客户端配置为以JSON格式的字符串发送或接收整个消息对象." + }, + "status": { + "connected": "连接数 __count__", + "connected_plural": "连接数 __count__" + }, + "errors": { + "connect-error": "ws连接发生了错误: ", + "send-error": "发送时发生了错误: ", + "missing-conf": "未设置服务器", + "duplicate-path": "同一路径上不能有两个WebSocket侦听器: __path__" + } + }, + "watch": { + "watch": "watch", + "label": { + "files": "文件", + "recursive": "递归所有子文件夹" + }, + "placeholder": { + "files": "逗号分开文件或文件夹" + }, + "tip": "在Windows上,请务必使用双斜杠 \\\\ 来隔开文件夹名字" + }, + "tcpin": { + "label": { + "type": "类型", + "output": "输出", + "port": "端口", + "host": "主机地址", + "payload": "有效载荷", + "delimited": "分隔符号", + "close-connection": "是否在成功发送每条信息后断开连接?", + "decode-base64": "用 Base64 解码信息?", + "server": "服务器", + "return": "返回", + "ms": "毫秒", + "chars": "字符" + }, + "type": { + "listen": "监听", + "connect": "连接", + "reply": "响应 TCP" + }, + "output": { + "stream": "字串流", + "single": "单一", + "buffer": "Buffer", + "string": "字符串", + "base64": "Base64 字符串" + }, + "return": { + "timeout": "指定时间后", + "character": "当收到某个字符为", + "number": "指定字符数", + "never": "永不 - 保持连接", + "immed": "马上 - 不需要等待回复" + }, + "status": { + "connecting": "正在连接到 __host__:__port__", + "connected": "已经连接到 __host__:__port__", + "listening-port": "监听端口 __port__", + "stopped-listening": "已停止监听端口", + "connection-from": "连接来自 __host__:__port__", + "connection-closed": "连接已关闭 __host__:__port__", + "connections": "__count__ 个连接", + "connections_plural": "__count__ 个连接" + + }, + "errors": { + "connection-lost": "连接中断 __host__:__port__", + "timeout": "超时关闭套接字连接,端口 __port__", + "cannot-listen": "无法监听端口 __port__, 错误: __error__", + "error": "错误: __error__", + + "socket-error": "套接字连接错误来自 __host__:__port__", + "no-host": "主机地址或端口未设定", + "connect-timeout": "连接超时", + "connect-fail": "连接失败" + } + }, + "udp": { + "label": { + "listen": "监听", + "onport": "端口", + "using": "使用", + "output": "输出", + "group": "组", + "interface": "本地IP", + "send": "发送一个", + "toport": "到端口", + "address": "地址", + "decode-base64": "是否解码Base64编码的信息?" + }, + "placeholder": { + "interface": "(可选)eth0的IP地址", + "interfaceprompt": "(可选) 要绑定的本地接口或地址", + "address": "目标IP地址" + }, + "udpmsgs": "udp信息", + "mcmsgs": "组播信息", + "udpmsg": "udp信息", + "bcmsg": "广播信息", + "mcmsg": "组播信息", + "output": { + "buffer": "Buffer", + "string": "字符串", + "base64": "Base64编码字符串" + }, + "bind": { + "random": "绑定到任意本地端口", + "local": "绑定到本地端口", + "target": "绑定到目标端口" + }, + "tip": { + "in": "提示:确保您的防火墙将允许数据进入", + "out": "提示:如果要使用<code>msg.ip</code>和<code>msg.port</code>设置,请将地址和端口留空", + "port": "正在使用端口: " + }, + "status": { + "listener-at": "udp 监听器正在监听 __host__:__port__", + "mc-group": "udp 组播到 __group__", + "listener-stopped": "udp 监听器已停止", + "output-stopped": "udp 输出已停止", + "mc-ready": "udp 组播已准备好: __outport__ -> __host__:__port__", + "bc-ready": "udp 广播已准备好: __outport__ -> __host__:__port__", + "ready": "udp 已准备好: __outport__ -> __host__:__port__", + "ready-nolocal": "udp 已准备好: __host__:__port__", + "re-use": "udp 重用套接字: __outport__ -> __host__:__port__" + }, + "errors": { + "access-error": "UDP 访问错误, 你可能需要root权限才能接入1024以下的端口", + "error": "错误: __error__", + "bad-mcaddress": "无效的组播地址", + "interface": "必须是指定接口的IP地址", + "ip-notset": "udp: IP地址未设定", + "port-notset": "udp: 端口未设定", + "port-invalid": "udp: 无效端口号码", + "alreadyused": "udp: 端口已被占用", + "ifnotfound": "udp: 接口 __iface__ 未发现" + } + }, + "switch": { + "switch": "switch", + "label": { + "property": "属性", + "rule": "规则", + "repair" : "重建信息队列" + }, + "previous": "先前值", + "and": "与", + "checkall": "全选所有规则", + "stopfirst": "接受第一条匹配信息后停止", + "ignorecase": "忽略大小写", + "rules": { + "btwn":"在之间", + "cont":"包含", + "regex":"匹配正则表达式", + "true":"为真", + "false":"为假", + "null":"为空", + "nnull":"非空", + "istype": "类型是", + "empty": "为空", + "nempty": "非空", + "head":"头", + "tail":"尾", + "index":"索引在..中间", + "exp":"JSONata表达式", + "else":"除此以外", + "hask": "拥有键" + }, + "errors": { + "invalid-expr": "无效的JSONata表达式: __error__", + "too-many" : "Switch节点中有太多待定信息" + } + }, + "change": { + "label": { + "rules": "规则", + "rule": "规则", + "set": "设定 __property__", + "change": "修改 __property__", + "delete": "删除 __property__", + "move": "移动 __property__", + "changeCount": "修改: __count__条规矩", + "regex": "使用正则表达式" + }, + "action": { + "set": "设定", + "change": "修改", + "delete": "删除", + "move": "转移", + "to": "到", + "search": "搜索", + "replace": "替代为" + }, + "errors": { + "invalid-from": "无效的'from'属性: __error__", + "invalid-json": "无效的'to'JSON 属性", + "invalid-expr": "无效的JSONata表达式: __error__" + } + }, + "range": { + "range": "range", + "label": { + "action": "操作", + "inputrange": "映射输入数据", + "resultrange": "至目标范围", + "from": "从", + "to": "到", + "roundresult": "取最接近整数?" + }, + "placeholder": { + "min": "e.g. 0", + "maxin": "e.g. 99", + "maxout": "e.g. 255" + }, + "scale": { + "payload": "按比例msg.payload", + "limit": "按比例并设定界限至目标范围", + "wrap": "按比例并包含在目标范围内" + }, + "tip": "提示: 此节点仅对数字有效", + "errors": { + "notnumber": "不是一个数字" + } + }, + "csv": { + "label": { + "columns": "列", + "separator": "分隔符", + "c2o": "CSV至对象", + "o2c": "对象至CSV", + "input": "输入", + "skip-s": "忽略前", + "skip-e": "行", + "firstrow": "第一行包含列名", + "output": "输出", + "includerow": "包含列名行", + "newline": "换行符", + "usestrings": "解析数值" + }, + "placeholder": { + "columns": "用逗号分割列名" + }, + "separator": { + "comma": "逗号", + "tab": "Tab", + "space": "空格", + "semicolon": "分号", + "colon": "冒号", + "hashtag": "井号", + "other": "其他..." + }, + "output": { + "row": "每行一条信息", + "array": "仅一条信息 [数组]" + }, + "newline": { + "linux": "Linux (\\n)", + "mac": "Mac (\\r)", + "windows": "Windows (\\r\\n)" + }, + "errors": { + "csv_js": "此节点仅处理CSV字符串或JS对象", + "obj_csv": "对象->CSV转换未设定列模版" + } + }, + "html": { + "label": { + "select": "选取项", + "output": "输出", + "in": "in" + }, + "output": { + "html": "选定元素的html内容", + "text": "选定元素的纯文本内容", + "attr": "包含选定元素的所有属性的对象" + }, + "format": { + "single": "一条信息 [数组]", + "multi": "多条信息,每条一个元素" + } + }, + "json": { + "errors": { + "dropped-object": "忽略非对象格式的有效负载", + "dropped": "忽略不支持格式的有效负载类型", + "dropped-error": "转换有效负载失败", + "schema-error": "JSON架构错误", + "schema-error-compile": "JSON架构错误: 未能编译架构" + }, + "label": { + "o2j": "对象至JSON", + "pretty": "格式化JSON字符串", + "action": "操作", + "property": "属性", + "actions": { + "toggle": "JSON字符串与对象互转", + "str":"总是转为JSON字符串", + "obj":"总是转为JS对象" + } + } + }, + "yaml": { + "errors": { + "dropped-object": "忽略非对象格式的有效负载", + "dropped": "忽略不支持格式的有效负载类型", + "dropped-error": "转换有效负载失败" + } + }, + "xml": { + "label": { + "represent": "XML标签属性的属性名称", + "prefix": "标签文本内容的属性名称", + "advanced": "高级选项", + "x2o": "XML到对象选项" + }, + "errors": { + "xml_js": "此节点仅处理XML字符串或JS对象." + } + }, + "file": { + "label": { + "filename": "文件名", + "action": "行为", + "addnewline": "向每个有效载荷添加换行符(\\n)?", + "createdir": "创建目录(如果不存在)?", + "outputas": "输出", + "breakchunks": "分拆成块", + "breaklines": "分拆成行", + "filelabel": "文件", + "sendError": "发生错误时发送消息(传统模式)", + "deletelabel": "删除 __file__", + "encoding": "编码", + "utf8String": "UTF8字符串", + "binaryBuffer": "二进制buffer" + }, + "action": { + "append": "追加至文件", + "overwrite": "复写文件", + "delete": "删除文件" + }, + "output": { + "utf8": "一个utf8字符串", + "buffer": "一个Buffer对象", + "lines": "每行一条信息", + "stream": "一个Buffer流" + }, + "status": { + "wrotefile": "写入至文件: __file__", + "deletedfile": "删除文件: __file__", + "appendedfile": "追加至文件: __file__" + }, + "encoding": { + "none": "默认", + "native": "Native", + "unicode": "Unicode", + "japanese": "日本", + "chinese": "中国", + "korean": "韩国", + "taiwan": "台湾/香港", + "windows": "Windows代码页", + "iso": "ISO代码页", + "ibm": "IBM代码页", + "mac": "Mac代码页", + "koi8": "KOI8代码页", + "misc": "其它" + }, + "errors": { + "nofilename": "未指定文件名", + "invaliddelete": "警告:无效删除。请在配置对话框中使用特定的删除选项", + "deletefail": "无法删除文件: __error__", + "writefail": "无法写入文件: __error__", + "appendfail": "无法追加到文件: __error__", + "createfail": "文件创建失败: __error__" + }, + "tip": "提示: 文件名应该是绝对路径,否则它将相对于Node-RED进程的工作目录。" + }, + "split": { + "split": "split", + "intro":"基于以下类型拆分<code>msg.payload</code>:", + "object":"<b>对象</b>", + "objectSend":"每个键值对作为单个消息发送", + "strBuff":"<b>字符串</b> / <b>Buffer</b>", + "array":"<b>数组</b>", + "splitUsing":"拆分使用", + "splitLength":"固定长度", + "stream":"作为消息流处理", + "addname":" 复制键到 " + }, + "join":{ + "join": "join", + "mode":{ + "mode":"模式", + "auto":"自动", + "merge":"合并序列", + "reduce":"缩减序列", + "custom":"手动" + }, + "combine":"合并每个", + "completeMessage": "完整的消息", + "create":"输出为", + "type":{ + "string":"字符串", + "array":"数组", + "buffer":"Buffer", + "object":"键值对对象", + "merged":"合并对象" + }, + "using":"使用此值", + "key":"作为键", + "joinedUsing":"合并符号", + "send":"发送信息:", + "afterCount":"达到一定数量的信息时", + "count":"数量", + "subsequent":"和每个后续的消息", + "afterTimeout":"第一条消息的若干时间后", + "seconds":"秒", + "complete":"在收到存在<code>msg.complete</code>的消息后", + "tip":"此模式假定此节点与<i>split</i>相连, 或者接收到的消息有正确配置的<code>msg.parts</code>属性.", + "too-many" : "join节点中有太多待定信息", + "merge": { + "topics-label":"合并主题", + "topics":"主题", + "topic" : "主题", + "on-change":"当收到一个新主题时发送已合并信息" + }, + "reduce": { + "exp": "Reduce表达式", + "exp-value": "exp", + "init": "初始值", + "right": "反向求值(从后往前)", + "fixup": "Fix-up exp" + }, + "errors": { + "invalid-expr": "无效的JSONata表达式: __error__" + } + }, + "sort" : { + "sort": "排序", + "target" : "排序属性", + "seq" : "信息队列", + "key" : "键值", + "elem" : "元素值", + "order" : "顺序", + "ascending" : "升序", + "descending" : "降序", + "as-number" : "作为数值", + "invalid-exp" : "排序节点中存在无效的JSONata表达式", + "too-many" : "排序节点中有太多待定信息", + "clear" : "清空排序节点中的待定信息" + }, + "batch" : { + "batch": "batch", + "mode": { + "label" : "模式", + "num-msgs" : "按指定数量分组", + "interval" : "按时间间隔分组", + "concat" : "按主题分组" + }, + "count": { + "label" : "分组数量", + "overlap" : "队末队首重叠数量", + "count" : "数量", + "invalid" : "无效的分组数量或重叠数量" + }, + "interval": { + "label" : "时间间隔", + "seconds" : "秒", + "empty" : "无数据到达时发送空信息" + }, + "concat": { + "topics-label": "主题", + "topic" : "主题" + }, + "too-many" : "batch节点中有太多待定信息", + "unexpected" : "未知模式", + "no-parts" : "信息中没有parts属性" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/05-tls.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/05-tls.html new file mode 100644 index 0000000..5a96039 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/05-tls.html @@ -0,0 +1,19 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="tls-config"> + <p>TLS连接的配置选项。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/06-httpproxy.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/06-httpproxy.html new file mode 100644 index 0000000..e849719 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/06-httpproxy.html @@ -0,0 +1,22 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http proxy"> + <p>HTTP代理的配置选项。</p> + + <h3>详细</h3> + <p>访问代理例外列表中的主机时,将不使用任何代理。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/10-mqtt.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/10-mqtt.html new file mode 100644 index 0000000..520d7f4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/10-mqtt.html @@ -0,0 +1,71 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="mqtt in"> +<p>连接到MQTT代理并订阅来自指定主题的消息。</p> + <h3>输出</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">字符串 | buffer</span></dt> + <dd>如果不是二进制buffer的话就是字符串</dd> + <dt>topic <span class="property-type">字符串</span></dt> + <dd>MQTT主题,使用<code>/</code>作为层次结构分隔符。</dd> + <dt>qos <span class="property-type">数值</span> </dt> + <dd>QoS服务质量:0, 最多一次; 1, 最少一次; 2, 只一次。</dd> + <dt>retain <span class="property-type">布尔值</span></dt> + <dd>值为true时表示消息已保留且可能是旧的。</dd> + </dl> + <h3>详细</h3> + <p>订阅主题可以包括MQTT通配符(+:一个级别,#:多个级别)。</p> + <p>使用该节点您首先需要建立与MQTT代理的连接。通过单击铅笔图标来进行配置。</p> + <p>如有需要,几个MQTT节点(输入或输出)可以共享相同的代理连接。</p> +</script> + +<script type="text/x-red" data-help-name="mqtt out"> + <p>连接到MQTT代理并发布消息。</p> + <h3>输入</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">字符串 | buffer</span></dt> + <dd>要发布的有效负载。如果未设置此属性,则不会发送任何消息。要发送空白消息,请将此属性设置为空字符串。</dd> + + <dt class="optional">topic <span class="property-type">字符串</span></dt> + <dd>要发布的MQTT主题。</dd> + + <dt class="optional">qos <span class="property-type">number</span></dt> + <dd>QoS服务质量:0, 最多一次; 1, 最少一次; 2, 只一次。默认值为0。</dd> + + <dt class="optional">retain <span class="property-type">布尔值</span></dt> + <dd>设置为<code>true</code>来将消息保留在代理上。默认值为<code>false</code>。</dd> + </dl> + <h3>详细</h3> + <p><code>msg.payload</code>用作已发布消息的有效载荷。如果包含Object,则会在发送之前将其转换为JSON字符串。如果它包含二进制buffer,则消息将按原样发布。</p> + <p>可以在节点中配置所使用的主题,或者如果留为空白,则可以通过<code>msg.topic</code>进行设置。</p> + <p>同样,可以在节点中配置QoS和保留值,或者如果保留空白,则分别由<code>msg.qos</code>和<code>msg.retain</code>设置。要清除先前存储在代理中的主题,请设置保留标志并向该主题发布空消息。</p> + <p>该节点需要与要配置的MQTT代理的连接。通过单击铅笔图标进行配置。</p> + <p>如果需要,几个MQTT节点(输入或输出)可以共享相同的代理连接。</p> +</script> + +<script type="text/x-red" data-help-name="mqtt-broker"> + <p>与MQTT代理的连接设置。</p> + <p>创建与代理的连接设置。可以在<code>MQTT In</code>和<code>MQTT Out</code>节点中重复利用这些设置。</p> + <p>如果未为该节点设置客户端ID,并且设置了会话初始化,则将生成一个随机客户端ID。设置客户端ID时,请确保它对于连接目标处的代理是唯一的。</p> + <h4>Birth Message</h4> + <p>建立连接后发布在以配置主题中的消息。</p> + <h4>Close Message</h4> + <p>在连接正常结束之前重新部署或者关闭了节点时,发布在以配置主题中的消息。</p> + <h4>Will Message</h4> + <p>当节点意外丢失连接时由代理发布的消息</p> + <h4>WebSockets</h4> + <p>可以将节点配置成使用WebSocket连接。使用WebSocket时,请在服务器字段中以完整格式描述连接目标的URI。 例如:</p> + <pre>ws://example.com:4000/mqtt</pre> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/21-httpin.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/21-httpin.html new file mode 100644 index 0000000..0fb52ef --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/21-httpin.html @@ -0,0 +1,81 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http in"> + <p>创建用于创建Web服务的HTTP端点。</p> + <h3>输出</h3> + <dl class="message-properties"> + <dt>payload</dt> + <dd>GET请求包含任何查询字符串参数的对象。或者包含HTTP请求正文。</dd> + <dt>req<span class="property-type">object</span></dt> + <dd>HTTP请求对象。该对象包含有关请求信息的多个属性。 + <ul> + <li><code>body</code> - 传入请求的正文。格式将取决于请求。</li> + <li><code>headers</code> - 包含HTTP请求标头的对象。</li> + <li><code>query</code> - 包含任何查询字符串参数的对象。</li> + <li><code>params</code> - 包含任何路由参数的对象。</li> + <li><code>cookies</code> - 包含请求cookie的对象。</li> + <li><code>files</code> - 如果节点启用了文件上传,则为包含了上传的文件的对象。</li> + </ul> + </dd> + <dt>res<span class="property-type">object</span></dt> + <dd>HTTP响应对象。此属性不应直接使用;<code>HTTP Response</code>节点记录了如何响应请求。该属性必须保留在传递给响应节点的消息上。</dd> + </dl> + <h3>详细</h3> + <p>节点将在配置的路径上监听特定类型的请求。路径可以完全指定,例如<code>/user</code>,或包括可以接受任何值的命名参数,例如<code>/user/:name</code>。 使用命名参数时,可以在<code>msg.req.params</code>下访问其在请求中的实际值。</p> + <p>对于包含正文的请求(例如POST或PUT),请求的内容将作为<code>msg.payload</code>提供。</p> + <p>如果可以确定请求的内容类型,则正文将被解析为任何适当的类型。例如,<code>application/json</code>将被解析为其JavaScript对象表示。</p> + <p><b>注意:</b>该节点不发送对请求的任何响应。该流必须包含HTTP响应节点才能完成请求。</p> +</script> + +<script type="text/x-red" data-help-name="http response"> + <p>将响应发送回从HTTP输入节点接收的请求。</p> + + <h3>输入</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">string</span></dt> + <dd>响应的正文。</dd> + <dt class="optional">statusCode <span class="property-type">数值</span></dt> + <dd>如果设置,则用作响应状态代码。默认值:200。</dd> + <dt class="optional">headers <span class="property-type">object</span></dt> + <dd>如果设置,则提供HTTP头以包含在响应中。</dd> + <dt class="optional">cookies <span class="property-type">object</span></dt> + <dd>如果设置,则可用于设置或删除cookie。</dd> + </dl> + <h3>详细</h3> + <p>还可以在节点本身内设置<code>statusCode</code>和<code>headers</code>。如果在节点内设置了属性,则不能被相应的message属性覆盖。</p> + <h4>Cookie处理</h4> + <p><code>cookies</code>属性必须是名称/值对的对象。该值可以是使用默认选项设置cookie值的字符串,也可以是options对象。<p> + <p>下面的示例设置两个cookie-一个名为<code>name</code>的值为<code>nick</code>,另一个名为<code>session</code>的值为<code>1234</code>,并且有效期设置为15分钟。</p> + <pre> +msg.cookies = { + name: 'nick', + session: { + value: '1234', + maxAge: 900000 + } +}</pre> + <p>有效选项包括:</p> + <ul> + <li><code>domain</code> - (字符串) Cookie的域名</li> + <li><code>expires</code> - (日期) GMT标准时间的到期日。如果未指定或设置为0,则创建会话cookie</li> + <li><code>maxAge</code> - (字符串) 相对于当前时间的到期日期(以毫秒为单位)</li> + <li><code>path</code> - (字符串) Cookie的路径。默认为/</li> + <li><code>value</code> - (字符串) Cookie使用的值</li> + </ul> + <p>要删除Cookie,请将其<code>value</code>设置为<code>null</code>。</p> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/21-httprequest.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/21-httprequest.html new file mode 100644 index 0000000..3c7b163 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/21-httprequest.html @@ -0,0 +1,78 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http request"> + <p>发送HTTP请求并返回响应。</p> + + <h3>输入</h3> + <dl class="message-properties"> + <dt class="optional">url <span class="property-type">字符串</span></dt> + <dd>如果未在节点中配置,则此可选属性设置请求的url。</dd> + <dt class="optional">method <span class="property-type">字符串</span></dt> + <dd>如果未在节点中配置,则此可选属性设置请求的HTTP方法。必须是<code>GET</code>,<code>PUT</code>,<code>POST</code>,<code>PATCH</code>或<code>DELETE</code>之一。</dd> + <dt class="optional">headers <span class="property-type">object</span></dt> + <dd>设置请求的HTTP头。</dd> + <dt class="optional">cookies <span class="property-type">object</span></dt> + <dd>如果设置,则可用于发送带有请求的cookie。</dd> + <dt class="optional">payload</dt> + <dd>发送为请求的正文。</dd> + <dt class="optional">rejectUnauthorized</dt> + <dd>如果设置为<code>false</code>,则允许对使用自签名证书的https站点进行请求。</dd> + <dt class="optional">followRedirects</dt> + <dd>如果设置为<code>false</code>,则阻止遵循重定向(HTTP 301)。默认情况下为<code>true</code></dd> + <dt class="optional">requestTimeout</dt> + <dd>如果设置为正数毫秒,将覆盖全局设置的<code>httpRequestTimeout</code>参数。</dd> + </dl> + <h3>输出</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">字符串 | object | buffer</span></dt> + <dd>响应的正文。可以将节点配置为以字符串形式返回主体,尝试将其解析为JSON字符串或将其保留为二进制buffer。</dd> + <dt>statusCode <span class="property-type">数值</span></dt> + <dd>响应的状态码,如果请求无法完成,则返回错误码。</dd> + <dt>headers <span class="property-type">object</span></dt> + <dd>包含响应头的对象。</dd> + <dt>responseUrl <span class="property-type">字符串</span></dt> + <dd>如果在处理请求时发生任何重定向,则此属性为最终重定向的URL。否则则为原始请求的URL。</dd> + <dt>responseCookies <span class="property-type">object</span></dt> + <dd>如果响应包含cookie,则此属性是每个cookie的‘名称/值’键值对的对象。</dd> + <dt>redirectList <span class="property-type">数组</span></dt> + <dd>如果请求被重定向了一次或多次,则累积的信息将被添加到此属性。“location”是下一个重定向目标。cookie是从重定向源返回的cookie。</dd> + </dl> + <h3>详细</h3> + <p>在节点内配置后,URL属性可以包含<a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache样式</a>标签。 这些标签允许使用传入消息的值来构造url。例如,如果url设置为<code>example.com/{{{{topic}}}</code>,它将自动插入<code>msg.topic</code>的值。使用{{{...}}}可以防止mustache转义/ &等字符。</p> + <p>节点可以选择自动将<code>msg.payload</code>编码为GET请求的查询字符串参数,在这种情况下,<code>msg.payload</code>必须是一个对象。</p> + <p><b>注意:</b>如果使用了代理,则应设置<code>http_proxy=...</code>环境变量并重新启动Node-RED,或使用“代理配置”。如果设置了代理配置,则配置优先于环境变量。</p> + <h4>使用多个HTTP请求节点</h4> + <p>为了在一个流程中多次使用该节点,必须要注意<code>msg.headers</code>属性的处理。通常在第一个节点在响应头中设置此属性,而不期望在下一个节点的请求头中使用此属性。如果节点之间的<code>msg.headers</code>属性保持不变,则第二个节点将忽略它。要设置自定义标题,首先应删除<code>msg.headers</code>或将其重置为空对象:<code>{}</code>。</p> + <h4>Cookie处理</h4> + <p>传递给节点的<code>cookies</code>属性必须是‘名称/值’键值对的对象。该值可以是设置cookie值的字符串,也可以是具有单个<code>value</code>属性的对象。</p> + <p>请求返回的所有cookie都将在<code>responseCookies</code>属性下传递回去。</p> + <h4>内容类型处理</h4> + <p>如果<code>msg.payload</code>是一个对象,则节点将自动将请求的内容类型设置为<code>application/json</code>并对其进行编码。</p> + <p>要将请求编码为表单数据,应将<code>msg.headers[“content-type”]</code>设置为<code>application/x-www-form-urlencoded</code>。</p> + <h4>文件上传</h4> + <p>要执行文件上传,应将<code>msg.headers["content-type"]</code>设置为<code>multipart/form-data</code>和<code>msg.payload</code>传递给节点的必须是具有以下结构的对象:</p> + <pre><code>{ + "KEY": { + "value": FILE_CONTENTS, + "options": { + "filename": "FILENAME" + } + } +}</code></pre> + <p><code>KEY</code>,<code>FILE_CONTENTS</code>和<code>FILENAME</code>的值应设置为适当的值。</p> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/22-websocket.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/22-websocket.html new file mode 100644 index 0000000..d2ee29d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/22-websocket.html @@ -0,0 +1,35 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="websocket in"> + <p>WebSocket输入节点。</p> + <p>默认情况下,从WebSocket接收的数据将位于<code>msg.payload</code>中。可以将套接字配置为期望格式正确的JSON字符串,在这种情况下,它将解析JSON并将结果对象作为整个消息发送。</p> +</script> + +<script type="text/x-red" data-help-name="websocket out"> + <p>WebSocket输出节点。</p> + <p>默认情况下,<code>msg.payload</code>将通过WebSocket发送。可以将套接字配置为将整个<code>msg</code>对象编码为JSON字符串,然后通过WebSocket发送。</p> + <p>如果到达此节点的消息是从WebSocket In节点开始的,则该消息将发送回触发流程的客户端。否则,消息将广播给所有连接的客户端。</p> + <p>如果要广播从“WebSocket输入”节点开始的消息,则可以应该删除流中的<code>msg._session</code>属性。</p> +</script> + +<script type="text/x-red" data-help-name="websocket-listener"> + <p>此配置节点使用指定的路径创建WebSocket服务器端点。</p> +</script> + +<script type="text/x-red" data-help-name="websocket-client"> + <p>此配置节点将WebSocket客户端连接到指定的URL。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/31-tcpin.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/31-tcpin.html new file mode 100644 index 0000000..2f00ed5 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/31-tcpin.html @@ -0,0 +1,35 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="tcp in"> + <p>提供TCP输入选择。可以连接到远程TCP端口,或接受传入连接。</p> + <p><b>注意:</b>在某些系统上,您可能需要root或管理员权限来访问低于1024的端口。</p> +</script> + +<script type="text/x-red" data-help-name="tcp out"> + <p>提供TCP输出的选择。可以连接到远程TCP端口,接受传入的连接,或回复从TCP In节点收到的消息。</p> + <p>仅发送<code>msg.payload</code>。</p> + <p>如果<code>msg.payload</code>是包含二进制数据的Base64编码的字符串,则Base64解码选项将导致它在发送之前先转换回二进制。</p> + <p>如果不存在<code>msg._session</code>,则有效负载将发送到<b>所有</b>连接的客户端。</p> + <p><b>注意:</b>在某些系统上,您可能需要root或管理员权限来访问低于1024的端口。</p> +</script> + +<script type="text/x-red" data-help-name="tcp request"> + <p>一个简单的TCP请求节点。将<code>msg.payload</code>发送到服务器tcp端口,并期望得到响应。</p> + <p>连接到服务器,发送“请求”并接收“响应”。 可以从固定数量的字符,与指定字符匹配的字符中选择操作,从第一个答复到达起等待指定的时间,等待数据到达,发送数据并立即取消连接而无需等待答复等操作中进行选择。</p> + <p>响应将在<code>msg.payload</code>中作为buffer输出,因此您可能需要对它进行<code>.toString()</code>操作。</p> + <p>如果将tcp主机或端口留空,则必须使用<code>msg.host</code>和<code>msg.port</code>属性进行设置。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/32-udp.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/32-udp.html new file mode 100644 index 0000000..1e01aa0 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/network/32-udp.html @@ -0,0 +1,28 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="udp in"> + <p>UDP输入节点。在<code>msg.payload</code>中生成Buffer,字符串或Base64编码的字符串。支持组播。</p> + <p>在<code>msg.ip</code>和<code>msg.port</code>中设置接收到的消息的IP地址和端口。</p> + <p><b>注意:</b>在某些系统上,您可能需要root或管理员权限才能使用低于1024的端口或广播。</p> +</script> + +<script type="text/x-red" data-help-name="udp out"> + <p>该节点将<code>msg.payload</code>发送到指定的UDP主机和端口。支持组播。</p> + <p>您也可以使用<code>msg.ip</code>和<code>msg.port</code>设置目标值,但是静态配置的值具有优先权。</p> + <p>如果选择广播,则将地址设置为本地广播IP地址。或者也可以尝试使用全局广播地址255.255.255.255。</p> + <p><b>注意:</b>在某些系统上,您可能需要root或管理员权限才能使用低于1024的端口或广播。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/parsers/70-CSV.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/parsers/70-CSV.html new file mode 100644 index 0000000..5657f4c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/parsers/70-CSV.html @@ -0,0 +1,43 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="csv"> + <p>在CSV格式的字符串及其JavaScript对象表示形式之间进行相互转换。</p> + <h3>输入</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 数组 | 字符串</span></dt> + <dd>JavaScript对象,数组或CSV字符串。</dd> + </dl> + <h3>输出</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 数组 | 字符串</span></dt> + <dd> + <ul> + <li>如果输入是字符串,它将尝试将其解析为CSV,并为每行创建键/值对的JavaScript对象。然后该节点将为每行发送一条消息,或者发送一条包含对象数组的消息。</li> + <li>如果输入是JavaScript对象,它将尝试构建CSV字符串。</li> + <li>如果输入是简单值的数组,则将构建单行CSV字符串。</li> + <li>如果输入是数组数组或对象数组,则会创建多行CSV字符串。</li> + </ul> + </dd> + </dl> + <h3>详细</h3> + <p>列模板可以包含列名称的有序列表。将CSV转换为对象时,列名将用作属性名称。或者也可以从CSV的第一行中获取列名称。</p> + <p>转换为CSV时,列模板用于标识从对象中提取的属性以及提取的顺序。</p> + <p>如果输入是数组,则列模板仅用于有选择地生成一行列标题。</p> + <p>只要正确设置<code>parts</code>属性,该节点就可以接受多部分输入。</p> + <p>如果输出多个消息,则将设置其<code>parts</code>属性并形成完整的消息序列。</p> + <p><b>注意:</b>列模板必须用逗号分隔,即使数据中已有了其他分隔符。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/parsers/70-HTML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/parsers/70-HTML.html new file mode 100644 index 0000000..73b3656 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/parsers/70-HTML.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="html"> + <p>使用CSS选择器从<code>msg.payload</code>中保存的html文档中提取元素。</p> + <h3>输入</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">字符串</span></dt> + <dd>从中提取元素的html字符串。</dd> + <dt class="optional">select <span class="property-type">字符串</span></dt> + <dd>如果未在编辑面板中配置,则可以将选择器设置为msg的属性。</dd> +</dl> + <h3>Output</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">数组 | 字符串</span></dt> + <dd>结果可以是有效载荷中包含匹配元素的数组的单个消息;也可以是多条消息,每条消息都包含匹配元素。发送多条消息时,需要为消息设置<code>parts</code>。</dd> + </dl> + <h3>详细</h3> + <p>该节点支持CSS和jQuery选择器的组合。查看<a href="https://github.com/fb55/CSSselect#user-content-supported-selectors" target="_blank">css-select documentation</a> 来获得更多信息。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/parsers/70-JSON.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/parsers/70-JSON.html new file mode 100644 index 0000000..2e574a0 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/parsers/70-JSON.html @@ -0,0 +1,43 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="json"> + <p>在JSON字符串及其JavaScript对象表示形式之间相互转换。</p> + <h3>输入</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 字符串</span></dt> + <dd>JavaScript对象或JSON字符串。</dd> + <dt>schema<span class="property-type">object</span></dt> + <dd>可选的JSON Schema对象用于验证有效负载。在将<code>msg</code>发送到下一个节点之前,将删除该属性。</dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 字符串</span></dt> + <dd> + <ul> + <li>如果输入是JSON字符串,它将尝试将其解析为JavaScript对象。</li> + <li>如果输入是JavaScript对象,它将创建一个JSON字符串。并可以选择对此JSON字符串进行整形。</li> + </ul> + </dd> + <dt>schemaError<span class="property-type">数组</span></dt> + <dd>如果JSON模式验证失败,则catch节点将具有包含错误数组的<code>schemaError</code>属性。</dd> + </dl> + <h3>详细</h3> + <p>默认的转换目标是<code>msg.payload</code>,但是也可以转换消息的其它属性。</p> + <p>您可以将其设置为仅执行特定的转换,而不是自动选择双向转换。例如,即使对<code>HTTP In</code>节点的请求未正确设置‘content-type’,也可以使用它来确保JSON节点的转换结果是JavaScript对象</p> + <p>如果指定了转换为JSON字符串,则不会对收到的字符串进行进一步的检查。也就是说,即使指定了格式化选项,它也不会检查字符串是否正确为JSON或对JSON执行整形。</p> + <p>有关JSON模式的更多详细信息,请查阅<a href="http://json-schema.org/latest/json-schema-validation.html">规范</a>.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/parsers/70-XML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/parsers/70-XML.html new file mode 100644 index 0000000..04a7783 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/parsers/70-XML.html @@ -0,0 +1,48 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="xml"> + <p>在XML字符串及其JavaScript对象表示形式之间进行相互转换。</p> + <h3>输入</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 字符串</span></dt> + <dd>JavaScript对象或XML字符串。</dd> + </dl> + <h3>输出</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 字符串</span></dt> + <dd> + <ul> + <li>如果输入是字符串,它将尝试将其解析为XML并创建一个JavaScript对象。</li> + <li>如果输入是JavaScript对象,它将尝试构建XML字符串。</li> + </ul> + </dd> + <dt class="optional">options <span class="property-type">object</span></dt> + <dd>可以将选项传递给内部使用的XML转换库。请参见<a href="https://github.com/Leonidas-from-XIV/node-xml2js/blob/master/README.md#options" target="_blank"> xml2js文档</a> 来获取更多信息。</dd> + </dl> + <h3>详细</h3> + <p>在XML和对象之间进行转换时,默认情况下XML属性会添加到名为<code>$</code>的属性中。将文本内容添加到名为<code>_</code>的属性中。这些属性名称可以在节点设置中更改。</p> + <p>例如,将如下所示转换以下XML:</p> + <pre>&lt;p class="tag"&gt;Hello World&lt;/p&gt;</pre> + <pre>{ + "p": { + "$": { + "class": "tag" + }, + "_": "Hello World" + } +}</pre> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/parsers/70-YAML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/parsers/70-YAML.html new file mode 100644 index 0000000..e65d1b8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/parsers/70-YAML.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="yaml"> + <p>在YAML格式的字符串及其JavaScript对象表示形式之间相互转换。</p> + <h3>输入</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 字符串</span></dt> + <dd>JavaScript对象或YAML字符串。</dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 字符串</span></dt> + <dd> + <ul> + <li>如果输入是YAML字符串,它将尝试将其解析为JavaScript对象。</li> + <li>如果输入是JavaScript对象,它将创建一个YAML字符串。</li> + </ul> + </dd> + </dl> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/sequence/17-split.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/sequence/17-split.html new file mode 100644 index 0000000..22f0183 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/sequence/17-split.html @@ -0,0 +1,133 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="split"> + <p>将一条消息拆分为一系列消息。</p> + + <h3>输入</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 字符串 | 数组 | buffer</span></dt> + <dd>节点的行为由<code>msg.payload</code>的类型决定: + <ul> + <li><b>字符串</b>/<b>buffer</b> - 使用指定的字符(默认值:<code>\n</code>),缓冲区序列或固定长度将消息拆分。</li> + <li><b>数组</b> - 消息被拆分为单个数组元素或固定长度的数组。</li> + <li><b>object</b> - 将为对象的每个键/值对发送一条消息。</li> + </ul> + </dd> + </dl> + <h3>输出</h3> + <dl class="message-properties"> + <dt>parts<span class="property-type">object</span></dt> + <dd>此属性包含有关如何将消息与原始消息分开的信息。如果传递给<b>join</b>节点,则可以将序列重组为单个消息。该属性具有以下属性: + <ul> + <li><code>id</code> - 一组消息的标识符</li> + <li><code>index</code> - 组中的位置</li> + <li><code>count</code> - 如果已知组中的邮件总数。请参阅下面的“流媒体模式”</li> + <li><code>type</code> - 消息的类型-字符串/数组/对象/buffer</li> + <li><code>ch</code> - 对于字符串或buffer,用于将消息拆分为字符串或字节数组的数据</li> + <li><code>key</code> - 对于对象,创建此消息的属性的键。可以将节点配置为也将此值复制到另一个消息属性,例如<code>msg.topic</code></li> + <li><code>len</code> - 使用固定长度值拆分消息时,每段子消息的长度</li> + </ul> + </dd> + </dl> + <h3>详细</h3> + <p>在使用<b>join</b>节点将序列重新组合为单个消息之前,推荐使用此节点来轻松地创建跨消息序列,执行通用操作的流。</p> + <p>它使用<code>msg.parts</code>属性跟踪序列的各个部分。</p> + <h4>流媒体模式</h4> + <p>该节点还可以用于重排消息流。例如,发送换行符终止命令的串行设备可能会传递一条消息,并在其末尾带有部分命令。 在“流模式”下,此节点将拆分一条消息并发送每个完整的段。如果末尾有部分片段,则该节点将保留该片段,并将其添加到收到的下一条消息之前。</p> + <p>在此模式下运行时,该节点将不会设置<code>msg.parts.count</code>属性,因为流中期望的消息数还是未知的。这意味着它不能在自动模式下与<b>join</b>节点一起使用。</p> +</script> + +<script type="text/x-red" data-help-name="join"> + <p>将消息序列合并为一条消息.</p> + <p>共有三种模式:</p> + <dl> + <dt>自动模式</dt> + <dd>与<b>split</b>节点配对时,它将自动将已被拆分的消息进行合并。</dd> + <dt>手动模式</dt> + <dd>手动地以各种方式合并消息序列。</dd> + <dt>列聚合模式</dt> + <dd>对消息列中的所有消息应用表达式以将其简化为单个消息。</dd> + </dl> + <h3>输入</h3> + <dl class="message-properties"> + <dt class="optional">parts<span class="property-type">object</span></dt> + <dd>使用自动模式时,所有的消息都应包含此属性。<b>split</b>节点会生成此属性,但也可以手动进行设置。该属性具有以下属性: + <ul> + <li><code>id</code> - 消息组的标识符</li> + <li><code>index</code> - 组中的位置</li> + <li><code>count</code> - 如果已知组中的邮件总数。请参阅下面的“流媒体模式”</li> + <li><code>type</code> - 消息的类型-字符串/数组/对象/buffer</li> + <li><code>ch</code> - 对于字符串或buffer,用于将消息拆分为字符串或字节数组的数据</li> + <li><code>key</code> - 对于对象,创建此消息的属性的键。可以将节点配置为也将此值复制到另一个消息属性,例如<code>msg.topic</code>/li> + <li><code>len</code> - 使用固定长度值拆分消息时,每段子消息的长度</li> + </ul> + </dd> + <dt class="optional">complete</dt> + <dd>如果设置,则节点将以其当前状态发送其输出消息。</dd> + </dl> + <h3>详细</h3> + + <h4>自动模式</h4> + <p>自动模式使用传入消息的<code>parts</code>属性来确定应如何连接序列。这使它可以自动逆转<b>split</b>节点的操作。</p> + + <h4>手动模式</h4> + <p>设置为以手动模式时,该节点能以各种不同的方法来处理消息:</p> + <ul> + <li><b>字符串</b>或<b>缓冲区</b>-通过将每条消息的选定属性与指定的连接字符或缓冲区连接起来。</li> + <li><b>数组</b> - 通过将每个选定的属性或整个消息添加到输出数组</li> + <li><b>键/值对象</b> - 通过使用每个消息的属性来确定存储所需值的键。</li> + <li><b>merged object</b> - 通过将每个消息的属性合并到一个对象下。</li> + </ul> + <p>输出消息的其他属性都取自发送结果前的最后一条消息。</p> + <p>可以用<i>计数</i>来确定应接收多少条消息来进行合并。对于对象输出,可以设置为达到此计数后的每条后续消息都发送一条输出。</p> + <p>可以用<i>超时</i>来设置发送新消息之前的等待时间。</p> + <p>如果收到设置了<b>msg.complete</b>属性的消息时发送输出消息并重置消息列数。</p> + <p>如果收到设置了<b>msg.reset</b>属性的消息,则部分收到的消息将被删除而不发送,同时重置消息列数。</p> + + <h4>列聚合模式</h4> + <p>选择列聚合模式时,将表达式应用于组成消息列的每条消息,并使用聚合值组成一条消息。</p> + + <dl class="message-properties"> + <dt>初始值</dt> + <dd>累积值的初始值(<code>$A</code>)。</dd> + <dt>聚合表达式</dt> + <dd>序列中的每个消息调用的JSONata表达式。结果将作为累加值传递到表达式的下一个调用。在表达式中,可以使用以下特殊变量: + <ul> + <li><code>$A</code>: 累计值 </li> + <li><code>$I</code>: 消息在序列中的索引</li> + <li><code>$N</code>: 序列中的消息数</li> + </ul> + </dd> + <dt>最终调整式子</dt> + <dd>可选的JSONata表达式,在将聚合表达式应用于序列中的所有消息之后应用。在表达式中,可以使用以下特殊变量: + <ul> + <li><code>$A</code>: 累计值</li> + <li><code>$N</code>: 消息在序列中的索引</li> + </ul> + </dd> + <p>默认情况下,按顺序从序列的第一条消息到最后一条消息应用聚合表达式。也可以选择以相反的顺序应用聚合表达式。</p> + </dl> + <p><b>例子:</b>给定一系列数字值,以下设置将计算平均值: + <ul> + <li><b>聚合表达式</b>: <code>$A+payload</code></li> + <li><b>初始值</b>: <code>0</code></li> + <li><b>最终调整式</b>: <code>$A/$N</code></li> + </ul> + </p> + <h4>储存讯息</h4> + <p>该节点将在内部缓存消息,以便跨序列工作。运行时设置<code>nodeMessageBufferMaxLength</code>可用于设定缓存的消息数。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/sequence/18-sort.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/sequence/18-sort.html new file mode 100644 index 0000000..226355a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/sequence/18-sort.html @@ -0,0 +1,41 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="sort"> + <p>对消息属性或消息序列进行排序的函数。</p> + <p>当配置为对消息属性进行排序时,节点将对指定消息属性所指向的数组数据进行排序。</p> + <p>当配置为对消息序列排序时,它将对消息重新排序。</p> + <p>排序顺序可以是:</p> + <ul> + <li><b>升序</b></li> + <li><b>降序</b></li> + </ul> + <p>对于数字,可以通过复选框指定数字顺序。</p> + <p>排序键可以是元素值,也可以是JSONata表达式来对属性值进行排序,还可以是message属性或JSONata表达式来对消息序列进行排序。<p> + <p>在对消息序列进行排序时,排序节点依赖于接收到的消息来设置<code>msg.parts</code>。拆分节点将生成此属性,但也可以手动创建。它具有以下属性:</p> + <p> + <ul> + <li><code>id</code> - 消息组的标识符</li> + <li><code>index</code> - 组中的位置</li> + <li><code>count</code> - 群组中的邮件总数</li> + </ul> + </p> + <p><b>注意:</b>在此节点的处理中,消息在内部存储。通过指定要累积的最大消息数,可以防止意外的高内存使用。默认设置是不限制消息数量。 + <ul> + <li><code>nodeMessageBufferMaxLength</code>属性在<b>settings.js</b>中设置。</li> + </ul> + </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/sequence/19-batch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/sequence/19-batch.html new file mode 100644 index 0000000..012f208 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/sequence/19-batch.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="batch"> + <p>根据各种规则创建消息序列。</p> + <h3>详细</h3> + <p>有三种创建消息序列的模式:</p> + <dl> + <dt>讯息数</dt> + <dd>将消息分组为给定长度的序列。 <b>overlap</b>(重叠)选项指定在一个序列的末尾应重复多少消息。</dd> + + <dt>时间间隔</dt> + <dd>对在指定时间间隔内到达的邮件进行分组。如果在该时间间隔内没有消息到达,则该节点可以选择发送空消息。</dd> + + <dt>串联序列</dt> + <dd>通过串联输入序列来创建消息序列。每条消息必须具有<code>msg.topic</code>属性和标识其序列的<code>msg.parts</code>属性。该节点配置有<code>topic</code>值列表,以标识所连接的顺序序列。 + </dd> + </dl> + <h4>储存讯息</h4> + <p>该节点将在内部缓冲消息,以便跨序列工作。运行时设置<code>nodeMessageBufferMaxLength</code>可用于限制节点将缓存多少消息。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/storage/10-file.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/storage/10-file.html new file mode 100644 index 0000000..eb38a52 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/storage/10-file.html @@ -0,0 +1,55 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/html" data-help-name="file"> + <p>将<code>msg.payload</code>写入文件,添加到末尾或替换现有内容。或者,它也可以删除文件。</p> + <h3>输入</h3> + <dl class="message-properties"> + <dt class="optional">filename<span class="property-type">字符串</span></dt> + <dd>如果未在节点中配置,则此可选属性可以设置文件名。</dd> + </dl> + <h3>输出</h3> + <p>写入完成后,输入消息将发送到输出端口。</p> + <h3>详细</h3> + <p>每个消息的有效荷载将添加到文件的末尾,可以选择在每个消息之间添加一个换行符(\n)。</p> + <p>如果使用<code>msg.filename</code>,则每次写入后文件都会关闭。为了获得最佳体验,请使用固定的文件名。</p> + <p>可以将其配置为覆盖整个文件,而不是在文件后添加段落。例如,在将二进制数据写入文件(例如图像)时,应使用此选项,并且应禁用添加换行符的选项。</p> + <p>可以从编码列表中指定写入文件的数据的编码。</p> + <p>您可以将此节点配置为删除文件。</p> +</script> + +<script type="text/html" data-help-name="file in"> + <p>以字符串或二进制缓冲区的形式读取文件的内容。</p> + <h3>输入</h3> + <dl class="message-properties"> + <dt class="optional">filename<span class="property-type">字符串</span></dt> + <dd>如果未在节点配置中设置,该属性可以选择要读取的文件名。</dd> + </dl> + <h3>输出</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">字符串 | buffer</span></dt> + <dd>文件的内容可以是字符串,也可以是二进制的buffer。</dd> + <dt class="optional">filename <span class="property-type">字符串</span></dt> + <dd>如果未在节点配置中设置,该属性可以选择要读取的文件名。</dd> + </dl> + <h3>详细</h3> + <p>文件名应该是绝对路径,否则将相对于Node-RED进程的工作目录。</p> + <p>在Windows上,可能需要使用转义路径分隔符,例如:<code>\\Users\\myUser</code>。</p> + <p>可以选择将文本文件拆分为几行,每行输出一条消息,或者将二进制文件拆分为较小的buffer块-块大小取决于操作系统,但通常为64k(Linux/Mac)或41k(Windows)。</p> + <p>当拆分为多条消息时,每条消息将具有<code>parts</code>属性集,从而形成完整的消息序列。</p> + <p>如果输出格式为字符串,则可以从编码列表中指定输入数据的编码。</p> + <p>应该使用Catch节点来捕获并处理错误。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/storage/23-watch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/storage/23-watch.html new file mode 100644 index 0000000..eec6114 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-CN/storage/23-watch.html @@ -0,0 +1,25 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="watch"> + <p>监视目录或文件中的更改。</p> + <p>您可以输入用逗号分隔的目录和/或文件的列表。您需要在所有带有空格的地方加上引号“...”。</p> + <p>在Windows上,必须在任何目录名称中使用双反斜杠<code>\\</code>。</p> + <p>实际更改的文件的完整文件名将放入<code>msg.payload</code>和<code>msg.filename</code>中,而监视列表的字符串化版本将在<code>msg.topic</code>中返回。</p> + <p><code>msg.file</code>仅包含已更改文件的短文件名。<code>msg.type</code>更改了事物的类型,通常是<i>file</i>或<i>directory</i>,而<code>msg.size</code>保留了文件的大小(以字节为单位)。</p> + <p>当然,在Linux中,<i>everything</i>也是一个文件,因此可以监视</p> + <p><b>注意:</b>该目录或文件必须存在才能被监视。如果文件或目录被删除,即使重新创建它也可能不再被监视。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/20-inject.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/20-inject.html new file mode 100644 index 0000000..046eddd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/20-inject.html @@ -0,0 +1,35 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="inject"> + <p>手動或定期得將消息注入流程中。消息的有效荷載可以為多種類型,包括字符串,JavaScript對象或當前時間。</p> + <h3>輸出</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">various</span></dt> + <dd>指定的消息的有效荷載。</dd> + <dt class="optional">topic <span class="property-type">字符串</span></dt> + <dd>可以在節點中配置的可選屬性。</dd> + </dl> + <h3>詳細</h3> + <p>通過使用特定的有效荷載,注入節點可以啟動流程。默認有效荷載是當前時間的時間戳(以毫秒為單位,自1970年1月1日起)。</p> + <p>該節點還支持注入字符串,數字,布林值,JavaScript對象或流程/全局上下文值。</p> + <p>默認情況下,節點可以通過在編輯器中單擊節點按鈕來手動觸發。同時也可以被設置為定期或按計劃注入。</p> + <p>另一個可選的設置是在每次啟動流程時注入一次。</p> + <p>可以指定的最大<i>間隔</i>約為596小時/24天。 但是,如果對於間隔超過一天的那些間隔,建議您使用scheduler節點來應對斷電或重啟。</p> + <p><b>注意</b>:選項<i>“時間間隔” </i>和<i>“特定時間” </i>使用了標準cron系統。這意味著因此“20分鐘”並不表示在此之後20分鐘,而是每小時的20分鐘,40分鐘。如果您希望設定為從現在開始的每20分鐘,那麽請使用<i>“間隔” </i>選項。</p> + <p><b>注意</b>: 如果您想在字符串中包含換行符,必須使用“功能”節點創建有效荷載。</p> + </script> + \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/21-debug.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/21-debug.html new file mode 100644 index 0000000..31f78e9 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/21-debug.html @@ -0,0 +1,25 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="debug"> + <p>在“調試”側邊欄選項卡和運行時日志中顯示選定的消息屬性。 默認情況下,它會顯示<code>msg.payload</code>的值,但您也可以將其設置成顯示任意屬性,完整消息或JSONata表達式的結果。</p> + <h3>詳細</h3> + <p>調試側邊欄會提供已發消息的結構化視圖,方便您查詢消息的結構。</p> + <p>JavaScript對象和數組可以根據需要來折疊或擴展。緩衝區對象可以顯示爲原始數據,也可以顯示爲字符串。</p> + <p>對任意條消息,調試側邊欄還會顯示接收消息的時間,發送消息的節點以及消息類型等信息。單擊源節點ID將在工作區中顯示該節點。</p> + <p>節點上的按鈕可用于啓用或禁用其輸出。建議禁用或刪除所有未使用的調試節點。</p> + <p>還可以通過配置節點,將所有消息發送到運行時的日志,或將簡短的數據(32個字符內)在調試節點下的狀態文本上顯示。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/24-complete.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/24-complete.html new file mode 100644 index 0000000..8627453 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/24-complete.html @@ -0,0 +1,24 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="complete"> + <p>當另一個節點完成對消息的處理時觸發流程。</p> + <h3>詳細</h3> + <p>如果一個節點通知運行時它已完成消息的處理,該節點可用于觸發第二個流程。</p> + <p>這個節點可以與沒有輸出端口的節點一起使用,例如在使用電子郵件發送節點來發送郵件後觸發一個流程。</p> + <p>此節點只能被設置爲處理流程中某個所選節點的事件。與Catch節點不同,您不能指定“所有節點”模式並以流程中的所有節點爲目標。</p> + <p>並非所有節點都會觸發此事件。這取決于它們是否支持于Node-RED 1.0中引入的此功能。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/25-catch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/25-catch.html new file mode 100644 index 0000000..4e3db01 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/25-catch.html @@ -0,0 +1,36 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="catch"> + <p>捕獲由同一標簽頁上的節點引發的錯誤。</p> + <h3>輸出</h3> + <dl class="message-properties"> + <dt>error.message <span class="property-type">字符串</span></dt> + <dd>錯誤消息。</dd> + <dt>error.source.id <span class="property-type">字符串</span></dt> + <dd>引發錯誤的節點的ID。</dd> + <dt>error.source.type <span class="property-type">字符串</span></dt> + <dd>引發錯誤的節點的類型。</dd> + <dt>error.source.name <span class="property-type">字符串</span></dt> + <dd>引發錯誤的節點的名稱。(如果已設置)</dd> + </dl> + <h3>詳細</h3> + <p>如果節點在處理消息時抛出錯誤,則流程通常會停止。該節點可用于捕獲那些錯誤並通過專用流程進行處理。</p> + <p>默認情況下,該節點將捕獲同一標簽頁上任何節點抛出的錯誤。或者,它可以針對特定節點,或配置爲僅捕獲另一個“目標”捕獲節點尚未捕獲的錯誤。</p> + <p>當錯誤發生時,所有匹配的catch節點都會收到錯誤消息。</p> + <p>如果在子流程中發送了錯誤,則該錯誤將由子流程中的任意捕獲節點處理。如果子流程中不存在捕獲節點,則那錯誤將被傳播到子流程實例所在的標簽頁。</p> + <p>如果消息已經具有<code>error</code>屬性,則將該<code>error</code>複制爲<code>_error</code>。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/25-status.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/25-status.html new file mode 100644 index 0000000..d961c8e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/25-status.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="status"> + <p>獲取在同一標簽頁上的其他節點的狀態消息。</p> + <h3>輸出</h3> + <dl class="message-properties"> + <dt>status.text <span class="property-type">字符串</span></dt> + <dd>狀態文本。</dd> + <dt>status.source.type <span class="property-type">字符串</span></dt> + <dd>報告狀態的節點的類型。</dd> + <dt>status.source.id <span class="property-type">字符串</span></dt> + <dd>報告狀態的節點的ID。</dd> + <dt>status.source.name <span class="property-type">字符串</span></dt> + <dd>報告狀態的節點的名稱(如果已設置)。</dd> + </dl> + <h3>詳細</h3> + <p>該節點不包含<code>有效荷載</code>。</p> + <p>默認情況下,節點會獲取同一工作空間標簽頁上報告所有節點的狀態。可以通過配置來設定目標節點。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/60-link.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/60-link.html new file mode 100644 index 0000000..e7723c4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/60-link.html @@ -0,0 +1,31 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="link in"> + <p>在流程之間創建虛擬連線。</p> + <h3>詳細</h3> + <p>該節點可以連接到任何標簽頁上存在的任何<code>link out</code>節點。連接後,它們的行爲就像連接在一起。</p> + <p>僅當選擇鏈接節點時,才會顯示鏈接節點之間的鏈接。如果有指向另一個選項卡的鏈接,則顯示一個虛擬節點。單擊該虛擬節點將帶您到相應的選項卡。</p> + <p><b>注意:</b>無法創建進入或離開子流程的鏈接。</p> +</script> + +<script type="text/x-red" data-help-name="link out"> + <p>在流程之間創建虛擬連線。</p> + <h3>詳細</h3> + <p>該節點可以連接到任何標簽頁上存在的任何<code>link in</code>節點。連接後,它們的行爲就像連接在一起。</p> + <p>僅當選擇鏈接節點時,才會顯示鏈接節點之間的鏈接。如果有指向另一個選項卡的鏈接,則顯示一個虛擬節點。單擊該虛擬節點將帶您到相應的選項卡。</p> + <p><b>注意:</b>無法創建進入或離開子流程的鏈接。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/90-comment.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/90-comment.html new file mode 100644 index 0000000..d044f28 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/90-comment.html @@ -0,0 +1,21 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="comment"> + <p>可用于向流程添加注釋的節點。</p> + <h3>詳細</h3> + <p>編輯面板接受Markdown語法。輸入的文本將在信息側面板中顯示。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/98-unknown.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/98-unknown.html new file mode 100644 index 0000000..c3588de --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/common/98-unknown.html @@ -0,0 +1,24 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="unknown"> + <p>您安裝的Node-RED無法識別該節點的類型。</p> + <h3>詳細</h3> + <p><i>如果在此狀態下部署節點,其配置會被保存。但是在安裝缺少的類型之前,流程不會開始。</i></p> + <p>使用<code> Menu-Manage Palette </code>選項來搜索並安裝節點,或者使用<b>npm install &lt;module&gt;</b>來安裝所有缺少的節點,並重新啓動Node-Red來導入這些節點。</p> + <p>另一種可能是,您已經安裝了此節點類型,但是缺少必須的依賴項。您應檢查Node-RED的啓動日志中是否有與缺少節點有關的錯誤消息。</p> + <p>以上方法都不適用時,您可以聯系該流程的作者以獲取缺少的節點類型的副本。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/10-function.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/10-function.html new file mode 100644 index 0000000..9f8ddb4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/10-function.html @@ -0,0 +1,51 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="function"> + <p>定義對接收到的消息進行處理的JavaScript代碼(函數的主體)。</p> + <p>輸入消息在名爲<code>msg</code>的JavaScript對象中傳遞。</p> + <p>通常,<code>msg</code>對象將消息正文保留在<code>msg.payload</code>屬性中。</p> + <p>該函數一般會返回一個消息對象(或多個消息對象),但也可以爲了停止流程而什麽都不返回。</p> + <h3>詳細</h3> + <p>請參見<a target="_blank" href="http://nodered.org/docs/writing-functions.html">在線文檔</a>來獲得更多有關編寫函數的信息。</p> + <h4>傳送消息</h4> + <p>要將消息傳遞到流程中的下一個節點,請返回消息或調用<code>node.send(messages)</code>。</p> + <p>它將返回/send:</p> + <ul> + <li>單個消息對象 - 傳遞給連接到第一個輸出的節點</li> + <li>消息對象數組,傳遞給連接到相應輸出的節點</li> + </ul> + <p>如果數組元素是數組,則將多個消息發送到相應的輸出。</p> + <p>無論return方法是單個值還是數組元素,如果返回值爲null,則不會發送任何消息。</p> + <h4>日志輸出和錯誤處理</h4> + <p>使用以下功能輸出日志信息和輸出錯誤:</p> + <ul> + <li><code>node.log("Log message")</code></li> + <li><code>node.warn("Warning")</code></li> + <li><code>node.error("Error")</code></li> + </ul> + </p> + <p>使用catch節點可以進行錯誤處理。 要由catch節點處理,請將<code>msg</code>作爲<code>node.error</code>的第二個參數傳遞:</p> + <pre>node.error("Error",msg);</pre> + <h4>訪問節點信息</h4> + <p>您可以使用以下屬性來在代碼中引用節點ID和名稱:</p> + <ul> + <li><code>node.id</code> - 節點的ID</li> + <li><code>node.name</code> - 節點的名稱</li> + </ul> + <h4>使用環境變量</h4> + <p>環境變量可以通過<code>env.get("MY_ENV_VAR")</code>來進行訪問。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/10-switch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/10-switch.html new file mode 100644 index 0000000..5a65eff --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/10-switch.html @@ -0,0 +1,37 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="switch"> + <p>按屬性值來分配消息的傳送路線。</p> + <h3>詳細</h3> + <p>根據接收到的消息評估指定的規則,然後將消息發送到與匹配的規則相對應的輸出端口。</p> + <p>可以將節點設置爲一旦發現一個匹配的規則,則停止後續的匹配。</p> + <p>對于評估規則,可以使用消息屬性,流程上下文/全局上下文屬性,環境變量和JSONata表達式的評估結果。</p> + <h4>規則</h4> + <p>有四種規則:</p> + <ol> + <li><b>值</b>根據配置的屬性評估規則</li> + <li><b>順序</b>可用于消息序列的規則,例如由“拆分”節點生成的規則</li> + <li><b>JSONata表達式</b>評估整個消息,如果結果爲真,則匹配。</li> + <li><b>其他</b>上述規則都不匹配時適用</li> + </ol> + <h4>注釋</h4> + <p><code>is true/false</code>與<code>is null</code> 規則將對類型進行嚴格的匹配。匹配之前的類型轉化不會發生。</p> + <p><code>is empty</code>規則與零字節的字符串,數組,緩衝區或沒有屬性的對象相匹配。與<code>null</code>或者<code>undefined</code>等不匹配。</p> + <h4>處理消息序列</h4> + <p>默認情況下,節點不會修改<code>msg.parts</code>屬性。</p> + <p>可以啓用<b>重建消息序列</b>選項來爲每條匹配的規則生成新的消息序列。在這種模式下,節點將在發送新序列之前對整個傳入序列進行緩存。運行時的設定<code>nodeMessageBufferMaxLength</code>可以用來限制可緩存的消息數目。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/15-change.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/15-change.html new file mode 100644 index 0000000..91a3209 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/15-change.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="change"> + <p>設置,更改,刪除或移動消息,流程上下文或全局上下文的屬性。</p> + <p>如果指定了多個規則,則將按定義的順序來應用它們。</p> + <h3>詳細</h3> + <p>可用的操作有:</p> + <dl class="message-properties"> + <dt>設置</dt> + <dd>設置一個屬性。該值可以是多種不同類型,也可以從現有消息或上下文屬性中獲取。</dd> + <dt>置換</dt> + <dd>搜索並替換屬性。 如果啓用了正則表達式,則可以爲“replace with”屬性指定捕獲組,例如<code>$1</code>。 在替換過程中,僅當規則完全匹配時才能更改屬性類型。</dd> + <dt>刪除</dt> + <dd>刪除一個屬性</dd> + <dt>移動</dt> + <dd>移動或者重命名一個屬性</dd> + </dl> + <p>類型"expression"使用<a href="http://jsonata.org/" target="_new">JSONata</a>語言。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/16-range.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/16-range.html new file mode 100644 index 0000000..62eb63d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/16-range.html @@ -0,0 +1,40 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="range"> + <p>將數值映射爲另一個區間的數值</p> + <h3>輸入</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">數值</span></dt> + <dd>有效荷載<i>一定</i>得是一個數值. 否則則會映射失敗。</dd> + </dl> + <h3>輸出</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">數值</span></dt> + <dd>被映射到新區間的數值。</dd> + </dl> + <h3>詳細</h3> + <p>該節點將線性縮放所接收到的數值。在默認情況下,結果不限于節點中定義的範圍。</p> + <p><i>縮放並限制到目標範圍</i>表示結果永遠不會超出目標範圍內指定的範圍。</p> + <p><i>在目標範圍內縮放並折疊</i>表示結果將會被限制(折疊)在目標範圍內。</p> + <p>例如,輸入0-10映射到0-100。</p> + <table style="outline-width:#888 solid thin"> + <tr><th width="80px">模式</th><th width="80px">輸入</th><th width="80px">輸出</th></tr> + <tr><td><center>scale</center></td><td><center>12</center></td><td><center>120</center></td></tr> + <tr><td><center>limit</center></td><td><center>12</center></td><td><center>100</center></td></tr> + <tr><td><center>wrap</center></td><td><center>12</center></td><td><center>20</center></td></tr> + </table> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/80-template.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/80-template.html new file mode 100644 index 0000000..874ae38 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/80-template.html @@ -0,0 +1,46 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="template"> + <p>根據提供的模板設置屬性。</p> + <h3>輸入</h3> + <dl class="message-properties"> + <dt>msg <span class="property-type">object</span></dt> + <dd>一個msg對象,其中包含著用于填充模板的信息。</dd> + <dt class="optional">template <span class="property-type">string</span></dt> + <dd>由<code>msg.payload</code>填充的模板。如果未在編輯面板中配置,則可以將設爲msg的屬性。</dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>msg <span class="property-type">object</span></dt> + <dd>由來自傳入msg的屬性來填充已配置的模板後輸出的帶有屬性的msg。</dd> + </dl> + <h3>詳細</h3> + <p>默認情況下使用<i><a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache</a></i>格式。如有需要也可以切換其他格式。</p> + <p>例如: + <pre>Hello {{payload.name}}. Today is {{date}}</pre> + <p>receives a message containing: + <pre>{ +date: "Monday", +payload: { + name: "Fred" +} +}</pre> + <p>輸出的消息將會是: + <pre>Hello Fred. Today is Monday</pre> + <p>也可以使用流程上下文或全局上下文中的屬性:<code>{{flow.name}}</code>或者<code>{{global.name}}</code>,或者爲了持久儲存<code>store</code>,可以使用<code>{{flow[store].name}}</code>或<code>{{global[store].name}}</code>。 + <p><b>注意:</b>默認情況下,<i>mustache</i>將在其替換的值中轉義任何非字母數字或HTML實體。爲了防止這種情況,請使用<code>{{{triple}}}</code>大括號。 +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/89-delay.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/89-delay.html new file mode 100644 index 0000000..28c291d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/89-delay.html @@ -0,0 +1,32 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="delay"> + <p>對通過節點的消息進行延遲發送或限制。</p> + <h3>輸入</h3> + <dl class="message-properties"> + <dt class="optional">delay <span class="property-type">數值</span></dt> + <dd>設置要應用于消息的延遲(以毫秒爲單位)。僅當節點配置爲允許消息去覆蓋配置的默認延遲間隔時,此選項才適用。</dd> + <dt class="optional">reset</dt> + <dd>如果接收到的消息將此屬性設置爲任何值,則將清空該節點保留的所有的未發送消息。</dd> + <dt class="optional">flush</dt> + <dd>如果接收到的消息的此屬性設置爲任何值,則將立即發送該節點保留的所有未發送消息。</dd> + </dl> + <h3>詳細</h3> + <p>當配置爲延遲發送消息時,延遲間隔可以是一個固定值,一個範圍內的隨機值或爲每個消息動態設置。</p> + <p>當配置爲對消息進行限制時,它們的傳遞將分散在配置的時間段內。狀態顯示隊列中當前的消息數。可以選擇在中間消息到達時丟棄它們。</p> + <p>速率限制可以應用于所有消息,也可以根據<code>msg.topic</code>的值來進行分組。分組時,中間消息將會被自動刪除。在每個時間間隔,節點可以釋放所有主題的最新消息,或釋放下一個主題的最新消息。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/89-trigger.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/89-trigger.html new file mode 100644 index 0000000..6bbe72f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/89-trigger.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="trigger"> + <p>触发后,将会发送一条消息。如果被拓展或重置,则可以选择发送第二条消息。</p> + + <h3>输入</h3> + <dl class="message-properties"> + <dt class="optional">reset</dt> + <dd>如果收到带有此属性的消息,则将清除当前正在进行的任何超时或重复,且不会触发任何消息。</dd> + </dl> + + <h3>详细</h3> + <p>该节点可用于在流程中创建一个超时。 默认情况下,当它收到一条消息时,它将发送一条带有<code>1</code>的有效荷载的消息。然后它将等待250毫秒,再发送第二条消息,其有效荷载为<code>0</code>。这可以用于使连接到Raspberry Pi GPIO引脚的LED闪烁等例子上。</p> + <p>可以将发送的每个消息的有效荷载配置为各种值,包括不发送任何内容的选项。例如,将初始消息设置为<i>nothing</i>,然后选择将计时器与每个收到的消息一起扩展的选项,则该节点将充当看门狗计时器;仅在设置的间隔内未收到任何消息时才发送消息。</p> + <p>如果设置为<i>字符串</i>类型,则该节点支持<i>mustache</i>模板语法。</p> + <p>如果节点收到具有<code>reset</code>属性或与节点中配置的匹配的<code>有效荷载</code>的消息,则将清除当前正在进行的任何超时或重复,并且不会触发任何消息。</p> + <p>可以将节点配置为以固定的时间间隔重新发送消息,直到被收到的消息重置为止。</p> + <p>(可选)可以将节点配置为将带有<code>msg.topic</code>的消息视为独立的流程。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/90-exec.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/90-exec.html new file mode 100644 index 0000000..27be34e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/function/90-exec.html @@ -0,0 +1,74 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="exec"> + <p>運行系統命令並返回其輸出。</p> + <p>可以將節點配置爲等待命令完成,或者在命令生成時發送其輸出。</p> + <p>運行的命令可以在節點中配置,也可以由收到的消息提供。</p> + + <h3>輸入</h3> + <dl class="message-properties"> + <dt class="optional">payload <span class="property-type">字符串</span></dt> + <dd>如果這樣配置,則將被附加到執行命令中。</dd> + <dt class="optional">kill <span class="property-type">字符串</span></dt> + <dd>指定發送到現有的exec節點進程的kill信號類型。</dd> + <dt class="optional">pid <span class="property-type">數值|字符串</span></dt> + <dd>要殺死的現有exec節點進程的進程ID</dd> + </dl> + + <h3>輸出</h3> + <ol class="node-ports"> + <li>標准輸出(stdout) + <dl class="message-properties"> + <dt>payload <span class="property-type">字符串</span></dt> + <dd>命令的標准輸出。</dd> + </dl> + <dl class="message-properties"> + <dt>rc <span class="property-type">object</span></dt> + <dd>(僅執行模式)一個返回代碼對象的副本(在端口3上也可用)</dd> + </dl> + </li> + <li>標准error輸出(stderr) + <dl class="message-properties"> + <dt>payload <span class="property-type">字符串</span></dt> + <dd>命令的標准錯誤輸出。</dd> + </dl> + <dl class="message-properties"> + <dt>rc <span class="property-type">object</span></dt> + <dd>(僅執行模式)一個返回代碼對象的副本(在端口3上也可用)</dd> + </dl> + </li> + <li>返回代碼 + <dl class="message-properties"> + <dt>payload <span class="property-type">object</span></dt> + <dd>一個包含返回代碼以及<code>message</code>,<code>signal</code>屬性的對象。</dd> + </dl> + </li> + </ol> + <h3>詳細</h3> + <p>默認情況下,使用<code>exec</code>系統調用來調用命令,等待命令完成,然後返回輸出。例如,成功的命令的返回碼應爲<code>{code:0}</code>。</p> + <p>(可選)可以選擇使用<code>spawn</code>代替,它會在命令運行時從stdout和stderr返回輸出,通常一次一行。完成後,它將在第三個端口上返回一個對象。例如,成功的命令應返回<code>{code:0}</code>。</p> + <p>錯誤可能會在第三個端口<code>msg.payload</code>上返回額外的信息,例如<code>message</code>字符串,<code>signal</code>字符串。</p> + <p>運行的命令是在節點內定義的,帶有附加<code>msg.payload</code>的選項和另外一組參數。</p> + <p>帶空格的命令或參數應該用引號引起來:<code>“這是一個參數”</code></p> + <p>返回的<code>有效荷載</code>通常是<i>字符串</i>類型,除非檢測到非UTF8字符,在這種情況下,它會是<i>buffer</i>類型。</p> + <p>節點處于活動狀態時,該節點的狀態圖標和PID將可見。對此更改可以通過<code>Status</code>節點讀取。</p> + <h4>殺死進程</h4> + <p>發送<code>msg.kill</code>將殺死一個活動進程。<code>msg.kill</code>應該是包含要發送的信號類型的字符串,例如<code>SIGINT</code>,<code>SIGQUIT</code>或<code>SIGHUP</code>。如果設置爲空字符串,則默認爲<code>SIGTERM</code>。</p> + <p>如果節點有多個進程在運行,則還必須設置<code>msg.pid</code>並設置要殺死的PID的值。</p> + <p>如果<code>超時</code>字段提供了一個值,則如果在指定的秒數過去後進程尚未完成,則該進程將自動終止。</p> + <p>提示:如果運行Python應用程序,則可能需要使用<code>-u</code>參數來停止對輸出進行緩存。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/messages.json b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/messages.json new file mode 100644 index 0000000..7ece333 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/messages.json @@ -0,0 +1,940 @@ +{ + "common": { + "label": { + "payload": "內容", + "topic": "主題", + "name": "名稱", + "username": "使用者名稱", + "password": "密碼", + "property": "屬性", + "selectNodes": "選擇節點...", + "expand": "擴展" + }, + "status": { + "connected": "已連接", + "not-connected": "未連接", + "disconnected": "已斷開", + "connecting": "連接中", + "error": "錯誤", + "ok": "確定" + }, + "notification": { + "error": "<strong>錯誤</strong>: __message__", + "errors": { + "not-deployed": "節點未部署", + "no-response": "伺服器無反應", + "unexpected": "發生意外錯誤 (__status__) __message__" + } + }, + "errors": { + "nooverride": "警告: 資訊的屬性已經不可以改寫節點的屬性. 詳情參考 bit.ly/nr-override-msg-props" + } + }, + "inject": { + "inject": "注入", + "repeat": "重複 = __repeat__", + "crontab": "crontab = __crontab__", + "stopped": "停止", + "failed": "注入失敗: __error__", + "label": { + "repeat": "重複", + "flow": "流上下午", + "global": "全局上下文", + "str": "字符串", + "num": "數值", + "bool": "布爾值", + "json": "JSON對象", + "bin": "buffer", + "date": "時間戳", + "env": "環境變量", + "object": "對象", + "string": "字符串", + "boolean": "布爾值", + "number": "數值", + "Array": "數組", + "invalid": "無效的JSON對象" + }, + "timestamp": "時間戳記", + "none": "無", + "interval": "週期性執行", + "interval-time": "指定時間段並週期性執行", + "time": "指定時間", + "seconds": "秒", + "minutes": "分鐘", + "hours": "小時", + "between": "介於", + "previous": "之前數值", + "at": "在", + "and": "至", + "every": "每隔", + "days": [ + "星期一", + "星期二", + "星期三", + "星期四", + "星期五", + "星期六", + "星期天" + ], + "on": "在", + "onstart": "立刻執行於", + "onceDelay": "秒後, 此後", + "tip": "<b>注意:</b> \"指定時間段並週期性執行\" 和 \"指定時間\" 會使用cron系統.<br/> 詳情查看信息頁.", + "success": "成功注入: __label__", + "errors": { + "failed": "注入失敗, 請查看日誌", + "toolong": "週期過長" + } + }, + "catch": { + "catch": "監測所有節點", + "catchNodes": "監測__number__個節點", + "catchUncaught": "捕獲:未捕獲", + "label": { + "source": "監測範圍", + "selectAll": "全選", + "uncaught": "忽略其他捕獲節點處理的錯誤" + }, + "scope": { + "all": "所有節點", + "selected": "指定節點" + } + }, + "status": { + "status": "報告所有節點狀態", + "statusNodes": "報告__number__個節點狀態", + "label": { + "source": "報告狀態範圍", + "sortByType": "按類型排序" + }, + "scope": { + "all": "所有節點", + "selected": "指定節點" + } + }, + "complete": { + "completeNodes": "完成: __number__個節點" + }, + "debug": { + "output": "輸出", + "none": "None", + "invalid-exp": "無效的JSONata表達式: __error__", + "msgprop": "資訊屬性", + "msgobj": "完整資訊", + "to": "目標", + "debtab": "除錯窗口", + "tabcon": "除錯窗口及Console", + "toSidebar": "除錯窗口", + "toConsole": "Console", + "toStatus": "節點狀態 (32位元字元)", + "severity": "級別", + "notification": { + "activated": "成功啟動: __label__", + "deactivated": "成功取消: __label__" + }, + "sidebar": { + "label": "除錯窗口", + "name": "名稱", + "filterAll": "所有節點", + "filterSelected": "已選節點", + "filterCurrent": "當前流程", + "debugNodes": "除錯節點", + "clearLog": "清空日誌", + "filterLog": "過濾日誌", + "openWindow": "在新視窗打開", + "copyPath": "復制路徑", + "copyPayload": "復制值", + "pinPath": "固定展開" + }, + "messageMenu": { + "collapseAll": "折疊所有路徑", + "clearPinned": "清空已固定路徑", + "filterNode": "過濾此節點", + "clearFilter": "清空過濾條件" + } + }, + "link": { + "linkIn": "輸入", + "linkOut": "輸出" + }, + "tls": { + "tls": "TLS設置", + "label": { + "use-local-files": "使用本地密鑰及證書檔", + "upload": "上傳", + "cert": "證書", + "key": "私密金鑰", + "passphrase": "密碼", + "ca": "CA證書", + "verify-server-cert": "驗證伺服器憑證", + "servername": "服務器名" + }, + "placeholder": { + "cert": "憑證路徑 (PEM 格式)", + "key": "私密金鑰路徑 (PEM 格式)", + "ca": "CA憑證路徑 (PEM 格式)", + "passphrase": "私密金鑰密碼 (可選)", + "servername": "用於SNI" + }, + "error": { + "missing-file": "未提供證書/金鑰檔案" + } + }, + "exec": { + "exec": "exec", + "spawn": "spawn", + "label": { + "command": "命令", + "append": "追加", + "timeout": "超時", + "timeoutplace": "可選填", + "return": "輸出", + "seconds": "秒", + "stdout": "標準輸出", + "stderr": "標準錯誤輸出", + "retcode": "返回碼" + }, + "placeholder": { + "extraparams": "額外的輸入參數" + }, + "opt": { + "exec": "當命令完成時 - exec模式", + "spawn": "當命令進行時 - spawn模式" + }, + "oldrc": "使用舊式輸出 (相容模式)" + }, + "function": { + "function": "函數", + "label": { + "function": "函數", + "outputs": "輸出" + }, + "error": { + "inputListener": "無法在函數中監聽對'注入'事件", + "non-message-returned": "函數節點嘗試返回類型為 __type__ 的資訊" + } + }, + "template": { + "template": "模板", + "label": { + "template": "模版", + "property": "屬性", + "format": "語法高亮", + "syntax": "格式", + "output": "輸出為", + "mustache": "Mustache 模版", + "plain": "純文字", + "json": "JSON", + "yaml": "YAML", + "none": "無" + }, + "templatevalue": "This is the payload: {{payload}} !" + }, + "delay": { + "action": "行為設置", + "for": "時長", + "delaymsg": "延遲每一條資訊", + "delayfixed": "固定延遲時間", + "delayvarmsg": "允許msg.delay複寫延遲時長", + "randomdelay": "隨機延遲", + "limitrate": "限制資訊頻率", + "limitall": "所有資訊", + "limittopic": "每一個msg.topic", + "fairqueue": "依次發送每一個topic", + "timedqueue": "發所有topic", + "milisecs": "毫秒", + "secs": "秒", + "sec": "秒", + "mins": "分", + "min": "分", + "hours": "小時", + "hour": "小時", + "days": "天", + "day": "天", + "between": "介於", + "and": "至", + "rate": "速度", + "msgper": "信息 每", + "dropmsg": "不傳輸中間資訊", + "label": { + "delay": "延遲", + "variable": "變數", + "limit": "限制", + "limitTopic": "限制主題", + "random": "隨機", + "units": { + "second": { + "plural": "秒", + "singular": "秒" + }, + "minute": { + "plural": "分鐘", + "singular": "分鐘" + }, + "hour": { + "plural": "小時", + "singular": "小時" + }, + "day": { + "plural": "天", + "singular": "天" + } + } + }, + "error": { + "buffer": "緩衝了超過 1000 條資訊", + "buffer1": "緩衝了超過 10000 條資訊" + } + }, + "trigger": { + "send": "發送", + "then": "然後", + "then-send": "然後發送", + "output": { + "string": "字串", + "number": "數字", + "existing": "現有資訊物件", + "original": "原本資訊物件", + "latest": "最新資訊物件", + "nothing": "無" + }, + "wait-reset": "等待被重置", + "wait-for": "等待", + "wait-loop": "週期性重發", + "for": "處理", + "bytopics": "每個msg.topic", + "alltopics": "所有消息", + "duration": { + "ms": "毫秒", + "s": "秒", + "m": "分鐘", + "h": "小時" + }, + "extend": " 如有新資訊,延長延遲", + "label": { + "trigger": "觸發", + "trigger-block": "觸發並阻止", + "trigger-loop": "週期性重發", + "reset": "重置觸發節點條件 如果:", + "resetMessage": "msg.reset已設置", + "resetPayload": "msg.payload等於", + "resetprompt": "可選填" + } + }, + "comment": { + "comment": "注釋" + }, + "unknown": { + "label": { + "unknown": "未知" + }, + "tip": "<p>此節點是您安裝,但Node-RED所不知道的類型。</p><p><i>如果在此狀態下部署節點,那麼它的配置將被保留,但是流程將不會啟動,直到安裝缺少的節點。</i></p><p>有關更多説明,請參閱資訊側欄</p>" + }, + "mqtt": { + "label": { + "broker": "服務端", + "example": "e.g. localhost", + "output": "輸出", + "qos": "QoS", + "retain": "保持", + "clientid": "使用者端ID", + "port": "埠", + "keepalive": "Keepalive計時(秒)", + "cleansession": "使用新的會話", + "use-tls": "使用安全連接 (SSL/TLS)", + "tls-config": "TLS 設置", + "verify-server-cert": "驗證伺服器憑證", + "compatmode": "使用舊式MQTT 3.1支援" + }, + "sections-label": { + "birth-message": "連接時發送的消息(出生消息)", + "will-message": "意外斷開連接時的發送消息(Will消息)", + "close-message": "斷開連接前發送的消息(關閉消息)" + }, + "tabs-label": { + "connection": "連接", + "security": "安全", + "messages": "消息" + }, + "placeholder": { + "clientid": "留白則自動隨機生成", + "clientid-nonclean": "如非新會話,必須設置使用者端ID", + "will-topic": "留白將禁止Will資訊", + "birth-topic": "留白將禁止Birth資訊", + "close-topic": "留白以禁用關閉消息" + }, + "state": { + "connected": "已連接到服務端: __broker__", + "disconnected": "已斷開與服務端 __broker__ 的連結", + "connect-failed": "與服務端 __broker__ 的連接失敗" + }, + "retain": "保留", + "output": { + "buffer": "Buffer", + "string": "字串", + "base64": "Base64編碼字串", + "auto": "自動檢測 (字符串或buffer)", + "json": "解析的JSON對象" + }, + "true": "是", + "false": "否", + "tip": "提示: 若希望通過msg屬性對topic(資訊), qos及retain(保留)進行設置, 則將上述項留白", + "errors": { + "not-defined": "主題未設置", + "missing-config": "未設置服務端", + "invalid-topic": "主題無效", + "nonclean-missingclientid": "使用者端ID未設定,使用新會話", + "invalid-json-string": "無效的JSON字符串", + "invalid-json-parse": "無法解析JSON字符串" + } + }, + "httpin": { + "label": { + "method": "請求方式", + "url": "URL", + "doc": "文字檔", + "return": "返回", + "upload": "接受檔案上傳?", + "status": "狀態碼", + "headers": "Header", + "other": "其他", + "paytoqs": "將msg.payload附加為查詢字符串參數", + "utf8String": "UTF8格式的字符串", + "binaryBuffer": "二進制buffer", + "jsonObject": "解析的JSON對象", + "authType": "類型", + "bearerToken": "Token" + }, + "setby": "- 用 msg.method 設定 -", + "basicauth": "基本認證", + "use-tls": "使用安全連接 (SSL/TLS) ", + "tls-config": "TLS 設置", + "basic": "基本認證", + "digest": "摘要認證", + "bearer": "bearer認證", + "use-proxy": "使用代理服務器", + "persist": "對連接啟用keep-alive", + "proxy-config": "代理服務器設置", + "use-proxyauth": "使用代理身份驗證", + "noproxy-hosts": "代理例外", + "utf8": "UTF-8 字串", + "binary": "二進位資料", + "json": "JSON對象", + "tip": { + "in": "相對URL", + "res": "發送到此節點的消息<b>必須</b>來自<i>http input</i>節點", + "req": "提示:如果JSON解析失敗,則獲取的字串將按原樣返回." + }, + "httpreq": "http 請求", + "errors": { + "not-created": "當httpNodeRoot為否時,無法創建http-in節點", + "missing-path": "無路徑", + "no-response": "無響應物件", + "json-error": "JSON 解析錯誤", + "no-url": "未設定 URL", + "deprecated-call": "__method__方法已棄用", + "invalid-transport": "非HTTP傳輸請求", + "timeout-isnan": "超時值不是有效數字,忽略", + "timeout-isnegative": "超時值為負,忽略", + "invalid-payload": "無效的有效載荷" + }, + "status": { + "requesting": "請求中" + } + }, + "websocket": { + "label": { + "type": "類型", + "path": "路徑", + "url": "URL" + }, + "listenon": "監聽", + "connectto": "連接", + "sendrec": "發送/接受", + "payload": "有效載荷", + "message": "完整資訊", + "tip": { + "path1": "預設情況下,<code>payload</code>將包含要發送或從Websocket接收的資料。偵聽器可以配置為以JSON格式的字串發送或接收整個消息物件.", + "path2": "這條路徑將相對於 ", + "url1": "URL 應該使用ws:&#47;&#47;或者wss:&#47;&#47;方案並指向現有的websocket監聽器.", + "url2": "預設情況下,<code>payload</code> 將包含要發送或從Websocket接收的資料。可以將使用者端配置為以JSON格式的字串發送或接收整個消息物件." + }, + "status": { + "connected": "連接數 __count__", + "connected_plural": "連接數 __count__" + }, + "errors": { + "connect-error": "ws連接發生了錯誤: ", + "send-error": "發送時發生了錯誤: ", + "missing-conf": "未設置伺服器", + "duplicate-path": "同一路徑上不能有兩個WebSocket偵聽器: __path__" + } + }, + "watch": { + "watch": "watch", + "label": { + "files": "文件", + "recursive": "遞迴所有子資料夾" + }, + "placeholder": { + "files": "逗號分開文件或資料夾" + }, + "tip": "在Windows上,請務必使用雙斜杠 \\\\ 來隔開資料夾名字" + }, + "tcpin": { + "label": { + "type": "類型", + "output": "輸出", + "port": "埠", + "host": "主機位址", + "payload": "的有效載荷", + "delimited": "分隔符號號", + "close-connection": "是否在成功發送每條資訊後斷開連接?", + "decode-base64": "用 Base64 解碼信息?", + "server": "伺服器", + "return": "返回", + "ms": "毫秒", + "chars": "字元" + }, + "type": { + "listen": "監聽", + "connect": "連接", + "reply": "回應 TCP" + }, + "output": { + "stream": "字串流", + "single": "單一", + "buffer": "Buffer", + "string": "字串", + "base64": "Base64 字串" + }, + "return": { + "timeout": "指定時間後", + "character": "當收到某個字元為", + "number": "指定字元數", + "never": "永不 - 保持連接", + "immed": "馬上 - 不需要等待回復" + }, + "status": { + "connecting": "正在連接到 __host__:__port__", + "connected": "已經連接到 __host__:__port__", + "listening-port": "監聽埠 __port__", + "stopped-listening": "已停止監聽埠", + "connection-from": "連接來自 __host__:__port__", + "connection-closed": "連接已關閉 __host__:__port__", + "connections": "__count__ 個連接", + "connections_plural": "__count__ 個連接" + }, + "errors": { + "connection-lost": "連接中斷 __host__:__port__", + "timeout": "超時關閉通訊端連接,埠 __port__", + "cannot-listen": "無法監聽埠 __port__, 錯誤: __error__", + "error": "錯誤: __error__", + "socket-error": "通訊端連接錯誤來自 __host__:__port__", + "no-host": "主機位址或埠未設定", + "connect-timeout": "連接逾時", + "connect-fail": "連接失敗" + } + }, + "udp": { + "label": { + "listen": "監聽", + "onport": "埠", + "using": "使用", + "output": "輸出", + "group": "組", + "interface": "本地IP", + "send": "發送一個", + "toport": "到埠", + "address": "地址", + "decode-base64": "是否解碼Base64編碼的資訊?", + "interfaceprompt": "(可選)本地 IP 綁定到" + }, + "placeholder": { + "interface": "(可選)eth0的IP地址", + "interfaceprompt": "(可選) 要綁定的本地接口或地址", + "address": "目標IP位址" + }, + "udpmsgs": "udp信息", + "mcmsgs": "群播信息", + "udpmsg": "udp信息", + "bcmsg": "廣播資訊", + "mcmsg": "群播信息", + "output": { + "buffer": "Buffer", + "string": "字串", + "base64": "Base64編碼字串" + }, + "bind": { + "random": "綁定到任意本地埠", + "local": "綁定到本地埠", + "target": "綁定到目標埠" + }, + "tip": { + "in": "提示:確保您的防火牆將允許資料進入", + "out": "提示:如果要使用<code>msg.ip</code>和<code>msg.port</code>設置,請將位址和埠留空", + "port": "正在使用埠: " + }, + "status": { + "listener-at": "udp 監聽器正在監聽 __host__:__port__", + "mc-group": "udp 群播到 __group__", + "listener-stopped": "udp 監聽器已停止", + "output-stopped": "udp 輸出已停止", + "mc-ready": "udp 群播已準備好: __outport__ -> __host__:__port__", + "bc-ready": "udp 廣播已準備好: __outport__ -> __host__:__port__", + "ready": "udp 已準備好: __outport__ -> __host__:__port__", + "ready-nolocal": "udp 已準備好: __host__:__port__", + "re-use": "udp 重用通訊端: __outport__ -> __host__:__port__" + }, + "errors": { + "access-error": "UDP 訪問錯誤, 你可能需要root許可權才能接入1024以下的埠", + "error": "錯誤: __error__", + "bad-mcaddress": "無效的群播地址", + "interface": "必須是指定介面的IP位址", + "ip-notset": "udp: IP地址未設定", + "port-notset": "udp: 埠未設定", + "port-invalid": "udp: 無效埠號碼", + "alreadyused": "udp: 埠已被佔用", + "ifnotfound": "udp: 接口 __iface__ 未發現" + } + }, + "switch": { + "switch": "switch", + "label": { + "property": "屬性", + "rule": "規則", + "repair": "重建資訊佇列" + }, + "previous": "先前值", + "and": "與", + "checkall": "全選所有規則", + "stopfirst": "接受第一條匹配資訊後停止", + "ignorecase": "忽略大小寫", + "rules": { + "btwn": "在之間", + "cont": "包含", + "regex": "匹配規則運算式", + "true": "為真", + "false": "為假", + "null": "為空", + "nnull": "非空", + "istype": "類型是", + "empty": "為空", + "nempty": "非空", + "head": "head", + "tail": "tail", + "index": "index between", + "exp": "JSONata運算式", + "else": "除此以外", + "hask": "擁有鍵" + }, + "errors": { + "invalid-expr": "無效的JSONata運算式: __error__", + "too-many": "Switch節點中有太多待定信息" + } + }, + "change": { + "label": { + "rules": "規則", + "rule": "規則", + "set": "設定 __property__", + "change": "修改 __property__", + "delete": "刪除 __property__", + "move": "移動 __property__", + "changeCount": "修改: __count__條規矩", + "regex": "使用規則運算式" + }, + "action": { + "set": "設定", + "change": "修改", + "delete": "刪除", + "move": "轉移", + "to": "到", + "search": "搜索", + "replace": "替代為" + }, + "errors": { + "invalid-from": "無效的'from'屬性: __error__", + "invalid-json": "無效的'to'JSON 屬性", + "invalid-expr": "無效的JSONata運算式: __error__" + } + }, + "range": { + "range": "range", + "label": { + "action": "操作", + "inputrange": "映射輸入資料", + "resultrange": "至目標範圍", + "from": "從", + "to": "到", + "roundresult": "取最接近整數?" + }, + "placeholder": { + "min": "e.g. 0", + "maxin": "e.g. 99", + "maxout": "e.g. 255" + }, + "scale": { + "payload": "按比例msg.payload", + "limit": "按比例並設定界限至目標範圍", + "wrap": "按比例並包含在目標範圍內" + }, + "tip": "提示: 此節點僅對數字有效", + "errors": { + "notnumber": "不是一個數字" + } + }, + "csv": { + "label": { + "columns": "列", + "separator": "分隔符號", + "c2o": "CSV至對象", + "o2c": "對象至CSV", + "input": "輸入", + "skip-s": "忽略前", + "skip-e": "行", + "firstrow": "第一行包含列名", + "output": "輸出", + "includerow": "包含列名行", + "newline": "分行符號", + "usestrings": "解析數值" + }, + "placeholder": { + "columns": "用逗號分割列名" + }, + "separator": { + "comma": "逗號", + "tab": "Tab", + "space": "空格", + "semicolon": "分號", + "colon": "冒號", + "hashtag": "井號", + "other": "其他..." + }, + "output": { + "row": "每行一條信息", + "array": "僅一條資訊 [陣列]" + }, + "newline": { + "linux": "Linux (\\n)", + "mac": "Mac (\\r)", + "windows": "Windows (\\r\\n)" + }, + "errors": { + "csv_js": "此節點僅處理CSV字串或JS物件", + "obj_csv": "對象->CSV轉換未設定列模版" + } + }, + "html": { + "label": { + "select": "選取項", + "output": "輸出", + "in": "in" + }, + "output": { + "html": "選定元素的html內容", + "text": "選定元素的純文字內容", + "attr": "包含選定元素的所有屬性的物件" + }, + "format": { + "single": "一條資訊 [陣列]", + "multi": "多條資訊,每條一個元素" + } + }, + "json": { + "errors": { + "dropped-object": "忽略非物件格式的有效負載", + "dropped": "忽略不支援格式的有效負載類型", + "dropped-error": "轉換有效負載失敗", + "schema-error": "JSON架構錯誤", + "schema-error-compile": "JSON架構錯誤: 未能編譯架構" + }, + "label": { + "o2j": "對象至JSON", + "pretty": "格式化JSON字串", + "action": "操作", + "property": "屬性", + "actions": { + "toggle": "JSON字串與物件互轉", + "str": "總是轉為JSON字串", + "obj": "總是轉為JS對象" + } + } + }, + "yaml": { + "errors": { + "dropped-object": "忽略非物件格式的有效負載", + "dropped": "忽略不支援格式的有效負載類型", + "dropped-error": "轉換有效負載失敗" + } + }, + "xml": { + "label": { + "represent": "XML標籤屬性的屬性名稱", + "prefix": "標籤文本內容的屬性名稱", + "advanced": "高級選項", + "x2o": "XML到物件選項" + }, + "errors": { + "xml_js": "此節點僅處理XML字串或JS物件." + } + }, + "file": { + "label": { + "filename": "檔案名", + "action": "行為", + "addnewline": "向每個有效載荷添加分行符號(\\n)?", + "createdir": "創建目錄(如果不存在)?", + "outputas": "輸出", + "breakchunks": "分拆成塊", + "breaklines": "分拆成行", + "filelabel": "文件", + "sendError": "發生錯誤時發送消息(傳統模式)", + "deletelabel": "刪除 __file__", + "encoding": "編碼", + "utf8String": "UTF8字符串", + "binaryBuffer": "二進制buffer" + }, + "action": { + "append": "追加至文件", + "overwrite": "複寫文件", + "delete": "刪除檔" + }, + "output": { + "utf8": "一個utf8字串", + "buffer": "一個Buffer物件", + "lines": "每行一條信息", + "stream": "一個Buffer流" + }, + "status": { + "wrotefile": "寫入至文件: __file__", + "deletedfile": "刪除檔: __file__", + "appendedfile": "追加至文件: __file__" + }, + "encoding": { + "none": "默認", + "native": "Native", + "unicode": "Unicode", + "japanese": "日本", + "chinese": "中國", + "korean": "韓國", + "taiwan": "臺灣/香港", + "windows": "Windows代碼頁", + "iso": "ISO代碼頁", + "ibm": "IBM代碼頁", + "mac": "Mac代碼頁", + "koi8": "KOI8代碼頁", + "misc": "其它" + }, + "errors": { + "nofilename": "未指定檔案名", + "invaliddelete": "警告:無效刪除。請在配置對話方塊中使用特定的刪除選項", + "deletefail": "無法刪除檔: __error__", + "writefail": "無法寫入文件: __error__", + "appendfail": "無法追加到文件: __error__", + "createfail": "檔創建失敗: __error__" + }, + "tip": "提示: 檔案名應該是絕對路徑,否則它將相對於Node-RED進程的工作目錄。" + }, + "split": { + "split": "split", + "intro": "基於以下類型拆分<code>msg.payload</code>:", + "object": "<b>對象</b>", + "objectSend": "每個鍵值對作為單個消息發送", + "strBuff": "<b>字串</b> / <b>Buffer</b>", + "array": "<b>陣列</b>", + "splitUsing": "拆分使用", + "splitLength": "固定長度", + "stream": "作為消息流處理", + "addname": " 複製鍵到 " + }, + "join": { + "join": "join", + "mode": { + "mode": "模式", + "auto": "自動", + "merge": "合併序列", + "reduce": "縮減序列", + "custom": "手動" + }, + "combine": "合併每個", + "completeMessage": "完整的消息", + "create": "輸出為", + "type": { + "string": "字串", + "array": "陣列", + "buffer": "Buffer", + "object": "鍵值對對象", + "merged": "合併對象" + }, + "using": "使用此值", + "key": "作為鍵", + "joinedUsing": "合併符號", + "send": "發送資訊:", + "afterCount": "達到一定數量的資訊時", + "count": "數量", + "subsequent": "和每個後續的消息", + "afterTimeout": "第一條消息的若幹時間後", + "seconds": "秒", + "complete": "在收到存在<code>msg.complete</code>的消息後", + "tip": "此模式假定此節點與<i>split</i>相連, 或者接收到的消息有正確配置的<code>msg.parts</code>屬性.", + "too-many": "join節點中有太多待定信息", + "merge": { + "topics-label": "合併主題", + "topics": "主題", + "topic": "主題", + "on-change": "當收到一個新主題時發送已合併資訊" + }, + "reduce": { + "exp": "Reduce運算式", + "exp-value": "exp", + "init": "初始值", + "right": "反向求值(從後往前)", + "fixup": "Fix-up exp" + }, + "errors": { + "invalid-expr": "無效的JSONata運算式: __error__" + } + }, + "sort": { + "sort": "排序", + "target": "排序屬性", + "seq": "資訊佇列", + "key": "鍵值", + "elem": "元素值", + "order": "順序", + "ascending": "昇冪", + "descending": "降冪", + "as-number": "作為數值", + "invalid-exp": "排序節點中存在無效的JSONata運算式", + "too-many": "排序節點中有太多待定信息", + "clear": "清空排序節點中的待定資訊" + }, + "batch": { + "batch": "batch", + "mode": { + "label": "模式", + "num-msgs": "按指定數量分組", + "interval": "按時間間隔分組", + "concat": "按主題分組" + }, + "count": { + "label": "分組數量", + "overlap": "隊末隊首重疊數量", + "count": "數量", + "invalid": "無效的分組數量或重疊數量" + }, + "interval": { + "label": "時間間隔", + "seconds": "秒", + "empty": "無數據到達時發送空資訊" + }, + "concat": { + "topics-label": "主題", + "topic": "主題" + }, + "too-many": "batch節點中有太多待定信息", + "unexpected": "未知模式", + "no-parts": "資訊中沒有parts屬性" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/05-tls.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/05-tls.html new file mode 100644 index 0000000..ee4b3bd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/05-tls.html @@ -0,0 +1,19 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="tls-config"> + <p>TLS連接的配置選項。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/06-httpproxy.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/06-httpproxy.html new file mode 100644 index 0000000..23f8996 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/06-httpproxy.html @@ -0,0 +1,22 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http proxy"> + <p>HTTP代理的配置選項。</p> + + <h3>詳細</h3> + <p>訪問代理例外列表中的主機時,將不使用任何代理。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/10-mqtt.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/10-mqtt.html new file mode 100644 index 0000000..825bf21 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/10-mqtt.html @@ -0,0 +1,70 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="mqtt in"> + <p>連接到MQTT代理並訂閱來自指定主題的消息。</p> + <h3>輸出</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">字符串 | buffer</span></dt> + <dd>如果不是二進制buffer的話就是字符串</dd> + <dt>topic <span class="property-type">字符串</span></dt> + <dd>MQTT主題,使用<code>/</code>作爲層次結構分隔符。</dd> + <dt>qos <span class="property-type">數值</span> </dt> + <dd>QoS服務質量:0, 最多一次; 1, 最少一次; 2, 只一次。</dd> + <dt>retain <span class="property-type">布爾值</span></dt> + <dd>值爲true時表示消息已保留且可能是舊的。</dd> + </dl> + <h3>詳細</h3> + <p>訂閱主題可以包括MQTT通配符(+:一個級別,#:多個級別)。</p> + <p>使用該節點您首先需要建立與MQTT代理的連接。通過單擊鉛筆圖標來進行配置。</p> + <p>如有需要,幾個MQTT節點(輸入或輸出)可以共享相同的代理連接。</p> +</script> + +<script type="text/x-red" data-help-name="mqtt out"> + <p>連接到MQTT代理並發布消息。</p> + <h3>輸入</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">字符串 | buffer</span></dt> + <dd>要發布的有效負載。如果未設置此屬性,則不會發送任何消息。要發送空白消息,請將此屬性設置爲空字符串。</dd> + + <dt class="optional">topic <span class="property-type">字符串</span></dt> + <dd>要發布的MQTT主題。</dd> + + <dt class="optional">qos <span class="property-type">number</span></dt> + <dd>QoS服務質量:0, 最多一次; 1, 最少一次; 2, 只一次。默認值爲0。</dd> + + <dt class="optional">retain <span class="property-type">布爾值</span></dt> + <dd>設置爲<code>true</code>來將消息保留在代理上。默認值爲<code>false</code>。</dd> + </dl> + <h3>詳細</h3> + <p><code>msg.payload</code>用作已發布消息的有效載荷。如果包含Object,則會在發送之前將其轉換爲JSON字符串。如果它包含二進制buffer,則消息將按原樣發布。</p> + <p>可以在節點中配置所使用的主題,或者如果留爲空白,則可以通過<code>msg.topic</code>進行設置。</p> + <p>同樣,可以在節點中配置QoS和保留值,或者如果保留空白,則分別由<code>msg.qos</code>和<code>msg.retain</code>設置。要清除先前存儲在代理中的主題,請設置保留標志並向該主題發布空消息。</p> + <p>該節點需要與要配置的MQTT代理的連接。通過單擊鉛筆圖標進行配置。</p> + <p>如果需要,幾個MQTT節點(輸入或輸出)可以共享相同的代理連接。</p> +</script> + +<script type="text/x-red" data-help-name="mqtt-broker"> + <p>與MQTT代理的連接設置。</p> + <p>創建與代理的連接設置。可以在<code>MQTT In</code>和<code>MQTT Out</code>節點中重複利用這些設置。</p> + <p>如果未爲該節點設置客戶端ID,並且設置了會話初始化,則將生成一個隨機客戶端ID。設置客戶端ID時,請確保它對于連接目標處的代理是唯一的。</p> + <h4>Birth Message</h4> + <p>建立連接後發布在以配置主題中的消息。</p> + <h4>Close Message</h4> + <p>在連接正常結束之前重新部署或者關閉了節點時,發布在以配置主題中的消息。</p> + <h4>Will Message</h4> + <p>當節點意外丟失連接時由代理發布的消息</p> + <h4>WebSockets</h4> + <p>可以將節點配置成使用WebSocket連接。使用WebSocket時,請在服務器字段中以完整格式描述連接目標的URI。 例如:</p> + <pre>ws://example.com:4000/mqtt</pre> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/21-httpin.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/21-httpin.html new file mode 100644 index 0000000..0d44ce3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/21-httpin.html @@ -0,0 +1,81 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http in"> + <p>創建用于創建Web服務的HTTP端點。</p> + <h3>輸出</h3> + <dl class="message-properties"> + <dt>payload</dt> + <dd>GET請求包含任何查詢字符串參數的對象。或者包含HTTP請求正文。</dd> + <dt>req<span class="property-type">object</span></dt> + <dd>HTTP請求對象。該對象包含有關請求信息的多個屬性。 + <ul> + <li><code>body</code> - 傳入請求的正文。格式將取決于請求。</li> + <li><code>headers</code> - 包含HTTP請求標頭的對象。</li> + <li><code>query</code> - 包含任何查詢字符串參數的對象。</li> + <li><code>params</code> - 包含任何路由參數的對象。</li> + <li><code>cookies</code> - 包含請求cookie的對象。</li> + <li><code>files</code> - 如果節點啓用了文件上傳,則爲包含了上傳的文件的對象。</li> + </ul> + </dd> + <dt>res<span class="property-type">object</span></dt> + <dd>HTTP響應對象。此屬性不應直接使用;<code>HTTP Response</code>節點記錄了如何響應請求。該屬性必須保留在傳遞給響應節點的消息上。</dd> + </dl> + <h3>詳細</h3> + <p>節點將在配置的路徑上監聽特定類型的請求。路徑可以完全指定,例如<code>/user</code>,或包括可以接受任何值的命名參數,例如<code>/user/:name</code>。 使用命名參數時,可以在<code>msg.req.params</code>下訪問其在請求中的實際值。</p> + <p>對于包含正文的請求(例如POST或PUT),請求的內容將作爲<code>msg.payload</code>提供。</p> + <p>如果可以確定請求的內容類型,則正文將被解析爲任何適當的類型。例如,<code>application/json</code>將被解析爲其JavaScript對象表示。</p> + <p><b>注意:</b>該節點不發送對請求的任何響應。該流程必須包含HTTP響應節點才能完成請求。</p> +</script> + +<script type="text/x-red" data-help-name="http response"> + <p>將響應發送回從HTTP輸入節點接收的請求。</p> + + <h3>輸入</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">string</span></dt> + <dd>響應的正文。</dd> + <dt class="optional">statusCode <span class="property-type">數值</span></dt> + <dd>如果設置,則用作響應狀態代碼。默認值:200。</dd> + <dt class="optional">headers <span class="property-type">object</span></dt> + <dd>如果設置,則提供HTTP頭以包含在響應中。</dd> + <dt class="optional">cookies <span class="property-type">object</span></dt> + <dd>如果設置,則可用于設置或刪除cookie。</dd> + </dl> + <h3>詳細</h3> + <p>還可以在節點本身內設置<code>statusCode</code>和<code>headers</code>。如果在節點內設置了屬性,則不能被相應的message屬性覆蓋。</p> + <h4>Cookie處理</h4> + <p><code>cookies</code>屬性必須是名稱/值對的對象。該值可以是使用默認選項設置cookie值的字符串,也可以是options對象。<p> + <p>下面的示例設置兩個cookie-一個名爲<code>name</code>的值爲<code>nick</code>,另一個名爲<code>session</code>的值爲<code>1234</code>,並且有效期設置爲15分鍾。</p> + <pre> +msg.cookies = { + name: 'nick', + session: { + value: '1234', + maxAge: 900000 + } +}</pre> + <p>有效選項包括:</p> + <ul> + <li><code>domain</code> - (字符串) Cookie的域名</li> + <li><code>expires</code> - (日期) GMT標准時間的到期日。如果未指定或設置爲0,則創建會話cookie</li> + <li><code>maxAge</code> - (字符串) 相對于當前時間的到期日期(以毫秒爲單位)</li> + <li><code>path</code> - (字符串) Cookie的路徑。默認爲/</li> + <li><code>value</code> - (字符串) Cookie使用的值</li> + </ul> + <p>要刪除Cookie,請將其<code>value</code>設置爲<code>null</code>。</p> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/21-httprequest.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/21-httprequest.html new file mode 100644 index 0000000..71ed960 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/21-httprequest.html @@ -0,0 +1,78 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="http request"> + <p>發送HTTP請求並返回響應。</p> + + <h3>輸入</h3> + <dl class="message-properties"> + <dt class="optional">url <span class="property-type">字符串</span></dt> + <dd>如果未在節點中配置,則此可選屬性設置請求的url。</dd> + <dt class="optional">method <span class="property-type">字符串</span></dt> + <dd>如果未在節點中配置,則此可選屬性設置請求的HTTP方法。必須是<code>GET</code>,<code>PUT</code>,<code>POST</code>,<code>PATCH</code>或<code>DELETE</code>之一。</dd> + <dt class="optional">headers <span class="property-type">object</span></dt> + <dd>設置請求的HTTP頭。</dd> + <dt class="optional">cookies <span class="property-type">object</span></dt> + <dd>如果設置,則可用于發送帶有請求的cookie。</dd> + <dt class="optional">payload</dt> + <dd>發送爲請求的正文。</dd> + <dt class="optional">rejectUnauthorized</dt> + <dd>如果設置爲<code>false</code>,則允許對使用自簽名證書的https站點進行請求。</dd> + <dt class="optional">followRedirects</dt> + <dd>如果設置爲<code>false</code>,則阻止遵循重定向(HTTP 301)。默認情況下爲<code>true</code></dd> + <dt class="optional">requestTimeout</dt> + <dd>如果設置爲正數毫秒,將覆蓋全局設置的<code>httpRequestTimeout</code>參數。</dd> + </dl> + <h3>輸出</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">字符串 | object | buffer</span></dt> + <dd>響應的正文。可以將節點配置爲以字符串形式返回主體,嘗試將其解析爲JSON字符串或將其保留爲二進制buffer。</dd> + <dt>statusCode <span class="property-type">數值</span></dt> + <dd>響應的狀態碼,如果請求無法完成,則返回錯誤碼。</dd> + <dt>headers <span class="property-type">object</span></dt> + <dd>包含響應頭的對象。</dd> + <dt>responseUrl <span class="property-type">字符串</span></dt> + <dd>如果在處理請求時發生任何重定向,則此屬性爲最終重定向的URL。否則則爲原始請求的URL。</dd> + <dt>responseCookies <span class="property-type">object</span></dt> + <dd>如果響應包含cookie,則此屬性是每個cookie的‘名稱/值’鍵值對的對象。</dd> + <dt>redirectList <span class="property-type">數組</span></dt> + <dd>如果請求被重定向了一次或多次,則累積的信息將被添加到此屬性。“location”是下一個重定向目標。cookie是從重定向源返回的cookie。</dd> + </dl> + <h3>詳細</h3> + <p>在節點內配置後,URL屬性可以包含<a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache樣式</a>標簽。 這些標簽允許使用傳入消息的值來構造url。例如,如果url設置爲<code>example.com/{{{{topic}}}</code>,它將自動插入<code>msg.topic</code>的值。使用{{{...}}}可以防止mustache轉義/ &等字符。</p> + <p>節點可以選擇自動將<code>msg.payload</code>編碼爲GET請求的查詢字符串參數,在這種情況下,<code>msg.payload</code>必須是一個對象。</p> + <p><b>注意:</b>如果使用了代理,則應設置<code>http_proxy=...</code>環境變量並重新啓動Node-RED,或使用“代理配置”。如果設置了代理配置,則配置優先于環境變量。</p> + <h4>使用多個HTTP請求節點</h4> + <p>爲了在一個流程中多次使用該節點,必須要注意<code>msg.headers</code>屬性的處理。通常在第一個節點在響應頭中設置此屬性,而不期望在下一個節點的請求頭中使用此屬性。如果節點之間的<code>msg.headers</code>屬性保持不變,則第二個節點將忽略它。要設置自定義標題,首先應刪除<code>msg.headers</code>或將其重置爲空對象:<code>{}</code>。</p> + <h4>Cookie處理</h4> + <p>傳遞給節點的<code>cookies</code>屬性必須是‘名稱/值’鍵值對的對象。該值可以是設置cookie值的字符串,也可以是具有單個<code>value</code>屬性的對象。</p> + <p>請求返回的所有cookie都將在<code>responseCookies</code>屬性下傳遞回去。</p> + <h4>內容類型處理</h4> + <p>如果<code>msg.payload</code>是一個對象,則節點將自動將請求的內容類型設置爲<code>application/json</code>並對其進行編碼。</p> + <p>要將請求編碼爲表單數據,應將<code>msg.headers[“content-type”]</code>設置爲<code>application/x-www-form-urlencoded</code>。</p> + <h4>文件上傳</h4> + <p>要執行文件上傳,應將<code>msg.headers["content-type"]</code>設置爲<code>multipart/form-data</code>和<code>msg.payload</code>傳遞給節點的必須是具有以下結構的對象:</p> + <pre><code>{ + "KEY": { + "value": FILE_CONTENTS, + "options": { + "filename": "FILENAME" + } + } +}</code></pre> + <p><code>KEY</code>,<code>FILE_CONTENTS</code>和<code>FILENAME</code>的值應設置爲適當的值。</p> + +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/22-websocket.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/22-websocket.html new file mode 100644 index 0000000..4bb2c7f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/22-websocket.html @@ -0,0 +1,35 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="websocket in"> + <p>WebSocket輸入節點。</p> + <p>默認情況下,從WebSocket接收的數據將位于<code>msg.payload</code>中。可以將套接字配置爲期望格式正確的JSON字符串,在這種情況下,它將解析JSON並將結果對象作爲整個消息發送。</p> +</script> + +<script type="text/x-red" data-help-name="websocket out"> + <p>WebSocket輸出節點。</p> + <p>默認情況下,<code>msg.payload</code>將通過WebSocket發送。可以將套接字配置爲將整個<code>msg</code>對象編碼爲JSON字符串,然後通過WebSocket發送。</p> + <p>如果到達此節點的消息是從WebSocket In節點開始的,則該消息將發送回觸發流程的客戶端。否則,消息將廣播給所有連接的客戶端。</p> + <p>如果要廣播從“WebSocket輸入”節點開始的消息,則可以應該刪除流中的<code>msg._session</code>屬性。</p> +</script> + +<script type="text/x-red" data-help-name="websocket-listener"> + <p>此配置節點使用指定的路徑創建WebSocket服務器端點。</p> +</script> + +<script type="text/x-red" data-help-name="websocket-client"> + <p>此配置節點將WebSocket客戶端連接到指定的URL。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/31-tcpin.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/31-tcpin.html new file mode 100644 index 0000000..2898ca7 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/31-tcpin.html @@ -0,0 +1,35 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="tcp in"> + <p>提供TCP輸入選擇。可以連接到遠程TCP端口,或接受傳入連接。</p> + <p><b>注意:</b>在某些系統上,您可能需要root或管理員權限來訪問低于1024的端口。</p> +</script> + +<script type="text/x-red" data-help-name="tcp out"> + <p>提供TCP輸出的選擇。可以連接到遠程TCP端口,接受傳入的連接,或回複從TCP In節點收到的消息。</p> + <p>僅發送<code>msg.payload</code>。</p> + <p>如果<code>msg.payload</code>是包含二進制數據的Base64編碼的字符串,則Base64解碼選項將導致它在發送之前先轉換回二進制。</p> + <p>如果不存在<code>msg._session</code>,則有效負載將發送到<b>所有</b>連接的客戶端。</p> + <p><b>注意:</b>在某些系統上,您可能需要root或管理員權限來訪問低于1024的端口。</p> +</script> + +<script type="text/x-red" data-help-name="tcp request"> + <p>一個簡單的TCP請求節點。將<code>msg.payload</code>發送到服務器tcp端口,並期望得到響應。</p> + <p>連接到服務器,發送“請求”並接收“響應”。 可以從固定數量的字符,與指定字符匹配的字符中選擇操作,從第一個答複到達起等待指定的時間,等待數據到達,發送數據並立即取消連接而無需等待答複等操作中進行選擇。</p> + <p>響應將在<code>msg.payload</code>中作爲buffer輸出,因此您可能需要對它進行<code>.toString()</code>操作。</p> + <p>如果將tcp主機或端口留空,則必須使用<code>msg.host</code>和<code>msg.port</code>屬性進行設置。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/32-udp.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/32-udp.html new file mode 100644 index 0000000..401af48 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/network/32-udp.html @@ -0,0 +1,28 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="udp in"> + <p>UDP輸入節點。在<code>msg.payload</code>中生成Buffer,字符串或Base64編碼的字符串。支持組播。</p> + <p>在<code>msg.ip</code>和<code>msg.port</code>中設置接收到的消息的IP地址和端口。</p> + <p><b>注意:</b>在某些系統上,您可能需要root或管理員權限才能使用低于1024的端口或廣播。</p> +</script> + +<script type="text/x-red" data-help-name="udp out"> + <p>該節點將<code>msg.payload</code>發送到指定的UDP主機和端口。支持組播。</p> + <p>您也可以使用<code>msg.ip</code>和<code>msg.port</code>設置目標值,但是靜態配置的值具有優先權。</p> + <p>如果選擇廣播,則將地址設置爲本地廣播IP地址。或者也可以嘗試使用全局廣播地址255.255.255.255。</p> + <p><b>注意:</b>在某些系統上,您可能需要root或管理員權限才能使用低于1024的端口或廣播。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-CSV.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-CSV.html new file mode 100644 index 0000000..9a86386 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-CSV.html @@ -0,0 +1,43 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="csv"> + <p>在CSV格式的字符串及其JavaScript對象表示形式之間進行相互轉換。</p> + <h3>輸入</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 數組 | 字符串</span></dt> + <dd>JavaScript對象,數組或CSV字符串。</dd> + </dl> + <h3>輸出</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 數組 | 字符串</span></dt> + <dd> + <ul> + <li>如果輸入是字符串,它將嘗試將其解析爲CSV,並爲每行創建鍵/值對的JavaScript對象。然後該節點將爲每行發送一條消息,或者發送一條包含對象數組的消息。</li> + <li>如果輸入是JavaScript對象,它將嘗試構建CSV字符串。</li> + <li>如果輸入是簡單值的數組,則將構建單行CSV字符串。</li> + <li>如果輸入是數組數組或對象數組,則會創建多行CSV字符串。</li> + </ul> + </dd> + </dl> + <h3>詳細</h3> + <p>列模板可以包含列名稱的有序列表。將CSV轉換爲對象時,列名將用作屬性名稱。或者也可以從CSV的第一行中獲取列名稱。</p> + <p>轉換爲CSV時,列模板用于標識從對象中提取的屬性以及提取的順序。</p> + <p>如果輸入是數組,則列模板僅用于有選擇地生成一行列標題。</p> + <p>只要正確設置<code>parts</code>屬性,該節點就可以接受多部分輸入。</p> + <p>如果輸出多個消息,則將設置其<code>parts</code>屬性並形成完整的消息序列。</p> + <p><b>注意:</b>列模板必須用逗號分隔,即使數據中已有了其他分隔符。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-HTML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-HTML.html new file mode 100644 index 0000000..b155945 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-HTML.html @@ -0,0 +1,33 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="html"> + <p>使用CSS選擇器從<code>msg.payload</code>中保存的html文檔中提取元素。</p> + <h3>輸入</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">字符串</span></dt> + <dd>從中提取元素的html字符串。</dd> + <dt class="optional">select <span class="property-type">字符串</span></dt> + <dd>如果未在編輯面板中配置,則可以將選擇器設置爲msg的屬性。</dd> +</dl> + <h3>Output</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">數組 | 字符串</span></dt> + <dd>結果可以是有效載荷中包含匹配元素的數組的單個消息;也可以是多條消息,每條消息都包含匹配元素。發送多條消息時,需要爲消息設置<code>parts</code>。</dd> + </dl> + <h3>詳細</h3> + <p>該節點支持CSS和jQuery選擇器的組合。查看<a href="https://github.com/fb55/CSSselect#user-content-supported-selectors" target="_blank">css-select documentation</a> 來獲得更多信息。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-JSON.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-JSON.html new file mode 100644 index 0000000..1a46c36 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-JSON.html @@ -0,0 +1,43 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="json"> + <p>在JSON字符串及其JavaScript對象表示形式之間相互轉換。</p> + <h3>輸入</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 字符串</span></dt> + <dd>JavaScript對象或JSON字符串。</dd> + <dt>schema<span class="property-type">object</span></dt> + <dd>可選的JSON Schema對象用于驗證有效負載。在將<code>msg</code>發送到下一個節點之前,將刪除該屬性。</dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 字符串</span></dt> + <dd> + <ul> + <li>如果輸入是JSON字符串,它將嘗試將其解析爲JavaScript對象。</li> + <li>如果輸入是JavaScript對象,它將創建一個JSON字符串。並可以選擇對此JSON字符串進行整形。</li> + </ul> + </dd> + <dt>schemaError<span class="property-type">數組</span></dt> + <dd>如果JSON模式驗證失敗,則catch節點將具有包含錯誤數組的<code>schemaError</code>屬性。</dd> + </dl> + <h3>詳細</h3> + <p>默認的轉換目標是<code>msg.payload</code>,但是也可以轉換消息的其它屬性。</p> + <p>您可以將其設置爲僅執行特定的轉換,而不是自動選擇雙向轉換。例如,即使對<code>HTTP In</code>節點的請求未正確設置‘content-type’,也可以使用它來確保JSON節點的轉換結果是JavaScript對象</p> + <p>如果指定了轉換爲JSON字符串,則不會對收到的字符串進行進一步的檢查。也就是說,即使指定了格式化選項,它也不會檢查字符串是否正確爲JSON或對JSON執行整形。</p> + <p>有關JSON模式的更多詳細信息,請查閱<a href="http://json-schema.org/latest/json-schema-validation.html">規範</a>.</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-XML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-XML.html new file mode 100644 index 0000000..4f04912 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-XML.html @@ -0,0 +1,48 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="xml"> + <p>在XML字符串及其JavaScript對象表示形式之間進行相互轉換。</p> + <h3>輸入</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 字符串</span></dt> + <dd>JavaScript對象或XML字符串。</dd> + </dl> + <h3>輸出</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 字符串</span></dt> + <dd> + <ul> + <li>如果輸入是字符串,它將嘗試將其解析爲XML並創建一個JavaScript對象。</li> + <li>如果輸入是JavaScript對象,它將嘗試構建XML字符串。</li> + </ul> + </dd> + <dt class="optional">options <span class="property-type">object</span></dt> + <dd>可以將選項傳遞給內部使用的XML轉換庫。請參見<a href="https://github.com/Leonidas-from-XIV/node-xml2js/blob/master/README.md#options" target="_blank"> xml2js文檔</a> 來獲取更多信息。</dd> + </dl> + <h3>詳細</h3> + <p>在XML和對象之間進行轉換時,默認情況下XML屬性會添加到名爲<code>$</code>的屬性中。將文本內容添加到名爲<code>_</code>的屬性中。這些屬性名稱可以在節點設置中更改。</p> + <p>例如,將如下所示轉換以下XML:</p> + <pre>&lt;p class="tag"&gt;Hello World&lt;/p&gt;</pre> + <pre>{ +"p": { + "$": { + "class": "tag" + }, + "_": "Hello World" +} +}</pre> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-YAML.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-YAML.html new file mode 100644 index 0000000..8ea4f87 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-YAML.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="yaml"> + <p>在YAML格式的字符串及其JavaScript對象表示形式之間相互轉換。</p> + <h3>輸入</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 字符串</span></dt> + <dd>JavaScript對象或YAML字符串。</dd> + </dl> + <h3>Outputs</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 字符串</span></dt> + <dd> + <ul> + <li>如果輸入是YAML字符串,它將嘗試將其解析爲JavaScript對象。</li> + <li>如果輸入是JavaScript對象,它將創建一個YAML字符串。</li> + </ul> + </dd> + </dl> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/17-split.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/17-split.html new file mode 100644 index 0000000..fd97b49 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/17-split.html @@ -0,0 +1,133 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="split"> + <p>將一條消息拆分爲一系列消息。</p> + + <h3>輸入</h3> + <dl class="message-properties"> + <dt>payload<span class="property-type">object | 字符串 | 數組 | buffer</span></dt> + <dd>節點的行爲由<code>msg.payload</code>的類型決定: + <ul> + <li><b>字符串</b>/<b>buffer</b> - 使用指定的字符(默認值:<code>\n</code>),緩衝區序列或固定長度將消息拆分。</li> + <li><b>數組</b> - 消息被拆分爲單個數組元素或固定長度的數組。</li> + <li><b>object</b> - 將爲對象的每個鍵/值對發送一條消息。</li> + </ul> + </dd> + </dl> + <h3>輸出</h3> + <dl class="message-properties"> + <dt>parts<span class="property-type">object</span></dt> + <dd>此屬性包含有關如何將消息與原始消息分開的信息。如果傳遞給<b>join</b>節點,則可以將序列重組爲單個消息。該屬性具有以下屬性: + <ul> + <li><code>id</code> - 一組消息的標識符</li> + <li><code>index</code> - 組中的位置</li> + <li><code>count</code> - 如果已知組中的郵件總數。請參閱下面的“流媒體模式”</li> + <li><code>type</code> - 消息的類型-字符串/數組/對象/buffer</li> + <li><code>ch</code> - 對于字符串或buffer,用于將消息拆分爲字符串或字節數組的數據</li> + <li><code>key</code> - 對于對象,創建此消息的屬性的鍵。可以將節點配置爲也將此值複制到另一個消息屬性,例如<code>msg.topic</code></li> + <li><code>len</code> - 使用固定長度值拆分消息時,每段子消息的長度</li> + </ul> + </dd> + </dl> + <h3>詳細</h3> + <p>在使用<b>join</b>節點將序列重新組合爲單個消息之前,推薦使用此節點來輕松地創建跨消息序列,執行通用操作的流。</p> + <p>它使用<code>msg.parts</code>屬性跟蹤序列的各個部分。</p> + <h4>流媒體模式</h4> + <p>該節點還可以用于重排消息流。例如,發送換行符終止命令的串行設備可能會傳遞一條消息,並在其末尾帶有部分命令。 在“流模式”下,此節點將拆分一條消息並發送每個完整的段。如果末尾有部分片段,則該節點將保留該片段,並將其添加到收到的下一條消息之前。</p> + <p>在此模式下運行時,該節點將不會設置<code>msg.parts.count</code>屬性,因爲流中期望的消息數還是未知的。這意味著它不能在自動模式下與<b>join</b>節點一起使用。</p> +</script> + +<script type="text/x-red" data-help-name="join"> + <p>將消息序列合並爲一條消息.</p> + <p>共有三種模式:</p> + <dl> + <dt>自動模式</dt> + <dd>與<b>split</b>節點配對時,它將自動將已被拆分的消息進行合並。</dd> + <dt>手動模式</dt> + <dd>手動地以各種方式合並消息序列。</dd> + <dt>列聚合模式</dt> + <dd>對消息列中的所有消息應用表達式以將其簡化爲單個消息。</dd> + </dl> + <h3>輸入</h3> + <dl class="message-properties"> + <dt class="optional">parts<span class="property-type">object</span></dt> + <dd>使用自動模式時,所有的消息都應包含此屬性。<b>split</b>節點會生成此屬性,但也可以手動進行設置。該屬性具有以下屬性: + <ul> + <li><code>id</code> - 消息組的標識符</li> + <li><code>index</code> - 組中的位置</li> + <li><code>count</code> - 如果已知組中的郵件總數。請參閱下面的“流媒體模式”</li> + <li><code>type</code> - 消息的類型-字符串/數組/對象/buffer</li> + <li><code>ch</code> - 對于字符串或buffer,用于將消息拆分爲字符串或字節數組的數據</li> + <li><code>key</code> - 對于對象,創建此消息的屬性的鍵。可以將節點配置爲也將此值複制到另一個消息屬性,例如<code>msg.topic</code>/li> + <li><code>len</code> - 使用固定長度值拆分消息時,每段子消息的長度</li> + </ul> + </dd> + <dt class="optional">complete</dt> + <dd>如果設置,則節點將以其當前狀態發送其輸出消息。</dd> + </dl> + <h3>詳細</h3> + + <h4>自動模式</h4> + <p>自動模式使用傳入消息的<code>parts</code>屬性來確定應如何連接序列。這使它可以自動逆轉<b>split</b>節點的操作。</p> + + <h4>手動模式</h4> + <p>設置爲以手動模式時,該節點能以各種不同的方法來處理消息:</p> + <ul> + <li><b>字符串</b>或<b>緩衝區</b>-通過將每條消息的選定屬性與指定的連接字符或緩衝區連接起來。</li> + <li><b>數組</b> - 通過將每個選定的屬性或整個消息添加到輸出數組</li> + <li><b>鍵/值對象</b> - 通過使用每個消息的屬性來確定存儲所需值的鍵。</li> + <li><b>merged object</b> - 通過將每個消息的屬性合並到一個對象下。</li> + </ul> + <p>輸出消息的其他屬性都取自發送結果前的最後一條消息。</p> + <p>可以用<i>計數</i>來確定應接收多少條消息來進行合並。對于對象輸出,可以設置爲達到此計數後的每條後續消息都發送一條輸出。</p> + <p>可以用<i>超時</i>來設置發送新消息之前的等待時間。</p> + <p>如果收到設置了<b>msg.complete</b>屬性的消息時發送輸出消息並重置消息列數。</p> + <p>如果收到設置了<b>msg.reset</b>屬性的消息,則部分收到的消息將被刪除而不發送,同時重置消息列數。</p> + + <h4>列聚合模式</h4> + <p>選擇列聚合模式時,將表達式應用于組成消息列的每條消息,並使用聚合值組成一條消息。</p> + + <dl class="message-properties"> + <dt>初始值</dt> + <dd>累積值的初始值(<code>$A</code>)。</dd> + <dt>聚合表達式</dt> + <dd>序列中的每個消息調用的JSONata表達式。結果將作爲累加值傳遞到表達式的下一個調用。在表達式中,可以使用以下特殊變量: + <ul> + <li><code>$A</code>: 累計值 </li> + <li><code>$I</code>: 消息在序列中的索引</li> + <li><code>$N</code>: 序列中的消息數</li> + </ul> + </dd> + <dt>最終調整式子</dt> + <dd>可選的JSONata表達式,在將聚合表達式應用于序列中的所有消息之後應用。在表達式中,可以使用以下特殊變量: + <ul> + <li><code>$A</code>: 累計值</li> + <li><code>$N</code>: 消息在序列中的索引</li> + </ul> + </dd> + <p>默認情況下,按順序從序列的第一條消息到最後一條消息應用聚合表達式。也可以選擇以相反的順序應用聚合表達式。</p> + </dl> + <p><b>例子:</b>給定一系列數字值,以下設置將計算平均值: + <ul> + <li><b>聚合表達式</b>: <code>$A+payload</code></li> + <li><b>初始值</b>: <code>0</code></li> + <li><b>最終調整式</b>: <code>$A/$N</code></li> + </ul> + </p> + <h4>儲存訊息</h4> + <p>該節點將在內部緩存消息,以便跨序列工作。運行時設置<code>nodeMessageBufferMaxLength</code>可用于設定緩存的消息數。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/18-sort.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/18-sort.html new file mode 100644 index 0000000..cb8e7fa --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/18-sort.html @@ -0,0 +1,41 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="sort"> + <p>對消息屬性或消息序列進行排序的函數。</p> + <p>當配置爲對消息屬性進行排序時,節點將對指定消息屬性所指向的數組數據進行排序。</p> + <p>當配置爲對消息序列排序時,它將對消息重新排序。</p> + <p>排序順序可以是:</p> + <ul> + <li><b>升序</b></li> + <li><b>降序</b></li> + </ul> + <p>對于數字,可以通過複選框指定數字順序。</p> + <p>排序鍵可以是元素值,也可以是JSONata表達式來對屬性值進行排序,還可以是message屬性或JSONata表達式來對消息序列進行排序。<p> + <p>在對消息序列進行排序時,排序節點依賴于接收到的消息來設置<code>msg.parts</code>。拆分節點將生成此屬性,但也可以手動創建。它具有以下屬性:</p> + <p> + <ul> + <li><code>id</code> - 消息組的標識符</li> + <li><code>index</code> - 組中的位置</li> + <li><code>count</code> - 群組中的郵件總數</li> + </ul> + </p> + <p><b>注意:</b>在此節點的處理中,消息在內部存儲。通過指定要累積的最大消息數,可以防止意外的高內存使用。默認設置是不限制消息數量。 + <ul> + <li><code>nodeMessageBufferMaxLength</code>屬性在<b>settings.js</b>中設置。</li> + </ul> + </p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/19-batch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/19-batch.html new file mode 100644 index 0000000..7987907 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/19-batch.html @@ -0,0 +1,34 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="batch"> + <p>根據各種規則創建消息序列。</p> + <h3>詳細</h3> + <p>有三種創建消息序列的模式:</p> + <dl> + <dt>訊息數</dt> + <dd>將消息分組爲給定長度的序列。 <b>overlap</b>(重疊)選項指定在一個序列的末尾應重複多少消息。</dd> + + <dt>時間間隔</dt> + <dd>對在指定時間間隔內到達的郵件進行分組。如果在該時間間隔內沒有消息到達,則該節點可以選擇發送空消息。</dd> + + <dt>串聯序列</dt> + <dd>通過串聯輸入序列來創建消息序列。每條消息必須具有<code>msg.topic</code>屬性和標識其序列的<code>msg.parts</code>屬性。該節點配置有<code>topic</code>值列表,以標識所連接的順序序列。 + </dd> + </dl> + <h4>儲存訊息</h4> + <p>該節點將在內部緩衝消息,以便跨序列工作。運行時設置<code>nodeMessageBufferMaxLength</code>可用于限制節點將緩存多少消息。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/10-file.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/10-file.html new file mode 100644 index 0000000..ce25311 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/10-file.html @@ -0,0 +1,55 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/html" data-help-name="file"> + <p>將<code>msg.payload</code>寫入文件,添加到末尾或替換現有內容。或者,它也可以刪除文件。</p> + <h3>輸入</h3> + <dl class="message-properties"> + <dt class="optional">filename<span class="property-type">字符串</span></dt> + <dd>如果未在節點中配置,則此可選屬性可以設置文件名。</dd> + </dl> + <h3>輸出</h3> + <p>寫入完成後,輸入消息將發送到輸出端口。</p> + <h3>詳細</h3> + <p>每個消息的有效荷載將添加到文件的末尾,可以選擇在每個消息之間添加一個換行符(\n)。</p> + <p>如果使用<code>msg.filename</code>,則每次寫入後文件都會關閉。爲了獲得最佳體驗,請使用固定的文件名。</p> + <p>可以將其配置爲覆蓋整個文件,而不是在文件後添加段落。例如,在將二進制數據寫入文件(例如圖像)時,應使用此選項,並且應禁用添加換行符的選項。</p> + <p>可以從編碼列表中指定寫入文件的數據的編碼。</p> + <p>您可以將此節點配置爲刪除文件。</p> +</script> + +<script type="text/html" data-help-name="file in"> + <p>以字符串或二進制緩衝區的形式讀取文件的內容。</p> + <h3>輸入</h3> + <dl class="message-properties"> + <dt class="optional">filename<span class="property-type">字符串</span></dt> + <dd>如果未在節點配置中設置,該屬性可以選擇要讀取的文件名。</dd> + </dl> + <h3>輸出</h3> + <dl class="message-properties"> + <dt>payload <span class="property-type">字符串 | buffer</span></dt> + <dd>文件的內容可以是字符串,也可以是二進制的buffer。</dd> + <dt class="optional">filename <span class="property-type">字符串</span></dt> + <dd>如果未在節點配置中設置,該屬性可以選擇要讀取的文件名。</dd> + </dl> + <h3>詳細</h3> + <p>文件名應該是絕對路徑,否則將相對于Node-RED進程的工作目錄。</p> + <p>在Windows上,可能需要使用轉義路徑分隔符,例如:<code>\\Users\\myUser</code>。</p> + <p>可以選擇將文本文件拆分爲幾行,每行輸出一條消息,或者將二進制文件拆分爲較小的buffer塊-塊大小取決于操作系統,但通常爲64k(Linux/Mac)或41k(Windows)。</p> + <p>當拆分爲多條消息時,每條消息將具有<code>parts</code>屬性集,從而形成完整的消息序列。</p> + <p>如果輸出格式爲字符串,則可以從編碼列表中指定輸入數據的編碼。</p> + <p>應該使用Catch節點來捕獲並處理錯誤。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/23-watch.html b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/23-watch.html new file mode 100644 index 0000000..d8e1b58 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/23-watch.html @@ -0,0 +1,25 @@ +<!-- + Copyright JS Foundation and other contributors, http://js.foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<script type="text/x-red" data-help-name="watch"> + <p>監視目錄或文件中的更改。</p> + <p>您可以輸入用逗號分隔的目錄和/或文件的列表。您需要在所有帶有空格的地方加上引號“...”。</p> + <p>在Windows上,必須在任何目錄名稱中使用雙反斜杠<code>\\</code>。</p> + <p>實際更改的文件的完整文件名將放入<code>msg.payload</code>和<code>msg.filename</code>中,而監視列表的字符串化版本將在<code>msg.topic</code>中返回。</p> + <p><code>msg.file</code>僅包含已更改文件的短文件名。<code>msg.type</code>更改了事物的類型,通常是<i>file</i>或<i>directory</i>,而<code>msg.size</code>保留了文件的大小(以字節爲單位)。</p> + <p>當然,在Linux中,<i>everything</i>也是一個文件,因此可以監視</p> + <p><b>注意:</b>該目錄或文件必須存在才能被監視。如果文件或目錄被刪除,即使重新創建它也可能不再被監視。</p> +</script> diff --git a/packages/connector/packages/node_modules/@node-red/nodes/package.json b/packages/connector/packages/node_modules/@node-red/nodes/package.json new file mode 100644 index 0000000..cf897db --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/nodes/package.json @@ -0,0 +1,44 @@ +{ + "name": "@node-red/nodes", + "version": "1.0.4", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/node-red/node-red.git" + }, + "contributors": [ + { + "name": "Nick O'Leary" + }, + { + "name": "Dave Conway-Jones" + } + ], + "dependencies": { + "ajv": "6.12.0", + "body-parser": "1.19.0", + "cheerio": "0.22.0", + "content-type": "1.0.4", + "cookie-parser": "1.4.4", + "cookie": "0.4.0", + "cors": "2.8.5", + "cron": "1.8.2", + "denque": "1.4.1", + "fs-extra": "8.1.0", + "fs.notify": "0.0.4", + "hash-sum": "2.0.0", + "https-proxy-agent": "5.0.0", + "is-utf8": "0.2.1", + "js-yaml": "3.13.1", + "media-typer": "1.1.0", + "mqtt": "2.18.8", + "multer": "1.4.2", + "mustache": "4.0.0", + "on-headers": "1.0.2", + "raw-body": "2.4.1", + "request": "2.88.0", + "ws": "6.2.1", + "xml2js": "0.4.23", + "iconv-lite": "0.5.1" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/registry/.npmignore b/packages/connector/packages/node_modules/@node-red/registry/.npmignore new file mode 100644 index 0000000..99c96b4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/registry/.npmignore @@ -0,0 +1,2 @@ +src +docs diff --git a/packages/connector/packages/node_modules/@node-red/registry/LICENSE b/packages/connector/packages/node_modules/@node-red/registry/LICENSE new file mode 100644 index 0000000..fc619bd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/registry/LICENSE @@ -0,0 +1,178 @@ +Copyright JS Foundation and other contributors, http://js.foundation + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/packages/connector/packages/node_modules/@node-red/registry/README.md b/packages/connector/packages/node_modules/@node-red/registry/README.md new file mode 100644 index 0000000..94981d1 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/registry/README.md @@ -0,0 +1,11 @@ +@node-red/registry +==================== + +Node-RED node registry module. + +This provides the node registry, responsible for discovering and managing the node +modules available to the Node-RED runtime. + +### Source + +The main Node-RED modules are maintained as a monorepo on [GitHub](https://github.com/node-red/node-red). diff --git a/packages/connector/packages/node_modules/@node-red/registry/lib/deprecated.js b/packages/connector/packages/node_modules/@node-red/registry/lib/deprecated.js new file mode 100644 index 0000000..9424299 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/registry/lib/deprecated.js @@ -0,0 +1,65 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +/* + * This provides a list of node types that have at one time been included with + * the core of Node-RED but have since moved out to their own module. + * + * If a user has a flow that depends on one of these types and they do not have + * the new module installed, this will help them identify the missing module. + */ +var nodes = { + "irc in": {module:"node-red-node-irc"}, + "irc out": {module:"node-red-node-irc"}, + "irc-server": {module:"node-red-node-irc"}, + + "arduino in": {module:"node-red-node-arduino"}, + "arduino out": {module:"node-red-node-arduino"}, + "arduino-board": {module:"node-red-node-arduino"}, + + "redis out": {module:"node-red-node-redis"}, + + "mongodb": {module:"node-red-node-mongodb"}, + "mongodb out": {module:"node-red-node-mongodb"}, + + "serial in": {module:"node-red-node-serialport"}, + "serial out": {module:"node-red-node-serialport"}, + "serial-port": {module:"node-red-node-serialport"}, + + "twitter-credentials": {module:"node-red-node-twitter"}, + "twitter in": {module:"node-red-node-twitter"}, + "twitter out": {module:"node-red-node-twitter"}, + + "e-mail": {module:"node-red-node-email"}, + "e-mail in": {module:"node-red-node-email"}, + + "feedparse": {module:"node-red-node-feedparser"}, + + "sentiment": {module:"node-red-node-sentiment"}, + + "tail": {module:"node-red-node-tail"}, + + "rpi-gpio in": {module:"node-red-node-pi-gpio"}, + "rpi-gpio out": {module:"node-red-node-pi-gpio"}, + "rpi-mouse": {module:"node-red-node-pi-gpio"}, + "rpi-keyboard": {module:"node-red-node-pi-gpio"} +} + +module.exports = { + get: function(id) { + return nodes[id]; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/registry/lib/index.js b/packages/connector/packages/node_modules/@node-red/registry/lib/index.js new file mode 100644 index 0000000..2805534 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/registry/lib/index.js @@ -0,0 +1,101 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + + /** + * This module provides the node registry for the Node-RED runtime. + * + * It is responsible for loading node modules and making them available + * to the runtime. + * + * @namespace @node-red/registry + */ + +var registry = require("./registry"); +var loader = require("./loader"); +var installer = require("./installer"); +var library = require("./library"); + +var settings; + +function init(runtime) { + settings = runtime.settings; + installer.init(runtime); + loader.init(runtime); + registry.init(settings,loader,runtime.events); + library.init(); +} + +function load() { + registry.load(); + return installer.checkPrereq().then(loader.load); +} + +function addModule(module) { + return loader.addModule(module).then(function() { + return registry.getModuleInfo(module); + }); +} + +function enableNodeSet(typeOrId) { + return registry.enableNodeSet(typeOrId).then(function() { + var nodeSet = registry.getNodeInfo(typeOrId); + if (!nodeSet.loaded) { + return loader.loadNodeSet(registry.getFullNodeInfo(typeOrId)).then(function() { + return registry.getNodeInfo(typeOrId); + }); + } + return Promise.resolve(nodeSet); + }); +} + +module.exports = { + init:init, + load:load, + clear: registry.clear, + registerType: registry.registerNodeConstructor, + + get: registry.getNodeConstructor, + getNodeInfo: registry.getNodeInfo, + getNodeList: registry.getNodeList, + + getModuleInfo: registry.getModuleInfo, + getModuleList: registry.getModuleList, + + getNodeConfigs: registry.getAllNodeConfigs, + getNodeConfig: registry.getNodeConfig, + getNodeIconPath: registry.getNodeIconPath, + getNodeIcons: registry.getNodeIcons, + + enableNode: enableNodeSet, + disableNode: registry.disableNodeSet, + + addModule: addModule, + removeModule: registry.removeModule, + + installModule: installer.installModule, + uninstallModule: installer.uninstallModule, + + cleanModuleList: registry.cleanModuleList, + + paletteEditorEnabled: installer.paletteEditorEnabled, + + getNodeExampleFlows: library.getExampleFlows, + getNodeExampleFlowPath: library.getExampleFlowPath, + + deprecated: require("./deprecated") + +}; diff --git a/packages/connector/packages/node_modules/@node-red/registry/lib/installer.js b/packages/connector/packages/node_modules/@node-red/registry/lib/installer.js new file mode 100644 index 0000000..3562dfb --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/registry/lib/installer.js @@ -0,0 +1,263 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +var path = require("path"); +var fs = require("fs"); + +var registry = require("./registry"); +var library = require("./library"); +var log; +var exec; + +var events; + +var child_process = require('child_process'); +var npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm'; +var paletteEditorEnabled = false; + +var settings; +var moduleRe = /^(@[^/]+?[/])?[^/]+?$/; +var slashRe = process.platform === "win32" ? /\\|[/]/ : /[/]/; + +function init(runtime) { + events = runtime.events; + settings = runtime.settings; + log = runtime.log; + exec = runtime.exec; +} + +var activePromise = Promise.resolve(); + +function checkModulePath(folder) { + var moduleName; + var err; + var fullPath = path.resolve(folder); + var packageFile = path.join(fullPath,'package.json'); + try { + var pkg = require(packageFile); + moduleName = pkg.name; + if (!pkg['node-red']) { + // TODO: nls + err = new Error("Invalid Node-RED module"); + err.code = 'invalid_module'; + throw err; + } + } catch(err2) { + err = new Error("Module not found"); + err.code = 404; + throw err; + } + return moduleName; +} + +function checkExistingModule(module,version) { + var info = registry.getModuleInfo(module); + if (info) { + if (!version || info.version === version) { + var err = new Error("Module already loaded"); + err.code = "module_already_loaded"; + throw err; + } + return true; + } + return false; +} +function installModule(module,version) { + activePromise = activePromise.then(() => { + //TODO: ensure module is 'safe' + return new Promise((resolve,reject) => { + var installName = module; + var isUpgrade = false; + try { + if (moduleRe.test(module)) { + // Simple module name - assume it can be npm installed + if (version) { + installName += "@"+version; + } + } else if (slashRe.test(module)) { + // A path - check if there's a valid package.json + installName = module; + module = checkModulePath(module); + } + isUpgrade = checkExistingModule(module,version); + } catch(err) { + return reject(err); + } + if (!isUpgrade) { + log.info(log._("server.install.installing",{name: module,version: version||"latest"})); + } else { + log.info(log._("server.install.upgrading",{name: module,version: version||"latest"})); + } + + var installDir = settings.userDir || process.env.NODE_RED_HOME || "."; + var args = ['install','--no-audit','--no-update-notifier','--save','--save-prefix="~"','--production',installName]; + log.trace(npmCommand + JSON.stringify(args)); + exec.run(npmCommand,args,{ + cwd: installDir + }, true).then(result => { + if (!isUpgrade) { + log.info(log._("server.install.installed",{name:module})); + resolve(require("./index").addModule(module).then(reportAddedModules)); + } else { + log.info(log._("server.install.upgraded",{name:module, version:version})); + events.emit("runtime-event",{id:"restart-required",payload:{type:"warning",text:"notification.warnings.restartRequired"},retain:true}); + resolve(require("./registry").setModulePendingUpdated(module,version)); + } + }).catch(result => { + var output = result.stderr; + var e; + var lookFor404 = new RegExp(" 404 .*"+module,"m"); + var lookForVersionNotFound = new RegExp("version not found: "+module+"@"+version,"m"); + if (lookFor404.test(output)) { + log.warn(log._("server.install.install-failed-not-found",{name:module})); + e = new Error("Module not found"); + e.code = 404; + reject(e); + } else if (isUpgrade && lookForVersionNotFound.test(output)) { + log.warn(log._("server.install.upgrade-failed-not-found",{name:module})); + e = new Error("Module not found"); + e.code = 404; + reject(e); + } else { + log.warn(log._("server.install.install-failed-long",{name:module})); + log.warn("------------------------------------------"); + log.warn(output); + log.warn("------------------------------------------"); + reject(new Error(log._("server.install.install-failed"))); + } + }) + }); + }).catch(err => { + // In case of error, reset activePromise to be resolvable + activePromise = Promise.resolve(); + throw err; + }); + return activePromise; +} + + +function reportAddedModules(info) { + //comms.publish("node/added",info.nodes,false); + if (info.nodes.length > 0) { + log.info(log._("server.added-types")); + for (var i=0;i<info.nodes.length;i++) { + for (var j=0;j<info.nodes[i].types.length;j++) { + log.info(" - "+ + (info.nodes[i].module?info.nodes[i].module+":":"")+ + info.nodes[i].types[j]+ + (info.nodes[i].err?" : "+info.nodes[i].err:"") + ); + } + } + } + return info; +} + +function reportRemovedModules(removedNodes) { + //comms.publish("node/removed",removedNodes,false); + log.info(log._("server.removed-types")); + for (var j=0;j<removedNodes.length;j++) { + for (var i=0;i<removedNodes[j].types.length;i++) { + log.info(" - "+(removedNodes[j].module?removedNodes[j].module+":":"")+removedNodes[j].types[i]); + } + } + return removedNodes; +} + +function uninstallModule(module) { + activePromise = activePromise.then(() => { + return new Promise((resolve,reject) => { + if (/[\s;]/.test(module)) { + reject(new Error(log._("server.install.invalid"))); + return; + } + var installDir = settings.userDir || process.env.NODE_RED_HOME || "."; + var moduleDir = path.join(installDir,"node_modules",module); + + try { + fs.statSync(moduleDir); + } catch(err) { + return reject(new Error(log._("server.install.uninstall-failed",{name:module}))); + } + + var list = registry.removeModule(module); + log.info(log._("server.install.uninstalling",{name:module})); + + var args = ['remove','--no-audit','--no-update-notifier','--save',module]; + log.trace(npmCommand + JSON.stringify(args)); + + exec.run(npmCommand,args,{ + cwd: installDir, + },true).then(result => { + log.info(log._("server.install.uninstalled",{name:module})); + reportRemovedModules(list); + library.removeExamplesDir(module); + resolve(list); + }).catch(result => { + var output = result.stderr; + log.warn(log._("server.install.uninstall-failed-long",{name:module})); + log.warn("------------------------------------------"); + log.warn(output.toString()); + log.warn("------------------------------------------"); + reject(new Error(log._("server.install.uninstall-failed",{name:module}))); + }); + }); + }).catch(err => { + // In case of error, reset activePromise to be resolvable + activePromise = Promise.resolve(); + throw err; + }); + return activePromise; +} + +function checkPrereq() { + if (settings.hasOwnProperty('editorTheme') && + settings.editorTheme.hasOwnProperty('palette') && + settings.editorTheme.palette.hasOwnProperty('editable') && + settings.editorTheme.palette.editable === false + ) { + log.info(log._("server.palette-editor.disabled")); + paletteEditorEnabled = false; + return Promise.resolve(); + } else { + return new Promise(resolve => { + child_process.execFile(npmCommand,['-v'],function(err,stdout) { + if (err) { + log.info(log._("server.palette-editor.npm-not-found")); + paletteEditorEnabled = false; + } else { + if (parseInt(stdout.split(".")[0]) < 3) { + log.info(log._("server.palette-editor.npm-too-old")); + paletteEditorEnabled = false; + } else { + paletteEditorEnabled = true; + } + } + resolve(); + }); + }) + } +} +module.exports = { + init: init, + checkPrereq: checkPrereq, + installModule: installModule, + uninstallModule: uninstallModule, + paletteEditorEnabled: function() { + return paletteEditorEnabled + } +} diff --git a/packages/connector/packages/node_modules/@node-red/registry/lib/library.js b/packages/connector/packages/node_modules/@node-red/registry/lib/library.js new file mode 100644 index 0000000..a8ca8a7 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/registry/lib/library.js @@ -0,0 +1,100 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var fs = require('fs'); +var fspath = require('path'); + +var runtime; + +var exampleRoots = {}; +var exampleFlows = null; + +function getFlowsFromPath(path) { + return new Promise(function(resolve,reject) { + var result = {}; + fs.readdir(path,function(err,files) { + var promises = []; + var validFiles = []; + files.forEach(function(file) { + var fullPath = fspath.join(path,file); + var stats = fs.lstatSync(fullPath); + if (stats.isDirectory()) { + validFiles.push(file); + promises.push(getFlowsFromPath(fullPath)); + } else if (/\.json$/.test(file)){ + validFiles.push(file); + promises.push(Promise.resolve(file.split(".")[0])) + } + }) + var i=0; + Promise.all(promises).then(function(results) { + results.forEach(function(r) { + if (typeof r === 'string') { + result.f = result.f||[]; + result.f.push(r); + } else { + result.d = result.d||{}; + result.d[validFiles[i]] = r; + } + i++; + }) + resolve(result); + }) + }); + }) +} + +function addNodeExamplesDir(module,path) { + exampleRoots[module] = path; + return getFlowsFromPath(path).then(function(result) { + if (JSON.stringify(result).indexOf('{"f":') === -1) { return; } + exampleFlows = exampleFlows||{}; + exampleFlows[module] = result; + }); +} +function removeNodeExamplesDir(module) { + delete exampleRoots[module]; + if (exampleFlows) { + delete exampleFlows[module]; + } + if (exampleFlows && Object.keys(exampleFlows).length === 0) { + exampleFlows = null; + } +} + +function init() { + exampleRoots = {}; + exampleFlows = null; +} + +function getExampleFlows() { + return exampleFlows; +} + +function getExampleFlowPath(module,path) { + if (exampleRoots[module]) { + return fspath.join(exampleRoots[module],path)+".json"; + } + return null; +} + +module.exports = { + init: init, + addExamplesDir: addNodeExamplesDir, + removeExamplesDir: removeNodeExamplesDir, + getExampleFlows: getExampleFlows, + getExampleFlowPath: getExampleFlowPath +} diff --git a/packages/connector/packages/node_modules/@node-red/registry/lib/loader.js b/packages/connector/packages/node_modules/@node-red/registry/lib/loader.js new file mode 100644 index 0000000..09589c8 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/registry/lib/loader.js @@ -0,0 +1,373 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require("when"); +var fs = require("fs"); +var path = require("path"); +var semver = require("semver"); + +var localfilesystem = require("./localfilesystem"); +var registry = require("./registry"); +var registryUtil = require("./util") +var i18n = require("@node-red/util").i18n; + +var settings; +var runtime; + +function init(_runtime) { + runtime = _runtime; + settings = runtime.settings; + localfilesystem.init(runtime); + registryUtil.init(runtime); +} + +function load(disableNodePathScan) { + // To skip node scan, the following line will use the stored node list. + // We should expose that as an option at some point, although the + // performance gains are minimal. + //return loadNodeFiles(registry.getModuleList()); + runtime.log.info(runtime.log._("server.loading")); + + var nodeFiles = localfilesystem.getNodeFiles(disableNodePathScan); + return loadNodeFiles(nodeFiles); +} + +function loadNodeFiles(nodeFiles) { + var promises = []; + var nodes = []; + for (var module in nodeFiles) { + /* istanbul ignore else */ + if (nodeFiles.hasOwnProperty(module)) { + if (nodeFiles[module].redVersion && + !semver.satisfies(runtime.version().replace(/(\-[1-9A-Za-z-][0-9A-Za-z-\.]*)?(\+[0-9A-Za-z-\.]+)?$/,""), nodeFiles[module].redVersion)) { + //TODO: log it + runtime.log.warn("["+module+"] "+runtime.log._("server.node-version-mismatch",{version:nodeFiles[module].redVersion})); + nodeFiles[module].err = "version_mismatch"; + continue; + } + if (module == "node-red" || !registry.getModuleInfo(module)) { + var first = true; + for (var node in nodeFiles[module].nodes) { + /* istanbul ignore else */ + if (nodeFiles[module].nodes.hasOwnProperty(node)) { + if (module != "node-red" && first) { + // Check the module directory exists + first = false; + var fn = nodeFiles[module].nodes[node].file; + var parts = fn.split("/"); + var i = parts.length-1; + for (;i>=0;i--) { + if (parts[i] == "node_modules") { + break; + } + } + var moduleFn = parts.slice(0,i+2).join("/"); + + try { + var stat = fs.statSync(moduleFn); + } catch(err) { + // Module not found, don't attempt to load its nodes + break; + } + } + + try { + promises.push(loadNodeConfig(nodeFiles[module].nodes[node]).then((function() { + var m = module; + var n = node; + return function(nodeSet) { + nodeFiles[m].nodes[n] = nodeSet; + nodes.push(nodeSet); + } + })())); + } catch(err) { + // + } + } + } + } + } + } + return when.settle(promises).then(function(results) { + for (var module in nodeFiles) { + if (nodeFiles.hasOwnProperty(module)) { + if (!nodeFiles[module].err) { + registry.addModule(nodeFiles[module]); + } + } + } + return loadNodeSetList(nodes); + }); +} + +function loadNodeConfig(fileInfo) { + return new Promise(function(resolve) { + var file = fileInfo.file; + var module = fileInfo.module; + var name = fileInfo.name; + var version = fileInfo.version; + + var id = module + "/" + name; + var info = registry.getNodeInfo(id); + var isEnabled = true; + if (info) { + if (info.hasOwnProperty("loaded")) { + throw new Error(file+" already loaded"); + } + isEnabled = info.enabled; + } + + var node = { + id: id, + module: module, + name: name, + file: file, + template: file.replace(/\.js$/,".html"), + enabled: isEnabled, + loaded:false, + version: version, + local: fileInfo.local + }; + if (fileInfo.hasOwnProperty("types")) { + node.types = fileInfo.types; + } + + fs.readFile(node.template,'utf8', function(err,content) { + if (err) { + node.types = []; + if (err.code === 'ENOENT') { + if (!node.types) { + node.types = []; + } + node.err = "Error: "+node.template+" does not exist"; + } else { + node.types = []; + node.err = err.toString(); + } + resolve(node); + } else { + var types = []; + + var regExp = /<script (?:[^>]*)data-template-name\s*=\s*['"]([^'"]*)['"]/gi; + var match = null; + + while ((match = regExp.exec(content)) !== null) { + types.push(match[1]); + } + node.types = types; + + var langRegExp = /^<script[^>]* data-lang\s*=\s*['"](.+?)['"]/i; + regExp = /(<script[^>]* data-help-name=[\s\S]*?<\/script>)/gi; + match = null; + var mainContent = ""; + var helpContent = {}; + var index = 0; + while ((match = regExp.exec(content)) !== null) { + mainContent += content.substring(index,regExp.lastIndex-match[1].length); + index = regExp.lastIndex; + var help = content.substring(regExp.lastIndex-match[1].length,regExp.lastIndex); + + var lang = i18n.defaultLang; + if ((match = langRegExp.exec(help)) !== null) { + lang = match[1]; + } + if (!helpContent.hasOwnProperty(lang)) { + helpContent[lang] = ""; + } + + helpContent[lang] += help; + } + mainContent += content.substring(index); + + node.config = mainContent; + node.help = helpContent; + // TODO: parse out the javascript portion of the template + //node.script = ""; + for (var i=0;i<node.types.length;i++) { + if (registry.getTypeId(node.types[i])) { + node.err = node.types[i]+" already registered"; + break; + } + } + if (node.module === 'node-red') { + // do not look up locales directory for core nodes + node.namespace = node.module; + resolve(node); + return; + } + fs.stat(path.join(path.dirname(file),"locales"),function(err,stat) { + if (!err) { + node.namespace = node.id; + i18n.registerMessageCatalog(node.id, + path.join(path.dirname(file),"locales"), + path.basename(file,".js")+".json") + .then(function() { + resolve(node); + }); + } else { + node.namespace = node.module; + resolve(node); + } + }); + } + }); + }); +} + +/** + * Loads the specified node into the runtime + * @param node a node info object - see loadNodeConfig + * @return a promise that resolves to an update node info object. The object + * has the following properties added: + * err: any error encountered whilst loading the node + * + */ +function loadNodeSet(node) { + var nodeDir = path.dirname(node.file); + var nodeFn = path.basename(node.file); + if (!node.enabled) { + return Promise.resolve(node); + } else { + } + try { + var loadPromise = null; + var r = require(node.file); + if (typeof r === "function") { + + var red = registryUtil.createNodeApi(node); + var promise = r(red); + if (promise != null && typeof promise.then === "function") { + loadPromise = promise.then(function() { + node.enabled = true; + node.loaded = true; + return node; + }).catch(function(err) { + node.err = err; + return node; + }); + } + } + if (loadPromise == null) { + node.enabled = true; + node.loaded = true; + loadPromise = Promise.resolve(node); + } + return loadPromise; + } catch(err) { + node.err = err; + var stack = err.stack; + var message; + if (stack) { + var i = stack.indexOf(node.file); + if (i > -1) { + var excerpt = stack.substring(i+node.file.length+1,i+node.file.length+20); + var m = /^(\d+):(\d+)/.exec(excerpt); + if (m) { + node.err = err+" (line:"+m[1]+")"; + } + } + } + return Promise.resolve(node); + } +} + +function loadNodeSetList(nodes) { + var promises = []; + nodes.forEach(function(node) { + if (!node.err) { + promises.push(loadNodeSet(node)); + } else { + promises.push(node); + } + }); + + return when.settle(promises).then(function() { + if (settings.available()) { + return registry.saveNodeList(); + } else { + return; + } + }); +} + +function addModule(module) { + if (!settings.available()) { + throw new Error("Settings unavailable"); + } + var nodes = []; + if (registry.getModuleInfo(module)) { + // TODO: nls + var e = new Error("module_already_loaded"); + e.code = "module_already_loaded"; + return Promise.reject(e); + } + try { + var moduleFiles = localfilesystem.getModuleFiles(module); + return loadNodeFiles(moduleFiles); + } catch(err) { + return Promise.reject(err); + } +} + +function loadNodeHelp(node,lang) { + var base = path.basename(node.template); + var localePath; + if (node.module === 'node-red') { + var cat_dir = path.dirname(node.template); + var cat = path.basename(cat_dir); + var dir = path.dirname(cat_dir); + localePath = path.join(dir, "..", "locales", lang, cat, base) + } + else { + var dir = path.dirname(node.template); + localePath = path.join(dir,"locales",lang,base); + } + try { + // TODO: make this async + var content = fs.readFileSync(localePath, "utf8") + return content; + } catch(err) { + return null; + } +} + +function getNodeHelp(node,lang) { + if (!node.help[lang]) { + var help = loadNodeHelp(node,lang); + if (help == null) { + var langParts = lang.split("-"); + if (langParts.length == 2) { + help = loadNodeHelp(node,langParts[0]); + } + } + if (help) { + node.help[lang] = help; + } else if (lang === i18n.defaultLang) { + return null; + } else { + node.help[lang] = getNodeHelp(node, i18n.defaultLang); + } + } + return node.help[lang]; +} + +module.exports = { + init: init, + load: load, + addModule: addModule, + loadNodeSet: loadNodeSet, + getNodeHelp: getNodeHelp +} diff --git a/packages/connector/packages/node_modules/@node-red/registry/lib/localfilesystem.js b/packages/connector/packages/node_modules/@node-red/registry/lib/localfilesystem.js new file mode 100644 index 0000000..9479720 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/registry/lib/localfilesystem.js @@ -0,0 +1,404 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var fs = require("fs"); +var path = require("path"); + +var events; +var log; + +var log = require("@node-red/util").log; +var i18n = require("@node-red/util").i18n; + +var settings; +var disableNodePathScan = false; +var iconFileExtensions = [".png", ".gif", ".svg"]; + +function init(runtime) { + settings = runtime.settings; + events = runtime.events; +} + +function isIncluded(name) { + if (settings.nodesIncludes) { + for (var i=0;i<settings.nodesIncludes.length;i++) { + if (settings.nodesIncludes[i] == name) { + return true; + } + } + } else { + return true; + } + return false; +} + +function isExcluded(name) { + if (settings.nodesExcludes) { + for (var i=0;i<settings.nodesExcludes.length;i++) { + if (settings.nodesExcludes[i] == name) { + return true; + } + } + } + return false; +} +function getLocalFile(file) { + if (!isIncluded(path.basename(file)) || isExcluded(path.basename(file))) { + return null; + } + try { + fs.statSync(file.replace(/\.js$/,".html")); + return { + file: file, + module: "node-red", + name: path.basename(file).replace(/^\d+-/,"").replace(/\.js$/,""), + version: settings.version + }; + } catch(err) { + return null; + } +} + + +/** + * Synchronously walks the directory looking for node files. + * Emits 'node-icon-dir' events for an icon dirs found + * @param dir the directory to search + * @return an array of fully-qualified paths to .js files + */ +function getLocalNodeFiles(dir) { + dir = path.resolve(dir); + + var result = []; + var files = []; + var icons = []; + try { + files = fs.readdirSync(dir); + } catch(err) { + return {files: [], icons: []}; + } + files.sort(); + files.forEach(function(fn) { + var stats = fs.statSync(path.join(dir,fn)); + if (stats.isFile()) { + if (/\.js$/.test(fn)) { + var info = getLocalFile(path.join(dir,fn)); + if (info) { + result.push(info); + } + } + } else if (stats.isDirectory()) { + // Ignore /.dirs/, /lib/ /node_modules/ + if (!/^(\..*|lib|icons|node_modules|test|locales)$/.test(fn)) { + var subDirResults = getLocalNodeFiles(path.join(dir,fn)); + result = result.concat(subDirResults.files); + icons = icons.concat(subDirResults.icons); + } else if (fn === "icons") { + var iconList = scanIconDir(path.join(dir,fn)); + icons.push({path:path.join(dir,fn),icons:iconList}); + } + } + }); + return {files: result, icons: icons} +} + +function scanDirForNodesModules(dir,moduleName) { + var results = []; + var scopeName; + try { + var files = fs.readdirSync(dir); + if (moduleName) { + var m = /^(?:(@[^/]+)[/])?([^@/]+)/.exec(moduleName); + if (m) { + scopeName = m[1]; + moduleName = m[2]; + } + } + for (var i=0;i<files.length;i++) { + var fn = files[i]; + if (/^@/.test(fn)) { + if (scopeName && scopeName === fn) { + // Looking for a specific scope/module + results = results.concat(scanDirForNodesModules(path.join(dir,fn),moduleName)); + break; + } else { + results = results.concat(scanDirForNodesModules(path.join(dir,fn),moduleName)); + } + } else { + if (isIncluded(fn) && !isExcluded(fn) && (!moduleName || fn == moduleName)) { + var pkgfn = path.join(dir,fn,"package.json"); + try { + var pkg = require(pkgfn); + if (pkg['node-red']) { + var moduleDir = path.join(dir,fn); + results.push({dir:moduleDir,package:pkg}); + } + } catch(err) { + if (err.code != "MODULE_NOT_FOUND") { + // TODO: handle unexpected error + } + } + if (fn == moduleName) { + break; + } + } + } + } + } catch(err) { + } + return results; +} + +/** + * Scans the node_modules path for nodes + * @param moduleName the name of the module to be found + * @return a list of node modules: {dir,package} + */ +function scanTreeForNodesModules(moduleName) { + var dir = settings.coreNodesDir; + var results = []; + var userDir; + + if (settings.userDir) { + userDir = path.join(settings.userDir,"node_modules"); + results = scanDirForNodesModules(userDir,moduleName); + results.forEach(function(r) { r.local = true; }); + } + + if (dir) { + var up = path.resolve(path.join(dir,"..")); + while (up !== dir) { + var pm = path.join(dir,"node_modules"); + if (pm != userDir) { + results = results.concat(scanDirForNodesModules(pm,moduleName)); + } + dir = up; + up = path.resolve(path.join(dir,"..")); + } + } + return results; +} + +function getModuleNodeFiles(module) { + + var moduleDir = module.dir; + var pkg = module.package; + + var nodes = pkg['node-red'].nodes||{}; + var results = []; + var iconDirs = []; + var iconList = []; + for (var n in nodes) { + /* istanbul ignore else */ + if (nodes.hasOwnProperty(n)) { + var file = path.join(moduleDir,nodes[n]); + results.push({ + file: file, + module: pkg.name, + name: n, + version: pkg.version + }); + var iconDir = path.join(moduleDir,path.dirname(nodes[n]),"icons"); + if (iconDirs.indexOf(iconDir) == -1) { + try { + fs.statSync(iconDir); + var icons = scanIconDir(iconDir); + iconList.push({path:iconDir,icons:icons}); + iconDirs.push(iconDir); + } catch(err) { + } + } + } + } + var result = {files:results,icons:iconList}; + + var examplesDir = path.join(moduleDir,"examples"); + try { + fs.statSync(examplesDir) + result.examples = {path:examplesDir}; + // events.emit("node-examples-dir",{name:pkg.name,path:examplesDir}); + } catch(err) { + } + return result; +} + +function getNodeFiles(disableNodePathScan) { + var dir; + // Find all of the nodes to load + var nodeFiles = []; + var results; + + var dir; + var iconList = []; + if (settings.coreNodesDir) { + results = getLocalNodeFiles(path.resolve(settings.coreNodesDir)); + nodeFiles = nodeFiles.concat(results.files); + iconList = iconList.concat(results.icons); + var defaultLocalesPath = path.join(settings.coreNodesDir,"locales"); + i18n.registerMessageCatalog("node-red",defaultLocalesPath,"messages.json"); + } + + if (settings.userDir) { + dir = path.join(settings.userDir,"lib","icons"); + var icons = scanIconDir(dir); + if (icons.length > 0) { + iconList.push({path:dir,icons:icons}); + } + + dir = path.join(settings.userDir,"nodes"); + results = getLocalNodeFiles(path.resolve(dir)); + nodeFiles = nodeFiles.concat(results.files); + iconList = iconList.concat(results.icons); + } + if (settings.nodesDir) { + dir = settings.nodesDir; + if (typeof settings.nodesDir == "string") { + dir = [dir]; + } + for (var i=0;i<dir.length;i++) { + results = getLocalNodeFiles(dir[i]); + nodeFiles = nodeFiles.concat(results.files); + iconList = iconList.concat(results.icons); + } + } + + var nodeList = { + "node-red": { + name: "node-red", + version: settings.version, + nodes: {}, + icons: iconList + } + } + nodeFiles.forEach(function(node) { + nodeList["node-red"].nodes[node.name] = node; + }); + + if (!disableNodePathScan) { + var moduleFiles = scanTreeForNodesModules(); + + // Filter the module list to ignore global modules + // that have also been installed locally - allowing the user to + // update a module they may not otherwise be able to touch + + moduleFiles.sort(function(A,B) { + if (A.local && !B.local) { + return -1 + } else if (!A.local && B.local) { + return 1 + } + return 0; + }) + var knownModules = {}; + moduleFiles = moduleFiles.filter(function(mod) { + var result; + if (!knownModules[mod.package.name]) { + knownModules[mod.package.name] = true; + result = true; + } else { + result = false; + } + log.debug("Module: "+mod.package.name+" "+mod.package.version+(result?"":" *ignored due to local copy*")); + log.debug(" "+mod.dir); + return result; + }); + + moduleFiles.forEach(function(moduleFile) { + var nodeModuleFiles = getModuleNodeFiles(moduleFile); + nodeList[moduleFile.package.name] = { + name: moduleFile.package.name, + version: moduleFile.package.version, + path: moduleFile.dir, + local: moduleFile.local||false, + nodes: {}, + icons: nodeModuleFiles.icons, + examples: nodeModuleFiles.examples + }; + if (moduleFile.package['node-red'].version) { + nodeList[moduleFile.package.name].redVersion = moduleFile.package['node-red'].version; + } + nodeModuleFiles.files.forEach(function(node) { + node.local = moduleFile.local||false; + nodeList[moduleFile.package.name].nodes[node.name] = node; + }); + nodeFiles = nodeFiles.concat(nodeModuleFiles.files); + }); + } else { + // console.log("node path scan disabled"); + } + return nodeList; +} + +function getModuleFiles(module) { + var nodeList = {}; + + var moduleFiles = scanTreeForNodesModules(module); + if (moduleFiles.length === 0) { + var err = new Error(log._("nodes.registry.localfilesystem.module-not-found", {module:module})); + err.code = 'MODULE_NOT_FOUND'; + throw err; + } + + moduleFiles.forEach(function(moduleFile) { + var nodeModuleFiles = getModuleNodeFiles(moduleFile); + nodeList[moduleFile.package.name] = { + name: moduleFile.package.name, + version: moduleFile.package.version, + nodes: {}, + icons: nodeModuleFiles.icons, + examples: nodeModuleFiles.examples + }; + if (moduleFile.package['node-red'].version) { + nodeList[moduleFile.package.name].redVersion = moduleFile.package['node-red'].version; + } + nodeModuleFiles.files.forEach(function(node) { + nodeList[moduleFile.package.name].nodes[node.name] = node; + nodeList[moduleFile.package.name].nodes[node.name].local = moduleFile.local || false; + }); + }); + return nodeList; +} + +// If this finds an svg and a png with the same name, it will only list the svg +function scanIconDir(dir) { + var iconList = []; + var svgs = {}; + try { + var files = fs.readdirSync(dir); + files.forEach(function(file) { + var stats = fs.statSync(path.join(dir, file)); + var ext = path.extname(file).toLowerCase(); + if (stats.isFile() && iconFileExtensions.indexOf(ext) !== -1) { + iconList.push(file); + if (ext === ".svg") { + svgs[file.substring(0,file.length-4)] = true; + } + } + }); + } catch(err) { + } + iconList = iconList.filter(f => { + return /.svg$/i.test(f) || !svgs[f.substring(0,f.length-4)] + }) + return iconList; +} + +module.exports = { + init: init, + getNodeFiles: getNodeFiles, + getLocalFile: getLocalFile, + getModuleFiles: getModuleFiles +} diff --git a/packages/connector/packages/node_modules/@node-red/registry/lib/registry.js b/packages/connector/packages/node_modules/@node-red/registry/lib/registry.js new file mode 100644 index 0000000..89f04ea --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/registry/lib/registry.js @@ -0,0 +1,647 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + //var UglifyJS = require("uglify-js"); +var path = require("path"); +var fs = require("fs"); + +var library = require("./library"); + +var events; +var settings; +var loader; + +var nodeConfigCache = {}; +var moduleConfigs = {}; +var nodeList = []; +var nodeConstructors = {}; +var nodeTypeToId = {}; +var moduleNodes = {}; + +function init(_settings,_loader, _events) { + settings = _settings; + loader = _loader; + events = _events; + moduleNodes = {}; + nodeTypeToId = {}; + nodeConstructors = {}; + nodeList = []; + nodeConfigCache = {}; +} + +function load() { + if (settings.available()) { + moduleConfigs = loadNodeConfigs(); + } else { + moduleConfigs = {}; + } +} + +function filterNodeInfo(n) { + var r = { + id: n.id||n.module+"/"+n.name, + name: n.name, + types: n.types, + enabled: n.enabled, + local: n.local||false + }; + if (n.hasOwnProperty("module")) { + r.module = n.module; + } + if (n.hasOwnProperty("err")) { + r.err = n.err; + } + return r; +} + + + +function getModule(id) { + var parts = id.split("/"); + return parts.slice(0,parts.length-1).join("/"); +} + +function getNode(id) { + var parts = id.split("/"); + return parts[parts.length-1]; +} + +function saveNodeList() { + var moduleList = {}; + var hadPending = false; + var hasPending = false; + for (var module in moduleConfigs) { + /* istanbul ignore else */ + if (moduleConfigs.hasOwnProperty(module)) { + if (Object.keys(moduleConfigs[module].nodes).length > 0) { + if (!moduleList[module]) { + moduleList[module] = { + name: module, + version: moduleConfigs[module].version, + local: moduleConfigs[module].local||false, + nodes: {} + }; + if (moduleConfigs[module].hasOwnProperty('pending_version')) { + hadPending = true; + if (moduleConfigs[module].pending_version !== moduleConfigs[module].version) { + moduleList[module].pending_version = moduleConfigs[module].pending_version; + hasPending = true; + } else { + delete moduleConfigs[module].pending_version; + } + } + } + var nodes = moduleConfigs[module].nodes; + for(var node in nodes) { + /* istanbul ignore else */ + if (nodes.hasOwnProperty(node)) { + var config = nodes[node]; + var n = filterNodeInfo(config); + delete n.err; + delete n.file; + delete n.id; + n.file = config.file; + moduleList[module].nodes[node] = n; + } + } + } + } + } + if (hadPending && !hasPending) { + events.emit("runtime-event",{id:"restart-required",retain: true}); + } + if (settings.available()) { + return settings.set("nodes",moduleList); + } else { + return Promise.reject("Settings unavailable"); + } +} + +function loadNodeConfigs() { + var configs = settings.get("nodes"); + + if (!configs) { + return {}; + } else if (configs['node-red']) { + return configs; + } else { + // Migrate from the 0.9.1 format of settings + var newConfigs = {}; + for (var id in configs) { + /* istanbul ignore else */ + if (configs.hasOwnProperty(id)) { + var nodeConfig = configs[id]; + var moduleName; + var nodeSetName; + + if (nodeConfig.module) { + moduleName = nodeConfig.module; + nodeSetName = nodeConfig.name.split(":")[1]; + } else { + moduleName = "node-red"; + nodeSetName = nodeConfig.name.replace(/^\d+-/,"").replace(/\.js$/,""); + } + + if (!newConfigs[moduleName]) { + newConfigs[moduleName] = { + name: moduleName, + nodes:{} + }; + } + newConfigs[moduleName].nodes[nodeSetName] = { + name: nodeSetName, + types: nodeConfig.types, + enabled: nodeConfig.enabled, + module: moduleName + }; + } + } + settings.set("nodes",newConfigs); + return newConfigs; + } +} + +function addModule(module) { + moduleNodes[module.name] = []; + moduleConfigs[module.name] = module; + for (var setName in module.nodes) { + if (module.nodes.hasOwnProperty(setName)) { + var set = module.nodes[setName]; + moduleNodes[module.name].push(set.name); + nodeList.push(set.id); + if (!set.err) { + set.types.forEach(function(t) { + if (nodeTypeToId.hasOwnProperty(t)) { + set.err = "Type already registered"; + set.err.code = "type_already_registered"; + set.err.details = { + type: t, + moduleA: getNodeInfo(t).module, + moduleB: set.module + } + + } + }); + if (!set.err) { + set.types.forEach(function(t) { + nodeTypeToId[t] = set.id; + }); + } + } + } + } + if (module.icons) { + icon_paths[module.name] = icon_paths[module.name] || []; + module.icons.forEach(icon=>icon_paths[module.name].push(path.resolve(icon.path)) ) + } + if (module.examples) { + library.addExamplesDir(module.name,module.examples.path); + } + nodeConfigCache = {}; +} + + +function removeNode(id) { + var config = moduleConfigs[getModule(id)].nodes[getNode(id)]; + if (!config) { + throw new Error("Unrecognised id: "+id); + } + delete moduleConfigs[getModule(id)].nodes[getNode(id)]; + var i = nodeList.indexOf(id); + if (i > -1) { + nodeList.splice(i,1); + } + config.types.forEach(function(t) { + var typeId = nodeTypeToId[t]; + if (typeId === id) { + delete nodeConstructors[t]; + delete nodeTypeToId[t]; + } + }); + config.enabled = false; + config.loaded = false; + nodeConfigCache = {}; + return filterNodeInfo(config); +} + +function removeModule(module) { + if (!settings.available()) { + throw new Error("Settings unavailable"); + } + var nodes = moduleNodes[module]; + if (!nodes) { + throw new Error("Unrecognised module: "+module); + } + var infoList = []; + for (var i=0;i<nodes.length;i++) { + infoList.push(removeNode(module+"/"+nodes[i])); + } + delete moduleNodes[module]; + delete moduleConfigs[module]; + saveNodeList(); + return infoList; +} + +function getNodeInfo(typeOrId) { + var id = typeOrId; + if (nodeTypeToId.hasOwnProperty(typeOrId)) { + id = nodeTypeToId[typeOrId]; + } + /* istanbul ignore else */ + if (id) { + var module = moduleConfigs[getModule(id)]; + if (module) { + var config = module.nodes[getNode(id)]; + if (config) { + var info = filterNodeInfo(config); + if (config.hasOwnProperty("loaded")) { + info.loaded = config.loaded; + } + if (module.pending_version) { + info.pending_version = module.pending_version; + } + + info.version = module.version; + return info; + } + } + } + return null; +} + +function getFullNodeInfo(typeOrId) { + // Used by index.enableNodeSet so that .file can be retrieved to pass + // to loader.loadNodeSet + var id = typeOrId; + if (nodeTypeToId.hasOwnProperty(typeOrId)) { + id = nodeTypeToId[typeOrId]; + } + /* istanbul ignore else */ + if (id) { + var module = moduleConfigs[getModule(id)]; + if (module) { + return module.nodes[getNode(id)]; + } + } + return null; +} + +function getNodeList(filter) { + var list = []; + for (var module in moduleConfigs) { + /* istanbul ignore else */ + if (moduleConfigs.hasOwnProperty(module)) { + var nodes = moduleConfigs[module].nodes; + for (var node in nodes) { + /* istanbul ignore else */ + if (nodes.hasOwnProperty(node)) { + var nodeInfo = filterNodeInfo(nodes[node]); + nodeInfo.version = moduleConfigs[module].version; + if (moduleConfigs[module].pending_version) { + nodeInfo.pending_version = moduleConfigs[module].pending_version; + } + if (!filter || filter(nodes[node])) { + list.push(nodeInfo); + } + } + } + } + } + return list; +} + +function getModuleList() { + //var list = []; + //for (var module in moduleNodes) { + // /* istanbul ignore else */ + // if (moduleNodes.hasOwnProperty(module)) { + // list.push(registry.getModuleInfo(module)); + // } + //} + //return list; + return moduleConfigs; + +} + +function getModuleInfo(module) { + if (moduleNodes[module]) { + var nodes = moduleNodes[module]; + var m = { + name: module, + version: moduleConfigs[module].version, + local: moduleConfigs[module].local, + path: moduleConfigs[module].path, + nodes: [] + }; + if (moduleConfigs[module] && moduleConfigs[module].pending_version) { + m.pending_version = moduleConfigs[module].pending_version; + } + for (var i = 0; i < nodes.length; ++i) { + var nodeInfo = filterNodeInfo(moduleConfigs[module].nodes[nodes[i]]); + nodeInfo.version = m.version; + m.nodes.push(nodeInfo); + } + return m; + } else { + return null; + } +} + +function getCaller(){ + var orig = Error.prepareStackTrace; + Error.prepareStackTrace = function(_, stack){ return stack; }; + var err = new Error(); + Error.captureStackTrace(err, arguments.callee); + var stack = err.stack; + Error.prepareStackTrace = orig; + stack.shift(); + stack.shift(); + return stack[0].getFileName(); +} + +function registerNodeConstructor(nodeSet,type,constructor) { + if (nodeConstructors.hasOwnProperty(type)) { + throw new Error(type+" already registered"); + } + //TODO: Ensure type is known - but doing so will break some tests + // that don't have a way to register a node template ahead + // of registering the constructor + + var nodeSetInfo = getFullNodeInfo(nodeSet); + if (nodeSetInfo) { + if (nodeSetInfo.types.indexOf(type) === -1) { + // A type is being registered for a known set, but for some reason + // we didn't spot it when parsing the HTML file. + // Registered a type is the definitive action - not the presence + // of an edit template. Ensure it is on the list of known types. + nodeSetInfo.types.push(type); + } + } + + nodeConstructors[type] = constructor; + events.emit("type-registered",type); +} + +function getAllNodeConfigs(lang) { + if (!nodeConfigCache[lang]) { + var result = ""; + var script = ""; + for (var i=0;i<nodeList.length;i++) { + var id = nodeList[i]; + var config = moduleConfigs[getModule(id)].nodes[getNode(id)]; + if (config.enabled && !config.err) { + result += "\n<!-- --- [red-module:"+id+"] --- -->\n"; + result += config.config; + result += loader.getNodeHelp(config,lang||"en-US")||""; + //script += config.script; + } + } + //if (script.length > 0) { + // result += '<script type="text/javascript">'; + // result += UglifyJS.minify(script, {fromString: true}).code; + // result += '</script>'; + //} + nodeConfigCache[lang] = result; + } + return nodeConfigCache[lang]; +} + +function getNodeConfig(id,lang) { + var config = moduleConfigs[getModule(id)]; + if (!config) { + return null; + } + config = config.nodes[getNode(id)]; + if (config) { + var result = "<!-- --- [red-module:"+id+"] --- -->\n"+config.config; + result += loader.getNodeHelp(config,lang||"en-US") + + //if (config.script) { + // result += '<script type="text/javascript">'+config.script+'</script>'; + //} + return result; + } else { + return null; + } +} + +function getNodeConstructor(type) { + var id = nodeTypeToId[type]; + + var config; + if (typeof id === "undefined") { + config = undefined; + } else { + config = moduleConfigs[getModule(id)].nodes[getNode(id)]; + } + + if (!config || (config.enabled && !config.err)) { + return nodeConstructors[type]; + } + return null; +} + +function clear() { + nodeConfigCache = {}; + moduleConfigs = {}; + nodeList = []; + nodeConstructors = {}; + nodeTypeToId = {}; +} + +function getTypeId(type) { + if (nodeTypeToId.hasOwnProperty(type)) { + return nodeTypeToId[type]; + } else { + return null; + } +} + +function enableNodeSet(typeOrId) { + if (!settings.available()) { + throw new Error("Settings unavailable"); + } + + var id = typeOrId; + if (nodeTypeToId.hasOwnProperty(typeOrId)) { + id = nodeTypeToId[typeOrId]; + } + var config; + try { + config = moduleConfigs[getModule(id)].nodes[getNode(id)]; + delete config.err; + config.enabled = true; + nodeConfigCache = {}; + settings.enableNodeSettings(config.types); + return saveNodeList().then(function() { + return filterNodeInfo(config); + }); + } catch (err) { + throw new Error("Unrecognised id: "+typeOrId); + } +} + +function disableNodeSet(typeOrId) { + if (!settings.available()) { + throw new Error("Settings unavailable"); + } + var id = typeOrId; + if (nodeTypeToId.hasOwnProperty(typeOrId)) { + id = nodeTypeToId[typeOrId]; + } + var config; + try { + config = moduleConfigs[getModule(id)].nodes[getNode(id)]; + // TODO: persist setting + config.enabled = false; + nodeConfigCache = {}; + settings.disableNodeSettings(config.types); + return saveNodeList().then(function() { + return filterNodeInfo(config); + }); + } catch (err) { + throw new Error("Unrecognised id: "+id); + } +} + +function cleanModuleList() { + var removed = false; + for (var mod in moduleConfigs) { + /* istanbul ignore else */ + if (moduleConfigs.hasOwnProperty(mod)) { + var nodes = moduleConfigs[mod].nodes; + var node; + if (mod == "node-red") { + // For core nodes, look for nodes that are enabled, !loaded and !errored + for (node in nodes) { + /* istanbul ignore else */ + if (nodes.hasOwnProperty(node)) { + var n = nodes[node]; + if (n.enabled && !n.err && !n.loaded) { + removeNode(mod+"/"+node); + removed = true; + } + } + } + } else { + if (moduleConfigs[mod] && !moduleNodes[mod]) { + // For node modules, look for missing ones + for (node in nodes) { + /* istanbul ignore else */ + if (nodes.hasOwnProperty(node)) { + removeNode(mod+"/"+node); + removed = true; + } + } + delete moduleConfigs[mod]; + } + } + } + } + if (removed) { + saveNodeList(); + } +} +function setModulePendingUpdated(module,version) { + moduleConfigs[module].pending_version = version; + return saveNodeList().then(function() { + return getModuleInfo(module); + }); +} + +var icon_paths = { }; +var iconCache = {}; + +function getNodeIconPath(module,icon) { + if (/\.\./.test(icon)) { + throw new Error(); + } + var iconName = module+"/"+icon; + if (iconCache[iconName]) { + return iconCache[iconName]; + } else { + var paths = icon_paths[module]; + if (paths) { + for (var p=0;p<paths.length;p++) { + var iconPath = path.join(paths[p],icon); + try { + fs.statSync(iconPath); + iconCache[iconName] = iconPath; + return iconPath; + } catch(err) { + // iconPath doesn't exist + } + } + } + if (module !== "node-red") { + return getNodeIconPath("node-red", icon); + } + return null; + } +} + +function getNodeIcons() { + var iconList = {}; + + for (var module in moduleConfigs) { + if (moduleConfigs.hasOwnProperty(module)) { + if (moduleConfigs[module].icons) { + iconList[module] = []; + moduleConfigs[module].icons.forEach(icon=>{ iconList[module] = iconList[module].concat(icon.icons)}) + } + } + } + return iconList; +} + +var registry = module.exports = { + init: init, + load: load, + clear: clear, + + registerNodeConstructor: registerNodeConstructor, + getNodeConstructor: getNodeConstructor, + + + addModule: addModule, + + enableNodeSet: enableNodeSet, + disableNodeSet: disableNodeSet, + + setModulePendingUpdated: setModulePendingUpdated, + removeModule: removeModule, + + getNodeInfo: getNodeInfo, + getFullNodeInfo: getFullNodeInfo, + getNodeList: getNodeList, + getModuleList: getModuleList, + getModuleInfo: getModuleInfo, + + getNodeIconPath: getNodeIconPath, + getNodeIcons: getNodeIcons, + /** + * Gets all of the node template configs + * @return all of the node templates in a single string + */ + getAllNodeConfigs: getAllNodeConfigs, + getNodeConfig: getNodeConfig, + + getTypeId: getTypeId, + + saveNodeList: saveNodeList, + + cleanModuleList: cleanModuleList +}; diff --git a/packages/connector/packages/node_modules/@node-red/registry/lib/util.js b/packages/connector/packages/node_modules/@node-red/registry/lib/util.js new file mode 100644 index 0000000..4e68caf --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/registry/lib/util.js @@ -0,0 +1,113 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var path = require("path"); +var i18n = require("@node-red/util").i18n; +var registry; +var runtime; + +function copyObjectProperties(src,dst,copyList,blockList) { + if (!src) { + return; + } + if (copyList && !blockList) { + copyList.forEach(function(i) { + if (src.hasOwnProperty(i)) { + var propDescriptor = Object.getOwnPropertyDescriptor(src,i); + Object.defineProperty(dst,i,propDescriptor); + } + }); + } else if (!copyList && blockList) { + for (var i in src) { + if (src.hasOwnProperty(i) && blockList.indexOf(i) === -1) { + var propDescriptor = Object.getOwnPropertyDescriptor(src,i); + Object.defineProperty(dst,i,propDescriptor); + } + } + } +} +function requireModule(name) { + var moduleInfo = registry.getModuleInfo(name); + if (moduleInfo && moduleInfo.path) { + var relPath = path.relative(__dirname, moduleInfo.path); + return require(relPath); + } else { + var err = new Error(`Cannot find module '${name}'`); + err.code = "MODULE_NOT_FOUND"; + throw err; + } +} + +function createNodeApi(node) { + var red = { + nodes: {}, + log: {}, + settings: {}, + events: runtime.events, + util: runtime.util, + version: runtime.version, + require: requireModule, + comms: { + publish: function(topic,data,retain) { + runtime.events.emit("comms",{ + topic: topic, + data: data, + retain: retain + }) + } + }, + library: { + register: function(type) { + return runtime.library.register(node.id,type); + } + }, + httpNode: runtime.nodeApp, + httpAdmin: runtime.adminApp, + server: runtime.server + } + copyObjectProperties(runtime.nodes,red.nodes,["createNode","getNode","eachNode","addCredentials","getCredentials","deleteCredentials" ]); + red.nodes.registerType = function(type,constructor,opts) { + runtime.nodes.registerType(node.id,type,constructor,opts); + } + copyObjectProperties(runtime.log,red.log,null,["init"]); + copyObjectProperties(runtime.settings,red.settings,null,["init","load","reset"]); + if (runtime.adminApi) { + red.auth = runtime.adminApi.auth; + } else { + //TODO: runtime.adminApi is always stubbed if not enabled, so this block + // is unused - but may be needed for the unit tests + red.auth = { + needsPermission: function(v) { return function(req,res,next) {next()} } + }; + // TODO: stub out httpAdmin/httpNode/server + } + red["_"] = function() { + var args = Array.prototype.slice.call(arguments, 0); + if (args[0].indexOf(":") === -1) { + args[0] = node.namespace+":"+args[0]; + } + return i18n._.apply(null,args); + } + return red; +} + +module.exports = { + init: function(_runtime) { + runtime = _runtime; + registry = require("@node-red/registry/lib"); + }, + createNodeApi: createNodeApi +} diff --git a/packages/connector/packages/node_modules/@node-red/registry/package.json b/packages/connector/packages/node_modules/@node-red/registry/package.json new file mode 100644 index 0000000..448c468 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/registry/package.json @@ -0,0 +1,24 @@ +{ + "name": "@node-red/registry", + "version": "1.0.4", + "license": "Apache-2.0", + "main": "./lib/index.js", + "repository": { + "type": "git", + "url": "https://github.com/node-red/node-red.git" + }, + "contributors": [ + { + "name": "Nick O'Leary" + }, + { + "name": "Dave Conway-Jones" + } + ], + "dependencies": { + "@node-red/util": "1.0.4", + "semver": "6.3.0", + "uglify-js": "3.8.0", + "when": "3.7.8" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/.npmignore b/packages/connector/packages/node_modules/@node-red/runtime/.npmignore new file mode 100644 index 0000000..99c96b4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/.npmignore @@ -0,0 +1,2 @@ +src +docs diff --git a/packages/connector/packages/node_modules/@node-red/runtime/LICENSE b/packages/connector/packages/node_modules/@node-red/runtime/LICENSE new file mode 100644 index 0000000..fc619bd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/LICENSE @@ -0,0 +1,178 @@ +Copyright JS Foundation and other contributors, http://js.foundation + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/packages/connector/packages/node_modules/@node-red/runtime/README.md b/packages/connector/packages/node_modules/@node-red/runtime/README.md new file mode 100644 index 0000000..60968a4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/README.md @@ -0,0 +1,11 @@ +@node-red/runtime +==================== + +Node-RED runtime module. + +This provides the core flow engine of Node-RED. It is the main entry point for +the runtime. + +### Source + +The main Node-RED modules are maintained as a monorepo on [GitHub](https://github.com/node-red/node-red). diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/api/comms.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/comms.js new file mode 100644 index 0000000..0652a65 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/comms.js @@ -0,0 +1,155 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +/** + * This is the comms subsystem of the runtime. + * @mixin @node-red/runtime_comms + */ + +/** + * A WebSocket connection between the runtime and the editor. + * @typedef CommsConnection + * @type {object} + * @property {string} session - a unique session identifier + * @property {Object} user - the user associated with the connection + * @property {Function} send - publish a message to the connection + */ + + +var runtime; +var retained = {}; +var connections = []; + + +function handleCommsEvent(event) { + publish(event.topic,event.data,event.retain); +} +function handleStatusEvent(event) { + var status = { + text: event.status.text, + fill: event.status.fill, + shape: event.status.shape + }; + publish("status/"+event.id,status,true); +} +function handleRuntimeEvent(event) { + runtime.log.trace("runtime event: "+JSON.stringify(event)); + publish("notification/"+event.id,event.payload||{},event.retain); +} +function handleEventLog(event) { + var type = event.payload.type; + var id = event.id; + if (event.payload.data) { + var data = event.payload.data; + if (data.endsWith('\n')) { + data = data.substring(0,data.length-1); + } + var lines = data.split(/\n/); + lines.forEach(line => { + runtime.log.debug((type?("["+type+"] "):"")+line) + }) + } + publish("event-log/"+event.id,event.payload||{}); +} + +function publish(topic,data,retain) { + if (retain) { + retained[topic] = data; + } else { + delete retained[topic]; + } + connections.forEach(connection => connection.send(topic,data)) +} + + +var api = module.exports = { + init: function(_runtime) { + runtime = _runtime; + connections = []; + retained = {}; + runtime.events.removeListener("node-status",handleStatusEvent); + runtime.events.on("node-status",handleStatusEvent); + runtime.events.removeListener("runtime-event",handleRuntimeEvent); + runtime.events.on("runtime-event",handleRuntimeEvent); + runtime.events.removeListener("comms",handleCommsEvent); + runtime.events.on("comms",handleCommsEvent); + runtime.events.removeListener("event-log",handleEventLog); + runtime.events.on("event-log",handleEventLog); + }, + + /** + * Registers a new comms connection + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {CommsConnection} opts.client - the client connection + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_comms + */ + addConnection: function(opts) { + connections.push(opts.client); + return Promise.resolve(); + }, + + /** + * Unregisters a comms connection + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {CommsConnection} opts.client - the client connection + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_comms + */ + removeConnection: function(opts) { + for (var i=0;i<connections.length;i++) { + if (connections[i] === opts.client) { + connections.splice(i,1); + break; + } + } + return Promise.resolve(); + }, + + /** + * Subscribes a comms connection to a given topic. Currently, all clients get + * automatically subscribed to everything and cannot unsubscribe. Sending a subscribe + * request will trigger retained messages to be sent. + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {CommsConnection} opts.client - the client connection + * @param {String} opts.topic - the topic to subscribe to + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_comms + */ + subscribe: function(opts) { + var re = new RegExp("^"+opts.topic.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$"); + for (var t in retained) { + if (re.test(t)) { + opts.client.send(t,retained[t]); + } + } + return Promise.resolve(); + }, + + /** + * TODO: Unsubscribes a comms connection from a given topic + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {CommsConnection} opts.client - the client connection + * @param {String} opts.topic - the topic to unsubscribe from + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_comms + */ + unsubscribe: function(opts) {} +}; diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/api/context.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/context.js new file mode 100644 index 0000000..f69349a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/context.js @@ -0,0 +1,254 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +/** + * @mixin @node-red/runtime_context + */ + +var runtime; + +var util = require("@node-red/util").util; + +function exportContextStore(scope,ctx, store, result, callback) { + ctx.keys(store,function(err, keys) { + if (err) { + return callback(err); + } + result[store] = {}; + var c = keys.length; + if (c === 0) { + callback(null); + } else { + keys.forEach(function(key) { + ctx.get(key,store,function(err, v) { + if (err) { + return callback(err); + } + if (scope !== 'global' || + store === runtime.nodes.listContextStores().default || + !runtime.settings.hasOwnProperty("functionGlobalContext") || + !runtime.settings.functionGlobalContext.hasOwnProperty(key) || + runtime.settings.functionGlobalContext[key] !== v) { + result[store][key] = util.encodeObject({msg:v}); + } + c--; + if (c === 0) { + callback(null); + } + }); + }); + } + }); +} + + +var api = module.exports = { + init: function(_runtime) { + runtime = _runtime; + }, + /** + * Gets the info of an individual node set + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.scope - the scope of the context + * @param {String} opts.id - the id of the context + * @param {String} opts.store - the context store + * @param {String} opts.key - the context key + * @param {Object} opts.req - the request to log (optional) + * @return {Promise} - the node information + * @memberof @node-red/runtime_context + */ + getValue: function(opts) { + return new Promise(function(resolve,reject) { + var scope = opts.scope; + var id = opts.id; + var store = opts.store; + var key = opts.key; + + var availableStores = runtime.nodes.listContextStores(); + //{ default: 'default', stores: [ 'default', 'file' ] } + if (store && availableStores.stores.indexOf(store) === -1) { + runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"not_found"}, opts.req); + var err = new Error(); + err.code = "not_found"; + err.status = 404; + return reject(err); + } + var ctx; + if (scope === 'global') { + ctx = runtime.nodes.getContext('global'); + } else if (scope === 'flow') { + ctx = runtime.nodes.getContext(id); + } else if (scope === 'node') { + var node = runtime.nodes.getNode(id); + if (node) { + ctx = node.context(); + } + } + if (ctx) { + if (key) { + store = store || availableStores.default; + ctx.get(key,store,function(err, v) { + var encoded = util.encodeObject({msg:v}); + if (store !== availableStores.default) { + encoded.store = store; + } + runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key}, opts.req); + resolve(encoded); + }); + return; + } else { + var stores; + if (!store) { + stores = availableStores.stores; + } else { + stores = [store]; + } + + var result = {}; + var c = stores.length; + var errorReported = false; + stores.forEach(function(store) { + exportContextStore(scope,ctx,store,result,function(err) { + if (err) { + // TODO: proper error reporting + if (!errorReported) { + errorReported = true; + runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"unexpected_error"}, opts.req); + var err = new Error(); + err.code = "unexpected_error"; + err.status = 400; + return reject(err); + } + + return; + } + c--; + if (c === 0) { + if (!errorReported) { + runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key},opts.req); + resolve(result); + } + } + }); + }) + } + } else { + runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key},opts.req); + resolve({}); + } + }) + }, + + /** + * Gets the info of an individual node set + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.scope - the scope of the context + * @param {String} opts.id - the id of the context + * @param {String} opts.store - the context store + * @param {String} opts.key - the context key + * @param {Object} opts.req - the request to log (optional) + * @return {Promise} - the node information + * @memberof @node-red/runtime_context + */ + delete: function(opts) { + return new Promise(function(resolve,reject) { + var scope = opts.scope; + var id = opts.id; + var store = opts.store; + var key = opts.key; + + var availableStores = runtime.nodes.listContextStores(); + //{ default: 'default', stores: [ 'default', 'file' ] } + if (store && availableStores.stores.indexOf(store) === -1) { + runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"not_found"},opts.req); + var err = new Error(); + err.code = "not_found"; + err.status = 404; + return reject(err); + } + var ctx; + if (scope === 'global') { + ctx = runtime.nodes.getContext('global'); + } else if (scope === 'flow') { + ctx = runtime.nodes.getContext(id); + } else if (scope === 'node') { + var node = runtime.nodes.getNode(id); + if (node) { + ctx = node.context(); + } + } + if (ctx) { + if (key) { + store = store || availableStores.default; + ctx.set(key,undefined,store,function(err) { + runtime.log.audit({event: "context.delete",scope:scope,id:id,store:store,key:key},opts.req); + resolve(); + }); + return; + } else { + // TODO: support deleting whole context + runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"not_found"},opts.req); + var err = new Error(); + err.code = "not_found"; + err.status = 404; + return reject(err); + // var stores; + // if (!store) { + // stores = availableStores.stores; + // } else { + // stores = [store]; + // } + // + // var result = {}; + // var c = stores.length; + // var errorReported = false; + // stores.forEach(function(store) { + // exportContextStore(scope,ctx,store,result,function(err) { + // if (err) { + // // TODO: proper error reporting + // if (!errorReported) { + // errorReported = true; + // runtime.log.audit({event: "context.delete",scope:scope,id:id,store:store,key:key,error:"unexpected_error"}); + // var err = new Error(); + // err.code = "unexpected_error"; + // err.status = 400; + // return reject(err); + // } + // + // return; + // } + // c--; + // if (c === 0) { + // if (!errorReported) { + // runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key}); + // resolve(result); + // } + // } + // }); + // }) + } + } else { + runtime.log.audit({event: "context.delete",scope:scope,id:id,store:store,key:key},opts.req); + resolve(); + } + + + }); + } + +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/api/flows.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/flows.js new file mode 100644 index 0000000..e585311 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/flows.js @@ -0,0 +1,260 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + /** + * @mixin @node-red/runtime_flows + */ + +/** + * @typedef Flows + * @type {object} + * @property {string} rev - the flow revision identifier + * @property {Array} flows - the flow configuration, an array of node configuration objects + */ + +/** + * @typedef Flow + * @type {object} + * @property {string} id - the flow identifier + * @property {string} label - a label for the flow + * @property {Array} nodes - an array of node configuration objects + */ + +var runtime; + +var api = module.exports = { + init: function(_runtime) { + runtime = _runtime; + }, + /** + * Gets the current flow configuration + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Flows>} - the active flow configuration + * @memberof @node-red/runtime_flows + */ + getFlows: function(opts) { + return new Promise(function(resolve,reject) { + runtime.log.audit({event: "flows.get"}, opts.req); + return resolve(runtime.nodes.getFlows()); + }); + }, + /** + * Sets the current flow configuration + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {Object} opts.flows - the flow configuration: `{flows: [..], credentials: {}}` + * @param {Object} opts.deploymentType - the type of deployment - "full", "nodes", "flows", "reload" + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Flows>} - the active flow configuration + * @memberof @node-red/runtime_flows + */ + setFlows: function(opts) { + return new Promise(function(resolve,reject) { + + var flows = opts.flows; + var deploymentType = opts.deploymentType||"full"; + runtime.log.audit({event: "flows.set",type:deploymentType}, opts.req); + + var apiPromise; + if (deploymentType === 'reload') { + apiPromise = runtime.nodes.loadFlows(true); + } else { + if (flows.hasOwnProperty('rev')) { + var currentVersion = runtime.nodes.getFlows().rev; + if (currentVersion !== flows.rev) { + var err; + err = new Error(); + err.code = "version_mismatch"; + err.status = 409; + //TODO: log warning + return reject(err); + } + } + apiPromise = runtime.nodes.setFlows(flows.flows,flows.credentials,deploymentType); + } + apiPromise.then(function(flowId) { + return resolve({rev:flowId}); + }).catch(function(err) { + runtime.log.warn(runtime.log._("api.flows.error-"+(deploymentType === 'reload'?'reload':'save'),{message:err.message})); + runtime.log.warn(err.stack); + return reject(err); + }); + }); + }, + + /** + * Adds a flow configuration + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {Object} opts.flow - the flow to add + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<String>} - the id of the added flow + * @memberof @node-red/runtime_flows + */ + addFlow: function(opts) { + return new Promise(function(resolve,reject) { + var flow = opts.flow; + runtime.nodes.addFlow(flow).then(function(id) { + runtime.log.audit({event: "flow.add",id:id}, opts.req); + return resolve(id); + }).catch(function(err) { + runtime.log.audit({event: "flow.add",error:err.code||"unexpected_error",message:err.toString()}, opts.req); + err.status = 400; + return reject(err); + }) + }) + + + }, + + /** + * Gets an individual flow configuration + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {Object} opts.id - the id of the flow to retrieve + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Flow>} - the active flow configuration + * @memberof @node-red/runtime_flows + */ + getFlow: function(opts) { + return new Promise(function (resolve,reject) { + var flow = runtime.nodes.getFlow(opts.id); + if (flow) { + runtime.log.audit({event: "flow.get",id:opts.id}, opts.req); + return resolve(flow); + } else { + runtime.log.audit({event: "flow.get",id:opts.id,error:"not_found"}, opts.req); + var err = new Error(); + err.code = "not_found"; + err.status = 404; + return reject(err); + } + }) + + }, + /** + * Updates an existing flow configuration + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {Object} opts.id - the id of the flow to update + * @param {Object} opts.flow - the flow configuration + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<String>} - the id of the updated flow + * @memberof @node-red/runtime_flows + */ + updateFlow: function(opts) { + return new Promise(function (resolve,reject) { + var flow = opts.flow; + var id = opts.id; + try { + runtime.nodes.updateFlow(id,flow).then(function() { + runtime.log.audit({event: "flow.update",id:id}, opts.req); + return resolve(id); + }).catch(function(err) { + runtime.log.audit({event: "flow.update",error:err.code||"unexpected_error",message:err.toString()}, opts.req); + err.status = 400; + return reject(err); + }) + } catch(err) { + if (err.code === 404) { + runtime.log.audit({event: "flow.update",id:id,error:"not_found"}, opts.req); + // TODO: this swap around of .code and .status isn't ideal + err.status = 404; + err.code = "not_found"; + return reject(err); + } else { + runtime.log.audit({event: "flow.update",error:err.code||"unexpected_error",message:err.toString()}, opts.req); + err.status = 400; + return reject(err); + } + } + }); + + }, + /** + * Deletes a flow + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {Object} opts.id - the id of the flow to delete + * @param {Object} opts.req - the request to log (optional) + * @return {Promise} - resolves if successful + * @memberof @node-red/runtime_flows + */ + deleteFlow: function(opts) { + return new Promise(function (resolve,reject) { + var id = opts.id; + try { + runtime.nodes.removeFlow(id).then(function() { + runtime.log.audit({event: "flow.remove",id:id}, opts.req); + return resolve(); + }).catch(function(err) { + runtime.log.audit({event: "flow.remove",id:id,error:err.code||"unexpected_error",message:err.toString()}, opts.req); + err.status = 400; + return reject(err); + }); + } catch(err) { + if (err.code === 404) { + runtime.log.audit({event: "flow.remove",id:id,error:"not_found"}, opts.req); + // TODO: this swap around of .code and .status isn't ideal + err.status = 404; + err.code = "not_found"; + return reject(err); + } else { + runtime.log.audit({event: "flow.remove",id:id,error:err.code||"unexpected_error",message:err.toString()}, opts.req); + err.status = 400; + return reject(err); + } + } + }); + }, + + /** + * Gets the safe credentials for a node + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.type - the node type to return the credential information for + * @param {String} opts.id - the node id + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - the safe credentials + * @memberof @node-red/runtime_flows + */ + getNodeCredentials: function(opts) { + return new Promise(function(resolve,reject) { + runtime.log.audit({event: "credentials.get",type:opts.type,id:opts.id}, opts.req); + var credentials = runtime.nodes.getCredentials(opts.id); + if (!credentials) { + return resolve({}); + } + var definition = runtime.nodes.getCredentialDefinition(opts.type) || {}; + + var sendCredentials = {}; + for (var cred in definition) { + if (definition.hasOwnProperty(cred)) { + if (definition[cred].type == "password") { + var key = 'has_' + cred; + sendCredentials[key] = credentials[cred] != null && credentials[cred] !== ''; + continue; + } + sendCredentials[cred] = credentials[cred] || ''; + } + } + resolve(sendCredentials); + }) + } + +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/api/index.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/index.js new file mode 100644 index 0000000..8856ac3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/index.js @@ -0,0 +1,47 @@ +/*! + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + + +var runtime; + +var api = module.exports = { + init: function(_runtime) { + runtime = _runtime; + api.comms.init(runtime); + api.flows.init(runtime); + api.nodes.init(runtime); + api.settings.init(runtime); + api.library.init(runtime); + api.projects.init(runtime); + api.context.init(runtime); + }, + + comms: require("./comms"), + flows: require("./flows"), + library: require("./library"), + nodes: require("./nodes"), + settings: require("./settings"), + projects: require("./projects"), + context: require("./context"), + + isStarted: function(opts) { + return Promise.resolve(runtime.isStarted()); + }, + version: function(opts) { + return Promise.resolve(runtime.version()); + } +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/api/library.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/library.js new file mode 100644 index 0000000..f252d32 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/library.js @@ -0,0 +1,99 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +/** + * @mixin @node-red/runtime_library + */ + +var runtime; + +var api = module.exports = { + init: function(_runtime) { + runtime = _runtime; + }, + + /** + * Gets an entry from the library. + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.library - the library + * @param {String} opts.type - the type of entry + * @param {String} opts.path - the path of the entry + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<String|Object>} - resolves when complete + * @memberof @node-red/runtime_library + */ + getEntry: function(opts) { + return new Promise(function(resolve,reject) { + runtime.library.getEntry(opts.library,opts.type,opts.path).then(function(result) { + runtime.log.audit({event: "library.get",library:opts.library,type:opts.type,path:opts.path}, opts.req); + return resolve(result); + }).catch(function(err) { + if (err) { + runtime.log.warn(runtime.log._("api.library.error-load-entry",{library:opts.library,type:opts.type,path:opts.path,message:err.toString()})); + if (err.code === 'forbidden') { + err.status = 403; + return reject(err); + } else if (err.code === "not_found") { + err.status = 404; + } else { + err.status = 400; + } + runtime.log.audit({event: "library.get",library:opts.library,type:opts.type,path:opts.path,error:err.code}, opts.req); + return reject(err); + } + runtime.log.audit({event: "library.get",library:opts.library,type:opts.type,error:"not_found"}, opts.req); + var error = new Error(); + error.code = "not_found"; + error.status = 404; + return reject(error); + }); + }) + }, + + /** + * Saves an entry to the library + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.library - the library + * @param {String} opts.type - the type of entry + * @param {String} opts.path - the path of the entry + * @param {Object} opts.meta - any meta data associated with the entry + * @param {String} opts.body - the body of the entry + * @param {Object} opts.req - the request to log (optional) + * @return {Promise} - resolves when complete + * @memberof @node-red/runtime_library + */ + saveEntry: function(opts) { + return new Promise(function(resolve,reject) { + runtime.library.saveEntry(opts.library,opts.type,opts.path,opts.meta,opts.body).then(function() { + runtime.log.audit({event: "library.set",type:opts.type,path:opts.path}, opts.req); + return resolve(); + }).catch(function(err) { + runtime.log.warn(runtime.log._("api.library.error-save-entry",{path:opts.path,message:err.toString()})); + if (err.code === 'forbidden') { + runtime.log.audit({event: "library.set",type:opts.type,path:opts.path,error:"forbidden"}, opts.req); + err.status = 403; + return reject(err); + } + runtime.log.audit({event: "library.set",type:opts.type,path:opts.path,error:"unexpected_error",message:err.toString()}, opts.req); + var error = new Error(); + error.status = 400; + return reject(error); + }); + }) + } +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/api/nodes.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/nodes.js new file mode 100644 index 0000000..ee4d3bc --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/nodes.js @@ -0,0 +1,448 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +/** + * @mixin @node-red/runtime_nodes + */ + +var fs = require("fs"); + +var runtime; + +function putNode(node, enabled) { + var info; + var promise; + if (!node.err && node.enabled === enabled) { + promise = Promise.resolve(node); + } else { + if (enabled) { + promise = runtime.nodes.enableNode(node.id); + } else { + promise = runtime.nodes.disableNode(node.id); + } + } + return promise; +} + +var api = module.exports = { + init: function(_runtime) { + runtime = _runtime; + }, + + + /** + * Gets the info of an individual node set + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the node set to return + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<NodeInfo>} - the node information + * @memberof @node-red/runtime_nodes + */ + getNodeInfo: function(opts) { + return new Promise(function(resolve,reject) { + var id = opts.id; + var result = runtime.nodes.getNodeInfo(id); + if (result) { + runtime.log.audit({event: "nodes.info.get",id:id}, opts.req); + delete result.loaded; + return resolve(result); + } else { + runtime.log.audit({event: "nodes.info.get",id:id,error:"not_found"}, opts.req); + var err = new Error(); + err.code = "not_found"; + err.status = 404; + return reject(err); + } + }) + }, + + /** + * Gets the list of node modules installed in the runtime + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<NodeList>} - the list of node modules + * @memberof @node-red/runtime_nodes + */ + getNodeList: function(opts) { + return new Promise(function(resolve,reject) { + runtime.log.audit({event: "nodes.list.get"}, opts.req); + return resolve(runtime.nodes.getNodeList()); + }) + }, + + /** + * Gets an individual node's html content + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the node set to return + * @param {String} opts.lang - the locale language to return + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<String>} - the node html content + * @memberof @node-red/runtime_nodes + */ + getNodeConfig: function(opts) { + return new Promise(function(resolve,reject) { + var id = opts.id; + var lang = opts.lang; + var result = runtime.nodes.getNodeConfig(id,lang); + if (result) { + runtime.log.audit({event: "nodes.config.get",id:id}, opts.req); + return resolve(result); + } else { + runtime.log.audit({event: "nodes.config.get",id:id,error:"not_found"}, opts.req); + var err = new Error(); + err.code = "not_found"; + err.status = 404; + return reject(err); + } + }); + }, + /** + * Gets all node html content + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.lang - the locale language to return + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<String>} - the node html content + * @memberof @node-red/runtime_nodes + */ + getNodeConfigs: function(opts) { + return new Promise(function(resolve,reject) { + runtime.log.audit({event: "nodes.configs.get"}, opts.req); + return resolve(runtime.nodes.getNodeConfigs(opts.lang)); + }); + }, + + /** + * Gets the info of a node module + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.module - the id of the module to return + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<ModuleInfo>} - the node module info + * @memberof @node-red/runtime_nodes + */ + getModuleInfo: function(opts) { + return new Promise(function(resolve,reject) { + var result = runtime.nodes.getModuleInfo(opts.module); + if (result) { + runtime.log.audit({event: "nodes.module.get",id:opts.module}, opts.req); + return resolve(result); + } else { + runtime.log.audit({event: "nodes.module.get",id:opts.module,error:"not_found"}, opts.req); + var err = new Error(); + err.code = "not_found"; + err.status = 404; + return reject(err); + } + }) + }, + + /** + * Install a new module into the runtime + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.module - the id of the module to install + * @param {String} opts.version - (optional) the version of the module to install + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<ModuleInfo>} - the node module info + * @memberof @node-red/runtime_nodes + */ + addModule: function(opts) { + return new Promise(function(resolve,reject) { + if (!runtime.settings.available()) { + runtime.log.audit({event: "nodes.install",error:"settings_unavailable"}, opts.req); + var err = new Error("Settings unavailable"); + err.code = "settings_unavailable"; + err.status = 400; + return reject(err); + } + if (opts.module) { + var existingModule = runtime.nodes.getModuleInfo(opts.module); + if (existingModule) { + if (!opts.version || existingModule.version === opts.version) { + runtime.log.audit({event: "nodes.install",module:opts.module, version:opts.version, error:"module_already_loaded"}, opts.req); + var err = new Error("Module already loaded"); + err.code = "module_already_loaded"; + err.status = 400; + return reject(err); + } + } + runtime.nodes.installModule(opts.module,opts.version).then(function(info) { + runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version}, opts.req); + return resolve(info); + }).catch(function(err) { + if (err.code === 404) { + runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:"not_found"}, opts.req); + // TODO: code/status + err.status = 404; + } else if (err.code) { + err.status = 400; + runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:err.code}, opts.req); + } else { + err.status = 400; + runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:err.code||"unexpected_error",message:err.toString()}, opts.req); + } + return reject(err); + }) + } else { + runtime.log.audit({event: "nodes.install",module:opts.module,error:"invalid_request"}, opts.req); + var err = new Error("Invalid request"); + err.code = "invalid_request"; + err.status = 400; + return reject(err); + } + + }); + }, + /** + * Removes a module from the runtime + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.module - the id of the module to remove + * @param {Object} opts.req - the request to log (optional) + * @return {Promise} - resolves when complete + * @memberof @node-red/runtime_nodes + */ + removeModule: function(opts) { + return new Promise(function(resolve,reject) { + if (!runtime.settings.available()) { + runtime.log.audit({event: "nodes.install",error:"settings_unavailable"}, opts.req); + var err = new Error("Settings unavailable"); + err.code = "settings_unavailable"; + err.status = 400; + return reject(err); + } + var module = runtime.nodes.getModuleInfo(opts.module); + if (!module) { + runtime.log.audit({event: "nodes.remove",module:opts.module,error:"not_found"}, opts.req); + var err = new Error(); + err.code = "not_found"; + err.status = 404; + return reject(err); + } + try { + runtime.nodes.uninstallModule(opts.module).then(function() { + runtime.log.audit({event: "nodes.remove",module:opts.module}, opts.req); + resolve(); + }).catch(function(err) { + err.status = 400; + runtime.log.audit({event: "nodes.remove",module:opts.module,error:err.code||"unexpected_error",message:err.toString()}, opts.req); + return reject(err); + }) + } catch(error) { + runtime.log.audit({event: "nodes.remove",module:opts.module,error:error.code||"unexpected_error",message:error.toString()}, opts.req); + error.status = 400; + return reject(error); + } + }); + }, + + /** + * Enables or disables a module in the runtime + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.module - the id of the module to enable or disable + * @param {String} opts.enabled - whether the module should be enabled or disabled + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<ModuleInfo>} - the module info object + * @memberof @node-red/runtime_nodes + */ + setModuleState: function(opts) { + var mod = opts.module; + return new Promise(function(resolve,reject) { + if (!runtime.settings.available()) { + runtime.log.audit({event: "nodes.module.set",error:"settings_unavailable"}, opts.req); + var err = new Error("Settings unavailable"); + err.code = "settings_unavailable"; + err.status = 400; + return reject(err); + } + try { + var module = runtime.nodes.getModuleInfo(mod); + if (!module) { + runtime.log.audit({event: "nodes.module.set",module:mod,error:"not_found"}, opts.req); + var err = new Error(); + err.code = "not_found"; + err.status = 404; + return reject(err); + } + + var nodes = module.nodes; + var promises = []; + for (var i = 0; i < nodes.length; ++i) { + promises.push(putNode(nodes[i],opts.enabled)); + } + Promise.all(promises).then(function() { + return resolve(runtime.nodes.getModuleInfo(mod)); + }).catch(function(err) { + err.status = 400; + return reject(err); + }); + } catch(error) { + runtime.log.audit({event: "nodes.module.set",module:mod,enabled:opts.enabled,error:error.code||"unexpected_error",message:error.toString()}, opts.req); + error.status = 400; + return reject(error); + } + }); + }, + + /** + * Enables or disables a n individual node-set in the runtime + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the node-set to enable or disable + * @param {String} opts.enabled - whether the module should be enabled or disabled + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<ModuleInfo>} - the module info object + * @memberof @node-red/runtime_nodes + */ + setNodeSetState: function(opts) { + return new Promise(function(resolve,reject) { + if (!runtime.settings.available()) { + runtime.log.audit({event: "nodes.info.set",error:"settings_unavailable"}, opts.req); + var err = new Error("Settings unavailable"); + err.code = "settings_unavailable"; + err.status = 400; + return reject(err); + } + + var id = opts.id; + var enabled = opts.enabled; + try { + var node = runtime.nodes.getNodeInfo(id); + if (!node) { + runtime.log.audit({event: "nodes.info.set",id:id,error:"not_found"}, opts.req); + var err = new Error(); + err.code = "not_found"; + err.status = 404; + return reject(err); + } else { + delete node.loaded; + putNode(node,enabled).then(function(result) { + runtime.log.audit({event: "nodes.info.set",id:id,enabled:enabled}, opts.req); + return resolve(result); + }).catch(function(err) { + runtime.log.audit({event: "nodes.info.set",id:id,enabled:enabled,error:err.code||"unexpected_error",message:err.toString()}, opts.req); + err.status = 400; + return reject(err); + }); + } + } catch(error) { + runtime.log.audit({event: "nodes.info.set",id:id,enabled:enabled,error:error.code||"unexpected_error",message:error.toString()}, opts.req); + error.status = 400; + return reject(error); + } + }); + }, + + /** + * Gets all registered module message catalogs + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {User} opts.lang - the i18n language to return. If not set, uses runtime default (en-US) + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - the message catalogs + * @memberof @node-red/runtime_nodes + */ + getModuleCatalogs: function(opts) { + return new Promise(function(resolve,reject) { + var namespace = opts.module; + var lang = opts.lang; + var prevLang = runtime.i18n.i.language; + // Trigger a load from disk of the language if it is not the default + runtime.i18n.i.changeLanguage(lang, function(){ + var nodeList = runtime.nodes.getNodeList(); + var result = {}; + nodeList.forEach(function(n) { + if (n.module !== "node-red") { + result[n.id] = runtime.i18n.i.getResourceBundle(lang, n.id)||{}; + } + }); + resolve(result); + }); + runtime.i18n.i.changeLanguage(prevLang); + }); + }, + + /** + * Gets a modules message catalog + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {User} opts.module - the module + * @param {User} opts.lang - the i18n language to return. If not set, uses runtime default (en-US) + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - the message catalog + * @memberof @node-red/runtime_nodes + */ + getModuleCatalog: function(opts) { + return new Promise(function(resolve,reject) { + var namespace = opts.module; + var lang = opts.lang; + var prevLang = runtime.i18n.i.language; + // Trigger a load from disk of the language if it is not the default + runtime.i18n.i.changeLanguage(lang, function(){ + var catalog = runtime.i18n.i.getResourceBundle(lang, namespace); + resolve(catalog||{}); + }); + runtime.i18n.i.changeLanguage(prevLang); + }); + }, + + /** + * Gets the list of all icons available in the modules installed within the runtime + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<IconList>} - the list of all icons + * @memberof @node-red/runtime_nodes + */ + getIconList: function(opts) { + return new Promise(function(resolve,reject) { + runtime.log.audit({event: "nodes.icons.get"}, opts.req); + return resolve(runtime.nodes.getNodeIcons()); + }); + + }, + /** + * Gets a node icon + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.module - the id of the module requesting the icon + * @param {String} opts.icon - the name of the icon + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Buffer>} - the icon file as a Buffer or null if no icon available + * @memberof @node-red/runtime_nodes + */ + getIcon: function(opts) { + return new Promise(function(resolve,reject) { + var iconPath = runtime.nodes.getNodeIconPath(opts.module,opts.icon); + if (iconPath) { + fs.readFile(iconPath,function(err,data) { + if (err) { + err.status = 400; + return reject(err); + } + return resolve(data) + }); + } else { + resolve(null); + } + }); + } +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/api/projects.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/projects.js new file mode 100644 index 0000000..d792f37 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/projects.js @@ -0,0 +1,491 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +/** + * @mixin @node-red/runtime_projects + */ + +var runtime; + +var api = module.exports = { + init: function(_runtime) { + runtime = _runtime; + }, + available: function(opts) { + return Promise.resolve(!!runtime.storage.projects); + }, + /** + * List projects known to the runtime + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + listProjects: function(opts) { + return runtime.storage.projects.listProjects(opts.user).then(function(list) { + var active = runtime.storage.projects.getActiveProject(opts.user); + var response = { + projects: list + }; + if (active) { + response.active = active.name; + } + return response; + }).catch(function(err) { + err.status = 400; + throw err; + }) + }, + + /** + * Create a new project + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {Object} opts.project - the project information + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + createProject: function(opts) { + runtime.log.audit({event: "projects.create",name:opts.project?opts.project.name:"missing-name"}, opts.req); + return runtime.storage.projects.createProject(opts.user, opts.project) + }, + + /** + * Initialises an empty project + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project to initialise + * @param {Object} opts.project - the project information + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + initialiseProject: function(opts) { + // Initialised set when creating default files for an empty repo + runtime.log.audit({event: "projects.initialise",id:opts.id}, opts.req); + return runtime.storage.projects.initialiseProject(opts.user, opts.id, opts.project) + }, + + /** + * Gets the active project + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - the active project + * @memberof @node-red/runtime_projects + */ + getActiveProject: function(opts) { + return Promise.resolve(runtime.storage.projects.getActiveProject(opts.user)); + }, + + /** + * + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project to activate + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + setActiveProject: function(opts) { + var currentProject = runtime.storage.projects.getActiveProject(opts.user); + runtime.log.audit({event: "projects.set",id:opts.id}, opts.req); + if (!currentProject || opts.id !== currentProject.name) { + return runtime.storage.projects.setActiveProject(opts.user, opts.id); + } else { + return Promise.resolve(); + } + }, + + /** + * Gets a projects metadata + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project to get + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - the project metadata + * @memberof @node-red/runtime_projects + */ + getProject: function(opts) { + return runtime.storage.projects.getProject(opts.user, opts.id) + }, + + /** + * Updates the metadata of an existing project + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project to update + * @param {Object} opts.project - the project information + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + updateProject: function(opts) { + runtime.log.audit({event: "projects.update",id:opts.id}, opts.req); + return runtime.storage.projects.updateProject(opts.user, opts.id, opts.project); + }, + + /** + * Deletes a project + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project to update + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + deleteProject: function(opts) { + runtime.log.audit({event: "projects.delete",id:opts.id}, opts.req); + return runtime.storage.projects.deleteProject(opts.user, opts.id); + }, + + /** + * Gets current git status of a project + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {Boolean} opts.remote - whether to include status of remote repos + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - the project status + * @memberof @node-red/runtime_projects + */ + getStatus: function(opts) { + return runtime.storage.projects.getStatus(opts.user, opts.id, opts.remote) + }, + + /** + * Get a list of local branches + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {Boolean} opts.remote - whether to return remote branches (true) or local (false) + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - a list of the local branches + * @memberof @node-red/runtime_projects + */ + getBranches: function(opts) { + return runtime.storage.projects.getBranches(opts.user, opts.id, opts.remote); + }, + + /** + * Gets the status of a branch + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {String} opts.branch - the name of the branch + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - the status of the branch + * @memberof @node-red/runtime_projects + */ + getBranchStatus: function(opts) { + return runtime.storage.projects.getBranchStatus(opts.user, opts.id, opts.branch); + }, + + /** + * Sets the current local branch + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {String} opts.branch - the name of the branch + * @param {Boolean} opts.create - whether to create the branch if it doesn't exist + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + setBranch: function(opts) { + runtime.log.audit({event: "projects.branch.set",id:opts.id, branch: opts.branch, create:opts.create}, opts.req); + return runtime.storage.projects.setBranch(opts.user, opts.id, opts.branch, opts.create) + }, + + /** + * Deletes a branch + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {String} opts.branch - the name of the branch + * @param {Boolean} opts.force - whether to force delete + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + deleteBranch: function(opts) { + runtime.log.audit({event: "projects.branch.delete",id:opts.id, branch: opts.branch, force:opts.force}, opts.req); + return runtime.storage.projects.deleteBranch(opts.user, opts.id, opts.branch, false, opts.force); + }, + + /** + * Commits the current staged files + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {String} opts.message - the message to associate with the commit + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + commit: function(opts) { + runtime.log.audit({event: "projects.commit",id:opts.id}, opts.req); + return runtime.storage.projects.commit(opts.user, opts.id,{message: opts.message}); + }, + + /** + * Gets the details of a single commit + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {String} opts.sha - the sha of the commit to return + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - the commit details + * @memberof @node-red/runtime_projects + */ + getCommit: function(opts) { + return runtime.storage.projects.getCommit(opts.user, opts.id, opts.sha); + }, + + /** + * Gets the commit history of the project + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {String} opts.limit - limit how many to return + * @param {String} opts.before - id of the commit to work back from + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Array>} - an array of commits + * @memberof @node-red/runtime_projects + */ + getCommits: function(opts) { + return runtime.storage.projects.getCommits(opts.user, opts.id, { + limit: opts.limit || 20, + before: opts.before + }); + }, + + /** + * Abort an in-progress merge + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + abortMerge: function(opts) { + runtime.log.audit({event: "projects.merge.abort",id:opts.id}, opts.req); + return runtime.storage.projects.abortMerge(opts.user, opts.id); + }, + + /** + * Resolves a merge conflict + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {String} opts.path - the path of the file being merged + * @param {String} opts.resolutions - how to resolve the merge conflict + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + resolveMerge: function(opts) { + runtime.log.audit({event: "projects.merge.resolve",id:opts.id, file:opts.path}, opts.req); + return runtime.storage.projects.resolveMerge(opts.user, opts.id, opts.path, opts.resolution); + }, + + /** + * Gets a listing of the files in the project + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - the file listing + * @memberof @node-red/runtime_projects + */ + getFiles: function(opts) { + return runtime.storage.projects.getFiles(opts.user, opts.id); + }, + + /** + * Gets the contents of a file + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {String} opts.path - the path of the file + * @param {String} opts.tree - the version control tree to use + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<String>} - the content of the file + * @memberof @node-red/runtime_projects + */ + getFile: function(opts) { + return runtime.storage.projects.getFile(opts.user, opts.id,opts.path,opts.tree); + }, + + /** + * + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {String|Array} opts.path - the path of the file, or an array of paths + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + stageFile: function(opts) { + runtime.log.audit({event: "projects.file.stage",id:opts.id, file:opts.path}, opts.req); + return runtime.storage.projects.stageFile(opts.user, opts.id, opts.path); + }, + + /** + * + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {String} opts.path - the path of the file. If not set, all staged files are unstaged + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + unstageFile: function(opts) { + runtime.log.audit({event: "projects.file.unstage",id:opts.id, file:opts.path}, opts.req); + return runtime.storage.projects.unstageFile(opts.user, opts.id, opts.path); + }, + + /** + * Reverts changes to a file back to its commited version + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {String} opts.path - the path of the file + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + revertFile: function(opts) { + runtime.log.audit({event: "projects.file.revert",id:opts.id, file:opts.path}, opts.req); + return runtime.storage.projects.revertFile(opts.user, opts.id,opts.path) + }, + + /** + * Get the diff of a file + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {String} opts.path - the path of the file + * @param {String} opts.type - the type of diff + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - the requested diff + * @memberof @node-red/runtime_projects + */ + getFileDiff: function(opts) { + return runtime.storage.projects.getFileDiff(opts.user, opts.id, opts.path, opts.type); + }, + + /** + * Gets a list of the project remotes + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - a list of project remotes + * @memberof @node-red/runtime_projects + */ + getRemotes: function(opts) { + return runtime.storage.projects.getRemotes(opts.user, opts.id); + + }, + + /** + * + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {Object} opts.remote - the remote metadata + * @param {String} opts.remote.name - the name of the remote + * @param {String} opts.remote.url - the url of the remote + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + addRemote: function(opts) { + runtime.log.audit({event: "projects.remote.add",id:opts.id, remote:opts.remote.name}, opts.req); + return runtime.storage.projects.addRemote(opts.user, opts.id, opts.remote) + }, + + /** + * Remove a project remote + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {String} opts.remote - the name of the remote + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + removeRemote: function(opts) { + runtime.log.audit({event: "projects.remote.delete",id:opts.id, remote:opts.remote}, opts.req); + return runtime.storage.projects.removeRemote(opts.user, opts.id, opts.remote); + }, + + /** + * + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {Object} opts.remote - the remote metadata + * @param {String} opts.remote.name - the name of the remote + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + updateRemote: function(opts) { + runtime.log.audit({event: "projects.remote.update",id:opts.id, remote:opts.remote.name}, opts.req); + return runtime.storage.projects.updateRemote(opts.user, opts.id, opts.remote.name, opts.remote) + }, + + /** + * Pull changes from the remote + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.remote - the remote to pull + * @param {Boolean} opts.track - whether to track this remote + * @param {Boolean} opts.allowUnrelatedHistories - + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + pull: function(opts) { + runtime.log.audit({event: "projects.pull",id:opts.id, remote: opts.remote, track:opts.track}, opts.req); + return runtime.storage.projects.pull(opts.user, opts.id, opts.remote, opts.track, opts.allowUnrelatedHistories); + }, + + /** + * Push changes to a remote + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {String} opts.id - the id of the project + * @param {String} opts.remote - the name of the remote + * @param {String} opts.track - whether to set the remote as the upstream + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - resolves when complete + * @memberof @node-red/runtime_projects + */ + push: function(opts) { + runtime.log.audit({event: "projects.push",id:opts.id, remote: opts.remote, track:opts.track}, opts.req); + return runtime.storage.projects.push(opts.user, opts.id, opts.remote, opts.track); + } + +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/api/settings.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/settings.js new file mode 100644 index 0000000..96bb6c9 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/api/settings.js @@ -0,0 +1,274 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +/** + * @mixin @node-red/runtime_settings + */ + +var util = require("util"); +var runtime; + +function extend(target, source) { + var keys = Object.keys(source); + var i = keys.length; + while(i--) { + var value = source[keys[i]] + var type = typeof value; + if (type === 'string' || type === 'number' || type === 'boolean' || Array.isArray(value)) { + target[keys[i]] = value; + } else if (value === null) { + if (target.hasOwnProperty(keys[i])) { + delete target[keys[i]]; + } + } else { + // Object + if (target.hasOwnProperty(keys[i])) { + target[keys[i]] = extend(target[keys[i]],value); + } else { + target[keys[i]] = value; + } + } + } + return target; +} + +function getSSHKeyUsername(userObj) { + var username = '__default'; + if ( userObj && userObj.username ) { + username = userObj.username; + } + return username; +} +var api = module.exports = { + init: function(_runtime) { + runtime = _runtime; + }, + /** + * Gets the runtime settings object + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - the runtime settings + * @memberof @node-red/runtime_settings + */ + getRuntimeSettings: function(opts) { + return new Promise(function(resolve,reject) { + try { + var safeSettings = { + httpNodeRoot: runtime.settings.httpNodeRoot||"/", + version: runtime.settings.version + } + if (opts.user) { + safeSettings.user = {} + var props = ["anonymous","username","image","permissions"]; + props.forEach(prop => { + if (opts.user.hasOwnProperty(prop)) { + safeSettings.user[prop] = opts.user[prop]; + } + }) + } + + safeSettings.context = runtime.nodes.listContextStores(); + + if (util.isArray(runtime.settings.paletteCategories)) { + safeSettings.paletteCategories = runtime.settings.paletteCategories; + } + + if (runtime.settings.flowFilePretty) { + safeSettings.flowFilePretty = runtime.settings.flowFilePretty; + } + + if (!runtime.nodes.paletteEditorEnabled()) { + safeSettings.editorTheme = safeSettings.editorTheme || {}; + safeSettings.editorTheme.palette = safeSettings.editorTheme.palette || {}; + safeSettings.editorTheme.palette.editable = false; + } + if (runtime.storage.projects) { + var activeProject = runtime.storage.projects.getActiveProject(); + if (activeProject) { + safeSettings.project = activeProject; + } else if (runtime.storage.projects.flowFileExists()) { + safeSettings.files = { + flow: runtime.storage.projects.getFlowFilename(), + credentials: runtime.storage.projects.getCredentialsFilename() + } + } + safeSettings.git = { + globalUser: runtime.storage.projects.getGlobalGitUser() + } + } + + safeSettings.flowEncryptionType = runtime.nodes.getCredentialKeyType(); + + runtime.settings.exportNodeSettings(safeSettings); + + resolve(safeSettings); + }catch(err) { + console.log(err); + } + }); + }, + + /** + * Gets an individual user's settings object + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - the user settings + * @memberof @node-red/runtime_settings + */ + getUserSettings: function(opts) { + var username; + if (!opts.user || opts.user.anonymous) { + username = '_'; + } else { + username = opts.user.username; + } + return Promise.resolve(runtime.settings.getUserSettings(username)||{}); + }, + + /** + * Updates an individual user's settings object. + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {Object} opts.settings - the updates to the user settings + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - the user settings + * @memberof @node-red/runtime_settings + */ + updateUserSettings: function(opts) { + var username; + if (!opts.user || opts.user.anonymous) { + username = '_'; + } else { + username = opts.user.username; + } + return new Promise(function(resolve,reject) { + var currentSettings = runtime.settings.getUserSettings(username)||{}; + currentSettings = extend(currentSettings, opts.settings); + try { + runtime.settings.setUserSettings(username, currentSettings).then(function() { + runtime.log.audit({event: "settings.update",username:username}, opts.req); + return resolve(); + }).catch(function(err) { + runtime.log.audit({event: "settings.update",username:username,error:err.code||"unexpected_error",message:err.toString()}, opts.req); + err.status = 400; + return reject(err); + }); + } catch(err) { + runtime.log.warn(runtime.log._("settings.user-not-available",{message:runtime.log._("settings.not-available")})); + runtime.log.audit({event: "settings.update",username:username,error:err.code||"unexpected_error",message:err.toString()}, opts.req); + err.status = 400; + return reject(err); + } + }); + }, + + /** + * Gets a list of a user's ssh keys + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<Object>} - the user's ssh keys + * @memberof @node-red/runtime_settings + */ + getUserKeys: function(opts) { + return new Promise(function(resolve,reject) { + var username = getSSHKeyUsername(opts.user); + runtime.storage.projects.ssh.listSSHKeys(username).then(function(list) { + return resolve(list); + }).catch(function(err) { + err.status = 400; + return reject(err); + }); + }); + }, + + /** + * Gets a user's ssh public key + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {User} opts.id - the id of the key to return + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<String>} - the user's ssh public key + * @memberof @node-red/runtime_settings + */ + getUserKey: function(opts) { + return new Promise(function(resolve,reject) { + var username = getSSHKeyUsername(opts.user); + // console.log('username:', username); + runtime.storage.projects.ssh.getSSHKey(username, opts.id).then(function(data) { + if (data) { + return resolve(data); + } else { + var err = new Error("Key not found"); + err.code = "not_found"; + err.status = 404; + return reject(err); + } + }).catch(function(err) { + err.status = 400; + return reject(err); + }); + }); + }, + + /** + * Generates a new ssh key pair + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {User} opts.name - the id of the key to return + * @param {User} opts.password - (optional) the password for the key pair + * @param {User} opts.comment - (option) a comment to associate with the key pair + * @param {User} opts.size - (optional) the size of the key. Default: 2048 + * @param {Object} opts.req - the request to log (optional) + * @return {Promise<String>} - the id of the generated key + * @memberof @node-red/runtime_settings + */ + generateUserKey: function(opts) { + return new Promise(function(resolve,reject) { + var username = getSSHKeyUsername(opts.user); + runtime.storage.projects.ssh.generateSSHKey(username, opts).then(function(name) { + return resolve(name); + }).catch(function(err) { + err.status = 400; + return reject(err); + }); + }); + }, + + /** + * Deletes a user's ssh key pair + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @param {User} opts.id - the id of the key to delete + * @param {Object} opts.req - the request to log (optional) + * @return {Promise} - resolves when deleted + * @memberof @node-red/runtime_settings + */ + removeUserKey: function(opts) { + return new Promise(function(resolve,reject) { + var username = getSSHKeyUsername(opts.user); + runtime.storage.projects.ssh.deleteSSHKey(username, opts.id).then(function() { + return resolve(); + }).catch(function(err) { + err.status = 400; + return reject(err); + }); + }); + + } +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/events.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/events.js new file mode 100644 index 0000000..ed280a6 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/events.js @@ -0,0 +1,43 @@ +/*! + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var events = require("events"); + +module.exports = new events.EventEmitter(); + +/** + * Runtime events emitter + * @mixin @node-red/runtime_events + */ + +/** + * Register an event listener for a runtime event + * @name on + * @function + * @memberof @node-red/runtime_events + * @param {String} eventName - the name of the event to listen to + * @param {Function} listener - the callback function for the event + */ + + /** + * Emit an event to all of its registered listeners + * @name emit + * @function + * @memberof @node-red/runtime_events + * @param {String} eventName - the name of the event to emit + * @param {any} ...args - the arguments to pass in the event + * @return {Boolean} - whether the event had listeners or not + */ diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/exec.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/exec.js new file mode 100644 index 0000000..0ef3c06 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/exec.js @@ -0,0 +1,69 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +const child_process = require('child_process'); +const { util } = require('@node-red/util'); + +var events; + +function logLines(id,type,data) { + events.emit("event-log", {id:id,payload:{ts: Date.now(),data:data,type:type}}); +} + +module.exports = { + init: function(_runtime) { + events = _runtime.events; + }, + run: function(command,args,options,emit) { + var invocationId = util.generateId(); + + emit && events.emit("event-log", {ts: Date.now(),id:invocationId,payload:{ts: Date.now(),data:command+" "+args.join(" ")}}); + + return new Promise((resolve, reject) => { + let stdout = ""; + let stderr = ""; + const child = child_process.spawn(command,args,options); + child.stdout.on('data', (data) => { + const str = ""+data; + stdout += str; + emit && logLines(invocationId,"out",str); + }); + child.stderr.on('data', (data) => { + const str = ""+data; + stderr += str; + emit && logLines(invocationId,"err",str); + }); + child.on('error', function(err) { + stderr = err.toString(); + emit && logLines(invocationId,"err",stderr); + }) + child.on('close', (code) => { + let result = { + code: code, + stdout: stdout, + stderr: stderr + } + emit && events.emit("event-log", {id:invocationId,payload:{ts: Date.now(),data:"rc="+code}}); + + if (code === 0) { + resolve(result) + } else { + reject(result); + } + }); + }) + } +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/index.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/index.js new file mode 100644 index 0000000..66bff6f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/index.js @@ -0,0 +1,371 @@ +/*! + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require('when'); + +var externalAPI = require("./api"); + +var redNodes = require("./nodes"); +var storage = require("./storage"); +var library = require("./library"); +var events = require("./events"); +var settings = require("./settings"); +var exec = require("./exec"); + +var express = require("express"); +var path = require('path'); +var fs = require("fs"); +var os = require("os"); + +var redUtil = require("@node-red/util"); +var log = redUtil.log; +var i18n = redUtil.i18n; + +var runtimeMetricInterval = null; + +var started = false; + +var stubbedExpressApp = { + get: function() {}, + post: function() {}, + put: function() {}, + delete: function() {} +} +var adminApi = { + auth: { + needsPermission: function() {return function(req,res,next) {next()}} + }, + adminApp: stubbedExpressApp, + server: {} +} + +var nodeApp; +var adminApp; +var server; + + +/** + * Initialise the runtime module. + * @param {Object} settings - the runtime settings object + * @param {HTTPServer} server - the http server instance for the server to use + * @param {AdminAPI} adminApi - an instance of @node-red/editor-api. <B>TODO</B>: This needs to be + * better abstracted. + * @memberof @node-red/runtime + */ +function init(userSettings,httpServer,_adminApi,__util) { + server = httpServer; + userSettings.version = getVersion(); + settings.init(userSettings); + + nodeApp = express(); + adminApp = express(); + + if (_adminApi) { + adminApi = _adminApi; + } + redNodes.init(runtime); + library.init(runtime); + externalAPI.init(runtime); + exec.init(runtime); + if (__util) { + log = __util.log; + i18n = __util.i18n; + } else { + log = redUtil.log; + i18n = redUtil.i18n; + } +} + +var version; + +function getVersion() { + if (!version) { + version = require(path.join(__dirname,"..","package.json")).version; + /* istanbul ignore else */ + try { + fs.statSync(path.join(__dirname,"..","..","..","..",".git")); + version += "-git"; + } catch(err) { + // No git directory + } + } + return version; +} + +/** + * Start the runtime. + * @return {Promise} - resolves when the runtime is started. This does not mean the + * flows will be running as they are started asynchronously. + * @memberof @node-red/runtime + */ +function start() { + return i18n.registerMessageCatalog("runtime",path.resolve(path.join(__dirname,"..","locales")),"runtime.json") + .then(function() { return storage.init(runtime)}) + .then(function() { return settings.load(storage)}) + .then(function() { + + if (log.metric()) { + runtimeMetricInterval = setInterval(function() { + reportMetrics(); + }, settings.runtimeMetricInterval||15000); + } + log.info("\n\n"+log._("runtime.welcome")+"\n===================\n"); + if (settings.version) { + log.info(log._("runtime.version",{component:"Node-RED",version:"v"+settings.version})); + } + log.info(log._("runtime.version",{component:"Node.js ",version:process.version})); + if (settings.UNSUPPORTED_VERSION) { + log.error("*****************************************************************"); + log.error("* "+log._("runtime.unsupported_version",{component:"Node.js",version:process.version,requires: ">=8.9.0"})+" *"); + log.error("*****************************************************************"); + events.emit("runtime-event",{id:"runtime-unsupported-version",payload:{type:"error",text:"notification.errors.unsupportedVersion"},retain:true}); + } + log.info(os.type()+" "+os.release()+" "+os.arch()+" "+os.endianness()); + return redNodes.load().then(function() { + + var i; + var nodeErrors = redNodes.getNodeList(function(n) { return n.err!=null;}); + var nodeMissing = redNodes.getNodeList(function(n) { return n.module && n.enabled && !n.loaded && !n.err;}); + if (nodeErrors.length > 0) { + log.warn("------------------------------------------------------"); + for (i=0;i<nodeErrors.length;i+=1) { + if (nodeErrors[i].err.code === "type_already_registered") { + log.warn("["+nodeErrors[i].id+"] "+log._("server.type-already-registered",{type:nodeErrors[i].err.details.type,module: nodeErrors[i].err.details.moduleA})); + } else { + log.warn("["+nodeErrors[i].id+"] "+nodeErrors[i].err); + } + } + log.warn("------------------------------------------------------"); + } + if (nodeMissing.length > 0) { + log.warn(log._("server.missing-modules")); + var missingModules = {}; + for (i=0;i<nodeMissing.length;i++) { + var missing = nodeMissing[i]; + missingModules[missing.module] = missingModules[missing.module]||{ + module:missing.module, + version:missing.pending_version||missing.version, + types:[] + } + missingModules[missing.module].types = missingModules[missing.module].types.concat(missing.types); + } + var moduleList = []; + var promises = []; + var installingModules = []; + for (i in missingModules) { + if (missingModules.hasOwnProperty(i)) { + log.warn(" - "+i+" ("+missingModules[i].version+"): "+missingModules[i].types.join(", ")); + if (settings.autoInstallModules && i != "node-red") { + installingModules.push({id:i,version:missingModules[i].version}); + } + } + } + if (!settings.autoInstallModules) { + log.info(log._("server.removing-modules")); + redNodes.cleanModuleList(); + } else if (installingModules.length > 0) { + reinstallAttempts = 0; + reinstallModules(installingModules); + } + } + if (settings.settingsFile) { + log.info(log._("runtime.paths.settings",{path:settings.settingsFile})); + } + if (settings.httpStatic) { + log.info(log._("runtime.paths.httpStatic",{path:path.resolve(settings.httpStatic)})); + } + return redNodes.loadContextsPlugin().then(function () { + redNodes.loadFlows().then(redNodes.startFlows).catch(function(err) {}); + started = true; + }); + }); + }); +} + +var reinstallAttempts; +var reinstallTimeout; +function reinstallModules(moduleList) { + var promises = []; + var failedModules = []; + for (var i=0;i<moduleList.length;i++) { + if (settings.autoInstallModules && i != "node-red") { + promises.push(redNodes.installModule(moduleList[i].id,moduleList[i].version)); + } + } + when.settle(promises).then(function(results) { + var reinstallList = []; + for (var i=0;i<results.length;i++) { + if (results[i].state === 'rejected') { + reinstallList.push(moduleList[i]); + } else { + events.emit("runtime-event",{id:"node/added",retain:false,payload:results[i].value.nodes}); + } + } + if (reinstallList.length > 0) { + reinstallAttempts++; + // First 5 at 1x timeout, next 5 at 2x, next 5 at 4x, then 8x + var timeout = (settings.autoInstallModulesRetry||30000) * Math.pow(2,Math.min(Math.floor(reinstallAttempts/5),3)); + reinstallTimeout = setTimeout(function() { + reinstallModules(reinstallList); + },timeout); + } + }); +} + +function reportMetrics() { + var memUsage = process.memoryUsage(); + + log.log({ + level: log.METRIC, + event: "runtime.memory.rss", + value: memUsage.rss + }); + log.log({ + level: log.METRIC, + event: "runtime.memory.heapTotal", + value: memUsage.heapTotal + }); + log.log({ + level: log.METRIC, + event: "runtime.memory.heapUsed", + value: memUsage.heapUsed + }); +} + +/** + * Stops the runtime. + * @return {Promise} - resolves when the runtime is stopped. + * @memberof @node-red/runtime + */ +function stop() { + if (runtimeMetricInterval) { + clearInterval(runtimeMetricInterval); + runtimeMetricInterval = null; + } + if (reinstallTimeout) { + clearTimeout(reinstallTimeout); + } + started = false; + return redNodes.stopFlows().then(function(){ + return redNodes.closeContextsPlugin(); + }); +} + +// This is the internal api +var runtime = { + version: getVersion, + get log() { return log }, + get i18n() { return i18n }, + settings: settings, + storage: storage, + events: events, + nodes: redNodes, + library: library, + exec: exec, + util: require("@node-red/util").util, + get adminApi() { return adminApi }, + get adminApp() { return adminApp }, + get nodeApp() { return nodeApp }, + get server() { return server }, + isStarted: function() { + return started; + } +}; + +/** + * This module provides the core runtime component of Node-RED. + * It does *not* include the Node-RED editor. All interaction with + * this module is done using the api provided. + * + * @namespace @node-red/runtime + */ +module.exports = { + init: init, + start: start, + stop: stop, + + /** + * @memberof @node-red/runtime + * @mixes @node-red/runtime_comms + */ + comms: externalAPI.comms, + /** + * @memberof @node-red/runtime + * @mixes @node-red/runtime_flows + */ + flows: externalAPI.flows, + /** + * @memberof @node-red/runtime + * @mixes @node-red/runtime_library + */ + library: externalAPI.library, + /** + * @memberof @node-red/runtime + * @mixes @node-red/runtime_nodes + */ + nodes: externalAPI.nodes, + /** + * @memberof @node-red/runtime + * @mixes @node-red/runtime_settings + */ + settings: externalAPI.settings, + /** + * @memberof @node-red/runtime + * @mixes @node-red/runtime_projects + */ + projects: externalAPI.projects, + /** + * @memberof @node-red/runtime + * @mixes @node-red/runtime_context + */ + context: externalAPI.context, + + /** + * Returns whether the runtime is started + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @return {Promise<Boolean>} - whether the runtime is started + * @function + * @memberof @node-red/runtime + */ + isStarted: externalAPI.isStarted, + + /** + * Returns version number of the runtime + * @param {Object} opts + * @param {User} opts.user - the user calling the api + * @return {Promise<String>} - the runtime version number + * @function + * @memberof @node-red/runtime + */ + version: externalAPI.version, + + storage: storage, + events: events, + util: require("@node-red/util").util, + get httpNode() { return nodeApp }, + get httpAdmin() { return adminApp }, + get server() { return server }, + + "_": runtime +} + + +/** + * A user accessing the API + * @typedef User + * @type {object} + */ diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/library/examples.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/library/examples.js new file mode 100644 index 0000000..28b7c76 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/library/examples.js @@ -0,0 +1,101 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var fs = require('fs'); + +var runtime; + +function init(_runtime) { + runtime = _runtime; +} + +function getEntry(type,path) { + var examples = runtime.nodes.getNodeExampleFlows()||{}; + var result = []; + if (path === "") { + return Promise.resolve(Object.keys(examples)); + } else { + path = path.replace(/\/$/,""); + var parts = path.split("/"); + var module = parts.shift(); + if (module[0] === "@") { + module = module+"/"+parts.shift(); + } + if (examples.hasOwnProperty(module)) { + examples = examples[module]; + examples = parts.reduce(function(ex,k) { + if (ex) { + if (ex.d && ex.d[k]) { + return ex.d[k] + } + if (ex.f && ex.f.indexOf(k) > -1) { + return runtime.nodes.getNodeExampleFlowPath(module,parts.join("/")); + } + } else { + return null; + } + },examples); + + if (!examples) { + return new Promise(function (resolve,reject) { + var error = new Error("not_found"); + error.code = "not_found"; + return reject(error); + }); + } else if (typeof examples === 'string') { + return new Promise(function(resolve,reject) { + try { + fs.readFile(examples,'utf8',function(err, data) { + runtime.log.audit({event: "library.get",library:"_examples",type:"flow",path:path}); + if (err) { + return reject(err); + } + return resolve(data); + }) + } catch(err) { + return reject(err); + } + }); + } else { + if (examples.d) { + for (var d in examples.d) { + if (examples.d.hasOwnProperty(d)) { + result.push(d); + } + } + } + if (examples.f) { + examples.f.forEach(function(f) { + result.push({fn:f}) + }) + } + return Promise.resolve(result); + } + } else { + return new Promise(function (resolve,reject) { + var error = new Error("not_found"); + error.code = "not_found"; + return reject(error); + }); + } + } +} + +module.exports = { + name: '_examples_', + init: init, + getEntry: getEntry +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/library/index.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/library/index.js new file mode 100644 index 0000000..8a4e651 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/library/index.js @@ -0,0 +1,75 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +var knownTypes = {}; + +var libraries = {}; + + +function init(runtime) { + knownTypes = { + 'flows': 'node-red' + }; + + libraries["_examples_"] = require("./examples"); + libraries["_examples_"].init(runtime); + libraries["local"] = require("./local"); + libraries["local"].init(runtime); + +} + +function registerType(id,type) { + // TODO: would like to enforce this, but currently the tests register the same type multiple + // times and have no way to remove themselves. + // if (knownTypes.hasOwnProperty(type)) { + // throw new Error(`Library type '${type}' already registered by ${id}'`) + // } + knownTypes[type] = id; +} + +function getEntry(library,type,path) { + if (!knownTypes.hasOwnProperty(type)) { + throw new Error(`Unknown library type '${type}'`); + } + if (libraries.hasOwnProperty(library)) { + return libraries[library].getEntry(type,path); + } else { + throw new Error(`Unknown library '${library}'`); + } +} +function saveEntry(library,type,path,meta,body) { + if (!knownTypes.hasOwnProperty(type)) { + throw new Error(`Unknown library type '${type}'`); + } + if (libraries.hasOwnProperty(library)) { + if (libraries[library].hasOwnProperty("saveEntry")) { + return libraries[library].saveEntry(type,path,meta,body); + } else { + throw new Error(`Library '${library}' is read-only`); + } + } else { + throw new Error(`Unknown library '${library}'`); + } +} + +module.exports = { + init: init, + register: registerType, + getEntry: getEntry, + saveEntry: saveEntry + +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/library/local.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/library/local.js new file mode 100644 index 0000000..454e800 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/library/local.js @@ -0,0 +1,37 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var runtime; +var storage; + +function init(_runtime) { + runtime = _runtime; + storage = runtime.storage; +} + +function getEntry(type,path) { + return storage.getLibraryEntry(type,path); +} +function saveEntry(type,path,meta,body) { + return storage.saveLibraryEntry(type,path,meta,body); +} + +module.exports = { + name: 'local', + init: init, + getEntry: getEntry, + saveEntry: saveEntry +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/Node.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/Node.js new file mode 100644 index 0000000..a834c8c --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/Node.js @@ -0,0 +1,554 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); +var EventEmitter = require("events").EventEmitter; + +var redUtil = require("@node-red/util").util; +var Log = require("@node-red/util").log; +var context = require("./context"); +var flows = require("./flows"); + +const NOOP_SEND = function() {} + +/** + * The Node object is the heart of a Node-RED flow. It is the object that all + * nodes extend. + * + * The Node object itself inherits from EventEmitter, although it provides + * custom implementations of some of the EE functions in order to handle + * `input` and `close` events properly. + */ +function Node(n) { + this.id = n.id; + this.type = n.type; + this.z = n.z; + this._closeCallbacks = []; + this._inputCallback = null; + this._inputCallbacks = null; + + if (n.name) { + this.name = n.name; + } + if (n._alias) { + this._alias = n._alias; + } + if (n._flow) { + // Make this a non-enumerable property as it may cause + // circular references. Any existing code that tries to JSON serialise + // the object (such as dashboard) will not like circular refs + // The value must still be writable in the case that a node does: + // Object.assign(this,config) + // as part of its constructor - config._flow will overwrite this._flow + // which we can tolerate as they are the same object. + Object.defineProperty(this,'_flow', {value: n._flow, enumerable: false, writable: true }) + this._asyncDelivery = n._flow.asyncMessageDelivery; + } + if (this._asyncDelivery === undefined) { + this._asyncDelivery = true; + } + this.updateWires(n.wires); +} + +util.inherits(Node, EventEmitter); + +/** + * Update the wiring configuration for this node. + * + * We try to optimise the message handling path. To do this there are three + * cases to consider: + * 1. this node is wired to nothing. In this case we replace node.send with a + * NO-OP function. + * 2. this node is wired to one other node. In this case we set `this._wire` + * as a reference to the node it is wired to. This means we avoid unnecessary + * iterations over what would otherwise be a 1-element array. + * 3. this node is wired to multiple things. The normal node.send processing of + * this.wires applies. + * + * @param {array} wires the new wiring configuration + */ +Node.prototype.updateWires = function(wires) { + //console.log("UPDATE",this.id); + this.wires = wires || []; + delete this._wire; + + var wc = 0; + this.wires.forEach(function(w) { + wc+=w.length; + }); + this._wireCount = wc; + if (wc === 0) { + // With nothing wired to the node, no-op send + this.send = NOOP_SEND + } else { + this.send = Node.prototype.send; + if (this.wires.length === 1 && this.wires[0].length === 1) { + // Single wire, so we can shortcut the send when + // a single message is sent + this._wire = this.wires[0][0]; + } + } + +} +/** + * Get the context object for this node. + * + * As most nodes do not use context, this is a lazy function that will only + * create a context instance for the node if it is needed. + * @return {object} the context object + */ +Node.prototype.context = function() { + if (!this._context) { + this._context = context.get(this._alias||this.id,this.z); + } + return this._context; +} + +/** + * Handle the complete event for a message + * + * @param {object} msg The message that has completed + * @param {error} error (optional) an error hit whilst handling the message + */ +Node.prototype._complete = function(msg,error) { + if (error) { + // For now, delegate this to this.error + // But at some point, the timeout handling will need to know about + // this as well. + this.error(error,msg); + } else { + this._flow.handleComplete(this,msg); + } +} + +/** + * An internal reference to the original EventEmitter.on() function + */ +Node.prototype._on = Node.prototype.on; + +/** + * Register a callback function for a named event. + * 'close' and 'input' events are handled locally, other events defer to EventEmitter.on() + */ +Node.prototype.on = function(event, callback) { + var node = this; + if (event == "close") { + this._closeCallbacks.push(callback); + } else if (event === "input") { + if (this._inputCallback) { + this._inputCallbacks = [this._inputCallback, callback]; + this._inputCallback = null; + } else if (this._inputCallbacks) { + this._inputCallbacks.push(callback); + } else { + this._inputCallback = callback; + } + } else { + this._on(event, callback); + } +}; + +/** + * An internal reference to the original EventEmitter.emit() function + */ +Node.prototype._emit = Node.prototype.emit; + +/** + * Emit an event to all registered listeners. + */ +Node.prototype.emit = function(event, ...args) { + var node = this; + if (event === "input") { + // When Pluggable Message Routing arrives, this will be called from + // that and will already be sync/async depending on the router. + if (this._asyncDelivery) { + setImmediate(function() { + node._emitInput.apply(node,args); + }); + } else { + this._emitInput.apply(this,args); + } + } else { + this._emit.apply(this,arguments); + } +} + +/** + * Handle the 'input' event. + * + * This will call all registered handlers for the 'input' event. + */ +Node.prototype._emitInput = function(arg) { + var node = this; + this.metric("receive", arg); + if (node._inputCallback) { + // Just one callback registered. + try { + node._inputCallback( + arg, + function() { node.send.apply(node,arguments) }, + function(err) { node._complete(arg,err); } + ); + } catch(err) { + node.error(err,arg); + } + } else if (node._inputCallbacks) { + // Multiple callbacks registered. Call each one, tracking eventual completion + var c = node._inputCallbacks.length; + for (var i=0;i<c;i++) { + var cb = node._inputCallbacks[i]; + if (cb.length === 2) { + c++; + } + try { + node._inputCallbacks[i]( + arg, + function() { node.send.apply(node,arguments) }, + function(err) { + c--; + if (c === 0) { + node._complete(arg,err); + } + } + ); + } catch(err) { + node.error(err,arg); + } + } + } +} + +/** + * An internal reference to the original EventEmitter.removeListener() function + */ +Node.prototype._removeListener = Node.prototype.removeListener; + +/** + * Remove a listener for an event + */ +Node.prototype.removeListener = function(name, listener) { + var index; + if (name === "input") { + if (this._inputCallback && this._inputCallback === listener) { + // Removing the only callback + this._inputCallback = null; + } else if (this._inputCallbacks) { + // Removing one of many callbacks + index = this._inputCallbacks.indexOf(listener); + if (index > -1) { + this._inputCallbacks.splice(index,1); + } + // Check if we can optimise back to a single callback + if (this._inputCallbacks.length === 1) { + this._inputCallback = this._inputCallbacks[0]; + this._inputCallbacks = null; + } + } + } else if (name === "close") { + index = this._closeCallbacks.indexOf(listener); + if (index > -1) { + this._closeCallbacks.splice(index,1); + } + } else { + this._removeListener(name, listener); + } +} + +/** + * An internal reference to the original EventEmitter.removeAllListeners() function + */ +Node.prototype._removeAllListeners = Node.prototype.removeAllListeners; + +/** + * Remove all listeners for an event + */ +Node.prototype.removeAllListeners = function(name) { + if (name === "input") { + this._inputCallback = null; + this._inputCallbacks = null; + } else if (name === "close") { + this._closeCallbacks = []; + } else { + this._removeAllListeners(name); + } +} + +/** + * Called when the node is being stopped + * @param {boolean} removed Whether the node has been removed, or just being stopped + * @return {Promise} resolves when the node has closed + */ +Node.prototype.close = function(removed) { + //console.log(this.type,this.id,removed); + var promises = []; + var node = this; + // Call all registered close callbacks. + for (var i=0;i<this._closeCallbacks.length;i++) { + var callback = this._closeCallbacks[i]; + if (callback.length > 0) { + // The callback takes a 'done' callback and (maybe) the removed flag + promises.push( + new Promise((resolve) => { + try { + var args = []; + if (callback.length === 2) { + // The listener expects the removed flag + args.push(!!removed); + } + args.push(() => { + resolve(); + }); + callback.apply(node, args); + } catch(err) { + // TODO: error thrown in node async close callback + // We've never logged this properly. + resolve(); + } + }) + ); + } else { + // No done callback so handle synchronously + try { + callback.call(node); + } catch(err) { + // TODO: error thrown in node sync close callback + // We've never logged this properly. + } + } + } + if (promises.length > 0) { + return Promise.all(promises).then(function() { + if (this._context) { + return context.delete(this._alias||this.id,this.z); + } + }); + } else { + if (this._context) { + return context.delete(this._alias||this.id,this.z); + } + return Promise.resolve(); + } +}; + +/** + * Send a message to the nodes wired. + * + * + * @param {object} msg A message or array of messages to send + */ +Node.prototype.send = function(msg) { + var msgSent = false; + var node; + + if (msg === null || typeof msg === "undefined") { + return; + } else if (!util.isArray(msg)) { + if (this._wire) { + // A single message and a single wire on output 0 + // TODO: pre-load flows.get calls - cannot do in constructor + // as not all nodes are defined at that point + if (!msg._msgid) { + msg._msgid = redUtil.generateId(); + } + this.metric("send",msg); + node = this._flow.getNode(this._wire); + /* istanbul ignore else */ + if (node) { + node.receive(msg); + } + return; + } else { + msg = [msg]; + } + } + + var numOutputs = this.wires.length; + + // Build a list of send events so that all cloning is done before + // any calls to node.receive + var sendEvents = []; + + var sentMessageId = null; + + // for each output of node eg. [msgs to output 0, msgs to output 1, ...] + for (var i = 0; i < numOutputs; i++) { + var wires = this.wires[i]; // wires leaving output i + /* istanbul ignore else */ + if (i < msg.length) { + var msgs = msg[i]; // msgs going to output i + if (msgs !== null && typeof msgs !== "undefined") { + if (!util.isArray(msgs)) { + msgs = [msgs]; + } + var k = 0; + // for each recipent node of that output + for (var j = 0; j < wires.length; j++) { + node = this._flow.getNode(wires[j]); // node at end of wire j + if (node) { + // for each msg to send eg. [[m1, m2, ...], ...] + for (k = 0; k < msgs.length; k++) { + var m = msgs[k]; + if (m !== null && m !== undefined) { + /* istanbul ignore else */ + if (!sentMessageId) { + sentMessageId = m._msgid; + } + if (msgSent) { + var clonedmsg = redUtil.cloneMessage(m); + sendEvents.push({n:node,m:clonedmsg}); + } else { + sendEvents.push({n:node,m:m}); + msgSent = true; + } + } + } + } + } + } + } + } + /* istanbul ignore else */ + if (!sentMessageId) { + sentMessageId = redUtil.generateId(); + } + this.metric("send",{_msgid:sentMessageId}); + + for (i=0;i<sendEvents.length;i++) { + var ev = sendEvents[i]; + /* istanbul ignore else */ + if (!ev.m._msgid) { + ev.m._msgid = sentMessageId; + } + ev.n.receive(ev.m); + } +}; + +/** + * Receive a message. + * + * This will emit the `input` event with the provided message. + * As of 1.0, this will return *before* any 'input' callback handler is invoked. + */ +Node.prototype.receive = function(msg) { + if (!msg) { + msg = {}; + } + if (!msg._msgid) { + msg._msgid = redUtil.generateId(); + } + this.emit("input",msg); +}; + +function log_helper(self, level, msg) { + var o = { + level: level, + id: self.id, + type: self.type, + msg: msg + }; + if (self._alias) { + o._alias = self._alias; + } + if (self._flow) { + o.path = self._flow.path; + } + if (self.z) { + o.z = self.z; + } + if (self.name) { + o.name = self.name; + } + Log.log(o); +} +/** + * Log an INFO level message + */ +Node.prototype.log = function(msg) { + log_helper(this, Log.INFO, msg); +}; + +/** + * Log a WARN level message + */ +Node.prototype.warn = function(msg) { + log_helper(this, Log.WARN, msg); +}; + +/** + * Log an ERROR level message + */ +Node.prototype.error = function(logMessage,msg) { + if (typeof logMessage != 'boolean') { + logMessage = logMessage || ""; + } + var handled = false; + if (msg && typeof msg === 'object') { + handled = this._flow.handleError(this,logMessage,msg); + } + if (!handled) { + log_helper(this, Log.ERROR, logMessage); + } +}; + +/** + * Log an DEBUG level message + */ +Node.prototype.debug = function(msg) { + log_helper(this, Log.DEBUG, msg); +} + +/** + * Log an TRACE level message + */ +Node.prototype.trace = function(msg) { + log_helper(this, Log.TRACE, msg); +} + +/** + * Log a metric event. + * If called with no args, returns whether metric collection is enabled + */ +Node.prototype.metric = function(eventname, msg, metricValue) { + if (typeof eventname === "undefined") { + return Log.metric(); + } + var metrics = {}; + metrics.level = Log.METRIC; + metrics.nodeid = this.id; + metrics.event = "node."+this.type+"."+eventname; + metrics.msgid = msg._msgid; + metrics.value = metricValue; + Log.log(metrics); +} + +/** + * Set the node's status object + * + * status: { fill:"red|green", shape:"dot|ring", text:"blah" } + * or + * status: "simple text status" + */ +Node.prototype.status = function(status) { + switch (typeof status) { + case "string": + case "number": + case "boolean": + status = {text:""+status} + } + this._flow.handleStatus(this,status); +}; + +module.exports = Node; diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/context/index.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/context/index.js new file mode 100644 index 0000000..322fa28 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/context/index.js @@ -0,0 +1,523 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var clone = require("clone"); +var log = require("@node-red/util").log; +var util = require("@node-red/util").util; +var memory = require("./memory"); +var flows; + +var settings; + +// A map of scope id to context instance +var contexts = {}; + +// A map of store name to instance +var stores = {}; +var storeList = []; +var defaultStore; + +// Whether there context storage has been configured or left as default +var hasConfiguredStore = false; + +// Unknown Stores +var unknownStores = {}; + +function logUnknownStore(name) { + if (name) { + var count = unknownStores[name] || 0; + if (count == 0) { + log.warn(log._("context.unknown-store", {name: name})); + count++; + unknownStores[name] = count; + } + } +} + +function init(_settings) { + flows = require("../flows"); + settings = _settings; + contexts = {}; + stores = {}; + storeList = []; + hasConfiguredStore = false; + var seed = settings.functionGlobalContext || {}; + contexts['global'] = createContext("global",seed); + // create a default memory store - used by the unit tests that skip the full + // `load()` initialisation sequence. + // If the user has any stores configured, this will be disgarded + stores["_"] = new memory(); + defaultStore = "memory"; +} + +function load() { + return new Promise(function(resolve,reject) { + // load & init plugins in settings.contextStorage + var plugins = settings.contextStorage || {}; + var defaultIsAlias = false; + var promises = []; + if (plugins && Object.keys(plugins).length > 0) { + var hasDefault = plugins.hasOwnProperty('default'); + var defaultName; + for (var pluginName in plugins) { + if (plugins.hasOwnProperty(pluginName)) { + // "_" is a reserved name - do not allow it to be overridden + if (pluginName === "_") { + continue; + } + if (!/^[a-zA-Z0-9_]+$/.test(pluginName)) { + return reject(new Error(log._("context.error-invalid-module-name", {name:pluginName}))); + } + + // Check if this is setting the 'default' context to be a named plugin + if (pluginName === "default" && typeof plugins[pluginName] === "string") { + // Check the 'default' alias exists before initialising anything + if (!plugins.hasOwnProperty(plugins[pluginName])) { + return reject(new Error(log._("context.error-invalid-default-module", {storage:plugins["default"]}))); + } + defaultIsAlias = true; + continue; + } + if (!hasDefault && !defaultName) { + defaultName = pluginName; + } + var plugin; + if (plugins[pluginName].hasOwnProperty("module")) { + // Get the provided config and copy in the 'approved' top-level settings (eg userDir) + var config = plugins[pluginName].config || {}; + copySettings(config, settings); + + if (typeof plugins[pluginName].module === "string") { + // This config identifies the module by name - assume it is a built-in one + // TODO: check it exists locally, if not, try to require it as-is + try { + plugin = require("./"+plugins[pluginName].module); + } catch(err) { + return reject(new Error(log._("context.error-loading-module2", {module:plugins[pluginName].module,message:err.toString()}))); + } + } else { + // Assume `module` is an already-required module we can use + plugin = plugins[pluginName].module; + } + try { + // Create a new instance of the plugin by calling its module function + stores[pluginName] = plugin(config); + var moduleInfo = plugins[pluginName].module; + if (typeof moduleInfo !== 'string') { + if (moduleInfo.hasOwnProperty("toString")) { + moduleInfo = moduleInfo.toString(); + } else { + moduleInfo = "custom"; + } + } + log.info(log._("context.log-store-init", {name:pluginName, info:"module="+moduleInfo})); + } catch(err) { + return reject(new Error(log._("context.error-loading-module2",{module:pluginName,message:err.toString()}))); + } + } else { + // Plugin does not specify a 'module' + return reject(new Error(log._("context.error-module-not-defined", {storage:pluginName}))); + } + } + } + + // Open all of the configured contexts + for (var plugin in stores) { + if (stores.hasOwnProperty(plugin)) { + promises.push(stores[plugin].open()); + } + } + // There is a 'default' listed in the configuration + if (hasDefault) { + // If 'default' is an alias, point it at the right module - we have already + // checked that it exists. If it isn't an alias, then it will + // already be set to a configured store + if (defaultIsAlias) { + stores["_"] = stores[plugins["default"]]; + defaultStore = plugins["default"]; + } else { + stores["_"] = stores["default"]; + defaultStore = "default"; + } + } else if (defaultName) { + // No 'default' listed, so pick first in list as the default + stores["_"] = stores[defaultName]; + defaultStore = defaultName; + defaultIsAlias = true; + } else { + // else there were no stores list the config object - fall through + // to below where we default to a memory store + storeList = ["memory"]; + defaultStore = "memory"; + } + hasConfiguredStore = true; + storeList = Object.keys(stores).filter(n=>!(defaultIsAlias && n==="default") && n!== "_"); + } else { + // No configured plugins + log.info(log._("context.log-store-init", {name:"default", info:"module=memory"})); + promises.push(stores["_"].open()) + storeList = ["memory"]; + defaultStore = "memory"; + } + return resolve(Promise.all(promises)); + }).catch(function(err) { + throw new Error(log._("context.error-loading-module",{message:err.toString()})); + }); +} + +function copySettings(config, settings){ + var copy = ["userDir"] + config.settings = {}; + copy.forEach(function(setting){ + config.settings[setting] = clone(settings[setting]); + }); +} + +function getContextStorage(storage) { + if (stores.hasOwnProperty(storage)) { + // A known context + return stores[storage]; + } else if (stores.hasOwnProperty("_")) { + // Not known, but we have a default to fall back to + if (storage !== defaultStore) { + // It isn't the default store either, so log it + logUnknownStore(storage); + } + return stores["_"]; + } +} + +function followParentContext(parent, key) { + if (key === "$parent") { + return [parent, undefined]; + } + else if (key.startsWith("$parent.")) { + var len = "$parent.".length; + var new_key = key.substring(len); + var ctx = parent; + while (ctx && new_key.startsWith("$parent.")) { + ctx = ctx.$parent; + new_key = new_key.substring(len); + } + return [ctx, new_key]; + } + return null; +} + +function createContext(id,seed,parent) { + // Seed is only set for global context - sourced from functionGlobalContext + var scope = id; + var obj = seed || {}; + var seedKeys; + var insertSeedValues; + if (seed) { + seedKeys = Object.keys(seed); + insertSeedValues = function(keys,values) { + if (!Array.isArray(keys)) { + if (values[0] === undefined) { + try { + values[0] = util.getObjectProperty(seed,keys); + } catch(err) { + if (err.code === "INVALID_EXPR") { + throw err; + } + values[0] = undefined; + } + } + } else { + for (var i=0;i<keys.length;i++) { + if (values[i] === undefined) { + try { + values[i] = util.getObjectProperty(seed,keys[i]); + } catch(err) { + if (err.code === "INVALID_EXPR") { + throw err; + } + values[i] = undefined; + } + } + } + } + } + } + Object.defineProperties(obj, { + get: { + value: function(key, storage, callback) { + var context; + + if (!callback && typeof storage === 'function') { + callback = storage; + storage = undefined; + } + if (callback && typeof callback !== 'function'){ + throw new Error("Callback must be a function"); + } + + if (!Array.isArray(key)) { + var keyParts = util.parseContextStore(key); + key = keyParts.key; + if (!storage) { + storage = keyParts.store || "_"; + } + var result = followParentContext(parent, key); + if (result) { + var [ctx, new_key] = result; + if (ctx && new_key) { + return ctx.get(new_key, storage, callback); + } + else { + if (callback) { + return callback(undefined); + } + else { + return undefined; + } + } + } + } else { + if (!storage) { + storage = "_"; + } + } + context = getContextStorage(storage); + + if (callback) { + if (!seed) { + context.get(scope,key,callback); + } else { + context.get(scope,key,function() { + if (arguments[0]) { + callback(arguments[0]); + return; + } + var results = Array.prototype.slice.call(arguments,[1]); + try { + insertSeedValues(key,results); + } catch(err) { + callback.apply(err); + return + } + // Put the err arg back + results.unshift(undefined); + callback.apply(null,results); + }); + } + } else { + // No callback, attempt to do this synchronously + var results = context.get(scope,key); + if (seed) { + if (Array.isArray(key)) { + insertSeedValues(key,results); + } else if (results === undefined){ + try { + results = util.getObjectProperty(seed,key); + } catch(err) { + if (err.code === "INVALID_EXPR") { + throw err; + } + results = undefined; + } + } + } + return results; + } + } + }, + set: { + value: function(key, value, storage, callback) { + var context; + + if (!callback && typeof storage === 'function') { + callback = storage; + storage = undefined; + } + if (callback && typeof callback !== 'function'){ + throw new Error("Callback must be a function"); + } + + if (!Array.isArray(key)) { + var keyParts = util.parseContextStore(key); + key = keyParts.key; + if (!storage) { + storage = keyParts.store || "_"; + } + var result = followParentContext(parent, key); + if (result) { + var [ctx, new_key] = result; + if (ctx && new_key) { + return ctx.set(new_key, value, storage, callback); + } + else { + if (callback) { + return callback(); + } + return undefined; + } + } + } else { + if (!storage) { + storage = "_"; + } + } + context = getContextStorage(storage); + + context.set(scope, key, value, callback); + } + }, + keys: { + value: function(storage, callback) { + var context; + if (!storage && !callback) { + context = stores["_"]; + } else { + if (typeof storage === 'function') { + callback = storage; + storage = "_"; + } + if (callback && typeof callback !== 'function') { + throw new Error("Callback must be a function"); + } + context = getContextStorage(storage); + } + if (seed && settings.exportGlobalContextKeys !== false) { + if (callback) { + context.keys(scope, function(err,keys) { + callback(err,Array.from(new Set(seedKeys.concat(keys)).keys())); + }); + } else { + var keys = context.keys(scope); + return Array.from(new Set(seedKeys.concat(keys)).keys()) + } + } else { + return context.keys(scope, callback); + } + } + } + }); + if (parent) { + Object.defineProperty(obj, "$parent", { + value: parent + }); + } + return obj; +} + +function createRootContext() { + var obj = {}; + Object.defineProperties(obj, { + get: { + value: function(key, storage, callback) { + return undefined; + } + }, + set: { + value: function(key, value, storage, callback) { + } + }, + keys: { + value: function(storage, callback) { + return undefined; + } + } + }); + return obj; +} + +function getContext(localId,flowId,parent) { + var contextId = localId; + if (flowId) { + contextId = localId+":"+flowId; + } + if (contexts.hasOwnProperty(contextId)) { + return contexts[contextId]; + } + var newContext = createContext(contextId,undefined,parent); + if (flowId) { + var node = flows.get(flowId); + var parent = undefined; + if (node && node.type.startsWith("subflow:")) { + parent = node.context().flow; + } + else { + parent = createRootContext(); + } + var flowContext = getContext(flowId,undefined,parent); + Object.defineProperty(newContext, 'flow', { + value: flowContext + }); + } + Object.defineProperty(newContext, 'global', { + value: contexts['global'] + }) + contexts[contextId] = newContext; + return newContext; +} + +function deleteContext(id,flowId) { + if(!hasConfiguredStore){ + // only delete context if there's no configured storage. + var contextId = id; + if (flowId) { + contextId = id+":"+flowId; + } + delete contexts[contextId]; + return stores["_"].delete(contextId); + }else{ + return Promise.resolve(); + } +} + +function clean(flowConfig) { + var promises = []; + for(var plugin in stores){ + if(stores.hasOwnProperty(plugin)){ + promises.push(stores[plugin].clean(Object.keys(flowConfig.allNodes))); + } + } + for (var id in contexts) { + if (contexts.hasOwnProperty(id) && id !== "global") { + var idParts = id.split(":"); + if (!flowConfig.allNodes.hasOwnProperty(idParts[0])) { + delete contexts[id]; + } + } + } + return Promise.all(promises); +} + +function close() { + var promises = []; + for(var plugin in stores){ + if(stores.hasOwnProperty(plugin)){ + promises.push(stores[plugin].close()); + } + } + return Promise.all(promises); +} + +function listStores() { + return {default:defaultStore,stores:storeList}; +} + +module.exports = { + init: init, + load: load, + listStores: listStores, + get: getContext, + delete: deleteContext, + clean: clean, + close: close +}; diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/context/localfilesystem.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/context/localfilesystem.js new file mode 100644 index 0000000..cf17697 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/context/localfilesystem.js @@ -0,0 +1,415 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +/** + * Local file-system based context storage + * + * Configuration options: + * { + * base: "context", // the base directory to use + * // default: "context" + * dir: "/path/to/storage", // the directory to create the base directory in + * // default: settings.userDir + * cache: true, // whether to cache contents in memory + * // default: true + * flushInterval: 30 // if cache is enabled, the minimum interval + * // between writes to storage, in seconds. This + * can be used to reduce wear on underlying storage. + * default: 30 seconds + * } + * + * + * $HOME/.node-red/contexts + * ├── global + * │ └── global_context.json + * ├── <id of Flow 1> + * │ ├── flow_context.json + * │ ├── <id of Node a>.json + * │ └── <id of Node b>.json + * └── <id of Flow 2> + * ├── flow_context.json + * ├── <id of Node x>.json + * └── <id of Node y>.json + */ + +var fs = require('fs-extra'); +var path = require("path"); +var util = require("@node-red/util").util; +var log = require("@node-red/util").log; + +var safeJSONStringify = require("json-stringify-safe"); +var MemoryStore = require("./memory"); + + +function getStoragePath(storageBaseDir, scope) { + if(scope.indexOf(":") === -1){ + if(scope === "global"){ + return path.join(storageBaseDir,"global",scope); + }else{ // scope:flow + return path.join(storageBaseDir,scope,"flow"); + } + }else{ // scope:local + var ids = scope.split(":") + return path.join(storageBaseDir,ids[1],ids[0]); + } +} + +function getBasePath(config) { + var base = config.base || "context"; + var storageBaseDir; + if (!config.dir) { + if(config.settings && config.settings.userDir){ + storageBaseDir = path.join(config.settings.userDir, base); + }else{ + try { + fs.statSync(path.join(process.env.NODE_RED_HOME,".config.json")); + storageBaseDir = path.join(process.env.NODE_RED_HOME, base); + } catch(err) { + try { + // Consider compatibility for older versions + if (process.env.HOMEPATH) { + fs.statSync(path.join(process.env.HOMEPATH,".node-red",".config.json")); + storageBaseDir = path.join(process.env.HOMEPATH, ".node-red", base); + } + } catch(err) { + } + if (!storageBaseDir) { + storageBaseDir = path.join(process.env.HOME || process.env.USERPROFILE || process.env.HOMEPATH || process.env.NODE_RED_HOME,".node-red", base); + } + } + } + }else{ + storageBaseDir = path.join(config.dir, base); + } + return storageBaseDir; +} + +function loadFile(storagePath){ + return fs.pathExists(storagePath).then(function(exists){ + if(exists === true){ + return fs.readFile(storagePath, "utf8"); + }else{ + return Promise.resolve(undefined); + } + }); +} + +function listFiles(storagePath) { + var promises = []; + return fs.readdir(storagePath).then(function(files) { + files.forEach(function(file) { + if (!/^\./.test(file)) { + var fullPath = path.join(storagePath,file); + var stats = fs.statSync(fullPath); + if (stats.isDirectory()) { + promises.push(fs.readdir(fullPath).then(function(subdirFiles) { + var result = []; + subdirFiles.forEach(subfile => { + if (/\.json$/.test(subfile)) { + result.push(path.join(file,subfile)) + } + }); + return result; + })) + } + } + }); + return Promise.all(promises); + }).then(dirs => dirs.reduce((acc, val) => acc.concat(val), [])); +} + +function stringify(value) { + var hasCircular; + var result = safeJSONStringify(value,null,4,function(k,v){hasCircular = true}) + return { json: result, circular: hasCircular }; +} + + +function writeFileAtomic(storagePath, content) { + // To protect against file corruption, write to a tmp file first and then + // rename to the destination file + let finalFile = storagePath + ".json"; + let tmpFile = finalFile + "."+Date.now()+".tmp"; + return fs.outputFile(tmpFile, content, "utf8").then(function() { + return fs.rename(tmpFile,finalFile); + }) +} +function LocalFileSystem(config){ + this.config = config; + this.storageBaseDir = getBasePath(this.config); + this.writePromise = Promise.resolve(); + if (config.hasOwnProperty('cache')?config.cache:true) { + this.cache = MemoryStore({}); + } + this.pendingWrites = {}; + this.knownCircularRefs = {}; + + if (config.hasOwnProperty('flushInterval')) { + this.flushInterval = Math.max(0,config.flushInterval) * 1000; + } else { + this.flushInterval = 30000; + } +} + +LocalFileSystem.prototype.open = function(){ + var self = this; + if (this.cache) { + var scopes = []; + var promises = []; + return listFiles(self.storageBaseDir).then(function(files) { + files.forEach(function(file) { + var parts = file.split(path.sep); + if (parts[0] === 'global') { + scopes.push("global"); + } else if (parts[1] === 'flow.json') { + scopes.push(parts[0]) + } else { + scopes.push(parts[1].substring(0,parts[1].length-5)+":"+parts[0]); + } + promises.push(loadFile(path.join(self.storageBaseDir,file))); + }) + return Promise.all(promises); + }).then(function(res) { + scopes.forEach(function(scope,i) { + var data = res[i]?JSON.parse(res[i]):{}; + Object.keys(data).forEach(function(key) { + self.cache.set(scope,key,data[key]); + }) + }); + }).catch(function(err){ + if(err.code == 'ENOENT') { + return fs.ensureDir(self.storageBaseDir); + }else{ + throw err; + } + }).then(function() { + self._flushPendingWrites = function() { + var scopes = Object.keys(self.pendingWrites); + self.pendingWrites = {}; + var promises = []; + var newContext = self.cache._export(); + scopes.forEach(function(scope) { + var storagePath = getStoragePath(self.storageBaseDir,scope); + var context = newContext[scope]; + var stringifiedContext = stringify(context); + if (stringifiedContext.circular && !self.knownCircularRefs[scope]) { + log.warn(log._("error-circular",{scope:scope})); + self.knownCircularRefs[scope] = true; + } else { + delete self.knownCircularRefs[scope]; + } + log.debug("Flushing localfilesystem context scope "+scope); + promises.push(writeFileAtomic(storagePath, stringifiedContext.json)) + }); + delete self._pendingWriteTimeout; + return Promise.all(promises); + } + }); + } else { + self._flushPendingWrites = function() { } + return fs.ensureDir(self.storageBaseDir); + } +} + +LocalFileSystem.prototype.close = function(){ + var self = this; + if (this.cache && this._pendingWriteTimeout) { + clearTimeout(this._pendingWriteTimeout); + delete this._pendingWriteTimeout; + this.flushInterval = 0; + self.writePromise = self.writePromise.then(function(){ + return self._flushPendingWrites.call(self).catch(function(err) { + log.error(log._("context.localfilesystem.error-write",{message:err.toString()})); + }); + }); + + } + return this.writePromise; +} + +LocalFileSystem.prototype.get = function(scope, key, callback) { + if (this.cache) { + return this.cache.get(scope,key,callback); + } + if(typeof callback !== "function"){ + throw new Error("File Store cache disabled - only asynchronous access supported"); + } + var storagePath = getStoragePath(this.storageBaseDir ,scope); + loadFile(storagePath + ".json").then(function(data){ + var value; + if(data){ + data = JSON.parse(data); + if (!Array.isArray(key)) { + try { + value = util.getObjectProperty(data,key); + } catch(err) { + if (err.code === "INVALID_EXPR") { + throw err; + } + value = undefined; + } + callback(null, value); + } else { + var results = [undefined]; + for (var i=0;i<key.length;i++) { + try { + value = util.getObjectProperty(data,key[i]); + } catch(err) { + if (err.code === "INVALID_EXPR") { + throw err; + } + value = undefined; + } + results.push(value) + } + callback.apply(null,results); + } + }else{ + callback(null, undefined); + } + }).catch(function(err){ + callback(err); + }); +}; + +LocalFileSystem.prototype.set = function(scope, key, value, callback) { + var self = this; + var storagePath = getStoragePath(this.storageBaseDir ,scope); + if (this.cache) { + this.cache.set(scope,key,value,callback); + this.pendingWrites[scope] = true; + if (this._pendingWriteTimeout) { + // there's a pending write which will handle this + return; + } else { + this._pendingWriteTimeout = setTimeout(function() { + self.writePromise = self.writePromise.then(function(){ + return self._flushPendingWrites.call(self).catch(function(err) { + log.error(log._("context.localfilesystem.error-write",{message:err.toString()})); + }); + }); + }, this.flushInterval); + } + } else if (callback && typeof callback !== 'function') { + throw new Error("File Store cache disabled - only asynchronous access supported"); + } else { + self.writePromise = self.writePromise.then(function() { return loadFile(storagePath + ".json") }).then(function(data){ + var obj = data ? JSON.parse(data) : {} + if (!Array.isArray(key)) { + key = [key]; + value = [value]; + } else if (!Array.isArray(value)) { + // key is an array, but value is not - wrap it as an array + value = [value]; + } + for (var i=0;i<key.length;i++) { + var v = null; + if (i<value.length) { + v = value[i]; + } + util.setObjectProperty(obj,key[i],v); + } + var stringifiedContext = stringify(obj); + if (stringifiedContext.circular && !self.knownCircularRefs[scope]) { + log.warn(log._("error-circular",{scope:scope})); + self.knownCircularRefs[scope] = true; + } else { + delete self.knownCircularRefs[scope]; + } + return writeFileAtomic(storagePath, stringifiedContext.json); + }).then(function(){ + if(typeof callback === "function"){ + callback(null); + } + }).catch(function(err){ + if(typeof callback === "function"){ + callback(err); + } + }); + } +}; + +LocalFileSystem.prototype.keys = function(scope, callback){ + if (this.cache) { + return this.cache.keys(scope,callback); + } + if(typeof callback !== "function"){ + throw new Error("Callback must be a function"); + } + var storagePath = getStoragePath(this.storageBaseDir ,scope); + loadFile(storagePath + ".json").then(function(data){ + if(data){ + callback(null, Object.keys(JSON.parse(data))); + }else{ + callback(null, []); + } + }).catch(function(err){ + callback(err); + }); +}; + +LocalFileSystem.prototype.delete = function(scope){ + var cachePromise; + if (this.cache) { + cachePromise = this.cache.delete(scope); + } else { + cachePromise = Promise.resolve(); + } + var that = this; + delete this.pendingWrites[scope]; + return cachePromise.then(function() { + var storagePath = getStoragePath(that.storageBaseDir,scope); + return fs.remove(storagePath + ".json"); + }); +} + +LocalFileSystem.prototype.clean = function(_activeNodes) { + var activeNodes = {}; + _activeNodes.forEach(function(node) { activeNodes[node] = true }); + var self = this; + var cachePromise; + if (this.cache) { + cachePromise = this.cache.clean(_activeNodes); + } else { + cachePromise = Promise.resolve(); + } + this.knownCircularRefs = {}; + return cachePromise.then(() => listFiles(self.storageBaseDir)).then(function(files) { + var promises = []; + files.forEach(function(file) { + var parts = file.split(path.sep); + var removePromise; + if (parts[0] === 'global') { + // never clean global + return; + } else if (!activeNodes[parts[0]]) { + // Flow removed - remove the whole dir + removePromise = fs.remove(path.join(self.storageBaseDir,parts[0])); + } else if (parts[1] !== 'flow.json' && !activeNodes[parts[1].substring(0,parts[1].length-5)]) { + // Node removed - remove the context file + removePromise = fs.remove(path.join(self.storageBaseDir,file)); + } + if (removePromise) { + promises.push(removePromise); + } + }); + return Promise.all(promises) + }) +} + +module.exports = function(config){ + return new LocalFileSystem(config); +}; diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/context/memory.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/context/memory.js new file mode 100644 index 0000000..2ad3aca --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/context/memory.js @@ -0,0 +1,173 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("@node-red/util").util; + +function Memory(config){ + this.data = {}; +} + +Memory.prototype.open = function(){ + return Promise.resolve(); +}; + +Memory.prototype.close = function(){ + return Promise.resolve(); +}; + +Memory.prototype._getOne = function(scope, key) { + var value; + var error; + if(this.data[scope]){ + try { + value = util.getObjectProperty(this.data[scope], key); + } catch(err) { + if (err.code === "INVALID_EXPR") { + throw err; + } + value = undefined; + } + } + return value; +} + +Memory.prototype.get = function(scope, key, callback) { + var value; + var error; + if (!Array.isArray(key)) { + try { + value = this._getOne(scope,key); + } catch(err) { + if (!callback) { + throw err; + } + error = err; + } + if (callback) { + callback(error,value); + return; + } else { + return value; + } + } + + value = []; + for (var i=0; i<key.length; i++) { + try { + value.push(this._getOne(scope,key[i])); + } catch(err) { + if (!callback) { + throw err; + } else { + callback(err); + return; + } + } + } + if (callback) { + callback.apply(null, [undefined].concat(value)); + } else { + return value; + } +}; + +Memory.prototype.set = function(scope, key, value, callback) { + if(!this.data[scope]){ + this.data[scope] = {}; + } + var error; + if (!Array.isArray(key)) { + key = [key]; + value = [value]; + } else if (!Array.isArray(value)) { + // key is an array, but value is not - wrap it as an array + value = [value]; + } + try { + for (var i=0; i<key.length; i++) { + var v = null; + if (i < value.length) { + v = value[i]; + } + util.setObjectProperty(this.data[scope],key[i],v); + } + } catch(err) { + if (callback) { + error = err; + } else { + throw err; + } + } + if(callback){ + callback(error); + } +}; + +Memory.prototype.keys = function(scope, callback){ + var values = []; + var error; + try{ + if(this.data[scope]){ + if (scope !== "global") { + values = Object.keys(this.data[scope]); + } else { + values = Object.keys(this.data[scope]).filter(function (key) { + return key !== "set" && key !== "get" && key !== "keys"; + }); + } + } + }catch(err){ + if(callback){ + error = err; + }else{ + throw err; + } + } + if(callback){ + if(error){ + callback(error); + } else { + callback(null, values); + } + } else { + return values; + } +}; + +Memory.prototype.delete = function(scope){ + delete this.data[scope]; + return Promise.resolve(); +}; + +Memory.prototype.clean = function(activeNodes){ + for(var id in this.data){ + if(this.data.hasOwnProperty(id) && id !== "global"){ + var idParts = id.split(":"); + if(activeNodes.indexOf(idParts[0]) === -1){ + delete this.data[id]; + } + } + } + return Promise.resolve(); +} + +Memory.prototype._export = function() { + return this.data; +} + +module.exports = function(config){ + return new Memory(config); +}; diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/credentials.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/credentials.js new file mode 100644 index 0000000..355bd9b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/credentials.js @@ -0,0 +1,432 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require("when"); +var crypto = require('crypto'); +var runtime; +var settings; +var log; + + +var encryptedCredentials = null; +var credentialCache = {}; +var credentialsDef = {}; +var dirty = false; + +var removeDefaultKey = false; +var encryptionEnabled = null; +var encryptionKeyType; // disabled, system, user, project +var encryptionAlgorithm = "aes-256-ctr"; +var encryptionKey; + +function decryptCredentials(key,credentials) { + var creds = credentials["$"]; + var initVector = Buffer.from(creds.substring(0, 32),'hex'); + creds = creds.substring(32); + var decipher = crypto.createDecipheriv(encryptionAlgorithm, key, initVector); + var decrypted = decipher.update(creds, 'base64', 'utf8') + decipher.final('utf8'); + return JSON.parse(decrypted); +} +function encryptCredentials(key,credentials) { + var initVector = crypto.randomBytes(16); + var cipher = crypto.createCipheriv(encryptionAlgorithm, key, initVector); + return {"$":initVector.toString('hex') + cipher.update(JSON.stringify(credentials), 'utf8', 'base64') + cipher.final('base64')}; +} + +var api = module.exports = { + init: function(_runtime) { + runtime = _runtime; + log = runtime.log; + settings = runtime.settings; + dirty = false; + credentialCache = {}; + credentialsDef = {}; + encryptionEnabled = null; + }, + + /** + * Sets the credentials from storage. + */ + load: function (credentials) { + dirty = false; + var credentialsEncrypted = credentials.hasOwnProperty("$") && Object.keys(credentials).length === 1; + + // Case 1: Active Project in place + // - use whatever its config says + + // Case 2: _credentialSecret unset, credentialSecret unset + // - generate _credentialSecret and encrypt + + // Case 3: _credentialSecret set, credentialSecret set + // - migrate from _credentialSecret to credentialSecret + // - delete _credentialSecret + + // Case 4: credentialSecret set + // - use it + + var setupEncryptionPromise = when.resolve(); + + var projectKey = false; + var activeProject; + encryptionKeyType = ""; + + if (runtime.storage && runtime.storage.projects) { + // projects enabled + activeProject = runtime.storage.projects.getActiveProject(); + if (activeProject) { + projectKey = activeProject.credentialSecret; + if (!projectKey) { + log.debug("red/runtime/nodes/credentials.load : using active project key - disabled"); + encryptionKeyType = "disabled"; + encryptionEnabled = false; + } else { + log.debug("red/runtime/nodes/credentials.load : using active project key"); + encryptionKeyType = "project"; + encryptionKey = crypto.createHash('sha256').update(projectKey).digest(); + encryptionEnabled = true; + } + } + } + + if (encryptionKeyType === '') { + var defaultKey; + try { + defaultKey = settings.get('_credentialSecret'); + } catch(err) { + } + if (defaultKey) { + defaultKey = crypto.createHash('sha256').update(defaultKey).digest(); + encryptionKeyType = "system"; + } + var userKey; + try { + userKey = settings.get('credentialSecret'); + } catch(err) { + userKey = false; + } + + if (userKey === false) { + encryptionKeyType = "disabled"; + log.debug("red/runtime/nodes/credentials.load : user disabled encryption"); + // User has disabled encryption + encryptionEnabled = false; + // Check if we have a generated _credSecret to decrypt with and remove + if (defaultKey) { + log.debug("red/runtime/nodes/credentials.load : default key present. Will migrate"); + if (credentialsEncrypted) { + try { + credentials = decryptCredentials(defaultKey,credentials) + } catch(err) { + credentials = {}; + log.warn(log._("nodes.credentials.error",{message:err.toString()})) + var error = new Error("Failed to decrypt credentials"); + error.code = "credentials_load_failed"; + return when.reject(error); + } + } + dirty = true; + removeDefaultKey = true; + } + } else if (typeof userKey === 'string') { + if (!projectKey) { + log.debug("red/runtime/nodes/credentials.load : user provided key"); + } + if (encryptionKeyType !== 'project') { + encryptionKeyType = 'user'; + } + // User has provided own encryption key, get the 32-byte hash of it + encryptionKey = crypto.createHash('sha256').update(userKey).digest(); + encryptionEnabled = true; + + if (encryptionKeyType !== 'project' && defaultKey) { + log.debug("red/runtime/nodes/credentials.load : default key present. Will migrate"); + // User has provided their own key, but we already have a default key + // Decrypt using default key + if (credentialsEncrypted) { + try { + credentials = decryptCredentials(defaultKey,credentials) + } catch(err) { + credentials = {}; + log.warn(log._("nodes.credentials.error",{message:err.toString()})) + var error = new Error("Failed to decrypt credentials"); + error.code = "credentials_load_failed"; + return when.reject(error); + } + } + dirty = true; + removeDefaultKey = true; + } + } else { + log.debug("red/runtime/nodes/credentials.load : no user key present"); + // User has not provide their own key + if (encryptionKeyType !== 'project') { + encryptionKeyType = 'system'; + } + encryptionKey = defaultKey; + encryptionEnabled = true; + if (encryptionKey === undefined) { + log.debug("red/runtime/nodes/credentials.load : no default key present - generating one"); + // No user-provided key, no generated key + // Generate a new key + defaultKey = crypto.randomBytes(32).toString('hex'); + try { + setupEncryptionPromise = settings.set('_credentialSecret',defaultKey); + encryptionKey = crypto.createHash('sha256').update(defaultKey).digest(); + } catch(err) { + log.debug("red/runtime/nodes/credentials.load : settings unavailable - disabling encryption"); + // Settings unavailable + encryptionEnabled = false; + encryptionKey = null; + } + dirty = true; + } else { + log.debug("red/runtime/nodes/credentials.load : using default key"); + } + } + } + + if (encryptionEnabled && !dirty) { + encryptedCredentials = credentials; + } + log.debug("red/runtime/nodes/credentials.load : keyType="+encryptionKeyType); + if (encryptionKeyType === 'system') { + log.warn(log._("nodes.credentials.system-key-warning")); + } + return setupEncryptionPromise.then(function() { + var clearInvalidFlag = false; + if (credentials.hasOwnProperty("$")) { + if (encryptionEnabled === false) { + // The credentials appear to be encrypted, but our config + // thinks they are not. + var error = new Error("Failed to decrypt credentials"); + error.code = "credentials_load_failed"; + if (activeProject) { + // This is a project with a bad key. Mark it as invalid + // TODO: this delves too deep into Project structure + activeProject.credentialSecretInvalid = true; + return when.reject(error); + } + return when.reject(error); + } + // These are encrypted credentials + try { + credentialCache = decryptCredentials(encryptionKey,credentials) + clearInvalidFlag = true; + } catch(err) { + credentialCache = {}; + dirty = true; + log.warn(log._("nodes.credentials.error",{message:err.toString()})) + var error = new Error("Failed to decrypt credentials"); + error.code = "credentials_load_failed"; + if (activeProject) { + // This is a project with a bad key. Mark it as invalid + // TODO: this delves too deep into Project structure + activeProject.credentialSecretInvalid = true; + return when.reject(error); + } + return when.reject(error); + } + } else { + credentialCache = credentials; + } + if (clearInvalidFlag) { + // TODO: this delves too deep into Project structure + if (activeProject) { + delete activeProject.credentialSecretInvalid; + } + } + }); + }, + + /** + * Adds a set of credentials for the given node id. + * @param id the node id for the credentials + * @param creds an object of credential key/value pairs + * @return a promise for backwards compatibility TODO: can this be removed? + */ + add: function (id, creds) { + if (!credentialCache.hasOwnProperty(id) || JSON.stringify(creds) !== JSON.stringify(credentialCache[id])) { + credentialCache[id] = creds; + dirty = true; + } + return when.resolve(); + }, + + /** + * Gets the credentials for the given node id. + * @param id the node id for the credentials + * @return the credentials + */ + get: function (id) { + return credentialCache[id]; + }, + + /** + * Deletes the credentials for the given node id. + * @param id the node id for the credentials + * @return a promise for the saving of credentials to storage + */ + delete: function (id) { + delete credentialCache[id]; + dirty = true; + }, + + clear: function() { + credentialCache = {}; + dirty = true; + }, + /** + * Deletes any credentials for nodes that no longer exist + * @param config a flow config + * @return a promise for the saving of credentials to storage + */ + clean: function (config) { + var existingIds = {}; + config.forEach(function(n) { + existingIds[n.id] = true; + if (n.credentials) { + api.extract(n); + } + }); + var deletedCredentials = false; + for (var c in credentialCache) { + if (credentialCache.hasOwnProperty(c)) { + if (!existingIds[c]) { + deletedCredentials = true; + delete credentialCache[c]; + } + } + } + if (deletedCredentials) { + dirty = true; + } + return when.resolve(); + }, + + /** + * Registers a node credential definition. + * @param type the node type + * @param definition the credential definition + */ + register: function (type, definition) { + var dashedType = type.replace(/\s+/g, '-'); + credentialsDef[dashedType] = definition; + }, + + /** + * Extracts and stores any credential updates in the provided node. + * The provided node may have a .credentials property that contains + * new credentials for the node. + * This function loops through the credentials in the definition for + * the node-type and applies any of the updates provided in the node. + * + * This function does not save the credentials to disk as it is expected + * to be called multiple times when a new flow is deployed. + * + * @param node the node to extract credentials from + */ + extract: function(node) { + var nodeID = node.id; + var nodeType = node.type; + var newCreds = node.credentials; + if (newCreds) { + delete node.credentials; + var savedCredentials = credentialCache[nodeID] || {}; + var dashedType = nodeType.replace(/\s+/g, '-'); + var definition = credentialsDef[dashedType]; + if (!definition) { + log.warn(log._("nodes.credentials.not-registered",{type:nodeType})); + return; + } + + for (var cred in definition) { + if (definition.hasOwnProperty(cred)) { + if (newCreds[cred] === undefined) { + continue; + } + if (definition[cred].type == "password" && newCreds[cred] == '__PWRD__') { + continue; + } + if (0 === newCreds[cred].length || /^\s*$/.test(newCreds[cred])) { + delete savedCredentials[cred]; + dirty = true; + continue; + } + if (!savedCredentials.hasOwnProperty(cred) || JSON.stringify(savedCredentials[cred]) !== JSON.stringify(newCreds[cred])) { + savedCredentials[cred] = newCreds[cred]; + dirty = true; + } + } + } + credentialCache[nodeID] = savedCredentials; + } + }, + + /** + * Gets the credential definition for the given node type + * @param type the node type + * @return the credential definition + */ + getDefinition: function (type) { + return credentialsDef[type]; + }, + + dirty: function() { + return dirty; + }, + setKey: function(key) { + if (key) { + encryptionKey = crypto.createHash('sha256').update(key).digest(); + encryptionEnabled = true; + dirty = true; + encryptionKeyType = "project"; + } else { + encryptionKey = null; + encryptionEnabled = false; + dirty = true; + encryptionKeyType = "disabled"; + } + }, + getKeyType: function() { + return encryptionKeyType; + }, + export: function() { + var result = credentialCache; + + if (encryptionEnabled) { + if (dirty) { + try { + log.debug("red/runtime/nodes/credentials.export : encrypting"); + result = encryptCredentials(encryptionKey, credentialCache); + } catch(err) { + log.warn(log._("nodes.credentials.error-saving",{message:err.toString()})) + } + } else { + result = encryptedCredentials; + } + } + dirty = false; + if (removeDefaultKey) { + log.debug("red/runtime/nodes/credentials.export : removing unused default key"); + return settings.delete('_credentialSecret').then(function() { + removeDefaultKey = false; + return result; + }) + } else { + return when.resolve(result); + } + } +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/flows/Flow.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/flows/Flow.js new file mode 100644 index 0000000..db15e8e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/flows/Flow.js @@ -0,0 +1,598 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var clone = require("clone"); +var redUtil = require("@node-red/util").util; +var flowUtil = require("./util"); +var events = require("../../events"); + +var Subflow; +var Log; + +var nodeCloseTimeout = 15000; +var asyncMessageDelivery = true; + +/** + * This class represents a flow within the runtime. It is responsible for + * creating, starting and stopping all nodes within the flow. + */ +class Flow { + + /** + * Create a Flow object. + * @param {[type]} parent The parent flow + * @param {[type]} globalFlow The global flow definition + * @param {[type]} flow This flow's definition + */ + constructor(parent,globalFlow,flow) { + this.TYPE = 'flow'; + this.parent = parent; + this.global = globalFlow; + if (typeof flow === 'undefined') { + this.flow = globalFlow; + this.isGlobalFlow = true; + } else { + this.flow = flow; + this.isGlobalFlow = false; + } + this.id = this.flow.id || "global"; + this.activeNodes = {}; + this.subflowInstanceNodes = {}; + this.catchNodes = []; + this.statusNodes = []; + this.path = this.id; + } + + /** + * Log a debug-level message from this flow + * @param {[type]} msg [description] + * @return {[type]} [description] + */ + debug(msg) { + Log.log({ + id: this.id||"global", + level: Log.DEBUG, + type:this.TYPE, + msg:msg + }) + } + + /** + * Log an error-level message from this flow + * @param {[type]} msg [description] + * @return {[type]} [description] + */ + error(msg) { + Log.log({ + id: this.id||"global", + level: Log.ERROR, + type:this.TYPE, + msg:msg + }) + } + + /** + * Log a info-level message from this flow + * @param {[type]} msg [description] + * @return {[type]} [description] + */ + log(msg) { + Log.log({ + id: this.id||"global", + level: Log.INFO, + type:this.TYPE, + msg:msg + }) + } + + /** + * Log a trace-level message from this flow + * @param {[type]} msg [description] + * @return {[type]} [description] + */ + trace(msg) { + Log.log({ + id: this.id||"global", + level: Log.TRACE, + type:this.TYPE, + msg:msg + }) + } + + + /** + * Start this flow. + * The `diff` argument helps define what needs to be started in the case + * of a modified-nodes/flows type deploy. + * @param {[type]} msg [description] + * @return {[type]} [description] + */ + start(diff) { + this.trace("start "+this.TYPE+" ["+this.path+"]"); + var node; + var newNode; + var id; + this.catchNodes = []; + this.statusNodes = []; + this.completeNodeMap = {}; + + var configNodes = Object.keys(this.flow.configs); + var configNodeAttempts = {}; + while (configNodes.length > 0) { + id = configNodes.shift(); + node = this.flow.configs[id]; + if (!this.activeNodes[id]) { + if (node.d !== true) { + var readyToCreate = true; + // This node doesn't exist. + // Check it doesn't reference another non-existent config node + for (var prop in node) { + if (node.hasOwnProperty(prop) && + prop !== 'id' && + prop !== 'wires' && + prop !== '_users' && + this.flow.configs[node[prop]] && + this.flow.configs[node[prop]].d !== true + ) { + if (!this.activeNodes[node[prop]]) { + // References a non-existent config node + // Add it to the back of the list to try again later + configNodes.push(id); + configNodeAttempts[id] = (configNodeAttempts[id]||0)+1; + if (configNodeAttempts[id] === 100) { + throw new Error("Circular config node dependency detected: "+id); + } + readyToCreate = false; + break; + } + } + } + if (readyToCreate) { + newNode = flowUtil.createNode(this,node); + if (newNode) { + this.activeNodes[id] = newNode; + } + } + } else { + this.debug("not starting disabled config node : "+id); + } + } + } + + if (diff && diff.rewired) { + for (var j=0;j<diff.rewired.length;j++) { + var rewireNode = this.activeNodes[diff.rewired[j]]; + if (rewireNode) { + rewireNode.updateWires(this.flow.nodes[rewireNode.id].wires); + } + } + } + + for (id in this.flow.nodes) { + if (this.flow.nodes.hasOwnProperty(id)) { + node = this.flow.nodes[id]; + if (node.d !== true) { + if (!node.subflow) { + if (!this.activeNodes[id]) { + newNode = flowUtil.createNode(this,node); + if (newNode) { + this.activeNodes[id] = newNode; + } + } + } else { + if (!this.subflowInstanceNodes[id]) { + try { + var subflowDefinition = this.flow.subflows[node.subflow]||this.global.subflows[node.subflow] + // console.log("NEED TO CREATE A SUBFLOW",id,node.subflow); + this.subflowInstanceNodes[id] = true; + var subflow = Subflow.create( + this, + this.global, + subflowDefinition, + node + ); + this.subflowInstanceNodes[id] = subflow; + subflow.start(); + this.activeNodes[id] = subflow.node; + + // this.subflowInstanceNodes[id] = nodes.map(function(n) { return n.id}); + // for (var i=0;i<nodes.length;i++) { + // if (nodes[i]) { + // this.activeNodes[nodes[i].id] = nodes[i]; + // } + // } + } catch(err) { + console.log(err.stack) + } + } + } + } else { + this.debug("not starting disabled node : "+id); + } + } + } + + var activeCount = Object.keys(this.activeNodes).length; + if (activeCount > 0) { + this.trace("------------------|--------------|-----------------"); + this.trace(" id | type | alias"); + this.trace("------------------|--------------|-----------------"); + } + // Build the map of catch/status/complete nodes. + for (id in this.activeNodes) { + if (this.activeNodes.hasOwnProperty(id)) { + node = this.activeNodes[id]; + this.trace(" "+id.padEnd(16)+" | "+node.type.padEnd(12)+" | "+(node._alias||"")+(node._zAlias?" [zAlias:"+node._zAlias+"]":"")); + if (node.type === "catch") { + this.catchNodes.push(node); + } else if (node.type === "status") { + this.statusNodes.push(node); + } else if (node.type === "complete") { + if (node.scope) { + node.scope.forEach(id => { + this.completeNodeMap[id] = this.completeNodeMap[id] || []; + this.completeNodeMap[id].push(node); + }) + } + } + } + } + this.catchNodes.sort(function(A,B) { + if (A.scope && !B.scope) { + return -1; + } else if (!A.scope && B.scope) { + return 1; + } else if (A.scope && B.scope) { + return 0; + } else if (A.uncaught && !B.uncaught) { + return 1; + } else if (!A.uncaught && B.uncaught) { + return -1; + } + return 0; + }); + + if (activeCount > 0) { + this.trace("------------------|--------------|-----------------"); + } + // this.dump(); + } + + /** + * Stop this flow. + * The `stopList` argument helps define what needs to be stopped in the case + * of a modified-nodes/flows type deploy. + * @param {[type]} stopList [description] + * @param {[type]} removedList [description] + * @return {[type]} [description] + */ + stop(stopList, removedList) { + this.trace("stop "+this.TYPE); + var i; + if (!stopList) { + stopList = Object.keys(this.activeNodes); + } + // this.trace(" stopList: "+stopList.join(",")) + // Convert the list to a map to avoid multiple scans of the list + var removedMap = {}; + removedList = removedList || []; + removedList.forEach(function(id) { + removedMap[id] = true; + }); + + var promises = []; + for (i=0;i<stopList.length;i++) { + var node = this.activeNodes[stopList[i]]; + if (node) { + delete this.activeNodes[stopList[i]]; + if (this.subflowInstanceNodes[stopList[i]]) { + try { + (function(subflow) { + promises.push(stopNode(node,false).then(() => subflow.stop())); + })(this.subflowInstanceNodes[stopList[i]]); + } catch(err) { + node.error(err); + } + delete this.subflowInstanceNodes[stopList[i]]; + } else { + try { + var removed = removedMap[stopList[i]]; + promises.push(stopNode(node,removed).catch(()=>{})); + } catch(err) { + node.error(err); + } + } + } + } + return Promise.all(promises); + } + + /** + * Update the flow definition. This doesn't change anything that is running. + * This should be called after `stop` and before `start`. + * @param {[type]} _global [description] + * @param {[type]} _flow [description] + * @return {[type]} [description] + */ + update(_global,_flow) { + this.global = _global; + this.flow = _flow; + } + + /** + * Get a node instance from this flow. If the node is not known to this + * flow, pass the request up to the parent. + * @param {String} id [description] + * @param {Boolean} cancelBubble if true, prevents the flow from passing the request to the parent + * This stops infinite loops when the parent asked this Flow for the + * node to begin with. + * @return {[type]} [description] + */ + getNode(id, cancelBubble) { + if (!id) { + return undefined; + } + // console.log((new Error().stack).toString().split("\n").slice(1,3).join("\n")) + if ((this.flow.configs && this.flow.configs[id]) || (this.flow.nodes && this.flow.nodes[id])) { + // This is a node owned by this flow, so return whatever we have got + // During a stop/restart, activeNodes could be null for this id + return this.activeNodes[id]; + } else if (this.activeNodes[id]) { + // TEMP: this is a subflow internal node within this flow + return this.activeNodes[id]; + } else if (cancelBubble) { + // The node could be inside one of this flow's subflows + var node; + for (var sfId in this.subflowInstanceNodes) { + if (this.subflowInstanceNodes.hasOwnProperty(sfId)) { + node = this.subflowInstanceNodes[sfId].getNode(id,cancelBubble); + if (node) { + return node; + } + } + } + } else { + // Node not found inside this flow - ask the parent + return this.parent.getNode(id); + } + return undefined; + } + + /** + * Get all of the nodes instantiated within this flow + * @return {[type]} [description] + */ + getActiveNodes() { + return this.activeNodes; + } + + /** + * Get a flow setting value. This currently automatically defers to the parent + * flow which, as defined in ./index.js returns `process.env[key]`. + * This lays the groundwork for Subflow to have instance-specific settings + * @param {[type]} key [description] + * @return {[type]} [description] + */ + getSetting(key) { + return this.parent.getSetting(key); + } + + /** + * Handle a status event from a node within this flow. + * @param {Node} node The original node that triggered the event + * @param {Object} statusMessage The status object + * @param {Node} reportingNode The node emitting the status event. + * This could be a subflow instance node when the status + * is being delegated up. + * @param {boolean} muteStatusEvent Whether to emit the status event + * @return {[type]} [description] + */ + handleStatus(node,statusMessage,reportingNode,muteStatusEvent) { + if (!reportingNode) { + reportingNode = node; + } + if (!muteStatusEvent) { + events.emit("node-status",{ + id: node.id, + status:statusMessage + }); + } + + let handled = false; + + if (this.id === 'global' && node.users) { + // This is a global config node + // Delegate status to any nodes using this config node + for (let userNode in node.users) { + if (node.users.hasOwnProperty(userNode)) { + node.users[userNode]._flow.handleStatus(node,statusMessage,node.users[userNode],true); + } + } + handled = true; + } else { + this.statusNodes.forEach(function(targetStatusNode) { + if (targetStatusNode.scope && targetStatusNode.scope.indexOf(reportingNode.id) === -1) { + return; + } + var message = { + status: clone(statusMessage) + } + if (statusMessage.hasOwnProperty("text")) { + message.status.text = statusMessage.text.toString(); + } + message.status.source = { + id: node.id, + type: node.type, + name: node.name + } + + targetStatusNode.receive(message); + handled = true; + }); + } + return handled; + } + + /** + * Handle an error event from a node within this flow. If there are no Catch + * nodes within this flow, pass the event to the parent flow. + * @param {[type]} node [description] + * @param {[type]} logMessage [description] + * @param {[type]} msg [description] + * @param {[type]} reportingNode [description] + * @return {[type]} [description] + */ + handleError(node,logMessage,msg,reportingNode) { + if (!reportingNode) { + reportingNode = node; + } + // console.log("HE",logMessage); + var count = 1; + if (msg && msg.hasOwnProperty("error") && msg.error !== null) { + if (msg.error.hasOwnProperty("source") && msg.error.source !== null) { + if (msg.error.source.id === node.id) { + count = msg.error.source.count+1; + if (count === 10) { + node.warn(Log._("nodes.flow.error-loop")); + return false; + } + } + } + } + let handled = false; + + if (this.id === 'global' && node.users) { + // This is a global config node + // Delegate status to any nodes using this config node + for (let userNode in node.users) { + if (node.users.hasOwnProperty(userNode)) { + node.users[userNode]._flow.handleError(node,logMessage,msg,node.users[userNode]); + } + } + handled = true; + } else { + var handledByUncaught = false; + + this.catchNodes.forEach(function(targetCatchNode) { + if (targetCatchNode.scope && targetCatchNode.scope.indexOf(reportingNode.id) === -1) { + return; + } + if (!targetCatchNode.scope && targetCatchNode.uncaught && !handledByUncaught) { + if (handled) { + // This has been handled by a !uncaught catch node + return; + } + // This is an uncaught error + handledByUncaught = true; + } + var errorMessage; + if (msg) { + errorMessage = redUtil.cloneMessage(msg); + } else { + errorMessage = {}; + } + if (errorMessage.hasOwnProperty("error")) { + errorMessage._error = errorMessage.error; + } + errorMessage.error = { + message: logMessage.toString(), + source: { + id: node.id, + type: node.type, + name: node.name, + count: count + } + }; + if (logMessage.hasOwnProperty('stack')) { + errorMessage.error.stack = logMessage.stack; + } + targetCatchNode.receive(errorMessage); + handled = true; + }); + } + return handled; + } + + handleComplete(node,msg) { + if (this.completeNodeMap[node.id]) { + let toSend = msg; + this.completeNodeMap[node.id].forEach((completeNode,index) => { + toSend = redUtil.cloneMessage(msg); + completeNode.receive(toSend); + }) + } + } + + get asyncMessageDelivery() { + return asyncMessageDelivery + } + + dump() { + console.log("==================") + console.log(this.TYPE, this.id); + for (var id in this.activeNodes) { + if (this.activeNodes.hasOwnProperty(id)) { + var node = this.activeNodes[id]; + console.log(" ",id.padEnd(16),node.type) + if (node.wires) { + console.log(" -> ",node.wires) + } + } + } + console.log("==================") + } + +} + +/** + * Stop an individual node within this flow. + * + * @param {[type]} node [description] + * @param {[type]} removed [description] + * @return {[type]} [description] + */ +function stopNode(node,removed) { + Log.trace("Stopping node "+node.type+":"+node.id+(removed?" removed":"")); + const start = Date.now(); + const closePromise = node.close(removed); + const closeTimeout = new Promise((resolve,reject) => { + setTimeout(() => { + reject("Close timed out"); + }, nodeCloseTimeout); + }); + return Promise.race([closePromise,closeTimeout]).then(() => { + var delta = Date.now() - start; + Log.trace("Stopped node "+node.type+":"+node.id+" ("+delta+"ms)" ); + }).catch(err => { + node.error(Log._("nodes.flows.stopping-error",{message:err})); + Log.debug(err.stack); + }) +} + + +module.exports = { + init: function(runtime) { + nodeCloseTimeout = runtime.settings.nodeCloseTimeout || 15000; + asyncMessageDelivery = !runtime.settings.runtimeSyncDelivery + Log = runtime.log; + Subflow = require("./Subflow"); + Subflow.init(runtime); + }, + create: function(parent,global,conf) { + return new Flow(parent,global,conf); + }, + Flow: Flow +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/flows/Subflow.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/flows/Subflow.js new file mode 100644 index 0000000..a7bec12 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/flows/Subflow.js @@ -0,0 +1,518 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +const clone = require("clone"); +const Flow = require('./Flow').Flow; + +const util = require("util"); + +const redUtil = require("@node-red/util").util; +const flowUtil = require("./util"); + +var Log; + +/** + * Create deep copy of object + */ +function deepCopy(obj) { + return JSON.parse(JSON.stringify(obj)); +} + +/** + * Evaluate Input Value + */ +function evaluateInputValue(value, type, node) { + if (type === "bool") { + return (value === "true") || (value === true); + } + return redUtil.evaluateNodeProperty(value, type, node, null, null); +} + +/** + * Compose information object for env var + */ +function composeInfo(info, val) { + var result = { + name: info.name, + type: info.type, + value: val, + }; + if (info.ui) { + var ui = info.ui; + result.ui = { + hasUI: ui.hasUI, + icon: ui.icon, + labels: ui.labels, + type: ui.type + }; + var retUI = result.ui; + if (ui.type === "input") { + retUI.inputTypes = ui.inputTypes; + } + if (ui.type === "select") { + retUI.menu = ui.menu; + } + if (ui.type === "spinner") { + retUI.spinner = ui.spinner; + } + } + return result; +} + + +/** + * This class represents a subflow - which is handled as a special type of Flow + */ +class Subflow extends Flow { + + /** + * Create a Subflow object. + * This takes a subflow definition and instance node, creates a clone of the + * definition with unique ids applied and passes to the super class. + * @param {[type]} parent [description] + * @param {[type]} globalFlow [description] + * @param {[type]} subflowDef [description] + * @param {[type]} subflowInstance [description] + */ + constructor(parent,globalFlow,subflowDef,subflowInstance) { + // console.log("CREATE SUBFLOW",subflowDef.id,subflowInstance.id,"alias?",subflowInstance._alias); + // console.log("SubflowInstance\n"+JSON.stringify(subflowInstance," ",2)); + // console.log("SubflowDef\n"+JSON.stringify(subflowDef," ",2)); + var subflows = parent.flow.subflows; + var globalSubflows = parent.global.subflows; + + var node_map = {}; + var node; + var wires; + var i; + + var subflowInternalFlowConfig = { + id: subflowInstance.id, + configs: {}, + nodes: {}, + subflows: {} + } + + if (subflowDef.configs) { + // Clone all of the subflow config node definitions and give them new IDs + for (i in subflowDef.configs) { + if (subflowDef.configs.hasOwnProperty(i)) { + node = createNodeInSubflow(subflowInstance.id,subflowDef.configs[i]); + node_map[node._alias] = node; + subflowInternalFlowConfig.configs[node.id] = node; + } + } + } + if (subflowDef.nodes) { + // Clone all of the subflow node definitions and give them new IDs + for (i in subflowDef.nodes) { + if (subflowDef.nodes.hasOwnProperty(i)) { + node = createNodeInSubflow(subflowInstance.id,subflowDef.nodes[i]); + node_map[node._alias] = node; + subflowInternalFlowConfig.nodes[node.id] = node; + } + } + } + + subflowInternalFlowConfig.subflows = clone(subflowDef.subflows || {}); + + remapSubflowNodes(subflowInternalFlowConfig.configs,node_map); + remapSubflowNodes(subflowInternalFlowConfig.nodes,node_map); + + // console.log("Instance config\n",JSON.stringify(subflowInternalFlowConfig,"",2)); + + super(parent,globalFlow,subflowInternalFlowConfig); + + this.TYPE = 'subflow'; + this.subflowDef = subflowDef; + this.subflowInstance = subflowInstance; + this.node_map = node_map; + this.path = parent.path+"/"+(subflowInstance._alias||subflowInstance.id); + + var env = []; + if (this.subflowDef.env) { + this.subflowDef.env.forEach(e => { + env[e.name] = e; + }); + } + if (this.subflowInstance.env) { + this.subflowInstance.env.forEach(e => { + var old = env[e.name]; + var ui = old ? old.ui : null; + env[e.name] = e; + if (ui) { + env[e.name].ui = ui; + } + }); + } + this.env = env; + } + + /** + * Start the subflow. + * This creates a subflow instance node to handle the inbound messages. It also + * rewires an subflow internal node that is connected to an output so it is connected + * to the parent flow nodes the subflow instance is wired to. + * @param {[type]} diff [description] + * @return {[type]} [description] + */ + start(diff) { + var self = this; + // Create a subflow node to accept inbound messages and route appropriately + var Node = require("../Node"); + + if (this.subflowDef.status) { + var subflowStatusConfig = { + id: this.subflowInstance.id+":status", + type: "subflow-status", + z: this.subflowInstance.id, + _flow: this.parent + } + this.statusNode = new Node(subflowStatusConfig); + this.statusNode.on("input", function(msg) { + if (msg.payload !== undefined) { + if (typeof msg.payload === "string") { + // if msg.payload is a String, use it as status text + self.node.status({text:msg.payload}) + return; + } else if (Object.prototype.toString.call(msg.payload) === "[object Object]") { + if (msg.payload.hasOwnProperty('text') || msg.payload.hasOwnProperty('fill') || msg.payload.hasOwnProperty('shape') || Object.keys(msg.payload).length === 0) { + // msg.payload is an object that looks like a status object + self.node.status(msg.payload); + return; + } + } + // Anything else - inspect it and use as status text + var text = util.inspect(msg.payload); + if (text.length > 32) { text = text.substr(0,32) + "..."; } + self.node.status({text:text}); + } else if (msg.status !== undefined) { + // if msg.status exists + if (msg.status.hasOwnProperty("text") && msg.status.text.indexOf("common.") === 0) { + msg.status.text = "node-red:"+msg.status.text; + } + self.node.status(msg.status) + } + }) + } + + + var subflowInstanceConfig = { + id: this.subflowInstance.id, + type: this.subflowInstance.type, + z: this.subflowInstance.z, + name: this.subflowInstance.name, + wires: [], + _flow: this + } + if (this.subflowDef.in) { + subflowInstanceConfig.wires = this.subflowDef.in.map(function(n) { return n.wires.map(function(w) { return self.node_map[w.id].id;})}) + subflowInstanceConfig._originalWires = clone(subflowInstanceConfig.wires); + } + + this.node = new Node(subflowInstanceConfig); + this.node.on("input", function(msg) { this.send(msg);}); + this.node.on("close", function() { this.status({}); }) + this.node.status = status => this.parent.handleStatus(this.node,status); + + this.node._updateWires = this.node.updateWires; + + this.node.updateWires = function(newWires) { + // Wire the subflow outputs + if (self.subflowDef.out) { + var node,wires,i,j; + // Restore the original wiring to the internal nodes + subflowInstanceConfig.wires = clone(subflowInstanceConfig._originalWires); + for (i=0;i<self.subflowDef.out.length;i++) { + wires = self.subflowDef.out[i].wires; + for (j=0;j<wires.length;j++) { + if (wires[j].id != self.subflowDef.id) { + node = self.node_map[wires[j].id]; + if (node._originalWires) { + node.wires = clone(node._originalWires); + } + } + } + } + + var modifiedNodes = {}; + var subflowInstanceModified = false; + for (i=0;i<self.subflowDef.out.length;i++) { + wires = self.subflowDef.out[i].wires; + for (j=0;j<wires.length;j++) { + if (wires[j].id === self.subflowDef.id) { + subflowInstanceConfig.wires[wires[j].port] = subflowInstanceConfig.wires[wires[j].port].concat(newWires[i]); + subflowInstanceModified = true; + } else { + node = self.node_map[wires[j].id]; + node.wires[wires[j].port] = node.wires[wires[j].port].concat(newWires[i]); + modifiedNodes[node.id] = node; + } + } + } + Object.keys(modifiedNodes).forEach(function(id) { + var node = modifiedNodes[id]; + self.activeNodes[id].updateWires(node.wires); + }); + + if (subflowInstanceModified) { + self.node._updateWires(subflowInstanceConfig.wires); + } + } + }; + + // Wire the subflow outputs + if (this.subflowDef.out) { + for (var i=0;i<this.subflowDef.out.length;i++) { + // i: the output index + // This is what this Output is wired to + var wires = this.subflowDef.out[i].wires; + for (var j=0;j<wires.length;j++) { + if (wires[j].id === this.subflowDef.id) { + // A subflow input wired straight to a subflow output + subflowInstanceConfig.wires[wires[j].port] = subflowInstanceConfig.wires[wires[j].port].concat(this.subflowInstance.wires[i]) + this.node._updateWires(subflowInstanceConfig.wires); + } else { + var node = self.node_map[wires[j].id]; + if (!node._originalWires) { + node._originalWires = clone(node.wires); + } + node.wires[wires[j].port] = (node.wires[wires[j].port]||[]).concat(this.subflowInstance.wires[i]); + } + } + } + } + + if (this.subflowDef.status) { + var subflowStatusId = this.statusNode.id; + wires = this.subflowDef.status.wires; + for (var j=0;j<wires.length;j++) { + if (wires[j].id === this.subflowDef.id) { + // A subflow input wired straight to a subflow output + subflowInstanceConfig.wires[wires[j].port].push(subflowStatusId); + this.node._updateWires(subflowInstanceConfig.wires); + } else { + var node = self.node_map[wires[j].id]; + if (!node._originalWires) { + node._originalWires = clone(node.wires); + } + node.wires[wires[j].port] = (node.wires[wires[j].port]||[]); + node.wires[wires[j].port].push(subflowStatusId); + } + } + } + super.start(diff); + } + + + /** + * Get environment variable of subflow + * @param {String} name name of env var + * @return {Object} val value of env var + */ + getSetting(name) { + this.trace("getSetting:"+name); + if (!/^\$parent\./.test(name)) { + var env = this.env; + var is_info = name.endsWith("_info"); + var is_type = name.endsWith("_type"); + var ename = (is_info || is_type) ? name.substring(0, name.length -5) : name; // 5 = length of "_info"/"_type" + + if (env && env.hasOwnProperty(ename)) { + var val = env[ename]; + + if (is_type) { + return val ? val.type : undefined; + } + // If this is an env type property we need to be careful not + // to get into lookup loops. + // 1. if the value to lookup is the same as this one, go straight to parent + // 2. otherwise, check if it is a compound env var ("foo $(bar)") + // and if so, substitute any instances of `name` with $parent.name + // See https://github.com/node-red/node-red/issues/2099 + if (val.type !== 'env' || val.value !== name) { + let value = val.value; + var type = val.type; + if (type === 'env') { + value = value.replace(new RegExp("\\${"+name+"}","g"),"${$parent."+name+"}"); + } + try { + var ret = evaluateInputValue(value, type, this.node); + if (is_info) { + return composeInfo(val, ret); + } + return ret; + } + catch (e) { + this.error(e); + return undefined; + } + } else { + // This _is_ an env property pointing at itself - go to parent + } + } + } else { + // name starts $parent. ... so delegate to parent automatically + name = name.substring(8); + } + var parent = this.parent; + if (parent) { + var val = parent.getSetting(name); + return val; + } + return undefined; + } + + /** + * Get a node instance from this subflow. + * If the subflow has a status node, check for that, otherwise use + * the super-class function + * @param {String} id [description] + * @param {Boolean} cancelBubble if true, prevents the flow from passing the request to the parent + * This stops infinite loops when the parent asked this Flow for the + * node to begin with. + * @return {[type]} [description] + */ + getNode(id, cancelBubble) { + if (this.statusNode && this.statusNode.id === id) { + return this.statusNode; + } + return super.getNode(id,cancelBubble); + } + + /** + * Handle a status event from a node within this flow. + * @param {Node} node The original node that triggered the event + * @param {Object} statusMessage The status object + * @param {Node} reportingNode The node emitting the status event. + * This could be a subflow instance node when the status + * is being delegated up. + * @param {boolean} muteStatus Whether to emit the status event + * @return {[type]} [description] + */ + handleStatus(node,statusMessage,reportingNode,muteStatus) { + let handled = super.handleStatus(node,statusMessage,reportingNode,muteStatus); + if (!handled) { + if (!this.statusNode || node === this.node) { + // No status node on this subflow caught the status message. + // AND there is no Subflow Status node - so the user isn't + // wanting to manage status messages themselves + // Pass up to the parent with this subflow's instance as the + // reporting node + handled = this.parent.handleStatus(node,statusMessage,this.node,true); + } + } + return handled; + + } + + /** + * Handle an error event from a node within this flow. If there are no Catch + * nodes within this flow, pass the event to the parent flow. + * @param {[type]} node [description] + * @param {[type]} logMessage [description] + * @param {[type]} msg [description] + * @param {[type]} reportingNode [description] + * @return {[type]} [description] + */ + handleError(node,logMessage,msg,reportingNode) { + let handled = super.handleError(node,logMessage,msg,reportingNode); + if (!handled) { + // No catch node on this subflow caught the error message. + // Pass up to the parent with the subflow's instance as the + // reporting node. + handled = this.parent.handleError(node,logMessage,msg,this.node); + } + return handled; + } +} + + +/** + * Clone a node definition for use within a subflow instance. + * Give the node a new id and set its _alias property to record + * its association with the original node definition. + * @param {[type]} subflowInstanceId [description] + * @param {[type]} def [description] + * @return {[type]} [description] + */ +function createNodeInSubflow(subflowInstanceId, def) { + let node = clone(def); + let nid = redUtil.generateId(); + // console.log("Create Node In subflow",node._alias, "--->",nid, "(",node.type,")") + // node_map[node.id] = node; + node._alias = node.id; + node.id = nid; + node.z = subflowInstanceId; + return node; +} + + +/** + * Given an object of {id:nodes} and a map of {old-id:node}, modifiy all + * properties in the nodes object to reference the new node ids. + * This handles: + * - node.wires, + * - node.scope of Catch and Status nodes, + * - node.XYZ for any property where XYZ is recognised as an old property + * @param {[type]} nodes [description] + * @param {[type]} nodeMap [description] + * @return {[type]} [description] + */ +function remapSubflowNodes(nodes,nodeMap) { + for (var id in nodes) { + if (nodes.hasOwnProperty(id)) { + var node = nodes[id]; + if (node.wires) { + var outputs = node.wires; + for (j=0;j<outputs.length;j++) { + wires = outputs[j]; + for (k=0;k<wires.length;k++) { + if (nodeMap[outputs[j][k]]) { + outputs[j][k] = nodeMap[outputs[j][k]].id + } else { + outputs[j][k] = null; + } + } + } + } + if ((node.type === 'catch' || node.type === 'status') && node.scope) { + node.scope = node.scope.map(function(id) { + return nodeMap[id]?nodeMap[id].id:"" + }) + } else { + for (var prop in node) { + if (node.hasOwnProperty(prop) && prop !== '_alias') { + if (nodeMap[node[prop]]) { + node[prop] = nodeMap[node[prop]].id; + } + } + } + } + } + } +} + +function createSubflow(parent,globalFlow,subflowDef,subflowInstance) { + return new Subflow(parent,globalFlow,subflowDef,subflowInstance) +} + +module.exports = { + init: function(runtime) { + Log = runtime.log; + }, + create: createSubflow +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/flows/index.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/flows/index.js new file mode 100644 index 0000000..16166fb --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/flows/index.js @@ -0,0 +1,754 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var clone = require("clone"); +var when = require("when"); + +var Flow = require('./Flow'); + +var typeRegistry = require("@node-red/registry"); +var deprecated = typeRegistry.deprecated; + + +var context = require("../context") +var credentials = require("../credentials"); + +var flowUtil = require("./util"); +var log; +var events = require("../../events"); +var redUtil = require("@node-red/util").util; + +var storage = null; +var settings = null; + +var activeConfig = null; +var activeFlowConfig = null; + +var activeFlows = {}; +var started = false; +var credentialsPendingReset = false; + +var activeNodesToFlow = {}; + +var typeEventRegistered = false; + +function init(runtime) { + if (started) { + throw new Error("Cannot init without a stop"); + } + settings = runtime.settings; + storage = runtime.storage; + log = runtime.log; + started = false; + if (!typeEventRegistered) { + events.on('type-registered',function(type) { + if (activeFlowConfig && activeFlowConfig.missingTypes.length > 0) { + var i = activeFlowConfig.missingTypes.indexOf(type); + if (i != -1) { + log.info(log._("nodes.flows.registered-missing", {type:type})); + activeFlowConfig.missingTypes.splice(i,1); + if (activeFlowConfig.missingTypes.length === 0 && started) { + events.emit("runtime-event",{id:"runtime-state",retain: true}); + start(); + } + } + } + }); + typeEventRegistered = true; + } + Flow.init(runtime); + flowUtil.init(runtime); +} + +function loadFlows() { + var config; + return storage.getFlows().then(function(_config) { + config = _config; + log.debug("loaded flow revision: "+config.rev); + return credentials.load(config.credentials).then(function() { + events.emit("runtime-event",{id:"runtime-state",retain:true}); + return config; + }); + }).catch(function(err) { + if (err.code === "credentials_load_failed" && !storage.projects) { + // project disabled, credential load failed + credentialsPendingReset = true; + log.warn(log._("nodes.flows.error",{message:err.toString()})); + events.emit("runtime-event",{id:"runtime-state",payload:{type:"warning",error:err.code,text:"notification.warnings.credentials_load_failed_reset"},retain:true}); + return config; + } else { + activeConfig = null; + events.emit("runtime-event",{id:"runtime-state",payload:{type:"warning",error:err.code,project:err.project,text:"notification.warnings."+err.code},retain:true}); + if (err.code === "project_not_found") { + log.warn(log._("storage.localfilesystem.projects.project-not-found",{project:err.project})); + } else { + log.warn(log._("nodes.flows.error",{message:err.toString()})); + } + throw err; + } + }); +} +function load(forceStart) { + if (forceStart && settings.safeMode) { + // This is a force reload from the API - disable safeMode + delete settings.safeMode; + } + return setFlows(null,null,"load",false,forceStart); +} + +/* + * _config - new node array configuration + * _credentials - new credentials configuration (optional) + * type - full/nodes/flows/load (default full) + * muteLog - don't emit the standard log messages (used for individual flow api) + */ +function setFlows(_config,_credentials,type,muteLog,forceStart) { + if (typeof _credentials === "string") { + type = _credentials; + _credentials = null; + } + type = type||"full"; + if (settings.safeMode) { + if (type !== "load") { + // If in safeMode, the flows are stopped. We cannot do a modified nodes/flows + // type deploy as nothing is running. Can only do a "load" or "full" deploy. + // The "load" case is already handled in `load()` to distinguish between + // startup-load and api-request-load. + type = "full"; + delete settings.safeMode; + } + } + + var configSavePromise = null; + var config = null; + var diff; + var newFlowConfig; + var isLoad = false; + if (type === "load") { + isLoad = true; + configSavePromise = loadFlows().then(function(_config) { + config = clone(_config.flows); + newFlowConfig = flowUtil.parseConfig(clone(config)); + type = "full"; + return _config.rev; + }); + } else { + // Clone the provided config so it can be manipulated + config = clone(_config); + // Parse the configuration + newFlowConfig = flowUtil.parseConfig(clone(config)); + // Generate a diff to identify what has changed + diff = flowUtil.diffConfigs(activeFlowConfig,newFlowConfig); + + // Now the flows have been compared, remove any credentials from newFlowConfig + // so they don't cause false-positive diffs the next time a flow is deployed + for (var id in newFlowConfig.allNodes) { + if (newFlowConfig.allNodes.hasOwnProperty(id)) { + delete newFlowConfig.allNodes[id].credentials; + } + } + var credsDirty; + + if (_credentials) { + // A full set of credentials have been provided. Use those instead + configSavePromise = credentials.load(_credentials); + credsDirty = true; + } else { + // Allow the credential store to remove anything no longer needed + credentials.clean(config); + + // Remember whether credentials need saving or not + var credsDirty = credentials.dirty(); + + configSavePromise = Promise.resolve(); + } + + // Get the latest credentials and ask storage to save them (if needed) + // as well as the new flow configuration. + configSavePromise = configSavePromise.then(function() { + return credentials.export() + }).then(function(creds) { + var saveConfig = { + flows: config, + credentialsDirty:credsDirty, + credentials: creds + } + return storage.saveFlows(saveConfig); + }); + } + + return configSavePromise + .then(function(flowRevision) { + if (!isLoad) { + log.debug("saved flow revision: "+flowRevision); + } + activeConfig = { + flows:config, + rev:flowRevision + }; + activeFlowConfig = newFlowConfig; + if (forceStart || started) { + // Flows are running (or should be) + + // Stop the active flows (according to deploy type and the diff) + return stop(type,diff,muteLog).then(() => { + // Once stopped, allow context to remove anything no longer needed + return context.clean(activeFlowConfig) + }).then(() => { + // Start the active flows + start(type,diff,muteLog).then(() => { + events.emit("runtime-event",{id:"runtime-deploy",payload:{revision:flowRevision},retain: true}); + }); + // Return the new revision asynchronously to the actual start + return flowRevision; + }).catch(function(err) { }) + } else { + events.emit("runtime-event",{id:"runtime-deploy",payload:{revision:flowRevision},retain: true}); + } + }); +} + +function getNode(id) { + var node; + if (activeNodesToFlow[id] && activeFlows[activeNodesToFlow[id]]) { + return activeFlows[activeNodesToFlow[id]].getNode(id,true); + } + for (var flowId in activeFlows) { + if (activeFlows.hasOwnProperty(flowId)) { + node = activeFlows[flowId].getNode(id,true); + if (node) { + return node; + } + } + } + return null; +} + +function eachNode(cb) { + for (var id in activeFlowConfig.allNodes) { + if (activeFlowConfig.allNodes.hasOwnProperty(id)) { + cb(activeFlowConfig.allNodes[id]); + } + } +} + +function getFlows() { + return activeConfig; +} + +function start(type,diff,muteLog) { + type = type||"full"; + started = true; + var i; + // If there are missing types, report them, emit the necessary runtime event and return + if (activeFlowConfig.missingTypes.length > 0) { + log.info(log._("nodes.flows.missing-types")); + var knownUnknowns = 0; + for (i=0;i<activeFlowConfig.missingTypes.length;i++) { + var nodeType = activeFlowConfig.missingTypes[i]; + var info = deprecated.get(nodeType); + if (info) { + log.info(log._("nodes.flows.missing-type-provided",{type:activeFlowConfig.missingTypes[i],module:info.module})); + knownUnknowns += 1; + } else { + log.info(" - "+activeFlowConfig.missingTypes[i]); + } + } + if (knownUnknowns > 0) { + log.info(log._("nodes.flows.missing-type-install-1")); + log.info(" npm install <module name>"); + log.info(log._("nodes.flows.missing-type-install-2")); + log.info(" "+settings.userDir); + } + events.emit("runtime-event",{id:"runtime-state",payload:{error:"missing-types", type:"warning",text:"notification.warnings.missing-types",types:activeFlowConfig.missingTypes},retain:true}); + return Promise.resolve(); + } + + // In safe mode, don't actually start anything, emit the necessary runtime event and return + if (settings.safeMode) { + log.info("*****************************************************************") + log.info(log._("nodes.flows.safe-mode")); + log.info("*****************************************************************") + events.emit("runtime-event",{id:"runtime-state",payload:{error:"safe-mode", type:"warning",text:"notification.warnings.safe-mode"},retain:true}); + return Promise.resolve(); + } + + if (!muteLog) { + if (type !== "full") { + log.info(log._("nodes.flows.starting-modified-"+type)); + } else { + log.info(log._("nodes.flows.starting-flows")); + } + } + + var id; + if (type === "full") { + // A full start means everything should + + // Check the 'global' flow is running + if (!activeFlows['global']) { + log.debug("red/nodes/flows.start : starting flow : global"); + activeFlows['global'] = Flow.create(flowAPI,activeFlowConfig); + } + + // Check each flow in the active configuration + for (id in activeFlowConfig.flows) { + if (activeFlowConfig.flows.hasOwnProperty(id)) { + if (!activeFlowConfig.flows[id].disabled && !activeFlows[id]) { + // This flow is not disabled, nor is it currently active, so create it + activeFlows[id] = Flow.create(flowAPI,activeFlowConfig,activeFlowConfig.flows[id]); + log.debug("red/nodes/flows.start : starting flow : "+id); + } else { + log.debug("red/nodes/flows.start : not starting disabled flow : "+id); + } + } + } + } else { + // A modified-type deploy means restarting things that have changed + + // Update the global flow + activeFlows['global'].update(activeFlowConfig,activeFlowConfig); + for (id in activeFlowConfig.flows) { + if (activeFlowConfig.flows.hasOwnProperty(id)) { + if (!activeFlowConfig.flows[id].disabled) { + if (activeFlows[id]) { + // This flow exists and is not disabled, so update it + activeFlows[id].update(activeFlowConfig,activeFlowConfig.flows[id]); + } else { + // This flow didn't previously exist, so create it + activeFlows[id] = Flow.create(flowAPI,activeFlowConfig,activeFlowConfig.flows[id]); + log.debug("red/nodes/flows.start : starting flow : "+id); + } + } else { + log.debug("red/nodes/flows.start : not starting disabled flow : "+id); + } + } + } + } + // Having created or updated all flows, now start them. + for (id in activeFlows) { + if (activeFlows.hasOwnProperty(id)) { + try { + activeFlows[id].start(diff); + + // Create a map of node id to flow id and also a subflowInstance lookup map + var activeNodes = activeFlows[id].getActiveNodes(); + Object.keys(activeNodes).forEach(function(nid) { + activeNodesToFlow[nid] = id; + }); + } catch(err) { + console.log(err.stack); + } + } + } + events.emit("nodes-started"); + + if (credentialsPendingReset === true) { + credentialsPendingReset = false; + } else { + events.emit("runtime-event",{id:"runtime-state",retain:true}); + } + + if (!muteLog) { + if (type !== "full") { + log.info(log._("nodes.flows.started-modified-"+type)); + } else { + log.info(log._("nodes.flows.started-flows")); + } + } + return Promise.resolve(); +} + +function stop(type,diff,muteLog) { + if (!started) { + return Promise.resolve(); + } + type = type||"full"; + diff = diff||{ + added:[], + changed:[], + removed:[], + rewired:[], + linked:[] + }; + if (!muteLog) { + if (type !== "full") { + log.info(log._("nodes.flows.stopping-modified-"+type)); + } else { + log.info(log._("nodes.flows.stopping-flows")); + } + } + started = false; + var promises = []; + var stopList; + var removedList = diff.removed; + if (type === 'nodes') { + stopList = diff.changed.concat(diff.removed); + } else if (type === 'flows') { + stopList = diff.changed.concat(diff.removed).concat(diff.linked); + } + + for (var id in activeFlows) { + if (activeFlows.hasOwnProperty(id)) { + var flowStateChanged = diff && (diff.added.indexOf(id) !== -1 || diff.removed.indexOf(id) !== -1); + log.debug("red/nodes/flows.stop : stopping flow : "+id); + promises.push(activeFlows[id].stop(flowStateChanged?null:stopList,removedList)); + if (type === "full" || flowStateChanged || diff.removed.indexOf(id)!==-1) { + delete activeFlows[id]; + } + } + } + + return Promise.all(promises).then(function() { + for (id in activeNodesToFlow) { + if (activeNodesToFlow.hasOwnProperty(id)) { + if (!activeFlows[activeNodesToFlow[id]]) { + delete activeNodesToFlow[id]; + } + } + } + if (stopList) { + stopList.forEach(function(id) { + delete activeNodesToFlow[id]; + }); + } + if (!muteLog) { + if (type !== "full") { + log.info(log._("nodes.flows.stopped-modified-"+type)); + } else { + log.info(log._("nodes.flows.stopped-flows")); + } + } + events.emit("nodes-stopped"); + }); +} + + +function checkTypeInUse(id) { + var nodeInfo = typeRegistry.getNodeInfo(id); + if (!nodeInfo) { + throw new Error(log._("nodes.index.unrecognised-id", {id:id})); + } else { + var inUse = {}; + var config = getFlows(); + config.flows.forEach(function(n) { + inUse[n.type] = (inUse[n.type]||0)+1; + }); + var nodesInUse = []; + nodeInfo.types.forEach(function(t) { + if (inUse[t]) { + nodesInUse.push(t); + } + }); + if (nodesInUse.length > 0) { + var msg = nodesInUse.join(", "); + var err = new Error(log._("nodes.index.type-in-use", {msg:msg})); + err.code = "type_in_use"; + throw err; + } + } +} + +function updateMissingTypes() { + var subflowInstanceRE = /^subflow:(.+)$/; + activeFlowConfig.missingTypes = []; + + for (var id in activeFlowConfig.allNodes) { + if (activeFlowConfig.allNodes.hasOwnProperty(id)) { + var node = activeFlowConfig.allNodes[id]; + if (node.type !== 'tab' && node.type !== 'subflow') { + var subflowDetails = subflowInstanceRE.exec(node.type); + if ( (subflowDetails && !activeFlowConfig.subflows[subflowDetails[1]]) || (!subflowDetails && !typeRegistry.get(node.type)) ) { + if (activeFlowConfig.missingTypes.indexOf(node.type) === -1) { + activeFlowConfig.missingTypes.push(node.type); + } + } + } + } + } +} + +function addFlow(flow) { + var i,node; + if (!flow.hasOwnProperty('nodes')) { + throw new Error('missing nodes property'); + } + flow.id = redUtil.generateId(); + + var tabNode = { + type:'tab', + label:flow.label, + id:flow.id + } + if (flow.hasOwnProperty('info')) { + tabNode.info = flow.info; + } + if (flow.hasOwnProperty('disabled')) { + tabNode.disabled = flow.disabled; + } + + var nodes = [tabNode]; + + for (i=0;i<flow.nodes.length;i++) { + node = flow.nodes[i]; + if (activeFlowConfig.allNodes[node.id]) { + // TODO nls + return when.reject(new Error('duplicate id')); + } + if (node.type === 'tab' || node.type === 'subflow') { + return when.reject(new Error('invalid node type: '+node.type)); + } + node.z = flow.id; + nodes.push(node); + } + if (flow.configs) { + for (i=0;i<flow.configs.length;i++) { + node = flow.configs[i]; + if (activeFlowConfig.allNodes[node.id]) { + // TODO nls + return when.reject(new Error('duplicate id')); + } + if (node.type === 'tab' || node.type === 'subflow') { + return when.reject(new Error('invalid node type: '+node.type)); + } + node.z = flow.id; + nodes.push(node); + } + } + var newConfig = clone(activeConfig.flows); + newConfig = newConfig.concat(nodes); + + return setFlows(newConfig,null,'flows',true).then(function() { + log.info(log._("nodes.flows.added-flow",{label:(flow.label?flow.label+" ":"")+"["+flow.id+"]"})); + return flow.id; + }); +} + +function getFlow(id) { + var flow; + if (id === 'global') { + flow = activeFlowConfig; + } else { + flow = activeFlowConfig.flows[id]; + } + if (!flow) { + return null; + } + var result = { + id: id + }; + if (flow.label) { + result.label = flow.label; + } + if (flow.disabled) { + result.disabled = flow.disabled; + } + if (flow.hasOwnProperty('info')) { + result.info = flow.info; + } + if (id !== 'global') { + result.nodes = []; + } + if (flow.nodes) { + var nodeIds = Object.keys(flow.nodes); + if (nodeIds.length > 0) { + result.nodes = nodeIds.map(function(nodeId) { + var node = clone(flow.nodes[nodeId]); + if (node.type === 'link out') { + delete node.wires; + } + return node; + }) + } + } + if (flow.configs) { + var configIds = Object.keys(flow.configs); + result.configs = configIds.map(function(configId) { + return clone(flow.configs[configId]); + }) + if (result.configs.length === 0) { + delete result.configs; + } + } + if (flow.subflows) { + var subflowIds = Object.keys(flow.subflows); + result.subflows = subflowIds.map(function(subflowId) { + var subflow = clone(flow.subflows[subflowId]); + var nodeIds = Object.keys(subflow.nodes); + subflow.nodes = nodeIds.map(function(id) { + return subflow.nodes[id]; + }); + if (subflow.configs) { + var configIds = Object.keys(subflow.configs); + subflow.configs = configIds.map(function(id) { + return subflow.configs[id]; + }) + } + delete subflow.instances; + return subflow; + }); + if (result.subflows.length === 0) { + delete result.subflows; + } + } + return result; +} + +function updateFlow(id,newFlow) { + var label = id; + if (id !== 'global') { + if (!activeFlowConfig.flows[id]) { + var e = new Error(); + e.code = 404; + throw e; + } + label = activeFlowConfig.flows[id].label; + } + var newConfig = clone(activeConfig.flows); + var nodes; + + if (id === 'global') { + // Remove all nodes whose z is not a known flow + // When subflows can be owned by a flow, this logic will have to take + // that into account + newConfig = newConfig.filter(function(node) { + return node.type === 'tab' || (node.hasOwnProperty('z') && activeFlowConfig.flows.hasOwnProperty(node.z)); + }) + + // Add in the new config nodes + nodes = newFlow.configs||[]; + if (newFlow.subflows) { + // Add in the new subflows + newFlow.subflows.forEach(function(sf) { + nodes = nodes.concat(sf.nodes||[]).concat(sf.configs||[]); + delete sf.nodes; + delete sf.configs; + nodes.push(sf); + }); + } + } else { + newConfig = newConfig.filter(function(node) { + return node.z !== id && node.id !== id; + }); + var tabNode = { + type:'tab', + label:newFlow.label, + id:id + } + if (newFlow.hasOwnProperty('info')) { + tabNode.info = newFlow.info; + } + if (newFlow.hasOwnProperty('disabled')) { + tabNode.disabled = newFlow.disabled; + } + + nodes = [tabNode].concat(newFlow.nodes||[]).concat(newFlow.configs||[]); + nodes.forEach(function(n) { + n.z = id; + }); + } + + newConfig = newConfig.concat(nodes); + return setFlows(newConfig,null,'flows',true).then(function() { + log.info(log._("nodes.flows.updated-flow",{label:(label?label+" ":"")+"["+id+"]"})); + }) +} + +function removeFlow(id) { + if (id === 'global') { + // TODO: nls + error code + throw new Error('not allowed to remove global'); + } + var flow = activeFlowConfig.flows[id]; + if (!flow) { + var e = new Error(); + e.code = 404; + throw e; + } + + var newConfig = clone(activeConfig.flows); + newConfig = newConfig.filter(function(node) { + return node.z !== id && node.id !== id; + }); + + return setFlows(newConfig,null,'flows',true).then(function() { + log.info(log._("nodes.flows.removed-flow",{label:(flow.label?flow.label+" ":"")+"["+flow.id+"]"})); + }); +} + +const flowAPI = { + getNode: getNode, + handleError: () => false, + handleStatus: () => false, + getSetting: k => flowUtil.getEnvVar(k) +} + + +module.exports = { + init: init, + + /** + * Load the current flow configuration from storage + * @return a promise for the loading of the config + */ + load: load, + + get:getNode, + eachNode: eachNode, + + /** + * Gets the current flow configuration + */ + getFlows: getFlows, + + /** + * Sets the current active config. + * @param config the configuration to enable + * @param type the type of deployment to do: full (default), nodes, flows, load + * @return a promise for the saving/starting of the new flow + */ + setFlows: setFlows, + + /** + * Starts the current flow configuration + */ + startFlows: start, + + /** + * Stops the current flow configuration + * @return a promise for the stopping of the flow + */ + stopFlows: stop, + + get started() { return started }, + + // handleError: handleError, + // handleStatus: handleStatus, + + checkTypeInUse: checkTypeInUse, + + addFlow: addFlow, + getFlow: getFlow, + updateFlow: updateFlow, + removeFlow: removeFlow, + disableFlow:null, + enableFlow:null, + isDeliveryModeAsync: function() { + // If settings is null, this is likely being run by unit tests + return !settings || !settings.runtimeSyncDelivery + } + +}; diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/flows/util.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/flows/util.js new file mode 100644 index 0000000..b6074d7 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/flows/util.js @@ -0,0 +1,500 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +var clone = require("clone"); +var redUtil = require("@node-red/util").util; +var Log = require("@node-red/util").log; +var subflowInstanceRE = /^subflow:(.+)$/; +var typeRegistry = require("@node-red/registry"); + +var envVarExcludes = {}; + +function diffNodes(oldNode,newNode) { + if (oldNode == null) { + return true; + } + var oldKeys = Object.keys(oldNode).filter(function(p) { return p != "x" && p != "y" && p != "wires" }); + var newKeys = Object.keys(newNode).filter(function(p) { return p != "x" && p != "y" && p != "wires" }); + if (oldKeys.length != newKeys.length) { + return true; + } + for (var i=0;i<newKeys.length;i++) { + var p = newKeys[i]; + if (!redUtil.compareObjects(oldNode[p],newNode[p])) { + return true; + } + } + + return false; +} + +var EnvVarPropertyRE_old = /^\$\((\S+)\)$/; +var EnvVarPropertyRE = /^\${(\S+)}$/; + +function mapEnvVarProperties(obj,prop,flow) { + var v = obj[prop]; + if (Buffer.isBuffer(v)) { + return; + } else if (Array.isArray(v)) { + for (var i=0;i<v.length;i++) { + mapEnvVarProperties(v,i,flow); + } + } else if (typeof obj[prop] === 'string') { + if (obj[prop][0] === "$" && (EnvVarPropertyRE_old.test(v) || EnvVarPropertyRE.test(v)) ) { + var envVar = v.substring(2,v.length-1); + var r = flow.getSetting(envVar); + obj[prop] = r!==undefined?r:obj[prop]; + } + } else { + for (var p in v) { + if (v.hasOwnProperty(p)) { + mapEnvVarProperties(v,p,flow); + } + } + } +} + +module.exports = { + init: function(runtime) { + envVarExcludes = {}; + if (runtime.settings.hasOwnProperty('envVarExcludes') && Array.isArray(runtime.settings.envVarExcludes)) { + runtime.settings.envVarExcludes.forEach(v => envVarExcludes[v] = true); + } + }, + getEnvVar: function(k) { + return !envVarExcludes[k]?process.env[k]:undefined + }, + diffNodes: diffNodes, + mapEnvVarProperties: mapEnvVarProperties, + + parseConfig: function(config) { + var flow = {}; + flow.allNodes = {}; + flow.subflows = {}; + flow.configs = {}; + flow.flows = {}; + flow.missingTypes = []; + + config.forEach(function(n) { + flow.allNodes[n.id] = clone(n); + if (n.type === 'tab') { + flow.flows[n.id] = n; + flow.flows[n.id].subflows = {}; + flow.flows[n.id].configs = {}; + flow.flows[n.id].nodes = {}; + } + }); + + config.forEach(function(n) { + if (n.type === 'subflow') { + flow.subflows[n.id] = n; + flow.subflows[n.id].configs = {}; + flow.subflows[n.id].nodes = {}; + flow.subflows[n.id].instances = []; + } + }); + var linkWires = {}; + var linkOutNodes = []; + config.forEach(function(n) { + if (n.type !== 'subflow' && n.type !== 'tab') { + var subflowDetails = subflowInstanceRE.exec(n.type); + + if ( (subflowDetails && !flow.subflows[subflowDetails[1]]) || (!subflowDetails && !typeRegistry.get(n.type)) ) { + if (flow.missingTypes.indexOf(n.type) === -1) { + flow.missingTypes.push(n.type); + } + } + var container = null; + if (flow.flows[n.z]) { + container = flow.flows[n.z]; + } else if (flow.subflows[n.z]) { + container = flow.subflows[n.z]; + } + if (n.hasOwnProperty('x') && n.hasOwnProperty('y')) { + if (subflowDetails) { + var subflowType = subflowDetails[1] + n.subflow = subflowType; + flow.subflows[subflowType].instances.push(n) + } + if (container) { + container.nodes[n.id] = n; + } + } else { + if (container) { + container.configs[n.id] = n; + } else { + flow.configs[n.id] = n; + flow.configs[n.id]._users = []; + } + } + if (n.type === 'link in' && n.links) { + // Ensure wires are present in corresponding link out nodes + n.links.forEach(function(id) { + linkWires[id] = linkWires[id]||{}; + linkWires[id][n.id] = true; + }) + } else if (n.type === 'link out' && n.links) { + linkWires[n.id] = linkWires[n.id]||{}; + n.links.forEach(function(id) { + linkWires[n.id][id] = true; + }) + linkOutNodes.push(n); + } + } + }); + linkOutNodes.forEach(function(n) { + var links = linkWires[n.id]; + var targets = Object.keys(links); + n.wires = [targets]; + }); + + + var addedTabs = {}; + config.forEach(function(n) { + if (n.type !== 'subflow' && n.type !== 'tab') { + for (var prop in n) { + if (n.hasOwnProperty(prop) && prop !== 'id' && prop !== 'wires' && prop !== 'type' && prop !== '_users' && flow.configs.hasOwnProperty(n[prop])) { + // This property references a global config node + flow.configs[n[prop]]._users.push(n.id) + } + } + if (n.z && !flow.subflows[n.z]) { + + if (!flow.flows[n.z]) { + flow.flows[n.z] = {type:'tab',id:n.z}; + flow.flows[n.z].subflows = {}; + flow.flows[n.z].configs = {}; + flow.flows[n.z].nodes = {}; + addedTabs[n.z] = flow.flows[n.z]; + } + if (addedTabs[n.z]) { + if (n.hasOwnProperty('x') && n.hasOwnProperty('y')) { + addedTabs[n.z].nodes[n.id] = n; + } else { + addedTabs[n.z].configs[n.id] = n; + } + } + } + } + }); + return flow; + }, + + diffConfigs: function(oldConfig, newConfig) { + var id; + var node; + var nn; + var wires; + var j,k; + + if (!oldConfig) { + oldConfig = { + flows:{}, + allNodes:{} + } + } + var changedSubflows = {}; + + var added = {}; + var removed = {}; + var changed = {}; + var wiringChanged = {}; + + var linkMap = {}; + + var changedTabs = {}; + + // Look for tabs that have been removed + for (id in oldConfig.flows) { + if (oldConfig.flows.hasOwnProperty(id) && (!newConfig.flows.hasOwnProperty(id))) { + removed[id] = oldConfig.allNodes[id]; + } + } + + // Look for tabs that have been disabled + for (id in oldConfig.flows) { + if (oldConfig.flows.hasOwnProperty(id) && newConfig.flows.hasOwnProperty(id)) { + var originalState = oldConfig.flows[id].disabled||false; + var newState = newConfig.flows[id].disabled||false; + if (originalState !== newState) { + changedTabs[id] = true; + if (originalState) { + added[id] = oldConfig.allNodes[id]; + } else { + removed[id] = oldConfig.allNodes[id]; + } + } + } + } + + for (id in oldConfig.allNodes) { + if (oldConfig.allNodes.hasOwnProperty(id)) { + node = oldConfig.allNodes[id]; + if (node.type !== 'tab') { + // build the map of what this node was previously wired to + if (node.wires) { + linkMap[node.id] = linkMap[node.id] || []; + for (j=0;j<node.wires.length;j++) { + wires = node.wires[j]; + for (k=0;k<wires.length;k++) { + linkMap[node.id].push(wires[k]); + nn = oldConfig.allNodes[wires[k]]; + if (nn) { + linkMap[nn.id] = linkMap[nn.id] || []; + linkMap[nn.id].push(node.id); + } + } + } + } + // This node has been removed + if (removed[node.z] || !newConfig.allNodes.hasOwnProperty(id)) { + removed[id] = node; + // Mark the container as changed + if (!removed[node.z] && newConfig.allNodes[removed[id].z]) { + changed[removed[id].z] = newConfig.allNodes[removed[id].z]; + if (changed[removed[id].z].type === "subflow") { + changedSubflows[removed[id].z] = changed[removed[id].z]; + //delete removed[id]; + } + } + } else { + if (added[node.z]) { + added[id] = node; + } else { + // This node has a material configuration change + if (diffNodes(node,newConfig.allNodes[id]) || newConfig.allNodes[id].credentials) { + changed[id] = newConfig.allNodes[id]; + if (changed[id].type === "subflow") { + changedSubflows[id] = changed[id]; + } + // Mark the container as changed + if (newConfig.allNodes[changed[id].z]) { + changed[changed[id].z] = newConfig.allNodes[changed[id].z]; + if (changed[changed[id].z].type === "subflow") { + changedSubflows[changed[id].z] = changed[changed[id].z]; + delete changed[id]; + } + } + } + // This node's wiring has changed + if (!redUtil.compareObjects(node.wires,newConfig.allNodes[id].wires)) { + wiringChanged[id] = newConfig.allNodes[id]; + // Mark the container as changed + if (newConfig.allNodes[wiringChanged[id].z]) { + changed[wiringChanged[id].z] = newConfig.allNodes[wiringChanged[id].z]; + if (changed[wiringChanged[id].z].type === "subflow") { + changedSubflows[wiringChanged[id].z] = changed[wiringChanged[id].z]; + delete wiringChanged[id]; + } + } + } + } + } + } + } + } + // Look for added nodes + for (id in newConfig.allNodes) { + if (newConfig.allNodes.hasOwnProperty(id)) { + node = newConfig.allNodes[id]; + // build the map of what this node is now wired to + if (node.wires) { + linkMap[node.id] = linkMap[node.id] || []; + for (j=0;j<node.wires.length;j++) { + wires = node.wires[j]; + for (k=0;k<wires.length;k++) { + if (linkMap[node.id].indexOf(wires[k]) === -1) { + linkMap[node.id].push(wires[k]); + } + nn = newConfig.allNodes[wires[k]]; + if (nn) { + linkMap[nn.id] = linkMap[nn.id] || []; + if (linkMap[nn.id].indexOf(node.id) === -1) { + linkMap[nn.id].push(node.id); + } + } + } + } + } + // This node has been added + if (!oldConfig.allNodes.hasOwnProperty(id)) { + added[id] = node; + // Mark the container as changed + if (newConfig.allNodes[added[id].z]) { + changed[added[id].z] = newConfig.allNodes[added[id].z]; + if (changed[added[id].z].type === "subflow") { + changedSubflows[added[id].z] = changed[added[id].z]; + delete added[id]; + } + } + } + } + } + + var madeChange; + // Loop through the nodes looking for references to changed config nodes + // Repeat the loop if anything is marked as changed as it may need to be + // propagated to parent nodes. + // TODO: looping through all nodes every time is a bit inefficient - could be more targeted + do { + madeChange = false; + for (id in newConfig.allNodes) { + if (newConfig.allNodes.hasOwnProperty(id)) { + node = newConfig.allNodes[id]; + for (var prop in node) { + if (node.hasOwnProperty(prop) && prop != "z" && prop != "id" && prop != "wires") { + // This node has a property that references a changed/removed node + // Assume it is a config node change and mark this node as + // changed. + if (changed[node[prop]] || removed[node[prop]]) { + if (!changed[node.id]) { + madeChange = true; + changed[node.id] = node; + // This node exists within subflow template + // Mark the template as having changed + if (newConfig.allNodes[node.z]) { + changed[node.z] = newConfig.allNodes[node.z]; + if (changed[node.z].type === "subflow") { + changedSubflows[node.z] = changed[node.z]; + } + } + } + } + } + } + } + } + } while (madeChange===true) + + // Find any nodes that exist on a subflow template and remove from changed + // list as the parent subflow will now be marked as containing a change + for (id in newConfig.allNodes) { + if (newConfig.allNodes.hasOwnProperty(id)) { + node = newConfig.allNodes[id]; + if (newConfig.allNodes[node.z] && newConfig.allNodes[node.z].type === "subflow") { + delete changed[node.id]; + } + } + } + + // Recursively mark all instances of changed subflows as changed + var changedSubflowStack = Object.keys(changedSubflows); + while (changedSubflowStack.length > 0) { + var subflowId = changedSubflowStack.pop(); + for (id in newConfig.allNodes) { + if (newConfig.allNodes.hasOwnProperty(id)) { + node = newConfig.allNodes[id]; + if (node.type === 'subflow:'+subflowId) { + if (!changed[node.id]) { + changed[node.id] = node; + if (!changed[changed[node.id].z] && newConfig.allNodes[changed[node.id].z]) { + changed[changed[node.id].z] = newConfig.allNodes[changed[node.id].z]; + if (newConfig.allNodes[changed[node.id].z].type === "subflow") { + // This subflow instance is inside a subflow. Add the + // containing subflow to the stack to mark + changedSubflowStack.push(changed[node.id].z); + delete changed[node.id]; + } + } + } + } + } + } + } + + var diff = { + added:Object.keys(added), + changed:Object.keys(changed), + removed:Object.keys(removed), + rewired:Object.keys(wiringChanged), + linked:[] + } + + // Traverse the links of all modified nodes to mark the connected nodes + var modifiedNodes = diff.added.concat(diff.changed).concat(diff.removed).concat(diff.rewired); + var visited = {}; + while (modifiedNodes.length > 0) { + node = modifiedNodes.pop(); + if (!visited[node]) { + visited[node] = true; + if (linkMap[node]) { + if (!changed[node] && !added[node] && !removed[node] && !wiringChanged[node]) { + diff.linked.push(node); + } + modifiedNodes = modifiedNodes.concat(linkMap[node]); + } + } + } + // console.log(diff); + // for (id in newConfig.allNodes) { + // console.log( + // (added[id]?"a":(changed[id]?"c":" "))+(wiringChanged[id]?"w":" ")+(diff.linked.indexOf(id)!==-1?"l":" "), + // newConfig.allNodes[id].type.padEnd(10), + // id.padEnd(16), + // (newConfig.allNodes[id].z||"").padEnd(16), + // newConfig.allNodes[id].name||newConfig.allNodes[id].label||"" + // ); + // } + // for (id in removed) { + // console.log( + // "- "+(diff.linked.indexOf(id)!==-1?"~":" "), + // id, + // oldConfig.allNodes[id].type, + // oldConfig.allNodes[id].name||oldConfig.allNodes[id].label||"" + // ); + // } + + return diff; + }, + + /** + * Create a new instance of a node + * @param {Flow} flow The containing flow + * @param {object} config The node configuration object + * @return {Node} The instance of the node + */ + createNode: function(flow,config) { + var newNode = null; + var type = config.type; + try { + var nodeTypeConstructor = typeRegistry.get(type); + if (nodeTypeConstructor) { + var conf = clone(config); + delete conf.credentials; + for (var p in conf) { + if (conf.hasOwnProperty(p)) { + mapEnvVarProperties(conf,p,flow); + } + } + try { + Object.defineProperty(conf,'_flow', {value: flow, enumerable: false, writable: true }) + newNode = new nodeTypeConstructor(conf); + } catch (err) { + Log.log({ + level: Log.ERROR, + id:conf.id, + type: type, + msg: err + }); + } + } else { + Log.error(Log._("nodes.flow.unknown-type", {type:type})); + } + } catch(err) { + Log.error(err); + } + return newNode; + } +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/index.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/index.js new file mode 100644 index 0000000..fcb153f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/nodes/index.js @@ -0,0 +1,247 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require("when"); +var path = require("path"); +var fs = require("fs"); +var clone = require("clone"); +var util = require("util"); + +var registry = require("@node-red/registry"); + +var credentials = require("./credentials"); +var flows = require("./flows"); +var flowUtil = require("./flows/util") +var context = require("./context"); +var Node = require("./Node"); +var log; + +var events = require("../events"); + +var settings; + +/** + * Registers a node constructor + * @param nodeSet - the nodeSet providing the node (module/set) + * @param type - the string type name + * @param constructor - the constructor function for this node type + * @param opts - optional additional options for the node + */ +function registerType(nodeSet,type,constructor,opts) { + if (typeof type !== "string") { + // This is someone calling the api directly, rather than via the + // RED object provided to a node. Log a warning + log.warn("["+nodeSet+"] Deprecated call to RED.runtime.nodes.registerType - node-set name must be provided as first argument"); + opts = constructor; + constructor = type; + type = nodeSet; + nodeSet = ""; + } + if (opts) { + if (opts.credentials) { + credentials.register(type,opts.credentials); + } + if (opts.settings) { + try { + settings.registerNodeSettings(type,opts.settings); + } catch(err) { + log.warn("["+type+"] "+err.message); + } + } + } + if(!(constructor.prototype instanceof Node)) { + if(Object.getPrototypeOf(constructor.prototype) === Object.prototype) { + util.inherits(constructor,Node); + } else { + var proto = constructor.prototype; + while(Object.getPrototypeOf(proto) !== Object.prototype) { + proto = Object.getPrototypeOf(proto); + } + //TODO: This is a partial implementation of util.inherits >= node v5.0.0 + // which should be changed when support for node < v5.0.0 is dropped + // see: https://github.com/nodejs/node/pull/3455 + proto.constructor.super_ = Node; + if(Object.setPrototypeOf) { + Object.setPrototypeOf(proto, Node.prototype); + } else { + // hack for node v0.10 + proto.__proto__ = Node.prototype; + } + } + } + registry.registerType(nodeSet,type,constructor); +} + +/** + * Called from a Node's constructor function, invokes the super-class + * constructor and attaches any credentials to the node. + * @param node the node object being created + * @param def the instance definition for the node + */ +function createNode(node,def) { + Node.call(node,def); + var id = node.id; + if (def._alias) { + id = def._alias; + } + var creds = credentials.get(id); + if (creds) { + creds = clone(creds); + //console.log("Attaching credentials to ",node.id); + // allow $(foo) syntax to substitute env variables for credentials also... + for (var p in creds) { + if (creds.hasOwnProperty(p)) { + flowUtil.mapEnvVarProperties(creds,p,node._flow); + } + } + node.credentials = creds; + } else if (credentials.getDefinition(node.type)) { + node.credentials = {}; + } +} + +function init(runtime) { + settings = runtime.settings; + log = runtime.log; + credentials.init(runtime); + flows.init(runtime); + registry.init(runtime); + context.init(runtime.settings); +} + +function disableNode(id) { + flows.checkTypeInUse(id); + return registry.disableNode(id).then(function(info) { + reportNodeStateChange(info,false); + return info; + }); +} + +function enableNode(id) { + return registry.enableNode(id).then(function(info) { + reportNodeStateChange(info,true); + return info; + }); +} + +function reportNodeStateChange(info,enabled) { + if (info.enabled === enabled && !info.err) { + events.emit("runtime-event",{id:"node/"+(enabled?"enabled":"disabled"),retain:false,payload:info}); + log.info(" "+log._("api.nodes."+(enabled?"enabled":"disabled"))); + for (var i=0;i<info.types.length;i++) { + log.info(" - "+info.types[i]); + } + } else if (enabled && info.err) { + log.warn(log._("api.nodes.error-enable")); + log.warn(" - "+info.name+" : "+info.err); + } +} + +function installModule(module,version) { + var existingModule = registry.getModuleInfo(module); + var isUpgrade = !!existingModule; + return registry.installModule(module,version).then(function(info) { + if (isUpgrade) { + events.emit("runtime-event",{id:"node/upgraded",retain:false,payload:{module:module,version:version}}); + } else { + events.emit("runtime-event",{id:"node/added",retain:false,payload:info.nodes}); + } + return info; + }); +} + +function uninstallModule(module) { + var info = registry.getModuleInfo(module); + if (!info) { + throw new Error(log._("nodes.index.unrecognised-module", {module:module})); + } else { + for (var i=0;i<info.nodes.length;i++) { + flows.checkTypeInUse(module+"/"+info.nodes[i].name); + } + return registry.uninstallModule(module).then(function(list) { + events.emit("runtime-event",{id:"node/removed",retain:false,payload:list}); + return list; + }); + } +} + +module.exports = { + // Lifecycle + init: init, + load: registry.load, + + // Node registry + createNode: createNode, + getNode: flows.get, + eachNode: flows.eachNode, + getContext: context.get, + + + paletteEditorEnabled: registry.paletteEditorEnabled, + installModule: installModule, + uninstallModule: uninstallModule, + + enableNode: enableNode, + disableNode: disableNode, + + // Node type registry + registerType: registerType, + getType: registry.get, + + getNodeInfo: registry.getNodeInfo, + getNodeList: registry.getNodeList, + + getModuleInfo: registry.getModuleInfo, + + getNodeConfigs: registry.getNodeConfigs, + getNodeConfig: registry.getNodeConfig, + getNodeIconPath: registry.getNodeIconPath, + getNodeIcons: registry.getNodeIcons, + getNodeExampleFlows: registry.getNodeExampleFlows, + getNodeExampleFlowPath: registry.getNodeExampleFlowPath, + + clearRegistry: registry.clear, + cleanModuleList: registry.cleanModuleList, + + // Flow handling + loadFlows: flows.load, + startFlows: flows.startFlows, + stopFlows: flows.stopFlows, + setFlows: flows.setFlows, + getFlows: flows.getFlows, + + addFlow: flows.addFlow, + getFlow: flows.getFlow, + updateFlow: flows.updateFlow, + removeFlow: flows.removeFlow, + // disableFlow: flows.disableFlow, + // enableFlow: flows.enableFlow, + + // Credentials + addCredentials: credentials.add, + getCredentials: credentials.get, + deleteCredentials: credentials.delete, + getCredentialDefinition: credentials.getDefinition, + setCredentialSecret: credentials.setKey, + clearCredentials: credentials.clear, + exportCredentials: credentials.export, + getCredentialKeyType: credentials.getKeyType, + + // Contexts + loadContextsPlugin: context.load, + closeContextsPlugin: context.close, + listContextStores: context.listStores +}; diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/settings.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/settings.js new file mode 100644 index 0000000..35417a4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/settings.js @@ -0,0 +1,191 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require("when"); +var clone = require("clone"); +var assert = require("assert"); +var log = require("@node-red/util").log; // TODO: separate module +var util = require("@node-red/util").util; + +// localSettings are those provided in the runtime settings.js file +var localSettings = null; +// globalSettings are provided by storage - .config.json on localfilesystem +var globalSettings = null; +// nodeSettings are those settings that a node module defines as being available +var nodeSettings = null; + +// A subset of globalSettings that deal with per-user settings +var userSettings = null; + +var disableNodeSettings = null; +var storage = null; + +var persistentSettings = { + init: function(settings) { + localSettings = settings; + for (var i in settings) { + /* istanbul ignore else */ + if (settings.hasOwnProperty(i) && i !== 'load' && i !== 'get' && i !== 'set' && i !== 'available' && i !== 'reset') { + // Don't allow any of the core functions get replaced via settings + (function() { + var j = i; + persistentSettings.__defineGetter__(j,function() { return localSettings[j]; }); + persistentSettings.__defineSetter__(j,function() { throw new Error("Property '"+j+"' is read-only"); }); + })(); + } + } + globalSettings = null; + nodeSettings = {}; + disableNodeSettings = {}; + }, + load: function(_storage) { + storage = _storage; + return storage.getSettings().then(function(_settings) { + globalSettings = _settings; + if (globalSettings) { + userSettings = globalSettings.users || {}; + } + else { + userSettings = {}; + } + }); + }, + get: function(prop) { + if (prop === 'users') { + throw new Error("Do not access user settings directly. Use settings.getUserSettings"); + } + if (localSettings.hasOwnProperty(prop)) { + return clone(localSettings[prop]); + } + if (globalSettings === null) { + throw new Error(log._("settings.not-available")); + } + return clone(globalSettings[prop]); + }, + + set: function(prop,value) { + if (prop === 'users') { + throw new Error("Do not access user settings directly. Use settings.setUserSettings"); + } + if (localSettings.hasOwnProperty(prop)) { + throw new Error(log._("settings.property-read-only", {prop:prop})); + } + if (globalSettings === null) { + throw new Error(log._("settings.not-available")); + } + var current = globalSettings[prop]; + globalSettings[prop] = value; + try { + assert.deepEqual(current,value); + return when.resolve(); + } catch(err) { + return storage.saveSettings(globalSettings); + } + }, + delete: function(prop) { + if (localSettings.hasOwnProperty(prop)) { + throw new Error(log._("settings.property-read-only", {prop:prop})); + } + if (globalSettings === null) { + throw new Error(log._("settings.not-available")); + } + if (globalSettings.hasOwnProperty(prop)) { + delete globalSettings[prop]; + return storage.saveSettings(globalSettings); + } + return when.resolve(); + }, + + available: function() { + return (globalSettings !== null); + }, + + reset: function() { + for (var i in localSettings) { + /* istanbul ignore else */ + if (localSettings.hasOwnProperty(i)) { + delete persistentSettings[i]; + } + } + localSettings = null; + globalSettings = null; + userSettings = null; + storage = null; + }, + registerNodeSettings: function(type, opts) { + var normalisedType = util.normaliseNodeTypeName(type); + for (var property in opts) { + if (opts.hasOwnProperty(property)) { + if (!property.startsWith(normalisedType)) { + throw new Error("Registered invalid property name '"+property+"'. Properties for this node must start with '"+normalisedType+"'"); + } + } + } + nodeSettings[type] = opts; + }, + exportNodeSettings: function(safeSettings) { + for (var type in nodeSettings) { + if (nodeSettings.hasOwnProperty(type) && !disableNodeSettings[type]) { + var nodeTypeSettings = nodeSettings[type]; + for (var property in nodeTypeSettings) { + if (nodeTypeSettings.hasOwnProperty(property)) { + var setting = nodeTypeSettings[property]; + if (setting.exportable) { + if (safeSettings.hasOwnProperty(property)) { + // Cannot overwrite existing setting + } else if (localSettings.hasOwnProperty(property)) { + safeSettings[property] = localSettings[property]; + } else if (setting.hasOwnProperty('value')) { + safeSettings[property] = setting.value; + } + } + } + } + } + } + + return safeSettings; + }, + enableNodeSettings: function(types) { + types.forEach(function(type) { + disableNodeSettings[type] = false; + }); + }, + disableNodeSettings: function(types) { + types.forEach(function(type) { + disableNodeSettings[type] = true; + }); + }, + getUserSettings: function(username) { + return clone(userSettings[username]); + }, + setUserSettings: function(username,settings) { + if (globalSettings === null) { + throw new Error(log._("settings.not-available")); + } + var current = userSettings[username]; + userSettings[username] = settings; + try { + assert.deepEqual(current,settings); + return when.resolve(); + } catch(err) { + globalSettings.users = userSettings; + return storage.saveSettings(globalSettings); + } + } +} + +module.exports = persistentSettings; diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/index.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/index.js new file mode 100644 index 0000000..4966820 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/index.js @@ -0,0 +1,240 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require('when'); +var Path = require('path'); +var crypto = require('crypto'); + +var log = require("@node-red/util").log; // TODO: separate module + +var runtime; +var storageModule; +var settingsAvailable; +var sessionsAvailable; + +var libraryFlowsCachedResult = null; + +function moduleSelector(aSettings) { + var toReturn; + if (aSettings.storageModule) { + if (typeof aSettings.storageModule === "string") { + // TODO: allow storage modules to be specified by absolute path + toReturn = require("./"+aSettings.storageModule); + } else { + toReturn = aSettings.storageModule; + } + } else { + toReturn = require("./localfilesystem"); + } + return toReturn; +} + +function is_malicious(path) { + return path.indexOf('../') != -1 || path.indexOf('..\\') != -1; +} + +var storageModuleInterface = { + init: function(_runtime) { + runtime = _runtime; + try { + storageModule = moduleSelector(runtime.settings); + settingsAvailable = storageModule.hasOwnProperty("getSettings") && storageModule.hasOwnProperty("saveSettings"); + sessionsAvailable = storageModule.hasOwnProperty("getSessions") && storageModule.hasOwnProperty("saveSessions"); + } catch (e) { + return when.reject(e); + } + if (!!storageModule.projects) { + var projectsEnabled = false; + if (runtime.settings.hasOwnProperty("editorTheme") && runtime.settings.editorTheme.hasOwnProperty("projects")) { + projectsEnabled = runtime.settings.editorTheme.projects.enabled === true; + } + if (projectsEnabled) { + storageModuleInterface.projects = storageModule.projects; + } + } + if (storageModule.sshkeys) { + storageModuleInterface.sshkeys = storageModule.sshkeys; + } + return storageModule.init(runtime.settings,runtime); + }, + getFlows: function() { + return storageModule.getFlows().then(function(flows) { + return storageModule.getCredentials().then(function(creds) { + var result = { + flows: flows, + credentials: creds + }; + result.rev = crypto.createHash('md5').update(JSON.stringify(result.flows)).digest("hex"); + return result; + }) + }); + }, + saveFlows: function(config) { + var flows = config.flows; + var credentials = config.credentials; + var credentialSavePromise; + if (config.credentialsDirty) { + credentialSavePromise = storageModule.saveCredentials(credentials); + } else { + credentialSavePromise = when.resolve(); + } + delete config.credentialsDirty; + + return credentialSavePromise.then(function() { + return storageModule.saveFlows(flows).then(function() { + return crypto.createHash('md5').update(JSON.stringify(config.flows)).digest("hex"); + }) + }); + }, + // getCredentials: function() { + // return storageModule.getCredentials(); + // }, + saveCredentials: function(credentials) { + return storageModule.saveCredentials(credentials); + }, + getSettings: function() { + if (settingsAvailable) { + return storageModule.getSettings(); + } else { + return when.resolve(null); + } + }, + saveSettings: function(settings) { + if (settingsAvailable) { + return storageModule.saveSettings(settings); + } else { + return when.resolve(); + } + }, + getSessions: function() { + if (sessionsAvailable) { + return storageModule.getSessions(); + } else { + return when.resolve(null); + } + }, + saveSessions: function(sessions) { + if (sessionsAvailable) { + return storageModule.saveSessions(sessions); + } else { + return when.resolve(); + } + }, + + /* Library Functions */ + + getLibraryEntry: function(type, path) { + if (is_malicious(path)) { + var err = new Error(); + err.code = "forbidden"; + return when.reject(err); + } + return storageModule.getLibraryEntry(type, path); + }, + saveLibraryEntry: function(type, path, meta, body) { + if (is_malicious(path)) { + var err = new Error(); + err.code = "forbidden"; + return when.reject(err); + } + return storageModule.saveLibraryEntry(type, path, meta, body); + }, + +/* Deprecated functions */ + getAllFlows: function() { + if (storageModule.hasOwnProperty("getAllFlows")) { + return storageModule.getAllFlows(); + } else { + if (libraryFlowsCachedResult) { + return Promise.resolve(libraryFlowsCachedResult); + } else { + return listFlows("/").then(function(result) { + libraryFlowsCachedResult = result; + return result; + }); + } + } + }, + getFlow: function(fn) { + if (is_malicious(fn)) { + var err = new Error(); + err.code = "forbidden"; + return when.reject(err); + } + if (storageModule.hasOwnProperty("getFlow")) { + return storageModule.getFlow(fn); + } else { + return storageModule.getLibraryEntry("flows",fn); + } + + }, + saveFlow: function(fn, data) { + if (is_malicious(fn)) { + var err = new Error(); + err.code = "forbidden"; + return when.reject(err); + } + libraryFlowsCachedResult = null; + if (storageModule.hasOwnProperty("saveFlow")) { + return storageModule.saveFlow(fn, data); + } else { + return storageModule.saveLibraryEntry("flows",fn,{},data); + } + } +/* End deprecated functions */ + +} + + +function listFlows(path) { + return storageModule.getLibraryEntry("flows",path).then(function(res) { + return when.promise(function(resolve) { + var promises = []; + res.forEach(function(r) { + if (typeof r === "string") { + promises.push(listFlows(Path.join(path,r))); + } else { + promises.push(when.resolve(r)); + } + }); + var i=0; + when.settle(promises).then(function(res2) { + var result = {}; + res2.forEach(function(r) { + // TODO: name||fn + if (r.value.fn) { + var name = r.value.name; + if (!name) { + name = r.value.fn.replace(/\.json$/, ""); + } + result.f = result.f || []; + result.f.push(name); + } else { + result.d = result.d || {}; + result.d[res[i]] = r.value; + //console.log(">",r.value); + } + i++; + }); + resolve(result); + }); + }); + }); +} + + + +module.exports = storageModuleInterface; diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/index.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/index.js new file mode 100644 index 0000000..70e7319 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/index.js @@ -0,0 +1,102 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var fs = require('fs-extra'); +var when = require('when'); +var fspath = require("path"); + +var log = require("@node-red/util").log; // TODO: separate module + +var util = require("./util"); +var library = require("./library"); +var sessions = require("./sessions"); +var runtimeSettings = require("./settings"); +var projects = require("./projects"); + +var initialFlowLoadComplete = false; +var settings; + +var localfilesystem = { + init: function(_settings, runtime) { + settings = _settings; + + var promises = []; + + if (!settings.userDir) { + try { + fs.statSync(fspath.join(process.env.NODE_RED_HOME,".config.json")); + settings.userDir = process.env.NODE_RED_HOME; + } catch(err) { + try { + // Consider compatibility for older versions + if (process.env.HOMEPATH) { + fs.statSync(fspath.join(process.env.HOMEPATH,".node-red",".config.json")); + settings.userDir = fspath.join(process.env.HOMEPATH,".node-red"); + } + } catch(err) { + } + if (!settings.userDir) { + settings.userDir = fspath.join(process.env.HOME || process.env.USERPROFILE || process.env.HOMEPATH || process.env.NODE_RED_HOME,".node-red"); + if (!settings.readOnly) { + promises.push(fs.ensureDir(fspath.join(settings.userDir,"node_modules"))); + } + } + } + } + + sessions.init(settings); + runtimeSettings.init(settings); + promises.push(library.init(settings)); + promises.push(projects.init(settings, runtime)); + + var packageFile = fspath.join(settings.userDir,"package.json"); + var packagePromise = when.resolve(); + + if (!settings.readOnly) { + packagePromise = function() { + try { + fs.statSync(packageFile); + } catch(err) { + var defaultPackage = { + "name": "node-red-project", + "description": "A Node-RED Project", + "version": "0.0.1", + "private": true + }; + return util.writeFile(packageFile,JSON.stringify(defaultPackage,"",4)); + } + return true; + } + } + return when.all(promises).then(packagePromise); + }, + + + getFlows: projects.getFlows, + saveFlows: projects.saveFlows, + getCredentials: projects.getCredentials, + saveCredentials: projects.saveCredentials, + + getSettings: runtimeSettings.getSettings, + saveSettings: runtimeSettings.saveSettings, + getSessions: sessions.getSessions, + saveSessions: sessions.saveSessions, + getLibraryEntry: library.getLibraryEntry, + saveLibraryEntry: library.saveLibraryEntry, + projects: projects +}; + +module.exports = localfilesystem; diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/library.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/library.js new file mode 100644 index 0000000..f72ce1e --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/library.js @@ -0,0 +1,166 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var fs = require('fs-extra'); +var when = require('when'); +var fspath = require("path"); +var nodeFn = require('when/node/function'); + +var util = require("./util"); + +var settings; +var libDir; +var libFlowsDir; + +function getFileMeta(root, path) { + var fn = fspath.join(root, path); + var fd = fs.openSync(fn, 'r'); + var size = fs.fstatSync(fd).size; + var meta = {}; + var read = 0; + var length = 10; + var remaining = Buffer.alloc(0); + var buffer = Buffer.alloc(length); + while (read < size) { + read += fs.readSync(fd, buffer, 0, length); + var data = Buffer.concat([remaining, buffer]); + var index = data.lastIndexOf(0x0a); + if (index !== -1) { + var parts = data.slice(0, index).toString().split('\n'); + for (var i = 0; i < parts.length; i++) { + var match = /^\/\/ (\w+): (.*)/.exec(parts[i]); + if (match) { + meta[match[1]] = match[2]; + } else { + read = size; + break; + } + } + remaining = data.slice(index + 1); + } else { + remaining = data; + } + } + fs.closeSync(fd); + return meta; +} + +function getFileBody(root, path) { + var body = ''; + var fn = fspath.join(root, path); + var data = fs.readFileSync(fn, 'utf8'); + var parts = data.split('\n'); + var scanning = true; + for (var i = 0; i < parts.length; i++) { + if (! /^\/\/ \w+: /.test(parts[i]) || !scanning) { + body += (body.length > 0 ? '\n' : '') + parts[i]; + scanning = false; + } + } + return body; +} + +function getLibraryEntry(type,path) { + var root = fspath.join(libDir,type); + var rootPath = fspath.join(libDir,type,path); + + // don't create the folder if it does not exist - we are only reading.... + return nodeFn.call(fs.lstat, rootPath).then(function(stats) { + if (stats.isFile()) { + return getFileBody(root,path); + } + if (path.substr(-1) == '/') { + path = path.substr(0,path.length-1); + } + return nodeFn.call(fs.readdir, rootPath).then(function(fns) { + var dirs = []; + var files = []; + fns.sort().filter(function(fn) { + var fullPath = fspath.join(path,fn); + var absoluteFullPath = fspath.join(root,fullPath); + if (fn[0] != ".") { + var stats = fs.lstatSync(absoluteFullPath); + if (stats.isDirectory()) { + dirs.push(fn); + } else { + var meta = getFileMeta(root,fullPath); + meta.fn = fn; + files.push(meta); + } + } + }); + return dirs.concat(files); + }); + }).catch(function(err) { + // if path is empty, then assume it was a folder, return empty + if (path === ""){ + return []; + } + + // if path ends with slash, it was a folder + // so return empty + if (path.substr(-1) == '/') { + return []; + } + + // else path was specified, but did not exist, + // check for path.json as an alternative if flows + if (type === "flows" && !/\.json$/.test(path)) { + return getLibraryEntry(type,path+".json") + .catch(function(e) { + throw err; + }); + } else { + throw err; + } + }); +} + +module.exports = { + init: function(_settings) { + settings = _settings; + libDir = fspath.join(settings.userDir,"lib"); + libFlowsDir = fspath.join(libDir,"flows"); + if (!settings.readOnly) { + return fs.ensureDir(libFlowsDir); + } else { + return when.resolve(); + } + }, + getLibraryEntry: getLibraryEntry, + + saveLibraryEntry: function(type,path,meta,body) { + if (settings.readOnly) { + return when.resolve(); + } + if (type === "flows" && !path.endsWith(".json")) { + path += ".json"; + } + var fn = fspath.join(libDir, type, path); + var headers = ""; + for (var i in meta) { + if (meta.hasOwnProperty(i)) { + headers += "// "+i+": "+meta[i]+"\n"; + } + } + if (type === "flows" && settings.flowFilePretty) { + body = JSON.stringify(JSON.parse(body),null,4); + } + return fs.ensureDir(fspath.dirname(fn)).then(function () { + util.writeFile(fn,headers+body); + }); + } +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/Project.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/Project.js new file mode 100644 index 0000000..7ba3bd2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/Project.js @@ -0,0 +1,1047 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +var fs = require('fs-extra'); +var when = require('when'); +var fspath = require("path"); +var os = require('os'); + +var gitTools = require("./git"); +var util = require("../util"); +var defaultFileSet = require("./defaultFileSet"); +var sshKeys = require("./ssh"); +var settings; +var runtime; +var log = require("@node-red/util").log; + +var projectsDir; + +var authCache = require("./git/authCache"); + +// TODO: DRY - red/api/editor/sshkeys ! +function getSSHKeyUsername(userObj) { + var username = '__default'; + if ( userObj && userObj.username ) { + username = userObj.username; + } + return username; +} +function getGitUser(user) { + var username; + if (!user) { + username = "_"; + } else { + username = user.username; + } + var userSettings = settings.getUserSettings(username); + if (userSettings && userSettings.git) { + return userSettings.git.user; + } + return null; +} + +function Project(path) { + this.path = path; + this.name = fspath.basename(path); + this.paths = {}; + this.files = {}; + this.auth = {origin:{}}; + this.missingFiles = []; + this.credentialSecret = null; +} +Project.prototype.load = function () { + var project = this; + var globalProjectSettings = settings.get("projects"); +// console.log(globalProjectSettings) + var projectSettings = {}; + if (globalProjectSettings) { + if (globalProjectSettings.projects.hasOwnProperty(this.name)) { + projectSettings = globalProjectSettings.projects[this.name] || {}; + } + } + this.paths.root = projectSettings.rootPath || ""; + this.credentialSecret = projectSettings.credentialSecret; + this.git = projectSettings.git || { user:{} }; + + // this.paths.flowFile = fspath.join(this.path,"flow.json"); + // this.paths.credentialsFile = fspath.join(this.path,"flow_cred.json"); + + var promises = []; + return checkProjectFiles(project).then(function(missingFiles) { + project.missingFiles = missingFiles; + if (missingFiles.indexOf('package.json') === -1) { + // We have a package.json in project.path+project.paths.root+"package.json" + project.paths['package.json'] = fspath.join(project.paths.root,"package.json"); + promises.push(fs.readFile(fspath.join(project.path,project.paths['package.json']),"utf8").then(function(content) { + try { + project.package = util.parseJSON(content); + if (project.package.hasOwnProperty('node-red')) { + if (project.package['node-red'].hasOwnProperty('settings')) { + project.paths.flowFile = fspath.join(project.paths.root,project.package['node-red'].settings.flowFile); + project.paths.credentialsFile = fspath.join(project.paths.root,project.package['node-red'].settings.credentialsFile); + } + } else { + // TODO: package.json doesn't have a node-red section + // is that a bad thing? + } + } catch(err) { + // package.json isn't valid JSON... is a merge underway? + project.package = {}; + } + })); + if (missingFiles.indexOf('README.md') === -1) { + project.paths['README.md'] = fspath.join(project.paths.root,"README.md"); + promises.push(fs.readFile(fspath.join(project.path,project.paths['README.md']),"utf8").then(function(content) { + project.description = content; + })); + } else { + project.description = ""; + } + } else { + project.package = {}; + project.description = ""; + } + + // if (missingFiles.indexOf('flow.json') !== -1) { + // console.log("MISSING FLOW FILE"); + // } else { + // project.paths.flowFile = fspath.join(project.path,"flow.json"); + // } + // if (missingFiles.indexOf('flow_cred.json') !== -1) { + // console.log("MISSING CREDS FILE"); + // } else { + // project.paths.credentialsFile = fspath.join(project.path,"flow_cred.json"); + // } + + promises.push(project.loadRemotes()); + + return when.settle(promises).then(function(results) { + return project; + }) + }); +}; + +Project.prototype.initialise = function(user,data) { + var project = this; + // if (!this.empty) { + // throw new Error("Cannot initialise non-empty project"); + // } + var files = Object.keys(defaultFileSet); + var promises = []; + + if (data.hasOwnProperty('credentialSecret')) { + var projects = settings.get('projects'); + projects.projects[project.name] = projects.projects[project.name] || {}; + projects.projects[project.name].credentialSecret = data.credentialSecret; + promises.push(settings.set('projects',projects)); + } + + if (data.hasOwnProperty('files')) { + if (data.files.hasOwnProperty('flow') && data.files.hasOwnProperty('credentials')) { + project.files.flow = data.files.flow; + project.files.credentials = data.files.credentials; + var flowFilePath = fspath.join(project.path,project.files.flow); + var credsFilePath = getCredentialsFilename(flowFilePath); + promises.push(util.writeFile(flowFilePath,"[]")); + promises.push(util.writeFile(credsFilePath,"{}")); + files.push(project.files.flow); + files.push(project.files.credentials); + } + } + for (var file in defaultFileSet) { + if (defaultFileSet.hasOwnProperty(file)) { + var path = fspath.join(project.path,file); + if (!fs.existsSync(path)) { + promises.push(util.writeFile(path,defaultFileSet[file](project))); + } + + } + } + + return when.all(promises).then(function() { + return gitTools.stageFile(project.path,files); + }).then(function() { + return gitTools.commit(project.path,"Create project files",getGitUser(user)); + }).then(function() { + return project.load() + }) +} + +Project.prototype.loadRemotes = function() { + var project = this; + return gitTools.getRemotes(project.path).then(function(remotes) { + project.remotes = remotes; + }).then(function() { + project.branches = {}; + return project.status(); + }).then(function() { + if (project.remotes) { + var allRemotes = Object.keys(project.remotes); + var match = ""; + if (project.branches.remote) { + allRemotes.forEach(function(remote) { + if (project.branches.remote.indexOf(remote) === 0 && match.length < remote.length) { + match = remote; + } + }); + project.currentRemote = project.parseRemoteBranch(project.branches.remote).remote; + } + } else { + delete project.currentRemote; + } + }); +} + +Project.prototype.parseRemoteBranch = function (remoteBranch) { + if (!remoteBranch) { + return {} + } + var project = this; + var allRemotes = Object.keys(project.remotes); + var match = ""; + allRemotes.forEach(function(remote) { + if (remoteBranch.indexOf(remote) === 0 && match.length < remote.length) { + match = remote; + } + }); + return { + remote: match, + branch: remoteBranch.substring(match.length+1) + } + +}; + +Project.prototype.isEmpty = function () { + return this.empty; +}; + +Project.prototype.isMerging = function() { + return this.merging; +} + +Project.prototype.update = function (user, data) { + var username; + if (!user) { + username = "_"; + } else { + username = user.username; + } + + var promises = []; + var project = this; + var saveSettings = false; + var saveREADME = false; + var savePackage = false; + var flowFilesChanged = false; + var credentialSecretChanged = false; + var reloadProject = false; + + var globalProjectSettings = settings.get("projects"); + if (!globalProjectSettings.projects.hasOwnProperty(this.name)) { + globalProjectSettings.projects[this.name] = {}; + saveSettings = true; + } + + if (data.credentialSecret && data.credentialSecret !== this.credentialSecret) { + var existingSecret = data.currentCredentialSecret; + var isReset = data.resetCredentialSecret; + var secret = data.credentialSecret; + + // console.log("updating credentialSecret"); + // console.log("request:"); + // console.log(JSON.stringify(data,"",4)); + // console.log(" this.credentialSecret",this.credentialSecret); + // console.log(" this.info", this.info); + + if (!isReset && // not a reset + this.credentialSecret && // key already set + !this.credentialSecretInvalid && // key not invalid + this.credentialSecret !== existingSecret) { // key doesn't match provided existing key + var e = new Error("Cannot change credentialSecret without current key"); + e.code = "missing_current_credential_key"; + return when.reject(e); + } + this.credentialSecret = secret; + + globalProjectSettings.projects[this.name].credentialSecret = project.credentialSecret; + delete this.credentialSecretInvalid; + saveSettings = true; + credentialSecretChanged = true; + } + + if (this.missingFiles.indexOf('package.json') !== -1) { + if (!data.files || !data.files.package) { + // Cannot update a project that doesn't have a known package.json + return Promise.reject("Cannot update project with missing package.json"); + } + } + + if (data.hasOwnProperty('files')) { + this.package['node-red'] = this.package['node-red'] || { settings: {}}; + if (data.files.hasOwnProperty('package') && (data.files.package !== fspath.join(this.paths.root,"package.json") || !this.paths['package.json'])) { + // We have a package file. It could be one that doesn't exist yet, + // or it does exist and we need to load it. + if (!/package\.json$/.test(data.files.package)) { + return Promise.reject("Invalid package file: "+data.files.package) + } + var root = data.files.package.substring(0,data.files.package.length-12); + this.paths.root = root; + this.paths['package.json'] = data.files.package; + globalProjectSettings.projects[this.name].rootPath = root; + saveSettings = true; + // 1. check if it exists + if (fs.existsSync(fspath.join(this.path,this.paths['package.json']))) { + // Load the existing one.... + } else { + var newPackage = defaultFileSet["package.json"](this); + fs.writeFileSync(fspath.join(this.path,this.paths['package.json']),newPackage); + this.package = JSON.parse(newPackage); + } + reloadProject = true; + flowFilesChanged = true; + } + + if (data.files.hasOwnProperty('flow') && this.package['node-red'].settings.flowFile !== data.files.flow.substring(this.paths.root.length)) { + this.paths.flowFile = data.files.flow; + this.package['node-red'].settings.flowFile = data.files.flow.substring(this.paths.root.length); + savePackage = true; + flowFilesChanged = true; + } + if (data.files.hasOwnProperty('credentials') && this.package['node-red'].settings.credentialsFile !== data.files.credentials.substring(this.paths.root.length)) { + this.paths.credentialsFile = data.files.credentials; + this.package['node-red'].settings.credentialsFile = data.files.credentials.substring(this.paths.root.length); + // Don't know if the credSecret is invalid or not so clear the flag + delete this.credentialSecretInvalid; + savePackage = true; + flowFilesChanged = true; + } + } + + if (data.hasOwnProperty('description')) { + saveREADME = true; + this.description = data.description; + } + if (data.hasOwnProperty('dependencies')) { + savePackage = true; + this.package.dependencies = data.dependencies; + } + if (data.hasOwnProperty('summary')) { + savePackage = true; + this.package.description = data.summary; + } + + if (data.hasOwnProperty('git')) { + if (data.git.hasOwnProperty('user')) { + globalProjectSettings.projects[this.name].git = globalProjectSettings.projects[this.name].git || {}; + globalProjectSettings.projects[this.name].git.user = globalProjectSettings.projects[this.name].git.user || {}; + globalProjectSettings.projects[this.name].git.user[username] = { + name: data.git.user.name, + email: data.git.user.email + } + this.git.user[username] = { + name: data.git.user.name, + email: data.git.user.email + } + saveSettings = true; + } + if (data.git.hasOwnProperty('remotes')) { + var remoteNames = Object.keys(data.git.remotes); + var remotesChanged = false; + var modifyRemotesPromise = Promise.resolve(); + remoteNames.forEach(function(name) { + if (data.git.remotes[name].removed) { + remotesChanged = true; + modifyRemotesPromise = modifyRemotesPromise.then(function() { gitTools.removeRemote(project.path,name) }); + } else { + if (data.git.remotes[name].url) { + remotesChanged = true; + modifyRemotesPromise = modifyRemotesPromise.then(function() { gitTools.addRemote(project.path,name,data.git.remotes[name])}); + } + if (data.git.remotes[name].username && data.git.remotes[name].password) { + var url = data.git.remotes[name].url || project.remotes[name].fetch; + authCache.set(project.name,url,username,data.git.remotes[name]); + } + } + }) + if (remotesChanged) { + modifyRemotesPromise = modifyRemotesPromise.then(function() { + return project.loadRemotes(); + }); + promises.push(modifyRemotesPromise); + } + } + } + + + if (saveSettings) { + promises.push(settings.set("projects",globalProjectSettings)); + } + if (saveREADME) { + promises.push(util.writeFile(fspath.join(this.path,this.paths['README.md']), this.description)); + } + if (savePackage) { + promises.push(fs.readFile(fspath.join(project.path,project.paths['package.json']),"utf8").then(content => { + var currentPackage = {}; + try { + currentPackage = util.parseJSON(content); + } catch(err) { + } + this.package = Object.assign(currentPackage,this.package); + return util.writeFile(fspath.join(project.path,this.paths['package.json']), JSON.stringify(this.package,"",4)); + })); + } + return when.settle(promises).then(res => { + if (reloadProject) { + return this.load() + } + }).then(() => { return { + flowFilesChanged: flowFilesChanged, + credentialSecretChanged: credentialSecretChanged + }}) +}; + +Project.prototype.getFiles = function () { + return gitTools.getFiles(this.path).catch(function(err) { + if (/ambiguous argument/.test(err.message)) { + return {}; + } + throw err; + }); +}; + +Project.prototype.stageFile = function(file) { + return gitTools.stageFile(this.path,file); +}; + +Project.prototype.unstageFile = function(file) { + return gitTools.unstageFile(this.path,file); +} + +Project.prototype.commit = function(user, options) { + var self = this; + return gitTools.commit(this.path,options.message,getGitUser(user)).then(function() { + if (self.merging) { + self.merging = false; + return + } + }); +} + +Project.prototype.getFileDiff = function(file,type) { + return gitTools.getFileDiff(this.path,file,type); +} + +Project.prototype.getCommits = function(options) { + return gitTools.getCommits(this.path,options).catch(function(err) { + if (/bad default revision/i.test(err.message) || /ambiguous argument/i.test(err.message) || /does not have any commits yet/i.test(err.message)) { + return { + count:0, + commits:[], + total: 0 + } + } + throw err; + }) +} + +Project.prototype.getCommit = function(sha) { + return gitTools.getCommit(this.path,sha); +} + +Project.prototype.getFile = function (filePath,treeish) { + if (treeish !== "_") { + return gitTools.getFile(this.path, filePath, treeish); + } else { + return fs.readFile(fspath.join(this.path,filePath),"utf8"); + } +}; + +Project.prototype.revertFile = function (filePath) { + var self = this; + return gitTools.revertFile(this.path, filePath).then(function() { + return self.load(); + }); +}; + +Project.prototype.status = function(user, includeRemote) { + var self = this; + + var fetchPromise; + if (this.remotes && includeRemote) { + fetchPromise = gitTools.getRemoteBranch(self.path).then(function(remoteBranch) { + if (remoteBranch) { + var allRemotes = Object.keys(self.remotes); + var match = ""; + allRemotes.forEach(function(remote) { + if (remoteBranch.indexOf(remote) === 0 && match.length < remote.length) { + match = remote; + } + }) + return self.fetch(user, match); + } + }); + } else { + fetchPromise = Promise.resolve(); + } + + var completeStatus = function(fetchError) { + var promises = [ + gitTools.getStatus(self.path), + fs.exists(fspath.join(self.path,".git","MERGE_HEAD")) + ]; + return Promise.all(promises).then(function(results) { + var result = results[0]; + if (results[1]) { + result.merging = true; + if (!self.merging) { + self.merging = true; + runtime.events.emit("runtime-event",{ + id:"runtime-state", + payload:{ + type:"warning", + error:"git_merge_conflict", + project:self.name, + text:"notification.warnings.git_merge_conflict" + }, + retain:true} + ); + } + } else { + self.merging = false; + } + self.branches.local = result.branches.local; + self.branches.remote = result.branches.remote; + if (fetchError && !/ambiguous argument/.test(fetchError.message)) { + result.branches.remoteError = { + remote: fetchError.remote, + code: fetchError.code + } + } + if (result.commits.total === 0 && Object.keys(result.files).length === 0) { + if (!self.empty) { + runtime.events.emit("runtime-event",{ + id:"runtime-state", + payload:{ + type:"warning", + error:"project_empty", + text:"notification.warnings.project_empty"}, + retain:true + } + ); + } + self.empty = true; + } else { + if (self.empty) { + if (self.paths.flowFile) { + runtime.events.emit("runtime-event",{id:"runtime-state",retain:true}); + } else { + runtime.events.emit("runtime-event",{ + id:"runtime-state", + payload:{ + type:"warning", + error:"missing_flow_file", + text:"notification.warnings.missing_flow_file"}, + retain:true + } + ); + } + } + delete self.empty; + } + return result; + }).catch(function(err) { + if (/ambiguous argument/.test(err.message)) { + return { + files:{}, + commits:{total:0}, + branches:{} + }; + } + throw err; + }); + } + return fetchPromise.then(completeStatus).catch(function(e) { + // if (e.code !== 'git_auth_failed') { + // console.log("Fetch failed"); + // console.log(e); + // } + return completeStatus(e); + }) +}; + +Project.prototype.push = function (user,remoteBranchName,setRemote) { + var username; + if (!user) { + username = "_"; + } else { + username = user.username; + } + var remote = this.parseRemoteBranch(remoteBranchName||this.branches.remote); + return gitTools.push(this.path, remote.remote || this.currentRemote,remote.branch, setRemote, authCache.get(this.name,this.remotes[remote.remote || this.currentRemote].fetch,username)); +}; + +Project.prototype.pull = function (user,remoteBranchName,setRemote,allowUnrelatedHistories) { + var username; + if (!user) { + username = "_"; + } else { + username = user.username; + } + var self = this; + if (setRemote) { + return gitTools.setUpstream(this.path, remoteBranchName).then(function() { + self.currentRemote = self.parseRemoteBranch(remoteBranchName).remote; + return gitTools.pull(self.path, null, null, allowUnrelatedHistories, authCache.get(self.name,self.remotes[self.currentRemote].fetch,username),getGitUser(user)); + }) + } else { + var remote = this.parseRemoteBranch(remoteBranchName); + return gitTools.pull(this.path, remote.remote, remote.branch, allowUnrelatedHistories, authCache.get(this.name,this.remotes[remote.remote||self.currentRemote].fetch,username),getGitUser(user)); + } +}; + +Project.prototype.resolveMerge = function (file,resolutions) { + var filePath = fspath.join(this.path,file); + var self = this; + if (typeof resolutions === 'string') { + return util.writeFile(filePath, resolutions).then(function() { + return self.stageFile(file); + }) + } + return fs.readFile(filePath,"utf8").then(function(content) { + var lines = content.split("\n"); + var result = []; + var ignoreBlock = false; + var currentBlock; + for (var i=1;i<=lines.length;i++) { + if (resolutions.hasOwnProperty(i)) { + currentBlock = resolutions[i]; + if (currentBlock.selection === "A") { + ignoreBlock = false; + } else { + ignoreBlock = true; + } + continue; + } + if (currentBlock) { + if (currentBlock.separator === i) { + if (currentBlock.selection === "A") { + ignoreBlock = true; + } else { + ignoreBlock = false; + } + continue; + } else if (currentBlock.changeEnd === i) { + currentBlock = null; + continue; + } else if (ignoreBlock) { + continue; + } + } + result.push(lines[i-1]); + } + var finalResult = result.join("\n"); + return util.writeFile(filePath,finalResult).then(function() { + return self.stageFile(file); + }) + }); +}; + +Project.prototype.abortMerge = function () { + var self = this; + return gitTools.abortMerge(this.path).then(function() { + self.merging = false; + }) +}; + +Project.prototype.getBranches = function (user, isRemote) { + var self = this; + var fetchPromise; + if (isRemote) { + fetchPromise = self.fetch(user); + } else { + fetchPromise = Promise.resolve(); + } + return fetchPromise.then(function() { + return gitTools.getBranches(self.path,isRemote); + }); +}; + +Project.prototype.deleteBranch = function (user, branch, isRemote, force) { + // TODO: isRemote==true support + // TODO: make sure we don't try to delete active branch + return gitTools.deleteBranch(this.path,branch,isRemote, force); +}; + +Project.prototype.fetch = function(user,remoteName) { + var username; + if (!user) { + username = "_"; + } else { + username = user.username; + } + var project = this; + if (remoteName) { + return gitTools.fetch(project.path,remoteName,authCache.get(project.name,project.remotes[remoteName].fetch,username)).catch(function(err) { + err.remote = remoteName; + throw err; + }) + } else { + var remotes = Object.keys(this.remotes); + var promise = Promise.resolve(); + remotes.forEach(function(remote) { + promise = promise.then(function() { + return gitTools.fetch(project.path,remote,authCache.get(project.name,project.remotes[remote].fetch,username)) + }).catch(function(err) { + err.remote = remote; + throw err; + }) + }); + return promise; + } +} + +Project.prototype.setBranch = function (branchName, isCreate) { + var self = this; + return gitTools.checkoutBranch(this.path, branchName, isCreate).then(function() { + return self.load(); + }) +}; + +Project.prototype.getBranchStatus = function (branchName) { + return gitTools.getBranchStatus(this.path,branchName); +}; + +Project.prototype.getRemotes = function (user) { + return gitTools.getRemotes(this.path).then(function(remotes) { + var result = []; + for (var name in remotes) { + if (remotes.hasOwnProperty(name)) { + remotes[name].name = name; + result.push(remotes[name]); + } + } + return {remotes:result}; + }) +}; + +Project.prototype.addRemote = function(user,remote,options) { + var project = this; + return gitTools.addRemote(this.path,remote,options).then(function() { + return project.loadRemotes() + }); +} + +Project.prototype.updateRemote = function(user,remote,options) { + var username; + if (!user) { + username = "_"; + } else { + username = user.username; + } + + if (options.auth) { + var url = this.remotes[remote].fetch; + if (options.auth.keyFile) { + options.auth.key_path = sshKeys.getPrivateKeyPath(getSSHKeyUsername(user), options.auth.keyFile); + } + authCache.set(this.name,url,username,options.auth); + } + return Promise.resolve(); +} + +Project.prototype.removeRemote = function(user, remote) { + // TODO: if this was the last remote using this url, then remove the authCache + // details. + var project = this; + return gitTools.removeRemote(this.path,remote).then(function() { + return project.loadRemotes() + }); +} + +Project.prototype.getFlowFile = function() { + // console.log("Project.getFlowFile = ",this.paths.flowFile); + if (this.paths.flowFile) { + return fspath.join(this.path,this.paths.flowFile); + } else { + return null; + } +} + +Project.prototype.getFlowFileBackup = function() { + var flowFile = this.getFlowFile(); + if (flowFile) { + return getBackupFilename(flowFile); + } + return null; +} + +Project.prototype.getCredentialsFile = function() { + // console.log("Project.getCredentialsFile = ",this.paths.credentialsFile); + if (this.paths.credentialsFile) { + return fspath.join(this.path,this.paths.credentialsFile); + } else { + return this.paths.credentialsFile; + } +} + +Project.prototype.getCredentialsFileBackup = function() { + return getBackupFilename(this.getCredentialsFile()); +} + +Project.prototype.export = function () { + + return { + name: this.name, + summary: this.package.description, + description: this.description, + dependencies: this.package.dependencies||{}, + empty: this.empty, + settings: { + credentialsEncrypted: (typeof this.credentialSecret === "string") && this.credentialSecret.length > 0, + credentialSecretInvalid: this.credentialSecretInvalid + }, + files: { + package: this.paths['package.json'], + flow: this.paths.flowFile, + credentials: this.paths.credentialsFile + }, + git: { + remotes: this.remotes, + branches: this.branches + } + } +}; + +function getCredentialsFilename(filename) { + filename = filename || "undefined"; + // TODO: DRY - ./index.js + var ffDir = fspath.dirname(filename); + var ffExt = fspath.extname(filename); + var ffBase = fspath.basename(filename,ffExt); + return fspath.join(ffDir,ffBase+"_cred"+ffExt); +} +function getBackupFilename(filename) { + // TODO: DRY - ./index.js + filename = filename || "undefined"; + var ffName = fspath.basename(filename); + var ffDir = fspath.dirname(filename); + return fspath.join(ffDir,"."+ffName+".backup"); +} +function checkProjectExists(projectPath) { + return fs.pathExists(projectPath).then(function(exists) { + if (!exists) { + var e = new Error("Project not found"); + e.code = "project_not_found"; + var name = fspath.basename(projectPath); + e.project = name; + throw e; + } + }); +} +function createDefaultProject(user, project) { + var projectPath = fspath.join(projectsDir,project.name); + // Create a basic skeleton of a project + return gitTools.initRepo(projectPath).then(function() { + var promises = []; + var files = Object.keys(defaultFileSet); + if (project.files) { + if (project.files.flow && !/\.\./.test(project.files.flow)) { + var flowFilePath; + var credsFilePath; + + if (project.migrateFiles) { + var baseFlowFileName = project.files.flow || fspath.basename(project.files.oldFlow); + var baseCredentialFileName = project.files.credentials || fspath.basename(project.files.oldCredentials); + files.push(baseFlowFileName); + files.push(baseCredentialFileName); + flowFilePath = fspath.join(projectPath,baseFlowFileName); + credsFilePath = fspath.join(projectPath,baseCredentialFileName); + if (fs.existsSync(project.files.oldFlow)) { + log.trace("Migrating "+project.files.oldFlow+" to "+flowFilePath); + promises.push(fs.copy(project.files.oldFlow,flowFilePath)); + } else { + log.trace(project.files.oldFlow+" does not exist - creating blank file"); + promises.push(util.writeFile(flowFilePath,"[]")); + } + log.trace("Migrating "+project.files.oldCredentials+" to "+credsFilePath); + runtime.nodes.setCredentialSecret(project.credentialSecret); + promises.push(runtime.nodes.exportCredentials().then(function(creds) { + var credentialData; + if (settings.flowFilePretty) { + credentialData = JSON.stringify(creds,null,4); + } else { + credentialData = JSON.stringify(creds); + } + return util.writeFile(credsFilePath,credentialData); + })); + delete project.migrateFiles; + project.files.flow = baseFlowFileName; + project.files.credentials = baseCredentialFileName; + } else { + project.files.credentials = project.files.credentials || getCredentialsFilename(project.files.flow); + files.push(project.files.flow); + files.push(project.files.credentials); + flowFilePath = fspath.join(projectPath,project.files.flow); + credsFilePath = getCredentialsFilename(flowFilePath); + promises.push(util.writeFile(flowFilePath,"[]")); + promises.push(util.writeFile(credsFilePath,"{}")); + } + } + } + for (var file in defaultFileSet) { + if (defaultFileSet.hasOwnProperty(file)) { + promises.push(util.writeFile(fspath.join(projectPath,file),defaultFileSet[file](project))); + } + } + + return when.all(promises).then(function() { + return gitTools.stageFile(projectPath,files); + }).then(function() { + return gitTools.commit(projectPath,"Create project",getGitUser(user)); + }) + }); +} +function checkProjectFiles(project) { + var promises = []; + var paths = []; + for (var file in defaultFileSet) { + if (defaultFileSet.hasOwnProperty(file)) { + paths.push(file); + promises.push(fs.stat(fspath.join(project.path,project.paths.root,file))); + } + } + return when.settle(promises).then(function(results) { + var missing = []; + results.forEach(function(result,i) { + if (result.state === 'rejected') { + missing.push(paths[i]); + } + }); + return missing; + }).then(function(missing) { + // if (createMissing) { + // var promises = []; + // missing.forEach(function(file) { + // promises.push(util.writeFile(fspath.join(projectPath,file),defaultFileSet[file](project))); + // }); + // return promises; + // } else { + return missing; + // } + }); +} +function createProject(user, metadata) { + var username; + if (!user) { + username = "_"; + } else { + username = user.username; + } + if (!metadata.path) { + throw new Error("Project missing path property"); + } + if (!metadata.name) { + throw new Error("Project missing name property"); + } + + var project = metadata.name; + var projectPath = metadata.path; + return new Promise(function(resolve,reject) { + fs.stat(projectPath, function(err,stat) { + if (!err) { + var e = new Error("NLS: Project already exists"); + e.code = "project_exists"; + return reject(e); + } + fs.ensureDir(projectPath).then(function() { + var projects = settings.get('projects'); + if (!projects) { + projects = { + projects:{} + } + } + projects.projects[project] = {}; + if (metadata.hasOwnProperty('credentialSecret')) { + if (metadata.credentialSecret === "") { + metadata.credentialSecret = false; + } + projects.projects[project].credentialSecret = metadata.credentialSecret; + } + return settings.set('projects',projects); + }).then(function() { + if (metadata.git && metadata.git.remotes && metadata.git.remotes.origin) { + var originRemote = metadata.git.remotes.origin; + var auth; + if (originRemote.hasOwnProperty("username") && originRemote.hasOwnProperty("password")) { + authCache.set(project,originRemote.url,username,{ // TODO: hardcoded remote name + username: originRemote.username, + password: originRemote.password + } + ); + auth = authCache.get(project,originRemote.url,username); + } + else if (originRemote.hasOwnProperty("keyFile") && originRemote.hasOwnProperty("passphrase")) { + authCache.set(project,originRemote.url,username,{ // TODO: hardcoded remote name + key_path: sshKeys.getPrivateKeyPath(getSSHKeyUsername(user), originRemote.keyFile), + passphrase: originRemote.passphrase + } + ); + auth = authCache.get(project,originRemote.url,username); + } + return gitTools.clone(originRemote,auth,projectPath); + } else { + return createDefaultProject(user, metadata); + } + }).then(function() { + resolve(loadProject(projectPath)) + }).catch(function(err) { + fs.remove(projectPath,function() { + reject(err); + }); + }); + }) + }) +} +function deleteProject(user, projectPath) { + return checkProjectExists(projectPath).then(function() { + return fs.remove(projectPath).then(function() { + var name = fspath.basename(projectPath); + var projects = settings.get('projects'); + delete projects.projects[name]; + return settings.set('projects', projects); + }); + }); +} +function loadProject(projectPath) { + return checkProjectExists(projectPath).then(function() { + var project = new Project(projectPath); + return project.load(); + }); +} +function init(_settings, _runtime) { + settings = _settings; + runtime = _runtime; + projectsDir = fspath.join(settings.userDir,"projects"); + authCache.init(); +} + +module.exports = { + init: init, + load: loadProject, + create: createProject, + delete: deleteProject +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/defaultFileSet.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/defaultFileSet.js new file mode 100644 index 0000000..04b95e3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/defaultFileSet.js @@ -0,0 +1,48 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var i18n = require("@node-red/util").i18n; + +module.exports = { + "package.json": function(project) { + var package = { + "name": project.name, + "description": project.summary||i18n._("storage.localfilesystem.projects.summary"), + "version": "0.0.1", + "dependencies": {}, + "node-red": { + "settings": { + } + } + }; + if (project.files) { + if (project.files.flow) { + package['node-red'].settings.flowFile = project.files.flow; + package['node-red'].settings.credentialsFile = project.files.credentials; + } + } + return JSON.stringify(package,"",4); + }, + "README.md": function(project) { + var content = project.name+"\n"+("=".repeat(project.name.length))+"\n\n"; + if (project.summary) { + content += project.summary+"\n\n"; + } + content += i18n._("storage.localfilesystem.projects.readme"); + return content; + }, + ".gitignore": function() { return "*.backup" ;} +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/authCache.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/authCache.js new file mode 100644 index 0000000..6780476 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/authCache.js @@ -0,0 +1,46 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var authCache = {} + +module.exports = { + init: function() { + authCache = {}; + }, + clear: function(project,remote, user) { + if (user && remote && authCache[project] && authCache[project][remote]) { + delete authCache[project][remote][user]; + } else if (remote && authCache.hasOwnProperty(project)) { + delete authCache[project][remote]; + } else { + delete authCache[project]; + } + }, + set: function(project,remote,user,auth) { + // console.log("AuthCache.set",remote,user,auth); + authCache[project] = authCache[project]||{}; + authCache[project][remote] = authCache[project][remote]||{}; + authCache[project][remote][user] = auth; + // console.log(JSON.stringify(authCache,'',4)); + }, + get: function(project,remote,user) { + // console.log("AuthCache.get",remote,user,authCache[project]&&authCache[project][remote]&&authCache[project][remote][user]); + if (authCache[project] && authCache[project][remote]) { + return authCache[project][remote][user]; + } + return + } +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/authServer.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/authServer.js new file mode 100644 index 0000000..95b4eda --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/authServer.js @@ -0,0 +1,132 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var net = require("net"); +var fs = require("fs-extra"); +var path = require("path"); +var os = require("os"); + +function getListenPath() { + var seed = (0x100000+Math.random()*0x999999).toString(16); + var fn = 'node-red-git-askpass-'+seed+'-sock'; + var listenPath; + if (process.platform === 'win32') { + listenPath = '\\\\.\\pipe\\'+fn; + } else { + listenPath = path.join(process.env['XDG_RUNTIME_DIR'] || os.tmpdir(), fn); + } + // console.log(listenPath); + return listenPath; +} + + + +var ResponseServer = function(auth) { + return new Promise(function(resolve, reject) { + var server = net.createServer(function(connection) { + connection.setEncoding('utf8'); + var parts = []; + connection.on('data', function(data) { + var m = data.indexOf("\n"); + if (m !== -1) { + parts.push(data.substring(0, m)); + data = data.substring(m); + var line = parts.join(""); + // console.log("LINE:",line); + parts = []; + if (line==='Username') { + connection.end(auth.username); + } else if (line === 'Password') { + connection.end(auth.password); + server.close(); + } else { + } + } + if (data.length > 0) { + parts.push(data); + } + + }); + }); + + var listenPath = getListenPath(); + + server.listen(listenPath, function(ready) { + resolve({path:listenPath,close:function() { server.close(); }}); + }); + server.on('close', function() { + // console.log("Closing response server"); + fs.removeSync(listenPath); + }); + server.on('error',function(err) { + console.log("ResponseServer unexpectedError:",err.toString()); + server.close(); + reject(err); + }) + }); +} + +var ResponseSSHServer = function(auth) { + return new Promise(function(resolve, reject) { + var server = net.createServer(function(connection) { + connection.setEncoding('utf8'); + var parts = []; + connection.on('data', function(data) { + var m = data.indexOf("\n"); + if (m !== -1) { + parts.push(data.substring(0, m)); + data = data.substring(m); + var line = parts.join(""); + parts = []; + if (line==='The') { + // TODO: document these exchanges! + connection.end('yes'); + // server.close(); + } else if (line === 'Enter') { + connection.end(auth.passphrase); + // server.close(); + } else { + } + } + if (data.length > 0) { + parts.push(data); + } + + }); + }); + + var listenPath = getListenPath(); + + server.listen(listenPath, function(ready) { + resolve({path:listenPath,close:function() { server.close(); }}); + }); + server.on('close', function() { + // console.log("Closing response server"); + fs.removeSync(listenPath); + }); + server.on('error',function(err) { + console.log("ResponseServer unexpectedError:",err.toString()); + server.close(); + reject(err); + }) + }); +} + + +module.exports = { + ResponseServer: ResponseServer, + ResponseSSHServer: ResponseSSHServer +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/authWriter.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/authWriter.js new file mode 100644 index 0000000..309c3ec --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/authWriter.js @@ -0,0 +1,24 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var net = require("net"); +var socket = net.connect(process.argv[2], function() { + socket.on('data', function(data) { console.log(data);}); + socket.on('end', function() { + }); + socket.write((process.argv[3]||"")+"\n", 'utf8'); +}); +socket.setEncoding('utf8'); diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/index.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/index.js new file mode 100644 index 0000000..d812c05 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/index.js @@ -0,0 +1,655 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var exec = require("../../../../exec"); + +var authResponseServer = require('./authServer').ResponseServer; +var sshResponseServer = require('./authServer').ResponseSSHServer; +var clone = require('clone'); +var path = require("path"); + +var gitCommand = "git"; +var gitVersion; +var log = require("@node-red/util").log; + +function runGitCommand(args,cwd,env,emit) { + log.trace(gitCommand + JSON.stringify(args)); + args.unshift("credential.helper=") + args.unshift("-c"); + return exec.run(gitCommand, args, {cwd:cwd, detached:true, env:env}, emit).then(result => { + return result.stdout; + }).catch(result => { + var stdout = result.stdout; + var stderr = result.stderr; + var err = new Error(stderr); + err.stdout = stdout; + err.stderr = stderr; + if (/Connection refused/i.test(stderr)) { + err.code = "git_connection_failed"; + } else if (/Connection timed out/i.test(stderr)) { + err.code = "git_connection_failed"; + } else if(/Host key verification failed/i.test(stderr)) { + // TODO: handle host key verification errors separately + err.code = "git_host_key_verification_failed"; + } else if (/fatal: could not read/i.test(stderr)) { + // Username/Password + err.code = "git_auth_failed"; + } else if(/HTTP Basic: Access denied/i.test(stderr)) { + err.code = "git_auth_failed"; + } else if(/Permission denied \(publickey\)/i.test(stderr)) { + err.code = "git_auth_failed"; + } else if (/commit your changes or stash/i.test(stderr)) { + err.code = "git_local_overwrite"; + } else if (/CONFLICT/.test(err.stdout)) { + err.code = "git_pull_merge_conflict"; + } else if (/not fully merged/i.test(stderr)) { + err.code = "git_delete_branch_unmerged"; + } else if (/remote .* already exists/i.test(stderr)) { + err.code = "git_remote_already_exists"; + } else if (/does not appear to be a git repository/i.test(stderr)) { + err.code = "git_not_a_repository"; + } else if (/Repository not found/i.test(stderr)) { + err.code = "git_repository_not_found"; + } else if (/repository '.*' does not exist/i.test(stderr)) { + err.code = "git_repository_not_found"; + } else if (/refusing to merge unrelated histories/i.test(stderr)) { + err.code = "git_pull_unrelated_history" + } else if (/Please tell me who you are/i.test(stderr)) { + err.code = "git_missing_user"; + } else if (/name consists only of disallowed characters/i.test(stderr)) { + err.code = "git_missing_user"; + } + throw err; + }) +} +function runGitCommandWithAuth(args,cwd,auth,emit) { + log.trace("runGitCommandWithAuth "+JSON.stringify(auth).replace(/("pass.*?"\s*:\s*").+?"/g,'$1[hidden]"')); + return authResponseServer(auth).then(function(rs) { + var commandEnv = clone(process.env); + commandEnv.GIT_ASKPASS = path.join(__dirname,"node-red-ask-pass.sh"); + commandEnv.NODE_RED_GIT_NODE_PATH = process.execPath; + commandEnv.NODE_RED_GIT_SOCK_PATH = rs.path; + commandEnv.NODE_RED_GIT_ASKPASS_PATH = path.join(__dirname,"authWriter.js"); + return runGitCommand(args,cwd,commandEnv,emit).then( result => { + rs.close(); + return result; + }).catch(err => { + rs.close(); + throw err; + }); + }) +} + +function runGitCommandWithSSHCommand(args,cwd,auth,emit) { + log.trace("runGitCommandWithSSHCommand "+JSON.stringify(auth).replace(/("pass.*?"\s*:\s*").+?"/g,'$1[hidden]"')); + return sshResponseServer(auth).then(function(rs) { + var commandEnv = clone(process.env); + commandEnv.SSH_ASKPASS = path.join(__dirname,"node-red-ask-pass.sh"); + commandEnv.DISPLAY = "dummy:0"; + commandEnv.NODE_RED_GIT_NODE_PATH = process.execPath; + commandEnv.NODE_RED_GIT_SOCK_PATH = rs.path; + commandEnv.NODE_RED_GIT_ASKPASS_PATH = path.join(__dirname,"authWriter.js"); + // For git < 2.3.0 + commandEnv.GIT_SSH = path.join(__dirname,"node-red-ssh.sh"); + commandEnv.NODE_RED_KEY_FILE=auth.key_path; + // GIT_SSH_COMMAND - added in git 2.3.0 + commandEnv.GIT_SSH_COMMAND = "ssh -i " + auth.key_path + " -F /dev/null"; + // console.log('commandEnv:', commandEnv); + return runGitCommand(args,cwd,commandEnv,emit).then( result => { + rs.close(); + return result; + }).catch(err => { + rs.close(); + throw err; + }); + }) +} + +function cleanFilename(name) { + if (name[0] !== '"') { + return name; + } + return name.substring(1,name.length-1); +} +function parseFilenames(name) { + var re = /([^ "]+|(".*?"))($| -> ([^ ]+|(".*"))$)/; + var m = re.exec(name); + var result = []; + if (m) { + result.push(cleanFilename(m[1])); + if (m[4]) { + result.push(cleanFilename(m[4])); + } + } + return result; +} +// function getBranchInfo(localRepo) { +// return runGitCommand(["status","--porcelain","-b"],localRepo).then(function(output) { +// var lines = output.split("\n"); +// var unknownDirs = []; +// var branchLineRE = /^## (No commits yet on )?(.+?)($|\.\.\.(.+?)($| \[(ahead (\d+))?.*?(behind (\d+))?\]))/m; +// console.log(output); +// console.log(lines); +// var m = branchLineRE.exec(output); +// console.log(m); +// var result = {}; //commits:{}}; +// if (m) { +// if (m[1]) { +// result.empty = true; +// } +// result.local = m[2]; +// if (m[4]) { +// result.remote = m[4]; +// } +// } +// return result; +// }); +// } +function getStatus(localRepo) { + // parseFilename('"test with space"'); + // parseFilename('"test with space" -> knownFile.txt'); + // parseFilename('"test with space" -> "un -> knownFile.txt"'); + var result = { + files: {}, + commits: {}, + branches: {} + } + return runGitCommand(['rev-list', 'HEAD', '--count'],localRepo).then(function(count) { + result.commits.total = parseInt(count); + }).catch(function(err) { + if (/ambiguous argument/i.test(err.message)) { + result.commits.total = 0; + } else { + throw err; + } + }).then(function() { + return runGitCommand(["ls-files","--cached","--others","--exclude-standard"],localRepo).then(function(output) { + var lines = output.split("\n"); + lines.forEach(function(l) { + if (l==="") { + return; + } + var fullName = cleanFilename(l); + // parseFilename(l); + var parts = fullName.split("/"); + var p = result.files; + var name; + for (var i = 0;i<parts.length-1;i++) { + var name = parts.slice(0,i+1).join("/")+"/"; + if (!p.hasOwnProperty(name)) { + p[name] = { + type:"d" + } + } + } + result.files[fullName] = { + type: /\/$/.test(fullName)?"d":"f" + } + }) + return runGitCommand(["status","--porcelain","-b"],localRepo).then(function(output) { + var lines = output.split("\n"); + var unknownDirs = []; + var branchLineRE = /^## (?:(?:No commits yet on )|(?:Initial commit on))?(.+?)(?:$|\.\.\.(.+?)(?:$| \[(?:(?:ahead (\d+)(?:,\s*)?)?(?:behind (\d+))?|(gone))\]))/; + lines.forEach(function(line) { + if (line==="") { + return; + } + if (line[0] === "#") { + var m = branchLineRE.exec(line); + if (m) { + result.branches.local = m[1]; + if (m[2]) { + result.branches.remote = m[2]; + result.commits.ahead = 0; + result.commits.behind = 0; + } + if (m[3] !== undefined) { + result.commits.ahead = parseInt(m[3]); + } + if (m[4] !== undefined) { + result.commits.behind = parseInt(m[4]); + } + if (m[5] !== undefined) { + result.commits.ahead = result.commits.total; + result.branches.remoteError = { + code: "git_remote_gone" + } + } + } + return; + } + var status = line.substring(0,2); + var fileName; + var names; + if (status !== '??') { + names = parseFilenames(line.substring(3)); + } else { + names = [cleanFilename(line.substring(3))]; + } + fileName = names[0]; + if (names.length > 1) { + fileName = names[1]; + } + + // parseFilename(fileName); + if (fileName.charCodeAt(0) === 34) { + fileName = fileName.substring(1,fileName.length-1); + } + if (result.files.hasOwnProperty(fileName)) { + result.files[fileName].status = status; + } else { + result.files[fileName] = { + type: "f", + status: status + }; + } + if (names.length > 1) { + result.files[fileName].oldName = names[0]; + } + if (status === "??" && fileName[fileName.length-1] === '/') { + unknownDirs.push(fileName); + } + }) + var allFilenames = Object.keys(result.files); + allFilenames.forEach(function(f) { + var entry = result.files[f]; + if (!entry.hasOwnProperty('status')) { + unknownDirs.forEach(function(uf) { + if (f.startsWith(uf)) { + entry.status = "??" + } + }); + } + }) + // console.log(files); + return result; + }) + }) + }) +} + +function parseLog(log) { + var lines = log.split("\n"); + var currentCommit = {}; + var commits = []; + lines.forEach(function(l) { + if (l === "-----") { + commits.push(currentCommit); + currentCommit = {} + return; + } + var m = /^(.*): (.*)$/.exec(l); + if (m) { + // git 2.1.4 (Debian Stable) doesn't support %D for refs - so filter out + if (m[1] === 'refs' && m[2]) { + if (m[2] !== '%D') { + currentCommit[m[1]] = m[2].split(",").map(function(v) { return v.trim() }); + } else { + currentCommit[m[1]] = []; + } + } else { + if (m[1] === 'parents') { + currentCommit[m[1]] = m[2].split(" "); + } else { + currentCommit[m[1]] = m[2]; + } + } + } + }); + return commits; +} + +function getRemotes(cwd) { + return runGitCommand(['remote','-v'],cwd).then(function(output) { + var result; + if (output.length > 0) { + result = {}; + var remoteRE = /^(.+)\t(.+) \((.+)\)$/gm; + var m; + while ((m = remoteRE.exec(output)) !== null) { + result[m[1]] = result[m[1]]||{}; + result[m[1]][m[3]] = m[2]; + } + } + return result; + }) +} + +function getBranches(cwd, remote) { + var args = ['branch','-vv','--no-color']; + if (remote) { + args.push('-r'); + } + var branchRE = /^([ \*] )(\S+) +(\S+)(?: \[(\S+?)(?:: (?:ahead (\d+)(?:, )?)?(?:behind (\d+))?)?\])? (.*)$/; + return runGitCommand(args,cwd).then(function(output) { + var branches = []; + var lines = output.split("\n"); + branches = lines.map(function(l) { + var m = branchRE.exec(l); + var branch = null; + if (m) { + branch = { + name: m[2], + remote: m[4], + status: { + ahead: m[5]||0, + behind: m[6]||0, + }, + commit: { + sha: m[3], + subject: m[7] + } + } + if (m[1] === '* ') { + branch.current = true; + } + } + return branch; + }).filter(function(v) { return !!v && v.commit.sha !== '->' }); + + return {branches:branches}; + }) +} +function getBranchStatus(cwd,remoteBranch) { + var commands = [ + // #commits master ahead + runGitCommand(['rev-list', 'HEAD','^'+remoteBranch, '--count'],cwd), + // #commits master behind + runGitCommand(['rev-list', '^HEAD',remoteBranch, '--count'],cwd) + ]; + return Promise.all(commands).then(function(results) { + return { + commits: { + ahead: parseInt(results[0]), + behind: parseInt(results[1]) + } + } + }) +} + +function addRemote(cwd,name,options) { + var args = ["remote","add",name,options.url] + return runGitCommand(args,cwd); +} +function removeRemote(cwd,name) { + var args = ["remote","remove",name]; + return runGitCommand(args,cwd); +} + +module.exports = { + init: function(_settings) { + return new Promise(function(resolve,reject) { + Promise.all([ + runGitCommand(["--version"]), + runGitCommand(["config","--global","user.name"]).catch(err=>""), + runGitCommand(["config","--global","user.email"]).catch(err=>"") + ]).then(function(output) { + var m = / (\d\S+)/.exec(output[0]); + gitVersion = m[1]; + var globalUserName = output[1].trim(); + var globalUserEmail = output[2].trim(); + var result = { + version: gitVersion + }; + if (globalUserName && globalUserEmail) { + result.user = { + name: globalUserName, + email: globalUserEmail + } + } + log.trace("git init: "+JSON.stringify(result)); + resolve(result); + }).catch(function(err) { + log.trace("git init: git not found"); + resolve(null); + }); + }); + }, + initRepo: function(cwd) { + return runGitCommand(["init"],cwd); + }, + setUpstream: function(cwd,remoteBranch) { + var args = ["branch","--set-upstream-to",remoteBranch]; + return runGitCommand(args,cwd); + }, + pull: function(cwd,remote,branch,allowUnrelatedHistories,auth,gitUser) { + var args = ["pull"]; + if (remote && branch) { + args.push(remote); + args.push(branch); + } + if (gitUser && gitUser['name'] && gitUser['email']) { + args.unshift('user.name="'+gitUser['name']+'"'); + args.unshift('-c'); + args.unshift('user.email="'+gitUser['email']+'"'); + args.unshift('-c'); + } + if (allowUnrelatedHistories) { + args.push("--allow-unrelated-histories"); + } + var promise; + if (auth) { + if ( auth.key_path ) { + promise = runGitCommandWithSSHCommand(args,cwd,auth,true); + } + else { + promise = runGitCommandWithAuth(args,cwd,auth,true); + } + } else { + promise = runGitCommand(args,cwd,undefined,true) + } + return promise; + // .catch(function(err) { + // if (/CONFLICT/.test(err.stdout)) { + // var e = new Error("pull failed - merge conflict"); + // e.code = "git_pull_merge_conflict"; + // throw e; + // } else if (/Please commit your changes or stash/i.test(err.message)) { + // var e = new Error("Pull failed - local changes would be overwritten"); + // e.code = "git_pull_overwrite"; + // throw e; + // } + // throw err; + // }); + }, + push: function(cwd,remote,branch,setUpstream, auth) { + var args = ["push"]; + if (branch) { + if (setUpstream) { + args.push("-u"); + } + args.push(remote); + args.push("HEAD:"+branch); + } else { + args.push(remote); + } + args.push("--porcelain"); + var promise; + if (auth) { + if ( auth.key_path ) { + promise = runGitCommandWithSSHCommand(args,cwd,auth,true); + } + else { + promise = runGitCommandWithAuth(args,cwd,auth,true); + } + } else { + promise = runGitCommand(args,cwd,undefined,true) + } + return promise.catch(function(err) { + if (err.code === 'git_error') { + if (/^!.*non-fast-forward/m.test(err.stdout)) { + err.code = 'git_push_failed'; + } + throw err; + } else { + throw err; + } + }); + }, + clone: function(remote, auth, cwd) { + var args = ["clone",remote.url]; + if (remote.name) { + args.push("-o"); + args.push(remote.name); + } + if (remote.branch) { + args.push("-b"); + args.push(remote.branch); + } + args.push("."); + if (auth) { + if ( auth.key_path ) { + return runGitCommandWithSSHCommand(args,cwd,auth,true); + } + else { + return runGitCommandWithAuth(args,cwd,auth,true); + } + } else { + return runGitCommand(args,cwd,undefined,true); + } + }, + getStatus: getStatus, + getFile: function(cwd, filePath, treeish) { + var args = ["show",treeish+":"+filePath]; + return runGitCommand(args,cwd); + }, + getFiles: function(cwd) { + return getStatus(cwd).then(function(status) { + return status.files; + }) + }, + revertFile: function(cwd, filePath) { + var args = ["checkout",filePath]; + return runGitCommand(args,cwd); + }, + stageFile: function(cwd,file) { + var args = ["add"]; + if (Array.isArray(file)) { + args = args.concat(file); + } else { + args.push(file); + } + return runGitCommand(args,cwd); + }, + unstageFile: function(cwd, file) { + var args = ["reset","--"]; + if (file) { + args.push(file); + } + return runGitCommand(args,cwd); + }, + commit: function(cwd, message, gitUser) { + var args = ["commit","-m",message]; + var env; + if (gitUser && gitUser['name'] && gitUser['email']) { + args.unshift('user.name="'+gitUser['name']+'"'); + args.unshift('-c'); + args.unshift('user.email="'+gitUser['email']+'"'); + args.unshift('-c'); + } + return runGitCommand(args,cwd,env); + }, + getFileDiff(cwd,file,type) { + var args = ["diff","-w"]; + if (type === "tree") { + // nothing else to do + } else if (type === "index") { + args.push("--cached"); + } + args.push(file); + return runGitCommand(args,cwd); + }, + fetch: function(cwd,remote,auth) { + var args = ["fetch",remote]; + if (auth) { + if ( auth.key_path ) { + return runGitCommandWithSSHCommand(args,cwd,auth); + } + else { + return runGitCommandWithAuth(args,cwd,auth); + } + } else { + return runGitCommand(args,cwd); + } + }, + getCommits: function(cwd,options) { + var args = ["log", "--format=sha: %H%nparents: %p%nrefs: %D%nauthor: %an%ndate: %ct%nsubject: %s%n-----"]; + var limit = parseInt(options.limit) || 20; + args.push("-n "+limit); + var before = options.before; + if (before) { + args.push(before); + } + var commands = [ + runGitCommand(['rev-list', 'HEAD', '--count'],cwd), + runGitCommand(args,cwd).then(parseLog) + ]; + return Promise.all(commands).then(function(results) { + var result = results[0]; + result.count = results[1].length; + result.before = before; + result.commits = results[1]; + return { + count: results[1].length, + commits: results[1], + before: before, + total: parseInt(results[0]) + }; + }) + }, + getCommit: function(cwd,sha) { + var args = ["show",sha]; + return runGitCommand(args,cwd); + }, + abortMerge: function(cwd) { + return runGitCommand(['merge','--abort'],cwd); + }, + getRemotes: getRemotes, + getRemoteBranch: function(cwd) { + return runGitCommand(['rev-parse','--abbrev-ref','--symbolic-full-name','@{u}'],cwd).catch(function(err) { + if (/no upstream configured for branch/i.test(err.message)) { + return null; + } + throw err; + }) + }, + getBranches: getBranches, + // getBranchInfo: getBranchInfo, + checkoutBranch: function(cwd, branchName, isCreate) { + var args = ['checkout']; + if (isCreate) { + args.push('-b'); + } + args.push(branchName); + return runGitCommand(args,cwd); + }, + deleteBranch: function(cwd, branchName, isRemote, force) { + if (isRemote) { + throw new Error("Deleting remote branches not supported"); + } + var args = ['branch']; + if (force) { + args.push('-D'); + } else { + args.push('-d'); + } + args.push(branchName); + return runGitCommand(args, cwd); + }, + getBranchStatus: getBranchStatus, + addRemote: addRemote, + removeRemote: removeRemote +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/node-red-ask-pass.sh b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/node-red-ask-pass.sh new file mode 100644 index 0000000..695b2a1 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/node-red-ask-pass.sh @@ -0,0 +1 @@ +"$NODE_RED_GIT_NODE_PATH" "$NODE_RED_GIT_ASKPASS_PATH" "$NODE_RED_GIT_SOCK_PATH" $@ diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/node-red-ssh.sh b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/node-red-ssh.sh new file mode 100644 index 0000000..26a232f --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/node-red-ssh.sh @@ -0,0 +1 @@ +ssh -i "$NODE_RED_KEY_FILE" -F /dev/null $@ diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/index.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/index.js new file mode 100644 index 0000000..82c1f8d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/index.js @@ -0,0 +1,646 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var fs = require('fs-extra'); +var when = require('when'); +var fspath = require("path"); +var nodeFn = require('when/node/function'); +var crypto = require('crypto'); + +var storageSettings = require("../settings"); +var util = require("../util"); +var gitTools = require("./git"); +var sshTools = require("./ssh"); + +var Projects = require("./Project"); + +var settings; +var runtime; +var log = require("@node-red/util").log; + +var projectsEnabled = false; +var projectLogMessages = []; + +var projectsDir; +var activeProject + +var globalGitUser = false; + +function init(_settings, _runtime) { + settings = _settings; + runtime = _runtime; + + try { + if (settings.editorTheme.projects.enabled === true) { + projectsEnabled = true; + } else if (settings.editorTheme.projects.enabled === false) { + projectLogMessages.push(log._("storage.localfilesystem.projects.disabled")) + } + } catch(err) { + projectLogMessages.push(log._("storage.localfilesystem.projects.disabledNoFlag")) + projectsEnabled = false; + } + + if (settings.flowFile) { + flowsFile = settings.flowFile; + // handle Unix and Windows "C:\" and Windows "\\" for UNC. + if (fspath.isAbsolute(flowsFile)) { + //if (((flowsFile[0] == "\\") && (flowsFile[1] == "\\")) || (flowsFile[0] == "/") || (flowsFile[1] == ":")) { + // Absolute path + flowsFullPath = flowsFile; + } else if (flowsFile.substring(0,2) === "./") { + // Relative to cwd + flowsFullPath = fspath.join(process.cwd(),flowsFile); + } else { + try { + fs.statSync(fspath.join(process.cwd(),flowsFile)); + // Found in cwd + flowsFullPath = fspath.join(process.cwd(),flowsFile); + } catch(err) { + // Use userDir + flowsFullPath = fspath.join(settings.userDir,flowsFile); + } + } + + } else { + flowsFile = 'flows_'+require('os').hostname()+'.json'; + flowsFullPath = fspath.join(settings.userDir,flowsFile); + } + var ffExt = fspath.extname(flowsFullPath); + var ffBase = fspath.basename(flowsFullPath,ffExt); + + flowsFileBackup = getBackupFilename(flowsFullPath); + credentialsFile = fspath.join(settings.userDir,ffBase+"_cred"+ffExt); + credentialsFileBackup = getBackupFilename(credentialsFile) + + var setupProjectsPromise; + + if (projectsEnabled) { + return sshTools.init(settings,runtime).then(function() { + gitTools.init(_settings).then(function(gitConfig) { + if (!gitConfig || /^1\./.test(gitConfig.version)) { + if (!gitConfig) { + projectLogMessages.push(log._("storage.localfilesystem.projects.git-not-found")) + } else { + projectLogMessages.push(log._("storage.localfilesystem.projects.git-version-old",{version:gitConfig.version})) + } + projectsEnabled = false; + try { + // As projects have to be turned on, we know this property + // must exist at this point, so turn it off. + // TODO: when on-by-default, this will need to do more + // work to disable. + settings.editorTheme.projects.enabled = false; + } catch(err) { + } + } else { + globalGitUser = gitConfig.user; + Projects.init(settings,runtime); + sshTools.init(settings); + projectsDir = fspath.join(settings.userDir,"projects"); + if (!settings.readOnly) { + return fs.ensureDir(projectsDir) + //TODO: this is accessing settings from storage directly as settings + // has not yet been initialised. That isn't ideal - can this be deferred? + .then(storageSettings.getSettings) + .then(function(globalSettings) { + var saveSettings = false; + if (!globalSettings.projects) { + globalSettings.projects = { + projects: {} + } + saveSettings = true; + } else { + activeProject = globalSettings.projects.activeProject; + } + if (!globalSettings.projects.projects) { + globalSettings.projects.projects = {}; + saveSettings = true; + } + if (settings.flowFile) { + // if flowFile is a known project name - use it + if (globalSettings.projects.projects.hasOwnProperty(settings.flowFile)) { + activeProject = settings.flowFile; + globalSettings.projects.activeProject = settings.flowFile; + saveSettings = true; + } else { + // if it resolves to a dir - use it + try { + var stat = fs.statSync(fspath.join(projectsDir,settings.flowFile)); + if (stat && stat.isDirectory()) { + activeProject = settings.flowFile; + globalSettings.projects.activeProject = activeProject; + // Now check for a credentialSecret + if (settings.credentialSecret !== undefined) { + globalSettings.projects.projects[settings.flowFile] = { + credentialSecret: settings.credentialSecret + } + saveSettings = true; + } + } + } catch(err) { + // Doesn't exist, handle as a flow file to be created + } + } + } + if (!activeProject) { + projectLogMessages.push(log._("storage.localfilesystem.no-active-project")) + } + if (saveSettings) { + return storageSettings.saveSettings(globalSettings); + } + }); + } + } + }); + }); + } + return Promise.resolve(); +} + +function listProjects() { + return fs.readdir(projectsDir).then(function(fns) { + var dirs = []; + fns.sort(function(A,B) { + return A.toLowerCase().localeCompare(B.toLowerCase()); + }).filter(function(fn) { + var fullPath = fspath.join(projectsDir,fn); + if (fn[0] != ".") { + var stats = fs.lstatSync(fullPath); + if (stats.isDirectory()) { + dirs.push(fn); + } + } + }); + return dirs; + }); +} + +function getUserGitSettings(user) { + var userSettings = settings.getUserSettings(user)||{}; + return userSettings.git; +} + +function getBackupFilename(filename) { + var ffName = fspath.basename(filename); + var ffDir = fspath.dirname(filename); + return fspath.join(ffDir,"."+ffName+".backup"); +} + +function loadProject(name) { + var projectPath = name; + if (projectPath.indexOf(fspath.sep) === -1) { + projectPath = fspath.join(projectsDir,name); + } + return Projects.load(projectPath).then(function(project) { + activeProject = project; + flowsFullPath = project.getFlowFile(); + flowsFileBackup = project.getFlowFileBackup(); + credentialsFile = project.getCredentialsFile(); + credentialsFileBackup = project.getCredentialsFileBackup(); + return project; + }) +} + +function getProject(user, name) { + checkActiveProject(name); + //return when.resolve(activeProject.info); + return Promise.resolve(activeProject.export()); +} + +function deleteProject(user, name) { + if (activeProject && activeProject.name === name) { + var e = new Error("NLS: Can't delete the active project"); + e.code = "cannot_delete_active_project"; + throw e; + } + var projectPath = fspath.join(projectsDir,name); + return Projects.delete(user, projectPath); +} + +function checkActiveProject(project) { + if (!activeProject || activeProject.name !== project) { + //TODO: throw better err + throw new Error("Cannot operate on inactive project wanted:"+project+" current:"+(activeProject&&activeProject.name)); + } +} +function getFiles(user, project) { + checkActiveProject(project); + return activeProject.getFiles(); +} +function stageFile(user, project,file) { + checkActiveProject(project); + return activeProject.stageFile(file); +} +function unstageFile(user, project,file) { + checkActiveProject(project); + return activeProject.unstageFile(file); +} +function commit(user, project,options) { + checkActiveProject(project); + var isMerging = activeProject.isMerging(); + return activeProject.commit(user, options).then(function() { + // The project was merging, now it isn't. Lets reload. + if (isMerging && !activeProject.isMerging()) { + return reloadActiveProject("merge-complete"); + } + }) +} +function getFileDiff(user, project,file,type) { + checkActiveProject(project); + return activeProject.getFileDiff(file,type); +} +function getCommits(user, project,options) { + checkActiveProject(project); + return activeProject.getCommits(options); +} +function getCommit(user, project,sha) { + checkActiveProject(project); + return activeProject.getCommit(sha); +} + +function getFile(user, project,filePath,sha) { + checkActiveProject(project); + return activeProject.getFile(filePath,sha); +} +function revertFile(user, project,filePath) { + checkActiveProject(project); + return activeProject.revertFile(filePath).then(function() { + return reloadActiveProject("revert"); + }) +} +function push(user, project,remoteBranchName,setRemote) { + checkActiveProject(project); + return activeProject.push(user,remoteBranchName,setRemote); +} +function pull(user, project,remoteBranchName,setRemote,allowUnrelatedHistories) { + checkActiveProject(project); + return activeProject.pull(user,remoteBranchName,setRemote,allowUnrelatedHistories).then(function() { + return reloadActiveProject("pull"); + }); +} +function getStatus(user, project, includeRemote) { + checkActiveProject(project); + return activeProject.status(user, includeRemote); +} +function resolveMerge(user, project,file,resolution) { + checkActiveProject(project); + return activeProject.resolveMerge(file,resolution); +} +function abortMerge(user, project) { + checkActiveProject(project); + return activeProject.abortMerge().then(function() { + return reloadActiveProject("merge-abort") + }); +} +function getBranches(user, project,isRemote) { + checkActiveProject(project); + return activeProject.getBranches(user, isRemote); +} + +function deleteBranch(user, project, branch, isRemote, force) { + checkActiveProject(project); + return activeProject.deleteBranch(user, branch, isRemote, force); +} + +function setBranch(user, project,branchName,isCreate) { + checkActiveProject(project); + return activeProject.setBranch(branchName,isCreate).then(function() { + return reloadActiveProject("change-branch"); + }); +} +function getBranchStatus(user, project,branchName) { + checkActiveProject(project); + return activeProject.getBranchStatus(branchName); +} + + +function getRemotes(user, project) { + checkActiveProject(project); + return activeProject.getRemotes(user); +} +function addRemote(user, project, options) { + checkActiveProject(project); + return activeProject.addRemote(user, options.name, options); +} +function removeRemote(user, project, remote) { + checkActiveProject(project); + return activeProject.removeRemote(user, remote); +} +function updateRemote(user, project, remote, body) { + checkActiveProject(project); + return activeProject.updateRemote(user, remote, body); +} + +function getActiveProject(user) { + return activeProject; +} + +function reloadActiveProject(action) { + return runtime.nodes.stopFlows().then(function() { + return runtime.nodes.loadFlows(true).then(function() { + runtime.events.emit("runtime-event",{id:"project-update", payload:{ project: activeProject.name, action:action}}); + }).catch(function(err) { + // We're committed to the project change now, so notify editors + // that it has changed. + runtime.events.emit("runtime-event",{id:"project-update", payload:{ project: activeProject.name, action:action}}); + throw err; + }); + }); +} +function createProject(user, metadata) { + // var userSettings = getUserGitSettings(user); + if (metadata.files && metadata.migrateFiles) { + // We expect there to be no active project in this scenario + if (activeProject) { + throw new Error("Cannot migrate as there is an active project"); + } + var currentEncryptionKey = settings.get('credentialSecret'); + if (currentEncryptionKey === undefined) { + currentEncryptionKey = settings.get('_credentialSecret'); + } + if (!metadata.hasOwnProperty('credentialSecret')) { + metadata.credentialSecret = currentEncryptionKey; + } + if (!metadata.files.flow) { + metadata.files.flow = fspath.basename(flowsFullPath); + } + if (!metadata.files.credentials) { + metadata.files.credentials = fspath.basename(credentialsFile); + } + + metadata.files.oldFlow = flowsFullPath; + metadata.files.oldCredentials = credentialsFile; + metadata.files.credentialSecret = currentEncryptionKey; + } + metadata.path = fspath.join(projectsDir,metadata.name); + return Projects.create(user, metadata).then(function(p) { + return setActiveProject(user, p.name); + }).then(function() { + return getProject(user, metadata.name); + }) +} +function setActiveProject(user, projectName) { + return loadProject(projectName).then(function(project) { + var globalProjectSettings = settings.get("projects"); + globalProjectSettings.activeProject = project.name; + return settings.set("projects",globalProjectSettings).then(function() { + log.info(log._("storage.localfilesystem.projects.changing-project",{project:(activeProject&&activeProject.name)||"none"})); + log.info(log._("storage.localfilesystem.flows-file",{path:flowsFullPath})); + // console.log("Updated file targets to"); + // console.log(flowsFullPath) + // console.log(credentialsFile) + return reloadActiveProject("loaded"); + }) + }); +} + +function initialiseProject(user, project, data) { + if (!activeProject || activeProject.name !== project) { + // TODO standardise + throw new Error("Cannot initialise inactive project"); + } + return activeProject.initialise(user,data).then(function(result) { + flowsFullPath = activeProject.getFlowFile(); + flowsFileBackup = activeProject.getFlowFileBackup(); + credentialsFile = activeProject.getCredentialsFile(); + credentialsFileBackup = activeProject.getCredentialsFileBackup(); + runtime.nodes.setCredentialSecret(activeProject.credentialSecret); + return reloadActiveProject("updated"); + }); +} +function updateProject(user, project, data) { + if (!activeProject || activeProject.name !== project) { + // TODO standardise + throw new Error("Cannot update inactive project"); + } + // In case this triggers a credential secret change + var isReset = data.resetCredentialSecret; + var wasInvalid = activeProject.credentialSecretInvalid; + + return activeProject.update(user,data).then(function(result) { + + if (result.flowFilesChanged) { + flowsFullPath = activeProject.getFlowFile(); + flowsFileBackup = activeProject.getFlowFileBackup(); + credentialsFile = activeProject.getCredentialsFile(); + credentialsFileBackup = activeProject.getCredentialsFileBackup(); + return reloadActiveProject("updated"); + } else if (result.credentialSecretChanged) { + if (isReset || !wasInvalid) { + if (isReset) { + runtime.nodes.clearCredentials(); + } + runtime.nodes.setCredentialSecret(activeProject.credentialSecret); + return runtime.nodes.exportCredentials() + .then(runtime.storage.saveCredentials) + .then(function() { + if (wasInvalid) { + return reloadActiveProject("updated"); + } + }); + } else if (wasInvalid) { + return reloadActiveProject("updated"); + } + } + }); +} +function setCredentialSecret(data) { //existingSecret,secret) { + var isReset = data.resetCredentialSecret; + var wasInvalid = activeProject.credentialSecretInvalid; + return activeProject.update(data).then(function() { + if (isReset || !wasInvalid) { + if (isReset) { + runtime.nodes.clearCredentials(); + } + runtime.nodes.setCredentialSecret(activeProject.credentialSecret); + return runtime.nodes.exportCredentials() + .then(runtime.storage.saveCredentials) + .then(function() { + if (wasInvalid) { + return reloadActiveProject("updated"); + } + }); + } else if (wasInvalid) { + return reloadActiveProject("updated"); + } + }) +} + + +var initialFlowLoadComplete = false; + +var flowsFile; +var flowsFullPath; +var flowsFileExists = false; +var flowsFileBackup; +var credentialsFile; +var credentialsFileBackup; + +function getFlows() { + if (!initialFlowLoadComplete) { + initialFlowLoadComplete = true; + log.info(log._("storage.localfilesystem.user-dir",{path:settings.userDir})); + if (activeProject) { + // At this point activeProject will be a string, so go load it and + // swap in an instance of Project + return loadProject(activeProject).then(function() { + log.info(log._("storage.localfilesystem.projects.active-project",{project:activeProject.name||"none"})); + log.info(log._("storage.localfilesystem.flows-file",{path:flowsFullPath})); + return getFlows(); + }); + } else { + if (projectsEnabled) { + log.warn(log._("storage.localfilesystem.projects.no-active-project")) + } else { + projectLogMessages.forEach(log.warn); + } + log.info(log._("storage.localfilesystem.flows-file",{path:flowsFullPath})); + } + } + if (activeProject) { + var error; + if (activeProject.isEmpty()) { + log.warn("Project repository is empty"); + error = new Error("Project repository is empty"); + error.code = "project_empty"; + return when.reject(error); + } + if (activeProject.missingFiles && activeProject.missingFiles.indexOf('package.json') !== -1) { + log.warn("Project missing package.json"); + error = new Error("Project missing package.json"); + error.code = "missing_package_file"; + return when.reject(error); + } + if (!activeProject.getFlowFile()) { + log.warn("Project has no flow file"); + error = new Error("Project has no flow file"); + error.code = "missing_flow_file"; + return when.reject(error); + } + if (activeProject.isMerging()) { + log.warn("Project has unmerged changes"); + error = new Error("Project has unmerged changes. Cannot load flows"); + error.code = "git_merge_conflict"; + return when.reject(error); + } + + } + return util.readFile(flowsFullPath,flowsFileBackup,null,'flow').then(function(result) { + if (result === null) { + flowsFileExists = false; + return []; + } + flowsFileExists = true; + return result; + }); +} + +function saveFlows(flows) { + if (settings.readOnly) { + return when.resolve(); + } + if (activeProject && activeProject.isMerging()) { + var error = new Error("Project has unmerged changes. Cannot deploy new flows"); + error.code = "git_merge_conflict"; + return when.reject(error); + } + + flowsFileExists = true; + + var flowData; + + if (settings.flowFilePretty) { + flowData = JSON.stringify(flows,null,4); + } else { + flowData = JSON.stringify(flows); + } + return util.writeFile(flowsFullPath, flowData, flowsFileBackup); +} + +function getCredentials() { + return util.readFile(credentialsFile,credentialsFileBackup,{},'credentials'); +} + +function saveCredentials(credentials) { + if (settings.readOnly) { + return when.resolve(); + } + + var credentialData; + if (settings.flowFilePretty) { + credentialData = JSON.stringify(credentials,null,4); + } else { + credentialData = JSON.stringify(credentials); + } + return util.writeFile(credentialsFile, credentialData, credentialsFileBackup); +} + +function getFlowFilename() { + if (flowsFullPath) { + return fspath.basename(flowsFullPath); + } +} +function getCredentialsFilename() { + if (flowsFullPath) { + return fspath.basename(credentialsFile); + } +} + +module.exports = { + init: init, + listProjects: listProjects, + getActiveProject: getActiveProject, + setActiveProject: setActiveProject, + getProject: getProject, + deleteProject: deleteProject, + createProject: createProject, + initialiseProject: initialiseProject, + updateProject: updateProject, + getFiles: getFiles, + getFile: getFile, + revertFile: revertFile, + stageFile: stageFile, + unstageFile: unstageFile, + commit: commit, + getFileDiff: getFileDiff, + getCommits: getCommits, + getCommit: getCommit, + push: push, + pull: pull, + getStatus:getStatus, + resolveMerge: resolveMerge, + abortMerge: abortMerge, + getBranches: getBranches, + deleteBranch: deleteBranch, + setBranch: setBranch, + getBranchStatus:getBranchStatus, + getRemotes: getRemotes, + addRemote: addRemote, + removeRemote: removeRemote, + updateRemote: updateRemote, + getFlowFilename: getFlowFilename, + flowFileExists: function() { return flowsFileExists }, + getCredentialsFilename: getCredentialsFilename, + getGlobalGitUser: function() { return globalGitUser }, + getFlows: getFlows, + saveFlows: saveFlows, + getCredentials: getCredentials, + saveCredentials: saveCredentials, + + ssh: sshTools + +}; diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/index.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/index.js new file mode 100644 index 0000000..25dacd3 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/index.js @@ -0,0 +1,213 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var fs = require('fs-extra'); +var when = require('when'); +var fspath = require("path"); +var keygen = require("./keygen"); + +var settings; +var log = require("@node-red/util").log; +var sshkeyDir; +var userSSHKeyDir; + +function init(_settings) { + settings = _settings; + sshkeyDir = fspath.resolve(fspath.join(settings.userDir, "projects", ".sshkeys")); + userSSHKeyDir = fspath.join(process.env.HOME || process.env.USERPROFILE || process.env.HOMEPATH, ".ssh"); + // console.log('sshkeys.init()'); + return fs.ensureDir(sshkeyDir); +} + +function listSSHKeys(username) { + return listSSHKeysInDir(sshkeyDir,username + '_').then(function(customKeys) { + return listSSHKeysInDir(userSSHKeyDir).then(function(existingKeys) { + existingKeys.forEach(function(k){ + k.system = true; + customKeys.push(k); + }) + return customKeys; + }); + }); +} + +function listSSHKeysInDir(dir,startStr) { + startStr = startStr || ""; + return fs.readdir(dir).then(function(fns) { + var ret = fns.sort() + .filter(function(fn) { + var fullPath = fspath.join(dir,fn); + if (fn.length > 2 || fn[0] != ".") { + var stats = fs.lstatSync(fullPath); + if (stats.isFile()) { + return fn.startsWith(startStr); + } + } + return false; + }) + .map(function(filename) { + return filename.substr(startStr.length); + }) + .reduce(function(prev, current) { + var parsePath = fspath.parse(current); + if ( parsePath ) { + if ( parsePath.ext !== '.pub' ) { + // Private Keys + prev.keyFiles.push(parsePath.base); + } + else if ( parsePath.ext === '.pub' && (prev.keyFiles.some(function(elem){ return elem === parsePath.name; }))) { + prev.privateKeyFiles.push(parsePath.name); + } + } + return prev; + }, { keyFiles: [], privateKeyFiles: [] }); + return ret.privateKeyFiles.map(function(filename) { + return { + name: filename + }; + }); + }).then(function(result) { + return result; + }).catch(function() { + return [] + }); +} + +function getSSHKey(username, name) { + return checkSSHKeyFileAndGetPublicKeyFileName(username, name) + .then(function(publicSSHKeyPath) { + return fs.readFile(publicSSHKeyPath, 'utf-8'); + }).catch(function() { + var privateKeyPath = fspath.join(userSSHKeyDir,name); + var publicKeyPath = privateKeyPath+".pub"; + return checkFilePairExist(privateKeyPath,publicKeyPath).then(function() { + return fs.readFile(publicKeyPath, 'utf-8'); + }).catch(function() { + return null + }); + }); +} + +function generateSSHKey(username, options) { + options = options || {}; + var name = options.name || ""; + if (!/^[a-zA-Z0-9\-_]+$/.test(options.name)) { + var err = new Error("Invalid SSH Key name"); + e.code = "invalid_key_name"; + return Promise.reject(err); + } + return checkExistSSHKeyFiles(username, name) + .then(function(result) { + if ( result ) { + var e = new Error("SSH Key name exists"); + e.code = "key_exists"; + throw e; + } else { + var comment = options.comment || ""; + var password = options.password || ""; + var size = options.size || 2048; + var sshKeyFileBasename = username + '_' + name; + var privateKeyFilePath = fspath.normalize(fspath.join(sshkeyDir, sshKeyFileBasename)); + return generateSSHKeyPair(name, privateKeyFilePath, comment, password, size) + } + }) +} + +function deleteSSHKey(username, name) { + return checkSSHKeyFileAndGetPublicKeyFileName(username, name) + .then(function() { + return deleteSSHKeyFiles(username, name); + }); +} + +function checkExistSSHKeyFiles(username, name) { + var sshKeyFileBasename = username + '_' + name; + var privateKeyFilePath = fspath.join(sshkeyDir, sshKeyFileBasename); + var publicKeyFilePath = fspath.join(sshkeyDir, sshKeyFileBasename + '.pub'); + return checkFilePairExist(privateKeyFilePath,publicKeyFilePath) + .then(function() { + return true; + }) + .catch(function() { + return false; + }); +} + +function checkSSHKeyFileAndGetPublicKeyFileName(username, name) { + var sshKeyFileBasename = username + '_' + name; + var privateKeyFilePath = fspath.join(sshkeyDir, sshKeyFileBasename); + var publicKeyFilePath = fspath.join(sshkeyDir, sshKeyFileBasename + '.pub'); + return checkFilePairExist(privateKeyFilePath,publicKeyFilePath).then(function() { + return publicKeyFilePath; + }); +} + +function checkFilePairExist(privateKeyFilePath,publicKeyFilePath) { + return Promise.all([ + fs.access(privateKeyFilePath, (fs.constants || fs).R_OK), + fs.access(publicKeyFilePath , (fs.constants || fs).R_OK) + ]) +} + +function deleteSSHKeyFiles(username, name) { + var sshKeyFileBasename = username + '_' + name; + var privateKeyFilePath = fspath.join(sshkeyDir, sshKeyFileBasename); + var publicKeyFilePath = fspath.join(sshkeyDir, sshKeyFileBasename + '.pub'); + return Promise.all([ + fs.remove(privateKeyFilePath), + fs.remove(publicKeyFilePath) + ]) +} + +function generateSSHKeyPair(name, privateKeyPath, comment, password, size) { + log.trace("ssh-keygen["+[name,privateKeyPath,comment,size,"hasPassword?"+!!password].join(",")+"]"); + return keygen.generateKey({location: privateKeyPath, comment: comment, password: password, size: size}) + .then(function(stdout) { + return name; + }) + .catch(function(err) { + log.log('[SSHKey generation] error:', err); + throw err; + }); +} + +function getPrivateKeyPath(username, name) { + var sshKeyFileBasename = username + '_' + name; + var privateKeyFilePath = fspath.normalize(fspath.join(sshkeyDir, sshKeyFileBasename)); + try { + fs.accessSync(privateKeyFilePath, (fs.constants || fs).R_OK); + } catch(err) { + privateKeyFilePath = fspath.join(userSSHKeyDir,name); + try { + fs.accessSync(privateKeyFilePath, (fs.constants || fs).R_OK); + } catch(err2) { + return null; + } + } + if (fspath.sep === '\\') { + privateKeyFilePath = privateKeyFilePath.replace(/\\/g,'\\\\'); + } + return privateKeyFilePath; +} + +module.exports = { + init: init, + listSSHKeys: listSSHKeys, + getSSHKey: getSSHKey, + getPrivateKeyPath: getPrivateKeyPath, + generateSSHKey: generateSSHKey, + deleteSSHKey: deleteSSHKey +}; diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/keygen.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/keygen.js new file mode 100644 index 0000000..cb73964 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/keygen.js @@ -0,0 +1,96 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var child_process = require('child_process'); + +var sshkeygenCommand = "ssh-keygen"; + +var log = require("@node-red/util").log; + +function runSshKeygenCommand(args,cwd,env) { + return new Promise(function(resolve, reject) { + var child = child_process.spawn(sshkeygenCommand, args, {cwd: cwd, detached: true, env: env}); + var stdout = ""; + var stderr = ""; + + child.stdout.on('data', function(data) { + stdout += data; + }); + child.stderr.on('data', function(data) { + stderr += data; + }); + child.on('close', function(code, signal) { + // console.log(code); + // console.log(stdout); + // console.log(stderr); + if (code !== 0) { + var err = new Error(stderr); + err.stdout = stdout; + err.stderr = stderr; + if (/short/.test(stderr)) { + err.code = "key_passphrase_too_short"; + } else if(/Key must at least be 1024 bits/.test(stderr)) { + err.code = "key_length_too_short"; + } + reject(err); + } + else { + resolve(stdout); + } + }); + child.on('error', function(err) { + if (/ENOENT/.test(err.toString())) { + err.code = "command_not_found"; + } + reject(err); + }); + }); +} + +function generateKey(options) { + var args = ['-q', '-t', 'rsa']; + var err; + if (options.size) { + if (options.size < 1024) { + err = new Error("key_length_too_short"); + err.code = "key_length_too_short"; + throw err; + } + args.push('-b', options.size); + } + if (options.location) { + args.push('-f', options.location); + } + if (options.comment) { + args.push('-C', options.comment); + } + if (options.password) { + if (options.password.length < 5) { + err = new Error("key_passphrase_too_short"); + err.code = "key_passphrase_too_short"; + throw err; + } + args.push('-N', options.password||''); + } else { + args.push('-N', ''); + } + + return runSshKeygenCommand(args,__dirname); +} + +module.exports = { + generateKey: generateKey +}; diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/sessions.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/sessions.js new file mode 100644 index 0000000..6b4deaa --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/sessions.js @@ -0,0 +1,53 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require('when'); +var fs = require('fs-extra'); +var fspath = require("path"); + +var log = require("@node-red/util").log; // TODO: separate module + +var util = require("./util"); + +var sessionsFile; +var settings; + +module.exports = { + init: function(_settings) { + settings = _settings; + sessionsFile = fspath.join(settings.userDir,".sessions.json"); + }, + getSessions: function() { + return when.promise(function(resolve,reject) { + fs.readFile(sessionsFile,'utf8',function(err,data){ + if (!err) { + try { + return resolve(util.parseJSON(data)); + } catch(err2) { + log.trace("Corrupted sessions file - resetting"); + } + } + resolve({}); + }) + }); + }, + saveSessions: function(sessions) { + if (settings.readOnly) { + return when.resolve(); + } + return util.writeFile(sessionsFile,JSON.stringify(sessions)); + } +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/settings.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/settings.js new file mode 100644 index 0000000..d0b6dd5 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/settings.js @@ -0,0 +1,54 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require('when'); +var fs = require('fs-extra'); +var fspath = require("path"); + +var log = require("@node-red/util").log; // TODO: separate module +var util = require("./util"); + +var globalSettingsFile; +var globalSettingsBackup; +var settings; + +module.exports = { + init: function(_settings) { + settings = _settings; + globalSettingsFile = fspath.join(settings.userDir,".config.json"); + globalSettingsBackup = fspath.join(settings.userDir,".config.json.backup"); + }, + getSettings: function() { + return when.promise(function(resolve,reject) { + fs.readFile(globalSettingsFile,'utf8',function(err,data) { + if (!err) { + try { + return resolve(util.parseJSON(data)); + } catch(err2) { + log.trace("Corrupted config detected - resetting"); + } + } + return resolve({}); + }) + }) + }, + saveSettings: function(newSettings) { + if (settings.readOnly) { + return when.resolve(); + } + return util.writeFile(globalSettingsFile,JSON.stringify(newSettings,null,1),globalSettingsBackup); + } +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/util.js b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/util.js new file mode 100644 index 0000000..b18c806 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/util.js @@ -0,0 +1,114 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var fs = require('fs-extra'); +var fspath = require('path'); +var when = require('when'); +var nodeFn = require('when/node/function'); + +var log = require("@node-red/util").log; // TODO: separate module + +function parseJSON(data) { + if (data.charCodeAt(0) === 0xFEFF) { + data = data.slice(1) + } + return JSON.parse(data); +} +function readFile(path,backupPath,emptyResponse,type) { + return when.promise(function(resolve) { + fs.readFile(path,'utf8',function(err,data) { + if (!err) { + if (data.length === 0) { + log.warn(log._("storage.localfilesystem.empty",{type:type})); + try { + var backupStat = fs.statSync(backupPath); + if (backupStat.size === 0) { + // Empty flows, empty backup - return empty flow + return resolve(emptyResponse); + } + // Empty flows, restore backup + log.warn(log._("storage.localfilesystem.restore",{path:backupPath,type:type})); + fs.copy(backupPath,path,function(backupCopyErr) { + if (backupCopyErr) { + // Restore backup failed + log.warn(log._("storage.localfilesystem.restore-fail",{message:backupCopyErr.toString(),type:type})); + resolve([]); + } else { + // Loop back in to load the restored backup + resolve(readFile(path,backupPath,emptyResponse,type)); + } + }); + return; + } catch(backupStatErr) { + // Empty flow file, no back-up file + return resolve(emptyResponse); + } + } + try { + return resolve(parseJSON(data)); + } catch(parseErr) { + log.warn(log._("storage.localfilesystem.invalid",{type:type})); + return resolve(emptyResponse); + } + } else { + if (type === 'flow') { + log.info(log._("storage.localfilesystem.create",{type:type})); + } + resolve(emptyResponse); + } + }); + }); +} + +module.exports = { + /** + * Write content to a file using UTF8 encoding. + * This forces a fsync before completing to ensure + * the write hits disk. + */ + writeFile: function(path,content,backupPath) { + if (backupPath) { + if (fs.existsSync(path)) { + fs.renameSync(path,backupPath); + } + } + return when.promise(function(resolve,reject) { + fs.ensureDir(fspath.dirname(path), (err)=>{ + if (err) { + reject(err); + return; + } + var stream = fs.createWriteStream(path); + stream.on('open',function(fd) { + stream.write(content,'utf8',function() { + fs.fsync(fd,function(err) { + if (err) { + log.warn(log._("storage.localfilesystem.fsync-fail",{path: path, message: err.toString()})); + } + stream.end(resolve); + }); + }); + }); + stream.on('error',function(err) { + reject(err); + }); + }); + }); + }, + readFile: readFile, + + parseJSON: parseJSON +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/locales/de/runtime.json b/packages/connector/packages/node_modules/@node-red/runtime/locales/de/runtime.json new file mode 100644 index 0000000..621a8b2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/locales/de/runtime.json @@ -0,0 +1,164 @@ +{ + "runtime" : { + "welcome" : "Willkommen bei Node-RED!", + "version" : "__component__ Version: __version__", + "unsupported_version" : "Nicht unterstützte Version von __component__. Erfordert: __requires__ Gefunden: __version__", + "paths" : { + "settings" : "Einstellungsdatei: __path__", + "httpStatic" : "HTTP-Statisch: __path__" + } + }, + "server" : { + "loading" : "Paletten-Nodes werden geladen", + "palette-editor" : { + "disabled" : "Paletteneditor inaktiviert: Benutzereinstellungen", + "npm-not-found" : "Paletteneditor inaktiviert: Befehl 'npm' nicht gefunden" + }, + "errors" : "Registrieren des Node-Typs __count__ ist fehlgeschlagen.", + "errors_plural" : "Fehler beim Registrieren von __count__ -Node-Typen", + "errors-help" : "Mit -v ausführen, um Details zu erfahren", + "missing-modules" : "Fehlende Node-Module:", + "node-version-mismatch" : "Das Node-Modul kann in dieser Version nicht geladen werden. Erfordert: __version__ ", + "type-already-registered" : "'__type__' bereits von Modul __module__ registriert", + "removing-modules" : "Module aus der Konfiguration entfernen", + "added-types" : "Hinzugefügte Node-Typen:", + "removed-types" : "Entfernte Node-Typen:", + "install" : { + "invalid" : "Ungültiger Modulname", + "installing" : "Modul wird installiert: __name__, Version: __version__", + "installed" : "Installiertes Modul: __name__", + "install-failed" : "Installation fehlgeschlagen", + "install-failed-long" : "Die Installation des Moduls __name__ ist fehlgeschlagen:", + "install-failed-not-found" : "Das Modul '$t(server.install.install-failed-long') wurde nicht gefunden.", + "upgrading" : "Modul wird aktualisiert: __name__ auf Version: __version__", + "upgraded" : "Erweitertes Modul: __name__. Neustart von Node-RED für die Verwendung der neuen Version", + "upgrade-failed-not-found" : "$t(server.install.install-failed-long) Version nicht gefunden", + "uninstalling" : "Modul wird deinstalliert: __name__", + "uninstall-failed" : "Deinstallation fehlgeschlagen", + "uninstall-failed-long" : "Das Deinstallieren des Moduls __name__ ist fehlgeschlagen:", + "uninstalled" : "Nicht installiertes Modul: __name__" + }, + "unable-to-listen" : "Zuhören auf __listenpath__ nicht möglich.", + "port-in-use" : "Fehler: Port wird verwendet", + "uncaught-exception" : "Nicht abgefangene Ausnahmebedingung:", + "admin-ui-disabled" : "Administratorbenutzerschnittstelle inaktiviert", + "now-running" : "Server wird jetzt auf __listenpath__ ausgeführt.", + "failed-to-start" : "Starten des Servers fehlgeschlagen:", + "headless-mode" : "Ausführung im Headless-Modus", + "httpadminauth-deprecated" : "Die Verwendung von httpAdminAuth wird nicht weiter unterstützt. Verwenden Sie stattdessen adminAuth." + }, + "api" : { + "flows" : { + "error-save" : "Fehler beim Speichern der Flows: __message__", + "error-reload" : "Fehler beim erneuten Laden von Flows: __message__" + }, + "library" : { + "error-load-entry" : "Fehler beim Laden des Bibliothekseintrags '__path__': __message__", + "error-save-entry" : "Fehler beim Speichern des Bibliothekseintrags '__path__': __message__", + "error-load-flow" : "Fehler beim Laden von Flow '__path__': __message__", + "error-save-flow" : "Fehler beim Speichern des Flows '__path__': __message__" + }, + "nodes" : { + "enabled" : "Aktivierte Node-Typen:", + "disabled" : "Inaktivierte Node-Typen:", + "error-enable" : "Der Node konnte nicht aktiviert werden:" + } + }, + "comms" : { + "error" : "Kommunikationskanalfehler: __message__", + "error-server" : "Kommunikationsserverfehler: __message__", + "error-send" : "Fehler beim Senden der Kommunikation: __message__" + }, + "settings" : { + "user-not-available" : "Benutzereinstellungen können nicht gespeichert werden: __message__", + "not-available" : "Einstellungen nicht verfügbar", + "property-read-only" : "Eigenschaft '__prop__' ist schreibgeschützt" + }, + "nodes" : { + "credentials" : { + "error" : "Fehler beim Laden der Berechtigungsnachweise: __message__", + "error-saving" : "Fehler beim Speichern der Berechtigungsnachweise: __message__", + "not-registered" : "Der Berechtigungsnachweistyp '__type__' ist nicht registriert.", + "system-key-warning" : "\n\n---------------------------------------------------------------------\nDie Datei mit den Datenflowberechtigungsnachweisen wird mit einem vom System generierten Schlüssel verschlüsselt.\n\nWenn der vom System generierte Schlüssel aus irgendeinem Grund verloren geht, werden Ihre Berechtigungsnachweise\nDie Datei kann nicht wiederhergestellt werden. Sie müssen sie löschen und erneut eingeben.\nIhre Berechtigungsnachweise.\n\nSie sollten Ihren eigenen Schlüssel mit Hilfe der Option 'credentialSecret' in\nIhre Einstellungsdatei. Node-RED wird dann Ihre Berechtigungsnachweise erneut verschlüsseln.\nDatei mit dem ausgewählten Schlüssel beim nächsten Deployen einer Änderung verwenden.\n---------------------------------------------------------------------\n" + }, + "flows" : { + "registered-missing" : "Fehlender Typ registriert: __type__", + "error" : "Fehler beim Laden von Flows: __message__", + "starting-modified-nodes" : "Modifizierte Nodes werden gestartet", + "starting-modified-flows" : "Modifizierte Flows werden gestartet", + "starting-flows" : "Flows starten", + "started-modified-nodes" : "Gestartete geänderte Nodes", + "started-modified-flows" : "Gestartete geänderte Flows", + "started-flows" : "Flows gestartet", + "stopping-modified-nodes" : "Modifizierte Nodes werden gestoppt", + "stopping-modified-flows" : "Modifizierte Flows werden gestoppt", + "stopping-flows" : "Flows stoppen", + "stopped-modified-nodes" : "Geänderte Nodes gestoppt", + "stopped-modified-flows" : "Geänderte Flows gestoppt", + "stopped-flows" : "Flows gestoppt", + "stopped" : "Gestoppt", + "stopping-error" : "Fehler beim Stoppen des Nodes: __message__", + "added-flow" : "Flow hinzufügen: __label__", + "updated-flow" : "Aktualisierter Flow: __label__", + "removed-flow" : "Entfernter Flow: __label__", + "missing-types" : "Warten auf fehlende Typen, die registriert werden sollen:", + "missing-type-provided" : " -__type__ (wird von npm Modul __module__ bereitgestellt)", + "missing-type-install-1" : "Führen Sie die folgenden Schritte aus, um eines der fehlenden Module zu installieren:", + "missing-type-install-2" : "im Verzeichnis:" + }, + "flow" : { + "unknown-type" : "Unbekannter Typ: __type__", + "missing-types" : "Fehlende Typen", + "error-loop" : "Nachricht überschritt die maximale Anzahl der Wiederholungen" + }, + "index" : { + "unrecognised-id" : "Nicht erkannte ID: __id__", + "type-in-use" : "Typ in Verwendung: __msg__", + "unrecognised-module" : "Nicht erkannes Modul: __module__" + }, + "registry" : { + "localfilesystem" : { + "module-not-found" : "Modul '__module__' wurde nicht gefunden." + } + } + }, + "storage" : { + "index" : { + "forbidden-flow-name" : "Unzulässiger Flowname" + }, + "localfilesystem" : { + "user-dir" : "Benutzerverzeichnis: __path__", + "flows-file" : "Flow-Datei: __path__", + "create" : "Neue __type__-Datei wird erstellt", + "empty" : "Vorhandene __type__-Datei ist leer", + "invalid" : "Vorhandene __type__ Datei ist ungültig (json)", + "restore" : "__type__ Dateisicherung wird zurückgespeichert: __path__", + "restore-fail" : "Das Zurückschreiben der __type__ Dateisicherung ist fehlgeschlagen: __message__", + "fsync-fail" : "Das Löschen der Datei __path__ auf die Platte ist fehlgeschlagen: __message__", + "projects" : { + "changing-project" : "Aktives Projekt wird festgelegt: __project__", + "active-project" : "Aktives Projekt: __project__", + "project-not-found" : "Projekt nicht gefunden: __project__", + "no-active-project" : "Kein aktives Projekt: Standarddatei für DatenFlows verwenden", + "disabled" : "Projekte inaktiviert: editorTheme.projects.enabled=false", + "disabledNoFlag" : "Projekte inaktiviert: setze editorTheme.projects.enabled=true zum Aktivieren", + "git-not-found" : "Projekte inaktiviert: Git-Befehl nicht gefunden", + "git-version-old" : "Projekte inaktiviert: git __version__ wird nicht unterstützt. Erfordert 2.x", + "summary" : "Ein Node-RED-Projekt", + "readme" : "### Produktinfo\n\nDies ist die Datei README.md Ihres Projekts. Es hilft den Benutzern zu verstehen, was Ihr\nProjekt macht, wie man es verwendet und alles andere, was sie vielleicht wissen müssen." + } + } + }, + "context" : { + "log-store-init" : "Kontextspeicher: '__name__' [ __info__]", + "error-loading-module" : "Fehler beim Laden des Kontextspeichers: __message__", + "error-module-not-defined" : "Kontextspeicher '__storage__' fehlt 'Modul' -Option", + "error-invalid-module-name" : "Ungültiger Kontextspeichername: '__name__'", + "error-invalid-default-module" : "Standardkontextspeicher unbekannt: '__storage__'", + "unknown-store" : "Unbekannter Kontextspeicher '__name__' angegeben. Standardspeicher wird verwendet.", + "localfilesystem" : { + "error-circular" : "Kontext __scope__ enthält einen kreisförmigen Verweis, der nicht persistent gespeichert werden kann.", + "error-write" : "Fehler beim Schreiben des Kontextes: __message__" + } + } +} \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/runtime/locales/en-US/runtime.json b/packages/connector/packages/node_modules/@node-red/runtime/locales/en-US/runtime.json new file mode 100644 index 0000000..d56031d --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/locales/en-US/runtime.json @@ -0,0 +1,175 @@ +{ + "runtime": { + "welcome": "Welcome to Node-RED", + "version": "__component__ version: __version__", + "unsupported_version": "Unsupported version of __component__. Requires: __requires__ Found: __version__", + "paths": { + "settings": "Settings file : __path__", + "httpStatic": "HTTP Static : __path__" + } + }, + + "server": { + "loading": "Loading palette nodes", + "palette-editor": { + "disabled": "Palette editor disabled : user settings", + "npm-not-found": "Palette editor disabled : npm command not found", + "npm-too-old": "Palette editor disabled : npm version too old. Requires npm >= 3.x" + }, + "errors": "Failed to register __count__ node type", + "errors_plural": "Failed to register __count__ node types", + "errors-help": "Run with -v for details", + "missing-modules": "Missing node modules:", + "node-version-mismatch": "Node module cannot be loaded on this version. Requires: __version__ ", + "type-already-registered": "'__type__' already registered by module __module__", + "removing-modules": "Removing modules from config", + "added-types": "Added node types:", + "removed-types": "Removed node types:", + "install": { + "invalid": "Invalid module name", + "installing": "Installing module: __name__, version: __version__", + "installed": "Installed module: __name__", + "install-failed": "Install failed", + "install-failed-long": "Installation of module __name__ failed:", + "install-failed-not-found": "$t(server.install.install-failed-long) module not found", + "upgrading": "Upgrading module: __name__ to version: __version__", + "upgraded": "Upgraded module: __name__. Restart Node-RED to use the new version", + "upgrade-failed-not-found": "$t(server.install.install-failed-long) version not found", + "uninstalling": "Uninstalling module: __name__", + "uninstall-failed": "Uninstall failed", + "uninstall-failed-long": "Uninstall of module __name__ failed:", + "uninstalled": "Uninstalled module: __name__" + }, + "unable-to-listen": "Unable to listen on __listenpath__", + "port-in-use": "Error: port in use", + "uncaught-exception": "Uncaught Exception:", + "admin-ui-disabled": "Admin UI disabled", + "now-running": "Server now running at __listenpath__", + "failed-to-start": "Failed to start server:", + "headless-mode": "Running in headless mode", + "httpadminauth-deprecated": "use of httpAdminAuth is deprecated. Use adminAuth instead" + }, + + "api": { + "flows": { + "error-save": "Error saving flows: __message__", + "error-reload": "Error reloading flows: __message__" + }, + "library": { + "error-load-entry": "Error loading library entry '__path__': __message__", + "error-save-entry": "Error saving library entry '__path__': __message__", + "error-load-flow": "Error loading flow '__path__': __message__", + "error-save-flow": "Error saving flow '__path__': __message__" + }, + "nodes": { + "enabled": "Enabled node types:", + "disabled": "Disabled node types:", + "error-enable": "Failed to enable node:" + } + }, + + "comms": { + "error": "Communication channel error: __message__", + "error-server": "Communication server error: __message__", + "error-send": "Communication send error: __message__" + }, + + "settings": { + "user-not-available": "Cannot save user settings: __message__", + "not-available": "Settings not available", + "property-read-only": "Property '__prop__' is read-only" + }, + + "nodes": { + "credentials": { + "error":"Error loading credentials: __message__", + "error-saving":"Error saving credentials: __message__", + "not-registered": "Credential type '__type__' is not registered", + "system-key-warning": "\n\n---------------------------------------------------------------------\nYour flow credentials file is encrypted using a system-generated key.\n\nIf the system-generated key is lost for any reason, your credentials\nfile will not be recoverable, you will have to delete it and re-enter\nyour credentials.\n\nYou should set your own key using the 'credentialSecret' option in\nyour settings file. Node-RED will then re-encrypt your credentials\nfile using your chosen key the next time you deploy a change.\n---------------------------------------------------------------------\n" + }, + "flows": { + "safe-mode": "Flows stopped in safe mode. Deploy to start.", + "registered-missing": "Missing type registered: __type__", + "error": "Error loading flows: __message__", + "starting-modified-nodes": "Starting modified nodes", + "starting-modified-flows": "Starting modified flows", + "starting-flows": "Starting flows", + "started-modified-nodes": "Started modified nodes", + "started-modified-flows": "Started modified flows", + "started-flows": "Started flows", + "stopping-modified-nodes": "Stopping modified nodes", + "stopping-modified-flows": "Stopping modified flows", + "stopping-flows": "Stopping flows", + "stopped-modified-nodes": "Stopped modified nodes", + "stopped-modified-flows": "Stopped modified flows", + "stopped-flows": "Stopped flows", + "stopped": "Stopped", + "stopping-error": "Error stopping node: __message__", + "added-flow": "Adding flow: __label__", + "updated-flow": "Updated flow: __label__", + "removed-flow": "Removed flow: __label__", + "missing-types": "Waiting for missing types to be registered:", + "missing-type-provided": " - __type__ (provided by npm module __module__)", + "missing-type-install-1": "To install any of these missing modules, run:", + "missing-type-install-2": "in the directory:" + }, + "flow": { + "unknown-type": "Unknown type: __type__", + "missing-types": "missing types", + "error-loop": "Message exceeded maximum number of catches" + }, + "index": { + "unrecognised-id": "Unrecognised id: __id__", + "type-in-use": "Type in use: __msg__", + "unrecognised-module": "Unrecognised module: __module__" + }, + "registry": { + "localfilesystem": { + "module-not-found": "Cannot find module '__module__'" + } + } + }, + + "storage": { + "index": { + "forbidden-flow-name": "forbidden flow name" + }, + "localfilesystem": { + "user-dir": "User directory : __path__", + "flows-file": "Flows file : __path__", + "create": "Creating new __type__ file", + "empty": "Existing __type__ file is empty", + "invalid": "Existing __type__ file is not valid json", + "restore": "Restoring __type__ file backup : __path__", + "restore-fail": "Restoring __type__ file backup failed : __message__", + "fsync-fail": "Flushing file __path__ to disk failed : __message__", + "projects": { + "changing-project": "Setting active project : __project__", + "active-project": "Active project : __project__", + "project-not-found": "Project not found : __project__", + "no-active-project": "No active project : using default flows file", + "disabled": "Projects disabled : editorTheme.projects.enabled=false", + "disabledNoFlag": "Projects disabled : set editorTheme.projects.enabled=true to enable", + "git-not-found": "Projects disabled : git command not found", + "git-version-old": "Projects disabled : git __version__ not supported. Requires 2.x", + "summary": "A Node-RED Project", + "readme": "### About\n\nThis is your project's README.md file. It helps users understand what your\nproject does, how to use it and anything else they may need to know." + } + } + }, + + "context": { + "log-store-init": "Context store : '__name__' [__info__]", + "error-loading-module": "Error loading context store: __message__", + "error-loading-module2": "Error loading context store '__module__': __message__", + "error-module-not-defined": "Context store '__storage__' missing 'module' option", + "error-invalid-module-name": "Invalid context store name: '__name__'", + "error-invalid-default-module": "Default context store unknown: '__storage__'", + "unknown-store": "Unknown context store '__name__' specified. Using default store.", + "localfilesystem": { + "error-circular": "Context __scope__ contains a circular reference that cannot be persisted", + "error-write": "Error writing context: __message__" + } + } + +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/locales/ja/runtime.json b/packages/connector/packages/node_modules/@node-red/runtime/locales/ja/runtime.json new file mode 100644 index 0000000..3dc4d58 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/locales/ja/runtime.json @@ -0,0 +1,167 @@ +{ + "runtime": { + "welcome": "Welcome to Node-RED", + "version": "__component__ バージョン: __version__", + "unsupported_version": "__component__ は未サポートのバージョンです。必要: __requires__ 検知: __version__", + "paths": { + "settings": "設定ファイル: __path__", + "httpStatic": "HTTP Static : __path__" + } + }, + "server": { + "loading": "パレットノードのロード", + "palette-editor": { + "disabled": "パレットエディタを無効化 : ユーザ設定", + "npm-not-found": "パレットエディタを無効化 : npmコマンドが見つかりません", + "npm-too-old": "パレットエディタを無効化 : npmのバージョンが古過ぎます。npm 3.x以上が必要です" + }, + "errors": "__count__ 個のノードの登録に失敗しました", + "errors_plural": "__count__ 個のノードの登録に失敗しました", + "errors-help": "詳細は -v を指定して実行してください", + "missing-modules": "不足しているノードモジュール:", + "node-version-mismatch": "ノードモジュールはこのバージョンではロードできません。必要なバージョン: __version__ ", + "type-already-registered": "'__type__' はモジュール __module__ で登録済みです", + "removing-modules": "設定からモジュールを削除します", + "added-types": "追加したノード:", + "removed-types": "削除したノード:", + "install": { + "invalid": "不正なモジュール名", + "installing": "モジュール__name__, バージョン: __version__ をインストールします", + "installed": "モジュール __name__ をインストールしました", + "install-failed": "インストールに失敗しました", + "install-failed-long": "モジュール __name__ のインストールに失敗しました:", + "install-failed-not-found": "$t(server.install.install-failed-long) モジュールが見つかりません", + "upgrading": "モジュール __name__ をバージョン __version__ に更新します", + "upgraded": "モジュール __name__ を更新しました。新しいバージョンを使うには、Node-REDを再起動してください。", + "upgrade-failed-not-found": "$t(server.install.install-failed-long) バージョンが見つかりません", + "uninstalling": "モジュールをアンインストールします: __name__", + "uninstall-failed": "アンインストールに失敗しました", + "uninstall-failed-long": "モジュール __name__ のアンインストールに失敗しました:", + "uninstalled": "モジュール __name__ をアンインストールしました" + }, + "unable-to-listen": "__listenpath__ に対してlistenできません", + "port-in-use": "エラー: ポートが使用中です", + "uncaught-exception": "未補足の例外:", + "admin-ui-disabled": "管理UIを無効化しました", + "now-running": "サーバは __listenpath__ で実行中です", + "failed-to-start": "サーバの起動に失敗しました:", + "headless-mode": "ヘッドレスモードで実行中です", + "httpadminauth-deprecated": "httpAdminAuthは非推奨です。代わりに adminAuth を使用してください" + }, + "api": { + "flows": { + "error-save": "フローの保存エラー: __message__", + "error-reload": "フローの読み込みエラー: __message__" + }, + "library": { + "error-load-entry": "ライブラリエントリ '__path__' の読み込みエラー: __message__", + "error-save-entry": "ライブラリエントリ '__path__' の保存エラー: __message__", + "error-load-flow": "フロー '__path__' の読み込みエラー: __message__", + "error-save-flow": "フロー '__path__' の保存エラー: __message__" + }, + "nodes": { + "enabled": "ノードを有効化しました:", + "disabled": "ノードを無効化しました:", + "error-enable": "ノードの有効化に失敗しました:" + } + }, + "comms": { + "error": "通信チャネルエラー: __message__", + "error-server": "サーバエラー: __message__", + "error-send": "送信エラー: __message__" + }, + "settings": { + "user-not-available": "ユーザ設定を保存できません: __message__", + "not-available": "設定が利用できません", + "property-read-only": "プロパティ '__prop__' は読み出し専用です" + }, + "nodes": { + "credentials": { + "error": "クレデンシャルの読み込みエラー: __message__", + "error-saving": "クレデンシャルの保存エラー: __message__", + "not-registered": "クレデンシャル '__type__' は登録されていません", + "system-key-warning": "\n\n---------------------------------------------------------------------\nフローのクレデンシャルファイルはシステム生成キーで暗号化されています。\n\nシステム生成キーを何らかの理由で失った場合、クレデンシャルファイルを\n復元することはできません。その場合、ファイルを削除してクレデンシャルを\n再入力しなければなりません。\n\n設定ファイル内で 'credentialSecret' オプションを使って独自キーを設定\nします。変更を次にデプロイする際、Node-REDは選択したキーを用いてクレ\nデンシャルを再暗号化します。 \n\n---------------------------------------------------------------------\n" + }, + "flows": { + "safe-mode": "セーフモードでフローを停止しました。開始するためにはデプロイしてください", + "registered-missing": "欠落しているノードを登録します: __type__", + "error": "フローの読み込みエラー: __message__", + "starting-modified-nodes": "更新されたノードを開始します", + "starting-modified-flows": "更新されたフローを開始します", + "starting-flows": "フローを開始します", + "started-modified-nodes": "更新されたノードを開始しました", + "started-modified-flows": "更新されたフローを開始しました", + "started-flows": "フローを開始しました", + "stopping-modified-nodes": "更新されたノードを停止します", + "stopping-modified-flows": "更新されたフローを停止します", + "stopping-flows": "フローを停止します", + "stopped-modified-nodes": "更新されたノードを停止しました", + "stopped-modified-flows": "更新されたフローを停止しました", + "stopped-flows": "フローを停止しました", + "stopped": "停止しました", + "stopping-error": "ノードの停止に失敗しました: __message__", + "added-flow": "フローを追加します: __label__", + "updated-flow": "フローを更新しました: __label__", + "removed-flow": "フローを削除しました: __label__", + "missing-types": "欠落しているノードが登録されるのを待っています:", + "missing-type-provided": " - __type__ (npmモジュール __module__ からインストールされました)", + "missing-type-install-1": "欠落しているモジュールをインストールするには次のコマンドを実行してください:", + "missing-type-install-2": "コマンドの実行は次のディレクトリで行います:" + }, + "flow": { + "unknown-type": "不明なノード: __type__", + "missing-types": "欠落したノード", + "error-loop": "メッセージの例外補足回数が最大値を超えました" + }, + "index": { + "unrecognised-id": "不明なID: __id__", + "type-in-use": "ノードは使用中です: __msg__", + "unrecognised-module": "不明なモジュール: __module__" + }, + "registry": { + "localfilesystem": { + "module-not-found": "モジュール '__module__' が見つかりません" + } + } + }, + "storage": { + "index": { + "forbidden-flow-name": "不正なフロー名" + }, + "localfilesystem": { + "user-dir": "ユーザディレクトリ : __path__", + "flows-file": "フローファイル : __path__", + "create": "__type__ ファイルを作成します", + "empty": "既存の __type__ ファイルが空です", + "invalid": "既存の __type__ ファイルはJSON形式ではありません", + "restore": " __type__ ファイルをバックアップ __path__ から復元します", + "restore-fail": "__type__ ファイルをバックアップから復元するのに失敗しました : __message__", + "fsync-fail": "ファイル __path__ のディスクへの書き出しに失敗しました : __message__", + "projects": { + "changing-project": "プロジェクトを設定します : __project__", + "active-project": "選択中のプロジェクト : __project__", + "project-not-found": "プロジェクトが見つかりません : __project__", + "no-active-project": "プロジェクトが選択されていません : デフォルトのフローファイルを使用します", + "disabled": "プロジェクトは無効化されています : editorTheme.projects.enabled=false", + "disabledNoFlag": "プロジェクトは無効化されています : 有効にするには editorTheme.projects.enabled=true を設定してください", + "git-not-found": "プロジェクトは無効化されています : gitコマンドが見つかりません", + "git-version-old": "プロジェクトは無効化されています : git __version__ はサポートされていません。2.xが必要です。", + "summary": "Node-REDプロジェクト", + "readme": "### 説明\nこれはプロジェクトのREADME.mdファイルです。このファイルには、\nプロジェクトの説明、利用方法、その他の情報を記載します。" + } + } + }, + "context": { + "log-store-init": "コンテキストストア : '__name__' [__info__]", + "error-loading-module": "コンテキストストアのロードでエラーが発生しました: __message__", + "error-loading-module2": "コンテキストストア '__module__' のロードでエラーが発生しました: __message__", + "error-module-not-defined": "コンテキストストア '__storage__' に 'module' オプションが指定されていません", + "error-invalid-module-name": "不正なコンテキストストア名: '__name__'", + "error-invalid-default-module": "デフォルトコンテキストストアが不明: '__storage__'", + "unknown-store": "不明なコンテキストストア '__name__' が指定されました。デフォルトストアを使用します。", + "localfilesystem": { + "error-circular": "コンテキスト __scope__ は永続化できない循環参照を含んでいます", + "error-write": "コンテキスト書込みエラー: __message__" + } + } +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/locales/ko/runtime.json b/packages/connector/packages/node_modules/@node-red/runtime/locales/ko/runtime.json new file mode 100644 index 0000000..ec59bd2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/locales/ko/runtime.json @@ -0,0 +1,167 @@ +{ + "runtime": { + "welcome": "Node-RED에 오신것을 환영합니다.", + "version": "__component__ 버전: __version__", + "unsupported_version": "__component__는 지원하지 않는 버전입니다. 요구버전: __requires__ 현재버전: __version__", + "paths": { + "settings": "설정 파일 : __path__", + "httpStatic": "HTTP Static : __path__" + } + }, + "server": { + "loading": "팔렛트 노드 읽는 중", + "palette-editor": { + "disabled": "팔렛트 에디터 사용불가 : 사용자 설정", + "npm-not-found": "팔렛트 에디터 사용불가 : npm 명령어가 없습니다.", + "npm-too-old": "팔렛트 에디터 사용불가 : npm 버전이 너무 오래되었습니다. 3.x이상의 npm을 사용하세요." + }, + "errors": "__count__개의 노드타입 등록 에러", + "errors_plural": "__count__개의 노드타입 등록 에러", + "errors-help": "-v 를 실행하여 상세내역을 확인하세요", + "missing-modules": "노드모듈이 없습니다:", + "node-version-mismatch": "버전이 잘못 되었습니다. 요구버전: __version__ ", + "type-already-registered": "'__type__' 은 __module__ 으로 이미 등록되어 있습니다.", + "removing-modules": "설정에서 모듈 제거중", + "added-types": "노드타입 추가:", + "removed-types": "노드타입 제거:", + "install": { + "invalid": "잘못된 모듈명", + "installing": "모듈 설치중: __name__, 버전: __version__", + "installed": "모듈이 설치되었습니다: __name__", + "install-failed": "설치 실패", + "install-failed-long": "__name__ 모듈 설치 실패:", + "install-failed-not-found": "$t(install-failed-long) 모듈이 없습니다.", + "upgrading": "모듈 업그레이드: __name__ to 버전: __version__", + "upgraded": "모듈 업그레이드: __name__. 새 버전을 사용하기 위해 Node-RED를 재시작 합니다.", + "upgrade-failed-not-found": "$t(server.install.install-failed-long) 버전이 없습니다.", + "uninstalling": "모듈 제거중: __name__", + "uninstall-failed": "제거 실패", + "uninstall-failed-long": "__name__ 모듈 제거 실패:", + "uninstalled": "모듈 제거: __name__" + }, + "unable-to-listen": "__listenpath__에서 listen 할 수 없습니다.", + "port-in-use": "에러: 포트 사용중", + "uncaught-exception": "Uncaught Exception:", + "admin-ui-disabled": "관리 UI 비활성화", + "now-running": "__listenpath__에서 서버가 실행중 입니다.", + "failed-to-start": "서버시작 실패:", + "headless-mode": "headless 모드로 실행중입니다.", + "httpadminauth-deprecated": "httpAdminAuth는 더 이상 사용되지 않습니다. adminAuth를 사용하세요." + }, + "api": { + "flows": { + "error-save": "플로우 저장 에러: __message__", + "error-reload": "플로우 새로고침 에러: __message__" + }, + "library": { + "error-load-entry": "라이브러리 '__path__'불러오기 에러: __message__", + "error-save-entry": "라이브러리 '__path__'저장 에러: __message__", + "error-load-flow": "플로우 '__path__'불러오기 에러: __message__", + "error-save-flow": "플로우 '__path__'저장 에러: __message__" + }, + "nodes": { + "enabled": "노드타입 활성화:", + "disabled": "노드타입 비활성화:", + "error-enable": "노드 활성화 에러:" + } + }, + "comms": { + "error": "통신채널 에러: __message__", + "error-server": "통신서버 에러: __message__", + "error-send": "전송 에러: __message__" + }, + "settings": { + "user-not-available": "사용자 설정을 저장할수 없습니다: __message__", + "not-available": "설정을 사용할 수 없습니다.", + "property-read-only": "'__prop__' 속성은 읽기 전용입니다." + }, + "nodes": { + "credentials": { + "error": "인증정보 읽어오기 에러: __message__", + "error-saving": "인증정보 저장 에러: __message__", + "not-registered": "인증정보 '__type__'는 등록되어 있지않습니다.", + "system-key-warning": "\n\n---------------------------------------------------------------------\n 시스템에서 생성한 키를 사용하여 플로우 자격증명 파일이 암호화되어 있습니다. \n\n 만일 시스템 생성 키가 어떤 이유로든 손실되면 자격증명파일을\n 복구 할 수 없습니다. 그러한 경우엔 삭제하고 자격증명을 다시 \n 입력해야 합니다.\n\n 'credentialSecret' 옵션을 사용하여 자신의 키를 설정해야 합니다. \n Node-RED는 변경내용을 다음 배포시에 선택한 키를 사용하여 \n 자격증명파일을 다시 암호화합니다.\n---------------------------------------------------------------------\n" + }, + "flows": { + "safe-mode": "[안전모드] 플로우가 정지되었습니다. 시작하려면 배포하세요.", + "registered-missing": "누락된 노드를 등록합니다: __type__", + "error": "플로우 불러오기 에러: __message__", + "starting-modified-nodes": "수정된 노드 시작중", + "starting-modified-flows": "수정된 플로우 시작중", + "starting-flows": "플로우 시작중", + "started-modified-nodes": "수정된 노드 시작됨", + "started-modified-flows": "수정된 플로우 시작됨", + "started-flows": "플로우 시작됨", + "stopping-modified-nodes": "수정된 노드 중지중", + "stopping-modified-flows": "수정된 플로우 중지중", + "stopping-flows": "플로우 중지중", + "stopped-modified-nodes": "수정된 노드 중지됨", + "stopped-modified-flows": "수정된 플로우 중지됨", + "stopped-flows": "플로우 중지됨", + "stopped": "중지됨", + "stopping-error": "노드 중지 오류: __message__", + "added-flow": "플로우 추가: __label__", + "updated-flow": "플로우 변경: __label__", + "removed-flow": "플로우 삭제: __label__", + "missing-types": "누락된 플로우타입이 등록되기를 기다림:", + "missing-type-provided": " - __type__ (provided by npm module __module__)", + "missing-type-install-1": "누락된 모듈을 설치하려면, 실행:", + "missing-type-install-2": "디렉토리에서:" + }, + "flow": { + "unknown-type": "알수없는 타입: __type__", + "missing-types": "누락된 타입", + "error-loop": "메세지 최대 캐치수를 초과했습니다." + }, + "index": { + "unrecognised-id": "인식할 수 없는 ID: __id__", + "type-in-use": "사용하는 타입: __msg__", + "unrecognised-module": "인식할 수 없는 모듈: __module__" + }, + "registry": { + "localfilesystem": { + "module-not-found": "'__module__' 모듈을 찾을 수 없습니다." + } + } + }, + "storage": { + "index": { + "forbidden-flow-name": "올바르지 않은 플로우명" + }, + "localfilesystem": { + "user-dir": "사용자 디렉토리: __path__", + "flows-file": "플로우 파일 : __path__", + "create": "새로운 __type__ 파일 만듭니다.", + "empty": "기존 __type__ 파일이 비어있습니다.", + "invalid": "기존 __type__ 파일이 json형식이 아닙니다.", + "restore": "__type__ 파일을 __path__ 에서 복원합니다.", + "restore-fail": "__type__ 파일 복원 실패 : __message__", + "fsync-fail": "__path__ 파일 디스크쓰기 실패 : __message__", + "projects": { + "changing-project": "프로젝트 설정: __project__", + "active-project": "선택중인 프로젝트: __project__", + "project-not-found": "프로젝트가 없습니다: __project__", + "no-active-project": "선택된 프로젝트가 없습니다: 기본 플로우 파일을 사용합니다.", + "disabled": "프로젝트가 비활성화 되어있습니다: editorTheme.projects.enabled=false", + "disabledNoFlag": "프로젝트가 비활성화 되어있습니다: set editorTheme.projects.enabled=true to enable", + "git-not-found": "프로젝트가 비활성화 되어있습니다: git 명령어가 없습니다.", + "git-version-old": "프로젝트가 비활성화 되어있습니다: git __version__ 을 지원하지 않습니다. 2.x가 요구됩니다.", + "summary": "Node-RED 프로젝트", + "readme": "### 설명\n\n 이것은 프로젝트 README.md 파일입니다. 이 파일에는 프로젝트의 설명, \n 이용방법, 그 외 정보를 기재합니다." + } + } + }, + "context": { + "log-store-init": "Context 저장소 : '__name__' [__info__]", + "error-loading-module": "context 저장소 불러오기 에러: __message__", + "error-loading-module2": "context 저장소 불러오기 에러 '__module__': __message__ ", + "error-module-not-defined": "Context 저장소 '__storage__'에 'module'옵션이 지정되지 않았습니다.", + "error-invalid-module-name": "context 저장소 이름 에러: '__name__'", + "error-invalid-default-module": "기본 context 저장소가 없음: '__storage__'", + "unknown-store": "알 수 없는 context 저장소 '__name__' 가 지정되었습니다. 기본 저장소를 사용합니다.", + "localfilesystem": { + "error-circular": "Context __scope__ 는 지속할 수 없는 순환참조를 포함합니다.", + "error-write": "context 저장 에러: __message__" + } + } +} \ No newline at end of file diff --git a/packages/connector/packages/node_modules/@node-red/runtime/locales/zh-CN/runtime.json b/packages/connector/packages/node_modules/@node-red/runtime/locales/zh-CN/runtime.json new file mode 100644 index 0000000..d0813f4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/locales/zh-CN/runtime.json @@ -0,0 +1,174 @@ +{ + "runtime": { + "welcome": "欢迎使用Node-RED", + "version": "__component__ 版本: __version__", + "unsupported_version": "__component__的不受支持的版本。要求: __requires__ 找到: __version__", + "paths": { + "settings": "设置文件 : __path__", + "httpStatic": "HTTP Static : __path__" + } + }, + + "server": { + "loading": "加载控制板节点", + "palette-editor": { + "disabled": "控制板编辑器已禁用:用户设置", + "npm-not-found": "控制板编辑器已禁用:找不到npm命令", + "npm-too-old": "控制板编辑器已禁用: npm版本太旧。需要版本npm >= 3.x" + }, + "errors": "无法注册__count__节点类型", + "errors_plural": "无法注册__count__个节点类型", + "errors-help": "使用-v运行以获取详细信息", + "missing-modules": "缺少节点模块:", + "node-version-mismatch": "无法在此版本上加载节点模块。要求:__ version__", + "type-already-registered": "'__type__'已由模块__module__注册", + "removing-modules": "从配置中删除模块", + "added-types": "添加的节点类型:", + "removed-types": "删除的节点类型:", + "install": { + "invalid": "无效的模块名称", + "installing": "安装模块:__ name__,版本:__ version__", + "installed": "已安装的模块:__ name__", + "install-failed": "安装失败", + "install-failed-long": "模块__name__安装失败:", + "install-failed-not-found": "$t(server.install.install-failed-long) 模块未发现", + "upgrading": "更新模块: __name__ 至版本: __version__", + "upgraded": "更新模块: __name__。 重新启动Node-RED以使用新版本", + "upgrade-failed-not-found": "$t(server.install.install-failed-long) 未发现版本", + "uninstalling": "卸载模块: __name__", + "uninstall-failed": "卸载失败", + "uninstall-failed-long": "卸载模块__name__失败:", + "uninstalled": "卸载模块: __name__" + }, + "unable-to-listen": "无法在__listenpath__上收听", + "port-in-use": "错误: 端口正在使用中", + "uncaught-exception": "未捕获的异常:", + "admin-ui-disabled": "管理员界面已禁用", + "now-running": "服务器现在在__listenpath__上运行", + "failed-to-start": "无法启动服务器:", + "headless-mode": "在headless模式下运行", + "httpadminauth-deprecated": "不建议使用httpAdminAuth。请改用adminAuth" + }, + + "api": { + "flows": { + "error-save": "保存流程错误: __message__", + "error-reload": "重载流程错误: __message__" + }, + "library": { + "error-load-entry": "加载库条目'__path__'时出错:__message__", + "error-save-entry": "保存库条目'__path__'时出错:__ message__", + "error-load-flow": "加载流程'__path__'时出错:__ message__", + "error-save-flow": "保存流'__path__'时出错:__ message__" + }, + "nodes": { + "enabled": "启用的节点类型:", + "disabled": "禁用的节点类型:", + "error-enable": "无法启用节点:" + } + }, + + "comms": { + "error": "通讯渠道错误:__ message__", + "error-server": "通信服务器错误:__ message__", + "error-send": "通讯发送错误:__ message__" + }, + + "settings": { + "user-not-available": "无法保存用户设置:__ message__", + "not-available": "设置不可用", + "property-read-only": "属性“ __prop__”是只读的" + }, + + "nodes": { + "credentials": { + "error":"加载证书时出错:__ message__", + "error-saving":"保存证书时出错:__ message__", + "not-registered": "证书类型'__type__'未注册", + "system-key-warning": "\n\n---------------------------------------------------------------------\n您的流程证书文件是使用系统生成的密钥加密的。\n\n如果系统生成的密钥由于任何原因丢失,则您的证书文件将无法恢复,您将必须删除它并重新输入您的证书。\n\n您应该使用您的设置文件中的'credentialSecret'选项设置自己的密钥。然后,下次部署更改时,Node-RED将使用选择的密钥重新加密您的证书文件。\n---------------------------------------------------------------------\n" + }, + "flows": { + "safe-mode": "流程在安全模式下停止。部署开始。", + "registered-missing": "缺少注册的类型:__ type__", + "error": "错误加载流程:__ message__", + "starting-modified-nodes": "启动修改的节点", + "starting-modified-flows": "启动修改的流程", + "starting-flows": "启动流程", + "started-modified-nodes": "修改的节点已启动", + "started-modified-flows": "修改的流程已启动", + "started-flows": "流程已启动", + "stopping-modified-nodes": "停止修改的节点", + "stopping-modified-flows": "停止修改的流程", + "stopping-flows": "停止流程", + "stopped-modified-nodes": "修改的节点已停止", + "stopped-modified-flows": "修改的流程已停止", + "stopped-flows": "流程已停止", + "stopped": "已停止", + "stopping-error": "错误停止节点:__ message__", + "added-flow": "流程已添加: __label__", + "updated-flow": "流程已更新: __label__", + "removed-flow": "流程已移除: __label__", + "missing-types": "等待缺少的类型被注册:", + "missing-type-provided": " - __type__ (由npm模块__module__提供)", + "missing-type-install-1": "要安装所有缺少的模块,请运行:", + "missing-type-install-2": "在目录中:" + }, + "flow": { + "unknown-type": "未知类型: __type__", + "missing-types": "缺少类型", + "error-loop": "邮件已超过最大捕获数" + }, + "index": { + "unrecognised-id": "无法识别的ID: __id__", + "type-in-use": "使用中的类型: __msg__", + "unrecognised-module": "无法识别的模块: __module__" + }, + "registry": { + "localfilesystem": { + "module-not-found": "找不到模块:'__module__'" + } + } + }, + + "storage": { + "index": { + "forbidden-flow-name": "禁止流程名称" + }, + "localfilesystem": { + "user-dir": "用户目录: __path__", + "flows-file": "流程文件: __path__", + "create": "创建新__type__文件", + "empty": "现有__type__文件为空", + "invalid": "现有__type__文件为无效json", + "restore": "恢复__type__文件备份:__path__", + "restore-fail": "恢复__type__文件备份失败:__ message__", + "fsync-fail": "将文件__path__刷新到磁盘失败:__message__", + "projects": { + "changing-project": "设置活动项目:__ project__", + "active-project": "活动项目:__ project__", + "project-not-found": "找不到项目:__ project__", + "no-active-project": "没有活动的项目:使用默认流文件", + "disabled": "项目已禁用:editorTheme.projects.enabled = false", + "disabledNoFlag": "项目已禁用:设置editorTheme.projects.enabled = true来启用", + "git-not-found": "项目已禁用:找不到git命令", + "git-version-old": "项目已禁用:不支持的git __version__。 需要的git版本为2.x", + "summary": "一个Node-RED项目", + "readme": "### 关于\n\n这是您项目的README.md文件。它可以帮助用户了解您的项目,如何使用它以及他们可能需要知道的其他任何信息。" + } + } + }, + + "context": { + "log-store-init": "上下文储存: '__name__' [__info__]", + "error-loading-module": "加载上下文存储时出错: __message__", + "error-loading-module2": "加载上下文存储时出错 '__module__': __message__", + "error-module-not-defined": "上下文存储库'__storage__'缺少“模块”选项", + "error-invalid-module-name": "无效的上下文存储名称:'__ name__'", + "error-invalid-default-module": "无效的默认的上下文存储库: '__storage__'", + "unknown-store": "指定了未知的上下文存储库'__name__'。 使用默认存储库。", + "localfilesystem": { + "error-circular": "上下文__scope__包含无法保留的循环引用", + "error-write": "编写上下文时出错:__ message__" + } + } +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/locales/zh-TW/runtime.json b/packages/connector/packages/node_modules/@node-red/runtime/locales/zh-TW/runtime.json new file mode 100644 index 0000000..b96d87a --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/locales/zh-TW/runtime.json @@ -0,0 +1,174 @@ +{ + "runtime": { + "welcome": "歡迎使用Node-RED", + "version": "__component__ 版本: __version__", + "unsupported_version": "__component__的不受支持的版本。要求: __requires__ 找到: __version__", + "paths": { + "settings": "設置文件 : __path__", + "httpStatic": "HTTP Static : __path__" + } + }, + + "server": { + "loading": "加載控制板節點", + "palette-editor": { + "disabled": "控制板編輯器已禁用:用戶設置", + "npm-not-found": "控制板編輯器已禁用:找不到npm命令", + "npm-too-old": "控制板編輯器已禁用: npm版本太舊。需要版本npm >= 3.x" + }, + "errors": "無法註冊__count__節點類型", + "errors_plural": "無法註冊__count__個節點類型", + "errors-help": "使用-v運行以獲取詳細信息", + "missing-modules": "缺少節點模組:", + "node-version-mismatch": "無法在此版本上加載節點模組。要求:__ version__", + "type-already-registered": "'__type__'已由模組__module__註冊", + "removing-modules": "從配置中刪除模組", + "added-types": "添加的節點類型:", + "removed-types": "刪除的節點類型:", + "install": { + "invalid": "無效的模組名稱", + "installing": "安裝模組:__ name__,版本:__ version__", + "installed": "已安裝的模組:__ name__", + "install-failed": "安裝失敗", + "install-failed-long": "模組__name__安裝失敗:", + "install-failed-not-found": "$t(server.install.install-failed-long) 模組未發現", + "upgrading": "更新模組: __name__ 至版本: __version__", + "upgraded": "更新模組: __name__。 重新啟動Node-RED以使用新版本", + "upgrade-failed-not-found": "$t(server.install.install-failed-long) 未發現版本", + "uninstalling": "卸載模組: __name__", + "uninstall-failed": "卸載失敗", + "uninstall-failed-long": "卸載模組__name__失敗:", + "uninstalled": "卸載模組: __name__" + }, + "unable-to-listen": "無法在__listenpath__上收聽", + "port-in-use": "錯誤: 端口正在使用中", + "uncaught-exception": "未捕獲的異常:", + "admin-ui-disabled": "管理員界面已禁用", + "now-running": "服務器現在在__listenpath__上運行", + "failed-to-start": "無法啟動服務器:", + "headless-mode": "在headless模式下運行", + "httpadminauth-deprecated": "不建議使用httpAdminAuth。請改用adminAuth" + }, + + "api": { + "flows": { + "error-save": "保存流程錯誤: __message__", + "error-reload": "重載流程錯誤: __message__" + }, + "library": { + "error-load-entry": "加載庫條目'__path__'時出錯:__message__", + "error-save-entry": "保存庫條目'__path__'時出錯:__ message__", + "error-load-flow": "加載流程'__path__'時出錯:__ message__", + "error-save-flow": "保存流'__path__'時出錯:__ message__" + }, + "nodes": { + "enabled": "啟用的節點類型:", + "disabled": "禁用的節點類型:", + "error-enable": "無法啟用節點:" + } + }, + + "comms": { + "error": "通訊渠道錯誤:__ message__", + "error-server": "通信服務器錯誤:__ message__", + "error-send": "通訊發送錯誤:__ message__" + }, + + "settings": { + "user-not-available": "無法保存用戶設置:__ message__", + "not-available": "設置不可用", + "property-read-only": "屬性“ __prop__”是只讀的" + }, + + "nodes": { + "credentials": { + "error":"加載證書時出錯:__ message__", + "error-saving":"保存證書時出錯:__ message__", + "not-registered": "證書類型'__type__'未註冊", + "system-key-warning": "\n\n---------------------------------------------------------------------\n您的流程證書文件是使用系統生成的密鑰加密的。\n\n如果系統生成的密鑰由於任何原因丟失,則您的證書文件將無法恢復,您將必須刪除它並重新輸入您的證書。\n\n您應該使用您的設置文件中的'credentialSecret'選項設置自己的密鑰。然後,下次部署更改時,Node-RED將使用選擇的密鑰重新加密您的證書文件。\n---------------------------------------------------------------------\n" + }, + "flows": { + "safe-mode": "流程在安全模式下停止。部署開始。", + "registered-missing": "缺少註冊的類型:__ type__", + "error": "錯誤加載流程:__ message__", + "starting-modified-nodes": "啟動修改的節點", + "starting-modified-flows": "啟動修改的流程", + "starting-flows": "啟動流程", + "started-modified-nodes": "修改的節點已啟動", + "started-modified-flows": "修改的流程已啟動", + "started-flows": "流程已啟動", + "stopping-modified-nodes": "停止修改的節點", + "stopping-modified-flows": "停止修改的流程", + "stopping-flows": "停止流程", + "stopped-modified-nodes": "修改的節點已停止", + "stopped-modified-flows": "修改的流程已停止", + "stopped-flows": "流程已停止", + "stopped": "已停止", + "stopping-error": "錯誤停止節點:__ message__", + "added-flow": "流程已添加: __label__", + "updated-flow": "流程已更新: __label__", + "removed-flow": "流程已移除: __label__", + "missing-types": "等待缺少的類型被註冊:", + "missing-type-provided": " - __type__ (由npm模組__module__提供)", + "missing-type-install-1": "要安裝所有缺少的模組,請運行:", + "missing-type-install-2": "在目錄中:" + }, + "flow": { + "unknown-type": "未知類型: __type__", + "missing-types": "缺少類型", + "error-loop": "郵件已超過最大捕獲數" + }, + "index": { + "unrecognised-id": "無法識別的ID: __id__", + "type-in-use": "使用中的類型: __msg__", + "unrecognised-module": "無法識別的模組: __module__" + }, + "registry": { + "localfilesystem": { + "module-not-found": "找不到模組:'__module__'" + } + } + }, + + "storage": { + "index": { + "forbidden-flow-name": "禁止流程名稱" + }, + "localfilesystem": { + "user-dir": "用戶目錄: __path__", + "flows-file": "流程文件: __path__", + "create": "創建新__type__文件", + "empty": "現有__type__文件為空", + "invalid": "現有__type__文件為無效json", + "restore": "恢復__type__文件備份:__path__", + "restore-fail": "恢復__type__文件備份失敗:__ message__", + "fsync-fail": "將文件__path__刷新到磁盤失敗:__message__", + "projects": { + "changing-project": "設置活動項目:__ project__", + "active-project": "活動項目:__ project__", + "project-not-found": "找不到項目:__ project__", + "no-active-project": "沒有活動的項目:使用默認流文件", + "disabled": "項目已禁用:editorTheme.projects.enabled = false", + "disabledNoFlag": "項目已禁用:設置editorTheme.projects.enabled = true來啟用", + "git-not-found": "項目已禁用:找不到git命令", + "git-version-old": "項目已禁用:不支持的git __version__。 需要的git版本為2.x", + "summary": "一個Node-RED項目", + "readme": "### 關於\n\n這是您項目的README.md文件。它可以幫助用戶了解您的項目,如何使用它以及他們可能需要知道的其他任何信息。" + } + } + }, + + "context": { + "log-store-init": "上下文儲存: '__name__' [__info__]", + "error-loading-module": "加載上下文存儲時出錯: __message__", + "error-loading-module2": "加載上下文存儲時出錯 '__module__': __message__", + "error-module-not-defined": "上下文存儲庫'__storage__'缺少“模組”選項", + "error-invalid-module-name": "無效的上下文存儲名稱:'__ name__'", + "error-invalid-default-module": "無效的默認的上下文存儲庫: '__storage__'", + "unknown-store": "指定了未知的上下文存儲庫'__name__'。 使用默認存儲庫。", + "localfilesystem": { + "error-circular": "上下文__scope__包含無法保留的循環引用", + "error-write": "編寫上下文時出錯:__ message__" + } + } +} diff --git a/packages/connector/packages/node_modules/@node-red/runtime/package.json b/packages/connector/packages/node_modules/@node-red/runtime/package.json new file mode 100644 index 0000000..50f9fb2 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/runtime/package.json @@ -0,0 +1,27 @@ +{ + "name": "@node-red/runtime", + "version": "1.0.4", + "license": "Apache-2.0", + "main": "./lib/index.js", + "repository": { + "type": "git", + "url": "https://github.com/node-red/node-red.git" + }, + "contributors": [ + { + "name": "Nick O'Leary" + }, + { + "name": "Dave Conway-Jones" + } + ], + "dependencies": { + "@node-red/registry": "1.0.4", + "@node-red/util": "1.0.4", + "clone": "2.1.2", + "express": "4.17.1", + "fs-extra": "8.1.0", + "json-stringify-safe": "5.0.1", + "when": "3.7.8" + } +} diff --git a/packages/connector/packages/node_modules/@node-red/util/.npmignore b/packages/connector/packages/node_modules/@node-red/util/.npmignore new file mode 100644 index 0000000..99c96b4 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/util/.npmignore @@ -0,0 +1,2 @@ +src +docs diff --git a/packages/connector/packages/node_modules/@node-red/util/LICENSE b/packages/connector/packages/node_modules/@node-red/util/LICENSE new file mode 100644 index 0000000..fc619bd --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/util/LICENSE @@ -0,0 +1,178 @@ +Copyright JS Foundation and other contributors, http://js.foundation + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/packages/connector/packages/node_modules/@node-red/util/README.md b/packages/connector/packages/node_modules/@node-red/util/README.md new file mode 100644 index 0000000..9228855 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/util/README.md @@ -0,0 +1,10 @@ +@node-red/util +==================== + +Node-RED utilities module. + +This provides common utilities shared by the Node-RED components. + +### Source + +The main Node-RED modules are maintained as a monorepo on [GitHub](https://github.com/node-red/node-red). diff --git a/packages/connector/packages/node_modules/@node-red/util/index.js b/packages/connector/packages/node_modules/@node-red/util/index.js new file mode 100644 index 0000000..66ac91b --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/util/index.js @@ -0,0 +1,57 @@ +/*! + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +const log = require("./lib/log"); +const i18n = require("./lib/i18n"); +const util = require("./lib/util"); + +/** + * This module provides common utilities for the Node-RED runtime and editor + * + * @namespace @node-red/util + */ +module.exports = { + /** + * Initialise the module with the runtime settings + * @param {Object} settings + * @memberof @node-red/util + */ + init: function(settings) { + log.init(settings); + i18n.init(); + }, + + /** + * Logging utilities + * @mixes @node-red/util_log + * @memberof @node-red/util + */ + log: log, + + /** + * Internationalization utilities + * @mixes @node-red/util_i18n + * @memberof @node-red/util + */ + i18n: i18n, + + /** + * General utilities + * @mixes @node-red/util_util + * @memberof @node-red/util + */ + util: util, +} diff --git a/packages/connector/packages/node_modules/@node-red/util/lib/i18n.js b/packages/connector/packages/node_modules/@node-red/util/lib/i18n.js new file mode 100644 index 0000000..d95f4be --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/util/lib/i18n.js @@ -0,0 +1,239 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * @ignore + **/ + +/** + * Internationalization utilities + * @mixin @node-red/util_i18n + */ + +var i18n = require("i18next"); + +var when = require("when"); +var path = require("path"); +var fs = require("fs"); + +var defaultLang = "en-US"; + +var resourceMap = {}; +var resourceCache = {}; +var initPromise; + +/** + * Register multiple message catalogs with i18n. + * @memberof @node-red/util_i18n + */ +function registerMessageCatalogs(catalogs) { + var promises = catalogs.map(function(catalog) { + return registerMessageCatalog(catalog.namespace,catalog.dir,catalog.file); + }); + return when.settle(promises); +} + +/** + * Register a message catalog with i18n. + * @memberof @node-red/util_i18n + */ +function registerMessageCatalog(namespace,dir,file) { + return initPromise.then(function() { + return new Promise((resolve,reject) => { + resourceMap[namespace] = { basedir:dir, file:file, lngs: []}; + fs.readdir(dir,function(err, files) { + if (err) { + resolve(); + } else { + files.forEach(function(f) { + if (fs.existsSync(path.join(dir,f,file))) { + resourceMap[namespace].lngs.push(f); + } + }); + i18n.loadNamespaces(namespace,function() { + resolve(); + }); + } + }) + }); + }); +} + +function mergeCatalog(fallback,catalog) { + for (var k in fallback) { + if (fallback.hasOwnProperty(k)) { + if (!catalog[k]) { + catalog[k] = fallback[k]; + } else if (typeof fallback[k] === 'object') { + mergeCatalog(fallback[k],catalog[k]); + } + } + } +} + + +function readFile(lng, ns) { + return new Promise((resolve, reject) => { + if (resourceCache[ns] && resourceCache[ns][lng]) { + resolve(resourceCache[ns][lng]); + } else if (resourceMap[ns]) { + var file = path.join(resourceMap[ns].basedir, lng, resourceMap[ns].file); + fs.readFile(file, "utf8", function (err, content) { + if (err) { + reject(err); + } else { + try { + resourceCache[ns] = resourceCache[ns] || {}; + resourceCache[ns][lng] = JSON.parse(content.replace(/^\uFEFF/, '')); + var baseLng = lng.split('-')[0]; + if (baseLng !== lng && resourceCache[ns][baseLng]) { + mergeCatalog(resourceCache[ns][baseLng], resourceCache[ns][lng]); + } + if (lng !== defaultLang) { + mergeCatalog(resourceCache[ns][defaultLang], resourceCache[ns][lng]); + } + resolve(resourceCache[ns][lng]); + } catch (e) { + reject(e); + } + } + }); + } else { + reject(new Error("Unrecognised namespace")); + } + }); +} + +var MessageFileLoader = { + type: "backend", + init: function (services, backendOptions, i18nextOptions) { }, + read: function (lng, ns, callback) { + readFile(lng, ns) + .then(data => callback(null, data)) + .catch(err => { + if (/-/.test(lng)) { + // if reading language file fails -> try reading base language (e. g. 'fr' instead of 'fr-FR' or 'de' for 'de-DE') + var baseLng = lng.split('-')[0]; + readFile(baseLng, ns).then(baseData => callback(null, baseData)).catch(err => callback(err)); + } else { + callback(err); + } + }); + } +} + +function getCurrentLocale() { + var env = process.env; + for (var name of ['LC_ALL', 'LC_MESSAGES', 'LANG']) { + if (name in env) { + var val = env[name]; + return val.substring(0, 2); + } + } + return undefined; +} + +function init() { + if (!initPromise) { + // Keep this as a 'when' promise as top-level red.js uses 'otherwise' + // and embedded users of NR may have copied that. + initPromise = when.promise((resolve,reject) => { + i18n.use(MessageFileLoader); + var opt = { + // debug: true, + defaultNS: "runtime", + ns: [], + fallbackLng: defaultLang, + interpolation: { + unescapeSuffix: 'HTML', + escapeValue: false, + prefix: '__', + suffix: '__' + } + }; + var lang = getCurrentLocale(); + if (lang) { + opt.lng = lang; + } + i18n.init(opt ,function() { + resolve(); + }); + }); + } +} + + +/** + * Gets a message catalog. + * @name catalog + * @function + * @memberof @node-red/util_i18n + */ +function getCatalog(namespace,lang) { + var result = null; + lang = lang || defaultLang; + if (resourceCache.hasOwnProperty(namespace)) { + result = resourceCache[namespace][lang]; + if (!result) { + var langParts = lang.split("-"); + if (langParts.length == 2) { + result = resourceCache[namespace][langParts[0]]; + } + } + } + return result; +} + +/** + * Gets a list of languages a given catalog is available in. + * @name availableLanguages + * @function + * @memberof @node-red/util_i18n + */ +function availableLanguages(namespace) { + if (resourceMap.hasOwnProperty(namespace)) { + return resourceMap[namespace].lngs + } +} + +var obj = module.exports = { + init: init, + registerMessageCatalog: registerMessageCatalog, + registerMessageCatalogs: registerMessageCatalogs, + catalog: getCatalog, + availableLanguages: availableLanguages, + /** + * The underlying i18n library for when direct access is really needed + */ + i: i18n, + /** + * The default language of the runtime + */ + defaultLang: defaultLang +} + +/** + * Perform a message catalog lookup. + * @name _ + * @function + * @memberof @node-red/util_i18n + */ +obj['_'] = function() { + //var opts = {}; + //if (def) { + // opts.defaultValue = def; + //} + //console.log(arguments); + var res = i18n.t.apply(i18n,arguments); + return res; +} diff --git a/packages/connector/packages/node_modules/@node-red/util/lib/log.js b/packages/connector/packages/node_modules/@node-red/util/lib/log.js new file mode 100644 index 0000000..8d7b849 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/util/lib/log.js @@ -0,0 +1,234 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * @ignore + **/ + +/** + * Logging utilities + * @mixin @node-red/util_log + */ + +var util = require("util"); +var EventEmitter = require("events").EventEmitter; + +var i18n = require("./i18n"); + +var levels = { + off: 1, + fatal: 10, + error: 20, + warn: 30, + info: 40, + debug: 50, + trace: 60, + audit: 98, + metric: 99 +}; + +var levelNames = { + 10: "fatal", + 20: "error", + 30: "warn", + 40: "info", + 50: "debug", + 60: "trace", + 98: "audit", + 99: "metric" +}; + +var logHandlers = []; + +var verbose; + +var metricsEnabled = false; + +var LogHandler = function(settings) { + this.logLevel = settings ? levels[settings.level]||levels.info : levels.info; + this.metricsOn = settings ? settings.metrics||false : false; + this.auditOn = settings ? settings.audit||false : false; + + metricsEnabled = metricsEnabled || this.metricsOn; + + this.handler = (settings && settings.handler) ? settings.handler(settings) : consoleLogger; + this.on("log",function(msg) { + if (this.shouldReportMessage(msg.level)) { + this.handler(msg); + } + }); +} +util.inherits(LogHandler, EventEmitter); + +LogHandler.prototype.shouldReportMessage = function(msglevel) { + return (msglevel == log.METRIC && this.metricsOn) || + (msglevel == log.AUDIT && this.auditOn) || + msglevel <= this.logLevel; +} + +var consoleLogger = function(msg) { + if (msg.level == log.METRIC || msg.level == log.AUDIT) { + util.log("["+levelNames[msg.level]+"] "+JSON.stringify(msg)); + } else { + if (verbose && msg.msg && msg.msg.stack) { + util.log("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+msg.msg.stack); + } else { + var message = msg.msg; + try { + if (typeof message === 'object' && message !== null && message.toString() === '[object Object]' && message.message) { + message = message.message; + } + } catch(e){ + message = 'Exception trying to log: '+util.inspect(message); + } + + util.log("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+message); + } + } +} + + +var log = module.exports = { + + FATAL: 10, + ERROR: 20, + WARN: 30, + INFO: 40, + DEBUG: 50, + TRACE: 60, + AUDIT: 98, + METRIC: 99, + + init: function(settings) { + metricsEnabled = false; + logHandlers = []; + var loggerSettings = {}; + verbose = settings.verbose; + if (settings.logging) { + var keys = Object.keys(settings.logging); + if (keys.length === 0) { + log.addHandler(new LogHandler()); + } else { + for (var i=0, l=keys.length; i<l; i++) { + var config = settings.logging[keys[i]]; + loggerSettings = config || {}; + if ((keys[i] === "console") || config.handler) { + log.addHandler(new LogHandler(loggerSettings)); + } + } + } + } else { + log.addHandler(new LogHandler()); + } + }, + + /** + * Add a log handler function + * @memberof @node-red/util_log + */ + addHandler: function(func) { + logHandlers.push(func); + }, + + /** + * Remove a log handler function + * @memberof @node-red/util_log + */ + removeHandler: function(func) { + var index = logHandlers.indexOf(func); + if (index > -1) { + logHandlers.splice(index,1); + } + }, + + /** + * Log a message object + * @memberof @node-red/util_log + */ + log: function(msg) { + msg.timestamp = Date.now(); + logHandlers.forEach(function(handler) { + handler.emit("log",msg); + }); + }, + + /** + * Log a message at INFO level + * @memberof @node-red/util_log + */ + info: function(msg) { + log.log({level:log.INFO,msg:msg}); + }, + + /** + * Log a message at WARN level + * @memberof @node-red/util_log + */ + warn: function(msg) { + log.log({level:log.WARN,msg:msg}); + }, + + /** + * Log a message at ERROR level + * @memberof @node-red/util_log + */ + error: function(msg) { + log.log({level:log.ERROR,msg:msg}); + }, + + /** + * Log a message at TRACE level + * @memberof @node-red/util_log + */ + trace: function(msg) { + log.log({level:log.TRACE,msg:msg}); + }, + + /** + * Log a message at DEBUG level + * @memberof @node-red/util_log + */ + debug: function(msg) { + log.log({level:log.DEBUG,msg:msg}); + }, + + /** + * Check if metrics are enabled + * @memberof @node-red/util_log + */ + metric: function() { + return metricsEnabled; + }, + + /** + * Log an audit event. + * @memberof @node-red/util_log + */ + audit: function(msg,req) { + msg.level = log.AUDIT; + if (req) { + msg.user = req.user; + msg.path = req.path; + msg.ip = req.ip || (req.headers && req.headers['x-forwarded-for']) || (req.connection && req.connection.remoteAddress) || undefined; + } + log.log(msg); + } +} + +/** + * Perform a message catalog lookup. + * @name _ + * @function + * @memberof @node-red/util_log + */ +log["_"] = i18n._; diff --git a/packages/connector/packages/node_modules/@node-red/util/lib/util.js b/packages/connector/packages/node_modules/@node-red/util/lib/util.js new file mode 100644 index 0000000..cd273df --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/util/lib/util.js @@ -0,0 +1,819 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * @ignore + **/ + +/** + * @mixin @node-red/util_util + */ + + +const clone = require("clone"); +const jsonata = require("jsonata"); +const safeJSONStringify = require("json-stringify-safe"); +const util = require("util"); + +/** + * Generates a psuedo-unique-random id. + * @return {String} a random-ish id + * @memberof @node-red/util_util + */ +function generateId() { + return (1+Math.random()*4294967295).toString(16); +} + +/** + * Converts the provided argument to a String, using type-dependent + * methods. + * + * @param {any} o - the property to convert to a String + * @return {String} the stringified version + * @memberof @node-red/util_util + */ +function ensureString(o) { + if (Buffer.isBuffer(o)) { + return o.toString(); + } else if (typeof o === "object") { + return JSON.stringify(o); + } else if (typeof o === "string") { + return o; + } + return ""+o; +} + +/** + * Converts the provided argument to a Buffer, using type-dependent + * methods. + * + * @param {any} o - the property to convert to a Buffer + * @return {String} the Buffer version + * @memberof @node-red/util_util + */ +function ensureBuffer(o) { + if (Buffer.isBuffer(o)) { + return o; + } else if (typeof o === "object") { + o = JSON.stringify(o); + } else if (typeof o !== "string") { + o = ""+o; + } + return Buffer.from(o); +} + +/** + * Safely clones a message object. This handles msg.req/msg.res objects that must + * not be cloned. + * + * @param {any} msg - the message object to clone + * @return {Object} the cloned message + * @memberof @node-red/util_util + */ +function cloneMessage(msg) { + if (typeof msg !== "undefined") { + // Temporary fix for #97 + // TODO: remove this http-node-specific fix somehow + var req = msg.req; + var res = msg.res; + delete msg.req; + delete msg.res; + var m = clone(msg); + if (req) { + m.req = req; + msg.req = req; + } + if (res) { + m.res = res; + msg.res = res; + } + return m; + } + return msg; +} + +/** + * Compares two objects, handling various JavaScript types. + * + * @param {any} obj1 + * @param {any} obj2 + * @return {boolean} whether the two objects are the same + * @memberof @node-red/util_util + */ +function compareObjects(obj1,obj2) { + var i; + if (obj1 === obj2) { + return true; + } + if (obj1 == null || obj2 == null) { + return false; + } + + var isArray1 = Array.isArray(obj1); + var isArray2 = Array.isArray(obj2); + if (isArray1 != isArray2) { + return false; + } + if (isArray1 && isArray2) { + if (obj1.length !== obj2.length) { + return false; + } + for (i=0;i<obj1.length;i++) { + if (!compareObjects(obj1[i],obj2[i])) { + return false; + } + } + return true; + } + var isBuffer1 = Buffer.isBuffer(obj1); + var isBuffer2 = Buffer.isBuffer(obj2); + if (isBuffer1 != isBuffer2) { + return false; + } + if (isBuffer1 && isBuffer2) { + if (obj1.equals) { + // For node 0.12+ - use the native equals + return obj1.equals(obj2); + } else { + if (obj1.length !== obj2.length) { + return false; + } + for (i=0;i<obj1.length;i++) { + if (obj1.readUInt8(i) !== obj2.readUInt8(i)) { + return false; + } + } + return true; + } + } + + if (typeof obj1 !== 'object' || typeof obj2 !== 'object') { + return false; + } + var keys1 = Object.keys(obj1); + var keys2 = Object.keys(obj2); + if (keys1.length != keys2.length) { + return false; + } + for (var k in obj1) { + /* istanbul ignore else */ + if (obj1.hasOwnProperty(k)) { + if (!compareObjects(obj1[k],obj2[k])) { + return false; + } + } + } + return true; +} + +function createError(code, message) { + var e = new Error(message); + e.code = code; + return e; +} + +/** + * Parses a property expression, such as `msg.foo.bar[3]` to validate it + * and convert it to a canonical version expressed as an Array of property + * names. + * + * For example, `a["b"].c` returns `['a','b','c']` + * + * @param {String} str - the property expression + * @return {Array} the normalised expression + * @memberof @node-red/util_util + */ +function normalisePropertyExpression(str) { + // This must be kept in sync with validatePropertyExpression + // in editor/js/ui/utils.js + + var length = str.length; + if (length === 0) { + throw createError("INVALID_EXPR","Invalid property expression: zero-length"); + } + var parts = []; + var start = 0; + var inString = false; + var inBox = false; + var quoteChar; + var v; + for (var i=0;i<length;i++) { + var c = str[i]; + if (!inString) { + if (c === "'" || c === '"') { + if (i != start) { + throw createError("INVALID_EXPR","Invalid property expression: unexpected "+c+" at position "+i); + } + inString = true; + quoteChar = c; + start = i+1; + } else if (c === '.') { + if (i===0) { + throw createError("INVALID_EXPR","Invalid property expression: unexpected . at position 0"); + } + if (start != i) { + v = str.substring(start,i); + if (/^\d+$/.test(v)) { + parts.push(parseInt(v)); + } else { + parts.push(v); + } + } + if (i===length-1) { + throw createError("INVALID_EXPR","Invalid property expression: unterminated expression"); + } + // Next char is first char of an identifier: a-z 0-9 $ _ + if (!/[a-z0-9\$\_]/i.test(str[i+1])) { + throw createError("INVALID_EXPR","Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1)); + } + start = i+1; + } else if (c === '[') { + if (i === 0) { + throw createError("INVALID_EXPR","Invalid property expression: unexpected "+c+" at position "+i); + } + if (start != i) { + parts.push(str.substring(start,i)); + } + if (i===length-1) { + throw createError("INVALID_EXPR","Invalid property expression: unterminated expression"); + } + // Next char is either a quote or a number + if (!/["'\d]/.test(str[i+1])) { + throw createError("INVALID_EXPR","Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1)); + } + start = i+1; + inBox = true; + } else if (c === ']') { + if (!inBox) { + throw createError("INVALID_EXPR","Invalid property expression: unexpected "+c+" at position "+i); + } + if (start != i) { + v = str.substring(start,i); + if (/^\d+$/.test(v)) { + parts.push(parseInt(v)); + } else { + throw createError("INVALID_EXPR","Invalid property expression: unexpected array expression at position "+start); + } + } + start = i+1; + inBox = false; + } else if (c === ' ') { + throw createError("INVALID_EXPR","Invalid property expression: unexpected ' ' at position "+i); + } + } else { + if (c === quoteChar) { + if (i-start === 0) { + throw createError("INVALID_EXPR","Invalid property expression: zero-length string at position "+start); + } + parts.push(str.substring(start,i)); + // If inBox, next char must be a ]. Otherwise it may be [ or . + if (inBox && !/\]/.test(str[i+1])) { + throw createError("INVALID_EXPR","Invalid property expression: unexpected array expression at position "+start); + } else if (!inBox && i+1!==length && !/[\[\.]/.test(str[i+1])) { + throw createError("INVALID_EXPR","Invalid property expression: unexpected "+str[i+1]+" expression at position "+(i+1)); + } + start = i+1; + inString = false; + } + } + + } + if (inBox || inString) { + throw new createError("INVALID_EXPR","Invalid property expression: unterminated expression"); + } + if (start < length) { + parts.push(str.substring(start)); + } + return parts; +} + +/** + * Gets a property of a message object. + * + * Unlike {@link @node-red/util-util.getObjectProperty}, this function will strip `msg.` from the + * front of the property expression if present. + * + * @param {Object} msg - the message object + * @param {String} expr - the property expression + * @return {any} the message property, or undefined if it does not exist + * @memberof @node-red/util_util + */ +function getMessageProperty(msg,expr) { + if (expr.indexOf('msg.')===0) { + expr = expr.substring(4); + } + return getObjectProperty(msg,expr); +} + +/** + * Gets a property of an object. + * + * @param {Object} msg - the object + * @param {String} expr - the property expression + * @return {any} the object property, or undefined if it does not exist + * @memberof @node-red/util_util + */ +function getObjectProperty(msg,expr) { + var result = null; + var msgPropParts = normalisePropertyExpression(expr); + var m; + msgPropParts.reduce(function(obj, key) { + result = (typeof obj[key] !== "undefined" ? obj[key] : undefined); + return result; + }, msg); + return result; +} + +/** + * Sets a property of a message object. + * + * Unlike {@link @node-red/util-util.setObjectProperty}, this function will strip `msg.` from the + * front of the property expression if present. + * + * @param {Object} msg - the message object + * @param {String} prop - the property expression + * @param {any} value - the value to set + * @param {boolean} createMissing - whether to create missing parent properties + * @memberof @node-red/util_util + */ +function setMessageProperty(msg,prop,value,createMissing) { + if (prop.indexOf('msg.')===0) { + prop = prop.substring(4); + } + return setObjectProperty(msg,prop,value,createMissing); +} + +/** + * Sets a property of an object. + * + * @param {Object} msg - the object + * @param {String} prop - the property expression + * @param {any} value - the value to set + * @param {boolean} createMissing - whether to create missing parent properties + * @memberof @node-red/util_util + */ +function setObjectProperty(msg,prop,value,createMissing) { + if (typeof createMissing === 'undefined') { + createMissing = (typeof value !== 'undefined'); + } + var msgPropParts = normalisePropertyExpression(prop); + var depth = 0; + var length = msgPropParts.length; + var obj = msg; + var key; + for (var i=0;i<length-1;i++) { + key = msgPropParts[i]; + if (typeof key === 'string' || (typeof key === 'number' && !Array.isArray(obj))) { + if (obj.hasOwnProperty(key)) { + obj = obj[key]; + } else if (createMissing) { + if (typeof msgPropParts[i+1] === 'string') { + obj[key] = {}; + } else { + obj[key] = []; + } + obj = obj[key]; + } else { + return null; + } + } else if (typeof key === 'number') { + // obj is an array + if (obj[key] === undefined) { + if (createMissing) { + if (typeof msgPropParts[i+1] === 'string') { + obj[key] = {}; + } else { + obj[key] = []; + } + obj = obj[key]; + } else { + return null; + } + } else { + obj = obj[key]; + } + } + } + key = msgPropParts[length-1]; + if (typeof value === "undefined") { + if (typeof key === 'number' && Array.isArray(obj)) { + obj.splice(key,1); + } else { + delete obj[key] + } + } else { + obj[key] = value; + } +} + +/*! + * Get value of environment variable. + * @param {Node} node - accessing node + * @param {String} name - name of variable + * @return {String} value of env var + */ +function getSetting(node, name) { + if (node && node._flow) { + var flow = node._flow; + if (flow) { + return flow.getSetting(name); + } + } + return process.env[name]; +} + + +/** + * Checks if a String contains any Environment Variable specifiers and returns + * it with their values substituted in place. + * + * For example, if the env var `WHO` is set to `Joe`, the string `Hello ${WHO}!` + * will return `Hello Joe!`. + * @param {String} value - the string to parse + * @param {Node} node - the node evaluating the property + * @return {String} The parsed string + * @memberof @node-red/util_util + */ +function evaluateEnvProperty(value, node) { + var result; + if (/^\${[^}]+}$/.test(value)) { + // ${ENV_VAR} + var name = value.substring(2,value.length-1); + result = getSetting(node, name); + } else if (!/\${\S+}/.test(value)) { + // ENV_VAR + result = getSetting(node, value); + } else { + // FOO${ENV_VAR}BAR + return value.replace(/\${([^}]+)}/g, function(match, name) { + var val = getSetting(node, name); + return (val === undefined)?"":val; + }); + } + return (result === undefined)?"":result; + +} + + +/** + * Parses a context property string, as generated by the TypedInput, to extract + * the store name if present. + * + * For example, `#:(file)::foo` results in ` { store: "file", key: "foo" }`. + * + * @param {String} key - the context property string to parse + * @return {Object} The parsed property + * @memberof @node-red/util_util + */ +function parseContextStore(key) { + var parts = {}; + var m = /^#:\((\S+?)\)::(.*)$/.exec(key); + if (m) { + parts.store = m[1]; + parts.key = m[2]; + } else { + parts.key = key; + } + return parts; +} + + +/** + * Evaluates a property value according to its type. + * + * @param {String} value - the raw value + * @param {String} type - the type of the value + * @param {Node} node - the node evaluating the property + * @param {Object} msg - the message object to evaluate against + * @param {Function} callback - (optional) called when the property is evaluated + * @return {any} The evaluted property, if no `callback` is provided + * @memberof @node-red/util_util + */ +function evaluateNodeProperty(value, type, node, msg, callback) { + var result = value; + if (type === 'str') { + result = ""+value; + } else if (type === 'num') { + result = Number(value); + } else if (type === 'json') { + result = JSON.parse(value); + } else if (type === 're') { + result = new RegExp(value); + } else if (type === 'date') { + result = Date.now(); + } else if (type === 'bin') { + var data = JSON.parse(value); + result = Buffer.from(data); + } else if (type === 'msg' && msg) { + try { + result = getMessageProperty(msg,value); + } catch(err) { + if (callback) { + callback(err); + } else { + throw err; + } + return; + } + } else if ((type === 'flow' || type === 'global') && node) { + var contextKey = parseContextStore(value); + result = node.context()[type].get(contextKey.key,contextKey.store,callback); + if (callback) { + return; + } + } else if (type === 'bool') { + result = /^true$/i.test(value); + } else if (type === 'jsonata') { + var expr = prepareJSONataExpression(value,node); + result = evaluateJSONataExpression(expr,msg); + } else if (type === 'env') { + result = evaluateEnvProperty(value, node); + } + if (callback) { + callback(null,result); + } else { + return result; + } +} + + +/** + * Prepares a JSONata expression for evaluation. + * This attaches Node-RED specific functions to the expression. + * + * @param {String} value - the JSONata expression + * @param {Node} node - the node evaluating the property + * @return {Object} The JSONata expression that can be evaluated + * @memberof @node-red/util_util + */ +function prepareJSONataExpression(value,node) { + var expr = jsonata(value); + expr.assign('flowContext',function(val, store) { + return node.context().flow.get(val, store); + }); + expr.assign('globalContext',function(val, store) { + return node.context().global.get(val, store); + }); + expr.assign('env', function(name) { + var val = getSetting(node, name); + return (val ? val : ""); + }) + expr.registerFunction('clone', cloneMessage, '<(oa)-:o>'); + expr._legacyMode = /(^|[^a-zA-Z0-9_'"])msg([^a-zA-Z0-9_'"]|$)/.test(value); + expr._node = node; + return expr; +} + +/** + * Evaluates a JSONata expression. + * The expression must have been prepared with {@link @node-red/util-util.prepareJSONataExpression} + * before passing to this function. + * + * @param {Object} expr - the prepared JSONata expression + * @param {Object} msg - the message object to evaluate against + * @param {Function} callback - (optional) called when the expression is evaluated + * @return {any} If no callback was provided, the result of the expression + * @memberof @node-red/util_util + */ +function evaluateJSONataExpression(expr,msg,callback) { + var context = msg; + if (expr._legacyMode) { + context = {msg:msg}; + } + var bindings = {}; + + if (callback) { + // If callback provided, need to override the pre-assigned sync + // context functions to be their async variants + bindings.flowContext = function(val, store) { + return new Promise((resolve,reject) => { + expr._node.context().flow.get(val, store, function(err,value) { + if (err) { + reject(err); + } else { + resolve(value); + } + }) + }); + } + bindings.globalContext = function(val, store) { + return new Promise((resolve,reject) => { + expr._node.context().global.get(val, store, function(err,value) { + if (err) { + reject(err); + } else { + resolve(value); + } + }) + }); + } + } + return expr.evaluate(context, bindings, callback); +} + +/** + * Normalise a node type name to camel case. + * + * For example: `a-random node type` will normalise to `aRandomNodeType` + * + * @param {String} name - the node type + * @return {String} The normalised name + * @memberof @node-red/util_util + */ +function normaliseNodeTypeName(name) { + var result = name.replace(/[^a-zA-Z0-9]/g, " "); + result = result.trim(); + result = result.replace(/ +/g, " "); + result = result.replace(/ ./g, + function(s) { + return s.charAt(1).toUpperCase(); + } + ); + result = result.charAt(0).toLowerCase() + result.slice(1); + return result; +} + +/** + * Encode an object to JSON without losing information about non-JSON types + * such as Buffer and Function. + * + * *This function is closely tied to its reverse within the editor* + * + * @param {Object} msg + * @param {Object} opts + * @return {Object} the encoded object + * @memberof @node-red/util_util + */ +function encodeObject(msg,opts) { + try { + var debuglength = 1000; + if (opts && opts.hasOwnProperty('maxLength')) { + debuglength = opts.maxLength; + } + var msgType = typeof msg.msg; + if (msg.msg instanceof Error) { + msg.format = "error"; + var errorMsg = {}; + if (msg.msg.name) { + errorMsg.name = msg.msg.name; + } + if (msg.msg.hasOwnProperty('message')) { + errorMsg.message = msg.msg.message; + } else { + errorMsg.message = msg.msg.toString(); + } + msg.msg = JSON.stringify(errorMsg); + } else if (msg.msg instanceof Buffer) { + msg.format = "buffer["+msg.msg.length+"]"; + msg.msg = msg.msg.toString('hex'); + if (msg.msg.length > debuglength) { + msg.msg = msg.msg.substring(0,debuglength); + } + } else if (msg.msg && msgType === 'object') { + try { + msg.format = msg.msg.constructor.name || "Object"; + // Handle special case of msg.req/res objects from HTTP In node + if (msg.format === "IncomingMessage" || msg.format === "ServerResponse") { + msg.format = "Object"; + } + } catch(err) { + msg.format = "Object"; + } + if (/error/i.test(msg.format)) { + msg.msg = JSON.stringify({ + name: msg.msg.name, + message: msg.msg.message + }); + } else { + var isArray = util.isArray(msg.msg); + if (isArray) { + msg.format = "array["+msg.msg.length+"]"; + if (msg.msg.length > debuglength) { + // msg.msg = msg.msg.slice(0,debuglength); + msg.msg = { + __enc__: true, + type: "array", + data: msg.msg.slice(0,debuglength), + length: msg.msg.length + } + } + } + if (isArray || (msg.format === "Object")) { + msg.msg = safeJSONStringify(msg.msg, function(key, value) { + if (key === '_req' || key === '_res') { + value = { + __enc__: true, + type: "internal" + } + } else if (value instanceof Error) { + value = value.toString() + } else if (util.isArray(value) && value.length > debuglength) { + value = { + __enc__: true, + type: "array", + data: value.slice(0,debuglength), + length: value.length + } + } else if (typeof value === 'string') { + if (value.length > debuglength) { + value = value.substring(0,debuglength)+"..."; + } + } else if (typeof value === 'function') { + value = { + __enc__: true, + type: "function" + } + } else if (typeof value === 'number') { + if (isNaN(value) || value === Infinity || value === -Infinity) { + value = { + __enc__: true, + type: "number", + data: value.toString() + } + } + } else if (value && value.constructor) { + if (value.type === "Buffer") { + value.__enc__ = true; + value.length = value.data.length; + if (value.length > debuglength) { + value.data = value.data.slice(0,debuglength); + } + } else if (value.constructor.name === "ServerResponse") { + value = "[internal]" + } else if (value.constructor.name === "Socket") { + value = "[internal]" + } + } + return value; + }," "); + } else { + try { msg.msg = msg.msg.toString(); } + catch(e) { msg.msg = "[Type not printable]" + util.inspect(msg.msg); } + } + } + } else if (msgType === "function") { + msg.format = "function"; + msg.msg = "[function]" + } else if (msgType === "boolean") { + msg.format = "boolean"; + msg.msg = msg.msg.toString(); + } else if (msgType === "number") { + msg.format = "number"; + msg.msg = msg.msg.toString(); + } else if (msg.msg === null || msgType === "undefined") { + msg.format = (msg.msg === null)?"null":"undefined"; + msg.msg = "(undefined)"; + } else { + msg.format = "string["+msg.msg.length+"]"; + if (msg.msg.length > debuglength) { + msg.msg = msg.msg.substring(0,debuglength)+"..."; + } + } + return msg; + } catch(e) { + msg.format = "error"; + var errorMsg = {}; + if (e.name) { + errorMsg.name = e.name; + } + if (e.hasOwnProperty('message')) { + errorMsg.message = 'encodeObject Error: ['+e.message + '] Value: '+util.inspect(msg.msg); + } else { + errorMsg.message = 'encodeObject Error: ['+e.toString() + '] Value: '+util.inspect(msg.msg); + } + if (errorMsg.message.length > debuglength) { + errorMsg.message = errorMsg.message.substring(0,debuglength); + } + msg.msg = JSON.stringify(errorMsg); + return msg; + } +} + +module.exports = { + encodeObject: encodeObject, + ensureString: ensureString, + ensureBuffer: ensureBuffer, + cloneMessage: cloneMessage, + compareObjects: compareObjects, + generateId: generateId, + getMessageProperty: getMessageProperty, + setMessageProperty: setMessageProperty, + getObjectProperty: getObjectProperty, + setObjectProperty: setObjectProperty, + evaluateNodeProperty: evaluateNodeProperty, + normalisePropertyExpression: normalisePropertyExpression, + normaliseNodeTypeName: normaliseNodeTypeName, + prepareJSONataExpression: prepareJSONataExpression, + evaluateJSONataExpression: evaluateJSONataExpression, + parseContextStore: parseContextStore +}; diff --git a/packages/connector/packages/node_modules/@node-red/util/package.json b/packages/connector/packages/node_modules/@node-red/util/package.json new file mode 100644 index 0000000..9beb618 --- /dev/null +++ b/packages/connector/packages/node_modules/@node-red/util/package.json @@ -0,0 +1,24 @@ +{ + "name": "@node-red/util", + "version": "1.0.4", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/node-red/node-red.git" + }, + "contributors": [ + { + "name": "Nick O'Leary" + }, + { + "name": "Dave Conway-Jones" + } + ], + "dependencies": { + "clone": "2.1.2", + "i18next": "15.1.2", + "json-stringify-safe": "5.0.1", + "jsonata": "1.8.1", + "when": "3.7.8" + } +} diff --git a/packages/connector/packages/node_modules/node-red/.gitignore b/packages/connector/packages/node_modules/node-red/.gitignore new file mode 100644 index 0000000..1b763b1 --- /dev/null +++ b/packages/connector/packages/node_modules/node-red/.gitignore @@ -0,0 +1 @@ +CHANGELOG.md diff --git a/packages/connector/packages/node_modules/node-red/.npmignore b/packages/connector/packages/node_modules/node-red/.npmignore new file mode 100644 index 0000000..99c96b4 --- /dev/null +++ b/packages/connector/packages/node_modules/node-red/.npmignore @@ -0,0 +1,2 @@ +src +docs diff --git a/packages/connector/packages/node_modules/node-red/LICENSE b/packages/connector/packages/node_modules/node-red/LICENSE new file mode 100644 index 0000000..fc619bd --- /dev/null +++ b/packages/connector/packages/node_modules/node-red/LICENSE @@ -0,0 +1,178 @@ +Copyright JS Foundation and other contributors, http://js.foundation + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/packages/connector/packages/node_modules/node-red/README.md b/packages/connector/packages/node_modules/node-red/README.md new file mode 100644 index 0000000..7ea4ffd --- /dev/null +++ b/packages/connector/packages/node_modules/node-red/README.md @@ -0,0 +1,53 @@ +# Node-RED + +http://nodered.org + +[![Build Status](https://travis-ci.org/node-red/node-red.svg)](https://travis-ci.org/node-red/node-red) +[![Coverage Status](https://coveralls.io/repos/node-red/node-red/badge.svg?branch=master)](https://coveralls.io/r/node-red/node-red?branch=master) + +A visual tool for wiring the Internet of Things. + +![Node-RED: A visual tool for wiring the Internet of Things](http://nodered.org/images/node-red-screenshot.png) + +## Quick Start + +Check out http://nodered.org/docs/getting-started/ for full instructions on getting +started. + +1. `sudo npm install -g --unsafe-perm node-red` +2. `node-red` +3. Open <http://localhost:1880> + +## Getting Help + +More documentation can be found [here](http://nodered.org/docs). + +For further help, or general discussion, please use the [Node-RED Forum](https://discourse.nodered.org) or [slack team](https://nodered.org/slack). + +## Developers + +The main Node-RED modules are maintained as a monorepo on [GitHub](https://github.com/node-red/node-red). + +## Contributing + +Before raising a pull-request, please read our +[contributing guide](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md). + +This project adheres to the [Contributor Covenant 1.4](http://contributor-covenant.org/version/1/4/). + By participating, you are expected to uphold this code. Please report unacceptable + behavior to any of the project's core team at team@nodered.org. + +## Authors + +Node-RED is a project of the [JS Foundation](http://js.foundation). + +It was created by [IBM Emerging Technology](https://www.ibm.com/blogs/emerging-technology/). + +* Nick O'Leary [@knolleary](http://twitter.com/knolleary) +* Dave Conway-Jones [@ceejay](http://twitter.com/ceejay) + + + +## Copyright and license + +Copyright JS Foundation and other contributors, http://js.foundation under [the Apache 2.0 license](LICENSE). diff --git a/packages/connector/packages/node_modules/node-red/bin/node-red-pi b/packages/connector/packages/node_modules/node-red/bin/node-red-pi new file mode 100644 index 0000000..0e9de3c --- /dev/null +++ b/packages/connector/packages/node_modules/node-red/bin/node-red-pi @@ -0,0 +1,43 @@ +#!/bin/bash +# +# Copyright JS Foundation and other contributors, http://js.foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Separate out node/v8 options from node-red ones +OPTIONS="" +ARGS="" + +for arg in "$@" +do + case $arg in + --userDir|--settings|--help) ARGS="$ARGS $arg";; + --*) OPTIONS="$OPTIONS $arg";; + *) ARGS="$ARGS $arg";; + esac +done + +# Find the real location of this script +CURRENT_PATH=`pwd` +SCRIPT_PATH="${BASH_SOURCE[0]}"; +while [ -h "${SCRIPT_PATH}" ]; do + cd "`dirname "${SCRIPT_PATH}"`" + SCRIPT_PATH="$(readlink "`basename "${SCRIPT_PATH}"`")"; +done +cd "`dirname "${SCRIPT_PATH}"`" > /dev/null +SCRIPT_PATH="`pwd`"; +cd $CURRENT_PATH + +# Run Node-RED +exec /usr/bin/env node $OPTIONS $SCRIPT_PATH/../red.js $ARGS diff --git a/packages/connector/packages/node_modules/node-red/lib/red.js b/packages/connector/packages/node_modules/node-red/lib/red.js new file mode 100644 index 0000000..9a4d778 --- /dev/null +++ b/packages/connector/packages/node_modules/node-red/lib/red.js @@ -0,0 +1,200 @@ +/*! + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var fs = require("fs"); +var path = require('path'); + +var runtime = require("@node-red/runtime"); +var redUtil = require("@node-red/util"); + +var api = require("@node-red/editor-api"); + +var server = null; +var apiEnabled = false; + +function checkVersion(userSettings) { + var semver = require('semver'); + if (!semver.satisfies(process.version,">=8.9.0")) { + // TODO: in the future, make this a hard error. + // var e = new Error("Unsupported version of Node.js"); + // e.code = "unsupported_version"; + // throw e; + userSettings.UNSUPPORTED_VERSION = process.version; + } +} +/** + * This module provides the full Node-RED application, with both the runtime + * and editor components built in. + * + * The API this module exposes allows it to be embedded within another Node.js + * application. + * + * @namespace node-red + */ +module.exports = { + /** + * Initialise the Node-RED application. + * @param {server} httpServer - the HTTP server object to use + * @param {Object} userSettings - an object containing the runtime settings + * @memberof node-red + */ + init: function(httpServer, userSettings) { + if (!userSettings) { + userSettings = httpServer; + httpServer = null; + } + + if (!userSettings.SKIP_BUILD_CHECK) { + checkVersion(userSettings); + } + + if (!userSettings.coreNodesDir) { + userSettings.coreNodesDir = path.dirname(require.resolve("@node-red/nodes")) + } + redUtil.init(userSettings); + if (userSettings.httpAdminRoot !== false) { + // Initialise the runtime + runtime.init(userSettings,httpServer,api); + // Initialise the editor-api + api.init(userSettings,httpServer,runtime.storage,runtime); + // Attach the runtime admin app to the api admin app + api.httpAdmin.use(runtime.httpAdmin); + + apiEnabled = true; + server = httpServer; + } else { + runtime.init(userSettings, httpServer); + apiEnabled = false; + if (httpServer) { + server = httpServer; + } else { + server = null; + } + } + return; + }, + /** + * Start the Node-RED application. + * @return {Promise} - resolves when complete + * @memberof node-red + */ + start: function() { + return runtime.start().then(function() { + if (apiEnabled) { + return api.start(); + } + }); + }, + /** + * Stop the Node-RED application. + * @return {Promise} - resolves when complete + * @memberof node-red + */ + stop: function() { + return runtime.stop().then(function() { + if (apiEnabled) { + return api.stop(); + } + }) + }, + + /** + * Logging utilities + * @see @node-red/util_log + * @memberof node-red + */ + log: redUtil.log, + + /** + * General utilities + * @see @node-red/util_util + * @memberof node-red + */ + util: redUtil.util, + + + /** + * This provides access to the internal nodes module of the + * runtime. The details of this API remain undocumented as they should not + * be used directly. + * + * Most administrative actions should be performed use the runtime api + * under [node-red.runtime]{@link node-red.runtime}. + * + * @memberof node-red + */ + get nodes() { return runtime._.nodes }, + + /** + * Runtime events emitter + * @see @node-red/runtime_events + * @memberof node-red + */ + events: runtime.events, + + /** + * This provides access to the internal settings module of the + * runtime. + * + * @memberof node-red + */ + get settings() { return runtime._.settings }, + + + /** + * Get the version of the runtime + * @return {String} - the runtime version + * @function + * @memberof node-red + */ + get version() { return runtime._.version }, + + + /** + * The express application for the Editor Admin API + * @type ExpressApplication + * @memberof node-red + */ + get httpAdmin() { return api.httpAdmin }, + + /** + * The express application for HTTP Nodes + * @type ExpressApplication + * @memberof node-red + */ + get httpNode() { return runtime.httpNode }, + + /** + * The HTTP Server used by the runtime + * @type HTTPServer + * @memberof node-red + */ + get server() { return server }, + + /** + * The runtime api + * @see @node-red/runtime + * @memberof node-red + */ + runtime: runtime, + + /** + * The editor authentication api. + * @see @node-red/editor-api_auth + * @memberof node-red + */ + auth: api.auth +}; diff --git a/packages/connector/packages/node_modules/node-red/package.json b/packages/connector/packages/node_modules/node-red/package.json new file mode 100644 index 0000000..2b7116f --- /dev/null +++ b/packages/connector/packages/node_modules/node-red/package.json @@ -0,0 +1,53 @@ +{ + "name": "node-red", + "version": "1.0.4", + "description": "Low-code programming for event-driven applications", + "homepage": "http://nodered.org", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/node-red/node-red.git" + }, + "main": "lib/red.js", + "scripts": { + "start": "node red.js" + }, + "bin": { + "node-red": "./red.js", + "node-red-pi": "bin/node-red-pi" + }, + "contributors": [ + { + "name": "Nick O'Leary" + }, + { + "name": "Dave Conway-Jones" + } + ], + "keywords": [ + "editor", + "messaging", + "iot", + "flow" + ], + "dependencies": { + "@node-red/editor-api": "1.0.4", + "@node-red/runtime": "1.0.4", + "@node-red/util": "1.0.4", + "@node-red/nodes": "1.0.4", + "basic-auth": "2.0.1", + "bcryptjs": "2.4.3", + "express": "4.17.1", + "fs-extra": "8.1.0", + "node-red-node-rbe": "^0.2.6", + "node-red-node-tail": "^0.1.0", + "nopt": "4.0.1", + "semver": "6.3.0" + }, + "optionalDependencies": { + "bcrypt": "3.0.6" + }, + "engines": { + "node": ">=8" + } +} diff --git a/packages/connector/packages/node_modules/node-red/red.js b/packages/connector/packages/node_modules/node-red/red.js new file mode 100644 index 0000000..26b6d1f --- /dev/null +++ b/packages/connector/packages/node_modules/node-red/red.js @@ -0,0 +1,349 @@ +#!/usr/bin/env node +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +var http = require('http'); +var https = require('https'); +var util = require("util"); +var express = require("express"); +var crypto = require("crypto"); +try { bcrypt = require('bcrypt'); } +catch(e) { bcrypt = require('bcryptjs'); } +var nopt = require("nopt"); +var path = require("path"); +var fs = require("fs-extra"); +var RED = require("./lib/red.js"); + +var server; +var app = express(); + +var settingsFile; +var flowFile; + +var knownOpts = { + "help": Boolean, + "port": Number, + "settings": [path], + "title": String, + "userDir": [path], + "verbose": Boolean, + "safe": Boolean +}; +var shortHands = { + "?":["--help"], + "p":["--port"], + "s":["--settings"], + // As we want to reserve -t for now, adding a shorthand to help so it + // doesn't get treated as --title + "t":["--help"], + "u":["--userDir"], + "v":["--verbose"] +}; +nopt.invalidHandler = function(k,v,t) { + // TODO: console.log(k,v,t); +} + +var parsedArgs = nopt(knownOpts,shortHands,process.argv,2) + +if (parsedArgs.help) { + console.log("Node-RED v"+RED.version()); + console.log("Usage: node-red [-v] [-?] [--settings settings.js] [--userDir DIR]"); + console.log(" [--port PORT] [--title TITLE] [--safe] [flows.json]"); + console.log(""); + console.log("Options:"); + console.log(" -p, --port PORT port to listen on"); + console.log(" -s, --settings FILE use specified settings file"); + console.log(" --title TITLE process window title"); + console.log(" -u, --userDir DIR use specified user directory"); + console.log(" -v, --verbose enable verbose output"); + console.log(" --safe enable safe mode"); + console.log(" -?, --help show this help"); + console.log(""); + console.log("Documentation can be found at http://nodered.org"); + process.exit(); +} + +if (parsedArgs.argv.remain.length > 0) { + flowFile = parsedArgs.argv.remain[0]; +} + +process.env.NODE_RED_HOME = process.env.NODE_RED_HOME || __dirname; + +if (parsedArgs.settings) { + // User-specified settings file + settingsFile = parsedArgs.settings; +} else if (parsedArgs.userDir && fs.existsSync(path.join(parsedArgs.userDir,"settings.js"))) { + // User-specified userDir that contains a settings.js + settingsFile = path.join(parsedArgs.userDir,"settings.js"); +} else { + if (fs.existsSync(path.join(process.env.NODE_RED_HOME,".config.json"))) { + // NODE_RED_HOME contains user data - use its settings.js + settingsFile = path.join(process.env.NODE_RED_HOME,"settings.js"); + } else if (process.env.HOMEPATH && fs.existsSync(path.join(process.env.HOMEPATH,".node-red",".config.json"))) { + // Consider compatibility for older versions + settingsFile = path.join(process.env.HOMEPATH,".node-red","settings.js"); + } else { + var userDir = parsedArgs.userDir || path.join(process.env.HOME || process.env.USERPROFILE || process.env.HOMEPATH,".node-red"); + var userSettingsFile = path.join(userDir,"settings.js"); + if (fs.existsSync(userSettingsFile)) { + // $HOME/.node-red/settings.js exists + settingsFile = userSettingsFile; + } else { + var defaultSettings = path.join(__dirname,"settings.js"); + var settingsStat = fs.statSync(defaultSettings); + if (settingsStat.mtime.getTime() <= settingsStat.ctime.getTime()) { + // Default settings file has not been modified - safe to copy + fs.copySync(defaultSettings,userSettingsFile); + settingsFile = userSettingsFile; + } else { + // Use default settings.js as it has been modified + settingsFile = defaultSettings; + } + } + } +} + +try { + var settings = require(settingsFile); + settings.settingsFile = settingsFile; +} catch(err) { + console.log("Error loading settings file: "+settingsFile) + if (err.code == 'MODULE_NOT_FOUND') { + if (err.toString().indexOf(settingsFile) === -1) { + console.log(err.toString()); + } + } else { + console.log(err); + } + process.exit(); +} + +if (parsedArgs.verbose) { + settings.verbose = true; +} +if (parsedArgs.safe || (process.env.NODE_RED_ENABLE_SAFE_MODE && !/^false$/i.test(process.env.NODE_RED_ENABLE_SAFE_MODE) )) { + settings.safeMode = true; +} +if (process.env.NODE_RED_ENABLE_PROJECTS) { + settings.editorTheme = settings.editorTheme || {}; + settings.editorTheme.projects = settings.editorTheme.projects || {}; + settings.editorTheme.projects.enabled = !/^false$/i.test(process.env.NODE_RED_ENABLE_PROJECTS); +} + +if (settings.https) { + server = https.createServer(settings.https,function(req,res) {app(req,res);}); +} else { + server = http.createServer(function(req,res) {app(req,res);}); +} +server.setMaxListeners(0); + +function formatRoot(root) { + if (root[0] != "/") { + root = "/" + root; + } + if (root.slice(-1) != "/") { + root = root + "/"; + } + return root; +} + +if (settings.httpRoot === false) { + settings.httpAdminRoot = false; + settings.httpNodeRoot = false; +} else { + settings.httpRoot = settings.httpRoot||"/"; + settings.disableEditor = settings.disableEditor||false; +} + +if (settings.httpAdminRoot !== false) { + settings.httpAdminRoot = formatRoot(settings.httpAdminRoot || settings.httpRoot || "/"); + settings.httpAdminAuth = settings.httpAdminAuth || settings.httpAuth; +} else { + settings.disableEditor = true; +} + +if (settings.httpNodeRoot !== false) { + settings.httpNodeRoot = formatRoot(settings.httpNodeRoot || settings.httpRoot || "/"); + settings.httpNodeAuth = settings.httpNodeAuth || settings.httpAuth; +} + +// if we got a port from command line, use it (even if 0) +// replicate (settings.uiPort = parsedArgs.port||settings.uiPort||1880;) but allow zero +if (parsedArgs.port !== undefined){ + settings.uiPort = parsedArgs.port; +} else { + if (settings.uiPort === undefined){ + settings.uiPort = 1880; + } +} + +settings.uiHost = settings.uiHost||"0.0.0.0"; + +if (flowFile) { + settings.flowFile = flowFile; +} +if (parsedArgs.userDir) { + settings.userDir = parsedArgs.userDir; +} + +try { + RED.init(server,settings); +} catch(err) { + if (err.code == "unsupported_version") { + console.log("Unsupported version of Node.js:",process.version); + console.log("Node-RED requires Node.js v8.9.0 or later"); + } else { + console.log("Failed to start server:"); + if (err.stack) { + console.log(err.stack); + } else { + console.log(err); + } + } + process.exit(1); +} + +function basicAuthMiddleware(user,pass) { + var basicAuth = require('basic-auth'); + var checkPassword; + var localCachedPassword; + if (pass.length == "32") { + // Assume its a legacy md5 password + checkPassword = function(p) { + return crypto.createHash('md5').update(p,'utf8').digest('hex') === pass; + } + } else { + checkPassword = function(p) { + return bcrypt.compareSync(p,pass); + } + } + + var checkPasswordAndCache = function(p) { + // For BasicAuth routes we know the password cannot change without + // a restart of Node-RED. This means we can cache the provided crypted + // version to save recalculating each time. + if (localCachedPassword === p) { + return true; + } + var result = checkPassword(p); + if (result) { + localCachedPassword = p; + } + return result; + } + + return function(req,res,next) { + if (req.method === 'OPTIONS') { + return next(); + } + var requestUser = basicAuth(req); + if (!requestUser || requestUser.name !== user || !checkPasswordAndCache(requestUser.pass)) { + res.set('WWW-Authenticate', 'Basic realm="Authorization Required"'); + return res.sendStatus(401); + } + next(); + } +} + +if (settings.httpAdminRoot !== false && settings.httpAdminAuth) { + RED.log.warn(RED.log._("server.httpadminauth-deprecated")); + app.use(settings.httpAdminRoot, basicAuthMiddleware(settings.httpAdminAuth.user,settings.httpAdminAuth.pass)); +} + +if (settings.httpAdminRoot !== false) { + app.use(settings.httpAdminRoot,RED.httpAdmin); +} +if (settings.httpNodeRoot !== false && settings.httpNodeAuth) { + app.use(settings.httpNodeRoot,basicAuthMiddleware(settings.httpNodeAuth.user,settings.httpNodeAuth.pass)); +} +if (settings.httpNodeRoot !== false) { + app.use(settings.httpNodeRoot,RED.httpNode); +} +if (settings.httpStatic) { + settings.httpStaticAuth = settings.httpStaticAuth || settings.httpAuth; + if (settings.httpStaticAuth) { + app.use("/",basicAuthMiddleware(settings.httpStaticAuth.user,settings.httpStaticAuth.pass)); + } + app.use("/",express.static(settings.httpStatic)); +} + +function getListenPath() { + var port = settings.serverPort; + if (port === undefined){ + port = settings.uiPort; + } + + var listenPath = 'http'+(settings.https?'s':'')+'://'+ + (settings.uiHost == '::'?'localhost':(settings.uiHost == '0.0.0.0'?'127.0.0.1':settings.uiHost))+ + ':'+port; + if (settings.httpAdminRoot !== false) { + listenPath += settings.httpAdminRoot; + } else if (settings.httpStatic) { + listenPath += "/"; + } + return listenPath; +} + +RED.start().then(function() { + if (settings.httpAdminRoot !== false || settings.httpNodeRoot !== false || settings.httpStatic) { + server.on('error', function(err) { + if (err.errno === "EADDRINUSE") { + RED.log.error(RED.log._("server.unable-to-listen", {listenpath:getListenPath()})); + RED.log.error(RED.log._("server.port-in-use")); + } else { + RED.log.error(RED.log._("server.uncaught-exception")); + if (err.stack) { + RED.log.error(err.stack); + } else { + RED.log.error(err); + } + } + process.exit(1); + }); + server.listen(settings.uiPort,settings.uiHost,function() { + if (settings.httpAdminRoot === false) { + RED.log.info(RED.log._("server.admin-ui-disabled")); + } + settings.serverPort = server.address().port; + process.title = parsedArgs.title || 'node-red'; + RED.log.info(RED.log._("server.now-running", {listenpath:getListenPath()})); + }); + } else { + RED.log.info(RED.log._("server.headless-mode")); + } +}).otherwise(function(err) { + RED.log.error(RED.log._("server.failed-to-start")); + if (err.stack) { + RED.log.error(err.stack); + } else { + RED.log.error(err); + } +}); + +process.on('uncaughtException',function(err) { + util.log('[red] Uncaught Exception:'); + if (err.stack) { + util.log(err.stack); + } else { + util.log(err); + } + process.exit(1); +}); + +process.on('SIGINT', function () { + RED.stop().then(function() { + process.exit(); + }); +}); diff --git a/packages/connector/packages/node_modules/node-red/settings.js b/packages/connector/packages/node_modules/node-red/settings.js new file mode 100644 index 0000000..c5e4355 --- /dev/null +++ b/packages/connector/packages/node_modules/node-red/settings.js @@ -0,0 +1,275 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +// The `https` setting requires the `fs` module. Uncomment the following +// to make it available: +//var fs = require("fs"); + +module.exports = { + // the tcp port that the Node-RED web server is listening on + uiPort: process.env.PORT || 1880, + + // By default, the Node-RED UI accepts connections on all IPv4 interfaces. + // To listen on all IPv6 addresses, set uiHost to "::", + // The following property can be used to listen on a specific interface. For + // example, the following would only allow connections from the local machine. + //uiHost: "127.0.0.1", + + // Retry time in milliseconds for MQTT connections + mqttReconnectTime: 15000, + + // Retry time in milliseconds for Serial port connections + serialReconnectTime: 15000, + + // Retry time in milliseconds for TCP socket connections + //socketReconnectTime: 10000, + + // Timeout in milliseconds for TCP server socket connections + // defaults to no timeout + //socketTimeout: 120000, + + // Maximum number of messages to wait in queue while attempting to connect to TCP socket + // defaults to 1000 + //tcpMsgQueueSize: 2000, + + // Timeout in milliseconds for HTTP request connections + // defaults to 120 seconds + //httpRequestTimeout: 120000, + + // The maximum length, in characters, of any message sent to the debug sidebar tab + debugMaxLength: 1000, + + // The maximum number of messages nodes will buffer internally as part of their + // operation. This applies across a range of nodes that operate on message sequences. + // defaults to no limit. A value of 0 also means no limit is applied. + //nodeMessageBufferMaxLength: 0, + + // To disable the option for using local files for storing keys and certificates in the TLS configuration + // node, set this to true + //tlsConfigDisableLocalFiles: true, + + // Colourise the console output of the debug node + //debugUseColors: true, + + // The file containing the flows. If not set, it defaults to flows_<hostname>.json + //flowFile: 'flows.json', + + // To enabled pretty-printing of the flow within the flow file, set the following + // property to true: + //flowFilePretty: true, + + // By default, credentials are encrypted in storage using a generated key. To + // specify your own secret, set the following property. + // If you want to disable encryption of credentials, set this property to false. + // Note: once you set this property, do not change it - doing so will prevent + // node-red from being able to decrypt your existing credentials and they will be + // lost. + //credentialSecret: "a-secret-key", + + // By default, all user data is stored in a directory called `.node-red` under + // the user's home directory. To use a different location, the following + // property can be used + //userDir: '/home/nol/.node-red/', + + // Node-RED scans the `nodes` directory in the userDir to find local node files. + // The following property can be used to specify an additional directory to scan. + //nodesDir: '/home/nol/.node-red/nodes', + + // By default, the Node-RED UI is available at http://localhost:1880/ + // The following property can be used to specify a different root path. + // If set to false, this is disabled. + //httpAdminRoot: '/admin', + + // Some nodes, such as HTTP In, can be used to listen for incoming http requests. + // By default, these are served relative to '/'. The following property + // can be used to specifiy a different root path. If set to false, this is + // disabled. + //httpNodeRoot: '/red-nodes', + + // The following property can be used in place of 'httpAdminRoot' and 'httpNodeRoot', + // to apply the same root to both parts. + //httpRoot: '/red', + + // When httpAdminRoot is used to move the UI to a different root path, the + // following property can be used to identify a directory of static content + // that should be served at http://localhost:1880/. + //httpStatic: '/home/nol/node-red-static/', + + // The maximum size of HTTP request that will be accepted by the runtime api. + // Default: 5mb + //apiMaxLength: '5mb', + + // If you installed the optional node-red-dashboard you can set it's path + // relative to httpRoot + //ui: { path: "ui" }, + + // Securing Node-RED + // ----------------- + // To password protect the Node-RED editor and admin API, the following + // property can be used. See http://nodered.org/docs/security.html for details. + //adminAuth: { + // type: "credentials", + // users: [{ + // username: "admin", + // password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.", + // permissions: "*" + // }] + //}, + + // To password protect the node-defined HTTP endpoints (httpNodeRoot), or + // the static content (httpStatic), the following properties can be used. + // The pass field is a bcrypt hash of the password. + // See http://nodered.org/docs/security.html#generating-the-password-hash + //httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."}, + //httpStaticAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."}, + + // The following property can be used to enable HTTPS + // See http://nodejs.org/api/https.html#https_https_createserver_options_requestlistener + // for details on its contents. + // See the comment at the top of this file on how to load the `fs` module used by + // this setting. + // + //https: { + // key: fs.readFileSync('privatekey.pem'), + // cert: fs.readFileSync('certificate.pem') + //}, + + // The following property can be used to cause insecure HTTP connections to + // be redirected to HTTPS. + //requireHttps: true, + + // The following property can be used to disable the editor. The admin API + // is not affected by this option. To disable both the editor and the admin + // API, use either the httpRoot or httpAdminRoot properties + //disableEditor: false, + + // The following property can be used to configure cross-origin resource sharing + // in the HTTP nodes. + // See https://github.com/troygoode/node-cors#configuration-options for + // details on its contents. The following is a basic permissive set of options: + //httpNodeCors: { + // origin: "*", + // methods: "GET,PUT,POST,DELETE" + //}, + + // If you need to set an http proxy please set an environment variable + // called http_proxy (or HTTP_PROXY) outside of Node-RED in the operating system. + // For example - http_proxy=http://myproxy.com:8080 + // (Setting it here will have no effect) + // You may also specify no_proxy (or NO_PROXY) to supply a comma separated + // list of domains to not proxy, eg - no_proxy=.acme.co,.acme.co.uk + + // The following property can be used to add a custom middleware function + // in front of all http in nodes. This allows custom authentication to be + // applied to all http in nodes, or any other sort of common request processing. + //httpNodeMiddleware: function(req,res,next) { + // // Handle/reject the request, or pass it on to the http in node by calling next(); + // // Optionally skip our rawBodyParser by setting this to true; + // //req.skipRawBodyParser = true; + // next(); + //}, + + // The following property can be used to pass custom options to the Express.js + // server used by Node-RED. For a full list of available options, refer + // to http://expressjs.com/en/api.html#app.settings.table + //httpServerOptions: { }, + + // The following property can be used to verify websocket connection attempts. + // This allows, for example, the HTTP request headers to be checked to ensure + // they include valid authentication information. + //webSocketNodeVerifyClient: function(info) { + // // 'info' has three properties: + // // - origin : the value in the Origin header + // // - req : the HTTP request + // // - secure : true if req.connection.authorized or req.connection.encrypted is set + // // + // // The function should return true if the connection should be accepted, false otherwise. + // // + // // Alternatively, if this function is defined to accept a second argument, callback, + // // it can be used to verify the client asynchronously. + // // The callback takes three arguments: + // // - result : boolean, whether to accept the connection or not + // // - code : if result is false, the HTTP error status to return + // // - reason: if result is false, the HTTP reason string to return + //}, + + // The following property can be used to seed Global Context with predefined + // values. This allows extra node modules to be made available with the + // Function node. + // For example, + // functionGlobalContext: { os:require('os') } + // can be accessed in a function block as: + // global.get("os") + functionGlobalContext: { + // os:require('os'), + // jfive:require("johnny-five"), + // j5board:require("johnny-five").Board({repl:false}) + }, + // `global.keys()` returns a list of all properties set in global context. + // This allows them to be displayed in the Context Sidebar within the editor. + // In some circumstances it is not desirable to expose them to the editor. The + // following property can be used to hide any property set in `functionGlobalContext` + // from being list by `global.keys()`. + // By default, the property is set to false to avoid accidental exposure of + // their values. Setting this to true will cause the keys to be listed. + exportGlobalContextKeys: false, + + + // Context Storage + // The following property can be used to enable context storage. The configuration + // provided here will enable file-based context that flushes to disk every 30 seconds. + // Refer to the documentation for further options: https://nodered.org/docs/api/context/ + // + //contextStorage: { + // default: { + // module:"localfilesystem" + // }, + //}, + + // The following property can be used to order the categories in the editor + // palette. If a node's category is not in the list, the category will get + // added to the end of the palette. + // If not set, the following default order is used: + //paletteCategories: ['subflows', 'common', 'function', 'network', 'sequence', 'parser', 'storage'], + + // Configure the logging output + logging: { + // Only console logging is currently supported + console: { + // Level of logging to be recorded. Options are: + // fatal - only those errors which make the application unusable should be recorded + // error - record errors which are deemed fatal for a particular request + fatal errors + // warn - record problems which are non fatal + errors + fatal errors + // info - record information about the general running of the application + warn + error + fatal errors + // debug - record information which is more verbose than info + info + warn + error + fatal errors + // trace - record very detailed logging + debug + info + warn + error + fatal errors + // off - turn off all logging (doesn't affect metrics or audit) + level: "info", + // Whether or not to include metric events in the log output + metrics: false, + // Whether or not to include audit events in the log output + audit: false + } + }, + + // Customising the editor + editorTheme: { + projects: { + // To enable the Projects feature, set this value to true + enabled: false + } + } +} diff --git a/packages/connector/scripts/build-custom-theme.js b/packages/connector/scripts/build-custom-theme.js new file mode 100644 index 0000000..2ed07a2 --- /dev/null +++ b/packages/connector/scripts/build-custom-theme.js @@ -0,0 +1,109 @@ +#!/usr/bin/env node + +// This script can be used to build custom colour-scheme css files. +// +// 1. Create a copy of packages/node_modules/@node-red/editor-client/src/sass/colors.scss +// and change the values to the desired colours. +// +// 2. Run this script, providing the path to the custom file using the --in option +// +// 3. Save the output of the script to a file - either redirect its output, +// or use the --out option. +// +// 4. Edit your settings file to set the theme: +// editorTheme: { +// page: { +// css: "/path/to/file/generated/by/this/script" +// } +// } +// +// 5. Restart Node-RED +// + + + +const nopt = require("nopt"); +const path = require("path"); +const fs = require("fs") +const sass = require("node-sass"); + +const knownOpts = { + "help": Boolean, + "in": [path], + "out": [path] +}; +const shortHands = { + "?":["--help"] +}; +nopt.invalidHandler = function(k,v,t) {} + +const parsedArgs = nopt(knownOpts,shortHands,process.argv,2) + +if (parsedArgs.help) { + console.log("Usage: build-custom-theme [-?] [--in FILE] [--out FILE]"); + console.log(""); + console.log("Options:"); + console.log(" --in FILE Custom colors sass file"); + console.log(" --out FILE Where you write the result"); + console.log(" -?, --help show this help"); + console.log(""); + process.exit(); +} + + +const ruleRegex = /(\$.*?) *: *(\S[\S\s]*?);/g; +var match; + +const customColors = {}; + +if (parsedArgs.in && fs.existsSync(parsedArgs.in)) { + let customColorsFile = fs.readFileSync(parsedArgs.in,"utf-8"); + while((match = ruleRegex.exec(customColorsFile)) !== null) { + customColors[match[1]] = match[2]; + } +} + +// Load base colours + +let colorsFile = fs.readFileSync(path.join(__dirname,"../packages/node_modules/@node-red/editor-client/src/sass/colors.scss"),"utf-8") +let updatedColors = []; + +while((match = ruleRegex.exec(colorsFile)) !== null) { + updatedColors.push(match[1]+": "+(customColors[match[1]]||match[2])+";") +} + +const result = sass.renderSync({ + outputStyle: "expanded", + file: path.join(__dirname,"../packages/node_modules/@node-red/editor-client/src/sass/style.scss"), + importer: function(url, prev, done){ + if (url === 'colors') { + return { + contents: updatedColors.join("\n") + } + } + return {file:"../packages/node_modules/@node-red/editor-client/src/sass/"+url+".scss"} + } +}); + +const css = result.css.toString() +const lines = css.split("\n"); +const colorCSS = [] +const nonColorCSS = []; + +lines.forEach(l => { + if (!/^ /.test(l)) { + colorCSS.push(l); + nonColorCSS.push(l); + } else if (/color|border|background|fill|stroke|outline|box-shadow/.test(l)) { + colorCSS.push(l); + } else { + nonColorCSS.push(l); + } +}); + +var output = sass.renderSync({outputStyle: "compressed",data:colorCSS.join("\n")}); +if (parsedArgs.out) { + fs.writeFileSync(parsedArgs.out,output.css); +} else { + console.log(output.css.toString()); +} diff --git a/packages/connector/scripts/generate-publish-script.js b/packages/connector/scripts/generate-publish-script.js new file mode 100644 index 0000000..45a4e84 --- /dev/null +++ b/packages/connector/scripts/generate-publish-script.js @@ -0,0 +1,38 @@ +#!/usr/bin/env node + +const path = require("path"); +const fs = require("fs-extra"); +const should = require("should"); + +function generateScript() { + return new Promise((resolve, reject) => { + const packages = [ + "node-red-util", + "node-red-runtime", + "node-red-registry", + "node-red-nodes", + "node-red-editor-client", + "node-red-editor-api", + "node-red" + ]; + const rootPackage = require(path.join(__dirname,"..","package.json")); + const version = rootPackage.version; + + const tagArg = /-/.test(version) ? "--tag next" : "" + + const lines = []; + + packages.forEach(name => { + lines.push(`npm publish ${name}-${version}.tgz ${tagArg}\n`); + }) + resolve(lines.join("")) + }); +} + +if (require.main === module) { + generateScript().then(output => { + console.log(output); + }); +} else { + module.exports = generateScript; +} diff --git a/packages/connector/scripts/install-ui-test-dependencies.sh b/packages/connector/scripts/install-ui-test-dependencies.sh new file mode 100644 index 0000000..155d2b2 --- /dev/null +++ b/packages/connector/scripts/install-ui-test-dependencies.sh @@ -0,0 +1,9 @@ +npm install --no-save \ + grunt-webdriver@^2.0.3 \ + wdio-chromedriver-service@^0.1.5 \ + wdio-mocha-framework@^0.6.4 \ + wdio-spec-reporter@^0.1.5 \ + webdriverio@^4.14.4 \ + chromedriver@^79.0.0 \ + wdio-browserstack-service@^0.1.19 \ + browserstack-local@^1.4.4 diff --git a/packages/connector/scripts/set-package-version.js b/packages/connector/scripts/set-package-version.js new file mode 100644 index 0000000..d5a3b3e --- /dev/null +++ b/packages/connector/scripts/set-package-version.js @@ -0,0 +1,44 @@ +#!/usr/bin/env node + +const path = require("path"); +const fs = require("fs-extra"); +const should = require("should"); + +const rootPackage = path.join(__dirname,"..","package.json"); +const packages = [ + "node-red", + "@node-red/editor-api", + "@node-red/editor-client", + "@node-red/nodes", + "@node-red/registry", + "@node-red/runtime", + "@node-red/util" +]; +function updatePackage(packageFile, version) { + let modulePackage = require(packageFile); + modulePackage.version = version; + let dependencies = Object.keys(modulePackage.dependencies||{}); + dependencies.forEach(module => { + if (/^@node-red\//.test(module)) { + modulePackage.dependencies[module] = version; + } + }); + return fs.writeJSON(packageFile,modulePackage,{spaces:4}); +} + +const targetVersion = process.argv[2]; + +if (/^\d+\.\d+\.\d+(-.*)?/.test(targetVersion)) { + let promises = []; + promises.push(updatePackage(rootPackage,targetVersion)); + packages.forEach(package => { + promises.push(updatePackage(path.join(__dirname,"../packages/node_modules",package,"package.json"),targetVersion)) + }); + Promise.all(promises).catch(e => { + console.log(e); + process.exit(1); + }) +} else { + console.log("Invalid target version"); + process.exit(1); +} diff --git a/packages/connector/scripts/verify-package-dependencies.js b/packages/connector/scripts/verify-package-dependencies.js new file mode 100644 index 0000000..9989d30 --- /dev/null +++ b/packages/connector/scripts/verify-package-dependencies.js @@ -0,0 +1,76 @@ +#!/usr/bin/env node + +const path = require("path"); +const fs = require("fs-extra"); +const should = require("should"); + +const rootPackage = require(path.join("..","package.json")); +const rootDependencies = rootPackage.dependencies; +const packages = [ + "node-red", + "@node-red/editor-api", + "@node-red/editor-client", + "@node-red/nodes", + "@node-red/registry", + "@node-red/runtime", + "@node-red/util" +]; + +const fixFlag = process.argv[2] === '--fix'; + +function verifyDependencies() { + let failures = []; + let packageUpdates = {}; + packages.forEach(package => { + let modulePackage = require(path.join("../packages/node_modules",package,"package.json")); + let dependencies = Object.keys(modulePackage.dependencies||{}); + dependencies.forEach(module => { + try { + if (!/^@node-red\//.test(module)) { + should.exist(rootDependencies[module],`[${package}] '${module}' missing from root package.json`); + try { + rootDependencies[module].should.eql(modulePackage.dependencies[module],`[${package}] '${module}' version mismatch. Expected '${modulePackage.dependencies[module]}' (got '${rootDependencies[module]}') `); + } catch(err) { + if (fixFlag) { + modulePackage.dependencies[module] = rootDependencies[module]; + packageUpdates[package] = modulePackage; + } else { + failures.push(err.toString()); + } + } + } + } catch(err) { + failures.push(err.toString()); + } + }); + }) + if (failures.length === 0 && fixFlag) { + var promises = []; + packages.forEach(package => { + if (packageUpdates.hasOwnProperty(package)) { + promises.push(fs.writeJSON(path.join(__dirname,"../packages/node_modules",package,"package.json"),packageUpdates[package],{spaces:4})); + } + }); + return Promise.all(promises).then(r => []).catch(e => { + console.log(e); + process.exit(1); + }) + } else { + return Promise.resolve(failures); + } +} + +if (require.main === module) { + verifyDependencies().then(failures => { + if (failures.length > 0) { + failures.forEach(f => console.log(` - ${f}`)); + console.log("Run with --fix option to fix up versions") + process.exit(1); + } + }).catch(e => { + console.log(e); + process.exit(1); + }); +} else { + module.exports = verifyDependencies; +} diff --git a/packages/connector/settings.js b/packages/connector/settings.js new file mode 100644 index 0000000..3808049 --- /dev/null +++ b/packages/connector/settings.js @@ -0,0 +1,313 @@ +const path = require("path"); +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +// The `https` setting requires the `fs` module. Uncomment the following +// to make it available: +//var fs = require("fs"); + +module.exports = { + // the tcp port that the Node-RED web server is listening on + uiPort: process.env.PORT || 5003, + + // By default, the Node-RED UI accepts connections on all IPv4 interfaces. + // To listen on all IPv6 addresses, set uiHost to "::", + // The following property can be used to listen on a specific interface. For + // example, the following would only allow connections from the local machine. + //uiHost: "127.0.0.1", + + // Retry time in milliseconds for MQTT connections + mqttReconnectTime: 15000, + + // Retry time in milliseconds for Serial port connections + serialReconnectTime: 15000, + + // Retry time in milliseconds for TCP socket connections + //socketReconnectTime: 10000, + + // Timeout in milliseconds for TCP server socket connections + // defaults to no timeout + //socketTimeout: 120000, + + // Maximum number of messages to wait in queue while attempting to connect to TCP socket + // defaults to 1000 + //tcpMsgQueueSize: 2000, + + // Timeout in milliseconds for HTTP request connections + // defaults to 120 seconds + //httpRequestTimeout: 120000, + + // The maximum length, in characters, of any message sent to the debug sidebar tab + debugMaxLength: 1000, + + // The maximum number of messages nodes will buffer internally as part of their + // operation. This applies across a range of nodes that operate on message sequences. + // defaults to no limit. A value of 0 also means no limit is applied. + //nodeMessageBufferMaxLength: 0, + + // To disable the option for using local files for storing keys and certificates in the TLS configuration + // node, set this to true + //tlsConfigDisableLocalFiles: true, + + // Colourise the console output of the debug node + //debugUseColors: true, + + // The file containing the flows. If not set, it defaults to flows_<hostname>.json + //flowFile: 'flows.json', + + // To enabled pretty-printing of the flow within the flow file, set the following + // property to true: + //flowFilePretty: true, + + // By default, credentials are encrypted in storage using a generated key. To + // specify your own secret, set the following property. + // If you want to disable encryption of credentials, set this property to false. + // Note: once you set this property, do not change it - doing so will prevent + // node-red from being able to decrypt your existing credentials and they will be + // lost. + credentialSecret: "trycrypto-dappstarter-secret", + + // By default, all user data is stored in a directory called `.node-red` under + // the user's home directory. To use a different location, the following + // property can be used + userDir: __dirname, + + // Node-RED scans the `nodes` directory in the userDir to find local node files. + // The following property can be used to specify an additional directory to scan. + //nodesDir: '/home/nol/.node-red/nodes', + + // By default, the Node-RED UI is available at http://localhost:1880/ + // The following property can be used to specify a different root path. + // If set to false, this is disabled. + //httpAdminRoot: '/admin', + + // Some nodes, such as HTTP In, can be used to listen for incoming http requests. + // By default, these are served relative to '/'. The following property + // can be used to specifiy a different root path. If set to false, this is + // disabled. + //httpNodeRoot: '/red-nodes', + + // The following property can be used in place of 'httpAdminRoot' and 'httpNodeRoot', + // to apply the same root to both parts. + //httpRoot: '/red', + + // When httpAdminRoot is used to move the UI to a different root path, the + // following property can be used to identify a directory of static content + // that should be served at http://localhost:1880/. + //httpStatic: '/home/nol/node-red-static/', + + // The maximum size of HTTP request that will be accepted by the runtime api. + // Default: 5mb + //apiMaxLength: '5mb', + + // If you installed the optional node-red-dashboard you can set it's path + // relative to httpRoot + //ui: { path: "ui" }, + + // Securing Node-RED + // ----------------- + // To password protect the Node-RED editor and admin API, the following + // property can be used. See http://nodered.org/docs/security.html for details. + //adminAuth: { + // type: "credentials", + // users: [{ + // username: "admin", + // password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.", + // permissions: "*" + // }] + //}, + + // To password protect the node-defined HTTP endpoints (httpNodeRoot), or + // the static content (httpStatic), the following properties can be used. + // The pass field is a bcrypt hash of the password. + // See http://nodered.org/docs/security.html#generating-the-password-hash + //httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."}, + //httpStaticAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."}, + + // The following property can be used to enable HTTPS + // See http://nodejs.org/api/https.html#https_https_createserver_options_requestlistener + // for details on its contents. + // See the comment at the top of this file on how to load the `fs` module used by + // this setting. + // + //https: { + // key: fs.readFileSync('privatekey.pem'), + // cert: fs.readFileSync('certificate.pem') + //}, + + // The following property can be used to cause insecure HTTP connections to + // be redirected to HTTPS. + //requireHttps: true, + + // The following property can be used to disable the editor. The admin API + // is not affected by this option. To disable both the editor and the admin + // API, use either the httpRoot or httpAdminRoot properties + //disableEditor: false, + + // The following property can be used to configure cross-origin resource sharing + // in the HTTP nodes. + // See https://github.com/troygoode/node-cors#configuration-options for + // details on its contents. The following is a basic permissive set of options: + //httpNodeCors: { + // origin: "*", + // methods: "GET,PUT,POST,DELETE" + //}, + + // If you need to set an http proxy please set an environment variable + // called http_proxy (or HTTP_PROXY) outside of Node-RED in the operating system. + // For example - http_proxy=http://myproxy.com:8080 + // (Setting it here will have no effect) + // You may also specify no_proxy (or NO_PROXY) to supply a comma separated + // list of domains to not proxy, eg - no_proxy=.acme.co,.acme.co.uk + + // The following property can be used to add a custom middleware function + // in front of all http in nodes. This allows custom authentication to be + // applied to all http in nodes, or any other sort of common request processing. + //httpNodeMiddleware: function(req,res,next) { + // // Handle/reject the request, or pass it on to the http in node by calling next(); + // // Optionally skip our rawBodyParser by setting this to true; + // //req.skipRawBodyParser = true; + // next(); + //}, + + // The following property can be used to pass custom options to the Express.js + // server used by Node-RED. For a full list of available options, refer + // to http://expressjs.com/en/api.html#app.settings.table + //httpServerOptions: { }, + + // The following property can be used to verify websocket connection attempts. + // This allows, for example, the HTTP request headers to be checked to ensure + // they include valid authentication information. + //webSocketNodeVerifyClient: function(info) { + // // 'info' has three properties: + // // - origin : the value in the Origin header + // // - req : the HTTP request + // // - secure : true if req.connection.authorized or req.connection.encrypted is set + // // + // // The function should return true if the connection should be accepted, false otherwise. + // // + // // Alternatively, if this function is defined to accept a second argument, callback, + // // it can be used to verify the client asynchronously. + // // The callback takes three arguments: + // // - result : boolean, whether to accept the connection or not + // // - code : if result is false, the HTTP error status to return + // // - reason: if result is false, the HTTP reason string to return + //}, + + // The following property can be used to seed Global Context with predefined + // values. This allows extra node modules to be made available with the + // Function node. + // For example, + // functionGlobalContext: { os:require('os') } + // can be accessed in a function block as: + // global.get("os") + functionGlobalContext: { + // os:require('os'), + // jfive:require("johnny-five"), + // j5board:require("johnny-five").Board({repl:false}) + }, + // `global.keys()` returns a list of all properties set in global context. + // This allows them to be displayed in the Context Sidebar within the editor. + // In some circumstances it is not desirable to expose them to the editor. The + // following property can be used to hide any property set in `functionGlobalContext` + // from being list by `global.keys()`. + // By default, the property is set to false to avoid accidental exposure of + // their values. Setting this to true will cause the keys to be listed. + exportGlobalContextKeys: false, + + // Context Storage + // The following property can be used to enable context storage. The configuration + // provided here will enable file-based context that flushes to disk every 30 seconds. + // Refer to the documentation for further options: https://nodered.org/docs/api/context/ + // + //contextStorage: { + // default: { + // module:"localfilesystem" + // }, + //}, + + // The following property can be used to order the categories in the editor + // palette. If a node's category is not in the list, the category will get + // added to the end of the palette. + // If not set, the following default order is used: + //paletteCategories: ['subflows','flow','input','output','function','parser','social','mobile','storage','analysis','advanced'], + + // Configure the logging output + logging: { + // Only console logging is currently supported + console: { + // Level of logging to be recorded. Options are: + // fatal - only those errors which make the application unusable should be recorded + // error - record errors which are deemed fatal for a particular request + fatal errors + // warn - record problems which are non fatal + errors + fatal errors + // info - record information about the general running of the application + warn + error + fatal errors + // debug - record information which is more verbose than info + info + warn + error + fatal errors + // trace - record very detailed logging + debug + info + warn + error + fatal errors + // off - turn off all logging (doesn't affect metrics or audit) + level: "info", + // Whether or not to include metric events in the log output + metrics: false, + // Whether or not to include audit events in the log output + audit: false + }, + trycrypto: { + level: "debug", + metrics: false, + audit: false + // handler: function(conf) { + // const bunyan = require("bunyan"); + // const seq = require("bunyan-seq"); + // const log = bunyan.createLogger({ + // name: "trycrypto", + // streams: [ + // { stream: process.stdout, level: "warn" }, + // seq.createStream({ + // serverUrl: "http://localhost:5341", + // level: "info" + // }) + // ] + // }); + + // return function(msg, a, b) { + // var message = { + // "@msg": msg, + // "@timestamp": new Date(msg.timestamp).toISOString() + // }; + // try { + // log.info(message, msg.event || msg.msg); + // } catch (err) { + // console.log(err); + // } + // }; + // } + } + }, + + // Customising the editor + editorTheme: { + page: { + css: path.resolve(__dirname + "/custom.css") + }, + header: { + title: " ", + image: null + }, + projects: { + // To enable the Projects feature, set this value to true + enabled: false + } + } +}; diff --git a/packages/connector/test/editor/editor_helper.js b/packages/connector/test/editor/editor_helper.js new file mode 100644 index 0000000..73177c2 --- /dev/null +++ b/packages/connector/test/editor/editor_helper.js @@ -0,0 +1,150 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require("when"); +var http = require('http'); +var express = require("express"); +var fs = require('fs-extra'); +var path = require('path'); +var app = express(); + +var RED = require("nr-test-utils").require("node-red/lib/red.js"); + +var utilPage = require("./pageobjects/util/util_page"); + +var server; +var homeDir = './test/resources/home'; +var address = '127.0.0.1'; +var listenPort = 0; // use ephemeral port +var url; +/* + * Set false when you need a flow to reproduce the failed test case. + * The flow file is under "homeDir" defined above. + */ +var isDeleteFlow = true; + +function getFlowFilename() { + var orig = Error.prepareStackTrace; + var err = new Error(); + Error.prepareStackTrace = function (err, stack) { + return stack; + }; + // Two level higher caller is the actual caller (e.g. a caller of startServer). + var filepath = err.stack[2].getFileName(); + var filename = path.basename(filepath, ".js"); + Error.prepareStackTrace = orig; + + var flowFile = 'flows_' + filename + '.json'; + return flowFile; +} + +function cleanup(flowFile) { + var credentialFile = flowFile.replace(/\.json$/, '') + '_cred.json'; + deleteFile(homeDir + "/" + flowFile); + deleteFile(homeDir + "/." + flowFile + ".backup"); + deleteFile(homeDir + "/" + credentialFile); + deleteFile(homeDir + "/." + credentialFile + ".backup"); + deleteFile(homeDir + "/package.json"); + deleteFile(homeDir + "/lib/flows"); + deleteFile(homeDir + "/lib"); +} + +function deleteFile(flowFile) { + try { + fs.statSync(flowFile); + if (isDeleteFlow) { + fs.unlinkSync(flowFile); + } + } catch (e) {} +} + +module.exports = { + startServer: function() { + try{ + utilPage.init(); + + // Name a flow file including caller filename so that multiple Node-RED servers can run simultaneously. + // Call this method here because retrieving the caller filename by call stack. + var flowFilename = getFlowFilename(); + browser.windowHandleMaximize(); + browser.call(function () { + return new Promise(function(resolve, reject) { + cleanup(flowFilename); + server = http.createServer(app); + var settings = { + httpAdminRoot: "/", + httpNodeRoot: "/api", + userDir: homeDir, + flowFile: flowFilename, + functionGlobalContext: { }, // enables global context + SKIP_BUILD_CHECK: true, + logging: {console: {level:'off'}} + }; + RED.init(server, settings); + app.use(settings.httpAdminRoot,RED.httpAdmin); + app.use(settings.httpNodeRoot,RED.httpNode); + server.listen(listenPort, address); + server.on('listening', function() { + var port = server.address().port; + url = 'http://' + address + ':' + port; + }); + RED.start().then(function() { + resolve(); + }); + }); + }); + browser.url(url); + browser.waitForExist(".red-ui-palette-node[data-palette-type='inject']"); + } catch (err) { + console.log(err); + throw err; + } + }, + + stopServer: function(done) { + try { + // Call this method here because retrieving the caller filename by call stack. + var flowFilename = getFlowFilename(); + browser.call(function () { + browser.close(); // need to call this inside browser.call(). + return when.promise(function(resolve, reject) { + if (server) { + RED.stop().then(function() { + server.close(function() { + cleanup(flowFilename); + resolve(); + }); + }); + } else { + cleanup(flowFilename); + resolve(); + } + }); + }); + } catch (err) { + console.log(err); + throw err; + } + }, + + url: function() { + return url; + }, + + red: function() { + return RED; + }, +}; diff --git a/packages/connector/test/editor/pageobjects/editor/debugTab_page.js b/packages/connector/test/editor/pageobjects/editor/debugTab_page.js new file mode 100644 index 0000000..5476a28 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/editor/debugTab_page.js @@ -0,0 +1,40 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +function open(retainMessage) { + browser.clickWithWait('#red-ui-tab-debug-link-button'); + + if (!retainMessage) { + // Clear old messages + browser.clickWithWait('//a[@id="red-ui-sidebar-debug-clear"]'); + } +} + +function getMessage(index) { + index = index ? index : 1; + var debugMessagePath = '//div[@class="red-ui-debug-content red-ui-debug-content-list"]/div[contains(@class,"red-ui-debug-msg")][' + index + ']//span[contains(@class, "red-ui-debug-msg-type")]'; + return browser.getTextWithWait(debugMessagePath); +} + +function clearMessage() { + browser.clickWithWait('//a[@id="red-ui-sidebar-debug-clear"]'); +} + +module.exports = { + open: open, + getMessage: getMessage, + clearMessage: clearMessage, +}; diff --git a/packages/connector/test/editor/pageobjects/editor/palette_page.js b/packages/connector/test/editor/pageobjects/editor/palette_page.js new file mode 100644 index 0000000..3b484a5 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/editor/palette_page.js @@ -0,0 +1,62 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var idMap = { + // common + "inject": ".red-ui-palette-node[data-palette-type='inject']", + "debug": ".red-ui-palette-node[data-palette-type='debug']", + "complete": ".red-ui-palette-node[data-palette-type='complete']", + "catch": ".red-ui-palette-node[data-palette-type='catch']", + "status": ".red-ui-palette-node[data-palette-type='status']", + "comment": ".red-ui-palette-node[data-palette-type='comment']", + // function + "function": ".red-ui-palette-node[data-palette-type='function']", + "switch": ".red-ui-palette-node[data-palette-type='switch']", + "change": ".red-ui-palette-node[data-palette-type='change']", + "range": ".red-ui-palette-node[data-palette-type='range']", + "template": ".red-ui-palette-node[data-palette-type='template']", + "delay": ".red-ui-palette-node[data-palette-type='delay']", + "trigger": ".red-ui-palette-node[data-palette-type='trigger']", + "exec": ".red-ui-palette-node[data-palette-type='exec']", + // network + "mqttIn": ".red-ui-palette-node[data-palette-type='mqtt in']", + "mqttOut": ".red-ui-palette-node[data-palette-type='mqtt out']", + "httpIn": ".red-ui-palette-node[data-palette-type='http in']", + "httpResponse": ".red-ui-palette-node[data-palette-type='http response']", + "httpRequest": ".red-ui-palette-node[data-palette-type='http request']", + "websocketIn": ".red-ui-palette-node[data-palette-type='websocket in']", + "websocketOut": ".red-ui-palette-node[data-palette-type='websocket out']", + // sequence + "split": ".red-ui-palette-node[data-palette-type='split']", + "join": ".red-ui-palette-node[data-palette-type='join']", + "batch": ".red-ui-palette-node[data-palette-type='batch']", + // parser + "csv": ".red-ui-palette-node[data-palette-type='csv']", + "html": ".red-ui-palette-node[data-palette-type='html']", + "json": ".red-ui-palette-node[data-palette-type='json']", + "xml": ".red-ui-palette-node[data-palette-type='xml']", + "yaml": ".red-ui-palette-node[data-palette-type='yaml']", + // storage + "fileIn": ".red-ui-palette-node[data-palette-type='file in']", +}; + +function getId(type) { + return idMap[type]; +} + +module.exports = { + getId: getId, +}; diff --git a/packages/connector/test/editor/pageobjects/editor/workspace_page.js b/packages/connector/test/editor/pageobjects/editor/workspace_page.js new file mode 100644 index 0000000..92a725d --- /dev/null +++ b/packages/connector/test/editor/pageobjects/editor/workspace_page.js @@ -0,0 +1,101 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require("when"); +var events = require("nr-test-utils").require("@node-red/runtime/lib/events.js"); +var palette = require("./palette_page"); +var nodeFactory = require("../nodes/nodefactory_page"); +var keyPage = require("../util/key_page"); +var flowLayout = { + flowRightEnd : 600, + widthInterval : 300, + heightInterval : 80 +}; +var previousX = -flowLayout.widthInterval; +var previousY = 0; + +function addNode(type, x, y) { + if (x !== undefined) { + previousX = x; + if (y !== undefined) { + previousY = y; + } + } else { + if (previousX < flowLayout.flowRightEnd) { + previousX = previousX + flowLayout.widthInterval; + } else { + previousX = 0; + previousY = previousY + flowLayout.heightInterval; + } + } + browser.waitForVisible('#red-ui-palette-search'); + browser.setValue('//*[@id="red-ui-palette-search"]/div/form/input', type.replace(/([A-Z])/g, ' $1').toLowerCase()); + browser.pause(300); + browser.waitForVisible(palette.getId(type)); + browser.moveToObject(palette.getId(type)); + browser.buttonDown(); + browser.moveToObject("#red-ui-palette-search", previousX + 300, previousY + 100); // adjust to the top-left corner of workspace. + browser.buttonUp(); + // Last node is the one that has been created right now. + var nodeElement = browser.elements('//*[contains(concat(" ", normalize-space(@class), " "), " red-ui-flow-node-group ")][last()]'); + var nodeId = nodeElement.getAttribute('id'); + var node = nodeFactory.create(type, nodeId); + return node; +} + +function deleteAllNodes() { + browser.waitForVisible('//*[contains(@class, "active")]/a[@class="red-ui-tab-label"]'); + browser.click('//*[contains(@class, "active")]/a[@class="red-ui-tab-label"]'); + browser.pause(1000); + browser.keys(keyPage.selectAll()); + browser.keys(['Delete']); +} + +function deploy() { + browser.call(function () { + return when.promise(function (resolve, reject) { + events.on("runtime-event", function (event) { + if (event.id === 'runtime-deploy') { + events.removeListener("runtime-event", arguments.callee); + resolve(); + } + }); + browser.clickWithWait('#red-ui-header-button-deploy'); + }); + }); + browser.waitForText('#red-ui-header-button-deploy', 10000); + // Need additional wait until buttons becomes clickable. + browser.pause(50); +} + +function init(width, height) { + deleteAllNodes(); + + if (width !== undefined) { + flowLayout.widthInterval = width; + } + if (height !== undefined) { + flowLayout.heightInterval = height; + } + previousX = -flowLayout.widthInterval; + previousY = 0; +} + +module.exports = { + addNode: addNode, + deploy: deploy, + init: init +}; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/common/20-inject_page.js b/packages/connector/test/editor/pageobjects/nodes/core/common/20-inject_page.js new file mode 100644 index 0000000..38e6e32 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/common/20-inject_page.js @@ -0,0 +1,78 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); + +var nodePage = require("../../node_page"); + +function injectNode(id) { + nodePage.call(this, id); +} + +util.inherits(injectNode, nodePage); + +var payloadTypeList = { + "flow": 1, + "global": 2, + "str": 3, + "num": 4, + "bool": 5, + "json": 6, + "bin": 7, + "date": 8, + "env": 9, +}; + +var repeatTypeList = { + "none": 1, + "interval": 2, + "intervalBetweenTimes": 3, + "atASpecificTime": 4, +}; + +injectNode.prototype.setPayload = function(payloadType, payload) { + // Open a payload type list. + browser.clickWithWait('//*[contains(@class, "red-ui-typedInput-container")]'); + // Select a payload type. + var payloadTypeXPath = '//*[contains(@class, "red-ui-typedInput-options")]/a[' + payloadTypeList[payloadType] + ']'; + browser.clickWithWait(payloadTypeXPath); + if (payload) { + // Input a value. + browser.setValue('//*[contains(@class, "red-ui-typedInput-input")]/input', payload); + } +} + +injectNode.prototype.setTopic = function(topic) { + browser.setValue('#node-input-topic', topic); +} + +injectNode.prototype.setOnce = function(once) { + var isChecked = browser.isSelected('#node-input-once'); + if (isChecked !== once) { + browser.clickWithWait('#node-input-once'); + } +} + +injectNode.prototype.setRepeat = function(repeatType) { + var repeatTypeXPath = '//*[@id="inject-time-type-select"]/option[' + repeatTypeList[repeatType] + ']'; + browser.clickWithWait(repeatTypeXPath); +} + +injectNode.prototype.setRepeatInterval = function(repeat) { + browser.setValue('#inject-time-interval-count', repeat); +} + +module.exports = injectNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/common/21-debug_page.js b/packages/connector/test/editor/pageobjects/nodes/core/common/21-debug_page.js new file mode 100644 index 0000000..990ed6c --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/common/21-debug_page.js @@ -0,0 +1,43 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); + +var nodePage = require("../../node_page"); + +function debugNode(id) { + nodePage.call(this, id); +} + +util.inherits(debugNode, nodePage); + +debugNode.prototype.setOutput = function (complete) { + // Open a payload type list. + browser.clickWithWait('//*[contains(@class, "red-ui-typedInput-container")]/button'); + if (complete !== 'true') { + // Select the "msg" type. + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options")][1]/a[1]'); + // Input the path in msg. + browser.clickWithWait('//*[contains(@class, "red-ui-typedInput-input")]/input'); + browser.keys(Array('payload'.length).fill('Backspace')); + browser.setValue('//*[contains(@class, "red-ui-typedInput-input")]/input', complete); + } else { + // Select the "complete msg object" type. + browser.clickWithWait('/html/body/div[11]/a[2]'); + } +} + +module.exports = debugNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/common/24-complete_page.js b/packages/connector/test/editor/pageobjects/nodes/core/common/24-complete_page.js new file mode 100644 index 0000000..558ee70 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/common/24-complete_page.js @@ -0,0 +1,47 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require('util'); + +var nodePage = require('../../node_page'); + +function completeNode(id) { + nodePage.call(this, id); +} + +util.inherits(completeNode, nodePage); + +completeNode.prototype.setScope = function (scope) { + if (scope) { + browser.clickWithWait('//*[@id="node-input-complete-target-select"]'); + browser.pause(1000); + if (Array.isArray(scope)) { + for (var i = 0; i < scope.length; i++) { + browser.moveToObject(scope[i].id); + browser.buttonDown(); + browser.buttonUp(); + } + } else { + browser.moveToObject(scope.id); + browser.buttonDown(); + browser.buttonUp(); + } + browser.clickWithWait('//*[contains(@class, "red-ui-notification")]/div/button[2]'); + browser.pause(1000); + } +} + +module.exports = completeNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/common/25-catch_page.js b/packages/connector/test/editor/pageobjects/nodes/core/common/25-catch_page.js new file mode 100644 index 0000000..89bcb7f --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/common/25-catch_page.js @@ -0,0 +1,48 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require('util'); + +var nodePage = require('../../node_page'); + +function catchNode(id) { + nodePage.call(this, id); +} + +util.inherits(catchNode, nodePage); + +catchNode.prototype.setScope = function (scope) { + if (scope) { + browser.selectWithWait('#node-input-scope-select', 'target'); + browser.clickWithWait('//*[@id="node-input-catch-target-select"]'); + browser.pause(1000); + if (Array.isArray(scope)) { + for (var i = 0; i < scope.length; i++) { + browser.moveToObject(scope[i].id); + browser.buttonDown(); + browser.buttonUp(); + } + } else { + browser.moveToObject(scope.id); + browser.buttonDown(); + browser.buttonUp(); + } + browser.clickWithWait('//*[contains(@class, "red-ui-notification")]/div/button[2]'); + browser.pause(1000); + } +} + +module.exports = catchNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/common/25-status_page.js b/packages/connector/test/editor/pageobjects/nodes/core/common/25-status_page.js new file mode 100644 index 0000000..6de0fcd --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/common/25-status_page.js @@ -0,0 +1,48 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require('util'); + +var nodePage = require('../../node_page'); + +function statusNode(id) { + nodePage.call(this, id); +} + +util.inherits(statusNode, nodePage); + +statusNode.prototype.setScope = function (scope) { + if (scope) { + browser.selectWithWait('#node-input-scope-select', 'target'); + browser.clickWithWait('//*[@id="node-input-status-target-select"]'); + browser.pause(1000); + if (Array.isArray(scope)) { + for (var i = 0; i < scope.length; i++) { + browser.moveToObject(scope[i].id); + browser.buttonDown(); + browser.buttonUp(); + } + } else { + browser.moveToObject(scope.id); + browser.buttonDown(); + browser.buttonUp(); + } + browser.clickWithWait('//*[contains(@class, "red-ui-notification")]/div/button[2]'); + browser.pause(1000); + } +} + +module.exports = statusNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/common/90-comment_page.js b/packages/connector/test/editor/pageobjects/nodes/core/common/90-comment_page.js new file mode 100644 index 0000000..2687dac --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/common/90-comment_page.js @@ -0,0 +1,27 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require('util'); + +var nodePage = require('../../node_page'); + +function commentNode(id) { + nodePage.call(this, id); +} + +util.inherits(commentNode, nodePage); + +module.exports = commentNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/function/10-function_page.js b/packages/connector/test/editor/pageobjects/nodes/core/function/10-function_page.js new file mode 100644 index 0000000..c1bb80a --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/function/10-function_page.js @@ -0,0 +1,41 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); + +var nodePage = require("../../node_page"); + +var keyPage = require("../../../util/key_page"); + +function functionNode(id) { + nodePage.call(this, id); +} + +util.inherits(functionNode, nodePage); + +functionNode.prototype.setFunction = function (func) { + browser.clickWithWait('#node-input-func-editor'); + browser.keys(keyPage.selectAll()); + browser.keys(['Delete']); + browser.keys(func); + // Delete the unnecessary code that ace editor does the autocompletion. + browser.keys(keyPage.selectToEnd()); + browser.keys(['Delete']); + // Need to wait until ace editor correctly checks the syntax. + browser.pause(300); +} + +module.exports = functionNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/function/10-switch_page.js b/packages/connector/test/editor/pageobjects/nodes/core/function/10-switch_page.js new file mode 100644 index 0000000..a040140 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/function/10-switch_page.js @@ -0,0 +1,234 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require('util'); + +var nodePage = require('../../node_page'); + +function switchNode(id) { + nodePage.call(this, id); +} + +util.inherits(switchNode, nodePage); + +var vtType = { + "msg": 1, + "flow": 2, + "global": 3, + "str": 4, + "num": 5, + "jsonata": 6, + "env": 7, + "prev": 8 +}; + +function setT(t, index) { + browser.selectWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/select', t); +} + +function setV(v, vt, index) { + if (vt) { + browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + vtType[vt] + ']'); + } + if (v) { + browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/div/input', v); + } +} + +function setBetweenV(v, vt, v2, v2t, index) { + if (vt) { + browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div[2]/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + vtType[vt] + ']'); + } + if (v) { + browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div[2]/div[1]/input', v); + } + if (v2t) { + browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[3]/div/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + vtType[v2t] + ']'); + } + if (v2) { + browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[3]/div/div[1]/input', v2); + } +} + +function setSequenceV(v, vt, index) { + var sType = { + "flow": 1, + "global": 2, + "num": 3, + "jsonata": 4, + "env": 5, + }; + + if (vt) { + browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div[2]/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + sType[vt] + ']'); + } + if (v) { + browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div[2]/div[1]/input', v); + } +} + +switchNode.prototype.ruleEqual = function (v, vt, index) { + index = index || 1; + setT('eq', index); + setV(v, vt, index); +} + +switchNode.prototype.ruleNotEqual = function (v, vt, index) { + index = index || 1; + setT('neq', index); + setV(v, vt, index); +} + +switchNode.prototype.ruleLessThan = function (v, vt, index) { + index = index || 1; + setT('lt', index); + setV(v, vt, index); +} + +switchNode.prototype.ruleLessThanOrEqual = function (v, vt, index) { + index = index || 1; + setT('lte', index); + setV(v, vt, index); +} + +switchNode.prototype.ruleGreaterThan = function (v, vt, index) { + index = index || 1; + setT('gt', index); + setV(v, vt, index); +} + +switchNode.prototype.ruleGreaterThanOrEqual = function (v, vt, index) { + index = index || 1; + setT('gte', index); + setV(v, vt, index); +} + +switchNode.prototype.ruleHasKey = function (v, vt, index) { + index = index || 1; + setT('hask', index); + setV(v, vt, index); +} + +switchNode.prototype.ruleIsBetween = function (v, vt, v2, v2t, index) { + index = index || 1; + setT('btwn', index); + setBetweenV(v, vt, v2, v2t, index); +} + +switchNode.prototype.ruleContains = function (v, vt, index) { + index = index || 1; + setT('cont', index); + setV(v, vt, index); +} + +switchNode.prototype.ruleMatchesRegex = function (v, vt, index) { + index = index || 1; + setT('regex', index); + setV(v, vt, index); +} + +switchNode.prototype.ruleIsTrue = function (index) { + index = index || 1; + setT('true', index); +} + +switchNode.prototype.ruleIsFalse = function (index) { + index = index || 1; + setT('false', index); +} + +switchNode.prototype.ruleIsNull = function (index) { + index = index || 1; + setT('null', index); +} + +switchNode.prototype.ruleIsNotNull = function (index) { + index = index || 1; + setT('nnull', index); +} + +switchNode.prototype.ruleIsOfType = function (t, index) { + index = index || 1; + setT('istype', index); + + var tType = { + "str": 1, + "num": 2, + "boolean": 3, + "array": 4, + "buffer": 5, + "object": 6, + "json": 7, + "undefined": 8, + "null": 9 + }; + + if (t) { + browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div[2]/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + tType[t] + ']'); + } +} + +switchNode.prototype.ruleIsEmpty = function (index) { + index = index || 1; + setT('empty', index); +} + +switchNode.prototype.ruleIsNotEmpty = function (index) { + index = index || 1; + setT('nempty', index); +} + +switchNode.prototype.ruleHead = function (v, vt, index) { + index = index || 1; + setT('head', index); + setSequenceV(v, vt, index); +} + +switchNode.prototype.ruleIndexBetween = function (v, vt, v2, v2t, index) { + index = index || 1; + setT('index', index); + setBetweenV(v, vt, v2, v2t, index); +} + +switchNode.prototype.ruleTail = function (v, vt, index) { + index = index || 1; + setT('tail', index); + setSequenceV(v, vt, index); +} + +switchNode.prototype.ruleJSONataExp = function (v, index) { + index = index || 1; + setT('jsonata_exp', index); + if (v) { + browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div[2]/div[1]/input', v); + } +} + +switchNode.prototype.ruleOtherwise = function (index) { + index = index || 1; + setT('else', index); +} + +switchNode.prototype.addRule = function () { + browser.clickWithWait('//div[contains(@class, "red-ui-editableList")]/a'); +} + +module.exports = switchNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/function/15-change_page.js b/packages/connector/test/editor/pageobjects/nodes/core/function/15-change_page.js new file mode 100644 index 0000000..eb26f48 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/function/15-change_page.js @@ -0,0 +1,132 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require('util'); + +var nodePage = require('../../node_page'); + +function changeNode(id) { + nodePage.call(this, id); +} + +util.inherits(changeNode, nodePage); + +var totType = { + "msg": 1, + "flow": 2, + "global": 3, + "str": 4, + "num": 5, + "bool": 6, + "json": 7, + "bin": 8, + "date": 9, + "jsonata": 10, + "env": 11, +}; + +var ptType = { + "msg": 1, + "flow": 2, + "global": 3, +}; + +function setT(t, index) { + browser.selectWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/select', t); +} + +// It is better to create a function whose input value is the object type in the future, +changeNode.prototype.ruleSet = function (p, pt, to, tot, index) { + index = index || 1; + setT('set', index); + if (pt) { + browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + ptType[pt] + ']'); + } + if (p) { + browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/div/input', p); + } + if (tot) { + browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[2]/div[2]/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + totType[tot] + ']'); + } + if (to) { + browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[2]/div[2]/div/input', to); + } +} + +changeNode.prototype.ruleChange = function (p, pt, from, fromt, to, tot, index) { + index = index || 1; + setT('change', index); + if (pt) { + browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + ptType[pt] + ']'); + } + if (p) { + browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/div/input', p); + } + if (fromt) { + browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[3]/div[1]/div[2]/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + totType[pt] + ']'); + } + if (from) { + browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[3]/div[1]/div[2]/div[1]/input', from); + } + if (tot) { + browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[3]/div[2]/div[2]/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + totType[pt] + ']'); + } + if (to) { + browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[3]/div[2]/div[2]/div[1]/input', to); + } +} + +changeNode.prototype.ruleDelete = function (p, pt, index) { + index = index || 1; + setT('delete', index); + if (pt) { + browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + ptType[pt] + ']'); + } + if (p) { + browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/div/input', p); + } +} + +changeNode.prototype.ruleMove = function (p, pt, to, tot, index) { + index = index || 1; + setT('move', index); + if (pt) { + browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + ptType[pt] + ']'); + } + if (p) { + browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/div/input', p); + } + if (tot) { + browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[4]/div[2]/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + totType[pt] + ']'); + } + if (to) { + browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[4]/div[2]/div/input', to); + } +} + +changeNode.prototype.addRule = function () { + browser.clickWithWait('//div[contains(@class, "red-ui-editableList")]/a'); +} + +module.exports = changeNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/function/16-range_page.js b/packages/connector/test/editor/pageobjects/nodes/core/function/16-range_page.js new file mode 100644 index 0000000..2309299 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/function/16-range_page.js @@ -0,0 +1,38 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); + +var nodePage = require("../../node_page"); + +function rangeNode(id) { + nodePage.call(this, id); +} + +util.inherits(rangeNode, nodePage); + +rangeNode.prototype.setAction = function(action) { + browser.selectWithWait('#node-input-action', action); +} + +rangeNode.prototype.setRange = function(minin, maxin, minout, maxout) { + browser.setValue('#node-input-minin', minin); + browser.setValue('#node-input-maxin', maxin); + browser.setValue('#node-input-minout', minout); + browser.setValue('#node-input-maxout', maxout); +} + +module.exports = rangeNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/function/80-template_page.js b/packages/connector/test/editor/pageobjects/nodes/core/function/80-template_page.js new file mode 100644 index 0000000..bf1786b --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/function/80-template_page.js @@ -0,0 +1,48 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); + +var nodePage = require("../../node_page"); + +var keyPage = require("../../../util/key_page"); + +function templateNode(id) { + nodePage.call(this, id); +} + +util.inherits(templateNode, nodePage); + +templateNode.prototype.setSyntax = function (syntax) { + browser.selectWithWait('#node-input-syntax', syntax); +} + +templateNode.prototype.setFormat = function (format) { + browser.selectWithWait('#node-input-format', format); +} + +templateNode.prototype.setTemplate = function (template) { + browser.clickWithWait('#node-input-template-editor'); + browser.keys(keyPage.selectAll()); + browser.keys(['Delete']); + browser.keys(template); + browser.keys(keyPage.selectToEnd()); + browser.keys(['Delete']); + // Need to wait until ace editor correctly checks the syntax. + browser.pause(300); +} + +module.exports = templateNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/function/89-delay_page.js b/packages/connector/test/editor/pageobjects/nodes/core/function/89-delay_page.js new file mode 100644 index 0000000..3604beb --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/function/89-delay_page.js @@ -0,0 +1,31 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); + +var nodePage = require("../../node_page"); + +function delayNode(id) { + nodePage.call(this, id); +} + +util.inherits(delayNode, nodePage); + +delayNode.prototype.setTimeout = function (timeout) { + browser.setValue('//*[@id="node-input-timeout"]', timeout); +} + +module.exports = delayNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/function/89-trigger_page.js b/packages/connector/test/editor/pageobjects/nodes/core/function/89-trigger_page.js new file mode 100644 index 0000000..5d24de3 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/function/89-trigger_page.js @@ -0,0 +1,83 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); + +var nodePage = require("../../node_page"); + +function triggerNode(id) { + nodePage.call(this, id); +} + +util.inherits(triggerNode, nodePage); + +triggerNode.prototype.setSend = function (send, sendt) { + var sendType = { + "flow": 1, + "global": 2, + "str": 3, + "num": 4, + "bool": 5, + "json": 6, + "bin": 7, + "date": 8, + "env": 9, + "pay": 10, + "nul": 11 + }; + + if (sendt) { + browser.clickWithWait('//*[@id="dialog-form"]/div[1]/div/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + sendType[sendt] + ']'); + } + if (send) { + browser.setValue('//*[@id="dialog-form"]/div[1]/div/div[1]/input', send); + } +} + +triggerNode.prototype.setDuration = function (duration, units) { + browser.setValue('//*[@id="node-input-duration"]', duration); + if (units) { + browser.selectWithWait('//*[@id="node-input-units"]', units); + } +} + +triggerNode.prototype.setThenSend = function (thenSend, thenSendt) { + var thenSendType = { + "flow": 1, + "global": 2, + "str": 3, + "num": 4, + "bool": 5, + "json": 6, + "bin": 7, + "date": 8, + "env": 9, + "pay": 10, + "payl": 11, + "nul": 12 + }; + + if (thenSendt) { + browser.clickWithWait('//*[@id="dialog-form"]/div[5]/div/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + thenSendType[thenSendt] + ']'); + } + if (thenSend) { + browser.setValue('//*[@id="dialog-form"]/div[5]/div/div[1]/input', thenSend); + } +} + +module.exports = triggerNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/function/90-exec_page.js b/packages/connector/test/editor/pageobjects/nodes/core/function/90-exec_page.js new file mode 100644 index 0000000..69b8b6c --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/function/90-exec_page.js @@ -0,0 +1,37 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); + +var nodePage = require("../../node_page"); + +function execNode(id) { + nodePage.call(this, id); +} + +util.inherits(execNode, nodePage); + +execNode.prototype.setCommand = function (command) { + browser.setValue('//*[@id="node-input-command"]', command); +} + +execNode.prototype.setAppend = function (checkbox) { + if (browser.isSelected('#node-input-addpay') !== checkbox) { + browser.click('#node-input-addpay'); + } +} + +module.exports = execNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/network/10-mqtt_page.js b/packages/connector/test/editor/pageobjects/nodes/core/network/10-mqtt_page.js new file mode 100644 index 0000000..4bdd923 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/network/10-mqtt_page.js @@ -0,0 +1,74 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); + +var nodePage = require("../../node_page"); + +var mqttBrokerNode = {}; + +mqttBrokerNode.setServer = function (broker, port) { + browser.setValue('#node-config-input-broker', broker); + port = port ? port : 1883; + browser.setValue('#node-config-input-port', port); +}; + +mqttBrokerNode.clickOk = function () { + browser.clickWithWait('#node-config-dialog-ok'); + // Wait until an config dialog closes. + browser.waitForVisible('#node-config-dialog-ok', 10000, true); +}; + +mqttBrokerNode.edit = function () { + browser.waitForVisible('#node-input-lookup-broker'); + browser.click('#node-input-lookup-broker'); + // Wait until a config dialog opens. + browser.waitForVisible('#node-config-dialog-ok', 10000); +}; + +function mqttInNode(id) { + nodePage.call(this, id); +} + +util.inherits(mqttInNode, nodePage); + +mqttInNode.prototype.setTopic = function (topic) { + browser.setValue('#node-input-topic', topic); +}; + +mqttInNode.prototype.setQoS = function (qos) { + browser.selectWithWait('#node-input-qos', qos); +}; + +mqttInNode.prototype.mqttBrokerNode = mqttBrokerNode; +module.exports.mqttInNode = mqttInNode; + +function mqttOutNode(id) { + nodePage.call(this, id); +} + +util.inherits(mqttOutNode, nodePage); + +mqttOutNode.prototype.setTopic = function (topic) { + browser.setValue('#node-input-topic', topic); +}; + +mqttOutNode.prototype.setRetain = function (retain) { + browser.selectWithWait('#node-input-retain', retain); +}; + +mqttOutNode.prototype.mqttBrokerNode = mqttBrokerNode; +module.exports.mqttOutNode = mqttOutNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/network/21-httpin_page.js b/packages/connector/test/editor/pageobjects/nodes/core/network/21-httpin_page.js new file mode 100644 index 0000000..9454ef0 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/network/21-httpin_page.js @@ -0,0 +1,35 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); + +var nodePage = require("../../node_page"); + +function httpInNode(id) { + nodePage.call(this, id); +} + +util.inherits(httpInNode, nodePage); + +httpInNode.prototype.setMethod = function(method) { + browser.selectWithWait('#node-input-method', method); +} + +httpInNode.prototype.setUrl = function(url) { + browser.setValue('#node-input-url', url); +} + +module.exports = httpInNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/network/21-httprequest_page.js b/packages/connector/test/editor/pageobjects/nodes/core/network/21-httprequest_page.js new file mode 100644 index 0000000..b2ca812 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/network/21-httprequest_page.js @@ -0,0 +1,39 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); + +var nodePage = require("../../node_page"); + +function httpRequestNode(id) { + nodePage.call(this, id); +} + +util.inherits(httpRequestNode, nodePage); + +httpRequestNode.prototype.setUrl = function(url) { + browser.setValue('#node-input-url', url); +} + +httpRequestNode.prototype.setMethod = function(method) { + browser.selectWithWait('#node-input-method', method); +} + +httpRequestNode.prototype.setReturn = function(ret) { + browser.selectWithWait('#node-input-ret', ret); +} + +module.exports = httpRequestNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/network/21-httpresponse_page.js b/packages/connector/test/editor/pageobjects/nodes/core/network/21-httpresponse_page.js new file mode 100644 index 0000000..7fb1886 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/network/21-httpresponse_page.js @@ -0,0 +1,27 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); + +var nodePage = require("../../node_page"); + +function httpResponseNode(id) { + nodePage.call(this, id); +} + +util.inherits(httpResponseNode, nodePage); + +module.exports = httpResponseNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/network/22-websocket_page.js b/packages/connector/test/editor/pageobjects/nodes/core/network/22-websocket_page.js new file mode 100644 index 0000000..8f7dc26 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/network/22-websocket_page.js @@ -0,0 +1,93 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); + +var nodePage = require("../../node_page"); + +var websocketListenerNode = {}; + +websocketListenerNode.setPath = function (path) { + browser.setValue('#node-config-input-path', path); +}; + +websocketListenerNode.setSendReceive = function (wholemsg) { + browser.selectWithWait('#node-config-input-wholemsg', wholemsg); +}; + +websocketListenerNode.clickOk = function () { + browser.clickWithWait('#node-config-dialog-ok'); + // Wait until an config dialog closes. + browser.waitForVisible('#node-config-dialog-ok', 10000, true); +}; + +websocketListenerNode.edit = function () { + browser.waitForVisible('#node-input-lookup-server'); + browser.click('#node-input-lookup-server'); + // Wait until a config dialog opens. + browser.waitForVisible('#node-config-dialog-ok', 10000); +}; + +var websocketClientNode = {}; + +websocketClientNode.setPath = function (path) { + browser.setValue('#node-config-input-path', path); +}; + +websocketClientNode.setSendReceive = function (wholemsg) { + browser.selectWithWait('#node-config-input-wholemsg', wholemsg); +}; + +websocketClientNode.clickOk = function () { + browser.clickWithWait('#node-config-dialog-ok'); + // Wait until an config dialog closes. + browser.waitForVisible('#node-config-dialog-ok', 10000, true); +}; + +websocketClientNode.edit = function () { + browser.waitForVisible('#node-input-lookup-client'); + browser.click('#node-input-lookup-client'); + // Wait until a config dialog opens. + browser.waitForVisible('#node-config-dialog-ok', 10000); +}; + +function websocketInNode(id) { + nodePage.call(this, id); +} + +util.inherits(websocketInNode, nodePage); + +websocketInNode.prototype.setType = function (type) { + browser.selectWithWait('#node-input-mode', type); +}; + +websocketInNode.prototype.websocketListenerNode = websocketListenerNode; +websocketInNode.prototype.websocketClientNode = websocketClientNode; +module.exports.websocketInNode = websocketInNode; + +function websocketOutNode(id) { + nodePage.call(this, id); +} + +util.inherits(websocketOutNode, nodePage); + +websocketOutNode.prototype.setType = function (type) { + browser.selectWithWait('#node-input-mode', type); +}; + +websocketOutNode.prototype.websocketListenerNode = websocketListenerNode; +websocketOutNode.prototype.websocketClientNode = websocketClientNode; +module.exports.websocketOutNode = websocketOutNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/parsers/70-CSV_page.js b/packages/connector/test/editor/pageobjects/nodes/core/parsers/70-CSV_page.js new file mode 100644 index 0000000..e4bc950 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/parsers/70-CSV_page.js @@ -0,0 +1,51 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require('util'); + +var nodePage = require('../../node_page'); + +function csvNode(id) { + nodePage.call(this, id); +} + +util.inherits(csvNode, nodePage); + +csvNode.prototype.setColumns = function (columns) { + browser.setValue('#node-input-temp', columns); +} + +csvNode.prototype.setSkipLines = function (skip) { + browser.setValue('#node-input-skip', skip); +} + +csvNode.prototype.setFirstRow4Names = function (checkbox) { + if (browser.isSelected('#node-input-hdrin') !== checkbox) { + browser.click('#node-input-hdrin'); + } +} + +csvNode.prototype.setOutput = function (output) { + browser.selectWithWait('#node-input-multi', output); +} + +csvNode.prototype.setIncludeRow = function (checkbox) { + if (browser.isSelected('#node-input-hdrout') !== checkbox) { + browser.click('#node-input-hdrout'); + } +} + +module.exports = csvNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/parsers/70-HTML_page.js b/packages/connector/test/editor/pageobjects/nodes/core/parsers/70-HTML_page.js new file mode 100644 index 0000000..243e4c9 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/parsers/70-HTML_page.js @@ -0,0 +1,31 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require('util'); + +var nodePage = require('../../node_page'); + +function htmlNode(id) { + nodePage.call(this, id); +} + +util.inherits(htmlNode, nodePage); + +htmlNode.prototype.setSelector = function (tag) { + browser.setValue('#node-input-tag', tag); +} + +module.exports = htmlNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/parsers/70-JSON_page.js b/packages/connector/test/editor/pageobjects/nodes/core/parsers/70-JSON_page.js new file mode 100644 index 0000000..e0b31dd --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/parsers/70-JSON_page.js @@ -0,0 +1,35 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require('util'); + +var nodePage = require('../../node_page'); + +function jsonNode(id) { + nodePage.call(this, id); +} + +util.inherits(jsonNode, nodePage); + +jsonNode.prototype.setAction = function (action) { + browser.setValue('node-input-action', action); +} + +jsonNode.prototype.setProperty = function (property) { + browser.setValue('//*[contains(@class, "red-ui-typedInput-container")]/div[1]/input', property); +} + +module.exports = jsonNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/parsers/70-XML_page.js b/packages/connector/test/editor/pageobjects/nodes/core/parsers/70-XML_page.js new file mode 100644 index 0000000..696ec59 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/parsers/70-XML_page.js @@ -0,0 +1,35 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require('util'); + +var nodePage = require('../../node_page'); + +function xmlNode(id) { + nodePage.call(this, id); +} + +util.inherits(xmlNode, nodePage); + +xmlNode.prototype.setAction = function (action) { + browser.setValue('node-input-action', action); +} + +xmlNode.prototype.setProperty = function (property) { + browser.setValue('//*[contains(@class, "red-ui-typedInput-container")]/div[1]/input', property); +} + +module.exports = xmlNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/parsers/70-YAML_page.js b/packages/connector/test/editor/pageobjects/nodes/core/parsers/70-YAML_page.js new file mode 100644 index 0000000..1002f3e --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/parsers/70-YAML_page.js @@ -0,0 +1,35 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require('util'); + +var nodePage = require('../../node_page'); + +function yamlNode(id) { + nodePage.call(this, id); +} + +util.inherits(yamlNode, nodePage); + +yamlNode.prototype.setAction = function (action) { + browser.setValue('node-input-action', action); +} + +yamlNode.prototype.setProperty = function (property) { + browser.setValue('//*[contains(@class, "red-ui-typedInput-container")]/div[1]/input', property); +} + +module.exports = yamlNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/sequence/17-split_page.js b/packages/connector/test/editor/pageobjects/nodes/core/sequence/17-split_page.js new file mode 100644 index 0000000..8fc32ab --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/sequence/17-split_page.js @@ -0,0 +1,47 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require('util'); + +var nodePage = require('../../node_page'); + +function splitNode(id) { + nodePage.call(this, id); +} + +util.inherits(splitNode, nodePage); + +splitNode.prototype.setSplitUsing = function (splt, spltt) { + var spltType = { + "str": 1, + "bin": 2, + "len": 3 + }; + + browser.clickWithWait('//*[@id="dialog-form"]/div[3]/div/button[1]'); + browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + spltType[spltt] + ']'); + browser.setValue('//*[@id="dialog-form"]/div[3]/div/div[1]/input', splt); +}; + +module.exports.splitNode = splitNode; + +function joinNode(id) { + nodePage.call(this, id); +} + +util.inherits(joinNode, nodePage); + +module.exports.joinNode = joinNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/sequence/19-batch_page.js b/packages/connector/test/editor/pageobjects/nodes/core/sequence/19-batch_page.js new file mode 100644 index 0000000..0d7b130 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/sequence/19-batch_page.js @@ -0,0 +1,39 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require('util'); + +var nodePage = require('../../node_page'); + +function batchNode(id) { + nodePage.call(this, id); +} + +batchNode.prototype.setMode = function (mode) { + browser.selectWithWait('#node-input-mode', mode); +} + +batchNode.prototype.setCount = function (count) { + browser.setValue('#node-input-count', count); +} + +batchNode.prototype.setOverlap = function (overlap) { + browser.setValue('#node-input-overlap', overlap); +} + +util.inherits(batchNode, nodePage); + +module.exports = batchNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/core/storage/10-filein_page.js b/packages/connector/test/editor/pageobjects/nodes/core/storage/10-filein_page.js new file mode 100644 index 0000000..942ea63 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/core/storage/10-filein_page.js @@ -0,0 +1,44 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); + +var nodePage = require("../../node_page"); + +function fileInNode(id) { + nodePage.call(this, id); +} + +util.inherits(fileInNode, nodePage); + +var formatType = { + "utf8": 1, + "lines": 2, + "": 3, // a single Buffer object + "stream": 4 +}; + +fileInNode.prototype.setFilename = function(filename) { + browser.setValue('#node-input-filename', filename); +} + +fileInNode.prototype.setOutput = function(format) { + browser.clickWithWait('#node-input-format'); + var formatTypeXPath = '//*[@id="node-input-format"]/option[' + formatType[format] + ']'; + browser.clickWithWait(formatTypeXPath); +} + +module.exports = fileInNode; diff --git a/packages/connector/test/editor/pageobjects/nodes/node_page.js b/packages/connector/test/editor/pageobjects/nodes/node_page.js new file mode 100644 index 0000000..03e734c --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/node_page.js @@ -0,0 +1,51 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +function Node(id) { + this.id = '//*[@id="' + id + '"]'; +} + +Node.prototype.edit = function () { + browser.waitForVisible(this.id); + browser.moveToObject(this.id); + browser.buttonDown(); + browser.buttonUp(); + browser.keys(['Enter']); + // Wait until an edit dialog opens. + browser.waitForVisible('#node-dialog-ok', 10000); +} + +Node.prototype.clickOk = function () { + browser.clickWithWait('#node-dialog-ok'); + // Wait untile an edit dialog closes. + browser.waitForVisible('#node-dialog-ok', 10000, true); + browser.pause(50); +} + +Node.prototype.connect = function (targetNode, port) { + port = port || 1; + var outputPort = this.id + '/*[@class="red-ui-flow-port-output"][' + port + ']'; + var inputPort = targetNode.id + '/*[@class="red-ui-flow-port-input"]'; + browser.dragAndDrop(outputPort, inputPort); +} + +Node.prototype.clickLeftButton = function () { + browser.moveToObject(this.id + '/*[@class="red-ui-flow-node-button"]'); + browser.buttonDown(); + browser.buttonUp(); +} + +module.exports = Node; diff --git a/packages/connector/test/editor/pageobjects/nodes/nodefactory_page.js b/packages/connector/test/editor/pageobjects/nodes/nodefactory_page.js new file mode 100644 index 0000000..008ecc6 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/nodes/nodefactory_page.js @@ -0,0 +1,94 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var injectNode = require('./core/common/20-inject_page'); +var debugNode = require('./core/common/21-debug_page'); +var completeNode = require('./core/common/24-complete_page'); +var catchNode = require('./core/common/25-catch_page'); +var statusNode = require('./core/common/25-status_page'); +var commentNode = require('./core/common/90-comment_page'); +var functionNode = require('./core/function/10-function_page'); +var switchNode = require('./core/function/10-switch_page'); +var changeNode = require('./core/function/15-change_page'); +var rangeNode = require('./core/function/16-range_page'); +var templateNode = require('./core/function/80-template_page'); +var delayNode = require('./core/function/89-delay_page'); +var triggerNode = require('./core/function/89-trigger_page'); +var execNode = require('./core/function/90-exec_page'); +var mqttInNode = require('./core/network/10-mqtt_page').mqttInNode; +var mqttOutNode = require('./core/network/10-mqtt_page').mqttOutNode; +var httpInNode = require('./core/network/21-httpin_page'); +var httpResponseNode = require('./core/network/21-httpresponse_page'); +var httpRequestNode = require('./core/network/21-httprequest_page'); +var websocketInNode = require('./core/network/22-websocket_page').websocketInNode; +var websocketOutNode = require('./core/network/22-websocket_page').websocketOutNode; +var splitNode = require('./core/sequence/17-split_page').splitNode; +var joinNode = require('./core/sequence/17-split_page').joinNode; +var batchNode = require('./core/sequence/19-batch_page'); +var csvNode = require('./core/parsers/70-CSV_page'); +var htmlNode = require('./core/parsers/70-HTML_page'); +var jsonNode = require('./core/parsers/70-JSON_page'); +var xmlNode = require('./core/parsers/70-XML_page'); +var yamlNode = require('./core/parsers/70-YAML_page'); +var fileInNode = require('./core/storage/10-filein_page'); + +var nodeCatalog = { + // common + "inject": injectNode, + "debug": debugNode, + "complete": completeNode, + "catch": catchNode, + "status": statusNode, + "comment": commentNode, + // function + "function": functionNode, + "switch": switchNode, + "change": changeNode, + "range": rangeNode, + "template": templateNode, + "delay": delayNode, + "trigger": triggerNode, + "exec": execNode, + // network + "mqttIn": mqttInNode, + "mqttOut": mqttOutNode, + "httpIn": httpInNode, + "httpResponse": httpResponseNode, + "httpRequest": httpRequestNode, + "websocketIn": websocketInNode, + "websocketOut": websocketOutNode, + // sequence + "split": splitNode, + "join": joinNode, + "batch": batchNode, + // parser + "csv": csvNode, + "html": htmlNode, + "json": jsonNode, + "xml": xmlNode, + "yaml": yamlNode, + // storage + "fileIn": fileInNode +}; + +function create(type, id) { + var Node = nodeCatalog[type]; + return new Node(id); +} + +module.exports = { + create: create, +}; diff --git a/packages/connector/test/editor/pageobjects/util/key_page.js b/packages/connector/test/editor/pageobjects/util/key_page.js new file mode 100644 index 0000000..497a8a1 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/util/key_page.js @@ -0,0 +1,55 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var os = require("os"); + +var shortCutKeyMap = { + "selectAll": ['Control', 'a', 'a', 'Control'], + "selectToEnd": ['Control', 'Shift', 'End', 'Shift', 'Control'], +}; + +var shortCutKeyMapForMac = { + "selectAll": ['Command', 'a', 'a', 'Command'], + "selectToEnd": ['Command', 'Shift', 'ArrowDown', 'Shift', 'Command'], +}; + +function getShortCutKey(type) { + if (process.env.BROWSERSTACK) { + if (browser.desiredCapabilities.os === 'OS X') { + return shortCutKeyMapForMac[type]; + } + return shortCutKeyMap[type]; + } + if (os.type() === 'Darwin') { + return shortCutKeyMapForMac[type]; + } + return shortCutKeyMap[type]; +} + +function selectAll() { + var key = getShortCutKey('selectAll'); + return key; +} + +function selectToEnd() { + var key = getShortCutKey('selectToEnd'); + return key; +} + +module.exports = { + selectAll: selectAll, + selectToEnd: selectToEnd, +}; diff --git a/packages/connector/test/editor/pageobjects/util/spec_util_page.js b/packages/connector/test/editor/pageobjects/util/spec_util_page.js new file mode 100644 index 0000000..f647436 --- /dev/null +++ b/packages/connector/test/editor/pageobjects/util/spec_util_page.js @@ -0,0 +1,23 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +function pause(msec) { + browser.pause(msec); +} + + module.exports = { + pause: pause, + }; diff --git a/packages/connector/test/editor/pageobjects/util/util_page.js b/packages/connector/test/editor/pageobjects/util/util_page.js new file mode 100644 index 0000000..3a764eb --- /dev/null +++ b/packages/connector/test/editor/pageobjects/util/util_page.js @@ -0,0 +1,84 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var waitTime = 5000; + +function repeatUntilSuccess(operation, args) { + // Wait at most 10 seconds. + for (var i = 0; i < 200; i++) { + try { + var ret = operation(args); + return ret; + } catch (e) { + if (i === 199) { + console.trace(); + throw e; + } + browser.pause(50); + } + } +} + +function init() { + browser.addCommand("clickWithWait", function(selector) { + try { + // This is necessary because there is a case that the target may exist but still moving. + browser.pause(50); + browser.waitForVisible(selector); + + var ret = repeatUntilSuccess(function(selector) { + return browser.click(selector); + }, selector); + return ret; + } catch (e) { + console.trace(); + throw e; + } + }, false); + + browser.addCommand("getTextWithWait", function(selector) { + try { + browser.waitForExist(selector); + browser.waitForValue(selector); + + var ret = repeatUntilSuccess(function(selector) { + return browser.getText(selector); + }, selector); + return ret; + } catch (e) { + console.trace(); + throw e; + } + }, false); + + browser.addCommand("selectWithWait", function(selector, value) { + try { + browser.waitForVisible(selector, waitTime); + + var ret = repeatUntilSuccess(function(args) { + return browser.selectByValue(args[0], args[1]); + }, [selector, value.toString()]); + return ret; + } catch (e) { + console.trace(); + throw e; + } + }, false); +} + + module.exports = { + init: init, + }; diff --git a/packages/connector/test/editor/specs/editor/workspace_uispec.js b/packages/connector/test/editor/specs/editor/workspace_uispec.js new file mode 100644 index 0000000..15de1a0 --- /dev/null +++ b/packages/connector/test/editor/specs/editor/workspace_uispec.js @@ -0,0 +1,55 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require('when'); +var should = require("should"); +var fs = require('fs-extra'); + +var helper = require("../../editor_helper"); +var debugTab = require('../../pageobjects/editor/debugTab_page'); +var workspace = require('../../pageobjects/editor/workspace_page'); + + +describe('Workspace', function() { + beforeEach(function() { + workspace.init(); + }); + + before(function() { + helper.startServer(); + }); + + after(function() { + helper.stopServer(); + }); + + it('should have a right title', function () { + browser.getTitle().should.startWith('Node-RED'); + }); + + it('should output a timestamp', function() { + var injectNode = workspace.addNode("inject"); + var debugNode = workspace.addNode("debug"); + injectNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.within(1500000000000, 3000000000000); + }); + +}); diff --git a/packages/connector/test/editor/specs/scenario/cookbook_dataformats_uispec.js b/packages/connector/test/editor/specs/scenario/cookbook_dataformats_uispec.js new file mode 100644 index 0000000..23bb4fb --- /dev/null +++ b/packages/connector/test/editor/specs/scenario/cookbook_dataformats_uispec.js @@ -0,0 +1,364 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require('when'); +var should = require('should'); +var fs = require('fs-extra'); + +var helper = require('../../editor_helper'); +var debugTab = require('../../pageobjects/editor/debugTab_page'); +var workspace = require('../../pageobjects/editor/workspace_page'); +var specUtil = require('../../pageobjects/util/spec_util_page'); + +var httpNodeRoot = '/api'; + +// https://cookbook.nodered.org/ +describe('cookbook', function () { + beforeEach(function () { + workspace.init(); + }); + + before(function () { + helper.startServer(); + }); + + after(function () { + helper.stopServer(); + }); + + describe('working with data formats', function () { + it('convert to/from JSON', function () { + var injectNode1 = workspace.addNode('inject'); + var jsonNode1 = workspace.addNode('json'); + var debugNode1 = workspace.addNode('debug'); + + injectNode1.edit(); + injectNode1.setPayload('str', '{"a":1}'); + injectNode1.clickOk(); + + jsonNode1.edit(); + jsonNode1.setProperty('payload'); + jsonNode1.clickOk(); + + injectNode1.connect(jsonNode1); + jsonNode1.connect(debugNode1); + + var injectNode2 = workspace.addNode('inject'); + var jsonNode2 = workspace.addNode('json'); + var debugNode2 = workspace.addNode('debug'); + + injectNode2.edit(); + injectNode2.setPayload('json', '{"a":1}'); + injectNode2.clickOk(); + + jsonNode2.edit(); + jsonNode2.setProperty('payload'); + jsonNode2.clickOk(); + + injectNode2.connect(jsonNode2); + jsonNode2.connect(debugNode2); + + workspace.deploy(); + + debugTab.open(); + injectNode1.clickLeftButton(); + debugTab.getMessage().should.eql('1'); + debugTab.clearMessage(); + injectNode2.clickLeftButton(); + debugTab.getMessage().should.eql('"{"a":1}"'); + }); + + it('convert to/from XML', function () { + var injectNode1 = workspace.addNode('inject', 0); + var templateNode1 = workspace.addNode('template', 200); + var xmlNode1 = workspace.addNode('xml', 400); + var debugNode1 = workspace.addNode('debug', 600); + + injectNode1.edit(); + injectNode1.setPayload('str', '{"a":1}'); + injectNode1.clickOk(); + + templateNode1.edit(); + templateNode1.setFormat('text'); + templateNode1.setSyntax('plain'); + templateNode1.setTemplate('<note priority="high">' + + ' <to>Nick</to>' + + ' <from>Dave</from>' + + ' <heading>Reminder</heading>' + + ' <body>Update the website</body>' + + '</note>'); + templateNode1.clickOk(); + + xmlNode1.edit(); + xmlNode1.setProperty('payload'); + xmlNode1.clickOk(); + + injectNode1.connect(templateNode1); + templateNode1.connect(xmlNode1); + xmlNode1.connect(debugNode1); + + var injectNode2 = workspace.addNode('inject'); + var xmlNode2 = workspace.addNode('xml'); + var debugNode2 = workspace.addNode('debug'); + + injectNode2.edit(); + injectNode2.setPayload('json', '{' + + ' "note": {' + + ' "$": { "priority": "high" },' + + ' "to": [ "Nick" ],' + + ' "from": [ "Dave" ],' + + ' "heading": [ "Reminder" ],' + + ' "body": [ "Update the website" ]' + + ' }' + + '}'); + injectNode2.clickOk(); + + xmlNode2.edit(); + xmlNode2.setProperty('payload'); + xmlNode2.clickOk(); + + injectNode2.connect(xmlNode2); + xmlNode2.connect(debugNode2); + + workspace.deploy(); + + debugTab.open(); + injectNode1.clickLeftButton(); + debugTab.getMessage().should.eql('object'); + debugTab.clearMessage(); + injectNode2.clickLeftButton(); + debugTab.getMessage().should.eql('"<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' + + '<note priority="high">' + + '<to>Nick</to>' + + '<from>Dave</from>' + + '<heading>Reminder</heading>' + + '<body>Update the website</body>' + + '</note>"'); + }); + + it('convert to/from YAML', function () { + var injectNode1 = workspace.addNode('inject', 0); + var templateNode1 = workspace.addNode('template', 200); + var yamlNode1 = workspace.addNode('yaml', 400); + var debugNode1 = workspace.addNode('debug', 600); + + injectNode1.edit(); + injectNode1.setPayload('str', '{"a":1}'); + injectNode1.clickOk(); + + templateNode1.edit(); + templateNode1.setFormat('yaml'); + templateNode1.setSyntax('plain'); + templateNode1.setTemplate('a: 1\n' + + 'b:\n' + + ' - 1\n' + + '- 2\n' + + '- 3'); + templateNode1.clickOk(); + + yamlNode1.edit(); + yamlNode1.setProperty('payload'); + yamlNode1.clickOk(); + + injectNode1.connect(templateNode1); + templateNode1.connect(yamlNode1); + yamlNode1.connect(debugNode1); + + var injectNode2 = workspace.addNode('inject'); + var yamlNode2 = workspace.addNode('yaml'); + var debugNode2 = workspace.addNode('debug'); + + injectNode2.edit(); + injectNode2.setPayload('json', '{"a":1, "b":[1,2,3]}'); + injectNode2.clickOk(); + + yamlNode2.edit(); + yamlNode2.setProperty('payload'); + yamlNode2.clickOk(); + + injectNode2.connect(yamlNode2); + yamlNode2.connect(debugNode2); + + workspace.deploy(); + + debugTab.open(); + injectNode1.clickLeftButton(); + debugTab.getMessage().should.eql([ '1', 'array[3]' ]); + debugTab.clearMessage(); + injectNode2.clickLeftButton(); + debugTab.getMessage().should.eql('"a: 1↵b:↵ - 1↵ - 2↵ - 3↵"'); + }); + + it('generate CSV output', function () { + var injectNode1 = workspace.addNode('inject', 0); + var changeNode1 = workspace.addNode('change', 200); + var csvNode1 = workspace.addNode('csv', 400); + var debugNode1 = workspace.addNode('debug', 600); + + changeNode1.edit(); + changeNode1.ruleSet('payload', 'msg', '{' + + ' "a": $floor(100*$random()),' + + ' "b": $floor(100*$random()),' + + ' "c": $floor(100*$random())' + + '}', 'jsonata'); + changeNode1.clickOk(); + + csvNode1.edit(); + csvNode1.setColumns('a,b,c'); + csvNode1.clickOk(); + + injectNode1.connect(changeNode1); + changeNode1.connect(csvNode1); + csvNode1.connect(debugNode1); + + var injectNode2 = workspace.addNode('inject', 0, 80); + var changeNode2 = workspace.addNode('change', 200, 80); + var csvNode2 = workspace.addNode('csv', 400, 80); + var debugNode2 = workspace.addNode('debug', 600, 80); + + changeNode2.edit(); + changeNode2.ruleSet('payload', 'msg', '[' + + ' {' + + ' "a": $floor(100*$random()),' + + ' "b": $floor(100*$random()),' + + ' "c": $floor(100*$random())' + + ' }, {' + + ' "a": $floor(100*$random()),' + + ' "b": $floor(100*$random()),' + + ' "c": $floor(100*$random())' + + ' }, {' + + ' "a": $floor(100*$random()),' + + ' "b": $floor(100*$random()),' + + ' "c": $floor(100*$random())' + + ' }, {' + + ' "a": $floor(100*$random()),' + + ' "b": $floor(100*$random()),' + + ' "c": $floor(100*$random())' + + ' }' + + ']', 'jsonata'); + changeNode2.clickOk(); + + csvNode2.edit(); + csvNode2.setColumns('a,b,c'); + csvNode2.setIncludeRow(true); + csvNode2.clickOk(); + + injectNode2.connect(changeNode2); + changeNode2.connect(csvNode2); + csvNode2.connect(debugNode2); + + workspace.deploy(); + + debugTab.open(); + injectNode1.clickLeftButton(); + debugTab.getMessage().should.match(/^"([1-9]?[0-9],){2}[1-9]?[0-9]↵"$/); + debugTab.clearMessage(); + injectNode2.clickLeftButton(); + debugTab.getMessage().should.match(/^"a,b,c↵(([1-9]?[0-9],){2}[1-9]?[0-9]↵){4}"$/); + }); + + it('parse CSV input', function () { + var injectNode = workspace.addNode('inject'); + var templateNode = workspace.addNode('template'); + var csvNode = workspace.addNode('csv'); + var debugNode = workspace.addNode('debug'); + + templateNode.edit(); + templateNode.setFormat('handlebars'); + templateNode.setSyntax('mustache'); + templateNode.setTemplate('# This is some random data\n' + + 'a,b,c\n' + + '80,18,2\n' + + '52,36,10\n' + + '91,18,61\n' + + '32,47,65'); + templateNode.clickOk(); + + csvNode.edit(); + csvNode.setSkipLines(1); + csvNode.setFirstRow4Names(true); + csvNode.setOutput('mult'); + csvNode.clickOk(); + + injectNode.connect(templateNode); + templateNode.connect(csvNode); + csvNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.eql([ 'object', 'object', 'object', 'object' ]); + }); + + it('simple GET request', function () { + var injectNode = workspace.addNode('inject'); + var httpRequestNode = workspace.addNode('httpRequest'); + var htmlNode = workspace.addNode('html'); + var debugNode = workspace.addNode('debug'); + + httpRequestNode.edit(); + httpRequestNode.setMethod('GET'); + httpRequestNode.setUrl('https://nodered.org'); + httpRequestNode.clickOk(); + + htmlNode.edit(); + htmlNode.setSelector('.node-red-latest-version'); + htmlNode.clickOk(); + + injectNode.connect(httpRequestNode); + httpRequestNode.connect(htmlNode); + htmlNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.match(/^"v[0-9]+\.[0-9]+\.[0-9]"$/); + }); + + it('split text into one message per line', function () { + var injectNode = workspace.addNode('inject'); + var templateNode = workspace.addNode('template'); + var splitNode = workspace.addNode('split'); + var changeNode = workspace.addNode('change'); + var joinNode = workspace.addNode('join'); + var debugNode = workspace.addNode('debug'); + + templateNode.edit(); + templateNode.setFormat('handlebars'); + templateNode.setSyntax('mustache'); + templateNode.setTemplate('one\ntwo\nthree\nfour\nfive'); + templateNode.clickOk(); + + changeNode.edit(); + changeNode.ruleSet('payload', 'msg', '(parts.index+1) & ": " & payload', 'jsonata'); + changeNode.clickOk(); + + injectNode.connect(templateNode); + templateNode.connect(splitNode); + splitNode.connect(changeNode); + changeNode.connect(joinNode); + joinNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.eql('"1: one↵2: two↵3: three↵4: four↵5: five"'); + }); + }); +}); diff --git a/packages/connector/test/editor/specs/scenario/cookbook_errorhandling_uispec.js b/packages/connector/test/editor/specs/scenario/cookbook_errorhandling_uispec.js new file mode 100644 index 0000000..5285c5c --- /dev/null +++ b/packages/connector/test/editor/specs/scenario/cookbook_errorhandling_uispec.js @@ -0,0 +1,74 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require('when'); +var should = require('should'); +var fs = require('fs-extra'); + +var helper = require('../../editor_helper'); +var debugTab = require('../../pageobjects/editor/debugTab_page'); +var workspace = require('../../pageobjects/editor/workspace_page'); +var specUtil = require('../../pageobjects/util/spec_util_page'); + +var httpNodeRoot = '/api'; + +// https://cookbook.nodered.org/ +describe('cookbook', function () { + beforeEach(function () { + workspace.init(); + }); + + before(function () { + helper.startServer(); + }); + + after(function () { + helper.stopServer(); + }); + + describe('messages', function () { + it('trigger a flow when a node throws an error', function () { + var injectNode = workspace.addNode('inject'); + var functionNode = workspace.addNode('function'); + var catchNode = workspace.addNode('catch', 0 , 80); + var debugNode = workspace.addNode('debug'); + + functionNode.edit(); + functionNode.setFunction('node.error("an example error", msg);'); + functionNode.clickOk(); + + catchNode.edit(); + catchNode.setScope(functionNode); + catchNode.clickOk(); + + debugNode.edit(); + debugNode.setOutput('error'); + debugNode.clickOk(); + + injectNode.connect(functionNode); + catchNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.eql(['"an example error"', 'function']); + }); + + // skip this case since the flow outputs random results. + it.skip('automatically retry an action after an error'); + }); +}); diff --git a/packages/connector/test/editor/specs/scenario/cookbook_flowcontrol_uispec.js b/packages/connector/test/editor/specs/scenario/cookbook_flowcontrol_uispec.js new file mode 100644 index 0000000..724d1c5 --- /dev/null +++ b/packages/connector/test/editor/specs/scenario/cookbook_flowcontrol_uispec.js @@ -0,0 +1,81 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require('when'); +var should = require('should'); +var fs = require('fs-extra'); + +var helper = require('../../editor_helper'); +var debugTab = require('../../pageobjects/editor/debugTab_page'); +var workspace = require('../../pageobjects/editor/workspace_page'); +var specUtil = require('../../pageobjects/util/spec_util_page'); + +var httpNodeRoot = '/api'; + +// https://cookbook.nodered.org/ +describe('cookbook', function () { + beforeEach(function () { + workspace.init(); + }); + + before(function () { + helper.startServer(); + }); + + after(function () { + helper.stopServer(); + }); + + describe('flow control', function () { + it('trigger a flow whenever Node-RED starts', function () { + var injectNode = workspace.addNode('inject'); + var debugNode = workspace.addNode('debug'); + + injectNode.edit(); + injectNode.setPayload('str', 'Started!'); + injectNode.setOnce(true); + injectNode.clickOk(); + injectNode.connect(debugNode); + + debugTab.open(); + workspace.deploy(); + debugTab.getMessage().should.eql('"Started!"'); + }); + + it('trigger a flow at regular intervals', function () { + var injectNode = workspace.addNode('inject'); + var debugNode = workspace.addNode('debug'); + + injectNode.edit(); + injectNode.setRepeat('interval'); + injectNode.setRepeatInterval(1); + injectNode.clickOk(); + injectNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + specUtil.pause(1000); + var t1 = Number(debugTab.getMessage(1)); + t1.should.within(1500000000000, 3000000000000); + specUtil.pause(1000); + debugTab.getMessage(2).should.within(t1 + 900, 3000000000000); + }); + + // skip this case since it needs up to one minite. + it.skip('trigger a flow at a specific time'); + }); +}); diff --git a/packages/connector/test/editor/specs/scenario/cookbook_httpendpoints_uispec.js b/packages/connector/test/editor/specs/scenario/cookbook_httpendpoints_uispec.js new file mode 100644 index 0000000..1344983 --- /dev/null +++ b/packages/connector/test/editor/specs/scenario/cookbook_httpendpoints_uispec.js @@ -0,0 +1,572 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); + +var helper = require("../../editor_helper"); +var debugTab = require('../../pageobjects/editor/debugTab_page'); +var workspace = require('../../pageobjects/editor/workspace_page'); + +var httpNodeRoot = "/api"; + +// https://cookbook.nodered.org/ +describe('cookbook', function () { + beforeEach(function () { + workspace.init(); + }); + + before(function () { + helper.startServer(); + }); + + after(function () { + helper.stopServer(); + }); + + describe('HTTP endpoints', function () { + it('create an HTTP endpoint', function () { + var httpInNode = workspace.addNode("httpIn"); + var templateNode = workspace.addNode("template"); + var httpResponseNode = workspace.addNode("httpResponse"); + + httpInNode.edit(); + httpInNode.setMethod("get"); + httpInNode.setUrl("/hello"); + httpInNode.clickOk(); + + templateNode.edit(); + templateNode.setSyntax("mustache"); + templateNode.setFormat("handlebars"); + templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>Hello World!</h1>\n</body>\n</html>"); + templateNode.clickOk(); + + httpInNode.connect(templateNode); + templateNode.connect(httpResponseNode); + + // The code for confirmation starts from here. + var injectNode = workspace.addNode("inject"); + var httpRequestNode = workspace.addNode("httpRequest"); + var debugNode = workspace.addNode("debug"); + + httpRequestNode.edit(); + httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello'); + httpRequestNode.setMethod("GET"); + httpRequestNode.clickOk(); + + injectNode.connect(httpRequestNode); + httpRequestNode.connect(debugNode); + // The code for confirmation ends here. + + workspace.deploy(); + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().indexOf('Hello World!').should.not.eql(-1); + }); + + it('handle query parameters passed to an HTTP endpoint', function () { + var httpInNode = workspace.addNode("httpIn"); + var templateNode = workspace.addNode("template"); + var httpResponseNode = workspace.addNode("httpResponse"); + + httpInNode.edit(); + httpInNode.setMethod("get"); + httpInNode.setUrl("/hello-query"); + httpInNode.clickOk(); + + templateNode.edit(); + templateNode.setSyntax("mustache"); + templateNode.setFormat("handlebars"); + templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>Hello {{req.query.name}}!</h1>\n</body>\n</html>"); + templateNode.clickOk(); + + httpInNode.connect(templateNode); + templateNode.connect(httpResponseNode); + + // The code for confirmation starts from here. + var injectNode = workspace.addNode("inject"); + var httpRequestNode = workspace.addNode("httpRequest"); + var debugNode = workspace.addNode("debug"); + + httpRequestNode.edit(); + httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-query?name=Nick'); + httpRequestNode.setMethod("GET"); + httpRequestNode.clickOk(); + + injectNode.connect(httpRequestNode); + httpRequestNode.connect(debugNode); + // The code for confirmation ends here. + + workspace.deploy(); + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().indexOf('Hello Nick!').should.not.eql(-1); + }); + + it('handle url parameters in an HTTP endpoint', function () { + var httpInNode = workspace.addNode("httpIn"); + var templateNode = workspace.addNode("template"); + var httpResponseNode = workspace.addNode("httpResponse"); + + httpInNode.edit(); + httpInNode.setMethod("get"); + httpInNode.setUrl("/hello-param/:name"); + httpInNode.clickOk(); + + templateNode.edit(); + templateNode.setSyntax("mustache"); + templateNode.setFormat("handlebars"); + templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>Hello {{req.params.name}}!</h1>\n</body>\n</html>"); + templateNode.clickOk(); + + httpInNode.connect(templateNode); + templateNode.connect(httpResponseNode); + + // The code for confirmation starts from here. + var injectNode = workspace.addNode("inject"); + var httpRequestNode = workspace.addNode("httpRequest"); + var debugNode = workspace.addNode("debug"); + + httpRequestNode.edit(); + httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-param/Dave'); + httpRequestNode.setMethod("GET"); + httpRequestNode.clickOk(); + + injectNode.connect(httpRequestNode); + httpRequestNode.connect(debugNode); + // The code for confirmation ends here. + + workspace.deploy(); + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().indexOf('Hello Dave!').should.not.eql(-1); + }); + + it('access HTTP request headers', function () { + var httpInNode = workspace.addNode("httpIn"); + var templateNode = workspace.addNode("template"); + var httpResponseNode = workspace.addNode("httpResponse"); + + httpInNode.edit(); + httpInNode.setMethod("get"); + httpInNode.setUrl("/hello-headers"); + httpInNode.clickOk(); + + templateNode.edit(); + templateNode.setSyntax("mustache"); + templateNode.setFormat("handlebars"); + templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>User agent: {{req.headers.user-agent}}</h1>\n</body>\n</html>"); + templateNode.clickOk(); + + httpInNode.connect(templateNode); + templateNode.connect(httpResponseNode); + + // The code for confirmation starts from here. + var injectNode = workspace.addNode("inject", 0, 100); + var changeNode = workspace.addNode("change"); + var httpRequestNode = workspace.addNode("httpRequest"); + var debugNode = workspace.addNode("debug"); + + changeNode.edit(); + changeNode.ruleSet("headers", "msg", '{"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}', "json"); + changeNode.clickOk(); + + httpRequestNode.edit(); + httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-headers'); + httpRequestNode.setMethod("GET"); + httpRequestNode.clickOk(); + + injectNode.connect(changeNode); + changeNode.connect(httpRequestNode); + httpRequestNode.connect(debugNode); + // The code for confirmation ends here. + + workspace.deploy(); + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().indexOf('Mozilla').should.not.eql(-1); + }); + + it('include data captured in another flow', function () { + var injectNodeTimestamp = workspace.addNode("inject"); + var changeNodeStore = workspace.addNode("change"); + + var httpInNode = workspace.addNode("httpIn", 0, 100); + var changeNodeCopy = workspace.addNode("change"); + var templateNode = workspace.addNode("template"); + var httpResponseNode = workspace.addNode("httpResponse"); + + injectNodeTimestamp.edit(); + injectNodeTimestamp.setPayload("date"); + injectNodeTimestamp.clickOk(); + + changeNodeStore.edit(); + changeNodeStore.ruleSet("timestamp", "flow", "payload", "msg"); + changeNodeStore.clickOk(); + + injectNodeTimestamp.connect(changeNodeStore); + + httpInNode.edit(); + httpInNode.setMethod("get"); + httpInNode.setUrl("/hello-data"); + httpInNode.clickOk(); + + changeNodeCopy.edit(); + changeNodeCopy.ruleSet("timestamp", "msg", "timestamp", "flow"); + changeNodeCopy.clickOk(); + + templateNode.edit(); + templateNode.setSyntax("mustache"); + templateNode.setFormat("handlebars"); + templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>Time: {{ timestamp }}</h1>\n</body>\n</html>"); + templateNode.clickOk(); + + httpInNode.connect(changeNodeCopy); + changeNodeCopy.connect(templateNode); + templateNode.connect(httpResponseNode); + + // The code for confirmation starts from here. + var injectNodeCheck = workspace.addNode("inject", 0, 300); + var httpRequestNode = workspace.addNode("httpRequest"); + var debugNode = workspace.addNode("debug"); + + httpRequestNode.edit(); + httpRequestNode.setMethod("GET"); + httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-data'); + httpRequestNode.clickOk(); + + injectNodeCheck.connect(httpRequestNode); + httpRequestNode.connect(debugNode); + // The code for confirmation ends here. + + workspace.deploy(); + debugTab.open(); + injectNodeTimestamp.clickLeftButton(); + injectNodeCheck.clickLeftButton(); + var index = debugTab.getMessage().indexOf('Time: ') + 6; + debugTab.getMessage().substring(index, index + 13).should.within(1500000000000, 3000000000000); + }); + + it('serve JSON content', function () { + var httpInNode = workspace.addNode("httpIn"); + var templateNode = workspace.addNode("template"); + var changeNode = workspace.addNode("change"); + var httpResponseNode = workspace.addNode("httpResponse"); + + httpInNode.edit(); + httpInNode.setMethod("get"); + httpInNode.setUrl("/hello-json"); + httpInNode.clickOk(); + + templateNode.edit(); + templateNode.setSyntax("mustache"); + templateNode.setFormat("handlebars"); + templateNode.setTemplate('{ "Hello": "World" }'); + templateNode.clickOk(); + + changeNode.edit(); + changeNode.ruleSet("headers", "msg", "{}", "json", "1"); + changeNode.addRule(); + changeNode.ruleSet("headers.content-type", "msg", "application/json", "str", "2"); + changeNode.clickOk(); + + httpInNode.connect(templateNode); + templateNode.connect(changeNode); + changeNode.connect(httpResponseNode); + + // The code for confirmation starts from here. + var injectNode = workspace.addNode("inject", 0, 200); + var httpRequestNode = workspace.addNode("httpRequest"); + var changeNodeCheck = workspace.addNode("change"); + var debugNode = workspace.addNode("debug"); + + httpRequestNode.edit(); + httpRequestNode.setMethod("GET"); + httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-json'); + httpRequestNode.clickOk(); + + changeNodeCheck.edit(); + changeNodeCheck.ruleSet("payload", "msg", "headers.content-type", "msg", "1"); + changeNodeCheck.clickOk(); + + injectNode.connect(httpRequestNode); + httpRequestNode.connect(changeNodeCheck); + changeNodeCheck.connect(debugNode); + // The code for confirmation ends here. + + workspace.deploy(); + debugTab.open(); + injectNode.clickLeftButton(); + var messages = debugTab.getMessage(); + messages.indexOf('application/json').should.not.eql(-1); + }); + + it('serve a local file', function () { + var httpInNode = workspace.addNode("httpIn"); + var fileInNode = workspace.addNode("fileIn"); + var changeNode = workspace.addNode("change", 200, 100); + var httpResponseNode = workspace.addNode("httpResponse"); + + httpInNode.edit(); + httpInNode.setMethod("get"); + httpInNode.setUrl("/hello-file"); + httpInNode.clickOk(); + + fileInNode.edit(); + fileInNode.setFilename("test/resources/file-in-node/test.txt"); + fileInNode.setOutput(""); + fileInNode.clickOk(); + + changeNode.edit(); + changeNode.ruleSet("headers", "msg", "{}", "json"); + changeNode.addRule(); + changeNode.ruleSet("headers.content-type", "msg", "text/plain", "str", "2"); + changeNode.clickOk(); + + httpInNode.connect(fileInNode); + fileInNode.connect(changeNode); + changeNode.connect(httpResponseNode); + + // The code for confirmation starts from here. + var injectNode = workspace.addNode("inject", 0, 200); + var httpRequestNode = workspace.addNode("httpRequest"); + var debugNode = workspace.addNode("debug"); + + httpRequestNode.edit(); + httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-file'); + httpRequestNode.setMethod("GET"); + httpRequestNode.clickOk(); + + injectNode.connect(httpRequestNode); + httpRequestNode.connect(debugNode); + // The code for confirmation ends here. + + workspace.deploy(); + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().indexOf('Text file').should.not.eql(-1); + }); + + it('post raw data to a flow', function () { + var httpInNode = workspace.addNode("httpIn"); + var templateNode = workspace.addNode("template"); + var httpResponseNode = workspace.addNode("httpResponse"); + + httpInNode.edit(); + httpInNode.setMethod("post"); + httpInNode.setUrl("/hello-raw"); + httpInNode.clickOk(); + + templateNode.edit(); + templateNode.setSyntax("mustache"); + templateNode.setFormat("handlebars"); + templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>Hello {{ payload }}!</h1>\n</body>\n</html>"); + templateNode.clickOk(); + + httpInNode.connect(templateNode); + templateNode.connect(httpResponseNode); + + // The code for confirmation starts from here. + var injectNode = workspace.addNode("inject"); + var httpRequestNode = workspace.addNode("httpRequest"); + var debugNode = workspace.addNode("debug"); + + injectNode.edit(); + injectNode.setPayload("str", "Nick"); + injectNode.clickOk(); + + httpRequestNode.edit(); + httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-raw'); + httpRequestNode.setMethod("POST"); + httpRequestNode.clickOk(); + + injectNode.connect(httpRequestNode); + httpRequestNode.connect(debugNode); + // The code for confirmation ends here. + + workspace.deploy(); + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().indexOf('Hello Nick!').should.not.eql(-1); + }); + + it('post form data to a flow', function () { + var httpInNode = workspace.addNode("httpIn"); + var templateNode = workspace.addNode("template"); + var httpResponseNode = workspace.addNode("httpResponse"); + + httpInNode.edit(); + httpInNode.setMethod("post"); + httpInNode.setUrl("/hello-form"); + httpInNode.clickOk(); + + templateNode.edit(); + templateNode.setSyntax("mustache"); + templateNode.setFormat("handlebars"); + templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>Hello {{ payload.name }}!</h1>\n</body>\n</html>"); + templateNode.clickOk(); + + httpInNode.connect(templateNode); + templateNode.connect(httpResponseNode); + + // The code for confirmation starts from here. + var injectNode = workspace.addNode("inject", 0, 100); + var changeNode = workspace.addNode("change"); + var httpRequestNode = workspace.addNode("httpRequest"); + var debugNode = workspace.addNode("debug"); + + injectNode.edit(); + injectNode.setPayload("str", "name=Nick"); + injectNode.clickOk(); + + changeNode.edit(); + changeNode.ruleSet("headers", "msg", '{"content-type":"application/x-www-form-urlencoded"}', "json"); + changeNode.clickOk(); + + httpRequestNode.edit(); + httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-form'); + httpRequestNode.setMethod("POST"); + httpRequestNode.clickOk(); + + injectNode.connect(changeNode); + changeNode.connect(httpRequestNode); + httpRequestNode.connect(debugNode); + // The code for confirmation ends here. + + workspace.deploy(); + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().indexOf('Hello Nick!').should.not.eql(-1); + }); + + it('post JSON data to a flow', function () { + var httpInNode = workspace.addNode("httpIn"); + var templateNode = workspace.addNode("template"); + var httpResponseNode = workspace.addNode("httpResponse"); + + httpInNode.edit(); + httpInNode.setMethod("post"); + httpInNode.setUrl("/hello-json"); + httpInNode.clickOk(); + + templateNode.edit(); + templateNode.setSyntax("mustache"); + templateNode.setFormat("handlebars"); + templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>Hello {{ payload.name }}!</h1>\n</body>\n</html>"); + templateNode.clickOk(); + + httpInNode.connect(templateNode); + templateNode.connect(httpResponseNode); + + // The code for confirmation starts from here. + var injectNode = workspace.addNode("inject", 0, 100); + var changeNode = workspace.addNode("change"); + var httpRequestNode = workspace.addNode("httpRequest"); + var debugNode = workspace.addNode("debug"); + + injectNode.edit(); + injectNode.setPayload("json", '{"name":"Nick"}'); + injectNode.clickOk(); + + changeNode.edit(); + changeNode.ruleSet("headers", "msg", '{"content-type":"application/json"}', "json"); + changeNode.clickOk(); + + httpRequestNode.edit(); + httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-json'); + httpRequestNode.setMethod("POST"); + httpRequestNode.clickOk(); + + injectNode.connect(changeNode); + changeNode.connect(httpRequestNode); + httpRequestNode.connect(debugNode); + // The code for confirmation ends here. + + workspace.deploy(); + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().indexOf('Hello Nick!').should.not.eql(-1); + }); + + it('work with cookies', function () { + var httpInNodeFormat = workspace.addNode("httpIn"); + var functionNodeFormat = workspace.addNode("function", 240); + var templateNode = workspace.addNode("template", 400); + var httpResponseNode = workspace.addNode("httpResponse", 600); + + var httpInNodeAdd = workspace.addNode("httpIn", 0, 100); + var functionNodeAdd = workspace.addNode("function", 240); + var changeNode = workspace.addNode("change", 400); + + var httpInNodeClear = workspace.addNode("httpIn", 0, 200); + var functionNodeClear = workspace.addNode("function", 250); + + httpInNodeFormat.edit(); + httpInNodeFormat.setMethod("get"); + httpInNodeFormat.setUrl("/hello-cookie"); + httpInNodeFormat.clickOk(); + + functionNodeFormat.edit(); + functionNodeFormat.setFunction("msg.payload = JSON.stringify(msg.req.cookies,null,4);\nreturn msg;"); + functionNodeFormat.clickOk(); + + templateNode.edit(); + templateNode.setSyntax("mustache"); + templateNode.setFormat("handlebars"); + templateNode.setTemplate('<html>\n<head></head>\n<body>\n<h1>Cookies</h1>\n<p></p><a href="hello-cookie/add">Add a cookie</a> &bull; <a href="hello-cookie/clear">Clear cookies</a></p>\n<pre>{{ payload }}</pre>\n</body>\n</html>'); + templateNode.clickOk(); + + httpInNodeFormat.connect(functionNodeFormat); + functionNodeFormat.connect(templateNode); + templateNode.connect(httpResponseNode); + + httpInNodeAdd.edit(); + httpInNodeAdd.setMethod("get"); + httpInNodeAdd.setUrl("/hello-cookie/add"); + httpInNodeAdd.clickOk(); + + functionNodeAdd.edit(); + functionNodeAdd.setFunction('msg.cookies = { };\n msg.cookies["demo-"+(Math.floor(Math.random()*1000))] = Date.now();\nreturn msg;'); + functionNodeAdd.clickOk(); + + changeNode.edit(); + changeNode.ruleSet("statusCode", "msg", "302", "num"); + changeNode.addRule(); + changeNode.ruleSet("headers", "msg", "{}", "json", "2"); + changeNode.addRule(); + changeNode.ruleSet("headers.location", "msg", httpNodeRoot + "/hello-cookie", "str", "3"); + changeNode.clickOk(); + + httpInNodeAdd.connect(functionNodeAdd); + functionNodeAdd.connect(changeNode); + changeNode.connect(httpResponseNode); + + httpInNodeClear.edit(); + httpInNodeClear.setMethod("get"); + httpInNodeClear.setUrl("/hello-cookie/clear"); + httpInNodeClear.clickOk(); + + functionNodeClear.edit(); + functionNodeClear.setFunction("var cookieNames = Object.keys(msg.req.cookies).filter(function(cookieName) { return /^demo-/.test(cookieName);});\nmsg.cookies = {};\n\ncookieNames.forEach(function(cookieName) {\n msg.cookies[cookieName] = null;\n});\nreturn msg;\n"); + functionNodeClear.clickOk(); + + httpInNodeClear.connect(functionNodeClear); + functionNodeClear.connect(changeNode); + + workspace.deploy(); + // This case cannot be checked since http request node does not transfer cookies when redirected. + }); + }); +}); diff --git a/packages/connector/test/editor/specs/scenario/cookbook_httprequests_uispec.js b/packages/connector/test/editor/specs/scenario/cookbook_httprequests_uispec.js new file mode 100644 index 0000000..797b060 --- /dev/null +++ b/packages/connector/test/editor/specs/scenario/cookbook_httprequests_uispec.js @@ -0,0 +1,300 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require('when'); +var should = require('should'); +var fs = require('fs-extra'); + +var helper = require('../../editor_helper'); +var debugTab = require('../../pageobjects/editor/debugTab_page'); +var workspace = require('../../pageobjects/editor/workspace_page'); +var specUtil = require('../../pageobjects/util/spec_util_page'); + +var httpNodeRoot = '/api'; + +// https://cookbook.nodered.org/ +describe('cookbook', function () { + beforeEach(function () { + workspace.init(); + }); + + before(function () { + helper.startServer(); + }); + + after(function () { + helper.stopServer(); + }); + + describe('HTTP requests', function () { + it('simple get request', function () { + var injectNode = workspace.addNode('inject'); + var httpRequestNode = workspace.addNode('httpRequest'); + var htmlNode = workspace.addNode('html'); + var debugNode = workspace.addNode('debug'); + + httpRequestNode.edit(); + httpRequestNode.setMethod('GET'); + httpRequestNode.setUrl(helper.url()); + httpRequestNode.clickOk(); + + htmlNode.edit(); + htmlNode.setSelector('title'); + htmlNode.clickOk(); + + injectNode.connect(httpRequestNode); + httpRequestNode.connect(htmlNode); + htmlNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.eql('"Node-RED"'); + }); + + it('set the URL of a request', function () { + var injectNode = workspace.addNode('inject'); + var changeNode = workspace.addNode('change'); + var httpRequestNode = workspace.addNode('httpRequest'); + var debugNode = workspace.addNode('debug'); + + injectNode.edit(); + injectNode.setPayload('str', helper.url()); + injectNode.clickOk(); + + changeNode.edit(); + changeNode.ruleSet('url', 'msg', 'payload', 'msg'); + changeNode.clickOk(); + + injectNode.connect(changeNode); + changeNode.connect(httpRequestNode); + httpRequestNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.containEql('<title>Node-RED</title>'); + }); + + it('set the URL of a request using a template', function () { + var injectNode = workspace.addNode('inject'); + var changeNode = workspace.addNode('change'); + var httpRequestNode = workspace.addNode('httpRequest'); + var debugNode = workspace.addNode('debug'); + + injectNode.edit(); + injectNode.setPayload('str', 'settings'); + injectNode.clickOk(); + + changeNode.edit(); + changeNode.ruleSet('query', 'msg', 'payload', 'msg'); + changeNode.clickOk(); + + httpRequestNode.edit(); + httpRequestNode.setUrl(helper.url() + '/{{{query}}}'); + httpRequestNode.clickOk(); + + injectNode.connect(changeNode); + changeNode.connect(httpRequestNode); + httpRequestNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.containEql('httpNodeRoot'); + }); + + it('set the query string parameters', function () { + var injectNode = workspace.addNode('inject'); + var changeNode = workspace.addNode('change'); + var httpRequestNode = workspace.addNode('httpRequest'); + var debugNode = workspace.addNode('debug'); + + injectNode.edit(); + injectNode.setPayload('str', 'Nick'); + injectNode.clickOk(); + + changeNode.edit(); + changeNode.ruleSet('query', 'msg', 'payload', 'msg'); + changeNode.clickOk(); + + httpRequestNode.edit(); + httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/set-query?q={{{query}}}'); + httpRequestNode.clickOk(); + + injectNode.connect(changeNode); + changeNode.connect(httpRequestNode); + httpRequestNode.connect(debugNode); + + // The code for confirmation starts from here. + var httpInNode = workspace.addNode('httpIn', 0, 200); + var templateNode = workspace.addNode('template'); + var httpResponseNode = workspace.addNode('httpResponse'); + + httpInNode.edit(); + httpInNode.setMethod('get'); + httpInNode.setUrl('/set-query'); + httpInNode.clickOk(); + + templateNode.edit(); + templateNode.setSyntax('mustache'); + templateNode.setFormat('handlebars'); + templateNode.setTemplate('Hello {{req.query.q}}'); + templateNode.clickOk(); + + httpInNode.connect(templateNode); + templateNode.connect(httpResponseNode); + // The code for confirmation ends here. + + workspace.deploy(); + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.eql('"Hello Nick"'); + }); + + it('get a parsed JSON response', function () { + var injectNode = workspace.addNode('inject'); + var changeNodeSetPost = workspace.addNode('change'); + var httpRequestNode = workspace.addNode('httpRequest'); + var debugNode = workspace.addNode('debug'); + + injectNode.edit(); + injectNode.setPayload('str', 'json-response'); + injectNode.clickOk(); + + changeNodeSetPost.edit(); + changeNodeSetPost.ruleSet('post', 'msg', 'payload', 'msg'); + changeNodeSetPost.clickOk(); + + httpRequestNode.edit(); + httpRequestNode.setMethod('GET'); + var url = helper.url() + httpNodeRoot + '/{{post}}'; + httpRequestNode.setUrl(url); + httpRequestNode.setReturn('obj'); + httpRequestNode.clickOk(); + + debugNode.edit(); + debugNode.setOutput('payload.title'); + debugNode.clickOk(); + + injectNode.connect(changeNodeSetPost); + changeNodeSetPost.connect(httpRequestNode); + httpRequestNode.connect(debugNode); + + // The code for confirmation starts from here. + var httpInNode = workspace.addNode('httpIn', 0, 200); + var templateNode = workspace.addNode('template'); + var changeNodeSetHeader = workspace.addNode('change'); + var httpResponseNode = workspace.addNode('httpResponse'); + + httpInNode.edit(); + httpInNode.setMethod('get'); + httpInNode.setUrl('/json-response'); + httpInNode.clickOk(); + + templateNode.edit(); + templateNode.setSyntax('mustache'); + templateNode.setFormat('handlebars'); + templateNode.setTemplate('{"title": "Hello"}'); + templateNode.clickOk(); + + changeNodeSetHeader.edit(); + changeNodeSetHeader.ruleSet('headers', 'msg', '{"content-type":"application/json"}', 'json'); + changeNodeSetHeader.clickOk(); + + httpInNode.connect(templateNode); + templateNode.connect(changeNodeSetHeader); + changeNodeSetHeader.connect(httpResponseNode); + // The code for confirmation ends here. + + workspace.deploy(); + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.eql('"Hello"'); + }); + + it('get a binary response', function () { + var injectNode = workspace.addNode('inject'); + var httpRequestNode = workspace.addNode('httpRequest'); + var debugNode = workspace.addNode('debug'); + + httpRequestNode.edit(); + httpRequestNode.setMethod('GET'); + httpRequestNode.setUrl(helper.url() + '/settings'); + httpRequestNode.setReturn('bin'); + httpRequestNode.clickOk(); + + injectNode.connect(httpRequestNode); + httpRequestNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + injectNode.clickLeftButton(); + + debugTab.getMessage().should.eql(['123', '34', '104', '116', '116', '112', '78', '111', '100', '101']); + }); + + it('set a request header', function () { + var injectNode = workspace.addNode('inject'); + var functionNode = workspace.addNode('function'); + var httpRequestNode = workspace.addNode('httpRequest'); + var debugNode = workspace.addNode('debug'); + + functionNode.edit(); + functionNode.setFunction('msg.payload = "data to post";\nreturn msg;'); + functionNode.clickOk(); + + httpRequestNode.edit(); + httpRequestNode.setMethod('POST'); + var url = helper.url() + httpNodeRoot + '/set-header'; + httpRequestNode.setUrl(url); + httpRequestNode.clickOk(); + + injectNode.connect(functionNode); + functionNode.connect(httpRequestNode); + httpRequestNode.connect(debugNode); + + // The code for confirmation starts from here. + var httpInNode = workspace.addNode('httpIn', 0, 200); + var templateNode = workspace.addNode('template'); + var httpResponseNode = workspace.addNode('httpResponse'); + + httpInNode.edit(); + httpInNode.setMethod('post'); + httpInNode.setUrl('/set-header'); + httpInNode.clickOk(); + + templateNode.edit(); + templateNode.setSyntax('mustache'); + templateNode.setFormat('handlebars'); + templateNode.setTemplate('{{ payload }}'); + templateNode.clickOk(); + + httpInNode.connect(templateNode); + templateNode.connect(httpResponseNode); + // The code for confirmation ends here. + + workspace.deploy(); + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.eql('"data to post"'); + }); + }); +}); diff --git a/packages/connector/test/editor/specs/scenario/cookbook_messages_uispec.js b/packages/connector/test/editor/specs/scenario/cookbook_messages_uispec.js new file mode 100644 index 0000000..78facbc --- /dev/null +++ b/packages/connector/test/editor/specs/scenario/cookbook_messages_uispec.js @@ -0,0 +1,142 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require('when'); +var should = require('should'); +var fs = require('fs-extra'); + +var helper = require('../../editor_helper'); +var debugTab = require('../../pageobjects/editor/debugTab_page'); +var workspace = require('../../pageobjects/editor/workspace_page'); +var specUtil = require('../../pageobjects/util/spec_util_page'); + +var httpNodeRoot = '/api'; + +// https://cookbook.nodered.org/ +describe('cookbook', function () { + beforeEach(function () { + workspace.init(); + }); + + before(function () { + helper.startServer(); + }); + + after(function () { + helper.stopServer(); + }); + + describe('messages', function () { + it('set a message property to a fixed value', function () { + var injectNode = workspace.addNode('inject'); + var changeNode = workspace.addNode('change'); + var debugNode = workspace.addNode('debug'); + + changeNode.edit(); + changeNode.ruleSet('payload', 'msg', 'Hello World!'); + changeNode.clickOk(); + + injectNode.connect(changeNode); + changeNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.eql('"Hello World!"'); + }); + + it('delete a message property', function () { + var injectNode = workspace.addNode('inject'); + var changeNode = workspace.addNode('change'); + var debugNode = workspace.addNode('debug'); + + changeNode.edit(); + changeNode.ruleDelete(); + changeNode.clickOk(); + + injectNode.connect(changeNode); + changeNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.eql('undefined'); + }); + + it('move a message property', function () { + var injectNode = workspace.addNode('inject'); + var changeNode = workspace.addNode('change'); + var debugNode = workspace.addNode('debug'); + + injectNode.edit(); + injectNode.setTopic('Hello'); + injectNode.clickOk(); + + changeNode.edit(); + changeNode.ruleMove('topic', 'msg', 'payload', 'msg'); + changeNode.clickOk(); + + injectNode.connect(changeNode); + changeNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.eql('"Hello"'); + }); + + it('map a property between different numeric ranges', function () { + var injectNode1 = workspace.addNode('inject'); + var injectNode2 = workspace.addNode('inject', 0, 100); + var injectNode3 = workspace.addNode('inject', 0, 200); + var rangeNode = workspace.addNode('range', 200, 100); + var debugNode = workspace.addNode('debug', 400); + + injectNode1.edit(); + injectNode1.setPayload('num', 0); + injectNode1.clickOk(); + injectNode2.edit(); + injectNode2.setPayload('num', 512); + injectNode2.clickOk(); + injectNode3.edit(); + injectNode3.setPayload('num', 1023); + injectNode3.clickOk(); + + rangeNode.edit(); + rangeNode.setAction('clamp'); + rangeNode.setRange(0, 1023, 0, 5); + rangeNode.clickOk(); + + injectNode1.connect(rangeNode); + injectNode2.connect(rangeNode); + injectNode3.connect(rangeNode); + rangeNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + injectNode1.clickLeftButton(); + debugTab.getMessage(1).should.eql('0'); + injectNode2.clickLeftButton(); + debugTab.getMessage(2).should.eql('2.5024437927663734'); + injectNode3.clickLeftButton(); + debugTab.getMessage(3).should.eql('5'); + }); + }); +}); diff --git a/packages/connector/test/editor/specs/scenario/cookbook_mqtt_uispec.js b/packages/connector/test/editor/specs/scenario/cookbook_mqtt_uispec.js new file mode 100644 index 0000000..b68170e --- /dev/null +++ b/packages/connector/test/editor/specs/scenario/cookbook_mqtt_uispec.js @@ -0,0 +1,224 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require('when'); +var should = require("should"); +var fs = require('fs-extra'); + +var helper = require("../../editor_helper"); +var debugTab = require('../../pageobjects/editor/debugTab_page'); +var workspace = require('../../pageobjects/editor/workspace_page'); +var specUtil = require('../../pageobjects/util/spec_util_page'); + +var httpNodeRoot = "/api"; + +var mqttServer; +var mosca = require('mosca'); +var moscaSettings = { + port: parseInt(Math.random() * 16383 + 49152), + persistence: { + // Needs for retaining messages. + factory: mosca.persistence.Memory + } +}; + +// https://cookbook.nodered.org/ +describe('cookbook', function () { + beforeEach(function () { + workspace.init(); + }); + + before(function () { + browser.call(function () { + return new Promise(function (resolve, reject) { + mqttServer = new mosca.Server(moscaSettings, function (err) { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + }); + helper.startServer(); + }); + + after(function () { + browser.call(function () { + return new Promise(function (resolve, reject) { + mqttServer.close(function () { + resolve(); + }); + }); + }); + helper.stopServer(); + }); + + describe('MQTT', function () { + it('Add an MQTT broker to prepare for UI test', function () { + var mqttOutNode = workspace.addNode("mqttOut"); + + mqttOutNode.edit(); + mqttOutNode.mqttBrokerNode.edit(); + mqttOutNode.mqttBrokerNode.setServer("localhost", moscaSettings.port); + mqttOutNode.mqttBrokerNode.clickOk(); + mqttOutNode.clickOk(); + + workspace.deploy(); + }); + + it('Connect to an MQTT broker', function () { + var injectNode = workspace.addNode("inject"); + var mqttOutNode = workspace.addNode("mqttOut"); + + var mqttInNode = workspace.addNode("mqttIn", 0, 100); + var debugNode = workspace.addNode("debug"); + + injectNode.edit(); + injectNode.setPayload("num", 22); + injectNode.clickOk(); + + mqttOutNode.edit(); + mqttOutNode.setTopic("sensors/livingroom/temp"); + mqttOutNode.clickOk(); + + injectNode.connect(mqttOutNode); + + mqttInNode.edit(); + mqttInNode.setTopic("sensors/livingroom/temp"); + mqttInNode.setQoS("2"); + mqttInNode.clickOk(); + + mqttInNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.eql('"22"'); + }); + + // skip this case since it is same as other cases. + it.skip('Publish messages to a topic'); + + it('Set the topic of a published message', function () { + var injectNode = workspace.addNode("inject"); + var mqttOutNode = workspace.addNode("mqttOut"); + + injectNode.edit(); + injectNode.setPayload("num", 22); + injectNode.setTopic("sensors/kitchen/temperature"); + injectNode.clickOk(); + + mqttOutNode.edit(); + mqttOutNode.clickOk(); + + injectNode.connect(mqttOutNode); + + // The code for confirmation starts from here. + var mqttInNode = workspace.addNode("mqttIn", 0, 100); + var debugNode = workspace.addNode("debug"); + + mqttInNode.edit(); + mqttInNode.setTopic("sensors/kitchen/temperature"); + mqttInNode.clickOk(); + + mqttInNode.connect(debugNode); + // The code for confirmation ends here. + + workspace.deploy(); + + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.eql('"22"'); + }); + + it('Publish a retained message to a topic', function () { + var injectNode = workspace.addNode("inject"); + var mqttOutNode = workspace.addNode("mqttOut"); + + injectNode.edit(); + injectNode.setPayload("num", 22); + injectNode.clickOk(); + + mqttOutNode.edit(); + mqttOutNode.setTopic("sensors/livingroom/temp"); + mqttOutNode.setRetain("true"); + mqttOutNode.clickOk(); + + injectNode.connect(mqttOutNode); + + workspace.deploy(); + debugTab.open(); + injectNode.clickLeftButton(); + + // The code for confirmation starts from here. + var mqttInNode = workspace.addNode("mqttIn", 0, 100); + var debugNode = workspace.addNode("debug"); + + mqttInNode.edit(); + mqttInNode.setTopic("sensors/livingroom/temp"); + mqttInNode.clickOk(); + + mqttInNode.connect(debugNode); + // The code for confirmation ends here. + + workspace.deploy(); + debugTab.open(true); + debugTab.getMessage().should.eql('"22"'); + }); + + // skip this case since it is same as other cases. + it.skip('Subscribe to a topic'); + + it('Receive a parsed JSON message', function () { + var injectNode = workspace.addNode("inject"); + var mqttOutNode = workspace.addNode("mqttOut"); + + var mqttInNode = workspace.addNode("mqttIn", 0, 100); + var jsonNode = workspace.addNode("json"); + var debugNode = workspace.addNode("debug"); + + injectNode.edit(); + injectNode.setPayload("json", '{"sensor_id": 1234, "temperature": 13 }'); + injectNode.clickOk(); + + mqttOutNode.edit(); + mqttOutNode.setTopic("sensors/livingroom/temp"); + mqttOutNode.clickOk(); + + injectNode.connect(mqttOutNode); + + mqttInNode.edit(); + mqttInNode.setTopic("sensors/#"); + mqttInNode.setQoS("2"); + mqttInNode.clickOk(); + + jsonNode.edit(); + jsonNode.setProperty("payload"); + jsonNode.clickOk(); + + mqttInNode.connect(jsonNode); + jsonNode.connect(debugNode); + + workspace.deploy(); + + debugTab.open(); + injectNode.clickLeftButton(); + debugTab.getMessage().should.eql(['1234', '13']); + }); + }); +}); diff --git a/packages/connector/test/editor/wdio.conf.js b/packages/connector/test/editor/wdio.conf.js new file mode 100644 index 0000000..4e5a602 --- /dev/null +++ b/packages/connector/test/editor/wdio.conf.js @@ -0,0 +1,338 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var browserstack = require('browserstack-local'); +exports.config = { + + // + // ================== + // Specify Test Files + // ================== + // Define which test specs should run. The pattern is relative to the directory + // from which `wdio` was called. Notice that, if you are calling `wdio` from an + // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working + // directory is where your package.json resides, so `wdio` will be called from there. + // + specs: [ + './test/editor/**/*_uispec.js' + ], + // Patterns to exclude. + exclude: [ + // 'path/to/excluded/files' + ], + // + // ============ + // Capabilities + // ============ + // Define your capabilities here. WebdriverIO can run multiple capabilities at the same + // time. Depending on the number of capabilities, WebdriverIO launches several test + // sessions. Within your capabilities you can overwrite the spec and exclude options in + // order to group specific specs to a specific capability. + // + // First, you can define how many instances should be started at the same time. Let's + // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have + // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec + // files and you set maxInstances to 10, all spec files will get tested at the same time + // and 30 processes will get spawned. The property handles how many capabilities + // from the same test should run tests. + // + // maxInstances: 10, + // + // If you have trouble getting all important capabilities together, check out the + // Sauce Labs platform configurator - a great tool to configure your capabilities: + // https://docs.saucelabs.com/reference/platforms-configurator + // + // capabilities: [{ + // maxInstances can get overwritten per capability. So if you have an in-house Selenium + // grid with only 5 firefox instances available you can make sure that not more than + // 5 instances get started at a time. + // maxInstances: 5, + // + // browserName: 'firefox' + // }], + // + // =================== + // Test Configurations + // =================== + // Define all options that are relevant for the WebdriverIO instance here + // + // By default WebdriverIO commands are executed in a synchronous way using + // the wdio-sync package. If you still want to run your tests in an async way + // e.g. using promises you can set the sync option to false. + sync: true, + // + // Level of logging verbosity: silent | verbose | command | data | result | error + logLevel: 'silent', + // + // Enables colors for log output. + coloredLogs: true, + // + // Warns when a deprecated command is used + deprecationWarnings: false, + // + // If you only want to run your tests until a specific amount of tests have failed use + // bail (default is 0 - don't bail, run all tests). + bail: 0, + // + // Saves a screenshot to a given path if a command fails. + screenshotPath: './test/errorShots/', + // + // Set a base URL in order to shorten url command calls. If your `url` parameter starts + // with `/`, the base url gets prepended, not including the path portion of your baseUrl. + // If your `url` parameter starts without a scheme or `/` (like `some/path`), the base url + // gets prepended directly. + baseUrl: 'http://localhost', + // + // Default timeout for all waitFor* commands. + waitforTimeout: 20000, + // + // Default timeout in milliseconds for request + // if Selenium Grid doesn't send response + connectionRetryTimeout: 90000, + // + // Default request retries count + connectionRetryCount: 3, + // + // Initialize the browser instance with a WebdriverIO plugin. The object should have the + // plugin name as key and the desired plugin options as properties. Make sure you have + // the plugin installed before running any tests. The following plugins are currently + // available: + // WebdriverCSS: https://github.com/webdriverio/webdrivercss + // WebdriverRTC: https://github.com/webdriverio/webdriverrtc + // Browserevent: https://github.com/webdriverio/browserevent + // plugins: { + // webdrivercss: { + // screenshotRoot: 'my-shots', + // failedComparisonsRoot: 'diffs', + // misMatchTolerance: 0.05, + // screenWidth: [320,480,640,1024] + // }, + // webdriverrtc: {}, + // browserevent: {} + // }, + // + // Test runner services + // Services take over a specific job you don't want to take care of. They enhance + // your test setup with almost no effort. Unlike plugins, they don't add new + // commands. Instead, they hook themselves up into the test process. + //services: ['chromedriver'], + // + // Framework you want to run your specs with. + // The following are supported: Mocha, Jasmine, and Cucumber + // see also: http://webdriver.io/guide/testrunner/frameworks.html + // + // Make sure you have the wdio adapter package for the specific framework installed + // before running any tests. + framework: 'mocha', + // + // Test reporter for stdout. + // The only one supported by default is 'dot' + // see also: http://webdriver.io/guide/reporters/dot.html + reporters: ['spec'], + + // + // Options to be passed to Mocha. + // See the full list at http://mochajs.org/ + mochaOpts: { + timeout: 1000000, + ui: 'bdd' + }, + // + // ===== + // Hooks + // ===== + // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance + // it and to build services around it. You can either apply a single function or an array of + // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got + // resolved to continue. + /** + * Gets executed once before all workers get launched. + * @param {Object} config wdio configuration object + * @param {Array.<Object>} capabilities list of capabilities details + */ + onPrepare: function (config, capabilities) { + if (process.env.BROWSERSTACK) { + return new Promise(function (resolve, reject) { + var options = { key: exports.config.key }; + var proxy = process.env.http_proxy || process.env.HTTP_PROXY; + if (proxy) { + var proxyConfigs = proxy.match(/^(https?):\/\/(([^:@\/]+):([^:@\/]+)@)?([^:@\/]+)(:([^:@\/]+))?\/?$/); + if (proxyConfigs) { + var protocol = proxyConfigs[1]; + var user = proxyConfigs[3]; + var pass = proxyConfigs[4]; + var host = proxyConfigs[5]; + var port = proxyConfigs[7]; + if (!port) { + if (protocol === 'http') { + port = 80; + } else if (protocol === 'https') { + port = 443; + } + } + if (host) { options.proxyHost = host; } + if (port) { options.proxyPort = port; } + if (user) { options.proxyUser = user; } + if (pass) { options.proxyPass = pass; } + } else { + reject('error in parsing the environment variable, http_proxy'); + } + } + exports.bs_local = new browserstack.Local(); + exports.bs_local.start(options, function (error) { + if (error) { + return reject(error); + } + resolve(); + }); + }); + } + }, + /** + * Gets executed just before initialising the webdriver session and test framework. It allows you + * to manipulate configurations depending on the capability or spec. + * @param {Object} config wdio configuration object + * @param {Array.<Object>} capabilities list of capabilities details + * @param {Array.<String>} specs List of spec file paths that are to be run + */ + // beforeSession: function (config, capabilities, specs) { + // }, + /** + * Gets executed before test execution begins. At this point you can access to all global + * variables like `browser`. It is the perfect place to define custom commands. + * @param {Array.<Object>} capabilities list of capabilities details + * @param {Array.<String>} specs List of spec file paths that are to be run + */ + // before: function (capabilities, specs) { + // }, + /** + * Runs before a WebdriverIO command gets executed. + * @param {String} commandName hook command name + * @param {Array} args arguments that command would receive + */ + // beforeCommand: function (commandName, args) { + // }, + + /** + * Hook that gets executed before the suite starts + * @param {Object} suite suite details + */ + // beforeSuite: function (suite) { + // }, + /** + * Function to be executed before a test (in Mocha/Jasmine) or a step (in Cucumber) starts. + * @param {Object} test test details + */ + // beforeTest: function (test) { + // }, + /** + * Hook that gets executed _before_ a hook within the suite starts (e.g. runs before calling + * beforeEach in Mocha) + */ + // beforeHook: function () { + // }, + /** + * Hook that gets executed _after_ a hook within the suite ends (e.g. runs after calling + * afterEach in Mocha) + */ + // afterHook: function () { + // }, + /** + * Function to be executed after a test (in Mocha/Jasmine) or a step (in Cucumber) ends. + * @param {Object} test test details + */ + // afterTest: function (test) { + // }, + /** + * Hook that gets executed after the suite has ended + * @param {Object} suite suite details + */ + // afterSuite: function (suite) { + // }, + + /** + * Runs after a WebdriverIO command gets executed + * @param {String} commandName hook command name + * @param {Array} args arguments that command would receive + * @param {Number} result 0 - command success, 1 - command error + * @param {Object} error error object if any + */ + // afterCommand: function (commandName, args, result, error) { + // }, + /** + * Gets executed after all tests are done. You still have access to all global variables from + * the test. + * @param {Number} result 0 - test pass, 1 - test fail + * @param {Array.<Object>} capabilities list of capabilities details + * @param {Array.<String>} specs List of spec file paths that ran + */ + // after: function (result, capabilities, specs) { + // }, + /** + * Gets executed right after terminating the webdriver session. + * @param {Object} config wdio configuration object + * @param {Array.<Object>} capabilities list of capabilities details + * @param {Array.<String>} specs List of spec file paths that ran + */ + // afterSession: function (config, capabilities, specs) { + // }, + /** + * Gets executed after all workers got shut down and the process is about to exit. + * @param {Object} exitCode 0 - success, 1 - fail + * @param {Object} config wdio configuration object + * @param {Array.<Object>} capabilities list of capabilities details + */ + onComplete: function(exitCode, config, capabilities) { + if (process.env.BROWSERSTACK) { + exports.bs_local.stop(function () {}); + } + } +}; + +if (process.env.BROWSERSTACK) { + exports.config.maxInstances = 1; + if (process.env.BROWSERSTACK_USERNAME && process.env.BROWSERSTACK_ACCESS_KEY) { + exports.config.user = process.env.BROWSERSTACK_USERNAME; + exports.config.key = process.env.BROWSERSTACK_ACCESS_KEY; + } else { + console.log('You need to set the following environment variables.'); + console.log('BROWSERSTACK_USERNAME=<BrowserStack user name>'); + console.log('BROWSERSTACK_ACCESS_KEY=<BrowserStack access key>'); + } + exports.config.services = ['browserstack']; + var capabilities = []; + capabilities.push({ os: 'Windows', os_version: '10', browser: 'Chrome', resolution: '1920x1080', 'browserstack.local': true }); + capabilities.push({ os: 'Windows', os_version: '10', browser: 'Firefox', resolution: '1920x1080', 'browserstack.local': true }); + capabilities.push({ os: 'OS X', os_version: 'Catalina', browser: 'Chrome', resolution: '1920x1080', 'browserstack.local': true }); + capabilities.push({ os: 'OS X', os_version: 'Catalina', browser: 'Firefox', resolution: '1920x1080', 'browserstack.local': true }); + exports.config.capabilities = capabilities; +} else { + exports.config.maxInstances = 10; + exports.config.port = 9515; + exports.config.path = '/'; + exports.config.services = ['chromedriver']; + exports.config.capabilities = [{ + maxInstances: 2, + browserName: 'chrome', + 'goog:chromeOptions': { + args: process.env.NODE_RED_NON_HEADLESS + // Runs tests with opening a browser. + ? ['--disable-gpu', '--no-sandbox'] + // Runs tests without opening a browser. + : ['--headless', '--disable-gpu', 'window-size=1920,1080', '--no-sandbox'] + } + }]; +} diff --git a/packages/connector/test/nodes/core/common/20-inject_spec.js b/packages/connector/test/nodes/core/common/20-inject_spec.js new file mode 100644 index 0000000..ea78d0f --- /dev/null +++ b/packages/connector/test/nodes/core/common/20-inject_spec.js @@ -0,0 +1,528 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var injectNode = require("nr-test-utils").require("@node-red/nodes/core/common/20-inject.js"); +var Context = require("nr-test-utils").require("@node-red/runtime/lib/nodes/context"); +var helper = require("node-red-node-test-helper"); + +describe('inject node', function() { + + beforeEach(function(done) { + helper.startServer(done); + }); + + function initContext(done) { + Context.init({ + contextStorage: { + memory0: { + module: "memory" + }, + memory1: { + module: "memory" + } + } + }); + Context.load().then(function () { + done(); + }); + } + + afterEach(function(done) { + helper.unload().then(function () { + return Context.clean({allNodes: {}}); + }).then(function () { + return Context.close(); + }).then(function () { + helper.stopServer(done); + }); + }); + + function basicTest(type, val, rval) { + it('inject value ('+type+')', function (done) { + var flow = [{id: "n1", type: "inject", topic: "t1", payload: val, payloadType: type, wires: [["n2"]], z: "flow"}, + {id: "n2", type: "helper"}]; + helper.load(injectNode, flow, function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function (msg) { + try { + msg.should.have.property("topic", "t1"); + if (rval) { + msg.should.have.property("payload"); + should.deepEqual(msg.payload, rval); + } + else { + msg.should.have.property("payload", val); + } + done(); + } catch (err) { + done(err); + } + }); + n1.receive({}); + }); + }); + } + + basicTest("num", 10); + basicTest("str", "10"); + basicTest("bool", true); + var val_json = '{ "x":"vx", "y":"vy", "z":"vz" }'; + basicTest("json", val_json, JSON.parse(val_json)); + var val_buf = "[1,2,3,4,5]"; + basicTest("bin", val_buf, Buffer.from(JSON.parse(val_buf))); + + it('inject value of environment variable ', function (done) { + var flow = [{id: "n1", type: "inject", topic: "t1", payload: "NR_TEST", payloadType: "env", wires: [["n2"]], z: "flow"}, + {id: "n2", type: "helper"}]; + helper.load(injectNode, flow, function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function (msg) { + try { + msg.should.have.property("topic", "t1"); + msg.should.have.property("payload", "foo"); + done(); + } catch (err) { + done(err); + } + }); + process.env.NR_TEST = 'foo'; + n1.receive({}); + }); + }); + + it('sets the value of flow context property', function (done) { + var flow = [{id: "n1", type: "inject", topic: "t1", payload: "flowValue", payloadType: "flow", wires: [["n2"]], z: "flow"}, + {id: "n2", type: "helper"}]; + helper.load(injectNode, flow, function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function (msg) { + try { + msg.should.have.property("topic", "t1"); + msg.should.have.property("payload", "changeMe"); + done(); + } catch (err) { + done(err); + } + }); + n1.context().flow.set("flowValue", "changeMe"); + n1.receive({}); + }); + }); + + it('sets the value of persistable flow context property', function (done) { + var flow = [{id: "n1", type: "inject", topic: "t1", payload: "#:(memory0)::flowValue", payloadType: "flow", wires: [["n2"]], z: "flow"}, + {id: "n2", type: "helper"}]; + helper.load(injectNode, flow, function () { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function (msg) { + try { + msg.should.have.property("topic", "t1"); + msg.should.have.property("payload", "changeMe"); + done(); + } catch (err) { + done(err); + } + }); + n1.context().flow.set("flowValue", "changeMe", "memory0", function (err) { + n1.receive({}); + }); + }); + }); + }); + + it('sets the value of two persistable flow context property', function (done) { + var flow = [{id: "n0", z: "flow", type: "inject", topic: "t0", payload: "#:(memory0)::val", payloadType: "flow", wires: [["n2"]]}, + {id: "n1", z: "flow", type: "inject", topic: "t1", payload: "#:(memory1)::val", payloadType: "flow", wires: [["n2"]]}, + {id: "n2", z: "flow", type: "helper"}]; + helper.load(injectNode, flow, function () { + initContext(function () { + var n0 = helper.getNode("n0"); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function (msg) { + try { + msg.should.have.property("topic"); + if (msg.topic === "t0") { + msg.should.have.property("payload", "foo"); + } + else if (msg.topic === "t1") { + msg.should.have.property("payload", "bar"); + } + else { + done(new Error("unexpected message")); + } + count++; + if (count === 2) { + done(); + } + } catch (err) { + done(err); + } + }); + var global = n0.context().flow; + global.set("val", "foo", "memory0", function (err) { + global.set("val", "bar", "memory1", function (err) { + n0.receive({}); + n1.receive({}); + }); + }); + }); + }); + }); + + it('sets the value of global context property', function (done) { + var flow = [{id: "n1", type: "inject", topic: "t1", payload: "globalValue", payloadType: "global", wires: [["n2"]]}, + {id: "n2", type: "helper"}]; + helper.load(injectNode, flow, function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function (msg) { + try { + msg.should.have.property("topic", "t1"); + msg.should.have.property("payload", "changeMe"); + done(); + } catch (err) { + done(err); + } + }); + n1.context().global.set("globalValue", "changeMe"); + n1.receive({}); + }); + }); + + it('sets the value of persistable global context property', function (done) { + var flow = [{id: "n1", z: "flow", type: "inject", topic: "t1", payload: "#:(memory1)::val", payloadType: "global", wires: [["n2"]]}, + {id: "n2", z: "flow", type: "helper"}]; + helper.load(injectNode, flow, function () { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function (msg) { + try { + msg.should.have.property("topic", "t1"); + msg.should.have.property("payload", "foo"); + done(); + } catch (err) { + done(err); + } + }); + var global = n1.context().global; + global.set("val", "foo", "memory1", function (err) { + n1.receive({}); + }); + }); + }); + }); + + it('sets the value of two persistable global context property', function (done) { + var flow = [{id: "n0", z: "flow", type: "inject", topic: "t0", payload: "#:(memory0)::val", payloadType: "global", wires: [["n2"]]}, + {id: "n1", z: "flow", type: "inject", topic: "t1", payload: "#:(memory1)::val", payloadType: "global", wires: [["n2"]]}, + {id: "n2", z: "flow", type: "helper"}]; + helper.load(injectNode, flow, function () { + initContext(function () { + var n0 = helper.getNode("n0"); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function (msg) { + try { + msg.should.have.property("topic"); + if (msg.topic === "t0") { + msg.should.have.property("payload", "foo"); + } + else if (msg.topic === "t1") { + msg.should.have.property("payload", "bar"); + } + else { + done(new Error("unexpected message")); + } + count++; + if (count === 2) { + done(); + } + } catch (err) { + done(err); + } + }); + var global = n0.context().global; + global.set("val", "foo", "memory0", function (err) { + global.set("val", "bar", "memory1", function (err) { + n0.receive({}); + n1.receive({}); + }); + }); + }); + }); + }); + + it('sets the value of persistable flow & global context property', function (done) { + var flow = [{id: "n0", z: "flow", type: "inject", topic: "t0", payload: "#:(memory0)::val", payloadType: "flow", wires: [["n2"]]}, + {id: "n1", z: "flow", type: "inject", topic: "t1", payload: "#:(memory1)::val", payloadType: "global", wires: [["n2"]]}, + {id: "n2", z: "flow", type: "helper"}]; + helper.load(injectNode, flow, function () { + initContext(function () { + var n0 = helper.getNode("n0"); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function (msg) { + try { + msg.should.have.property("topic"); + if (msg.topic === "t0") { + msg.should.have.property("payload", "foo"); + } + else if (msg.topic === "t1") { + msg.should.have.property("payload", "bar"); + } + else { + done(new Error("unexpected message")); + } + count++; + if (count === 2) { + done(); + } + } catch (err) { + done(err); + } + }); + var context = n0.context(); + var flow = context.flow; + var global = context.global; + flow.set("val", "foo", "memory0", function (err) { + global.set("val", "bar", "memory1", function (err) { + n0.receive({}); + n1.receive({}); + }); + }); + }); + }); + }); + + it('sets the value of two persistable global context property', function (done) { + var flow = [{id: "n0", z: "flow", type: "inject", topic: "t0", payload: "#:(memory0)::val", payloadType: "global", wires: [["n2"]]}, + {id: "n1", z: "flow", type: "inject", topic: "t1", payload: "#:(memory1)::val", payloadType: "global", wires: [["n2"]]}, + {id: "n2", z: "flow", type: "helper"}]; + helper.load(injectNode, flow, function () { + initContext(function () { + var n0 = helper.getNode("n0"); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function (msg) { + try { + msg.should.have.property("topic"); + if (msg.topic === "t0") { + msg.should.have.property("payload", "foo"); + } + else if (msg.topic === "t1") { + msg.should.have.property("payload", "bar"); + } + else { + done(new Error("unexpected message")); + } + count++; + if (count === 2) { + done(); + } + } catch (err) { + done(err); + } + }); + var global = n0.context().global; + global.set("val", "foo", "memory0", function (err) { + global.set("val", "bar", "memory1", function (err) { + n0.receive({}); + n1.receive({}); + }); + }); + }); + }); + }); + it('should inject once with default delay property', function(done) { + helper.load(injectNode, [{id:"n1", type:"inject", topic: "t1", + payload:"",payloadType:"date", + once: true, wires:[["n2"]] }, + {id:"n2", type:"helper"}], + function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('onceDelay', 100); + done(); + }); + }); + + it('should inject once with default delay', function(done) { + var timestamp = new Date(); + timestamp.setSeconds(timestamp.getSeconds() + 1); + + helper.load(injectNode, [{id:"n1", type:"inject", topic: "t1", + payload:"",payloadType:"date", + once: true, wires:[["n2"]] }, + {id:"n2", type:"helper"}], + function() { + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 't1'); + msg.should.have.property('payload'); + should(msg.payload).be.lessThan(timestamp.getTime()); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + + it('should inject once with 500 msec. delay', function(done) { + helper.load(injectNode, [{id:"n1", type:"inject", topic: "t1", + payload:"",payloadType:"date", + once: true, onceDelay: 0.5, wires:[["n2"]] }, + {id:"n2", type:"helper"}], + function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('onceDelay', 500); + done(); + }); + }); + + it('should inject once with delay of two seconds', function(done) { + this.timeout(2700); // have to wait for the inject with delay of two seconds + + var timestamp = new Date(); + timestamp.setSeconds(timestamp.getSeconds() + 1); + + helper.load(injectNode, [{id:"n1", type:"inject", topic: "t1", + payload:"",payloadType:"date", + once: true, onceDelay: 2, wires:[["n2"]] }, + {id:"n2", type:"helper"}], + function() { + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 't1'); + should(msg.payload).be.greaterThan(timestamp.getTime()); + done(); + }); + }); + }); + + it('should inject repeatedly', function(done) { + + helper.load(injectNode, [{id:"n1", type:"inject", + payload:"payload", topic: "t2", + repeat: 0.2, wires:[["n2"]] }, + {id:"n2", type:"helper"}], + function() { + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + msg.should.have.property('topic', 't2'); + msg.should.have.property('payload', 'payload'); + count += 1; + if (count > 2) { + helper.clearFlows().then(function() { + done(); + }); + } + }); + }); + }); + + it('should inject once with delay of two seconds and repeatedly', function(done) { + var timestamp = new Date(); + timestamp.setSeconds(timestamp.getSeconds() + 1); + + helper.load(injectNode, [{id:"n1", type:"inject", topic: "t1", + payload:"",payloadType:"date", repeat: 0.2, + once: true, onceDelay: 1.2, wires:[["n2"]] }, + {id:"n2", type:"helper"}], + function() { + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + msg.should.have.property('topic', 't1'); + should(msg.payload).be.greaterThan(timestamp.getTime()); + count += 1; + if (count > 2) { + helper.clearFlows().then(function() { + done(); + }); + } + }); + }); + }); + + it('should inject with cron', function(done) { + helper.load(injectNode, [{id:"n1", type:"inject", + payloadType:"date", topic: "t3", + crontab: "* * * * * *", wires:[["n3"]] }, + {id:"n3", type:"helper"}], + function() { + var n3 = helper.getNode("n3"); + n3.on("input", function(msg) { + msg.should.have.property('topic', 't3'); + msg.should.have.property('payload').be.a.Number(); + helper.clearFlows().then(function() { + done(); + }); + }); + }); + }); + + describe('post', function() { + it('should inject message', function(done) { + helper.load(injectNode, + [{id:"n1", type:"inject", + payloadType:"str", topic: "t4",payload:"hello", + wires:[["n4"]] }, + { id:"n4", type:"helper"}], function() { + var n4 = helper.getNode("n4"); + n4.on("input", function(msg) { + msg.should.have.property('topic', 't4'); + msg.should.have.property('payload', 'hello'); + helper.clearFlows().then(function() { + done(); + }); + }); + try { + helper.request() + .post('/inject/n1') + .expect(200).end(function(err) { + if (err) { + console.log(err); + return helper.clearFlows() + .then(function () { + done(err); + }); + } + }); + } catch(err) { + done(err); + } + }); + }); + + it('should fail for invalid node', function(done) { + helper.request().post('/inject/invalid').expect(404).end(done); + }); + }); +}); diff --git a/packages/connector/test/nodes/core/common/21-debug_spec.js b/packages/connector/test/nodes/core/common/21-debug_spec.js new file mode 100644 index 0000000..bdff797 --- /dev/null +++ b/packages/connector/test/nodes/core/common/21-debug_spec.js @@ -0,0 +1,635 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var debugNode = require("nr-test-utils").require("@node-red/nodes/core/common/21-debug.js"); +var helper = require("node-red-node-test-helper"); +var WebSocket = require('ws'); + +describe('debug node', function() { + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + beforeEach(function (done) { + setTimeout(function() { + done(); + }, 55); + }); + + afterEach(function() { + helper.unload(); + }); + + + it('should be loaded', function(done) { + var flow = [{id:"n1", type:"debug", name:"Debug", complete:"false" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('name', 'Debug'); + n1.should.have.property('complete', "payload"); + done(); + }); + }); + + it('should publish on input', function(done) { + var flow = [{id:"n1", type:"debug", name:"Debug" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload:"test"}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug",data:{id:"n1",name:"Debug",msg:"test",path:"global", + format:"string[4]",property:"payload"} + }]); + }, done); + }); + }); + + it('should publish to console', function(done) { + var flow = [{id:"n1", type:"debug", console:"true"}]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + var count = 0; + websocket_test(function() { + n1.emit("input", {payload:"test"}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug",data:{id:"n1",msg:"test",property:"payload",format:"string[4]",path:"global"} + }]); + count++; + }, function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "debug"; + }); + logEvents.should.have.length(1); + var tstmp = logEvents[0][0].timestamp; + logEvents[0][0].should.eql({level:helper.log().INFO, id:'n1',type:'debug',msg:'test', timestamp:tstmp,path:"global"}); + + done(); + } catch(err) { + done(err); + } + }); + }); + }); + + it('should publish complete message', function(done) { + var flow = [{id:"n1", type:"debug", complete:"true" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload:"test"}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug", + data:{id:"n1",msg:'{\n "payload": "test"\n}',format:"Object",path:"global"} + }]); + }, done); + }); + }); + + it('should publish complete message to console', function(done) { + var flow = [{id:"n1", type:"debug", complete:"true", console:"true" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload:"test"}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug", + data:{id:"n1",msg:'{\n "payload": "test"\n}',format:"Object",path:"global"} + }]); + }, function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "debug"; + }); + logEvents.should.have.length(1); + var tstmp = logEvents[0][0].timestamp; + logEvents[0][0].should.eql({level:helper.log().INFO, id:"n1",type:"debug",msg:'\n{ payload: \'test\' }',timestamp:tstmp,path:"global"}); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + + it('should publish other property', function(done) { + var flow = [{id:"n1", type:"debug", complete:"foo" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload:"test", foo:"bar"}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug",data:{id:"n1",msg:"bar",property:"foo",format:"string[3]",path:"global"} + }]); + }, done); + }); + }); + + it('should publish multi-level properties', function(done) { + var flow = [{id:"n1", type:"debug", complete:"foo.bar" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload:"test", foo: {bar:"bar"}}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug",data:{id:"n1",msg:"bar",property:"foo.bar",format:"string[3]",path:"global"} + }]); + }, done); + }); + }); + + it('should publish an Error', function(done) { + var flow = [{id:"n1", type:"debug" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload: new Error("oops")}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug",data:{id:"n1",msg:'{"name":"Error","message":"oops"}',property:"payload",format:"error",path:"global"} + }]); + }, done); + }); + }); + + it('should publish a boolean', function(done) { + var flow = [{id:"n1", type:"debug" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload: true}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug",data:{id:"n1",msg: 'true',property:"payload",format:"boolean",path:"global"} + }]); + }, done); + }); + }); + + it('should publish a number', function(done) { + var flow = [{id:"n1", type:"debug", console:"true" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload: 7}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug",data:{id:"n1",msg:"7",property:"payload",format:"number",path:"global"} + }]); + }, done); + }); + }); + + it('should publish a NaN', function(done) { + var flow = [{id:"n1", type:"debug", console:"true" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload: Number.NaN}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug",data:{id:"n1",msg:"NaN",property:"payload",format:"number",path:"global"} + }]); + }, done); + }); + }); + + it('should publish with no payload', function(done) { + var flow = [{id:"n1", type:"debug" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug",data:{id:"n1",msg:'(undefined)',property:"payload",format:"undefined",path:"global"} + }]); + }, done); + }); + }); + + it('should publish a null', function(done) { + var flow = [{id:"n1", type:"debug" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload:null}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug",data:{id:"n1",msg:'(undefined)',property:"payload",format:"null",path:"global"} + }]); + }, done); + }); + }); + + it('should publish an object', function(done) { + var flow = [{id:"n1", type:"debug" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload: {type:'foo'}}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug", + data:{id:"n1",msg:'{\n "type": "foo"\n}',property:"payload",format:"Object",path:"global"} + }]); + }, done); + }); + }); + + it('should publish an array', function(done) { + var flow = [{id:"n1", type:"debug" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload: [0,1,2,3]}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug", + data:{id:"n1",msg: '[\n 0,\n 1,\n 2,\n 3\n]',format:"array[4]", + property:"payload",path:"global"} + }]); + }, done); + }); + }); + + it('should publish an object with circular references', function(done) { + var flow = [{id:"n1", type:"debug" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + var o = { name: 'bar' }; + o.o = o; + n1.emit("input", {payload: o}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug", + data:{ + id:"n1", + msg:'{\n "name": "bar",\n "o": "[Circular ~]"\n}', + property:"payload",format:"Object",path:"global" + } + }]); + }, done); + }); + }); + + it('should publish an object to console', function(done) { + var flow = [{id:"n1", type:"debug", console:"true"}]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload: {type:'foo'}}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug",data:{id:"n1",msg:'{\n "type": "foo"\n}',property:"payload",format:"Object",path:"global"} + }]); + }, function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "debug"; + }); + logEvents.should.have.length(1); + var tstmp = logEvents[0][0].timestamp; + logEvents[0][0].should.eql({level:helper.log().INFO,id:"n1",type:"debug",msg:'\n{ type: \'foo\' }',timestamp:tstmp,path:"global"}); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + + it('should publish a string after a newline to console if the string contains \\n', function(done) { + var flow = [{id:"n1", type:"debug", console:"true"}]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload:"test\ntest"}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug",data:{id:"n1",msg:"test\ntest",property:"payload",format:"string[9]",path:"global"} + }]); + }, function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "debug"; + }); + logEvents.should.have.length(1); + var tstmp = logEvents[0][0].timestamp; + logEvents[0][0].should.eql({level:helper.log().INFO,id:"n1",type:"debug",msg:"\ntest\ntest",timestamp:tstmp,path:"global"}); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + + it('should publish complete message with edit', function(done) { + var flow = [{id:"n1", type:"debug", name:"Debug", complete: "true", + targetType: "jsonata", complete: '"<" & payload & ">"'}]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload:"test"}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug",data:{id:"n1",name:"Debug",msg:"<test>", + format:"string[6]",path:"global"} + }]); + }, done); + }); + }); + + it('should truncate a long message', function(done) { + var flow = [{id:"n1", type:"debug" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload:Array(1002).join("X")}); + }, function(msg) { + var a = JSON.parse(msg); + a.should.eql([{ + topic:"debug", + data:{ + id:"n1", + msg: Array(1001).join("X")+'...', + property:"payload", + format:"string[1001]", + path:"global" + } + }]); + }, done); + }); + }); + + it('should truncate a long string in the object', function(done) { + var flow = [{id:"n1", type:"debug"}]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload: {foo: Array(1002).join("X")}}); + }, function(msg) { + var a = JSON.parse(msg); + a.should.eql([{ + topic:"debug", + data:{ + id:"n1", + msg:'{\n "foo": "'+Array(1001).join("X")+'..."\n}', + property:"payload", + format:"Object", + path:"global" + } + }]); + }, done); + }); + }); + + it('should truncate a large array', function(done) { + var flow = [{id:"n1", type:"debug" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload: Array(1001).fill("X")}); + }, function(msg) { + var a = JSON.parse(msg); + a.should.eql([{ + topic:"debug", + data:{ + id:"n1", + msg:JSON.stringify({ + __enc__: true, + type: "array", + data: Array(1000).fill("X"), + length: 1001 + },null," "), + property:"payload", + format:"array[1001]", + path:"global" + } + }]); + }, done); + }); + }); + + it('should truncate a large array in the object', function(done) { + var flow = [{id:"n1", type:"debug"}]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload: {foo: Array(1001).fill("X")}}); + }, function(msg) { + var a = JSON.parse(msg); + a.should.eql([{ + topic:"debug", + data:{ + id:"n1", + msg:JSON.stringify({ + foo:{ + __enc__: true, + type: "array", + data: Array(1000).fill("X"), + length: 1001 + } + },null," "), + property:"payload", + format:"Object", + path:"global" + } + }]); + }, done); + }); + }); + + it('should truncate a large buffer', function(done) { + var flow = [{id:"n1", type:"debug" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload: Buffer.alloc(501,"\"")}); + }, function(msg) { + var a = JSON.parse(msg); + a[0].should.eql({ + topic:"debug", + data:{ + id:"n1", + msg: Array(1001).join("2"), + property:"payload", + format:"buffer[501]", + path:"global" + } + }); + }, done); + }); + }); + + it('should truncate a large buffer in the object', function(done) { + var flow = [{id:"n1", type:"debug"}]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload: {foo: Buffer.alloc(1001,"X")}}); + }, function(msg) { + var a = JSON.parse(msg); + a[0].should.eql({ + topic:"debug", + data:{ + id:"n1", + msg:JSON.stringify({ + foo:{ + type: "Buffer", + data: Array(1000).fill(88), + __enc__: true, + length: 1001 + } + },null," "), + property:"payload", + format:"Object", + path:"global" + } + }); + }, done); + }); + }); + + it('should convert Buffer to hex', function(done) { + var flow = [{id:"n1", type:"debug" }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload: Buffer.from('HELLO', 'utf8')}); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug", + data:{ + id:"n1", + msg:'48454c4c4f', + property:"payload", + format:"buffer[5]", + path:"global" + } + }]); + }, done); + }); + }); + + it('should publish when active', function(done) { + var flow = [{id:"n1", type:"debug", active: false }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function() { + n1.emit("input", {payload:"message 1"}); + helper.request() + .post('/debug/n1/enable') + .expect(200).end(function(err) { + if (err) { return done(err); } + n1.emit("input", {payload:"message 2"}); + }); + }, function(msg) { + JSON.parse(msg).should.eql([{ + topic:"debug",data:{id:"n1",msg:"message 2",property:"payload",format:"string[9]",path:"global"} + }]); + }, done); + }); + }); + + it('should not publish when inactive', function(done) { + var flow = [{id:"n1", type:"debug", active: true }]; + helper.load(debugNode, flow, function() { + var n1 = helper.getNode("n1"); + websocket_test(function(close) { + helper.request() + .post('/debug/n1/disable') + .expect(201).end(function(err) { + if (err) { + close(); + return done(err); + } + n1.emit("input", {payload:"message"}); + setTimeout(function() { + close(); + done(); + }, 200); + }); + }, function(msg) { + should.fail(null,null,"unexpected message"); + }, function() {}); + }); + }); + + describe('post', function() { + it('should return 404 on invalid state', function(done) { + var flow = [{id:"n1", type:"debug", active: true }]; + helper.load(debugNode, flow, function() { + helper.request() + .post('/debug/n1/foobar') + .expect(404).end(done); + }); + }); + + it('should return 404 on invalid node', function(done) { + helper.request() + .post('/debug/n99/enable') + .expect(404).end(done); + }); + }); + + describe('get', function() { + it('should return the view.html', function(done) { + var flow = [{id:"n1", type:"debug"}]; + helper.load(debugNode, flow, function() { + helper.request() + .get('/debug/view/view.html') + .expect(200) + .end(done); + }); + }); + }); + +}); + +function websocket_test(open_callback, message_callback, done_callback) { + var ws = new WebSocket(helper.url() + "/comms"); + var close_callback = function() { ws.close(); }; + ws.on('open', function() { open_callback(close_callback); }); + ws.on('message', function(msg) { + try { + message_callback(msg, close_callback); + ws.close(); + done_callback(); + } catch(err) { + done_callback(err); + } + }); +} diff --git a/packages/connector/test/nodes/core/common/25-catch_spec.js b/packages/connector/test/nodes/core/common/25-catch_spec.js new file mode 100644 index 0000000..466d912 --- /dev/null +++ b/packages/connector/test/nodes/core/common/25-catch_spec.js @@ -0,0 +1,44 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var catchNode = require("nr-test-utils").require("@node-red/nodes/core/common/25-catch.js"); +var helper = require("node-red-node-test-helper"); + +describe('catch Node', function() { + + afterEach(function() { + helper.unload(); + }); + + it('should output a message when called', function(done) { + var flow = [ { id:"n1", type:"catch", name:"catch", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(catchNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.should.have.property('name', 'catch'); + n2.on("input", function(msg) { + msg.should.be.a.Error(); + msg.toString().should.equal("Error: big error"); + done(); + }); + var err = new Error("big error"); + n1.emit("input", err); + }); + }); + +}); diff --git a/packages/connector/test/nodes/core/common/25-status_spec.js b/packages/connector/test/nodes/core/common/25-status_spec.js new file mode 100644 index 0000000..41b0a79 --- /dev/null +++ b/packages/connector/test/nodes/core/common/25-status_spec.js @@ -0,0 +1,54 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var catchNode = require("nr-test-utils").require("@node-red/nodes/core/common/25-status.js"); +var helper = require("node-red-node-test-helper"); + +describe('status Node', function() { + + afterEach(function() { + helper.unload(); + }); + + it('should output a message when called', function(done) { + var flow = [ { id:"n1", type:"status", name:"status", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(catchNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.should.have.property('name', 'status'); + n2.on("input", function(msg) { + msg.text.should.equal("Oh dear"); + msg.should.have.property('source'); + msg.source.should.have.property('id',"12345"); + msg.source.should.have.property('type',"testnode"); + msg.source.should.have.property('name',"fred"); + done(); + }); + var mst = { + text: "Oh dear", + source: { + id: "12345", + type: "testnode", + name: "fred" + } + } + n1.emit("input", mst); + }); + }); + +}); diff --git a/packages/connector/test/nodes/core/common/60-link_spec.js b/packages/connector/test/nodes/core/common/60-link_spec.js new file mode 100644 index 0000000..50072d7 --- /dev/null +++ b/packages/connector/test/nodes/core/common/60-link_spec.js @@ -0,0 +1,122 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var linkNode = require("nr-test-utils").require("@node-red/nodes/core/common/60-link.js"); +var helper = require("node-red-node-test-helper"); + +describe('link Node', function() { + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + afterEach(function() { + helper.unload(); + }); + + it('should be loaded (link in)', function(done) { + var flow = [{id:"n1", type:"link in", name: "link-in" }]; + helper.load(linkNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('name', 'link-in'); + done(); + }); + }); + + it('should be loaded (link out)', function(done) { + var flow = [{id:"n1", type:"link out", name: "link-out" }]; + helper.load(linkNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('name', 'link-out'); + done(); + }); + }); + + it('should be linked', function(done) { + var flow = [{id:"n1", type:"link out", name: "link-out", links:["n2"]}, + {id:"n2", type:"link in", name: "link-in", wires:[["n3"]]}, + {id:"n3", type:"helper"}]; + helper.load(linkNode, flow, function() { + var n1 = helper.getNode("n1"); + var n3 = helper.getNode("n3"); + n3.on("input", function(msg) { + try { + msg.should.have.property('payload', 'hello'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"hello"}); + }); + }); + + it('should be linked to multiple nodes', function(done) { + var flow = [{id:"n1", type:"link out", name: "link-out", links:["n2", "n3"]}, + {id:"n2", type:"link in", name: "link-in0", wires:[["n4"]]}, + {id:"n3", type:"link in", name: "link-in1", wires:[["n4"]]}, + {id:"n4", type:"helper"} ]; + helper.load(linkNode, flow, function() { + var n1 = helper.getNode("n1"); + var n4 = helper.getNode("n4"); + var count = 0; + n4.on("input", function (msg) { + try { + msg.should.have.property('payload', 'hello'); + count++; + if(count == 2) { + done(); + } + } catch(err) { + done(err); + } + }); + n1.receive({payload:"hello"}); + }); + }); + + it('should be linked from multiple nodes', function(done) { + var flow = [{id:"n1", type:"link out", name: "link-out0", links:["n3"]}, + {id:"n2", type:"link out", name: "link-out1", links:["n3"]}, + {id:"n3", type:"link in", name: "link-in", wires:[["n4"]]}, + {id:"n4", type:"helper"} ]; + helper.load(linkNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n4 = helper.getNode("n4"); + var count = 0; + n4.on("input", function(msg) { + try { + msg.should.have.property('payload', 'hello'); + count++; + if(count == 2) { + done(); + } + } catch(err) { + done(err); + } + }); + n1.receive({payload:"hello"}); + n2.receive({payload:"hello"}); + }); + }); + +}); diff --git a/packages/connector/test/nodes/core/common/90-comment_spec.js b/packages/connector/test/nodes/core/common/90-comment_spec.js new file mode 100644 index 0000000..a6f6a82 --- /dev/null +++ b/packages/connector/test/nodes/core/common/90-comment_spec.js @@ -0,0 +1,36 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var commentNode = require("nr-test-utils").require("@node-red/nodes/core/common/90-comment.js"); +var helper = require("node-red-node-test-helper"); + +describe('comment Node', function() { + + afterEach(function() { + helper.unload(); + }); + + it('should be loaded', function(done) { + var flow = [{id:"n1", type:"comment", name: "comment" }]; + helper.load(commentNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('name', 'comment'); + done(); + }); + }); + +}); diff --git a/packages/connector/test/nodes/core/common/98-unknown_spec.js b/packages/connector/test/nodes/core/common/98-unknown_spec.js new file mode 100644 index 0000000..1b16a5c --- /dev/null +++ b/packages/connector/test/nodes/core/common/98-unknown_spec.js @@ -0,0 +1,36 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var unknown = require("nr-test-utils").require("@node-red/nodes/core/common/98-unknown.js"); +var helper = require("node-red-node-test-helper"); + +describe('unknown Node', function() { + + afterEach(function() { + helper.unload(); + }); + + it('should be loaded', function(done) { + var flow = [{id:"n1", type:"unknown", name: "unknown" }]; + helper.load(unknown, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('name', 'unknown'); + done(); + }); + }); + +}); diff --git a/packages/connector/test/nodes/core/function/10-function_spec.js b/packages/connector/test/nodes/core/function/10-function_spec.js new file mode 100644 index 0000000..c13dd19 --- /dev/null +++ b/packages/connector/test/nodes/core/function/10-function_spec.js @@ -0,0 +1,1534 @@ +/** +* Copyright JS Foundation and other contributors, http://js.foundation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + +var should = require("should"); +var functionNode = require("nr-test-utils").require("@node-red/nodes/core/function/10-function.js"); +var Context = require("nr-test-utils").require("@node-red/runtime/lib/nodes/context"); +var helper = require("node-red-node-test-helper"); + +describe('function node', function() { + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + function initContext(done) { + Context.init({ + contextStorage: { + memory1: { + module: "memory" + }, + memory2: { + module: "memory" + } + } + }); + Context.load().then(function () { + done(); + }); + } + + afterEach(function() { + helper.unload().then(function () { + return Context.clean({allNodes:{}}); + }).then(function () { + return Context.close(); + }); + }); + + + it('should be loaded', function(done) { + var flow = [{id:"n1", type:"function", name: "function" }]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('name', 'function'); + done(); + }); + }); + + it('should send returned message', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should send returned message using send()', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"node.send(msg);"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + function testSendCloning(args,done) { + var flow = [{id:"n1",type:"function",wires:[["n2"],["n2"]],func:"node.send("+args+"); msg.payload = 'changed';"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + done(); + } catch(err) { + done(err); + } + }); + var origMessage = {payload:"foo",topic: "bar"}; + n1.receive(origMessage); + }); + } + it('should clone single message sent using send()', function(done) { + testSendCloning("msg",done); + }); + it('should not clone single message sent using send(,false)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"node.send(msg,false); msg.payload = 'changed';"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'changed'); + done(); + }); + var origMessage = {payload:"foo",topic: "bar"}; + n1.receive(origMessage); + }); + }); + it('should clone first message sent using send() - array 1', function(done) { + testSendCloning("[msg]",done); + }); + it('should clone first message sent using send() - array 2', function(done) { + testSendCloning("[[msg],[null]]",done); + }); + it('should clone first message sent using send() - array 3', function(done) { + testSendCloning("[null,msg]",done); + }); + it('should clone first message sent using send() - array 3', function(done) { + testSendCloning("[null,[msg]]",done); + }); + + it('should pass through _topic', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + msg.should.have.property('_topic', 'baz'); + done(); + }); + n1.receive({payload:"foo",topic: "bar", _topic: "baz"}); + }); + }); + + it('should send to multiple outputs', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"],["n3"]], + func:"return [{payload: '1'},{payload: '2'}];"}, + {id:"n2", type:"helper"}, {id:"n3", type:"helper"} ]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var count = 0; + n2.on("input", function(msg) { + should(msg).have.property('payload', '1'); + count++; + if (count == 2) { + done(); + } + }); + n3.on("input", function(msg) { + should(msg).have.property('payload', '2'); + count++; + if (count == 2) { + done(); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should send to multiple messages', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]], + func:"return [[{payload: 1},{payload: 2}]];"}, + {id:"n2", type:"helper"} ]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + count++; + try { + should(msg).have.property('payload', count); + should(msg).have.property('_msgid', 1234); + if (count == 2) { + done(); + } + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", topic: "bar",_msgid:1234}); + }); + }); + + it('should allow input to be discarded by returning null', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"return null"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + setTimeout(function() { + done(); + }, 20); + n2.on("input", function(msg) { + should.fail(null,null,"unexpected message"); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should handle null amongst valid messages', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"return [[msg,null,msg],null]"}, + {id:"n2", type:"helper"}, + {id:"n3", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n2MsgCount = 0; + var n3MsgCount = 0; + n2.on("input", function(msg) { + n2MsgCount++; + }); + n3.on("input", function(msg) { + n3MsgCount++; + }); + n1.receive({payload:"foo",topic: "bar"}); + setTimeout(function() { + n2MsgCount.should.equal(2); + n3MsgCount.should.equal(0); + done(); + },20); + }); + }); + + it('should get keys in global context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=global.keys();return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().global.set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', ['count']); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + function testNonObjectMessage(functionText,done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:functionText}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n2MsgCount = 0; + n2.on("input", function(msg) { + n2MsgCount++; + }); + n1.receive({}); + setTimeout(function() { + try { + n2MsgCount.should.equal(0); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'function.error.non-message-returned'); + done(); + } catch(err) { + done(err); + } + },20); + }); + } + it('should drop and log non-object message types - string', function(done) { + testNonObjectMessage('return "foo"', done) + }); + it('should drop and log non-object message types - buffer', function(done) { + testNonObjectMessage('return Buffer.from("hello")', done) + }); + it('should drop and log non-object message types - array', function(done) { + testNonObjectMessage('return [[[1,2,3]]]', done) + }); + it('should drop and log non-object message types - boolean', function(done) { + testNonObjectMessage('return true', done) + }); + it('should drop and log non-object message types - number', function(done) { + testNonObjectMessage('return 123', done) + }); + + it('should handle and log script error', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"var a = 1;\nretunr"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.receive({payload:"foo",topic: "bar"}); + setTimeout(function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'ReferenceError: retunr is not defined (line 2, col 1)'); + done(); + } catch(err) { + done(err); + } + },50); + }); + }); + + it('should handle node.on()', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"node.on('close',function(){ node.log('closed')});"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.receive({payload:"foo",topic: "bar"}); + setTimeout(function() { + n1.close().then(function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().INFO); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'closed'); + done(); + } catch(err) { + done(err); + } + }); + },1500); + }); + }); + + it('should set node context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set('count','0');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n1.context().get("count").should.equal("0"); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should set persistable node context (w/o callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set('count','0','memory1');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n1.context().get("count", "memory1", function (err, val) { + val.should.equal("0"); + done(); + }); + } + catch (e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should set two persistable node context (w/o callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set('count','0','memory1');context.set('count','1','memory2');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n1.context().get("count", "memory1", function (err, val1) { + val1.should.equal("0"); + n1.context().get("count", "memory2", function (err, val2) { + val2.should.equal("1"); + done(); + }); + }); + } + catch (e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should set two persistable node context (single call, w/o callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set(['count1','count2'],['0','1'],'memory1');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n1.context().get("count1", "memory1", function (err, val1) { + val1.should.equal("0"); + n1.context().get("count2", "memory1", function (err, val2) { + val2.should.equal("1"); + done(); + }); + }); + } + catch (e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + + it('should set persistable node context (w callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set('count','0','memory1', function (err) { node.send(msg); });"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n1.context().get("count", "memory1", function (err, val) { + val.should.equal("0"); + done(); + }); + } + catch (e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should set two persistable node context (w callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set('count','0','memory1', function (err) { context.set('count', '1', 'memory2', function (err) { node.send(msg); }); });"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n1.context().get("count", "memory1", function (err, val1) { + val1.should.equal("0"); + n1.context().get("count", "memory1", function (err, val2) { + val2.should.equal("0"); + done(); + }); + }); + } + catch (e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should set two persistable node context (single call, w callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set(['count1','count2'],['0','1'],'memory1', function(err) { node.send(msg); });"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n1.context().get("count1", "memory1", function (err, val1) { + val1.should.equal("0"); + n1.context().get("count2", "memory1", function (err, val2) { + val2.should.equal("1"); + done(); + }); + }); + } + catch (e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + + it('should set default persistable node context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set('count','0');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n1.context().get("count", "memory1", function (err, val) { + val.should.equal("0"); + done(); + }); + } + catch (e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should get node context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.get('count');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + function checkCallbackError(name, done) { + setTimeout(function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', name); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'Error: Callback must be a function'); + done(); + } + catch (e) { + done(e); + } + },50); + } + + it('should get persistable node context (w/o callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.get('count','memory1');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().set("count","0","memory1"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should get persistable node context (w/ callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.get('count','memory1',function (err, val) { msg.payload=val; node.send(msg); });"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().set("count","0","memory1"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should get keys in node context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.keys();return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', ['count']); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should get keys in persistable node context (w/o callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.keys('memory1');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().set("count","0","memory1"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', ['count']); + done(); + } + catch(e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should get keys in persistable node context (w/ callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.keys('memory1', function(err, keys) { msg.payload=keys; node.send(msg); });"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().set("count","0","memory1"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', ['count']); + done(); + } + catch(e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should get keys in default persistable node context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.keys();return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().set("count","0","memory1"); + n1.context().set("number","1","memory2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', ['count']); + done(); + } + catch(e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should set flow context', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.set('count','0');return msg;"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n2.context().flow.get("count").should.equal("0"); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should set persistable flow context (w/o callback)', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.set('count','0','memory1');return msg;"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n2.context().flow.get("count", "memory1", function (err, val) { + val.should.equal("0"); + done(); + }); + } + catch(e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should set two persistable flow context (w/o callback)', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.set('count','0','memory1');flow.set('count','1','memory2');return msg;"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n2.context().flow.get("count", "memory1", function (err, val1) { + val1.should.equal("0"); + n2.context().flow.get("count", "memory2", function (err, val2) { + val2.should.equal("1"); + done(); + }); + }); + } + catch(e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should set persistable flow context (w/ callback)', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.set('count','0','memory1', function (err) { node.send(msg); });"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n2.context().flow.get("count", "memory1", function (err, val) { + val.should.equal("0"); + done(); + }); + } + catch(e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should set two persistable flow context (w/ callback)', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.set('count','0','memory1', function (err) { flow.set('count','1','memory2', function (err) { node.send(msg); }); });"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n2.context().flow.get("count", "memory1", function (err, val1) { + val1.should.equal("0"); + n2.context().flow.get("count", "memory2", function (err, val2) { + val2.should.equal("1"); + done(); + }); + }); + } + catch(e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should get flow context', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=flow.get('count');return msg;"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().flow.set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should get persistable flow context (w/o callback)', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=flow.get('count','memory1');return msg;"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().flow.set("count","0","memory1"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should get persistable flow context (w/ callback)', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.get('count','memory1', function(err, val) { msg.payload=val; node.send(msg); });"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().flow.set("count","0","memory1"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should get flow context', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=context.flow.get('count');return msg;"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().flow.set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should get keys in flow context', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=flow.keys();return msg;"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().flow.set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', ['count']); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should get keys in persistable flow context (w/o callback)', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=flow.keys('memory1');return msg;"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().flow.set("count","0","memory1"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', ['count']); + done(); + } + catch(e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should get keys in persistable flow context (w/ callback)', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.keys('memory1', function (err, val) { msg.payload=val; node.send(msg); });"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().flow.set("count","0","memory1"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', ['count']); + done(); + } + catch(e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should set global context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"global.set('count','0');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n2.context().global.get("count").should.equal("0"); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should set persistable global context (w/o callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"global.set('count','0','memory1');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n2.context().global.get("count", "memory1", function(err, val) { + val.should.equal("0"); + done(); + }); + } + catch(e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should set persistable global context (w/ callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"global.set('count','0','memory1', function (err) { node.send(msg); });"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n2.context().global.get("count", "memory1", function(err, val) { + val.should.equal("0"); + done(); + }); + } + catch(e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should get global context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=global.get('count');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().global.set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should get persistable global context (w/o callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=global.get('count', 'memory1');return msg;"}, + {id:"n2", type:"helper"}]; + initContext(function () { + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().global.set("count","0", 'memory1'); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should get persistable global context (w/ callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"global.get('count', 'memory1', function (err, val) { msg.payload=val; node.send(msg); });"}, + {id:"n2", type:"helper"}]; + initContext(function () { + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().global.set("count","0", 'memory1'); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should get global context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.global.get('count');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().global.set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should get persistable global context (w/o callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.global.get('count','memory1');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().global.set("count","0", "memory1"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + } + catch(e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should get persistable global context (w/ callback)', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.global.get('count','memory1', function (err, val) { msg.payload = val; node.send(msg); });"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().global.set("count","0", "memory1"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + } + catch(e) { + done(e); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should handle error on get persistable context', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=context.get('count','memory1','callback');return msg;"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().flow.set("count","0","memory1"); + n1.receive({payload:"foo",topic: "bar"}); + checkCallbackError('n1', done); + }); + }); + }); + + it('should handle error on set persistable context', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=context.set('count','0','memory1','callback');return msg;"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.receive({payload:"foo",topic: "bar"}); + checkCallbackError('n1', done); + }); + }); + }); + + it('should handle error on get keys in persistable context', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=context.keys('memory1','callback');return msg;"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().flow.set("count","0","memory1"); + n1.receive({payload:"foo",topic: "bar"}); + checkCallbackError('n1', done); + }); + }); + }); + + + it('should handle setTimeout()', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"setTimeout(function(){node.send(msg);},1000);"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + var endTime = process.hrtime(startTime); + var nanoTime = endTime[0] * 1000000000 + endTime[1]; + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + if (900000000 < nanoTime && nanoTime < 1100000000) { + done(); + } else { + try { + should.fail(null, null, "Delayed time was not between 900 and 1100 ms"); + } catch (err) { + done(err); + } + } + }); + var startTime = process.hrtime(); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should handle setInterval()', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"setInterval(function(){node.send(msg);},100);"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + count++; + if (count > 2) { + done(); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should handle clearInterval()', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"var id=setInterval(null,100);setTimeout(function(){clearInterval(id);node.send(msg);},1000);"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should allow accessing node.id', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload = node.id; return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', n1.id); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should allow accessing node.name', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload = node.name; return msg;", "name":"name of node"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', n1.name); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should use the same Date object from outside the sandbox', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=global.get('typeTest')(new Date());return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().global.set("typeTest",function(d) { return d instanceof Date }); + n2.on("input", function(msg) { + msg.should.have.property('payload', true); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should allow accessing env vars', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload = env.get('_TEST_FOO_'); return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + delete process.env._TEST_FOO_; + + n2.on("input", function(msg) { + try { + if (count === 0) { + msg.should.have.property('payload', undefined); + process.env._TEST_FOO_ = "hello"; + count++; + n1.receive({payload:"foo",topic: "bar"}); + } else { + msg.should.have.property('payload', "hello"); + delete process.env._TEST_FOO_; + done(); + } + } catch(err) { + delete process.env._TEST_FOO_; + done(err); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + describe('Logger', function () { + it('should log an Info Message', function (done) { + var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "node.log('test');"}]; + helper.load(functionNode, flow, function () { + var n1 = helper.getNode("n1"); + n1.receive({payload: "foo", topic: "bar"}); + setTimeout(function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().INFO); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'test'); + done(); + } catch (err) { + done(err); + } + },50); + }); + }); + it('should log a Debug Message', function (done) { + var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "node.debug('test');"}]; + helper.load(functionNode, flow, function () { + var n1 = helper.getNode("n1"); + n1.receive({payload: "foo", topic: "bar"}); + setTimeout(function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().DEBUG); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'test'); + done(); + } catch (err) { + done(err); + } + },50); + }); + }); + it('should log a Trace Message', function (done) { + var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "node.trace('test');"}]; + helper.load(functionNode, flow, function () { + var n1 = helper.getNode("n1"); + n1.receive({payload: "foo", topic: "bar"}); + setTimeout(function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().TRACE); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'test'); + done(); + } catch (err) { + done(err); + } + },50); + }); + }); + it('should log a Warning Message', function (done) { + var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "node.warn('test');"}]; + helper.load(functionNode, flow, function () { + var n1 = helper.getNode("n1"); + n1.receive({payload: "foo", topic: "bar"}); + setTimeout(function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().WARN); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'test'); + done(); + } catch (err) { + done(err); + } + },50); + }); + }); + it('should log an Error Message', function (done) { + var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "node.error('test');"}]; + helper.load(functionNode, flow, function () { + var n1 = helper.getNode("n1"); + n1.receive({payload: "foo", topic: "bar"}); + setTimeout(function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'test'); + done(); + } catch (err) { + done(err); + } + },50); + }); + }); + it('should catch thrown string', function (done) { + var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "throw \"small mistake\";"}]; + helper.load(functionNode, flow, function () { + var n1 = helper.getNode("n1"); + n1.receive({payload: "foo", topic: "bar"}); + setTimeout(function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'small mistake'); + done(); + } catch (err) { + done(err); + } + },50); + }); + }); + it('should catch thrown number', function (done) { + var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "throw 99;"}]; + helper.load(functionNode, flow, function () { + var n1 = helper.getNode("n1"); + n1.receive({payload: "foo", topic: "bar"}); + setTimeout(function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', '99'); + done(); + } catch (err) { + done(err); + } + },50); + }); + }); + it('should catch thrown object (bad practice)', function (done) { + var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "throw {a:1};"}]; + helper.load(functionNode, flow, function () { + var n1 = helper.getNode("n1"); + n1.receive({payload: "foo", topic: "bar"}); + setTimeout(function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', '{"a":1}'); + done(); + } catch (err) { + done(err); + } + },50); + }); + }); + }); + +}); diff --git a/packages/connector/test/nodes/core/function/10-switch_spec.js b/packages/connector/test/nodes/core/function/10-switch_spec.js new file mode 100644 index 0000000..b431fca --- /dev/null +++ b/packages/connector/test/nodes/core/function/10-switch_spec.js @@ -0,0 +1,1105 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); + +var switchNode = require("nr-test-utils").require("@node-red/nodes/core/function/10-switch.js"); +var helper = require("node-red-node-test-helper"); +var RED = require("nr-test-utils").require("node-red/lib/red"); +var Context = require("nr-test-utils").require("@node-red/runtime/lib/nodes/context/"); + +describe('switch Node', function() { + + beforeEach(function(done) { + helper.startServer(done); + }); + + function initContext(done) { + Context.init({ + contextStorage: { + memory0: { + module: "memory" + }, + memory1: { + module: "memory" + } + } + }); + Context.load().then(function () { + done(); + }); + } + + afterEach(function(done) { + helper.unload().then(function () { + return Context.clean({allNodes: {}}); + }).then(function () { + return Context.close(); + }).then(function () { + RED.settings.nodeMessageBufferMaxLength = 0; + helper.stopServer(done); + }); + }); + + it('should be loaded with some defaults', function(done) { + var flow = [{"id":"switchNode1","type":"switch","name":"switchNode"}]; + helper.load(switchNode, flow, function() { + var switchNode1 = helper.getNode("switchNode1"); + switchNode1.should.have.property('name', 'switchNode'); + switchNode1.should.have.property('checkall', "true"); + switchNode1.should.have.property('rules', []); + done(); + }); + }); + + /** + * Test a switch node where one argument is consumed by the rule (such as greater than). + * @param rule - the switch rule (see 10-switc.js) string we're using + * @param ruleWith - whatever the rule should be executed with (say greater than 5) + * @param aCheckall - whether the switch flow should have the checkall flag set to true/false + * @param shouldReceive - whether the helper node should receive a payload + * @param sendPayload - the payload message we're sending + * @param done - callback when done + */ + function genericSwitchTest(rule, ruleWith, aCheckall, shouldReceive, sendPayload, done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":rule,"v":ruleWith}],checkall:aCheckall,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSwitchTest(flow, shouldReceive, sendPayload, done); + } + + /** + * Test a switch node where NO arguments are consumed by the rule (such as TRUE/FALSE) + * @param rule - the switch rule (see 10-switc.js) string we're using + * @param aCheckall - whether the switch flow should have the checkall flag set to true/false + * @param shouldReceive - whether the helper node should receive a payload + * @param sendPayload - the payload message we're sending + * @param done - callback when done + */ + function singularSwitchTest(rule, aCheckall, shouldReceive, sendPayload, done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":rule}],checkall:aCheckall,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSwitchTest(flow, shouldReceive, sendPayload, done); + } + + /** + * Test a switch node where two arguments are consumed by the rule (such as between). + * @param rule - the switch rule (see 10-switc.js) string we're using + * @param ruleWith - whatever the rule should be executed with (say between 5...) + * @param ruleWith2 - whatever the rule should be executed with (say ...and 5) + * @param aCheckall - whether the switch flow should have the checkall flag set to true/false + * @param shouldReceive - whether the helper node should receive a payload + * @param sendPayload - the payload message we're sending + * @param done - callback when done + */ + function twoFieldSwitchTest(rule, ruleWith, ruleWith2, aCheckall, shouldReceive, sendPayload, done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":rule,"v":ruleWith,"v2":ruleWith2}],checkall:aCheckall,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSwitchTest(flow, shouldReceive, sendPayload, done); + } + + /** + * Execute a switch test. Can specify whether the should node is expected to send a payload onwards to the helper node. + * The flow and the payload can be customised + * @param flow - the custom flow to be tested => must contain a switch node (switchNode1) wiring a helper node (helperNode1) + * @param shouldReceive - whether the helper node should receive a payload + * @param sendPayload - the payload message we're sending + * @param done - callback when done + */ + function customFlowSwitchTest(flow, shouldReceive, sendPayload, done) { + helper.load(switchNode, flow, function() { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + if (shouldReceive === true) { + should.equal(msg.payload,sendPayload); + done(); + } else { + should.fail(null, null, "We should never get an input!"); + } + } catch(err) { + done(err); + } + }); + switchNode1.receive({payload:sendPayload}); + if (shouldReceive === false) { + setTimeout(function() { + done(); + }, 200); + } + }); + } + + function customFlowSequenceSwitchTest(flow, seq_in, seq_out, repair, modifier, done) { + helper.load(switchNode, flow, function() { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + var sid; + var count = 0; + if (modifier !== undefined) { + modifier(switchNode1); + } + helperNode1.on("input", function(msg) { + try { + msg.should.have.property("payload", seq_out[count]); + msg.should.have.property("parts"); + var parts = msg.parts; + parts.should.have.property("id"); + var id = parts.id; + if (sid === undefined) { + sid = id; + } + else { + id.should.equal(sid); + } + if (repair) { + parts.should.have.property("index", count); + parts.should.have.property("count", seq_out.length); + } + else { + parts.should.have.property("index", msg.xindex); + parts.should.have.property("count", seq_in.length); + } + count++; + if (count === seq_out.length) { + done(); + } + } catch (e) { + done(e); + } + }); + var len = seq_in.length; + for (var i = 0; i < len; i++) { + var parts = {index:i, count:len, id:222}; + var msg = {payload:seq_in[i], xindex:i, parts:parts}; + switchNode1.receive(msg); + } + }); + } + + it('should check if payload equals given value', function(done) { + genericSwitchTest("eq", "Hello", true, true, "Hello", done); + }); + + it('should return nothing when the payload doesn\'t equal to desired string', function(done) { + genericSwitchTest("eq", "Hello", true, false, "Hello!", done); + }); + + it('should check if payload NOT equals given value', function(done) { + genericSwitchTest("neq", "Hello", true, true, "HEllO", done); + }); + + it('should return nothing when the payload does equal to desired string', function(done) { + genericSwitchTest("neq", "Hello", true, false, "Hello", done); + }); + + it('should check if payload equals given numeric value', function(done) { + genericSwitchTest("eq", 3, true, true, 3, done); + }); + + it('should return nothing when the payload doesn\'t equal to desired numeric value', function(done) { + genericSwitchTest("eq", 2, true, false, 4, done); + }); + + it('should check if payload NOT equals given numeric value', function(done) { + genericSwitchTest("neq", 55667744, true, true, -1234, done); + }); + + it('should return nothing when the payload does equal to desired numeric value', function(done) { + genericSwitchTest("neq", 10, true, false, 10, done); + }); + + it('should check if payload is less than given value', function(done) { + genericSwitchTest("lt", 3, true, true, 2, done); + }); + + it('should return nothing when the payload is not less than desired string', function(done) { + genericSwitchTest("lt", 3, true, false, 4, done); + }); + + it('should check if payload less than equals given value', function(done) { + genericSwitchTest("lte", 3, true, true, 3, done); + }); + + it('should check if payload is greater than given value', function(done) { + genericSwitchTest("gt", 3, true, true, 6, done); + }); + + it('should return nothing when the payload is not greater than desired string', function(done) { + genericSwitchTest("gt", 3, true, false, -1, done); + }); + + it('should check if payload is greater than/equals given value', function(done) { + genericSwitchTest("gte", 3, true, true, 3, done); + }); + + it('should return nothing when the payload is not greater than desired string', function(done) { + genericSwitchTest("gt", 3, true, false, -1, done); + }); + + it('should check if payload is greater than/equals given value', function(done) { + genericSwitchTest("gte", 3, true, true, 3, done); + }); + + it('should match if a payload has a required property', function(done) { + genericSwitchTest("hask", "a", true, true, {a:1}, done); + }); + it('should not match if a payload does not have a required property', function(done) { + genericSwitchTest("hask", "a", true, false, {b:1}, done); + }); + it('should not match if the key is not a string', function(done) { + genericSwitchTest("hask", 1, true, false, {a:1}, done); + }); + + it('should check if payload is between given values', function(done) { + twoFieldSwitchTest("btwn", "3", "5", true, true, 4, done); + }); + + it('should check if payload is between given values in "wrong" order', function(done) { + twoFieldSwitchTest("btwn", "5", "3", true, true, 4, done); + }); + + it('should check if payload is between given string values', function(done) { + twoFieldSwitchTest("btwn", "c", "e", true, true, "d", done); + }); + + it('should check if payload is not between given values', function(done) { + twoFieldSwitchTest("btwn", 3, 5, true, false, 12, done); + }); + + it('should check if payload contains given value', function(done) { + genericSwitchTest("cont", "Hello", true, true, "Hello World!", done); + }); + + it('should return nothing when the payload doesn\'t contain desired string', function(done) { + genericSwitchTest("cont", "Hello", true, false, "This is not a greeting!", done); + }); + + it('should match regex', function(done) { + genericSwitchTest("regex", "[abc]+", true, true, "abbabac", done); + }); + + it('should check if payload if of type string ', function(done) { + genericSwitchTest("istype", "string", true, true, "Hello", done); + }); + it('should check if payload if of type number ', function(done) { + genericSwitchTest("istype", "number", true, true, 999, done); + }); + it('should check if payload if of type number 0', function(done) { + genericSwitchTest("istype", "number", true, true, 0, done); + }); + it('should check if payload if of type boolean true', function(done) { + genericSwitchTest("istype", "boolean", true, true, true, done); + }); + it('should check if payload if of type boolean false', function(done) { + genericSwitchTest("istype", "boolean", true, true, true, done); + }); + it('should check if payload if of type array ', function(done) { + genericSwitchTest("istype", "array", true, true, [1,2,3,"a","b"], done); + }); + it('should check if payload if of type buffer ', function(done) { + genericSwitchTest("istype", "buffer", true, true, Buffer.from("Hello"), done); + }); + it('should check if payload if of type object ', function(done) { + genericSwitchTest("istype", "object", true, true, {a:1,b:"b",c:true}, done); + }); + it('should check if payload if of type JSON string ', function(done) { + genericSwitchTest("istype", "json", true, true, JSON.stringify({a:1,b:"b",c:true}), done); + }); + it('should check if payload if of type JSON string (and fail if not) ', function(done) { + genericSwitchTest("istype", "json", true, false, "Hello", done); + }); + it('should check if payload if of type null', function(done) { + genericSwitchTest("istype", "null", true, true, null, done); + }); + it('should check if payload if of type undefined', function(done) { + genericSwitchTest("istype", "undefined", true, true, undefined, done); + }); + + it('should handle flow context', function (done) { + var flow = [{"id": "switchNode1", "type": "switch", "property": "foo", "propertyType": "flow", + "rules": [{"t": "eq", "v": "bar", "vt": "flow"}], + "checkall": "true", "outputs": "1", "wires": [["helperNode1"]], "z": "flow"}, + {"id": "helperNode1", "type": "helper", "wires": []}]; + helper.load(switchNode, flow, function () { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function (msg) { + try { + msg.payload.should.equal("value"); + done(); + } catch (err) { + done(err); + } + }); + switchNode1.context().flow.set("foo", "flowValue"); + switchNode1.context().flow.set("bar", "flowValue"); + switchNode1.receive({payload: "value"}); + }); + }); + + it('should handle persistable flow context', function (done) { + var flow = [{"id": "switchNode1", "type": "switch", "property": "#:(memory1)::foo", "propertyType": "flow", + "rules": [{"t": "eq", "v": "#:(memory1)::bar", "vt": "flow"}], + "checkall": "true", "outputs": "1", "wires": [["helperNode1"]], "z": "flow"}, + {"id": "helperNode1", "type": "helper", "wires": []}]; + helper.load(switchNode, flow, function () { + initContext(function () { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function (msg) { + try { + msg.payload.should.equal("value"); + done(); + } catch (err) { + done(err); + } + }); + switchNode1.context().flow.set("foo", "flowValue", "memory1", function (err) { + switchNode1.context().flow.set("bar", "flowValue", "memory1", function (err) { + switchNode1.receive({payload: "value"}); + }); + }); + }); + }); + }); + + it('should handle global context', function (done) { + var flow = [{"id": "switchNode1", "type": "switch", "property": "foo", "propertyType": "global", + "rules": [{"t": "eq", "v": "bar", "vt": "global"}], + "checkall": "true", "outputs": "1", "wires": [["helperNode1"]]}, + {"id": "helperNode1", "type": "helper", "wires": []}]; + helper.load(switchNode, flow, function () { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function (msg) { + try { + msg.payload.should.equal("value"); + done(); + } catch (err) { + done(err); + } + }); + switchNode1.context().global.set("foo", "globalValue"); + switchNode1.context().global.set("bar", "globalValue"); + switchNode1.receive({payload: "value"}); + }); + }); + + it('should handle persistable global context', function (done) { + var flow = [{"id": "switchNode1", "type": "switch", "property": "#:(memory1)::foo", "propertyType": "global", + "rules": [{"t": "eq", "v": "#:(memory1)::bar", "vt": "global"}], + "checkall": "true", "outputs": "1", "wires": [["helperNode1"]]}, + {"id": "helperNode1", "type": "helper", "wires": []}]; + helper.load(switchNode, flow, function () { + initContext(function () { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function (msg) { + try { + msg.payload.should.equal("foo"); + done(); + } catch (err) { + done(err); + } + }); + switchNode1.context().global.set("foo", "globalValue", "memory1", function (err) { + switchNode1.context().global.set("bar", "globalValue", "memory1", function (err) { + switchNode1.receive({payload: "foo"}); + }); + }); + }); + }); + }); + + it('should match regex with ignore-case flag set true', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"regex","v":"onetwothree","case":true}],checkall:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSwitchTest(flow, true, "oneTWOthree", done); + }); + it('should not match regex with ignore-case flag unset', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"regex","v":"onetwothree"}],checkall:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSwitchTest(flow, false, "oneTWOthree", done); + }); + it('should not match regex with ignore-case flag set false', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"regex","v":"onetwothree",case:false}],checkall:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSwitchTest(flow, false, "oneTWOthree", done); + }); + + it('should return nothing when the payload doesn\'t match regex', function(done) { + genericSwitchTest("regex", "\\d+", true, false, "This is not a digit", done); + }); + + it('should return nothing when the payload doesn\'t contain desired string', function(done) { + genericSwitchTest("cont", "Hello", true, false, "This is not a greeting!", done); + }); + + it('should check if input is true', function(done) { + singularSwitchTest(true, true, true, true, done); + }); + + it('sends nothing when input is false and checking for true', function(done) { + singularSwitchTest(true, true, false, false, done); + }); + + it('should check if input is indeed false', function(done) { + singularSwitchTest(false, true, true, false, done); + }); + + it('sends nothing when input is false and checking for true', function(done) { + singularSwitchTest(false, true, false, true, done); + }); + + it('should check if payload is empty (string)', function(done) { + singularSwitchTest("empty", true, true, "", done); + }); + it('should check if payload is empty (array)', function(done) { + singularSwitchTest("empty", true, true, [], done); + }); + it('should check if payload is empty (buffer)', function(done) { + singularSwitchTest("empty", true, true, Buffer.alloc(0), done); + }); + it('should check if payload is empty (object)', function(done) { + singularSwitchTest("empty", true, true, {}, done); + }); + it('should check if payload is empty (non-empty string)', function(done) { + singularSwitchTest("empty", true, false, "1", done); + }); + it('should check if payload is empty (non-empty array)', function(done) { + singularSwitchTest("empty", true, false, [1], done); + }); + it('should check if payload is empty (non-empty buffer)', function(done) { + singularSwitchTest("empty", true, false, Buffer.alloc(1), done); + }); + it('should check if payload is empty (non-empty object)', function(done) { + singularSwitchTest("empty", true, false, {a:1}, done); + }); + it('should check if payload is empty (null)', function(done) { + singularSwitchTest("empty", true, false, null, done); + }); + it('should check if payload is empty (undefined)', function(done) { + singularSwitchTest("empty", true, false, undefined, done); + }); + it('should check if payload is empty (0)', function(done) { + singularSwitchTest("empty", true, false, 0, done); + }); + + it('should check if payload is not empty (string)', function(done) { + singularSwitchTest("nempty", true, !true, "", done); + }); + it('should check if payload is not empty (array)', function(done) { + singularSwitchTest("nempty", true, !true, [], done); + }); + it('should check if payload is not empty (buffer)', function(done) { + singularSwitchTest("nempty", true, !true, Buffer.alloc(0), done); + }); + it('should check if payload is not empty (object)', function(done) { + singularSwitchTest("nempty", true, !true, {}, done); + }); + it('should check if payload is not empty (non-empty string)', function(done) { + singularSwitchTest("nempty", true, !false, "1", done); + }); + it('should check if payload is not empty (non-empty array)', function(done) { + singularSwitchTest("nempty", true, !false, [1], done); + }); + it('should check if payload is not empty (non-empty buffer)', function(done) { + singularSwitchTest("nempty", true, !false, Buffer.alloc(1), done); + }); + it('should check if payload is not empty (non-empty object)', function(done) { + singularSwitchTest("nempty", true, !false, {a:1}, done); + }); + it('should check if payload is not empty (null)', function(done) { + singularSwitchTest("nempty", true, false, null, done); + }); + it('should check if payload is not empty (undefined)', function(done) { + singularSwitchTest("nempty", true, false, undefined, done); + }); + it('should check if payload is not empty (0)', function(done) { + singularSwitchTest("nempty", true, false, 0, done); + }); + + it('should check input against a previous value', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{ "t": "gt", "v": "", "vt": "prev" }],checkall:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + + helper.load(switchNode, flow, function() { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + var c = 0; + helperNode1.on("input", function(msg) { + if (msg.payload) { + try { + if (c === 0) { + msg.payload.should.equal(1); + } + if (c === 1) { + msg.payload.should.equal(2); + done(); + } + c += 1; + } catch (err) { + done(err); + } + } else { + done(); + } + }); + switchNode1.receive({payload:1}); + switchNode1.receive({payload:0}); + switchNode1.receive({payload:-2}); + switchNode1.receive({payload:2}); + }); + }); + + it('should check input against a previous value (2nd option)', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t": "btwn", "v": "10", "vt": "num", "v2": "", "v2t": "prev" }],checkall:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + + helper.load(switchNode, flow, function() { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + var c = 0; + helperNode1.on("input", function(msg) { + if (msg.payload) { + try { + if (c === 0) { + msg.payload.should.equal(20); + } + if (c === 1) { + msg.payload.should.equal(25); + done(); + } + c += 1; + } catch (err) { + done(err); + } + } else { + //done(); + } + }); + switchNode1.receive({payload:0}); + switchNode1.receive({payload:20}); // between 10 and 0 + switchNode1.receive({payload:30}); // between 10 and 20 + switchNode1.receive({payload:20}); // between 10 and 30 yes + switchNode1.receive({payload:30}); // between 10 and 20 no + switchNode1.receive({payload:25}); // between 10 and 30 yes + }); + }); + + it('should check if input is indeed null', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"null"}],checkall:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + + helper.load(switchNode, flow, function() { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + if (msg.payload === null) { + done(); + } else { + console.log("msg is ",msg); + } + }); + switchNode1.receive({payload:null}); + }); + }); + + it('should check if input is indeed undefined', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"null"}],checkall:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + + helper.load(switchNode, flow, function() { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + if (msg.payload === undefined) { + done(); + } + else { + console.log("msg is ",msg); + } + }); + switchNode1.receive({payload:undefined}); + }); + }); + it('should treat non-existant msg property conditional as undefined', function(done) { + var flow = [{"id":"switchNode1","type":"switch","z":"feee1df.c3263e","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"this.does.not.exist","vt":"msg"}],"checkall":"true","outputs":1,"x":190,"y":440,"wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + + helper.load(switchNode, flow, function() { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + var received = []; + helperNode1.on("input", function(msg) { + received.push(msg); + }); + // First message should be dropped as payload is not undefined + switchNode1.receive({topic:"messageOne",payload:""}); + // Second message should pass through as payload is undefined + switchNode1.receive({topic:"messageTwo",payload:undefined}); + setTimeout(function() { + try { + received.should.have.lengthOf(1); + received[0].should.have.a.property("topic","messageTwo"); + done(); + } catch(err) { + done(err); + } + },500) + }); + }); + + it('should check if input is indeed not null', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"nnull"}],checkall:false,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + + helper.load(switchNode, flow, function() { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + if (msg.payload) { + done(); + } else { + try { + msg.payload.should.equal("Anything here"); + } catch (err) { + done(err); + } + } + }); + switchNode1.receive({payload:"Anything here"}); + }); + }); + + it('sends a message when the "else/otherwise" statement is selected' , function(done) { + singularSwitchTest("else", true, true, 123456, done); + }); + + it('handles more than one switch statement' , function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"eq","v":"Hello"},{"t":"cont","v":"ello"}, {"t":"else"}],checkall:true,outputs:3,wires:[["helperNode1"], ["helperNode2"], ["helperNode3"]]}, + {id:"helperNode1", type:"helper", wires:[]}, + {id:"helperNode2", type:"helper", wires:[]}, + {id:"helperNode3", type:"helper", wires:[]}]; + + + helper.load(switchNode, flow, function() { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + var helperNode2 = helper.getNode("helperNode2"); + var helperNode3 = helper.getNode("helperNode3"); + + var nodeHitCount = 0; + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("Hello"); + nodeHitCount++; + } catch (err) { + done(err); + } + }); + helperNode2.on("input", function(msg) { + try { + msg.payload.should.equal("Hello"); + nodeHitCount++; + if (nodeHitCount == 2) { + done(); + } else { + try { + should.fail(null, null, "Both statements should be triggered!"); + } catch (err) { + done(err); + } + } + } catch (err) { + done(err); + } + }); + helperNode3.on("input", function(msg) { + try { + should.fail(null, null, "The otherwise/else statement should not be triggered here!"); + } catch (err) { + done(err); + } + }); + switchNode1.receive({payload:"Hello"}); + }); + }); + + it('stops after first statement' , function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"eq","v":"Hello"},{"t":"cont","v":"ello"}, {"t":"else"}],checkall:"false",outputs:3,wires:[["helperNode1"], ["helperNode2"], ["helperNode3"]]}, + {id:"helperNode1", type:"helper", wires:[]}, + {id:"helperNode2", type:"helper", wires:[]}, + {id:"helperNode3", type:"helper", wires:[]}]; + + helper.load(switchNode, flow, function() { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + var helperNode2 = helper.getNode("helperNode2"); + var helperNode3 = helper.getNode("helperNode3"); + + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("Hello"); + done(); + } catch (err) { + done(err); + } + }); + helperNode2.on("input", function(msg) { + try { + should.fail(null, null, "The otherwise/else statement should not be triggered here!"); + } catch (err) { + done(err); + } + }); + helperNode3.on("input", function(msg) { + try { + should.fail(null, null, "The otherwise/else statement should not be triggered here!"); + } catch (err) { + done(err); + } + }); + switchNode1.receive({payload:"Hello"}); + }); + }); + + it('should handle JSONata expression', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"$abs(payload)",propertyType:"jsonata",rules:[{"t":"btwn","v":"$sqrt(16)","vt":"jsonata","v2":"$sqrt(36)","v2t":"jsonata"}],checkall:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSwitchTest(flow, true, -5, done); + }); + + it('should handle flow and global contexts with JSONata expression', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"$abs($flowContext(\"payload\"))",propertyType:"jsonata",rules:[{"t":"btwn","v":"$flowContext(\"vt\")","vt":"jsonata","v2":"$globalContext(\"v2t\")","v2t":"jsonata"}],checkall:true,outputs:1,wires:[["helperNode1"]],z:"flow"}, + {id:"helperNode1", type:"helper", wires:[],z:"flow"}, + {id:"flow",type:"tab"}]; + helper.load(switchNode, flow, function() { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + switchNode1.context().flow.set("payload",-5); + switchNode1.context().flow.set("vt",4); + switchNode1.context().global.set("v2t",6); + helperNode1.on("input", function(msg) { + try { + should.equal(msg.payload,"pass"); + done(); + } catch(err) { + done(err); + } + }); + switchNode1.receive({payload:"pass"}); + }); + }); + + it('should handle persistable flow and global contexts with JSONata expression', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"$abs($flowContext(\"payload\",\"memory1\"))",propertyType:"jsonata",rules:[{"t":"btwn","v":"$flowContext(\"vt\",\"memory1\")","vt":"jsonata","v2":"$globalContext(\"v2t\",\"memory1\")","v2t":"jsonata"}],checkall:true,outputs:1,wires:[["helperNode1"]],z:"flow"}, + {id:"helperNode1", type:"helper", wires:[],z:"flow"}, + {id:"flow",type:"tab"}]; + helper.load(switchNode, flow, function() { + initContext(function () { + var switchNode1 = helper.getNode("switchNode1"); + var helperNode1 = helper.getNode("helperNode1"); + switchNode1.context().flow.set(["payload","vt"],[-7,6],"memory1",function(){ + switchNode1.context().global.set("v2t",8,"memory1",function(){ + helperNode1.on("input", function(msg) { + try { + should.equal(msg.payload,"pass"); + done(); + } catch(err) { + done(err); + } + }); + switchNode1.receive({payload:"pass"}); + }); + }); + }); + }); + }); + + it('should handle env var expression', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"VAR",propertyType:"env",rules:[{"t":"eq","v":"VAL"}],checkall:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + process.env.VAR = "VAL"; + customFlowSwitchTest(flow, true, "OK", done); + }); + + + it('should take head of message sequence (no repair)', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"head","v":3}],checkall:false,repair:false,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSequenceSwitchTest(flow, [0, 1, 2, 3, 4], [0, 1, 2], false, undefined, done); + }); + + it('should take head of message sequence (repair)', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"head","v":3}],checkall:false,repair:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSequenceSwitchTest(flow, [0, 1, 2, 3, 4], [0, 1, 2], true, undefined, done); + }); + + it('should take head of message sequence (w. context)', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"head","v":"count",vt:"global"}],checkall:false,repair:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSequenceSwitchTest(flow, [0, 1, 2, 3, 4], [0, 1, 2], true, + function(node) { + node.context().global.set("count", 3); + }, done); + }); + + it('should take head of message sequence (w. JSONata)', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"head","v":"1+4/2",vt:"jsonata"}],checkall:false,repair:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSequenceSwitchTest(flow, [0, 1, 2, 3, 4], [0, 1, 2], true, undefined, done); + }); + + it('should take tail of message sequence (no repair)', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"tail","v":3}],checkall:true,repair:false,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSequenceSwitchTest(flow, [0, 1, 2, 3, 4], [2, 3, 4], false, undefined, done); + }); + + it('should take tail of message sequence (repair)', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"tail","v":3}],checkall:true,repair:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSequenceSwitchTest(flow, [0, 1, 2, 3, 4], [2, 3, 4], true, undefined, done); + }); + + it('should take slice of message sequence (no repair)', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"index","v":1,"v2":3}],checkall:true,repair:false,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSequenceSwitchTest(flow, [0, 1, 2, 3, 4], [1, 2, 3], false, undefined, done); + }); + + it('should take slice of message sequence (repair)', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"index","v":1,"v2":3}],checkall:true,repair:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSequenceSwitchTest(flow, [0, 1, 2, 3, 4], [1, 2, 3], true, undefined, done); + }); + + it('should check JSONata expression is true', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload", + rules:[{"t":"jsonata_exp","v":"payload%2 = 1","vt":"jsonata"}], + checkall:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSwitchTest(flow, true, 9, done); + }); + + it('should be able to use $I in JSONata expression', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"jsonata_exp","v":"$I % 2 = 1",vt:"jsonata"}],checkall:true,repair:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSequenceSwitchTest(flow, [0, 1, 2, 3, 4], [1, 3], true, undefined, done); + }); + + it('should be able to use $N in JSONata expression', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"jsonata_exp","v":"payload >= $N-2",vt:"jsonata"}],checkall:true,repair:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSequenceSwitchTest(flow, [0, 1, 2, 3, 4], [3, 4], true, undefined, done); + }); + + + function customFlowSequenceMultiSwitchTest(flow, seq_in, outs, repair, done) { + helper.load(switchNode, flow, function() { + var n1 = helper.getNode("n1"); + var port_count = Object.keys(outs).length; + var sid; + var ids = new Array(port_count).fill(undefined); + var counts = new Array(port_count).fill(0); + var vals = new Array(port_count); + var recv_count = 0; + for (var id in outs) { + if (outs.hasOwnProperty(id)) { + var out = outs[id]; + vals[out.port] = out.vals; + recv_count += out.vals.length; + } + } + var count = 0; + function check_msg(msg, ix, vf) { + try { + msg.should.have.property("payload"); + var payload = msg.payload; + msg.should.have.property("parts"); + vf(payload).should.be.ok(); + var parts = msg.parts; + var evals = vals[ix]; + parts.should.have.property("id"); + var id = parts.id; + if (repair) { + if (ids[ix] === undefined) { + ids[ix] = id; + } + else { + ids[ix].should.equal(id); + } + parts.should.have.property("count", evals.length); + parts.should.have.property("index", counts[ix]); + } + else { + if (sid === undefined) { + sid = id; + } + else { + sid.should.equal(id); + } + parts.should.have.property("count", seq_in.length); + parts.should.have.property("index", msg.xindex); + } + var index = parts.index; + var eindex = counts[ix]; + var value = evals[eindex]; + payload.should.equal(value); + counts[ix]++; + count++; + if (count === recv_count) { + done(); + } + } + catch (e) { + done(e); + } + } + for (var id in outs) { + if (outs.hasOwnProperty(id)) { + (function() { + var node = helper.getNode(id); + var port = outs[id].port; + var vf = outs[id].vf; + node.on("input", function(msg) { + check_msg(msg, port, vf); + }); + })(); + } + } + for(var i in seq_in) { + if (seq_in.hasOwnProperty(i)) { + n1.receive({payload:seq_in[i], xindex:i, + parts:{index:i, count:seq_in.length, id:222}}); + } + } + }); + } + + it('should not repair message sequence for each port', function(done) { + var flow = [{id:"n1",type:"switch",name:"switchNode",property:"payload", + rules:[{"t":"gt","v":0},{"t":"lt","v":0},{"t":"else"}], + checkall:true,repair:false, + outputs:3,wires:[["n2"],["n3"],["n4"]]}, + {id:"n2", type:"helper", wires:[]}, + {id:"n3", type:"helper", wires:[]}, + {id:"n4", type:"helper", wires:[]} + ]; + var data = [ 1, -2, 2, 0, -1 ]; + var outs = { + "n2" : { port:0, vals:[1, 2], + vf:function(x) { return(x > 0); } }, + "n3" : { port:1, vals:[-2, -1], + vf:function(x) { return(x < 0); } }, + "n4" : { port:2, vals:[0], + vf:function(x) { return(x == 0); } }, + }; + customFlowSequenceMultiSwitchTest(flow, data, outs, false, done); + }); + + it('should repair message sequence for each port', function(done) { + var flow = [{id:"n1",type:"switch",name:"switchNode",property:"payload", + rules:[{"t":"gt","v":0},{"t":"lt","v":0},{"t":"else"}], + checkall:true,repair:true, + outputs:3,wires:[["n2"],["n3"],["n4"]]}, + {id:"n2", type:"helper", wires:[]}, // >0 + {id:"n3", type:"helper", wires:[]}, // <0 + {id:"n4", type:"helper", wires:[]} // ==0 + ]; + var data = [ 1, -2, 2, 0, -1 ]; + var outs = { + "n2" : { port:0, vals:[1, 2], + vf:function(x) { return(x > 0); } }, + "n3" : { port:1, vals:[-2, -1], + vf:function(x) { return(x < 0); } }, + "n4" : { port:2, vals:[0], + vf:function(x) { return(x == 0); } }, + }; + customFlowSequenceMultiSwitchTest(flow, data, outs, true, done); + }); + + it('should repair message sequence for each port (overlap)', function(done) { + var flow = [{id:"n1",type:"switch",name:"switchNode",property:"payload", + rules:[{"t":"gte","v":0},{"t":"lte","v":0},{"t":"else"}], + checkall:true,repair:true, + outputs:3,wires:[["n2"],["n3"],["n4"]]}, + {id:"n2", type:"helper", wires:[]}, // >=0 + {id:"n3", type:"helper", wires:[]}, // <=0 + {id:"n4", type:"helper", wires:[]} // none + ]; + var data = [ 1, -2, 2, 0, -1 ]; + var outs = { + "n2" : { port:0, vals:[1, 2, 0], + vf:function(x) { return(x >= 0); } }, + "n3" : { port:1, vals:[-2, 0, -1], + vf:function(x) { return(x <= 0); } }, + "n4" : { port:2, vals:[], + vf:function(x) { return(false); } }, + }; + customFlowSequenceMultiSwitchTest(flow, data, outs, true, done); + }); + + it('should handle too many pending messages', function(done) { + var flow = [{id:"n1",type:"switch",name:"switchNode",property:"payload", + rules:[{"t":"tail","v":2}], + checkall:true,repair:false, + outputs:3,wires:[["n2"]]}, + {id:"n2", type:"helper", wires:[]} + ]; + helper.load(switchNode, flow, function() { + var n1 = helper.getNode("n1"); + RED.settings.nodeMessageBufferMaxLength = 2; + setTimeout(function() { + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "switch"; + }); + var evt = logEvents[0][0]; + evt.should.have.property('id', "n1"); + evt.should.have.property('type', "switch"); + evt.should.have.property('msg', "switch.errors.too-many"); + done(); + }, 150); + n1.receive({payload:3, parts:{index:2, count:4, id:222}}); + n1.receive({payload:2, parts:{index:1, count:4, id:222}}); + n1.receive({payload:4, parts:{index:3, count:4, id:222}}); + n1.receive({payload:1, parts:{index:0, count:4, id:222}}); + }); + }); + + it('should handle invalid jsonata expression', function(done) { + + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"$invalidExpression(payload)",propertyType:"jsonata",rules:[{"t":"btwn","v":"$sqrt(16)","vt":"jsonata","v2":"$sqrt(36)","v2t":"jsonata"}],checkall:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(switchNode, flow, function() { + var n1 = helper.getNode("switchNode1"); + setTimeout(function() { + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "switch"; + }); + var evt = logEvents[0][0]; + evt.should.have.property('id', "switchNode1"); + evt.should.have.property('type', "switch"); + done(); + }, 150); + n1.receive({payload:1}); + }); + }); + +}); diff --git a/packages/connector/test/nodes/core/function/15-change_spec.js b/packages/connector/test/nodes/core/function/15-change_spec.js new file mode 100644 index 0000000..1809d91 --- /dev/null +++ b/packages/connector/test/nodes/core/function/15-change_spec.js @@ -0,0 +1,1707 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); + +var changeNode = require("nr-test-utils").require("@node-red/nodes/core/function/15-change.js"); +var Context = require("nr-test-utils").require("@node-red/runtime/lib/nodes/context"); +var helper = require("node-red-node-test-helper"); + +describe('change Node', function() { + + beforeEach(function(done) { + helper.startServer(done); + }); + + function initContext(done) { + Context.init({ + contextStorage: { + memory0: { + module: "memory" + }, + memory1: { + module: "memory" + } + } + }); + Context.load().then(function () { + done(); + }); + } + + afterEach(function(done) { + helper.unload().then(function () { + return Context.clean({allNodes: {}}); + }).then(function () { + return Context.close(); + }).then(function () { + helper.stopServer(done); + }); + }); + + it('should load node with defaults', function(done) { + var flow = [{ id: "c1", type: "change", name:"change1" }]; + helper.load(changeNode, flow, function() { + helper.getNode("c1").should.have.property("name", "change1"); + helper.getNode("c1").should.have.property("rules", [{fromt:'str',pt:'msg',tot:'str',t:undefined,p:''}]); + done(); + }); + }); + it('should load defaults if set to replace', function(done) { + var flow = [{ id: "c1", type: "change", name:"change1", action:"replace" }]; + helper.load(changeNode, flow, function() { + helper.getNode("c1").should.have.property("name", "change1"); + helper.getNode("c1").should.have.property("rules", [ {fromt: 'str', p: '', pt: 'msg', t: 'set', to: '', tot: 'str'} ]); + done(); + }); + }); + it('should load defaults if set to change', function(done) { + var flow = [{ id: "c1", type: "change", name:"change1", action:"change" }]; + helper.load(changeNode, flow, function() { + //console.log(helper.getNode("c1")); + helper.getNode("c1").should.have.property("name", "change1"); + helper.getNode("c1").should.have.property("rules", [ { from: '', fromRE:/(?:)/g,fromt: 'str', p: '',pt: 'msg', re: undefined, t: 'change', to: '',tot: 'str' } ]); + done(); + }); + }); + it('should no-op if there are no rules', function(done) { + var flow = [{"id":"changeNode1","type":"change","rules":[],"action":"","property":"","from":"","to":"","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.should.eql(sentMsg); + done(); + } catch(err) { + done(err); + } + }); + var sentMsg = {payload:"leaveMeAlong"}; + changeNode1.receive(sentMsg); + }); + }); + + describe('#set' , function() { + + it('sets the value of the message property', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"replace","property":"payload","from":"","to":"changed","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("changed"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"changeMe"}); + }); + }); + + it('sets the value of global context property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t":"set","p":"globalValue","pt":"global","to":"changed","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + changeNode1.context().global.get("globalValue").should.equal("changed"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().global.set("globalValue","changeMe"); + changeNode1.receive({payload:""}); + }); + }); + + it('sets the value of persistable global context property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t":"set","p":"#:(memory1)::globalValue","pt":"global","to":"changed","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + changeNode1.context().global.get("globalValue", "memory1", function (err, val) { + val.should.equal("changed"); + done(); + }); + } catch(err) { + done(err); + } + }); + changeNode1.context().global.set("globalValue","changeMe","memory1", function (err) { + changeNode1.receive({payload:""}); + }); + }); + }); + }); + + it('sets the value and type of the message property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "set", "p": "payload", "pt": "msg", "to": "12345", "tot": "num" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal(12345); + var t = typeof(msg.payload); + t.should.equal("number"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"changeMe"}); + }); + }); + + it('sets the value of an already set multi-level message property', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"replace","property":"foo.bar","from":"","to":"bar","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.foo.bar.should.equal("bar"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({foo:{bar:"foo"}}); + }); + }); + + it('sets the value of an empty multi-level message property', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"replace","property":"foo.bar","from":"","to":"bar","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.foo.bar.should.equal("bar"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({}); + }); + }); + + it('sets the value of a message property to another message property', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"replace","property":"foo","from":"","to":"msg.fred","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + var rule = helper.getNode("changeNode1").rules[0]; + rule.t.should.eql('set'); + rule.tot.should.eql('msg'); + helperNode1.on("input", function(msg) { + try { + msg.foo.should.equal("bar"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({fred:"bar"}); + }); + }); + + it('sets the value of a multi-level message property to another multi-level message property', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"replace","property":"foo.bar","from":"","to":"msg.fred.red","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.foo.bar.should.equal("bar"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({fred:{red:"bar"}}); + }); + }); + + it('doesn\'t set the value of a message property when the \'to\' message property does not exist', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"replace","property":"foo.bar","from":"","to":"msg.fred.red","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + should.not.exist(msg.foo); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({}); + }); + }); + + it('overrides the value of a message property when the \'to\' message property does not exist', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"replace","property":"payload","from":"","to":"msg.foo","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + should.not.exist(msg.payload); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"Hello"}); + }); + }); + + it('sets the message property to null when the \'to\' message property equals null', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"replace","property":"payload","from":"","to":"msg.foo","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + (msg.payload === null).should.be.true(); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"Hello", foo:null}); + }); + }); + + it('does not set other properties using = inside to property', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"replace","property":"payload","from":"","to":"msg.otherProp=10","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + should.not.exist(msg.payload); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"changeMe"}); + }); + }); + + it('splits dot delimited properties into objects', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"replace","property":"pay.load","from":"","to":"10","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.pay.load.should.equal("10"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({pay:{load:"changeMe"}}); + }); + }); + + it('changes the value to flow context property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"flowValue","tot":"flow"}],"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.eql("Hello World!"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().flow.set("flowValue","Hello World!"); + changeNode1.receive({payload:""}); + }); + }); + + it('changes the value to persistable flow context property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"#:(memory1)::flowValue","tot":"flow"}],"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.eql("Hello World!"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().flow.set("flowValue","Hello World!","memory1",function(err) { + changeNode1.receive({payload:""}); + }); + }); + }); + }); + + it('changes the value to global context property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"globalValue","tot":"global"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.eql("Hello World!"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().global.set("globalValue","Hello World!"); + changeNode1.receive({payload:""}); + }); + }); + + it('changes the value to persistable global context property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"#:(memory1)::globalValue","tot":"global"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.eql("Hello World!"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().global.set("globalValue","Hello World!","memory1", function (err) { + changeNode1.receive({payload:""}); + }); + }); + }); + }); + + it('changes the value to a number', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"123","tot":"num"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.eql(123); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:""}); + }); + }); + + it('changes the value to a boolean value', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"true","tot":"bool"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.eql(true); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:""}); + }); + }); + + it('changes the value to a js object', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":'{"a":123}',"tot":"json"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.eql({a:123}); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:""}); + }); + }); + + it('changes the value to a buffer object', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"[72,101,108,108,111,32,87,111,114,108,100]","tot":"bin"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + var buff = Buffer.from("Hello World"); + msg.payload.should.eql(buff); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:""}); + }); + }); + + it('sets the value of the message property to the current timestamp', function(done) { + var flow = [{"id":"changeNode1","type":"change","rules":[{"t":"set","p":"ts","pt":"msg","to":"","tot":"date"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + (Date.now() - msg.ts).should.be.approximately(0,50); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:Date.now()}); + }); + }); + + describe('env var', function() { + before(function() { + process.env.NR_TEST_A = 'foo'; + }) + after(function() { + delete process.env.NR_TEST_A; + }) + it('sets the value using env property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","pt":"msg","to":"NR_TEST_A","tot":"env"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("foo"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"123",topic:"ABC"}); + }); + }); + }); + + + it('changes the value using jsonata', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"$length(payload)","tot":"jsonata"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.eql(12); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"Hello World!"}); + }); + }); + + it('reports invalid jsonata expression', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"$invalid(payload)","tot":"jsonata"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + done("Invalid jsonata expression passed message through"); + }); + changeNode1.on("call:error", function(err) { + // Expect error to be called + done(); + }); + changeNode1.receive({payload:"Hello World!"}); + }); + }); + + it('changes the value using flow context with jsonata', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"$flowContext(\"foo\")","tot":"jsonata"}],"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[],"z":"flow"},{"id":"flow","type":"tab"}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + changeNode1.context().flow.set("foo","bar"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.eql("bar"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"Hello World!"}); + }); + }); + + it('changes the value using global context with jsonata', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"$globalContext(\"foo\")","tot":"jsonata"}],"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[],"z":"flow"},{"id":"flow","type":"tab"}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + changeNode1.context().global.set("foo","bar"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.eql("bar"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"Hello World!"}); + }); + }); + + it('changes the value using persistable flow context with jsonata', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"$flowContext(\"foo\",\"memory1\")","tot":"jsonata"}],"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[],"z":"flow"},{"id":"flow","type":"tab"}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.eql("bar"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().flow.set("foo","bar","memory1",function(err){ + if(err){ + done(err); + }else{ + changeNode1.context().flow.set("foo","error!"); + changeNode1.receive({payload:"Hello World!"}); + } + }); + }); + }); + }); + + it('changes the value using persistable global context with jsonata', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"$globalContext(\"foo\",\"memory1\")","tot":"jsonata"}],"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[],"z":"flow"},{"id":"flow","type":"tab"}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.eql("bar"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().global.set("foo","bar","memory1",function(err){ + if(err){ + done(err); + }else{ + changeNode1.context().global.set("foo","error!"); + changeNode1.receive({payload:"Hello World!"}); + } + }); + }); + }); + }); + + }); + describe('#change', function() { + it('changes the value of the message property', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"change","property":"payload","from":"Hello","to":"Goodbye","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("Goodbye World!"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"Hello World!"}); + }); + }); + + it('changes the value and doesnt change type of the message property for partial match', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "payload", "pt": "msg", "from": "123", "fromt": "str", "to": "456", "tot": "num" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("Change456Me"); + var t = typeof(msg.payload); + t.should.equal("string"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"Change123Me"}); + }); + }); + + it('changes the value and type of the message property if a complete match', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "payload", "pt": "msg", "from": "123", "fromt": "str", "to": "456", "tot": "num" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal(456); + var t = typeof(msg.payload); + t.should.equal("number"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"123"}); + }); + }); + + it('changes the value of a multi-level message property', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"change","property":"foo.bar","from":"Hello","to":"Goodbye","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.foo.bar.should.equal("Goodbye World!"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({foo:{bar:"Hello World!"}}); + }); + }); + + it('sends unaltered message if the changed message property does not exist', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"change","property":"foo","from":"Hello","to":"Goodbye","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("Hello World!"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"Hello World!"}); + }); + }); + + it('sends unaltered message if a changed multi-level message property does not exist', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"change","property":"foo.bar","from":"Hello","to":"Goodbye","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("Hello World!"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"Hello World!"}); + }); + }); + + it('changes the value of the message property based on a regex', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"change","property":"payload","from":"\\d+","to":"NUMBER","reg":true,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("Replace all numbers NUMBER and NUMBER"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"Replace all numbers 12 and 14"}); + }); + }); + + it('supports regex groups', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"change","property":"payload","from":"(Hello)","to":"$1-$1-$1","reg":true,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("Hello-Hello-Hello World"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"Hello World"}); + }); + }); + + it('reports invalid regex', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"change","property":"payload","from":"\\+**+","to":"NUMBER","reg":true,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "change"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', 'changeNode1'); + done(); + + }); + }); + + it('supports regex groups - new rule format', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"(Hello)","to":"$1-$1-$1","fromt":"re","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("Hello-Hello-Hello World"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"Hello World"}); + }); + }); + + it('changes the value - new rule format', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"ABC","to":"123","fromt":"str","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("abc123abc"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"abcABCabc"}); + }); + }); + + it('changes the value using msg property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"topic","to":"123","fromt":"msg","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("abc123abc"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"abcABCabc",topic:"ABC"}); + }); + }); + + it('changes the value using flow context property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"topic","to":"123","fromt":"flow","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("abc123abc"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().flow.set("topic","ABC"); + changeNode1.receive({payload:"abcABCabc"}); + }); + }); + + it('changes the value using persistable flow context property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"#:(memory1)::topic","to":"123","fromt":"flow","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("abc123abc"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().flow.set("topic","ABC","memory1", function (err) { + changeNode1.receive({payload:"abcABCabc"}); + }); + }); + }); + }); + + it('changes the value using global context property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"topic","to":"123","fromt":"global","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("abc123abc"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().global.set("topic","ABC"); + changeNode1.receive({payload:"abcABCabc"}); + }); + }); + + it('changes the value using persistable global context property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"#:(memory1)::topic","to":"123","fromt":"global","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("abc123abc"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().global.set("topic","ABC","memory1",function (err) { + changeNode1.receive({payload:"abcABCabc"}); + }); + }); + }); + }); + + it('changes the number using global context property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"topic","to":"ABC","fromt":"global","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("ABC"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().global.set("topic",123); + changeNode1.receive({payload:123}); + }); + }); + + it('changes the number using persistable global context property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"#:(memory1)::topic","to":"ABC","fromt":"global","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("ABC"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().global.set("topic",123,"memory1",function (err) { + changeNode1.receive({payload:123}); + }); + }); + }); + }); + + it('changes the value using number - string payload', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"123","to":"456","fromt":"num","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("456"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"123"}); + }); + }); + + it('changes the value using number - number payload', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"123","to":"abc","fromt":"num","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("abc"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:123}); + }); + }); + + it('changes the value using boolean - string payload', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"true","to":"xxx","fromt":"bool","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("xxx"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"true"}); + }); + }); + + it('changes the value using boolean - boolean payload', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"true","to":"xxx","fromt":"bool","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("xxx"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:true}); + }); + }); + + it('changes the value of the global context', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "payload", "pt": "global", "from": "Hello", "fromt": "str", "to": "Goodbye", "tot": "str" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[],"z":"flow"}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + helperNode1.context().global.get("payload").should.equal("Goodbye World!"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().global.set("payload","Hello World!"); + changeNode1.receive({payload:""}); + }); + }); + + it('changes the value of the persistable global context', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "#:(memory1)::payload", "pt": "global", "from": "Hello", "fromt": "str", "to": "Goodbye", "tot": "str" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[],"z":"flow"}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + helperNode1.context().global.get("payload","memory1", function (err, val) { + val.should.equal("Goodbye World!"); + done(); + }); + } catch(err) { + done(err); + } + }); + changeNode1.context().global.set("payload","Hello World!","memory1",function (err) { + changeNode1.receive({payload:""}); + }); + }); + }); + }); + + it('changes the value and doesnt change type of the flow context for partial match', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "payload", "pt": "flow", "from": "123", "fromt": "str", "to": "456", "tot": "num" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[],"z":"flow"}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + helperNode1.context().flow.get("payload").should.equal("Change456Me"); + helperNode1.context().flow.get("payload").should.be.a.String(); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().flow.set("payload","Change123Me"); + changeNode1.receive({payload:""}); + }); + }); + + it('changes the value and doesnt change type of the persistable flow context for partial match', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "#:(memory1)::payload", "pt": "flow", "from": "123", "fromt": "str", "to": "456", "tot": "num" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[],"z":"flow"}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + helperNode1.context().flow.get("payload","memory1",function (err, val) { + val.should.equal("Change456Me"); + val.should.be.a.String(); + done(); + }); + } catch(err) { + done(err); + } + }); + changeNode1.context().flow.set("payload","Change123Me","memory1",function (err) { + changeNode1.receive({payload:""}); + }); + }); + }); + }); + + it('changes the value and type of the flow context if a complete match', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "payload", "pt": "flow", "from": "123", "fromt": "str", "to": "456", "tot": "num" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[],"z":"flow"}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + helperNode1.context().flow.get("payload").should.equal(456); + helperNode1.context().flow.get("payload").should.be.a.Number(); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().flow.set("payload","123"); + changeNode1.receive({payload:""}); + }); + }); + + it('changes the value and type of the persistable flow context if a complete match', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "#:(memory1)::payload", "pt": "flow", "from": "123", "fromt": "str", "to": "456", "tot": "num" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[],"z":"flow"}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + helperNode1.context().flow.get("payload","memory1",function (err, val) { + val.should.be.a.Number(); + val.should.equal(456); + done(); + }); + } catch(err) { + done(err); + } + }); + changeNode1.context().flow.set("payload","123","memory1",function (err) { + changeNode1.receive({payload:""}); + }); + }); + }); + }); + + it('changes the value using number - number flow context', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "payload", "pt": "flow", "from": "123", "fromt": "num", "to": "abc", "tot": "str" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[],"z":"flow"}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + helperNode1.context().flow.get("payload").should.equal("abc"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().flow.set("payload",123); + changeNode1.receive({payload:""}); + }); + }); + + it('changes the value using number - number persistable flow context', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "#:(memory1)::payload", "pt": "flow", "from": "123", "fromt": "num", "to": "abc", "tot": "str" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[],"z":"flow"}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + helperNode1.context().flow.get("payload","memory1",function (err, val) { + val.should.equal("abc"); + done(); + }); + } catch(err) { + done(err); + } + }); + changeNode1.context().flow.set("payload",123,"memory1",function (err) { + changeNode1.receive({payload:""}); + }); + }); + }); + }); + + it('changes the value using boolean - boolean flow context', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "payload", "pt": "flow", "from": "true", "fromt": "bool", "to": "abc", "tot": "str" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[],"z":"flow"}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + helperNode1.context().flow.get("payload").should.equal("abc"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().flow.set("payload",true); + changeNode1.receive({payload:""}); + }); + }); + + it('changes the value using boolean - boolean persistable flow context', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "#:(memory1)::payload", "pt": "flow", "from": "true", "fromt": "bool", "to": "abc", "tot": "str" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"}, + {id:"helperNode1", type:"helper", wires:[],"z":"flow"}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + helperNode1.context().flow.get("payload","memory1",function (err, val) { + val.should.equal("abc"); + done(); + }); + } catch(err) { + done(err); + } + }); + changeNode1.context().flow.set("payload",true,"memory1",function (err) { + changeNode1.receive({payload:""}); + }); + }); + }); + }); + + it('reports invalid fromValue', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"null","fromt":"msg","to":"abc","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + setTimeout(function() { + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "change"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', 'changeNode1'); + done(); + },25); + changeNode1.receive({payload:"",null:null}); + }); + }); + + describe('env var', function() { + before(function() { + process.env.NR_TEST_A = 'foo'; + }) + after(function() { + delete process.env.NR_TEST_A; + }) + it('changes the value using env property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"topic","to":"NR_TEST_A","fromt":"msg","tot":"env"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("abcfooabc"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"abcABCabc",topic:"ABC"}); + }); + }); + }); + + }); + + describe("#delete", function() { + it('deletes the value of the message property', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"delete","property":"payload","from":"","to":"","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.should.not.have.property('payload'); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"This won't get through!"}); + }); + }); + + it('deletes the value of global context property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "delete", "p": "globalValue", "pt": "global"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + changeNode1.context().global.should.not.have.property("globalValue"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.context().global.set("globalValue","Hello World!"); + changeNode1.receive({payload:""}); + }); + }); + + it('deletes the value of persistable global context property', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "delete", "p": "#:(memory1)::globalValue", "pt": "global"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + changeNode1.context().global.get("globalValue","memory1",function(err,val) { + should.equal(undefined); + done(); + }); + } catch(err) { + done(err); + } + }); + changeNode1.context().global.set("globalValue","Hello World!","memory1",function (err) { + changeNode1.receive({payload:""}); + }); + }); + }); + }); + + it('deletes the value of a multi-level message property', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"delete","property":"foo.bar","from":"","to":"","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.should.not.have.property('foo.bar'); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"This won't get through!", foo:{bar:"This will be deleted!"}}); + }); + }); + + it('sends unaltered message if the deleted message property does not exist', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"delete","property":"foo","from":"","to":"","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.should.not.have.property('foo'); + msg.payload.should.equal('payload'); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"payload"}); + }); + }); + + it('sends unaltered message if a deleted multi-level message property does not exist', function(done) { + var flow = [{"id":"changeNode1","type":"change","action":"delete","property":"foo.bar","from":"","to":"","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.should.not.have.property('foo.bar'); + msg.payload.should.equal('payload'); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"payload"}); + }); + }); + }); + + describe("#move", function() { + it('moves the value of the message property', function(done) { + var flow = [{"id":"changeNode1","type":"change","rules":[{"t":"move","p":"topic","pt":"msg","to":"payload","tot":"msg"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.should.not.have.property('topic'); + msg.should.have.property('payload'); + msg.payload.should.equal("You've got to move it move it."); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({topic:"You've got to move it move it.", payload:{foo:"bar"}}); + }); + }); + it('moves the value of a message property object', function(done) { + var flow = [{"id":"changeNode1","type":"change","rules":[{"t":"move","p":"topic","pt":"msg","to":"payload","tot":"msg"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.should.not.have.property('topic'); + msg.should.have.property('payload'); + msg.payload.should.have.property('foo'); + msg.payload.foo.should.have.property('bar'); + msg.payload.foo.bar.should.equal(1); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({topic:{foo:{bar:1}}, payload:"String"}); + }); + }); + it('moves the value of a message property object to a sub-property', function(done) { + var flow = [{"id":"changeNode1","type":"change","rules":[{"t":"move","p":"payload","pt":"msg","to":"payload.foo","tot":"msg"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.should.have.property('foo'); + msg.payload.foo.should.equal("bar"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:"bar"}); + }); + }); + it('moves the value of a message sub-property object to a property', function(done) { + var flow = [{"id":"changeNode1","type":"change","rules":[{"t":"move","p":"payload.foo","pt":"msg","to":"payload","tot":"msg"}],"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.should.equal("bar"); + (typeof msg.payload).should.equal("string"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload:{foo:"bar"}}); + }); + }); + }); + + describe('- multiple rules', function() { + it('handles multiple rules', function(done) { + var flow = [{"id":"changeNode1","type":"change","wires":[["helperNode1"]], + rules:[ + {t:"set",p:"payload",to:"newValue"}, + {t:"change",p:"changeProperty",from:"this",to:"that"}, + {t:"delete",p:"deleteProperty"} + ]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("newValue"); + msg.changeProperty.should.equal("change that value"); + should.not.exist(msg.deleteProperty); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({ + payload:"changeMe", + changeProperty:"change this value", + deleteProperty:"delete this value" + }); + }); + }); + + it('applies multiple rules in order', function(done) { + var flow = [{"id":"changeNode1","type":"change","wires":[["helperNode1"]], + rules:[ + {t:"set",p:"payload",to:"a this (hi)"}, + {t:"change",p:"payload",from:"this",to:"that"}, + {t:"change",p:"payload",from:"\\(.*\\)",to:"[new]",re:true}, + ]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal("a that [new]"); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({ + payload:"changeMe" + }); + }); + }); + + it('can access two persistable flow context property', function(done) { + var flow = [{"id":"changeNode1", "z":"t1", "type":"change", + "wires":[["helperNode1"]], + rules:[ + {"t":"set", "p":"val0", "to":"#:(memory0)::val", "tot":"flow"}, + {"t":"set", "p":"val1", "to":"#:(memory1)::val", "tot":"flow"} + ]}, + {id:"helperNode1", "z":"t1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.should.have.property("val0", "foo"); + msg.should.have.property("val1", "bar"); + done(); + } catch(err) { + done(err); + } + }); + var flow = changeNode1.context().flow; + flow.set("val", "foo", "memory0", function (err) { + flow.set("val", "bar", "memory1", function (err) { + changeNode1.receive({payload:""}); + }); + }); + }); + }); + }); + + it('can access two persistable global context property', function(done) { + var flow = [{"id":"changeNode1", "z":"t1", "type":"change", + "wires":[["helperNode1"]], + rules:[ + {"t":"set", "p":"val0", "to":"#:(memory0)::val", "tot":"global"}, + {"t":"set", "p":"val1", "to":"#:(memory1)::val", "tot":"global"} + ]}, + {id:"helperNode1", "z":"t1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.should.have.property("val0", "foo"); + msg.should.have.property("val1", "bar"); + done(); + } catch(err) { + done(err); + } + }); + var global = changeNode1.context().global; + global.set("val", "foo", "memory0", function (err) { + global.set("val", "bar", "memory1", function (err) { + changeNode1.receive({payload:""}); + }); + }); + }); + }); + }); + + it('can access persistable global & flow context property', function(done) { + var flow = [{"id":"changeNode1", "z":"t1", "type":"change", + "wires":[["helperNode1"]], + rules:[ + {"t":"set", "p":"val0", "to":"#:(memory0)::val", "tot":"flow"}, + {"t":"set", "p":"val1", "to":"#:(memory1)::val", "tot":"global"} + ]}, + {id:"helperNode1", "z":"t1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + initContext(function () { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.should.have.property("val0", "foo"); + msg.should.have.property("val1", "bar"); + done(); + } catch(err) { + done(err); + } + }); + var context = changeNode1.context(); + var flow = context.flow; + var global = context.global; + flow.set("val", "foo", "memory0", function (err) { + global.set("val", "bar", "memory1", function (err) { + changeNode1.receive({payload:""}); + }); + }); + }); + }); + }); + + }); +}); diff --git a/packages/connector/test/nodes/core/function/16-range_spec.js b/packages/connector/test/nodes/core/function/16-range_spec.js new file mode 100644 index 0000000..a0dcd00 --- /dev/null +++ b/packages/connector/test/nodes/core/function/16-range_spec.js @@ -0,0 +1,152 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); + +var rangeNode = require("nr-test-utils").require("@node-red/nodes/core/function/16-range.js"); +var helper = require("node-red-node-test-helper"); + +describe('range Node', function() { + + beforeEach(function(done) { + helper.startServer(done); + }); + + afterEach(function(done) { + helper.unload(); + helper.stopServer(done); + }); + + it('should load some defaults', function(done) { + var flow = [{"id":"rangeNode1","type":"range","name":"rangeNode"}]; + helper.load(rangeNode, flow, function() { + var rangeNode1 = helper.getNode("rangeNode1"); + rangeNode1.should.have.property('name', 'rangeNode'); + rangeNode1.should.have.property('round', false); + done(); + }); + }); + + /** + * Run a generic range test + * @param action - scale/clamp (range limit)/roll (modulo): what action to choose + * @param minin - map from minimum value + * @param maxin - map from maximum value + * @param minout - map to minimum value + * @param maxout - map to maximum value + * @param round - whether to round the result to the nearest integer + * @param aPayload - what payload to send to the range node + * @param expectedResult - what result we're expecting + * @param done - the callback to call when test done + */ + function genericRangeTest(action, minin, maxin, minout, maxout, round, aPayload, expectedResult, done) { + var flow = [{"id":"rangeNode1","type":"range","minin":minin,"maxin":maxin,"minout":minout,"maxout":maxout,"action":action,"round":round,"name":"rangeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(rangeNode, flow, function() { + var rangeNode1 = helper.getNode("rangeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.should.equal(expectedResult); + done(); + } catch(err) { + done(err); + } + }); + rangeNode1.receive({payload:aPayload}); + }); + } + + it('ranges numbers up tenfold', function(done) { + genericRangeTest("scale", 0, 100, 0, 1000, false, 50, 500, done); + }); + + it('ranges numbers down such as centimetres to metres', function(done) { + genericRangeTest("scale", 0, 100, 0, 1, false, 55, 0.55, done); + }); + + it('wraps numbers down say for degree/rotation reading 1/2', function(done) { + genericRangeTest("roll", 0, 10, 0, 360, true, 15, 180, done); // 1/2 around wrap => "one and a half turns" + }); + + it('wraps numbers around say for degree/rotation reading 1/3', function(done) { + genericRangeTest("roll", 0, 10, 0, 360, true, 13.3333, 120, done); // 1/3 around wrap => "one and a third turns" + }); + + it('wraps numbers around say for degree/rotation reading 1/4', function(done) { + genericRangeTest("roll", 0, 10, 0, 360, true, 12.5, 90, done); // 1/4 around wrap => "one and a quarter turns" + }); + + it('wraps numbers down say for degree/rotation reading 1/4', function(done) { + genericRangeTest("roll", 0, 10, 0, 360, true, -12.5, 270, done); // 1/4 backwards wrap => "one and a quarter turns backwards" + }); + + it('wraps numbers around say for degree/rotation reading 0', function(done) { + genericRangeTest("roll", 0, 10, 0, 360, true, -10, 0, done); + }); + + it('clamps numbers within a range - over max', function(done) { + genericRangeTest("clamp", 0, 10, 0, 1000, false, 111, 1000, done); + }); + + it('clamps numbers within a range - below min', function(done) { + genericRangeTest("clamp", 0, 10, 0, 1000, false, -1, 0, done); + }); + + it('just passes on msg if payload not present', function(done) { + var flow = [{"id":"rangeNode1","type":"range","minin":0,"maxin":100,"minout":0,"maxout":100,"action":"scale","round":true,"name":"rangeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(rangeNode, flow, function() { + var rangeNode1 = helper.getNode("rangeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.should.not.have.property('payload'); + msg.topic.should.equal("pass on"); + done(); + } catch(err) { + done(err); + } + }); + rangeNode1.receive({topic:"pass on"}); + }); + }); + + it('reports if input is not a number', function(done) { + var flow = [{"id":"rangeNode1","type":"range","minin":0,"maxin":0,"minout":0,"maxout":0,"action":"scale","round":true,"name":"rangeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(rangeNode, flow, function() { + var rangeNode1 = helper.getNode("rangeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + rangeNode1.on("call:log",function(args) { + var log = args.args[0]; + if (log.indexOf("notnumber") > -1) { + rangeNode1.log.restore(); + done(); + } else { + try { + should.fail(null, null, "Non-number inputs should be reported!"); + } catch (err) { + rangeNode1.log.restore(); + done(err); + } + } + }); + + rangeNode1.receive({payload:"NOT A NUMBER"}); + }); + }); +}); diff --git a/packages/connector/test/nodes/core/function/80-template_spec.js b/packages/connector/test/nodes/core/function/80-template_spec.js new file mode 100644 index 0000000..e944824 --- /dev/null +++ b/packages/connector/test/nodes/core/function/80-template_spec.js @@ -0,0 +1,498 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var templateNode = require("nr-test-utils").require("@node-red/nodes/core/function/80-template.js"); +var Context = require("nr-test-utils").require("@node-red/runtime/lib/nodes/context"); +var helper = require("node-red-node-test-helper"); + +describe('template node', function() { + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + beforeEach(function(done) { + done(); + }); + + function initContext(done) { + Context.init({ + contextStorage: { + memory0: { // do not use (for excluding effect fallback) + module: "memory" + }, + memory1: { + module: "memory" + }, + memory2: { + module: "memory" + } + } + }); + Context.load().then(function () { + done(); + }); + } + + afterEach(function() { + helper.unload().then(function () { + return Context.clean({allNodes:{}}); + }).then(function () { + return Context.close(); + }); + }); + + + it('should modify payload using node-configured template', function(done) { + var flow = [{id:"n1", type:"template", field:"payload", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'payload=foo'); + msg.should.have.property('template', 'this should be ignored as the node has its own template {{payload}}'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo",topic: "bar", template: "this should be ignored as the node has its own template {{payload}}"}); + }); + }); + + it('should modify the configured property using msg.template', function(done) { + var flow = [{id:"n1", type:"template", field:"randomProperty", template:"",wires:[["n2"]]},{id:"n2",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + msg.should.have.property('template', 'payload={{payload}}'); + msg.should.have.property('randomProperty', 'payload=foo'); + done(); + }); + n1.receive({payload:"foo", topic: "bar", template: "payload={{payload}}"}); + }); + }); + + it('should be able to overwrite msg.template using the template from msg.template', function(done) { + var flow = [{id:"n1", type:"template", field:"payload", template:"",wires:[["n2"]]},{id:"n2",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'topic=bar'); + msg.should.have.property('template', 'topic={{topic}}'); + done(); + }); + n1.receive({payload:"foo", topic: "bar", template: "topic={{topic}}"}); + }); + }); + + it('should modify payload from msg.template', function(done) { + var flow = [{id:"n1", type:"template", field:"payload", template:"",wires:[["n2"]]},{id:"n2",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var received = []; + n2.on("input", function(msg) { + try { + received.push(msg); + if (received.length === 3) { + received[0].should.have.property('topic', 'bar'); + received[0].should.have.property('payload', 'topic=bar'); + received[0].should.have.property('template', 'topic={{topic}}'); + + received[1].should.have.property('topic', 'another bar'); + received[1].should.have.property('payload', 'topic=another bar'); + received[1].should.have.property('template', 'topic={{topic}}'); + + received[2].should.have.property('topic', 'bar'); + received[2].should.have.property('payload', 'payload=foo'); + received[2].should.have.property('template', 'payload={{payload}}'); + done(); + } + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", topic: "bar", template: "topic={{topic}}"}); + n1.receive({payload:"foo", topic: "another bar", template: "topic={{topic}}"}); + n1.receive({payload:"foo", topic: "bar", template: "payload={{payload}}"}); + }); + }); + + it('should modify payload from flow context', function(done) { + var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{flow.value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().flow.set("value","foo"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'payload=foo'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should modify payload from persistable flow context', function(done) { + var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{flow[memory1].value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}]; + helper.load(templateNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'payload=foo'); + done(); + }); + n1.context().flow.set("value","foo","memory1",function (err) { + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + }); + + it('should handle nested context tags - property not set', function(done) { + // This comes from the Coursera Node-RED course and is a good example of + // multiple conditional tags + var template = `{{#flow.time}}time={{flow.time}}{{/flow.time}}{{^flow.time}}!time{{/flow.time}}{{#flow.random}}random={{flow.random}}randomtime={{flow.randomtime}}{{/flow.random}}{{^flow.random}}!random{{/flow.random}}`; + var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:template,wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}]; + helper.load(templateNode, flow, function() { + initContext(function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '!time!random'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }) + it('should handle nested context tags - property set', function(done) { + // This comes from the Coursera Node-RED course and is a good example of + // multiple conditional tags + var template = `{{#flow.time}}time={{flow.time}}{{/flow.time}}{{^flow.time}}!time{{/flow.time}}{{#flow.random}}random={{flow.random}}randomtime={{flow.randomtime}}{{/flow.random}}{{^flow.random}}!random{{/flow.random}}`; + var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:template,wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}]; + helper.load(templateNode, flow, function() { + initContext(function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'time=123random=456randomtime=789'); + done(); + } catch(err) { + done(err); + } + }); + n1.context().flow.set(["time","random","randomtime"],["123","456","789"],function (err) { + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + }) + + it('should modify payload from two persistable flow context', function(done) { + var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{flow[memory1].value}}/{{flow[memory2].value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}]; + helper.load(templateNode, flow, function() { + initContext(function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'payload=foo/bar'); + done(); + }); + n1.context().flow.set("value","foo","memory1",function (err) { + n1.context().flow.set("value","bar","memory2",function (err) { + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + }); + }); + + it('should modify payload from global context', function(done) { + var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{global.value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().global.set("value","foo"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'payload=foo'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should modify payload from persistable global context', function(done) { + var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{global[memory1].value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}]; + helper.load(templateNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'payload=foo'); + done(); + }); + n1.context().global.set("value","foo","memory1", function (err) { + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + }); + + it('should modify payload from two persistable global context', function(done) { + var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{global[memory1].value}}/{{global[memory2].value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}]; + helper.load(templateNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'payload=foo/bar'); + done(); + }); + n1.context().global.set("value","foo","memory1", function (err) { + n1.context().global.set("value","bar","memory2", function (err) { + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + }); + }); + + it('should modify payload from persistable flow & global context', function(done) { + var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{flow[memory1].value}}/{{global[memory1].value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}]; + helper.load(templateNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'payload=foo/bar'); + done(); + }); + n1.context().flow.set("value","foo","memory1", function (err) { + n1.context().global.set("value","bar","memory1", function (err) { + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + }); + }); + + it('should handle missing node context', function(done) { + // this is artificial test because in flow there is missing z property (probably never happen in real usage) + var flow = [{id:"n1",type:"template", field:"payload", template:"payload={{flow.value}},{{global.value}}",wires:[["n2"]]},{id:"n2",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'payload=,'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should handle escape characters in Mustache format and JSON output mode', function(done) { + var flow = [{id:"n1", type:"template", field:"payload", syntax:"mustache", template:"{\"data\":\"{{payload}}\"}", output:"json", wires:[["n2"]]},{id:"n2",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.payload.should.have.property('data', 'line\t1\nline\\2\r\nline\b3\f'); + done(); + }); + n1.receive({payload:"line\t1\nline\\2\r\nline\b3\f"}); + }); + }); + + it('should modify payload in plain text mode', function(done) { + var flow = [{id:"n1", type:"template", field:"payload", syntax:"plain", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'payload={{payload}}'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should modify flow context', function(done) { + var flow = [{id:"n1",z:"t1", type:"template", field:"payload", fieldType:"flow", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + // mesage is intact + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + // result is in flow context + n2.context().flow.get("payload").should.equal("payload=foo"); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should modify persistable flow context', function(done) { + var flow = [{id:"n1",z:"t1", type:"template", field:"#:(memory1)::payload", fieldType:"flow", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}]; + helper.load(templateNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + // mesage is intact + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + // result is in flow context + n2.context().flow.get("payload", "memory1", function (err, val) { + val.should.equal("payload=foo"); + done(); + }); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should modify global context', function(done) { + var flow = [{id:"n1",z:"t1", type:"template", field:"payload", fieldType:"global", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + // mesage is intact + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + // result is in global context + n2.context().global.get("payload").should.equal("payload=foo"); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should modify persistable global context', function(done) { + var flow = [{id:"n1",z:"t1", type:"template", field:"#:(memory1)::payload", fieldType:"global", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}]; + helper.load(templateNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + // mesage is intact + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + // result is in global context + n2.context().global.get("payload", "memory1", function (err, val) { + val.should.equal("payload=foo"); + done(); + }); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + }); + + it('should handle if the field isn\'t set', function(done) { + var flow = [{id:"n1", type:"template", template: "payload={{payload}}",wires:[["n2"]]},{id:"n2",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'payload=foo'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should handle deeper objects', function(done) { + var flow = [{id:"n1", type:"template", field: "topic.foo.bar", template: "payload={{payload.doh.rei.me}}",wires:[["n2"]]},{id:"n2",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic'); + msg.topic.should.have.property('foo'); + msg.topic.foo.should.have.a.property('bar', 'payload=foo'); + done(); + }); + n1.receive({payload:{doh:{rei:{me:"foo"}}}}); + }); + }); + + it('should handle block contexts objects', function(done) { + var flow = [{id:"n1", type:"template", template: "A{{#payload.A}}{{payload.A}}{{.}}{{/payload.A}}B",wires:[["n2"]]},{id:"n2",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload','AabcabcB'); + done(); + }); + n1.receive({payload:{A:"abc"}}); + }); + }); + + it('should raise error if passed bad template', function(done) { + var flow = [{id:"n1", type:"template", field: "payload", template: "payload={{payload",wires:[["n2"]]},{id:"n2",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + setTimeout(function() { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "template"; + }); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.toString().should.startWith("Unclosed tag at "); + done(); + },25); + n1.receive({payload:"foo"}); + }); + }); + +}); diff --git a/packages/connector/test/nodes/core/function/89-delay_spec.js b/packages/connector/test/nodes/core/function/89-delay_spec.js new file mode 100644 index 0000000..51583d8 --- /dev/null +++ b/packages/connector/test/nodes/core/function/89-delay_spec.js @@ -0,0 +1,722 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); + +var delayNode = require("nr-test-utils").require("@node-red/nodes/core/function/89-delay.js"); +var helper = require("node-red-node-test-helper"); + +var GRACE_PERCENTAGE=10; + +var nanosToSeconds = 1000000000; +var millisToSeconds = 1000; + +var secondsToMinutes = 60; +var secondsToHours = 3600; +var secondsToDays = 86400; + +describe('delay Node', function() { + + beforeEach(function(done) { + helper.startServer(done); + }); + + afterEach(function(done) { + helper.unload(); + helper.stopServer(done); + }); + + it('should be loaded', function(done) { + var flow = [{"id":"delayNode1","type":"delay", "nbRateUnits":"1", "name":"delayNode","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","rateUnits":"day","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"wires":[[]]}]; + helper.load(delayNode, flow, function() { + var delayNode1 = helper.getNode("delayNode1"); + delayNode1.should.have.property('name', 'delayNode'); + delayNode1.should.have.property('rate', 86400000); + done(); + }); + }); + + it('should be able to set rate to hour', function(done) { + var flow = [{"id":"delayNode1","type":"delay", "nbRateUnits":"1", "name":"delayNode","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","rateUnits":"hour","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"wires":[[]]}]; + helper.load(delayNode, flow, function() { + var delayNode1 = helper.getNode("delayNode1"); + delayNode1.should.have.property('name', 'delayNode'); + delayNode1.should.have.property('rate', 3600000); + done(); + }); + }); + + it('should be able to set rate to minute', function(done) { + var flow = [{"id":"delayNode1","type":"delay", "nbRateUnits":"1", "name":"delayNode","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","rateUnits":"minute","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"wires":[[]]}]; + helper.load(delayNode, flow, function() { + var delayNode1 = helper.getNode("delayNode1"); + delayNode1.should.have.property('name', 'delayNode'); + delayNode1.should.have.property('rate', 60000); + done(); + }); + }); + + var TimeUnitEnum = { + MILLIS : "milliseconds", + SECONDS : "seconds", + MINUTES : "minutes", + HOURS : "hours", + DAYS : "days" + } + + /** + * Tells whether two numeric values are close enough to each other + * @param actualValue - the value we're testing + * @param expectedValue - the value we're matching the test value against + * @param tolerancePercent - the percentage of tolerated deviation (0 means equals) + */ + function closeEnough(actualValue, expectedValue, tolerancePercent) { + var toReturn; + var toleranceFraction = expectedValue * (tolerancePercent/100); + var minExpected = expectedValue - toleranceFraction; + var maxExpected = expectedValue + toleranceFraction; + + if (actualValue >= minExpected && actualValue <= maxExpected) { + toReturn = true; + } else { + toReturn = false; + } + return toReturn; + } + + /** + * Runs a delay test + * @param aTimeout - the timeout quantity + * @param aTimeoutUnit - the unit of the timeout: milliseconds, seconds, minutes, hours, days + */ + function genericDelayTest(aTimeout, aTimeoutUnit, done) { + var flow = [{"id":"delayNode1","type":"delay","name":"delayNode","pauseType":"delay","timeout":aTimeout,"timeoutUnits":aTimeoutUnit,"rate":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(delayNode, flow, function() { + var delayNode1 = helper.getNode("delayNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + var endTime = process.hrtime(startTime); + var runtimeNanos = ( (endTime[0] * nanosToSeconds) + endTime[1] ); + var runtimeSeconds = runtimeNanos / nanosToSeconds; + var aTimeoutUnifiedToSeconds; + + // calculating the timeout in seconds + if (aTimeoutUnit == TimeUnitEnum.MILLIS) { + aTimeoutUnifiedToSeconds = aTimeout / millisToSeconds; + } else if (aTimeoutUnit == TimeUnitEnum.SECONDS) { + aTimeoutUnifiedToSeconds = aTimeout; + } else if (aTimeoutUnit == TimeUnitEnum.MINUTES) { + aTimeoutUnifiedToSeconds = aTimeout * secondsToMinutes; + } else if (aTimeoutUnit == TimeUnitEnum.HOURS) { + aTimeoutUnifiedToSeconds = aTimeout * secondsToHours; + } else if (aTimeoutUnit == TimeUnitEnum.DAYS) { + aTimeoutUnifiedToSeconds = aTimeout * secondsToDays; + } + + if (closeEnough(runtimeSeconds, aTimeoutUnifiedToSeconds, GRACE_PERCENTAGE)) { + done(); + } else { + try { + should.fail(null, null, "Delayed runtime seconds " + runtimeSeconds + " was not close enough to exlected timeout seconds: " + aTimeoutUnifiedToSeconds); + } catch (err) { + done(err); + } + } + } catch(err) { + done(err); + } + }); + var startTime = process.hrtime(); + delayNode1.receive({payload:"delayMe"}); + }); + } + + /** + * We send a message, take a timestamp then when the message is received by the helper node, we take another timestamp. + * Then check if the message has been delayed by the expected amount. + */ + it('delays the message in seconds', function(done) { + genericDelayTest(0.5, "seconds", done); + }); + + it('delays the message in milliseconds', function(done) { + genericDelayTest(500, "milliseconds", done); + }); + + it('delays the message in minutes', function(done) { // this is also 0.5 seconds + genericDelayTest(0.00833, "minutes", done); + }); + + it('delays the message in hours', function(done) { // this is also 0.5 seconds + genericDelayTest(0.0001388, "hours", done); + }); + + it('delays the message in days', function(done) { // this is also 0.5 seconds + genericDelayTest(0.000005787, "days", done); + }); + + /** + * Runs a rate limit test - only testing seconds! + * @param aLimit - the message limit count + * @param nbUnit - the multiple of the unit, aLimit Message for nbUnit Seconds + * @param runtimeInMillis - when to terminate run and count messages received + */ + function genericRateLimitSECONDSTest(aLimit, nbUnit, runtimeInMillis, done) { + var flow = [{"id":"delayNode1","type":"delay","nbRateUnits":nbUnit,"name":"delayNode","pauseType":"rate","timeout":5,"timeoutUnits":"seconds","rate":aLimit,"rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(delayNode, flow, function() { + var delayNode1 = helper.getNode("delayNode1"); + var helperNode1 = helper.getNode("helperNode1"); + var receivedMessagesStack = []; + var rate = 1000/aLimit; + + var receiveTimestamp; + + helperNode1.on("input", function(msg) { + if (receiveTimestamp) { + var elapse = process.hrtime(receiveTimestamp); + var receiveInterval = (elapse[0] * 1000) + ((elapse[1] / nanosToSeconds) * 1000); + receiveInterval.should.be.above(rate * 0.9); + } + receiveTimestamp = process.hrtime(); + receivedMessagesStack.push(msg); + }); + + var possibleMaxMessageCount = Math.ceil(aLimit * (runtimeInMillis / 1000) + aLimit); // +aLimit as at the start of the 2nd period, we're allowing the 3rd burst + + var i = 0; + for (; i < possibleMaxMessageCount + 1; i++) { + delayNode1.receive({payload:i}); + } + + setTimeout(function() { + try { + receivedMessagesStack.length.should.be.lessThan(possibleMaxMessageCount); + for (var j = 0; j < receivedMessagesStack.length; j++) { + if (receivedMessagesStack[j].payload === j) { + if (j === (receivedMessagesStack.length -1)) { // last message, all matched so far + done(); + } + } else { + should.fail(null, null, "Received messages were not received in order. Message was " + receivedMessagesStack[i].payload + " on count " + i); + } + } + } catch (err) { + done(err); + } + }, runtimeInMillis); + }); + } + + it('limits the message rate to 1 per second', function(done) { + genericRateLimitSECONDSTest(1, 1, 1500, done); + }); + + it('limits the message rate to 1 per 2 seconds', function(done) { + this.timeout(6000); + genericRateLimitSECONDSTest(1, 2, 3000, done); + }); + + it('limits the message rate to 2 per seconds, 2 seconds', function(done) { + this.timeout(6000); + genericRateLimitSECONDSTest(2, 1, 2100, done); + }); + + /** + * Runs a rate limit test with drop support - only testing seconds! + * @param aLimit - the message limit count + * @param nbUnit - the multiple of the unit, aLimit Message for nbUnit Seconds + * @param runtimeInMillis - when to terminate run and count messages received + */ + function dropRateLimitSECONDSTest(aLimit, nbUnit, runtimeInMillis, done) { + var flow = [{"id":"delayNode1","type":"delay","name":"delayNode","pauseType":"rate","timeout":5,"nbRateUnits":nbUnit,"timeoutUnits":"seconds","rate":aLimit,"rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(delayNode, flow, function() { + var delayNode1 = helper.getNode("delayNode1"); + var helperNode1 = helper.getNode("helperNode1"); + var receivedMessagesStack = []; + + // Add a small grace to the calculated delay + var rate = 1000/aLimit + 10; + + var receiveTimestamp; + + helperNode1.on("input", function(msg) { + if (receiveTimestamp) { + var elapse = process.hrtime(receiveTimestamp); + var receiveInterval = (elapse[0] * 1000) + ((elapse[1] / nanosToSeconds) * 1000); + receiveInterval.should.be.above(rate * 0.9); + } + receiveTimestamp = process.hrtime(); + receivedMessagesStack.push(msg); + }); + + var possibleMaxMessageCount = Math.ceil(aLimit * (runtimeInMillis / 1000) + aLimit); // +aLimit as at the start of the 2nd period, we're allowing the 3rd burst + + var i = 0; + delayNode1.receive({payload:i}); + i++; + for (; i < possibleMaxMessageCount + 1; i++) { + setTimeout(function() { + delayNode1.receive({payload:i}); + }, 2 * ((rate * i) / possibleMaxMessageCount) ); + } + + //we need to send a message delayed so that it doesn't get dropped + setTimeout(function() { + delayNode1.receive({payload:++i}); + }, runtimeInMillis - 300); // should give enough time to squeeze another message in + + setTimeout(function() { + try { + receivedMessagesStack.length.should.be.lessThan(possibleMaxMessageCount + 1); + receivedMessagesStack.length.should.be.greaterThan(2); // ensure that we receive more than 1st and last message + receivedMessagesStack[0].payload.should.be.exactly(0); // means we received the last message injected just before test termination + var foundAtLeastOneDrop = false; + for (var i = 0; i < receivedMessagesStack.length; i++) { + if (i > 0) { + if (receivedMessagesStack[i].payload - receivedMessagesStack[i - 1].payload > 1) { + foundAtLeastOneDrop = true; + } + } + } + foundAtLeastOneDrop.should.be.true(); + done(); + } catch (err) { + done(err); + } + }, runtimeInMillis); + }); + } + + it('limits the message rate to 1 per second, 4 seconds, with drop', function(done) { + this.timeout(6000); + dropRateLimitSECONDSTest(1, 1, 4000, done); + }); + + it('limits the message rate to 1 per 2 seconds, 4 seconds, with drop', function(done) { + this.timeout(6000); + dropRateLimitSECONDSTest(1, 2, 4500, done); + }); + + it('limits the message rate to 2 per second, 5 seconds, with drop', function(done) { + this.timeout(6000); + dropRateLimitSECONDSTest(2, 1, 5000, done); + }); + + /** + * Returns true if the actualTimeout is gracefully in between the timeoutFrom and timeoutTo + * values. Gracefully means that inBetween could actually mean smaller/greater values + * than the timeout range so long as it's within an actual grace percentage. + * @param timeoutFrom - The expected timeout range (low number) + * @param timeoutTo - The expected timeout range (high number) + * @param actualTimeout - The actual measured timeout value of test + * @param allowedGracePercent - The percentage of grace allowed + */ + function inBetweenDelays(timeoutFrom, timeoutTo, actualTimeout, allowedGracePercent) { + if (closeEnough(actualTimeout, timeoutFrom, allowedGracePercent)) { + return true; + } else if (closeEnough(actualTimeout, timeoutTo, allowedGracePercent)) { + return true; + } else if (timeoutFrom < actualTimeout && timeoutTo > actualTimeout) { + return true; + } else { + return false; + } + } + + /** + * Runs a VARIABLE DELAY test, checks if the delay is in between the given timeout values + * @param aTimeoutFrom - the timeout quantity which is the minimal acceptable wait period + * @param aTimeoutTo - the timeout quantity which is the maximum acceptable wait period + * @param aTimeoutUnit - the unit of the timeout: milliseconds, seconds, minutes, hours, days + * @param delay - the variable delay: milliseconds + */ + function variableDelayTest(aTimeoutFrom, aTimeoutTo, aTimeoutUnit, delay, done) { + var flow = [{"id":"delayNode1","type":"delay","name":"delayNode","pauseType":"delayv","timeout":0.5,"timeoutUnits":"seconds","rate":"1","rateUnits":"second","randomFirst":aTimeoutFrom,"randomLast":aTimeoutTo,"randomUnits":aTimeoutUnit,"drop":false,"wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(delayNode, flow, function() { + var delayNode1 = helper.getNode("delayNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + var endTime = process.hrtime(startTime); + var runtimeNanos = ( (endTime[0] * nanosToSeconds) + endTime[1] ); + var runtimeSeconds = runtimeNanos / nanosToSeconds; + var aTimeoutFromUnifiedToSeconds; + var aTimeoutToUnifiedToSeconds; + + // calculating the timeout in seconds + if (aTimeoutUnit == TimeUnitEnum.MILLIS) { + aTimeoutFromUnifiedToSeconds = aTimeoutFrom / millisToSeconds; + aTimeoutToUnifiedToSeconds = aTimeoutTo / millisToSeconds; + } else if (aTimeoutUnit == TimeUnitEnum.SECONDS) { + aTimeoutFromUnifiedToSeconds = aTimeoutFrom; + aTimeoutToUnifiedToSeconds = aTimeoutTo; + } else if (aTimeoutUnit == TimeUnitEnum.MINUTES) { + aTimeoutFromUnifiedToSeconds = aTimeoutFrom * secondsToMinutes; + aTimeoutToUnifiedToSeconds = aTimeoutTo * secondsToMinutes; + } else if (aTimeoutUnit == TimeUnitEnum.HOURS) { + aTimeoutFromUnifiedToSeconds = aTimeoutFrom * secondsToHours; + aTimeoutToUnifiedToSeconds = aTimeoutTo * secondsToHours; + } else if (aTimeoutUnit == TimeUnitEnum.DAYS) { + aTimeoutFromUnifiedToSeconds = aTimeoutFrom * secondsToDays; + aTimeoutToUnifiedToSeconds = aTimeoutTo * secondsToDays; + } + + if (inBetweenDelays(aTimeoutFromUnifiedToSeconds, aTimeoutToUnifiedToSeconds, runtimeSeconds, GRACE_PERCENTAGE)) { + done(); + } else { + try { + should.fail(null, null, "Delayed runtime seconds " + runtimeSeconds + " was not \"in between enough\" enough to expected values of: " + aTimeoutFromUnifiedToSeconds + " and " + aTimeoutToUnifiedToSeconds); + } catch (err) { + done(err); + } + } + } catch(err) { + done(err); + } + }); + var startTime = process.hrtime(); + delayNode1.receive({payload:"delayMe", delay:delay}); + }); + } + + it('variable delay set by msg.delay the message in milliseconds', function(done) { + variableDelayTest("200", "300", "milliseconds", 250, done); + }); + + it('variable delay is the default if msg.delay not specified', function(done) { + variableDelayTest("450", "550", "milliseconds", null, done); + }); + + it('variable delay is zero if msg.delay is zero', function(done) { + variableDelayTest("0", "20", "milliseconds", 0, done); + }); + + it('variable delay is zero if msg.delay is negative', function(done) { + variableDelayTest("0", "20", "milliseconds", -250, done); + }); + + /** + * Runs a RANDOM DELAY test, checks if the delay is in between the given timeout values + * @param aTimeoutFrom - the timeout quantity which is the minimal acceptable wait period + * @param aTimeoutTo - the timeout quantity which is the maximum acceptable wait period + * @param aTimeoutUnit - the unit of the timeout: milliseconds, seconds, minutes, hours, days + */ + function randomDelayTest(aTimeoutFrom, aTimeoutTo, aTimeoutUnit, done) { + var flow = [{"id":"delayNode1","type":"delay","name":"delayNode","pauseType":"random","timeout":5,"timeoutUnits":"seconds","rate":"1","rateUnits":"second","randomFirst":aTimeoutFrom,"randomLast":aTimeoutTo,"randomUnits":aTimeoutUnit,"drop":false,"wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(delayNode, flow, function() { + var delayNode1 = helper.getNode("delayNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + var endTime = process.hrtime(startTime); + var runtimeNanos = ( (endTime[0] * nanosToSeconds) + endTime[1] ); + var runtimeSeconds = runtimeNanos / nanosToSeconds; + var aTimeoutFromUnifiedToSeconds; + var aTimeoutToUnifiedToSeconds; + + // calculating the timeout in seconds + if (aTimeoutUnit == TimeUnitEnum.MILLIS) { + aTimeoutFromUnifiedToSeconds = aTimeoutFrom / millisToSeconds; + aTimeoutToUnifiedToSeconds = aTimeoutTo / millisToSeconds; + } else if (aTimeoutUnit == TimeUnitEnum.SECONDS) { + aTimeoutFromUnifiedToSeconds = aTimeoutFrom; + aTimeoutToUnifiedToSeconds = aTimeoutTo; + } else if (aTimeoutUnit == TimeUnitEnum.MINUTES) { + aTimeoutFromUnifiedToSeconds = aTimeoutFrom * secondsToMinutes; + aTimeoutToUnifiedToSeconds = aTimeoutTo * secondsToMinutes; + } else if (aTimeoutUnit == TimeUnitEnum.HOURS) { + aTimeoutFromUnifiedToSeconds = aTimeoutFrom * secondsToHours; + aTimeoutToUnifiedToSeconds = aTimeoutTo * secondsToHours; + } else if (aTimeoutUnit == TimeUnitEnum.DAYS) { + aTimeoutFromUnifiedToSeconds = aTimeoutFrom * secondsToDays; + aTimeoutToUnifiedToSeconds = aTimeoutTo * secondsToDays; + } + + if (inBetweenDelays(aTimeoutFromUnifiedToSeconds, aTimeoutToUnifiedToSeconds, runtimeSeconds, GRACE_PERCENTAGE)) { + done(); + } else { + try { + should.fail(null, null, "Delayed runtime seconds " + runtimeSeconds + " was not \"in between enough\" enough to expected values of: " + aTimeoutFromUnifiedToSeconds + " and " + aTimeoutToUnifiedToSeconds); + } catch (err) { + done(err); + } + } + } catch(err) { + done(err); + } + }); + var startTime = process.hrtime(); + delayNode1.receive({payload:"delayMe"}); + }); + } + + it('randomly delays the message in seconds', function(done) { + randomDelayTest(0.4, 0.8, "seconds", done); + }); + + it('randomly delays the message in milliseconds', function(done) { + randomDelayTest("400", "800", "milliseconds", done); + }); + + it('randomly delays the message in minutes', function(done) { + randomDelayTest(0.0066, 0.0133, "minutes", done); + }); + + it('delays the message in hours', function(done) { + randomDelayTest(0.000111111, 0.000222222, "hours", done); + }); + + it('delays the message in days', function(done) { + randomDelayTest(0.0000046296, 0.0000092593, "days", done); + }); + + it('handles delay queue', function(done) { + this.timeout(2000); + var flow = [{id:"delayNode1", type :"delay","name":"delayNode","nbRateUnits":"1","pauseType":"queue","timeout":1,"timeoutUnits":"seconds","rate":4,"rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(delayNode, flow, function() { + var delayNode1 = helper.getNode("delayNode1"); + var helperNode1 = helper.getNode("helperNode1"); + var t = Date.now(); + helperNode1.on("input", function(msg) { + msg.should.have.a.property('payload'); + msg.should.have.a.property('topic'); + try { + if (msg.topic === "_none_") { + msg.payload.should.equal(2); + (Date.now() - t).should.be.approximately(500,200); + } + else if (msg.topic === "A") { + msg.payload.should.equal(4); + (Date.now() - t).should.be.approximately(750,200); + } + else { + msg.topic.should.equal("B"); + msg.payload.should.equal(1); + (Date.now() - t).should.be.approximately(1000,200); + done(); + } + } catch(e) { + done(e); + } + }); + setTimeout(function() { + // send test messages + delayNode1.receive({payload:1}); // send something with blank topic + delayNode1.receive({payload:1,topic:"A"}); // and something with a fixed topic + delayNode1.receive({payload:1,topic:"B"}); // and something else with a fixed topic (3rd tick) + delayNode1.receive({payload:2,topic:"A"}); // these should replace them in queue + delayNode1.receive({payload:3,topic:"A"}); // ditto + delayNode1.receive({payload:2}); // so only this should get out on first tick + delayNode1.receive({payload:4,topic:"A"}); // and this one on second tick + }, 275); // wait one tick beofre starting.. (to test no messages in queue path.) + }); + }); + + it('handles timed queue', function(done) { + this.timeout(2000); + var flow = [{"id":"delayNode1","type":"delay","name":"delayNode","pauseType":"timed","timeout":1,"timeoutUnits":"seconds","rate":2,"rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(delayNode, flow, function() { + var delayNode1 = helper.getNode("delayNode1"); + var helperNode1 = helper.getNode("helperNode1"); + var t = Date.now(); + helperNode1.on("input", function(msg) { + msg.should.have.a.property('payload'); + msg.should.have.a.property('topic'); + try { + if (msg.topic === "_none_") { + msg.payload.should.equal(2); + (Date.now() - t).should.be.approximately(500,200); + } + else if (msg.topic === "A") { + msg.payload.should.equal(4); + (Date.now() - t).should.be.approximately(500,200); + } + else { + msg.topic.should.equal("B"); + msg.payload.should.equal(1); + (Date.now() - t).should.be.approximately(500,200); + done(); + } + } catch(e) { + done(e); + } + }); + + // send test messages + delayNode1.receive({payload:1}); // send something with blank topic + delayNode1.receive({payload:1,topic:"A"}); // and something with a fixed topic + delayNode1.receive({payload:1,topic:"B"}); // and something else with a fixed topic + delayNode1.receive({payload:2,topic:"A"}); // these should replace them in queue + delayNode1.receive({payload:3,topic:"A"}); // ditto + delayNode1.receive({payload:2}); // so all should go on first tick + delayNode1.receive({payload:4,topic:"A"}); // and nothing on second + }); + }); + + it('can flush delay queue', function(done) { + this.timeout(2000); + var flow = [{"id":"delayNode1","type":"delay","name":"delayNode","pauseType":"delay","timeout":1,"timeoutUnits":"seconds","rate":2,"rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(delayNode, flow, function() { + var delayNode1 = helper.getNode("delayNode1"); + var helperNode1 = helper.getNode("helperNode1"); + var t = Date.now(); + var c = 0; + helperNode1.on("input", function(msg) { + msg.should.have.a.property('payload'); + msg.should.have.a.property('topic'); + try { + if (msg.topic === "foo") { + msg.payload.should.equal(1); + (Date.now() - t).should.be.approximately(0,100); + c = c + 1; + } + else { + if (msg.topic === "bar") { + msg.payload.should.equal(1); + (Date.now() - t).should.be.approximately(0,100); + c = c + 1; + } + } + if (c === 5) { done(); } + } catch(e) { + done(e); + } + }); + + // send test messages + delayNode1.receive({payload:1,topic:"foo"}); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({flush:true}); }); // reset the queue + }); + }); + + it('can reset delay queue', function(done) { + this.timeout(2000); + var flow = [{"id":"delayNode1","type":"delay","name":"delayNode","pauseType":"delay","timeout":1,"timeoutUnits":"seconds","rate":2,"rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(delayNode, flow, function() { + var delayNode1 = helper.getNode("delayNode1"); + var helperNode1 = helper.getNode("helperNode1"); + var t = Date.now(); + var c = 0; + helperNode1.on("input", function(msg) { + c = c + 1; + }); + + setTimeout( function() { + if (c === 0) { done(); } + }, 700); + + // send test messages + delayNode1.receive({payload:1,topic:"foo"}); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({reset:true}); }); // reset the queue + }); + }); + + it('can flush rate limit queue', function(done) { + this.timeout(2000); + var flow = [{"id":"delayNode1","type":"delay","name":"delayNode","pauseType":"rate","timeout":1,"timeoutUnits":"seconds","rate":2,"rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(delayNode, flow, function() { + var delayNode1 = helper.getNode("delayNode1"); + var helperNode1 = helper.getNode("helperNode1"); + var t = Date.now(); + var c = 0; + helperNode1.on("input", function(msg) { + msg.should.have.a.property('payload'); + msg.should.have.a.property('topic'); + try { + if (msg.topic === "foo") { + msg.payload.should.equal(1); + (Date.now() - t).should.be.approximately(0,100); + c = c + 1; + } + else { + if (msg.topic === "bar") { + msg.payload.should.equal(1); + (Date.now() - t).should.be.approximately(0,100); + c = c + 1; + } + } + if (c === 5) { done(); } + } catch(e) { + done(e); + } + }); + + // send test messages + delayNode1.receive({payload:1,topic:"foo"}); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({flush:true}); }); // reset the queue + }); + }); + + it('can reset rate limit queue', function(done) { + this.timeout(2000); + var flow = [{"id":"delayNode1","type":"delay","name":"delayNode","pauseType":"rate","timeout":1,"timeoutUnits":"seconds","rate":2,"rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(delayNode, flow, function() { + var delayNode1 = helper.getNode("delayNode1"); + var helperNode1 = helper.getNode("helperNode1"); + var t = Date.now(); + var c = 0; + helperNode1.on("input", function(msg) { + msg.should.have.a.property('payload'); + msg.should.have.a.property('topic'); + try { + if (msg.topic === "foo") { + msg.payload.should.equal(1); + (Date.now() - t).should.be.approximately(0,100); + c = c + 1; + } + } catch(e) { + done(e); + } + }); + + setTimeout( function() { + if (c === 1) { done(); } + }, 700); + + // send test messages + delayNode1.receive({payload:1,topic:"foo"}); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({payload:1,topic:"bar"}); } ); // send something with blank topic + setImmediate( function() { delayNode1.receive({reset:true}); }); // reset the queue + }); + }); +}); diff --git a/packages/connector/test/nodes/core/function/89-trigger_spec.js b/packages/connector/test/nodes/core/function/89-trigger_spec.js new file mode 100644 index 0000000..7d74505 --- /dev/null +++ b/packages/connector/test/nodes/core/function/89-trigger_spec.js @@ -0,0 +1,1011 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); +var helper = require("node-red-node-test-helper"); +var triggerNode = require("nr-test-utils").require("@node-red/nodes/core/function/89-trigger.js"); +var Context = require("nr-test-utils").require("@node-red/runtime/lib/nodes/context"); +var RED = require("nr-test-utils").require("node-red/lib/red"); + +describe('trigger node', function() { + + beforeEach(function(done) { + helper.startServer(done); + }); + + function initContext(done) { + Context.init({ + contextStorage: { + memory0: { + module: "memory" + }, + memory1: { + module: "memory" + }, + memory2: { + module: "memory" + } + } + }); + Context.load().then(function () { + done(); + }); + } + + afterEach(function(done) { + helper.unload().then(function () { + return Context.clean({allNodes: {}}); + }).then(function () { + return Context.close(); + }).then(function () { + helper.stopServer(done); + }); + }); + + it("should be loaded with correct defaults", function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", "wires":[[]]}]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('name', 'triggerNode'); + n1.should.have.property('op1', '1'); + n1.should.have.property('op2', '0'); + n1.should.have.property('op1type', 'str'); + n1.should.have.property('op2type', 'str'); + n1.should.have.property('extend', "false"); + n1.should.have.property('units', 'ms'); + n1.should.have.property('duration', 250); + done(); + }); + }); + + it("should be able to set delay in seconds", function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", units:"s", duration:"1", "wires":[[]]}]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('duration', 1000); + done(); + }); + }); + + it("should be able to set delay in minutes", function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", units:"min", duration:"1", "wires":[[]]}]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('duration', 60000); + done(); + }); + }); + + it("should be able to set delay in hours", function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", units:"hr", duration:"1", "wires":[[]]}]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('duration', 3600000); + done(); + }); + }); + + function basicTest(type, val, rval) { + it('should output 1st value when triggered ('+type+')', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:val, op1type:type, op2:"", op2type:"null", duration:"20", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + process.env[val] = rval; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + if (rval) { + msg.should.have.property("payload"); + should.deepEqual(msg.payload, rval); + } + else { + msg.should.have.property("payload", val); + } + delete process.env[val]; + done(); + } + catch(err) { done(err); } + }); + n1.emit("input", {payload:null}); + }); + }); + + it('should output 2st value when triggered ('+type+')', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:"foo", op1type:"str", op2:val, op2type:type, duration:"20", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + process.env[val] = rval; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + if (c === 0) { + msg.should.have.property("payload", "foo"); + c++; + } + else { + if (rval) { + msg.should.have.property("payload"); + should.deepEqual(msg.payload, rval); + } + else { + msg.should.have.property("payload", val); + } + delete process.env[val]; + done(); + } + } + catch(err) { done(err); } + }); + n1.emit("input", {payload:null}); + }); + }); + } + + basicTest("num", 10); + basicTest("str", "10"); + basicTest("bool", true); + var val_json = '{ "x":"vx", "y":"vy", "z":"vz" }'; + basicTest("json", val_json, JSON.parse(val_json)); + var val_buf = "[1,2,3,4,5]"; + basicTest("bin", val_buf, Buffer.from(JSON.parse(val_buf))); + basicTest("env", "NR-TEST", "env-val"); + + it('should output 1 then 0 when triggered (default)', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", duration:"20", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + if (c === 0) { + msg.should.have.a.property("payload", '1'); + c+=1; + } + else { + msg.should.have.a.property("payload", '0'); + done(); + } + } + catch(err) { done(err); } + }); + n1.emit("input", {payload:null}); + }); + }); + + it('should ignore any other inputs while triggered if extend is false', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", duration:"50",wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + var errored = false; + n2.on("input", function(msg) { + try { + if (c === 0) { + msg.should.have.a.property("payload", '1'); + } + else { + msg.should.have.a.property("payload", '0'); + } + c+=1; + }catch(err) { + errored = true; + done(err); + } + }); + setTimeout( function() { + if (!errored) { + try { + c.should.equal(2); + done(); + } catch(err) { + done(err); + } + } + },100); + n1.emit("input", {payload:null}); + setTimeout( function() { + n1.emit("input", {payload:null}); + },10); + setTimeout( function() { + n1.emit("input", {payload:null}); + },30); + }); + }); + + it('should handle true and false as strings and delay of 0', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:"true",op1type:"val",op2:"false",op2type:"val",duration:"30", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + if (c === 0) { + msg.should.have.a.property("payload", true); + c+=1; + } + else { + msg.should.have.a.property("payload", false); + done(); + } + } catch(err) { + done(err); + } + }); + n1.emit("input", {payload:null}); + }); + }); + + it('should handle multiple topics as one if not asked to handle', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", bytopic:"all", op1:"1", op2:"0", op1type:"num", op2type:"num", duration:"30", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + c += 1; + if (c === 1) { + msg.should.have.a.property("payload", 1); + msg.should.have.a.property("topic", "A"); + } + else if (c === 2) { + msg.should.have.a.property("payload", 0); + msg.should.have.a.property("topic", "A"); + done(); + } + } catch(err) { + done(err); + } + }); + n1.emit("input", {payload:1,topic:"A"}); + n1.emit("input", {payload:2,topic:"B"}); + n1.emit("input", {payload:3,topic:"C"}); + }); + }); + + it('should handle multiple topics individually if asked to do so', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", bytopic:"topic", op1:"1", op2:"0", op1type:"num", op2type:"num", duration:"30", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + c += 1; + if (c === 1) { + msg.should.have.a.property("payload", 1); + msg.should.have.a.property("topic", "A"); + } + else if (c === 2) { + msg.should.have.a.property("payload", 1); + msg.should.have.a.property("topic", "B"); + } + else if (c === 3) { + msg.should.have.a.property("payload", 1); + msg.should.have.a.property("topic", "C"); + } + else if (c === 4) { + msg.should.have.a.property("payload", 0); + msg.should.have.a.property("topic", "A"); + } + else if (c === 5) { + msg.should.have.a.property("payload", 0); + msg.should.have.a.property("topic", "B"); + } + else if (c === 6) { + msg.should.have.a.property("payload", 0); + msg.should.have.a.property("topic", "C"); + done(); + } + } catch(err) { + done(err); + } + }); + n1.emit("input", {payload:1,topic:"A"}); + n1.emit("input", {payload:2,topic:"B"}); + n1.emit("input", {payload:3,topic:"C"}); + }); + }); + + it('should handle multiple topics individually, and extend one, if asked to do so', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", bytopic:"topic", extend:"true", op1:"1", op2:"0", op1type:"num", op2type:"num", duration:"30", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + c += 1; + if (c === 1) { + msg.should.have.a.property("payload", 1); + msg.should.have.a.property("topic", "A"); + } + else if (c === 2) { + msg.should.have.a.property("payload", 1); + msg.should.have.a.property("topic", "B"); + } + else if (c === 3) { + msg.should.have.a.property("payload", 1); + msg.should.have.a.property("topic", "C"); + } + else if (c === 4) { + msg.should.have.a.property("payload", 0); + msg.should.have.a.property("topic", "A"); + } + else if (c === 5) { + msg.should.have.a.property("payload", 0); + msg.should.have.a.property("topic", "C"); + } + else if (c === 6) { + msg.should.have.a.property("payload", 0); + msg.should.have.a.property("topic", "B"); + done(); + } + } catch(err) { + done(err); + } + }); + n1.emit("input", {payload:1,topic:"A"}); + n1.emit("input", {payload:2,topic:"B"}); + n1.emit("input", {payload:3,topic:"C"}); + setTimeout( function() { n1.emit("input", {payload:2,topic:"B"})}, 20 ); + }); + }); + + it('should be able to return things from flow and global context variables', function(done) { + var spy = sinon.stub(RED.util, 'evaluateNodeProperty', + function(arg1, arg2, arg3, arg4, arg5) { if (arg5) { arg5(null, arg1) } else { return arg1; } } + ); + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:"foo", op1type:"flow", op2:"bar", op2type:"global", duration:"20", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + if (c === 0) { + msg.should.have.a.property("payload", "foo"); + c+=1; + } + else { + msg.should.have.a.property("payload", "bar"); + RED.util.evaluateNodeProperty.restore(); + done(); + } + } + catch(err) { RED.util.evaluateNodeProperty.restore(); done(err); } + }); + n1.emit("input", {payload:null}); + }); + }); + + it('should be able to return things from persistable flow and global context variables', function (done) { + var flow = [{"id": "n1", "type": "trigger", "name": "triggerNode", "op1": "#:(memory1)::foo", "op1type": "flow", + "op2": "#:(memory1)::bar", "op2type": "global", "duration": "20", "wires": [["n2"]], "z": "flow" }, + {"id": "n2", "type": "helper"}]; + helper.load(triggerNode, flow, function () { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function (msg) { + try { + if (c === 0) { + msg.should.have.a.property("payload", "foo"); + c += 1; + } else { + msg.should.have.a.property("payload", "bar"); + done(); + } + } catch (err) { + done(err); + } + }); + var context = n1.context(); + var flow = context.flow; + var global = context.global; + flow.set("foo", "foo", "memory1", function (err) { + global.set("bar", "bar", "memory1", function (err) { + n1.emit("input", { payload: null }); + }); + }); + }); + }); + }); + + it('should be able to return things from multiple persistable global context variables', function (done) { + var flow = [{"id": "n1", "z": "flow", "type": "trigger", + "duration": "20", "wires": [["n2"]], + "op1": "#:(memory1)::val", "op1type": "global", + "op2": "#:(memory2)::val", "op2type": "global" + }, + {"id": "n2", "type": "helper"}]; + helper.load(triggerNode, flow, function () { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function (msg) { + try { + if (count === 0) { + msg.should.have.a.property("payload", "foo"); + } + else { + msg.should.have.a.property("payload", "bar"); + } + count++; + if (count === 1) { + done(); + } + } + catch (err) { + done(err); + } + }); + var global = n1.context().global; + global.set("val", "foo", "memory1", function (err) { + global.set("val", "bar", "memory2", function (err) { + n1.emit("input", { payload: null }); + }); + }); + }); + }); + }); + + it('should be able to return things from multiple persistable flow context variables', function (done) { + var flow = [{"id": "n1", "z": "flow", "type": "trigger", + "duration": "20", "wires": [["n2"]], + "op1": "#:(memory1)::val", "op1type": "flow", + "op2": "#:(memory2)::val", "op2type": "flow" + }, + {"id": "n2", "type": "helper"}]; + helper.load(triggerNode, flow, function () { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function (msg) { + try { + if (count === 0) { + msg.should.have.a.property("payload", "foo"); + } + else { + msg.should.have.a.property("payload", "bar"); + } + count++; + if (count === 1) { + done(); + } + } + catch (err) { + done(err); + } + }); + var flow = n1.context().flow; + flow.set("val", "foo", "memory1", function (err) { + flow.set("val", "bar", "memory2", function (err) { + n1.emit("input", { payload: null }); + }); + }); + }); + }); + }); + + it('should be able to return things from multiple persistable flow & global context variables', function (done) { + var flow = [{"id": "n1", "z": "flow", "type": "trigger", + "duration": "20", "wires": [["n2"]], + "op1": "#:(memory1)::val", "op1type": "flow", + "op2": "#:(memory2)::val", "op2type": "global" + }, + {"id": "n2", "type": "helper"}]; + helper.load(triggerNode, flow, function () { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function (msg) { + try { + if (count === 0) { + msg.should.have.a.property("payload", "foo"); + } + else { + msg.should.have.a.property("payload", "bar"); + } + count++; + if (count === 1) { + done(); + } + } + catch (err) { + done(err); + } + }); + var context = n1.context(); + var flow = context.flow; + var global = context.flow; + flow.set("val", "foo", "memory1", function (err) { + global.set("val", "bar", "memory2", function (err) { + n1.emit("input", { payload: null }); + }); + }); + }); + }); + }); + + it('should be able to not output anything on first trigger', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1type:"nul", op1:"true",op2:"false",op2type:"val",duration:"30", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.a.property("payload", false); + done(); + } catch(err) { + done(err); + } + }); + n1.emit("input", {payload:null}); + }); + }); + + it('should be able to not output anything on second edge', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op2type:"nul", op1:"true",op1type:"val", op2:"false", duration:"30", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + msg.should.have.a.property("payload", true); + c += 1; + } + catch(err) { done(err); } + }); + setTimeout( function() { + c.should.equal(1); // should only have had one output. + done(); + },90); + n1.emit("input", {payload:null}); + }); + }); + + it('should be able to reset correctly having not output anything on second edge', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op2type:"nul", op1:"true",op1type:"val", op2:"false", duration:"35", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + msg.should.have.a.property("payload", true); + c += 1; + } + catch(err) { done(err); } + }); + setTimeout( function() { + c.should.equal(3); // should only have had one output. + done(); + },300); + n1.emit("input", {payload:1}); + setTimeout( function() { + n1.emit("input", {payload:2}); + },100); + setTimeout( function() { + n1.emit("input", {payload:3}); + },200); + }); + }); + + it('should be able to extend the delay', function(done) { + this.timeout(5000); // add extra time for flake + var spy = sinon.stub(RED.util, 'evaluateNodeProperty', + function(arg1, arg2, arg3, arg4, arg5) { if (arg5) { arg5(null, arg1) } else { return arg1; } } + ); + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", extend:"true", op1type:"flow", op1:"foo", op2:"bar", op2type:"global", duration:"100", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + if (c === 0) { + msg.should.have.a.property("payload", "foo"); + c += 1; + } + else { + msg.should.have.a.property("payload", "bar"); + //console.log(Date.now() - ss); + (Date.now() - ss).should.be.greaterThan(149); + spy.restore(); + done(); + } + } + catch(err) { spy.restore(); done(err); } + }); + var ss = Date.now(); + n1.emit("input", {payload:"Hello"}); + setTimeout( function() { + n1.emit("input", {payload:null}); + },50); + }); + }); + + it('should be able to extend the delay (but with no 2nd output)', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", extend:"true", op1type:"pay", op2type:"nul", op1:"false", op2:"true", duration:"200", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + if (c === 0) { + msg.should.have.a.property("payload", "Hello"); + c += 1; + } + else { + msg.should.have.a.property("payload", "World"); + (Date.now() - ss).should.be.greaterThan(300); + done(); + } + } catch(err) { + console.log(err); + done(err); + } + }); + var ss = Date.now(); + n1.emit("input", {payload:"Hello"}); + setTimeout( function() { + n1.emit("input", {payload:"Error"}); + },50); + setTimeout( function() { + n1.emit("input", {payload:"Error"}); + },100); + setTimeout( function() { + n1.emit("input", {payload:"World"}); + },330); + }); + }); + + it('should be able to extend the delay and output the most recent payload', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", extend:"true", op1type:"nul", op2type:"payl", op1:"false", op2:"true", duration:"60", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + msg.should.have.a.property("payload", "World"); + (Date.now() - ss).should.be.greaterThan(120); + done(); + } + catch(err) { done(err); } + }); + var ss = Date.now(); + n1.emit("input", {payload:"Hello"}); + setTimeout( function() { + n1.emit("input", {payload:"Goodbye"}); + },40); + setTimeout( function() { + n1.emit("input", {payload:"World"}); + },80); + }); + }); + + it('should be able output the 2nd payload', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", extend:"false", op1type:"nul", op2type:"payl", op1:"false", op2:"true", duration:"50", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + if (c === 0) { + msg.should.have.a.property("payload", "Goodbye"); + msg.should.have.a.property("topic", "test2"); + c += 1; + } + else { + msg.should.have.a.property("payload", "World"); + msg.should.have.a.property("topic", "test3"); + (Date.now() - ss).should.be.greaterThan(70); + done(); + } + } + catch(err) { done(err); } + }); + var ss = Date.now(); + n1.emit("input", {payload:"Hello", topic:"test1"}); + setTimeout( function() { + n1.emit("input", {payload:"Goodbye", topic:"test2"}); + },20); + setTimeout( function() { + n1.emit("input", {payload:"World", topic:"test3"}); + },80); + }); + }); + + it('should be able output the 2nd payload and handle multiple topics', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", extend:"false", op1type:"nul", op2type:"payl", op1:"false", op2:"true", duration:"80", bytopic:"topic", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + if (c === 0) { + msg.should.have.a.property("payload", "Goodbye1"); + msg.should.have.a.property("topic", "test1"); + c += 1; + } + else { + msg.should.have.a.property("payload", "Goodbye2"); + msg.should.have.a.property("topic", "test2"); + done(); + } + } + catch(err) { done(err); } + }); + n1.emit("input", {payload:"Hello1", topic:"test1"}); + setTimeout( function() { + n1.emit("input", {payload:"Hello2", topic:"test2"}); + },20); + setTimeout( function() { + n1.emit("input", {payload:"Goodbye2", topic:"test2"}); + },20); + setTimeout( function() { + n1.emit("input", {payload:"Goodbye1", topic:"test1"}); + },20); + }); + }); + + it('should be able to apply mustache templates to payloads', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1type:"val", op2type:"val", op1:"{{payload}}", op2:"{{topic}}", duration:"50", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + if (c === 0) { + msg.should.have.a.property("payload", "Hello"); + c+=1; + } + else { + msg.should.have.a.property("payload", "World"); + done(); + } + } + catch(err) { done(err); } + }); + n1.emit("input", {payload:"Hello",topic:"World"}); + }); + }); + + it('should handle string null as null', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1type:"val", op2type:"pay", op1:"null", op2:"null", duration:"40", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + if (c === 0) { + msg.should.have.a.property("payload", null); + c+=1; + } + else { + msg.should.have.a.property("payload", "World"); + done(); + } + } + catch(err) { done(err); } + }); + n1.emit("input", {payload:"World"}); + }); + }); + + it('should handle string null as null on op2', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1type:"val", op2type:"val", op1:"null", op2:"null", duration:"40", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + if (c === 0) { + msg.should.have.a.property("payload", null); + c+=1; + } + else { + msg.should.have.a.property("payload", null); + done(); + } + } + catch(err) { done(err); } + }); + n1.emit("input", {payload:"null"}); + }); + }); + + it('should be able to set infinite timeout, and clear timeout', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", duration:"0", extend: false, wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + c += 1; + msg.should.have.a.property("payload", "1"); + } + catch(err) { done(err); } + }); + setTimeout( function() { + if (c === 2) { done(); } + else { + done(new Error("Too many messages received")); + } + },20); + n1.emit("input", {payload:null}); // trigger + n1.emit("input", {payload:null}); // blocked + n1.emit("input", {payload:null}); // blocked + n1.emit("input", {reset:true}); // clear the blockage + n1.emit("input", {payload:null}); // trigger + }); + }); + + it('should be able to set infinite timeout, and clear timeout by message', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", reset:"boo", duration:"0", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + c += 1; + msg.should.have.a.property("payload", "1"); + } + catch(err) { done(err); } + }); + setTimeout( function() { + if (c === 2) { done(); } + else { + done(new Error("Too many messages received")); + } + },20); + n1.emit("input", {payload:null}); // trigger + n1.emit("input", {payload:null}); // blocked + n1.emit("input", {payload:null}); // blocked + n1.emit("input", {payload:"foo"}); // don't clear the blockage + n1.emit("input", {payload:"boo"}); // clear the blockage + n1.emit("input", {payload:null}); // trigger + }); + }); + + it('should be able to set infinite timeout, and clear timeout by boolean true', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", reset:"true", duration:"0", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + c += 1; + msg.should.have.a.property("payload", "1"); + } + catch(err) { done(err); } + }); + setTimeout( function() { + if (c === 2) { done(); } + else { + done(new Error("Too many messages received")); + } + },20); + n1.emit("input", {payload:null}); // trigger + n1.emit("input", {payload:null}); // blocked + n1.emit("input", {payload:null}); // blocked + n1.emit("input", {payload:false}); // don't clear the blockage + n1.emit("input", {payload:true}); // clear the blockage + n1.emit("input", {payload:null}); // trigger + }); + }); + + it('should be able to set infinite timeout, and clear timeout by boolean false', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", reset:"false", duration:"0", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + c += 1; + msg.should.have.a.property("payload", "1"); + } + catch(err) { done(err); } + }); + setTimeout( function() { + if (c === 2) { done(); } + else { + done(new Error("Too many messages received")); + } + },20); + n1.emit("input", {payload:null}); // trigger + n1.emit("input", {payload:null}); // blocked + n1.emit("input", {payload:null}); // blocked + n1.emit("input", {payload:"foo"}); // don't clear the blockage + n1.emit("input", {payload:false}); // clear the blockage + n1.emit("input", {payload:null}); // trigger + }); + }); + + it('should be able to set a repeat, and clear loop by reset', function(done) { + var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", reset:"boo", op1:"", op1type:"pay", duration:-25, wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(triggerNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + c += 1; + try { + msg.should.have.property('payload','foo'); + msg.payload = "bar"; // try to provoke pass by reference error + } + catch(err) { done(err); } + }); + n1.emit("input", {payload:"foo"}); // trigger + n1.emit("input", {payload:"foo"}); // trigger + setTimeout( function() { + n1.emit("input", {reset:true}); // reset + },90); + setTimeout( function() { + c.should.within(2,5); // should send foo between 2 and 5 times. + done(); + },180); + }); + }); + +}); diff --git a/packages/connector/test/nodes/core/function/90-exec_spec.js b/packages/connector/test/nodes/core/function/90-exec_spec.js new file mode 100644 index 0000000..6dbe813 --- /dev/null +++ b/packages/connector/test/nodes/core/function/90-exec_spec.js @@ -0,0 +1,919 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); +var helper = require("node-red-node-test-helper"); +var execNode = require("nr-test-utils").require("@node-red/nodes/core/function/90-exec.js"); +var osType = require("os").type(); + +var child_process = require('child_process'); + +describe('exec node', function() { + + beforeEach(function(done) { + helper.startServer(done); + }); + + afterEach(function(done) { + helper.unload().then(function() { + helper.stopServer(done); + }); + }); + + it('should be loaded with any defaults', function(done) { + var flow = [{id:"n1", type:"exec", name: "exec1"}]; + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property("name", "exec1"); + n1.should.have.property("cmd", ""); + n1.should.have.property("append", ""); + n1.should.have.property("addpay",true); + n1.should.have.property("timer",0); + n1.should.have.property("oldrc","false"); + done(); + }); + }); + + describe('calling exec', function() { + + it('should exec a simple command', function(done) { + var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"echo", addpay:false, append:"", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + var spy = sinon.stub(child_process, 'exec', + function(arg1, arg2, arg3, arg4) { + // arg3(error,stdout,stderr); + arg3(null,arg1,arg1.toUpperCase()); + }); + + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + var received = 0; + var messages = [null,null,null]; + var completeTest = function() { + received = received + 1; + if (received < 3) { + return; + } + try { + var msg = messages[0]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal("echo"); + msg.should.have.property("rc"); + msg.rc.should.have.property("code",0); + + msg = messages[1]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal("ECHO"); + msg.should.have.property("rc"); + msg.rc.should.have.property("code",0); + + msg = messages[2]; + msg.should.have.property("payload"); + msg.payload.should.have.property("code",0); + + child_process.exec.restore(); + done(); + } + catch(err) { + child_process.exec.restore(); + done(err); + } + }; + n2.on("input", function(msg) { + messages[0] = msg; + completeTest(); + }); + n3.on("input", function(msg) { + messages[1] = msg; + completeTest(); + }); + n4.on("input", function(msg) { + messages[2] = msg; + completeTest(); + }); + n1.receive({payload:"and"}); + }); + }); + + it('should exec a simple command with extra parameters', function(done) { + var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"echo", addpay:true, append:"more", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + var spy = sinon.stub(child_process, 'exec', + function(arg1, arg2, arg3, arg4) { + //console.log(arg1); + // arg3(error,stdout,stderr); + arg3(null,arg1,arg1.toUpperCase()); + }); + + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + var received = 0; + var messages = [null,null]; + var completeTest = function() { + received++; + if (received < 2) { + return; + } + try { + var msg = messages[0]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal("echo and more"); + msg.should.have.property("rc"); + msg.rc.should.have.property("code",0); + + msg = messages[1]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal("ECHO AND MORE"); + msg.should.have.property("rc"); + msg.rc.should.have.property("code",0); + child_process.exec.restore(); + done(); + } + catch(err) { + child_process.exec.restore(); + done(err); + } + }; + n2.on("input", function(msg) { + messages[0] = msg; + completeTest(); + }); + n3.on("input", function(msg) { + messages[1] = msg; + completeTest(); + }); + n1.receive({payload:"and"}); + }); + }); + + it('should be able to return a binary buffer', function(done) { + var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"echo", addpay:true, append:"more", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + var spy = sinon.stub(child_process, 'exec', + function(arg1, arg2, arg3, arg4) { + //console.log(arg1); + // arg3(error,stdout,stderr); + arg3("error",Buffer.from([0x01,0x02,0x03,0x88]),Buffer.from([0x01,0x02,0x03,0x88])); + }); + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + n2.on("input", function(msg) { + //console.log("n2",msg); + try { + msg.should.have.property("payload"); + Buffer.isBuffer(msg.payload).should.be.true(); + msg.payload.length.should.equal(4); + child_process.exec.restore(); + done(); + } catch(err) { + child_process.exec.restore(); + done(err); + } + }); + n1.receive({}); + }); + }); + + it('should be able to timeout a long running command', function(done) { + var flow; + if (osType === "Windows_NT") { + // Although Windows timeout command is equivalent to sleep, this cannot be used because it promptly outputs a message. + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"ping", addpay:false, append:"192.0.2.0 -n 1 -w 1000 > NUL", timer:"0.3", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + } + else { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"sleep", addpay:false, append:"1", timer:"0.3", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + } + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + n4.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.have.property("signal","SIGTERM"); + done(); + } + catch(err) { done(err); } + }); + n1.receive({}); + }); + }); + + it('should be able to kill a long running command', function(done) { + var flow; + if (osType === "Windows_NT") { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"ping", addpay:false, append:"192.0.2.0 -n 1 -w 1000 > NUL", timer:"2", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + } + else { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"sleep", addpay:false, append:"1", timer:"2", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + } + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + n2.on("input", function(msg) { + try { + msg.should.have.property("rc"); + msg.rc.should.have.property("code",null); + msg.rc.should.have.property("signal","SIGTERM"); + } catch(err) { done(err); } + }); + n4.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.have.property("signal","SIGTERM"); + done(); + } + catch(err) { done(err); } + }); + setTimeout(function() { + n1.receive({kill:""}); + },150); + n1.receive({}); + }); + }); + + it('should be able to kill a long running command - SIGINT', function(done) { + var flow; + var sig = "SIGINT"; + if (osType === "Windows_NT") { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"ping", addpay:false, append:"192.0.2.0 -n 1 -w 1000 > NUL", timer:"2", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + } else { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"sleep", addpay:false, append:"1", timer:"2", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + } + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + n2.on("input", function(msg) { + try { + msg.should.have.property("rc"); + msg.rc.should.have.property("code",null); + msg.rc.should.have.property("signal","SIGINT"); + } catch(err) { done(err); } + }); + n4.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.have.property("signal",sig); + done(); + } catch(err) { done(err); } + }); + setTimeout(function() { + n1.receive({kill:"SIGINT"}); + },150); + n1.receive({}); + }); + }); + + it('should return the rc for a failing command', function(done) { + var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"error", addpay:false, append:"", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + var spy = sinon.stub(child_process, 'exec', + function(arg1, arg2, arg3, arg4) { + //console.log(arg1); + // arg3(error,stdout,stderr); + arg3({code: 1},arg1,arg1.toUpperCase()); + }); + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + var received = 0; + var messages = [null,null,null]; + var completeTest = function() { + received++; + if (received < 3) { + return; + } + try { + var msg = messages[0]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal("error"); + msg.should.have.property("rc"); + msg.rc.should.have.property("code",1); + msg.rc.should.have.property("message",undefined); + + msg = messages[1]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal("ERROR"); + + msg = messages[2]; + msg.should.have.property("payload"); + msg.payload.should.have.property("code",1); + + child_process.exec.restore(); + done(); + } + catch(err) { + child_process.exec.restore(); + done(err); + } + }; + n2.on("input", function(msg) { + messages[0] = msg; + completeTest(); + }); + n3.on("input", function(msg) { + messages[1] = msg; + completeTest(); + }); + n4.on("input", function(msg) { + messages[2] = msg; + completeTest(); + }); + n1.receive({payload:"and"}); + }); + }); + + it('should preserve existing properties on msg object', function(done) { + var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"echo", addpay:false, append:"", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + var spy = sinon.stub(child_process, 'exec', + function(arg1, arg2, arg3, arg4) { + // arg3(error,stdout,stderr); + arg3(null,arg1,arg1.toUpperCase()); + }); + + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + var received = 0; + var messages = [null,null,null]; + var completeTest = function() { + received = received + 1; + if (received < 3) { + return; + } + try { + var msg = messages[0]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal("echo"); + msg.should.have.property("rc"); + msg.rc.should.have.property("code",0); + msg.should.have.property("foo","bar"); + + msg = messages[1]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal("ECHO"); + msg.should.have.property("rc"); + msg.rc.should.have.property("code",0); + msg.should.have.property("foo","bar"); + + msg = messages[2]; + msg.should.have.property("payload"); + msg.payload.should.have.property("code",0); + msg.should.have.property("foo","bar"); + + child_process.exec.restore(); + done(); + } + catch(err) { + child_process.exec.restore(); + done(err); + } + }; + n2.on("input", function(msg) { + messages[0] = msg; + completeTest(); + }); + n3.on("input", function(msg) { + messages[1] = msg; + completeTest(); + }); + n4.on("input", function(msg) { + messages[2] = msg; + completeTest(); + }); + n1.receive({payload:"and", foo:"bar"}); + }); + }); + + it('should preserve existing properties on msg object for a failing command', function(done) { + var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"error", addpay:false, append:"", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + var spy = sinon.stub(child_process, 'exec', + function(arg1, arg2, arg3, arg4) { + // arg3(error,stdout,stderr); + arg3({code: 1},arg1,arg1.toUpperCase()); + }); + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + var received = 0; + var messages = [null,null,null]; + var completeTest = function() { + received++; + if (received < 3) { + return; + } + try { + var msg = messages[0]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal("error"); + msg.should.have.property("rc"); + msg.rc.should.have.property("code",1); + msg.rc.should.have.property("message",undefined); + msg.should.have.property("foo",null); + + msg = messages[1]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal("ERROR"); + msg.should.have.property("foo",null); + + msg = messages[2]; + msg.should.have.property("payload"); + msg.payload.should.have.property("code",1); + msg.should.have.property("foo",null); + + child_process.exec.restore(); + done(); + } + catch(err) { + child_process.exec.restore(); + done(err); + } + }; + n2.on("input", function(msg) { + messages[0] = msg; + completeTest(); + }); + n3.on("input", function(msg) { + messages[1] = msg; + completeTest(); + }); + n4.on("input", function(msg) { + messages[2] = msg; + completeTest(); + }); + n1.receive({payload:"and", foo:null}); + }); + }); + + }); + + describe('calling spawn', function() { + + it('should spawn a simple command', function(done) { + var flow; + var expected; + if (osType === "Windows_NT") { + // Need to use cmd to spawn a process because Windows echo command is a built-in command and cannot be spawned. + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"cmd /C echo", addpay:true, append:"", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + expected = "hello world\r\n"; + } else { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"echo", addpay:true, append:"", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + expected = "hello world\n"; + } + var events = require('events'); + + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + n2.on("input", function(msg) { + //console.log(msg); + try { + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal(expected); + done(); + } + catch(err) { done(err); } + }); + n1.receive({payload:"hello world"}); + }); + }); + + it('should spawn a simple command with a non string payload parameter', function(done) { + var flow; + var expected; + if (osType === "Windows_NT") { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"cmd /C echo", addpay:true, append:" deg C", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + expected = "12345 deg C\r\n"; + } else { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"echo", addpay:true, append:" deg C", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + expected = "12345 deg C\n"; + } + + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + n2.on("input", function(msg) { + //console.log(msg); + try { + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal(expected); + done(); + } + catch(err) { done(err); } + }); + n1.receive({payload:12345}); + }); + }); + + it('should spawn a simple command and return binary buffer', function(done) { + var flow; + if (osType === "Windows_NT") { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"cmd /C echo", addpay:true, append:"", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + } else { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"echo", addpay:true, append:"", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + } + + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + Buffer.isBuffer(msg.payload).should.be.true(); + if (osType === "Windows_NT") { + msg.payload.length.should.equalOneOf(6,8); + } else { + msg.payload.length.should.equal(7); + } + done(); + } + catch(err) { done(err); } + }); + n1.receive({payload:Buffer.from([0x01,0x02,0x03,0x88])}); + }); + }); + + it('should work if passed multiple words to spawn command', function(done) { + var flow; + var expected; + if (osType === "Windows_NT") { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"cmd /C echo this now works", addpay:false, append:"", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + expected = "this now works\r\n"; + } else { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"echo this now works", addpay:false, append:"", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + expected = "this now works\n"; + } + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + var received = 0; + var messages = [null,null]; + var completeTest = function() { + received++; + if (received < 2) { + return; + } + try { + var msg = messages[0]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal(expected); + + msg = messages[1]; + msg.should.have.property("payload"); + should.exist(msg.payload); + msg.payload.should.have.property("code",0); + done(); + } + catch(err) { + done(err); + } + }; + + n2.on("input", function(msg) { + messages[0] = msg; + completeTest(); + }); + n4.on("input", function(msg) { + messages[1] = msg; + completeTest(); + }); + n1.receive({payload:null,fred:123}); + }); + }); + + it('should return an error for a bad command', function(done) { + var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"madeupcommandshouldfail", addpay:false, append:"", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + n4.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.have.property("code"); + msg.payload.code.should.be.below(0); + done(); + } + catch(err) { done(err); } + }); + n1.receive({payload:null}); + }); + }); + + it('should return an error for a failing command', function(done) { + var flow; + var expected; + var expectedFound = false; + if (osType === "Windows_NT") { + // Cannot use mkdir because Windows mkdir command automatically creates non-existent directories. + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"ping /foo/bar/doo/dah", addpay:false, append:"", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + expected = "IP address must be specified."; + } else { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"mkdir /foo/bar/doo/dah", addpay:false, append:"", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + expected = ' directory'; + } + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + n3.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + if (msg.payload.indexOf(expected) >= 0) { + // The error text on the stderr stream might get sent in more than one piece. + // We only need to know that it occurred before the return code is sent, + // as checked below in node n4. + expectedFound = true; + } + } + catch(err) { done(err); } + }); + n4.on("input", function(msg) { + try { + expectedFound.should.be.true; + msg.should.have.property("payload"); + msg.payload.should.have.property("code",1); + done(); + } + catch(err) { done(err); } + }); + n1.receive({payload:null}); + }); + }); + + it('should be able to timeout a long running command', function(done) { + var flow; + if (osType === "Windows_NT") { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"ping", addpay:false, append:"192.0.2.0 -n 1 -w 1000", timer:"0.3", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + } else { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"sleep", addpay:false, append:"1", timer:"0.3", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + } + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + n4.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.have.property("code",null); + msg.payload.should.have.property("signal","SIGTERM"); + done(); + } + catch(err) { done(err); } + }); + n1.receive({}); + }); + }); + + it('should be able to kill a long running command', function(done) { + var flow; + if (osType === "Windows_NT") { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"ping", addpay:false, append:"192.0.2.0 -n 1 -w 1000 > NUL", timer:"2", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + } else { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"sleep", addpay:false, append:"1", timer:"2", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + } + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + n4.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.have.property("signal","SIGTERM"); + done(); + } + catch(err) { done(err); } + }); + setTimeout(function() { + n1.receive({kill:""}); + },150); + n1.receive({}); + }); + }); + + it('should be able to kill a long running command - SIGINT', function(done) { + var flow; + var sig = "SIGINT"; + if (osType === "Windows_NT") { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"ping", addpay:false, append:"192.0.2.0 -n 1 -w 1000 > NUL", timer:"2", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + } else { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"sleep", addpay:false, append:"1", timer:"2", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + } + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + n4.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.have.property("signal",sig); + done(); + } + catch(err) { done(err); } + }); + setTimeout(function() { + n1.receive({kill:"SIGINT"}); + },150); + n1.receive({}); + }); + }); + + it('should preserve existing properties on msg object', function(done) { + var flow; + var expected; + if (osType === "Windows_NT") { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"cmd /C echo this now works", addpay:false, append:"", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + expected = "this now works\r\n"; + } else { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"echo this now works", addpay:false, append:"", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + expected = "this now works\n"; + } + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + var received = 0; + var messages = [null,null]; + var completeTest = function() { + received++; + if (received < 2) { + return; + } + try { + var msg = messages[0]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.payload.should.equal(expected); + msg.should.have.property("foo",123); + + msg = messages[1]; + msg.should.have.property("payload"); + should.exist(msg.payload); + msg.payload.should.have.property("code",0); + msg.should.have.property("foo",123); + + done(); + } + catch(err) { + done(err); + } + }; + + n2.on("input", function(msg) { + messages[0] = msg; + completeTest(); + }); + n4.on("input", function(msg) { + messages[1] = msg; + completeTest(); + }); + n1.receive({payload:null,foo:123}); + }); + }); + + it('should preserve existing properties on msg object for a failing command', function(done) { + var flow; + var expected; + if (osType === "Windows_NT") { + // Cannot use mkdir because Windows mkdir command automatically creates non-existent directories. + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"ping /foo/bar/doo/dah", addpay:false, append:"", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + expected = "IP address must be specified."; + } else { + flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"mkdir /foo/bar/doo/dah", addpay:false, append:"", useSpawn:"true", oldrc:"false"}, + {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; + expected = ' directory'; + } + helper.load(execNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n4 = helper.getNode("n4"); + var received = 0; + var messages = [null,null]; + var completeTest = function() { + if (messages[0] === null || messages[1] === null) { + // We have not yet had responses on both ports. + return + } + try { + var msg = messages[0]; + msg.should.have.property("payload"); + msg.payload.should.be.a.String(); + msg.should.have.property("foo","baz"); + + msg = messages[1]; + msg.should.have.property("payload"); + msg.payload.should.have.property("code",1); + msg.should.have.property("foo","baz"); + + done(); + } + catch(err) { + done(err); + } + }; + + n3.on("input", function(msg) { + messages[0] = msg; + completeTest(); + }); + n4.on("input", function(msg) { + messages[1] = msg; + completeTest(); + }); + n1.receive({payload:null,foo:"baz"}); + }); + }); + + }); +}); diff --git a/packages/connector/test/nodes/core/network/21-httprequest_spec.js b/packages/connector/test/nodes/core/network/21-httprequest_spec.js new file mode 100644 index 0000000..ab9020a --- /dev/null +++ b/packages/connector/test/nodes/core/network/21-httprequest_spec.js @@ -0,0 +1,1939 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var when = require("when"); +var http = require("http"); +var https = require("https"); +var should = require("should"); +var express = require("express"); +var bodyParser = require('body-parser'); +var stoppable = require('stoppable'); +var helper = require("node-red-node-test-helper"); +var httpRequestNode = require("nr-test-utils").require("@node-red/nodes/core/network/21-httprequest.js"); +var tlsNode = require("nr-test-utils").require("@node-red/nodes/core/network/05-tls.js"); +var httpProxyNode = require("nr-test-utils").require("@node-red/nodes/core/network/06-httpproxy.js"); +var hashSum = require("hash-sum"); +var httpProxy = require('http-proxy'); +var cookieParser = require('cookie-parser'); +var multer = require("multer"); +var RED = require("nr-test-utils").require("node-red/lib/red"); +var fs = require('fs-extra'); +var auth = require('basic-auth'); + +describe('HTTP Request Node', function() { + var testApp; + var testServer; + var testPort = 10234; + var testSslServer; + var testSslPort = 10334; + var testProxyServer; + var testProxyPort = 10444; + + //save environment variables + var preEnvHttpProxyLowerCase; + var preEnvHttpProxyUpperCase; + var preEnvNoProxyLowerCase; + var preEnvNoProxyUpperCase; + + //rediect cookie variables + var receivedCookies = {}; + + function startServer(done) { + testPort += 1; + testServer = stoppable(http.createServer(testApp)); + testServer.listen(testPort,function(err) { + testSslPort += 1; + var sslOptions = { + key: fs.readFileSync('test/resources/ssl/server.key'), + cert: fs.readFileSync('test/resources/ssl/server.crt') + /* + Country Name (2 letter code) [AU]: + State or Province Name (full name) [Some-State]: + Locality Name (eg, city) []: + Organization Name (eg, company) [Internet Widgits Pty Ltd]: + Organizational Unit Name (eg, section) []: + Common Name (e.g. server FQDN or YOUR name) []:localhost + Email Address []: + + Please enter the following 'extra' attributes to be sent with your certificate request + A challenge password []: + An optional company name []: + */ + }; + testSslServer = stoppable(https.createServer(sslOptions,testApp)); + testSslServer.listen(testSslPort); + + testProxyPort += 1; + testProxyServer = stoppable(httpProxy.createProxyServer({target:'http://localhost:' + testPort})); + testProxyServer.on('proxyReq', function(proxyReq, req, res, options) { + proxyReq.setHeader('x-testproxy-header', 'foobar'); + }); + testProxyServer.on('proxyRes', function (proxyRes, req, res, options) { + if (req.url == getTestURL('/proxyAuthenticate')){ + var user = auth.parse(req.headers['proxy-authorization']); + if (!(user.name == "foouser" && user.pass == "barpassword")){ + proxyRes.headers['proxy-authenticate'] = 'BASIC realm="test"'; + proxyRes.statusCode = 407; + } + } + }); + testProxyServer.listen(testProxyPort); + done(err); + }); + } + + function getTestURL(url) { + return "http://localhost:"+testPort+url; + } + + function getSslTestURL(url) { + return "https://localhost:"+testSslPort+url; + } + + function getDifferentTestURL(url) { + return "http://127.0.0.1:"+testPort+url; + } + + function getSslTestURLWithoutProtocol(url) { + return "localhost:"+testSslPort+url; + } + + function deleteProxySetting() { + delete process.env.http_proxy; + delete process.env.HTTP_PROXY; + delete process.env.no_proxy; + delete process.env.NO_PROXY; + } + + before(function(done) { + + testApp = express(); + + // The fileupload test needs a different set of middleware - so mount + // as a separate express instance + var fileUploadApp = express(); + var mp = multer({ storage: multer.memoryStorage() }).any(); + fileUploadApp.post("/file-upload",function(req,res,next) { + mp(req,res,function(err) { + req._body = true; + next(err); + }) + },bodyParser.json(),function(req,res) { + res.json({ + body: req.body, + files: req.files + }) + }); + testApp.use(fileUploadApp); + + + + testApp.use(bodyParser.raw({type:"*/*"})); + testApp.use(cookieParser(undefined,{decode:String})); + testApp.get('/statusCode204', function(req,res) { res.status(204).end();}); + testApp.get('/text', function(req, res){ res.send('hello'); }); + testApp.get('/redirectToText', function(req, res){ res.status(302).set('Location', getTestURL('/text')).end(); }); + testApp.get('/json-valid', function(req, res){ res.json({a:1}); }); + testApp.get('/json-invalid', function(req, res){ res.set('Content-Type', 'application/json').send("{a:1"); }); + testApp.get('/headersInspect', function(req, res){ res.set('x-test-header', 'bar').send("a"); }); + testApp.get('/timeout', function(req, res){ + setTimeout(function() { + res.send('hello'); + }, 10000); + }); + testApp.get('/timeout50ms', function(req, res){ + setTimeout(function() { + res.send('hello'); + }, 50); + }); + testApp.get('/checkCookie', function(req, res){ + res.send(req.cookies); + }); + testApp.get('/setCookie', function(req, res){ + res.cookie('data','hello'); + res.send(""); + }); + testApp.get('/authenticate', function(req, res){ + var user = auth.parse(req.headers['authorization']); + var result = { + user: user.name, + pass: user.pass, + }; + res.json(result); + }); + testApp.get('/proxyAuthenticate', function(req, res){ + var user = auth.parse(req.headers['proxy-authorization']); + var result = { + user: user.name, + pass: user.pass, + headers: req.headers + }; + res.json(result); + }); + testApp.post('/postInspect', function(req,res) { + var result = { + body: req.body.toString(), + headers: req.headers + }; + res.json(result); + }); + testApp.put('/putInspect', function(req,res) { + var result = { + body: req.body.toString(), + headers: req.headers + }; + res.json(result); + }); + testApp.delete('/deleteInspect', function(req,res) { res.status(204).end();}); + testApp.head('/headInspect', function(req,res) { res.status(204).end();}); + testApp.patch('/patchInspect', function(req,res) { + var result = { + body: req.body.toString(), + headers: req.headers + }; + res.json(result); + }); + testApp.trace('/traceInspect', function(req,res) { + var result = { + body: req.body.toString(), + headers: req.headers + }; + res.json(result); + }); + testApp.options('/*', function(req,res) { + res.status(200).end(); + }); + testApp.get('/redirectToSameDomain', function(req, res) { + var key = req.headers.host + req.url; + receivedCookies[key] = req.cookies; + res.cookie('redirectToSameDomainCookie','same1'); + res.redirect(getTestURL('/redirectReturn')); + }); + testApp.get('/redirectToDifferentDomain', function(req, res) { + var key = req.headers.host + req.url; + receivedCookies[key] = req.cookies; + res.cookie('redirectToDifferentDomain','different1'); + res.redirect(getDifferentTestURL('/redirectReturn')); + }); + testApp.get('/redirectMultipleTimes', function(req, res) { + var key = req.headers.host + req.url; + receivedCookies[key] = req.cookies; + res.cookie('redirectMultipleTimes','multiple1'); + res.redirect(getTestURL('/redirectToDifferentDomain')); + }); + testApp.get('/redirectReturn', function(req, res) { + var key = req.headers.host + req.url; + receivedCookies[key] = req.cookies; + res.cookie('redirectReturn','return1'); + res.status(200).end(); + }); + testApp.get('/getQueryParams', function(req,res) { + res.json({ + query:req.query, + url: req.originalUrl + }); + }) + startServer(function(err) { + if (err) { + done(err); + } + helper.startServer(done); + }); + }); + + after(function(done) { + testServer.stop(() => { + testProxyServer.stop(() => { + testSslServer.stop(() => { + helper.stopServer(done); + }); + }); + }); + }); + + beforeEach(function() { + preEnvHttpProxyLowerCase = process.env.http_proxy; + preEnvHttpProxyUpperCase = process.env.HTTP_PROXY; + preEnvNoProxyLowerCase = process.env.no_proxy; + preEnvNoProxyUpperCase = process.env.NO_PROXY; + process.env.no_proxy = 'localhost'; + process.env.NO_PROXY = 'localhost'; + }); + + afterEach(function() { + process.env.http_proxy = preEnvHttpProxyLowerCase; + process.env.HTTP_PROXY = preEnvHttpProxyUpperCase; + // On Windows, if environment variable of NO_PROXY that includes lower cases + // such as No_Proxy is replaced with NO_PROXY. + process.env.no_proxy = preEnvNoProxyLowerCase; + process.env.NO_PROXY = preEnvNoProxyUpperCase; + if (preEnvHttpProxyLowerCase == undefined) { + delete process.env.http_proxy; + } + if (preEnvHttpProxyUpperCase == undefined) { + delete process.env.HTTP_PROXY; + } + if (preEnvNoProxyLowerCase == undefined) { + delete process.env.no_proxy; + } + if (preEnvNoProxyUpperCase == undefined) { + delete process.env.NO_PROXY; + } + helper.unload(); + }); + + describe('request', function() { + it('should get plain text content', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-length',''+('hello'.length)); + msg.headers.should.have.property('content-type').which.startWith('text/html'); + msg.redirectList.length.should.equal(0); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should get JSON content', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/json-valid')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload',{a:1}); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-type').which.startWith('application/json'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should send the payload as the body of a POST as application/json', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.body.should.eql('{"foo":"abcde"}'); + msg.payload.headers.should.have.property('content-type').which.startWith('application/json'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-type').which.startWith('application/json'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:{foo:"abcde"}}); + }); + }); + + it('should send a payload of 0 as the body of a POST as text/plain', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.body.should.eql('0'); + msg.payload.headers.should.have.property('content-length','1'); + msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:0, headers: { 'content-type': 'text/plain'}}); + }); + }); + + it('should send an Object payload as the body of a POST', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.body.should.eql('{"foo":"abcde"}'); + msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-type').which.startWith('application/json'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:{foo:"abcde"}, headers: { 'content-type': 'text/plain'}}); + }); + }); + + it('should send a Buffer as the body of a POST', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.body.should.eql('hello'); + msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-type').which.startWith('application/json'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:Buffer.from('hello'), headers: { 'content-type': 'text/plain'}}); + }); + }); + + it('should send form-based request', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.body.should.equal("foo=1%202%203&bar="); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.have.property('content-type','application/x-www-form-urlencoded'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:{foo:'1 2 3', bar:''}, headers: { 'content-type': 'application/x-www-form-urlencoded'}}); + }); + }); + + it('should send PUT request', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"PUT",ret:"obj",url:getTestURL('/putInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.body.should.eql('foo'); + msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-type').which.startWith('application/json'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", headers: { 'content-type': 'text/plain'}}); + }); + }); + + it('should send DELETE request', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"DELETE",ret:"obj",url:getTestURL('/deleteInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload',''); + msg.should.have.property('statusCode',204); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:{foo:"abcde"}}); + }); + }); + + it('should send HEAD request', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"use",ret:"txt",url:getTestURL('/headInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload',''); + msg.should.have.property('statusCode',204); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", method:"head"}); + }); + }); + + it('should send PATCH request', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"PATCH",ret:"obj",url:getTestURL('/patchInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.body.should.eql('foo'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('etag'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", headers: { 'content-type': 'text/plain'}}); + }); + }); + + it('should send OPTIONS request', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"use",ret:"obj",url:getTestURL('/*')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", method:"options"}); + }); + }); + + it('should send TRACE request', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"use",ret:"obj",url:getTestURL('/traceInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.body.should.eql('foo'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", method:"trace", headers: { 'content-type': 'text/plain'}}); + }); + }); + + it('should get Buffer content', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"bin",url:getTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + Buffer.isBuffer(msg.payload).should.be.true(); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-type'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should return plain text when JSON fails to parse', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/json-invalid')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload',"{a:1"); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-type').which.startWith('application/json'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should return the status code', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/statusCode204')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload',''); + msg.should.have.property('statusCode',204); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should use msg.url', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", url:"/foo"}); + }); + }); + + it('should output an error when URL is not provided', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:""}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var inError = false; + n2.on("input", function(msg) { + inError = true; + }); + n1.receive({payload:"foo"}); + setTimeout(function() { + if (inError) { + done(new Error("no url allowed though")); + } else { + done(); + } + },20); + }); + }); + + it('should allow the message to provide the url', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt"}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-length',''+('hello'.length)); + msg.headers.should.have.property('content-type').which.startWith('text/html'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo",url:getTestURL('/text')}); + }); + }); + + it('should allow the url to contain mustache placeholders', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/te{{placeholder}}')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-length',''+('hello'.length)); + msg.headers.should.have.property('content-type').which.startWith('text/html'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo",placeholder:"xt"}); + }); + }); + + it('should allow the url to be missing the http:// prefix', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/text').substring("http://".length)}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-length',''+('hello'.length)); + msg.headers.should.have.property('content-type').which.startWith('text/html'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should reject non http:// schemes - node config', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:"ftp://foo"}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var inError = false; + n2.on("input", function(msg) { + inError = true; + }); + n1.receive({payload:"foo"}); + setTimeout(function() { + if (inError) { + done(new Error("non http(s):// scheme allowed through")); + } else { + done(); + } + },20); + }); + }); + + it('should reject non http:// schemes - msg.url', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt"}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var inError = false; + n2.on("input", function(msg) { + inError = true; + }); + n1.receive({payload:"foo",url:"ftp://foo"}); + setTimeout(function() { + if (inError) { + done(new Error("non http(s):// scheme allowed through")); + } else { + done(); + } + },20); + }); + }); + + it('should use msg.method', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", method:"POST"}); + }); + }); + + it('should allow the message to provide the method', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"use",ret:"txt",url:getTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-length',''+('hello'.length)); + msg.headers.should.have.property('content-type').which.startWith('text/html'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo",method:"get"}); + }); + }); + + it('should receive msg.responseUrl', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.should.have.property('responseUrl', getTestURL('/text')); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should receive msg.responseUrl when redirected', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/redirectToText')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('responseUrl', getTestURL('/text')); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should prevent following redirect when msg.followRedirects is false', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/redirectToText')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',302); + msg.should.have.property('responseUrl', getTestURL('/redirectToText')); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo",followRedirects:false}); + }); + }); + + it('should output an error when request timeout occurred', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/timeout')}, + {id:"n2", type:"helper"}]; + var timeout = RED.settings.httpRequestTimeout; + RED.settings.httpRequestTimeout = 50; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode','ESOCKETTIMEDOUT'); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == 'http request'; + }); + logEvents.should.have.length(1); + var tstmp = logEvents[0][0].timestamp; + logEvents[0][0].should.eql({level:helper.log().ERROR, id:'n1',type:'http request',msg:'common.notification.errors.no-response', timestamp:tstmp, path:"global"}); + done(); + } catch(err) { + done(err); + } finally { + RED.settings.httpRequestTimeout = timeout; + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should output an error when request timeout occurred when set via msg.requestTimeout', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/timeout')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode','ESOCKETTIMEDOUT'); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == 'http request'; + }); + logEvents.should.have.length(1); + var tstmp = logEvents[0][0].timestamp; + logEvents[0][0].should.eql({level:helper.log().ERROR, id:'n1',type:'http request',msg:'common.notification.errors.no-response', timestamp:tstmp, path:"global"}); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", requestTimeout: 50}); + }); + }); + it('should show a warning if msg.requestTimeout is not a number', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode', 200); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == 'http request'; + }); + logEvents.should.have.length(2); + var tstmp = logEvents[0][0].timestamp; + logEvents[0][0].should.eql({level:helper.log().WARN, id:'n1',type:'http request',msg:'httpin.errors.timeout-isnan', timestamp:tstmp, path:"global"}); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", requestTimeout: "foo"}); + }); + }); + it('should show a warning if msg.requestTimeout is negative', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode', 200); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == 'http request'; + }); + logEvents.should.have.length(2); + var tstmp = logEvents[0][0].timestamp; + logEvents[0][0].should.eql({level:helper.log().WARN, id:'n1',type:'http request',msg:'httpin.errors.timeout-isnegative', timestamp:tstmp, path:"global"}); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", requestTimeout: -4}); + }); + }); + it('should show a warning if msg.requestTimeout is set to 0', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode', 200); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == 'http request'; + }); + logEvents.should.have.length(2); + var tstmp = logEvents[0][0].timestamp; + logEvents[0][0].should.eql({level:helper.log().WARN, id:'n1',type:'http request',msg:'httpin.errors.timeout-isnegative', timestamp:tstmp, path:"global"}); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", requestTimeout: 0}); + }); + }); + it('should pass if response time is faster than timeout set via msg.requestTimeout', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/timeout50ms')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", requestTimeout: 100}); + }); + }); + + + it('should append query params to url - obj', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",paytoqs:true,ret:"obj",url:getTestURL('/getQueryParams')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload',{ + query:{a:'1',b:'2',c:'3'}, + url: '/getQueryParams?a=1&b=2&c=3' + }); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:{a:1,b:2,c:3}}); + }); + }); + }); + + describe('HTTP header', function() { + it('should receive cookie', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/setCookie')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.responseCookies.should.have.property('data'); + msg.responseCookies.data.should.have.property('value','hello'); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should send cookie with string', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/checkCookie')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.payload.should.have.property('data','abc'); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", cookies:{data:'abc'}}); + }); + }); + + it('should send multiple cookies with string', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/checkCookie')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.payload.should.have.property('data','abc'); + msg.payload.should.have.property('foo','bar'); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", cookies:{data:'abc',foo:'bar'}}); + }); + }); + + it('should send cookie with object data', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/checkCookie')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.payload.should.have.property('data','abc'); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", cookies:{data:{value:'abc'}}}); + }); + }); + + it('should send multiple cookies with object data', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/checkCookie')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.payload.should.have.property('data','abc'); + msg.payload.should.have.property('foo','bar'); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", cookies:{data:{value:'abc'},foo:{value:'bar'}}}); + }); + }); + + it('should encode cookie value', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/checkCookie')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var value = ';,/?:@ &=+$#'; + n2.on("input", function(msg) { + try { + msg.payload.should.have.property('data',encodeURIComponent(value)); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", cookies:{data:value}}); + }); + }); + + it('should encode cookie object', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/checkCookie')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var value = ';,/?:@ &=+$#'; + n2.on("input", function(msg) { + try { + msg.payload.should.have.property('data',encodeURIComponent(value)); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", cookies:{data:{value:value, encode:true}}}); + }); + }); + + it('should not encode cookie when encode option is false', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/checkCookie')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var value = '!#$%&\'()*+-./:<>?@[]^_`{|}~'; + n2.on("input", function(msg) { + try { + msg.payload.should.have.property('data',value); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", cookies:{data:{value:value, encode:false}}}); + }); + }); + + it('should send cookie by msg.headers', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/checkCookie')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.payload.should.have.property('data','abc'); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", cookies:{boo:'123'}, headers:{'cookie':'data=abc'}}); + }); + }); + + it('should send multiple cookies by msg.headers', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/checkCookie')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.payload.should.have.property('data','abc'); + msg.payload.should.have.property('foo','bar'); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", cookies:{boo:'123'}, headers:{'cookie':'data=abc; foo=bar;'}}); + }); + }); + + it('should convert all HTTP headers into lower case', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); + msg.payload.headers.should.have.property('content-length', "3"); + msg.payload.headers.should.have.property('if-modified-since','Sun, 01 Jun 2000 00:00:00 GMT'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", headers: { 'Content-Type':'text/plain', 'Content-Length': "3", 'If-Modified-Since':'Sun, 01 Jun 2000 00:00:00 GMT'}}); + }); + }); + + it('should receive HTTP header', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/headersInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.headers.should.have.property('x-test-header','bar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should ignore unmodified x-node-red-request-node header', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.payload.headers.should.have.property('content-type').which.startWith('application/json'); + msg.payload.headers.should.not.have.property('x-node-red-request-node'); + done(); + } catch(err) { + done(err); + } + }); + // Pass in a headers property with an unmodified x-node-red-request-node hash + // This should cause the node to ignore the headers + + var headers = { 'content-type': 'text/plain' }; + headers['x-node-red-request-node'] = require("hash-sum")(headers); + + n1.receive({payload:{foo:"bar"}, headers: headers}); + }); + }); + + it('should use modified msg.headers property', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); + msg.payload.headers.should.not.have.property('x-node-red-request-node'); + done(); + } catch(err) { + done(err); + } + }); + // Pass in a headers property with a x-node-red-request-node hash that doesn't match the contents + // This should cause the node to use the headers + n1.receive({payload:{foo:"bar"}, headers: { 'content-type': 'text/plain', "x-node-red-request-node":"INVALID_SUM"}}); + }); + }); + }); + + describe('protocol', function() { + it('should use msg.rejectUnauthorized', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getSslTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n2 = helper.getNode("n2"); + var n1 = helper.getNode("n1"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-length',''+('hello'.length)); + msg.headers.should.have.property('content-type').which.startWith('text/html'); + msg.should.have.property('responseUrl').which.startWith('https://'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", rejectUnauthorized: false}); + }); + }); + + it('should use tls-config', function(done) { + var flow = [ + {id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getSslTestURLWithoutProtocol('/text'),tls:"n3"}, + {id:"n2", type:"helper"}, + {id:"n3", type:"tls-config", cert:"test/resources/ssl/server.crt", key:"test/resources/ssl/server.key", ca:"", verifyservercert:false}]; + var testNodes = [httpRequestNode, tlsNode]; + helper.load(testNodes, flow, function() { + var n3 = helper.getNode("n3"); + var n2 = helper.getNode("n2"); + var n1 = helper.getNode("n1"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-length',''+('hello'.length)); + msg.headers.should.have.property('content-type').which.startWith('text/html'); + msg.should.have.property('responseUrl').which.startWith('https://'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should use http_proxy', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + deleteProxySetting(); + process.env.http_proxy = "http://localhost:" + testProxyPort; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should use http_proxy when environment variable is invalid', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + deleteProxySetting(); + process.env.http_proxy = "invalidvalue"; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.not.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should use HTTP_PROXY', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + deleteProxySetting(); + process.env.HTTP_PROXY = "http://localhost:" + testProxyPort; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should use no_proxy', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + deleteProxySetting(); + process.env.http_proxy = "http://localhost:" + testProxyPort; + process.env.no_proxy = "foo,localhost"; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.headers.should.not.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should use NO_PROXY', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + deleteProxySetting(); + process.env.HTTP_PROXY = "http://localhost:" + testProxyPort; + process.env.NO_PROXY = "foo,localhost"; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.headers.should.not.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should use http-proxy-config', function(done) { + var flow = [ + {id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect'),proxy:"n3"}, + {id:"n2",type:"helper"}, + {id:"n3",type:"http proxy",url:"http://localhost:" + testProxyPort} + ]; + var testNode = [ httpRequestNode, httpProxyNode ]; + deleteProxySetting(); + helper.load(testNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should not use http-proxy-config when invalid url is specified', function(done) { + var flow = [ + {id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect'),proxy:"n3"}, + {id:"n2", type:"helper"}, + {id:"n3",type:"http proxy",url:"invalidvalue"} + ]; + var testNode = [ httpRequestNode, httpProxyNode ]; + deleteProxySetting(); + helper.load(testNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.not.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should use http-proxy-config when valid noproxy is specified', function(done) { + var flow = [ + {id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect'),proxy:"n3"}, + {id:"n2", type:"helper"}, + {id:"n3",type:"http proxy",url:"http://localhost:" + testProxyPort,noproxy:["foo","localhost"]} + ]; + var testNode = [ httpRequestNode, httpProxyNode ]; + deleteProxySetting(); + helper.load(testNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.headers.should.not.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + }); + + describe('authentication', function() { + it('should authenticate on server', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/authenticate')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.credentials = {user:'userfoo', password:'passwordfoo'}; + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.should.have.property('user', 'userfoo'); + msg.payload.should.have.property('pass', 'passwordfoo'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should authenticate on proxy server', function(done) { + var flow = [{id:"n1",type:"http request", wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/proxyAuthenticate')}, + {id:"n2", type:"helper"}]; + deleteProxySetting(); + process.env.http_proxy = "http://foouser:barpassword@localhost:" + testProxyPort; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.should.have.property('user', 'foouser'); + msg.payload.should.have.property('pass', 'barpassword'); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should output an error when proxy authentication was failed', function(done) { + var flow = [{id:"n1",type:"http request", wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/proxyAuthenticate')}, + {id:"n2", type:"helper"}]; + deleteProxySetting(); + process.env.http_proxy = "http://xxxuser:barpassword@localhost:" + testProxyPort; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',407); + msg.headers.should.have.property('proxy-authenticate', 'BASIC realm="test"'); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should authenticate on proxy server(http-proxy-config)', function(done) { + var flow = [ + {id:"n1",type:"http request", wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/proxyAuthenticate'),proxy:"n3"}, + {id:"n2", type:"helper"}, + {id:"n3",type:"http proxy",url:"http://localhost:" + testProxyPort} + ]; + var testNode = [ httpRequestNode, httpProxyNode ]; + deleteProxySetting(); + helper.load(testNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + n3.credentials = {username:'foouser', password:'barpassword'}; + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.should.have.property('user', 'foouser'); + msg.payload.should.have.property('pass', 'barpassword'); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should output an error when proxy authentication was failed(http-proxy-config)', function(done) { + var flow = [ + {id:"n1",type:"http request", wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/proxyAuthenticate'),proxy:"n3"}, + {id:"n2", type:"helper"}, + {id:"n3",type:"http proxy",url:"http://@localhost:" + testProxyPort} + ]; + var testNode = [ httpRequestNode, httpProxyNode ]; + deleteProxySetting(); + helper.load(testNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + n3.credentials = {username:'xxxuser', password:'barpassword'}; + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',407); + msg.headers.should.have.property('proxy-authenticate', 'BASIC realm="test"'); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + }); + + describe('file-upload', function() { + it('should upload a file', function(done) { + var flow = [{id:'n1',type:'http request',wires:[['n2']],method:'POST',ret:'obj',url:getTestURL('/file-upload')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.payload.should.have.property("body",{"other":"123"}); + msg.payload.should.have.property("files"); + msg.payload.files.should.have.length(1); + msg.payload.files[0].should.have.property('fieldname','file'); + msg.payload.files[0].should.have.property('originalname','file.txt'); + msg.payload.files[0].should.have.property('buffer',{"type":"Buffer","data":[72,101,108,108,111,32,87,111,114,108,100]}); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({ + headers: { + 'content-type':'multipart/form-data' + }, + payload: { + file: { + value: Buffer.from("Hello World"), + options: { + filename: "file.txt" + } + }, + other: 123 + } + }); + }); + }) + }) + + describe('redirect-cookie', function() { + it('should send cookies to the same domain when redirected(no cookies)', function(done) { + var flow = [{id:'n1',type:'http request',wires:[['n2']],method:'GET',ret:'obj',url:getTestURL('/redirectToSameDomain')}, + {id:"n2", type:"helper"}]; + receivedCookies = {}; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + var cookies1 = receivedCookies['localhost:'+testPort+'/redirectToSameDomain']; + var cookies2 = receivedCookies['localhost:'+testPort+'/redirectReturn']; + if (cookies1 && Object.keys(cookies1).length != 0) { + done(new Error('Invalid cookie(path:/rediectToSame)')); + return; + } + if ((cookies2 && Object.keys(cookies2).length != 1) || + cookies2['redirectToSameDomainCookie'] !== 'same1') { + done(new Error('Invalid cookie(path:/rediectReurn)')); + return; + } + var redirect1 = msg.redirectList[0]; + redirect1.location.should.equal('http://localhost:'+testPort+'/redirectReturn'); + redirect1.cookies.redirectToSameDomainCookie.Path.should.equal('/'); + redirect1.cookies.redirectToSameDomainCookie.value.should.equal('same1'); + done(); + }); + n1.receive({}); + }); + }); + it('should not send cookies to the different domain when redirected(no cookies)', function(done) { + var flow = [{id:'n1',type:'http request',wires:[['n2']],method:'GET',ret:'obj',url:getTestURL('/redirectToDifferentDomain')}, + {id:"n2", type:"helper"}]; + receivedCookies = {}; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + var cookies1 = receivedCookies['localhost:'+testPort+'/redirectToSameDomain']; + var cookies2 = receivedCookies['127.0.0.1:'+testPort+'/redirectReturn']; + if (cookies1 && Object.keys(cookies1).length != 0) { + done(new Error('Invalid cookie(path:/rediectToDiffer)')); + return; + } + if (cookies2 && Object.keys(cookies2).length != 0) { + done(new Error('Invalid cookie(path:/rediectReurn)')); + return; + } + var redirect1 = msg.redirectList[0]; + redirect1.location.should.equal('http://127.0.0.1:'+testPort+'/redirectReturn'); + redirect1.cookies.redirectToDifferentDomain.Path.should.equal('/'); + redirect1.cookies.redirectToDifferentDomain.value.should.equal('different1'); + done(); + }); + n1.receive({}); + }); + }); + it('should send cookies to the same domain when redirected(msg.cookies)', function(done) { + var flow = [{id:'n1',type:'http request',wires:[['n2']],method:'GET',ret:'obj',url:getTestURL('/redirectToSameDomain')}, + {id:"n2", type:"helper"}]; + receivedCookies = {}; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + var cookies1 = receivedCookies['localhost:'+testPort+'/redirectToSameDomain']; + var cookies2 = receivedCookies['localhost:'+testPort+'/redirectReturn']; + if ((cookies1 && Object.keys(cookies1).length != 1) || + cookies1['requestCookie'] !== 'request1') { + done(new Error('Invalid cookie(path:/rediectToSame)')); + return; + } + if ((cookies2 && Object.keys(cookies2).length != 2) || + cookies1['requestCookie'] !== 'request1' || + cookies2['redirectToSameDomainCookie'] !== 'same1') { + done(new Error('Invalid cookie(path:/rediectReurn)')); + return; + } + var redirect1 = msg.redirectList[0]; + redirect1.location.should.equal('http://localhost:'+testPort+'/redirectReturn'); + redirect1.cookies.redirectToSameDomainCookie.Path.should.equal('/'); + redirect1.cookies.redirectToSameDomainCookie.value.should.equal('same1'); + done(); + }); + n1.receive({ + cookies: { requestCookie: 'request1' } + }); + }); + }); + it('should not send cookies to the different domain when redirected(msg.cookies)', function(done) { + var flow = [{id:'n1',type:'http request',wires:[['n2']],method:'GET',ret:'obj',url:getTestURL('/redirectToDifferentDomain')}, + {id:"n2", type:"helper"}]; + receivedCookies = {}; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + var cookies1 = receivedCookies['localhost:'+testPort+'/redirectToDifferentDomain']; + var cookies2 = receivedCookies['127.0.0.1:'+testPort+'/redirectReturn']; + if ((cookies1 && Object.keys(cookies1).length != 1) || + cookies1['requestCookie'] !== 'request1') { + done(new Error('Invalid cookie(path:/rediectToDiffer)')); + return; + } + if (cookies2 && Object.keys(cookies2).length != 0) { + done(new Error('Invalid cookie(path:/rediectReurn)')); + return; + } + var redirect1 = msg.redirectList[0]; + redirect1.location.should.equal('http://127.0.0.1:'+testPort+'/redirectReturn'); + redirect1.cookies.redirectToDifferentDomain.Path.should.equal('/'); + redirect1.cookies.redirectToDifferentDomain.value.should.equal('different1'); + done(); + }); + n1.receive({ + cookies: { requestCookie: 'request1' } + }); + }); + }); + it('should send cookies to the same domain when redirected(msg.headers.cookie)', function(done) { + var flow = [{id:'n1',type:'http request',wires:[['n2']],method:'GET',ret:'obj',url:getTestURL('/redirectToSameDomain')}, + {id:"n2", type:"helper"}]; + receivedCookies = {}; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + var cookies1 = receivedCookies['localhost:'+testPort+'/redirectToSameDomain']; + var cookies2 = receivedCookies['localhost:'+testPort+'/redirectReturn']; + if ((cookies1 && Object.keys(cookies1).length != 1) || + cookies1['requestCookie'] !== 'request1') { + done(new Error('Invalid cookie(path:/rediectToSame)')); + return; + } + if ((cookies2 && Object.keys(cookies2).length != 2) || + cookies1['requestCookie'] !== 'request1' || + cookies2['redirectToSameDomainCookie'] !== 'same1') { + done(new Error('Invalid cookie(path:/rediectReurn)')); + return; + } + var redirect1 = msg.redirectList[0]; + redirect1.location.should.equal('http://localhost:'+testPort+'/redirectReturn'); + redirect1.cookies.redirectToSameDomainCookie.Path.should.equal('/'); + redirect1.cookies.redirectToSameDomainCookie.value.should.equal('same1'); + done(); + }); + n1.receive({ + headers: { cookie: 'requestCookie=request1' } + }); + }); + }); + it('should not send cookies to the different domain when redirected(msg.headers.cookie)', function(done) { + var flow = [{id:'n1',type:'http request',wires:[['n2']],method:'GET',ret:'obj',url:getTestURL('/redirectToDifferentDomain')}, + {id:"n2", type:"helper"}]; + receivedCookies = {}; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + var cookies1 = receivedCookies['localhost:'+testPort+'/redirectToDifferentDomain']; + var cookies2 = receivedCookies['127.0.0.1:'+testPort+'/redirectReturn']; + if ((cookies1 && Object.keys(cookies1).length != 1) || + cookies1['requestCookie'] !== 'request1') { + done(new Error('Invalid cookie(path:/rediectToDiffer)')); + return; + } + if (cookies2 && Object.keys(cookies2).length != 0) { + done(new Error('Invalid cookie(path:/rediectReurn)')); + return; + } + var redirect1 = msg.redirectList[0]; + redirect1.location.should.equal('http://127.0.0.1:'+testPort+'/redirectReturn'); + redirect1.cookies.redirectToDifferentDomain.Path.should.equal('/'); + redirect1.cookies.redirectToDifferentDomain.value.should.equal('different1'); + done(); + }); + n1.receive({ + headers: { cookie: 'requestCookie=request1' } + }); + }); + }); + it('should return all redirect information when redirected multiple times', function(done) { + var flow = [{id:'n1',type:'http request',wires:[['n2']],method:'GET',ret:'obj',url:getTestURL('/redirectMultipleTimes')}, + {id:"n2", type:"helper"}]; + receivedCookies = {}; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + var redirect1 = msg.redirectList[0]; + redirect1.location.should.equal('http://localhost:'+testPort+'/redirectToDifferentDomain'); + redirect1.cookies.redirectMultipleTimes.Path.should.equal('/'); + redirect1.cookies.redirectMultipleTimes.value.should.equal('multiple1'); + var redirect2 = msg.redirectList[1]; + redirect2.location.should.equal('http://127.0.0.1:'+testPort+'/redirectReturn'); + redirect2.cookies.redirectToDifferentDomain.Path.should.equal('/'); + redirect2.cookies.redirectToDifferentDomain.value.should.equal('different1'); + done(); + }); + n1.receive({ + headers: { cookie: 'requestCookie=request1' } + }); + }); + }); + }); +}); diff --git a/packages/connector/test/nodes/core/network/22-websocket_spec.js b/packages/connector/test/nodes/core/network/22-websocket_spec.js new file mode 100644 index 0000000..e13b513 --- /dev/null +++ b/packages/connector/test/nodes/core/network/22-websocket_spec.js @@ -0,0 +1,559 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var ws = require("ws"); +var when = require("when"); +var should = require("should"); +var helper = require("node-red-node-test-helper"); +var websocketNode = require("nr-test-utils").require("@node-red/nodes/core/network/22-websocket.js"); + +var sockets = []; + +function getWsUrl(path) { + return helper.url().replace(/http/, "ws") + path; +} + +function createClient(listenerid) { + return when.promise(function(resolve, reject) { + var node = helper.getNode(listenerid); + var url = getWsUrl(node.path); + var sock = new ws(url); + sockets.push(sock); + + sock.on("open", function() { + resolve(sock); + }); + + sock.on("error", function(err) { + reject(err); + }); + }); +} + +function closeAll() { + for (var i = 0; i < sockets.length; i++) { + sockets[i].close(); + } + sockets = []; +} + +function getSocket(listenerid) { + var node = helper.getNode(listenerid); + return node.server; +} + +describe('websocket Node', function() { + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + afterEach(function() { + closeAll(); + helper.unload(); + }); + + describe('websocket-listener', function() { + it('should load', function(done) { + var flow = [{ id: "n1", type: "websocket-listener", path: "/ws" }]; + helper.load(websocketNode, flow, function() { + helper.getNode("n1").should.have.property("path", "/ws"); + done(); + }); + }); + + it('should be server', function(done) { + var flow = [{ id: "n1", type: "websocket-listener", path: "/ws" }]; + helper.load(websocketNode, flow, function() { + helper.getNode("n1").should.have.property('isServer', true); + done(); + }); + }); + + it('should handle wholemsg property', function(done) { + var flow = [ + { id: "n1", type: "websocket-listener", path: "/ws" }, + { id: "n2", type: "websocket-listener", path: "/ws2", wholemsg: "true" }]; + helper.load(websocketNode, flow, function() { + helper.getNode("n1").should.have.property("wholemsg", false); + helper.getNode("n2").should.have.property("wholemsg", true); + done(); + }); + }); + + it('should create socket', function(done) { + var flow = [ + { id: "n1", type: "websocket-listener", path: "/ws" }, + { id: "n2", type: "websocket in", server: "n1" }]; + helper.load(websocketNode, flow, function() { + createClient("n1").then(function(sock) { + done(); + }).catch(function(err) { + done(err); + }); + }); + }); + + it('should close socket on delete', function(done) { + var flow = [{ id: "n1", type: "websocket-listener", path: "/ws" }]; + helper.load(websocketNode, flow, function() { + createClient("n1").then(function(sock) { + sock.on("close", function(code, msg) { + done(); + }); + helper.clearFlows(); + }).catch(function(err) { + done(err); + }); + }); + }); + + it('should receive data', function(done) { + var flow = [ + { id: "n1", type: "websocket-listener", path: "/ws" }, + { id: "n2", type: "websocket in", server: "n1", wires: [["n3"]] }, + { id: "n3", type: "helper" }]; + helper.load(websocketNode, flow, function() { + createClient("n1").then(function(sock) { + helper.getNode("n3").on("input", function(msg) { + msg.should.have.property("payload", "hello"); + done(); + }); + sock.send("hello"); + }).catch(function(err) { + done(err); + }); + }); + }); + + it('should receive wholemsg', function(done) { + var flow = [ + { id: "n1", type: "websocket-listener", path: "/ws", wholemsg: "true" }, + { id: "n2", type: "websocket in", server: "n1", wires: [["n3"]] }, + { id: "n3", type: "helper" }]; + helper.load(websocketNode, flow, function() { + createClient("n1").then(function(sock) { + sock.send('{"text":"hello"}'); + helper.getNode("n3").on("input", function(msg) { + msg.should.have.property("text", "hello"); + done(); + }); + }).catch(function(err) { + done(err); + }); + }); + }); + + it('should receive wholemsg when data not JSON', function(done) { + var flow = [ + { id: "n1", type: "websocket-listener", path: "/ws", wholemsg: "true" }, + { id: "n2", type: "websocket in", server: "n1", wires: [["n3"]] }, + { id: "n3", type: "helper" }]; + helper.load(websocketNode, flow, function() { + createClient("n1").then(function(sock) { + sock.send('hello'); + helper.getNode("n3").on("input", function(msg) { + msg.should.have.property("payload", "hello"); + done(); + }); + }).catch(function(err) { + done(err); + }); + }); + }); + + it('should receive wholemsg when data not object', function(done) { + var flow = [ + { id: "n1", type: "websocket-listener", path: "/ws", wholemsg: "true" }, + { id: "n2", type: "websocket in", server: "n1", wires: [["n3"]] }, + { id: "n3", type: "helper" }]; + helper.load(websocketNode, flow, function() { + createClient("n1").then(function(sock) { + helper.getNode("n3").on("input", function(msg) { + msg.should.have.property("payload", 123); + done(); + }); + sock.send(123); + }).catch(function(err) { + done(err); + }); + }); + }); + + it('should send', function(done) { + var flow = [ + { id: "n1", type: "websocket-listener", path: "/ws" }, + { id: "n2", type: "helper", wires: [["n3"]] }, + { id: "n3", type: "websocket out", server: "n1" }]; + helper.load(websocketNode, flow, function() { + createClient("n1").then(function(sock) { + sock.on("message", function(msg, flags) { + msg.should.equal("hello"); + done(); + }); + helper.getNode("n2").send({ + payload: "hello" + }); + }).catch(function(err) { + done(err); + }); + }); + }); + + it('should send wholemsg', function(done) { + var flow = [ + { id: "n1", type: "websocket-listener", path: "/ws", wholemsg: "true" }, + { id: "n2", type: "websocket out", server: "n1" }, + { id: "n3", type: "helper", wires: [["n2"]] }]; + helper.load(websocketNode, flow, function() { + createClient("n1").then(function(sock) { + sock.on("message", function(msg, flags) { + JSON.parse(msg).should.have.property("text", "hello"); + done(); + }); + helper.getNode("n3").send({ + text: "hello" + }); + }).catch(function(err) { + done(err); + }); + }); + }); + + it('should do nothing if no payload', function(done) { + var flow = [ + { id: "n1", type: "websocket-listener", path: "/ws" }, + { id: "n2", type: "helper", wires: [["n3"]] }, + { id: "n3", type: "websocket out", server: "n1" }]; + helper.load(websocketNode, flow, function() { + createClient("n1").then(function(sock) { + setTimeout(function() { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "file"; + }); + logEvents.should.have.length(0); + done(); + },100); + helper.getNode("n2").send({topic: "hello"}); + }).catch(function(err) { + done(err); + }); + }); + }); + + it('should echo', function(done) { + var flow = [ + { id: "n1", type: "websocket-listener", path: "/ws" }, + { id: "n2", type: "websocket in", server: "n1", wires: [["n3"]] }, + { id: "n3", type: "websocket out", server: "n1" }]; + helper.load(websocketNode, flow, function() { + createClient("n1").then(function(sock) { + sock.on("message", function(msg, flags) { + msg.should.equal("hello"); + done(); + }); + sock.send("hello"); + }).catch(function(err) { + done(err); + }); + }); + }); + + it('should echo wholemsg', function(done) { + var flow = [ + { id: "n1", type: "websocket-listener", path: "/ws", wholemsg: "true" }, + { id: "n2", type: "websocket in", server: "n1", wires: [["n3"]] }, + { id: "n3", type: "websocket out", server: "n1" }]; + helper.load(websocketNode, flow, function() { + createClient("n1").then(function(sock) { + sock.on("message", function(msg, flags) { + JSON.parse(msg).should.have.property("text", "hello"); + done(); + }); + sock.send('{"text":"hello"}'); + }).catch(function(err) { + done(err); + }); + }); + }); + + it('should broadcast', function(done) { + var flow = [ + { id: "n1", type: "websocket-listener", path: "/ws" }, + { id: "n2", type: "websocket out", server: "n1" }, + { id: "n3", type: "helper", wires: [["n2"]] }]; + helper.load(websocketNode, flow, function() { + var def1 = when.defer(), + def2 = when.defer(); + when.all([createClient("n1"), createClient("n1")]).then(function(socks) { + socks[0].on("message", function(msg, flags) { + msg.should.equal("hello"); + def1.resolve(); + }); + socks[1].on("message", function(msg, flags) { + msg.should.equal("hello"); + def2.resolve(); + }); + helper.getNode("n3").send({ + payload: "hello" + }); + return when.all([def1.promise, def2.promise]).then(function() { + done(); + }); + }).catch(function(err) { + done(err); + }); + }); + }); + }); + + describe('websocket-client', function() { + it('should load', function(done) { + var flow = [ + { id: "server", type: "websocket-listener", path: "/ws" }, + { id: "n1", type: "websocket-client", path: getWsUrl("/ws") }]; + helper.load(websocketNode, flow, function() { + helper.getNode("n1").should.have.property('path', getWsUrl("/ws")); + done(); + }); + }); + + it('should not be server', function(done) { + var flow = [ + { id: "server", type: "websocket-listener", path: "/ws" }, + { id: "n1", type: "websocket-client", path: getWsUrl("/ws") }]; + helper.load(websocketNode, flow, function() { + helper.getNode("n1").should.have.property('isServer', false); + done(); + }); + }); + + it('should handle wholemsg property', function(done) { + var flow = [ + { id: "server", type: "websocket-listener", path: "/ws" }, + { id: "n1", type: "websocket-client", path: getWsUrl("/ws") }, + { id: "n2", type: "websocket-client", path: getWsUrl("/ws"), wholemsg: "true" }]; + helper.load(websocketNode, flow, function() { + helper.getNode("n1").should.have.property("wholemsg", false); + helper.getNode("n2").should.have.property("wholemsg", true); + done(); + }); + }); + + it('should connect to server', function(done) { + var flow = [ + { id: "server", type: "websocket-listener", path: "/ws" }, + { id: "n2", type: "websocket-client", path: getWsUrl("/ws") }]; + helper.load(websocketNode, flow, function() { + getSocket('server').on('connection', function(sock) { + done(); + }); + + }); + }); + + it('should close on delete', function(done) { + var flow = [ + { id: "server", type: "websocket-listener", path: "/ws" }, + { id: "n2", type: "websocket-client", path: getWsUrl("/ws") }]; + helper.load(websocketNode, flow, function() { + getSocket('server').on('connection', function(sock) { + sock.on('close', function() { + done(); + }); + helper.getNode("n2").close(); + }); + }); + }); + + it('should receive data', function(done) { + var flow = [ + { id: "server", type: "websocket-listener", path: "/ws" }, + { id: "n1", type: "websocket-client", path: getWsUrl("/ws") }, + { id: "n2", type: "websocket in", client: "n1", wires: [["n3"]] }, + { id: "n3", type: "helper" }]; + helper.load(websocketNode, flow, function() { + getSocket('server').on('connection', function(sock) { + sock.send('hello'); + }); + + helper.getNode("n3").on("input", function(msg) { + msg.should.have.property("payload", "hello"); + done(); + }); + }); + }); + + it('should receive wholemsg data ', function(done) { + var flow = [ + { id: "server", type: "websocket-listener", path: "/ws" }, + { id: "n1", type: "websocket-client", path: getWsUrl("/ws"), wholemsg: "true" }, + { id: "n2", type: "websocket in", client: "n1", wires: [["n3"]] }, + { id: "n3", type: "helper" }]; + helper.load(websocketNode, flow, function() { + getSocket('server').on('connection', function(sock) { + sock.send('{"text":"hello"}'); + }); + helper.getNode("n3").on("input", function(msg) { + msg.should.have.property("text", "hello"); + done(); + }); + }); + }); + + it('should receive wholemsg when data not JSON', function(done) { + var flow = [ + { id: "server", type: "websocket-listener", path: "/ws" }, + { id: "n1", type: "websocket-client", path: getWsUrl("/ws"), wholemsg: "true" }, + { id: "n2", type: "websocket in", client: "n1", wires: [["n3"]] }, + { id: "n3", type: "helper" }]; + helper.load(websocketNode, flow, function() { + getSocket('server').on('connection', function(sock) { + sock.send('hello'); + }); + helper.getNode("n3").on("input", function(msg) { + msg.should.have.property("payload", "hello"); + done(); + }); + }); + }); + + it('should send', function(done) { + var flow = [ + { id: "server", type: "websocket-listener", path: "/ws" }, + { id: "n1", type: "websocket-client", path: getWsUrl("/ws") }, + { id: "n2", type: "websocket out", client: "n1" }, + { id: "n3", type: "helper", wires: [["n2"]] }]; + helper.load(websocketNode, flow, function() { + getSocket('server').on('connection', function(sock) { + sock.on('message', function(msg) { + msg.should.equal("hello"); + done(); + }); + }); + getSocket("n1").on("open", function() { + helper.getNode("n3").send({ + payload: "hello" + }); + }); + }); + }); + + it('should send buffer', function(done) { + var flow = [ + { id: "server", type: "websocket-listener", path: "/ws" }, + { id: "n1", type: "websocket-client", path: getWsUrl("/ws") }, + { id: "n2", type: "websocket out", client: "n1" }, + { id: "n3", type: "helper", wires: [["n2"]] }]; + helper.load(websocketNode, flow, function() { + getSocket('server').on('connection', function(sock) { + sock.on('message', function(msg) { + Buffer.isBuffer(msg).should.be.true(); + msg.should.have.length(5); + done(); + }); + }); + getSocket("n1").on("open", function() { + helper.getNode("n3").send({ + payload: Buffer.from("hello") + }); + }); + }); + }); + + it('should send wholemsg', function(done) { + var flow = [ + { id: "server", type: "websocket-listener", path: "/ws" }, + { id: "n1", type: "websocket-client", path: getWsUrl("/ws"), wholemsg: "true" }, + { id: "n2", type: "websocket out", client: "n1" }, + { id: "n3", type: "helper", wires: [["n2"]] }]; + helper.load(websocketNode, flow, function() { + getSocket('server').on('connection', function(sock) { + sock.on('message', function(msg) { + JSON.parse(msg).should.have.property("text", "hello"); + done(); + }); + }); + getSocket("n1").on('open', function(){ + helper.getNode("n3").send({ + text: "hello" + }); + }); + }); + }); + + it('should NOT feedback more than once', function(done) { + var flow = [ + { id: "server", type: "websocket-listener", path: "/ws", wholemsg: "true" }, + { id: "client", type: "websocket-client", path: getWsUrl("/ws"), wholemsg: "true" }, + { id: "n1", type: "websocket in", client: "client", wires: [["n2", "output"]] }, + { id: "n2", type: "websocket out", server: "server" }, + { id: "n3", type: "helper", wires: [["n2"]] }, + { id: "output", type: "helper" }]; + helper.load(websocketNode, flow, function() { + getSocket('client').on('open', function() { + helper.getNode("n3").send({ + payload: "ping" + }); + }); + var acc = 0; + helper.getNode("output").on("input", function(msg) { + acc = acc + 1; + }); + setTimeout( function() { + acc.should.equal(1); + helper.clearFlows(); + done(); + }, 250); + }); + }); + }); + + describe('websocket in node', function() { + it('should report error if no server config', function(done) { + var flow = [{ id: "n1", type: "websocket in", mode: "server" }]; + helper.load(websocketNode, flow, function() { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "websocket in"; + }); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.toString().should.startWith("websocket.errors.missing-conf"); + done(); + }); + }); + }); + + describe('websocket out node', function() { + it('should report error if no server config', function(done) { + var flow = [{ id: "n1", type: "websocket out", mode: "server" }]; + helper.load(websocketNode, flow, function() { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "websocket out"; + }); + //console.log(logEvents); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.toString().should.startWith("websocket.errors.missing-conf"); + done(); + }); + }); + }); +}); diff --git a/packages/connector/test/nodes/core/network/31-tcpin_spec.js b/packages/connector/test/nodes/core/network/31-tcpin_spec.js new file mode 100644 index 0000000..cbe7ced --- /dev/null +++ b/packages/connector/test/nodes/core/network/31-tcpin_spec.js @@ -0,0 +1,224 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var net = require("net"); +var should = require("should"); +var stoppable = require('stoppable'); +var helper = require("node-red-node-test-helper"); + +var tcpinNode = require("nr-test-utils").require("@node-red/nodes/core/network/31-tcpin.js"); + + +describe('TCP in Node', function() { + var port = 9200; + var server = undefined; + var server_port = 9300; + var reply_data = undefined; + + beforeEach(function(done) { + startServer(done); + }); + + afterEach(function(done) { + helper.unload(); + stopServer(done); + }); + + function sendArray(sock, array) { + if(array.length > 0) { + sock.write(array[0], function() { + sendArray(sock, array.slice(1)); + }); + } + else { + sock.end(); + } + } + + function startServer(done) { + server_port += 1; + server = stoppable(net.createServer(function(c) { + sendArray(c, reply_data); + })).listen(server_port, "localhost", function(err) { + done(err); + }); + } + + function stopServer(done) { + server.stop(done); + } + + function send(wdata) { + var opt = {port:port, host:"localhost"}; + var client = net.createConnection(opt, function() { + client.write(wdata[0], function() { + client.end(); + if(wdata.length > 1) { + send(wdata.slice(1)); + } + }); + }); + } + + function eql(v0, v1) { + return((v0 === v1) || ((typeof v0) === 'object' && v0.equals(v1))); + } + + function testTCP(flow, wdata, rdata, is_server, done) { + if(is_server) { + reply_data = wdata; + } + helper.load(tcpinNode, flow, function() { + var n2 = helper.getNode("n2"); + var rcount = 0; + n2.on("input", function(msg) { + if(eql(msg.payload, rdata[rcount])) { + rcount++; + } + else { + should.fail(); + } + if(rcount === rdata.length) { + done(); + } + }); + if(!is_server) { + send(wdata); + } + }); + } + + function testTCP0(flow, wdata, rdata, done) { + testTCP(flow, wdata, rdata, false, done); + } + + function testTCP1(flow, wdata, rdata, done) { + testTCP(flow, wdata, rdata, true, done); + } + + it('should recv data (Stream/Buffer)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"server", host:"localhost", port:port, datamode:"stream", datatype:"buffer", newline:"", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP0(flow, ["foo"], [Buffer("foo")], done); + }); + + it('should recv data (Stream/String/Delimiter:\\n)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"server", host:"localhost", port:port, datamode:"stream", datatype:"utf8", newline:"\n", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP0(flow, ["foo\nbar"], ["foo", "bar"], done); + }); + + it('should recv data (Stream/String/No delimiter)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"server", host:"localhost", port:port, datamode:"stream", datatype:"utf8", newline:"", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP0(flow, ["foo\nbar"], ["foo\nbar"], done); + }); + + it('should recv data (Stream/Base64)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"server", host:"localhost", port:port, datamode:"stream", datatype:"base64", newline:"", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP0(flow, ["foo"], [Buffer("foo").toString('base64')], done); + }); + + it('should recv data (Single/Buffer)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"server", host:"localhost", port:port, datamode:"single", datatype:"buffer", newline:"", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP0(flow, ["foo"], [Buffer("foo")], done); + }); + + it('should recv data (Single/String)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"server", host:"localhost", port:port, datamode:"single", datatype:"utf8", newline:"\n", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP0(flow, ["foo\nbar\nbaz"], ["foo\nbar\nbaz"], done); + }); + + it('should recv data (Stream/Base64)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"server", host:"localhost", port:port, datamode:"single", datatype:"base64", newline:"", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP0(flow, ["foo"], [Buffer("foo").toString('base64')], done); + }); + + it('should recv multiple data (Stream/Buffer)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"server", host:"localhost", port:port, datamode:"stream", datatype:"buffer", newline:"", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP0(flow, ["foo", "bar"], [Buffer("foo"), Buffer("bar")], done); + }); + + it('should recv multiple data (Stream/String/Delimiter:\\n)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"server", host:"localhost", port:port, datamode:"stream", datatype:"utf8", newline:"\n", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP0(flow, ["foo", "bar\nbaz"], ["foo", "bar", "baz"], done); + }); + + it('should recv multiple data (Stream/String/No delimiter)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"server", host:"localhost", port:port, datamode:"stream", datatype:"utf8", newline:"", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP0(flow, ["foo", "bar\nbaz"], ["foo", "bar\nbaz"], done); + }); + + it('should recv multiple data (Stream/Base64)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"server", host:"localhost", port:port, datamode:"stream", datatype:"base64", newline:"", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + var wdata = ["foo", "bar"]; + var rdata = wdata.map(function(x) { + return Buffer(x).toString('base64'); + }); + testTCP0(flow, wdata, rdata, done); + }); + + it('should connect & recv data (Stream/Buffer)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"client", host:"localhost", port:server_port, datamode:"stream", datatype:"buffer", newline:"", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP1(flow, ["foo"], [Buffer("foo")], done); + }); + + it('should connect & recv data (Stream/String/Delimiter:\\n)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"client", host:"localhost", port:server_port, datamode:"stream", datatype:"utf8", newline:"\n", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP1(flow, ["foo\nbar"], ["foo", "bar"], done); + }); + + it('should connect & recv data (Stream/String/No delimiter)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"client", host:"localhost", port:server_port, datamode:"stream", datatype:"utf8", newline:"", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP1(flow, ["foo\nbar"], ["foo\nbar"], done); + }); + + it('should connect & recv data (Stream/Base64)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"client", host:"localhost", port:server_port, datamode:"stream", datatype:"base64", newline:"", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP1(flow, ["foo"], [Buffer("foo").toString('base64')], done); + }); + + it('should connect & recv data (Single/Buffer)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"client", host:"localhost", port:server_port, datamode:"single", datatype:"buffer", newline:"", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP1(flow, ["foo"], [Buffer("foo")], done); + }); + + it('should connect & recv data (Single/String)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"client", host:"localhost", port:server_port, datamode:"single", datatype:"utf8", newline:"\n", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP1(flow, ["foo\nbar\nbaz"], ["foo\nbar\nbaz"], done); + }); + + it('should connect & recv data (Stream/Base64)', function(done) { + var flow = [{id:"n1", type:"tcp in", server:"client", host:"localhost", port:server_port, datamode:"single", datatype:"base64", newline:"", topic:"", base64:false, wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP1(flow, ["foo"], [Buffer("foo").toString('base64')], done); + }); + +}); diff --git a/packages/connector/test/nodes/core/network/31-tcprequest_spec.js b/packages/connector/test/nodes/core/network/31-tcprequest_spec.js new file mode 100644 index 0000000..69ae9ad --- /dev/null +++ b/packages/connector/test/nodes/core/network/31-tcprequest_spec.js @@ -0,0 +1,301 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var net = require("net"); +var should = require("should"); +var stoppable = require('stoppable'); +var helper = require("node-red-node-test-helper"); +var tcpinNode = require("nr-test-utils").require("@node-red/nodes/core/network/31-tcpin.js"); +var RED = require("nr-test-utils").require("node-red/lib/red.js"); + + +describe('TCP Request Node', function() { + var server = undefined; + var port = 9000; + + function startServer(done) { + port += 1; + server = stoppable(net.createServer(function(c) { + c.on('data', function(data) { + var rdata = "ACK:"+data.toString(); + c.write(rdata); + }); + c.on('error', function(err) { + startServer(done); + }); + })).listen(port, "127.0.0.1", function(err) { + done(); + }); + } + + before(function(done) { + startServer(done); + }); + + after(function(done) { + server.stop(done); + }); + + afterEach(function() { + helper.unload(); + }); + + function testTCP(flow, val0, val1, done) { + helper.load(tcpinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + if (typeof val1 === 'object') { + msg.should.have.properties(Object.assign({}, val1, {payload: Buffer(val1.payload)})); + } else { + msg.should.have.property('payload', Buffer(val1)); + } + done(); + } catch(err) { + done(err); + } + }); + if((typeof val0) === 'object') { + n1.receive(val0); + } else { + n1.receive({payload:val0}); + } + }); + } + + function testTCPMany(flow, values, result, done) { + helper.load(tcpinNode, flow, () => { + const n1 = helper.getNode("n1"); + const n2 = helper.getNode("n2"); + n2.on("input", msg => { + try { + if (typeof result === 'object') { + msg.should.have.properties(Object.assign({}, result, {payload: Buffer(result.payload)})); + } else { + msg.should.have.property('payload', Buffer(result)); + } + done(); + } catch(err) { + done(err); + } + }); + values.forEach(value => { + n1.receive(typeof value === 'object' ? value : {payload: value}); + }); + }); + } + + describe('single message', function () { + it('should send & recv data', function(done) { + var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"time", splitc: "0", wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP(flow, { + payload: 'foo', + topic: 'bar' + }, { + payload: 'ACK:foo', + topic: 'bar' + }, done); + }); + + it('should retain complete message', function(done) { + var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"time", splitc: "0", wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP(flow, { + payload: 'foo', + topic: 'bar' + }, { + payload: 'ACK:foo', + topic: 'bar' + }, done); + }); + + it('should send & recv data when specified character received', function(done) { + var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"char", splitc: "0", wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP(flow, { + payload: 'foo0bar0', + topic: 'bar' + }, { + payload: 'ACK:foo0', + topic: 'bar' + }, done); + }); + + it('should send & recv data after fixed number of chars received', function(done) { + var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"count", splitc: "7", wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP(flow, { + payload: 'foo bar', + topic: 'bar' + }, { + payload: 'ACK:foo', + topic: 'bar' + }, done); + }); + + it('should send & receive, then keep connection', function(done) { + var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"sit", splitc: "5", wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP(flow, { + payload: 'foo', + topic: 'bar' + }, { + payload: 'ACK:foo', + topic: 'bar' + }, done); + }); + + it('should send & recv data to/from server:port from msg', function(done) { + var flow = [{id:"n1", type:"tcp request", server:"", port:"", out:"time", splitc: "0", wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCP(flow, { + payload: "foo", + host: "localhost", + port: port + }, { + payload: "ACK:foo", + host: 'localhost', + port: port + }, done); + }); + }); + + describe('many messages', function () { + it('should send & recv data', function(done) { + var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"time", splitc: "0", wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCPMany(flow, [{ + payload: 'f', + topic: 'bar' + }, { + payload: 'o', + topic: 'bar' + }, { + payload: 'o', + topic: 'bar' + }], { + payload: 'ACK:foo', + topic: 'bar' + }, done); + }); + + it('should send & recv data when specified character received', function(done) { + var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"char", splitc: "0", wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCPMany(flow, [{ + payload: "foo0", + topic: 'bar' + }, { + payload: "bar0", + topic: 'bar' + }], { + payload: "ACK:foo0", + topic: 'bar' + }, done); + }); + + it('should send & recv data after fixed number of chars received', function(done) { + var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"count", splitc: "7", wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCPMany(flow, [{ + payload: "fo", + topic: 'bar' + }, { + payload: "ob", + topic: 'bar' + }, { + payload: "ar", + topic: 'bar' + }], { + payload: "ACK:foo", + topic: 'bar' + }, done); + }); + + it('should send & receive, then keep connection', function(done) { + var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"sit", splitc: "5", wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCPMany(flow, [{ + payload: "foo", + topic: 'bar' + }, { + payload: "bar", + topic: 'bar' + }, { + payload: "baz", + topic: 'bar' + }], { + payload: "ACK:foobarbaz", + topic: 'bar' + }, done); + }); + + it('should send & recv data to/from server:port from msg', function(done) { + var flow = [{id:"n1", type:"tcp request", server:"", port:"", out:"time", splitc: "0", wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCPMany(flow, [{ + payload: "f", + host: "localhost", + port: port + }, + { + payload: "o", + host: "localhost", + port: port + }, + { + payload: "o", + host: "localhost", + port: port + } + ], { + payload: "ACK:foo", + host: 'localhost', + port: port + }, done); + }); + + it('should limit the queue size', function (done) { + RED.settings.tcpMsgQueueSize = 10; + var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"sit", splitc: "5", wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + // create one more msg than is allowed + const msgs = new Array(RED.settings.tcpMsgQueueSize + 1).fill('x'); + const expected = msgs.slice(0, -1); + testTCPMany(flow, msgs, "ACK:" + expected.join(''), done); + }); + + it('should only retain the latest message', function(done) { + var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"time", splitc: "0", wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + testTCPMany(flow, [{ + payload: 'f', + topic: 'bar' + }, { + payload: 'o', + topic: 'baz' + }, { + payload: 'o', + topic: 'quux' + }], { + payload: 'ACK:foo', + topic: 'quux' + }, done); + }); + }); +}); diff --git a/packages/connector/test/nodes/core/network/32-udpin_spec.js b/packages/connector/test/nodes/core/network/32-udpin_spec.js new file mode 100644 index 0000000..107c313 --- /dev/null +++ b/packages/connector/test/nodes/core/network/32-udpin_spec.js @@ -0,0 +1,94 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var dgram = require("dgram"); +var should = require("should"); +var helper = require("node-red-node-test-helper"); +var udpNode = require("nr-test-utils").require("@node-red/nodes/core/network/32-udp.js"); + + +describe('UDP in Node', function() { + var port = 9100; + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + afterEach(function() { + helper.unload(); + }); + + function sendIPv4(msg) { + var sock = dgram.createSocket('udp4'); + sock.send(msg, 0, msg.length, port, "127.0.0.1", function(msg) { + sock.close(); + }); + } + + function checkRecv(dt, proto, val0, val1, done) { + var flow = [{id:"n1", type:"udp in", + group: "", multicast:false, + port:port, ipv:proto, + datatype: dt, iface: "", + wires:[["n2"]] }, + {id:"n2", type:"helper"}]; + helper.load(udpNode, flow, function() { + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + var ip = ((proto === 'udp6') ? '::ffff:':'') +'127.0.0.1'; + msg.should.have.property('ip', ip); + msg.should.have.property('port'); + msg.should.have.property('payload'); + msg.payload.should.deepEqual(val1); + done(); + } catch(err) { + done(err); + } + }); + sendIPv4(val0); + }); + } + + it('should recv IPv4 data (Buffer)', function(done) { + checkRecv('buffer', 'udp4', 'hello', Buffer('hello'), done); + }); + + it('should recv IPv4 data (String)', function(done) { + checkRecv('utf8', 'udp4', 'hello', 'hello', done); + }); + + it('should recv IPv4 data (base64)', function(done) { + checkRecv('base64', 'udp4', 'hello', Buffer('hello').toString('base64'), done); + }); + + it('should recv IPv6 data (Buffer)', function(done) { + checkRecv('buffer', 'udp6', 'hello', Buffer('hello'), done); + }); + + it('should recv IPv6 data (String)', function(done) { + checkRecv('utf8', 'udp6', 'hello', 'hello', done); + }); + + it('should recv IPv6 data (base64)', function(done) { + checkRecv('base64', 'udp6', 'hello', Buffer('hello').toString('base64'), done); + }); + +}); diff --git a/packages/connector/test/nodes/core/network/32-udpout_spec.js b/packages/connector/test/nodes/core/network/32-udpout_spec.js new file mode 100644 index 0000000..ff01c2f --- /dev/null +++ b/packages/connector/test/nodes/core/network/32-udpout_spec.js @@ -0,0 +1,88 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var dgram = require("dgram"); +var should = require("should"); +var helper = require("node-red-node-test-helper"); +var udpNode = require("nr-test-utils").require("@node-red/nodes/core/network/32-udp.js"); + + +describe('UDP out Node', function() { + var port = 9200; + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + afterEach(function() { + helper.unload(); + }); + + function recvData(data, done) { + var sock = dgram.createSocket('udp4'); + sock.on('message', function(msg, rinfo) { + sock.close(done); + msg.should.deepEqual(data); + }); + sock.bind(port, '127.0.0.1'); + port++; + } + + function checkSend(proto, val0, val1, decode, dest_in_msg, done) { + var dst_ip = dest_in_msg ? undefined : "127.0.0.1"; + var dst_port = dest_in_msg ? undefined : port; + var flow = [{id:"n1", type:"udp out", + addr:dst_ip, port:dst_port, iface: "", + ipv:proto, outport: "", + base64:decode, multicast:false, + wires:[] }]; + helper.load(udpNode, flow, function() { + var n1 = helper.getNode("n1"); + var msg = {}; + if (decode) { + msg.payload = Buffer.from("hello").toString('base64'); + } + else { + msg.payload = "hello"; + } + if (dest_in_msg) { + msg.ip = "127.0.0.1"; + msg.port = port; + } + recvData(val1, done); + setTimeout(function() { + n1.receive(msg); + }, 200); + }); + } + + it('should send IPv4 data', function(done) { + checkSend('udp4', 'hello', Buffer.from('hello'), false, false, done); + }); + + it('should send IPv4 data (base64)', function(done) { + checkSend('udp4', 'hello', Buffer.from('hello'), true, false, done); + }); + + it('should send IPv4 data with dest from msg', function(done) { + checkSend('udp4', 'hello', Buffer.from('hello'), false, true, done); + }); + +}); diff --git a/packages/connector/test/nodes/core/parsers/70-CSV_spec.js b/packages/connector/test/nodes/core/parsers/70-CSV_spec.js new file mode 100644 index 0000000..f46afc2 --- /dev/null +++ b/packages/connector/test/nodes/core/parsers/70-CSV_spec.js @@ -0,0 +1,604 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var csvNode = require("nr-test-utils").require("@node-red/nodes/core/parsers/70-CSV.js"); +var helper = require("node-red-node-test-helper"); + +describe('CSV node', function() { + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + afterEach(function() { + helper.unload(); + }); + + it('should be loaded with defaults', function(done) { + var flow = [{id:"csvNode1", type:"csv", name: "csvNode" }]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("csvNode1"); + n1.should.have.property('name', 'csvNode'); + n1.should.have.property('template', [ '' ]); + n1.should.have.property('sep', ','); + n1.should.have.property('quo', '"'); + n1.should.have.property('ret', '\n'); + n1.should.have.property('winflag', false); + n1.should.have.property('lineend', '\n'); + n1.should.have.property('multi', 'one'); + n1.should.have.property('hdrin', false); + done(); + }); + }); + + describe('csv to json', function() { + var parts_id = undefined; + + afterEach(function() { + parts_id = undefined; + }); + + function check_parts(msg, index, count) { + msg.should.have.property('parts'); + if(parts_id === undefined) { + parts_id = msg.parts.id; + } + else { + msg.parts.should.have.property('id', parts_id); + } + msg.parts.should.have.property('index', index); + msg.parts.should.have.property('count', count); + } + + it('should convert a simple csv string to a javascript object', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { a: 1, b: 2, c: 3, d: 4 }); + check_parts(msg, 0, 1); + done(); + }); + var testString = "1,2,3,4"+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + + it('should remove quotes and whitespace from template', function(done) { + var flow = [ { id:"n1", type:"csv", temp:'"a", "b" , " c "," d " ', wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { a: 1, b: 2, c: 3, d: 4 }); + check_parts(msg, 0, 1); + done(); + }); + var testString = "1,2,3,4"+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + + it('should create column names if no template provided', function(done) { + var flow = [ { id:"n1", type:"csv", temp:'', wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { col1: 1, col2: 2, col3: 3, col4: 4 }); + check_parts(msg, 0, 1); + done(); + }); + var testString = "1,2,3,4"+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + + it('should allow dropping of fields from the template', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,,,d", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { a: 1, d: 4 }); + check_parts(msg, 0, 1); + done(); + }); + var testString = "1,2,3,4"+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + + it('should leave numbers starting with 0, e and + as strings (except 0.)', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { a: 123, b: "0123", c: '+123', d: 'e123', e: 'E123', f: -123 }); + check_parts(msg, 0, 1); + done(); + }); + var testString = '123,0123,+123,e123,E123,-123'+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + + it('should not parse numbers when told not to do so', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", strings:false, wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { a: "1.23", b: "0123", c: "+123", d: "e123", e: "0", f: "-123", g: "1e3" }); + check_parts(msg, 0, 1); + done(); + }); + var testString = '1.23,0123,+123,e123,0,-123,1e3'+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + + it('should leave handle strings with scientific notation as numbers', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { a: 12000, b: 0.012, c: -12000, d: -0.012 }); + check_parts(msg, 0, 1); + done(); + }); + var testString = '12E3,12e-3,-12e3,-12E-3'+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + + + it('should allow quotes in the input', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + //console.log(msg); + msg.should.have.property('payload', { a: 1, b: -2, c: '+3', d: '04', e: '-05', f: 'ab"cd', g: 'with,a,comma' }); + check_parts(msg, 0, 1); + done(); + }); + var testString = '"1","-2","+3","04","-05","ab""cd","with,a,comma"'+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + + it('should recover from an odd number of quotes in the input', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + //console.log(msg); + msg.should.have.property('payload', { a: "with,an", b: "odd,number", c: "ofquotes" }); + //msg.should.have.property('payload', { a: 1, b: -2, c: '+3', d: 4, e: -5, f: 'ab"cd', g: 'with,a,comma' }); + check_parts(msg, 0, 1); + done(); + }); + var testString = '"with,a"n,odd","num"ber","of"qu"ot"es"'+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + + it('should be able to use the first line as a template', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", hdrin:true, wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + //console.log(msg); + if (c === 0) { + msg.should.have.property('payload', { w: 1, x: 2, y: 3, z: 4 }); + check_parts(msg, 0, 2); + c += 1; + } + else { + msg.should.have.property('payload', { w: 5, x: 6, y: 7, z: 8 }); + check_parts(msg, 1, 2); + done(); + } + }); + var testString = "w,x,y,z\n1,2,3,4\n\n5,6,7,8"; + n1.emit("input", {payload:testString}); + }); + }); + + it('should be able to output multiple lines as one array', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", multi:"yes", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', [ { a: 1, b: 2, c: 3, d: 4 },{ a: 5, b: -6, c: '07', d: '+8' },{ a: 9, b: 0, c: 'a', d: 'b' },{ a: 'c', b: 'd', c: 'e', d: 'f' } ]); + msg.should.not.have.property('parts'); + done(); + }); + var testString = "1,2,3,4\n5,-6,07,+8\n9,0,a,b\nc,d,e,f"; + n1.emit("input", {payload:testString}); + }); + }); + + it('should handle numbers in strings but not IP addresses', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { a: "a", b: "127.0.0.1", c: 56.7, d: -32.8, e: "+76.22C" }); + check_parts(msg, 0, 1); + done(); + }); + var testString = "a,127.0.0.1,56.7,-32.8,+76.22C"; + n1.emit("input", {payload:testString}); + }); + }); + + it('should preserve parts property', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { a: 1, b: 2, c: 3, d: 4 }); + check_parts(msg, 3, 4); + done(); + }); + var testString = "1,2,3,4"+String.fromCharCode(10); + n1.emit("input", {payload:testString, parts: {id:"X", index:3, count:4} }); + }); + }); + + it('should be able to use the first of multiple parts as a template if parts are present', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"", hdrin:true, wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + if (c === 0) { + msg.should.have.property('payload', { w: 1, x: 2, y: 3, z: 4 }); + check_parts(msg, 0, 2); + c += 1; + } + else { + msg.should.have.property('payload', { w: 5, x: 6, y: 7, z: 8 }); + check_parts(msg, 1, 2); + done(); + } + }); + var testString1 = "w,x,y,z\n"; + var testString2 = "1,2,3,4\n"; + var testString3 = "5,6,7,8\n"; + n1.emit("input", {payload:testString1, parts:{id:"X", index:0, count:3}}); + n1.emit("input", {payload:testString2, parts:{id:"X", index:1, count:3}}); + n1.emit("input", {payload:testString3, parts:{id:"X", index:2, count:3}}); + }); + }); + + it('should skip several lines from start if requested', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", skip: 2, wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { a: 9, b: 0, c: "A", d: "B" }); + check_parts(msg, 0, 1); + done(); + }); + var testString = "1,2,3,4"+String.fromCharCode(10)+"5,6,7,8"+String.fromCharCode(10)+"9,0,A,B"+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + + it('should skip several lines from start then use next line as a tempate', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", hdrin:true, skip: 2, wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { "9": "C", "0": "D", "A": "E", "B": "F" }); + check_parts(msg, 0, 1); + done(); + }); + var testString = "1,2,3,4"+String.fromCharCode(10)+"5,6,7,8"+String.fromCharCode(10)+"9,0,A,B"+String.fromCharCode(10)+"C,D,E,F"+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + + it('should skip several lines from start and correct parts', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", skip: 2, wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + if (c===0) { + msg.should.have.property('payload', { a: 9, b: 0, c: "A", d: "B" }); + check_parts(msg, 0, 2); + c = c+1; + } + else { + msg.should.have.property('payload', { a: "C", b: "D", c: "E", d: "F" }); + check_parts(msg, 1, 2); + done(); + } + }); + var testString = "1,2,3,4"+String.fromCharCode(10)+"5,6,7,8"+String.fromCharCode(10)+"9,0,A,B"+String.fromCharCode(10)+"C,D,E,F"+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + + it('should be able to skip and then use the first of multiple parts as a template if parts are present', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"", hdrin:true, skip:2, wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + if (c === 0) { + msg.should.have.property('payload', { w: 1, x: 2, y: 3, z: 4 }); + check_parts(msg, 0, 2); + c += 1; + } + else { + msg.should.have.property('payload', { w: 5, x: 6, y: 7, z: 8 }); + check_parts(msg, 1, 2); + done(); + } + }); + var testStringA = "foo\n"; + var testStringB = "bar\n"; + var testString1 = "w,x,y,z\n"; + var testString2 = "1,2,3,4\n"; + var testString3 = "5,6,7,8\n"; + n1.emit("input", {payload:testStringA, parts:{id:"X", index:0, count:5}}); + n1.emit("input", {payload:testStringB, parts:{id:"X", index:1, count:5}}); + n1.emit("input", {payload:testString1, parts:{id:"X", index:2, count:5}}); + n1.emit("input", {payload:testString2, parts:{id:"X", index:3, count:5}}); + n1.emit("input", {payload:testString3, parts:{id:"X", index:4, count:5}}); + }); + }); + + }); + + describe('json object to csv', function() { + + it('should convert a simple object back to a csv', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,,e", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload', '4,foo,true,,0\n'); + done(); + } + catch(e) { done(e); } + }); + var testJson = { e:0, d:1, b:"foo", c:true, a:4 }; + n1.emit("input", {payload:testJson}); + }); + }); + + it('should convert a simple object back to a csv with no template', function(done) { + var flow = [ { id:"n1", type:"csv", temp:" ", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload', '1,foo,"ba""r","di,ng"\n'); + done(); + } + catch(e) { done(e); } + }); + var testJson = { d:1, b:"foo", c:"ba\"r", a:"di,ng" }; + n1.emit("input", {payload:testJson}); + }); + }); + + it('should handle a template with spaces in the property names', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b o,c p,,e", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload', '4,foo,true,,0\n'); + done(); + } + catch(e) { done(e); } + }); + var testJson = { e:0, d:1, "b o":"foo", "c p":true, a:4 }; + n1.emit("input", {payload:testJson}); + }); + }); + + it('should convert an array of objects to a multi-line csv', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload', '4,3,2,1\n1,2,3,4\n'); + done(); + } + catch(e) { done(e); } + }); + var testJson = [{ d: 1, b: 3, c: 2, a: 4 },{d:4,a:1,c:3,b:2}]; + n1.emit("input", {payload:testJson}); + }); + }); + + it('should convert a simple array back to a csv', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload', ',0,1,foo,"ba""r","di,ng"\n'); + done(); + } + catch(e) { done(e); } + }); + var testJson = ["",0,1,"foo",'ba"r','di,ng']; + n1.emit("input", {payload:testJson}); + }); + }); + + it('should convert an array of arrays back to a multi-line csv', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload', '0,1,2,3,4\n4,3,2,1,0\n'); + done(); + } + catch(e) { done(e); } + }); + var testJson = [[0,1,2,3,4],[4,3,2,1,0]]; + n1.emit("input", {payload:testJson}); + }); + }); + + it('should be able to include column names as first row', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", hdrout:true, ret:"\r\n", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload', 'a,b,c,d\r\n4,3,2,1\r\n'); + done(); + } + catch(e) { done(e); } + }); + var testJson = [{ d: 1, b: 3, c: 2, a: 4 }]; + n1.emit("input", {payload:testJson}); + }); + }); + + it('should handle quotes and sub-properties', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload', '{},"text,with,commas","This ""is"" a banana","{""sub"":""object""}"\n'); + done(); + } + catch(e) { done(e); } + }); + var testJson = { d: {sub:"object"}, b: "text,with,commas", c: 'This "is" a banana', a: {sub2:undefined} }; + n1.emit("input", {payload:testJson}); + }); + }); + + }); + + it('should just pass through if no payload provided', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('topic', { a: 4, b: 3, c: 2, d: 1 }); + msg.should.not.have.property('payload'); + + done(); + } + catch(e) { done(e); } + }); + var testJson = { d: 1, b: 3, c: 2, a: 4 }; + n1.emit("input", {topic:testJson}); + }); + }); + + it('should warn if provided a number or boolean', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "csv"; + }); + logEvents.should.have.length(2); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.toString().should.startWith('csv.errors.csv_js'); + logEvents[1][0].should.have.a.property('msg'); + logEvents[1][0].msg.toString().should.startWith('csv.errors.csv_js'); + done(); + } catch(err) { + done(err); + } + },150); + n1.emit("input", {payload:1}); + n1.emit("input", {payload:true}); + }); + }); + +}); diff --git a/packages/connector/test/nodes/core/parsers/70-HTML_spec.js b/packages/connector/test/nodes/core/parsers/70-HTML_spec.js new file mode 100644 index 0000000..3183a05 --- /dev/null +++ b/packages/connector/test/nodes/core/parsers/70-HTML_spec.js @@ -0,0 +1,432 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var path = require("path"); +var fs = require('fs-extra'); + +var htmlNode = require("nr-test-utils").require("@node-red/nodes/core/parsers/70-HTML.js"); +var helper = require("node-red-node-test-helper"); + +describe('HTML node', function() { + + var resourcesDir = __dirname+ path.sep + ".." + path.sep + ".." + path.sep + ".." + path.sep + "resources" + path.sep; + var file = path.join(resourcesDir, "70-HTML-test-file.html"); + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + beforeEach(function() { + fs.existsSync(file).should.be.true(); + }); + + afterEach(function() { + helper.unload(); + }); + + it('should be loaded', function(done) { + var flow = [{id:"htmlNode1", type:"html", name: "htmlNode" }]; + helper.load(htmlNode, flow, function() { + var htmlNode1 = helper.getNode("htmlNode1"); + htmlNode1.should.have.property('name', 'htmlNode'); + done(); + }); + }); + + it('should retrieve header contents if asked to by msg.select', function(done) { + fs.readFile(file, 'utf8', function(err, data) { + var flow = [{id:"n1",type:"html",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + should.equal(msg.payload, 'This is a test page for node 70-HTML'); + done(); + }); + n1.receive({payload:data,topic:"bar",select:"h1"}); + }); + }); + }); + + it('should retrieve header contents if asked to by msg.select - alternative in property', function(done) { + fs.readFile(file, 'utf8', function(err, data) { + var flow = [{id:"n1",type:"html",property:"foo",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.foo[0].should.equal('This is a test page for node 70-HTML'); + done(); + }); + n1.receive({foo:data,topic:"bar",select:"h1"}); + }); + }); + }); + + it('should retrieve header contents if asked to by msg.select - alternative in and out properties', function(done) { + fs.readFile(file, 'utf8', function(err, data) { + var flow = [{id:"n1",type:"html",property:"foo",outproperty:"bar",tag:"h1",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.bar[0].should.equal('This is a test page for node 70-HTML'); + done(); + }); + n1.receive({foo:data,topic:"bar"}); + }); + }); + }); + + it('should emit an empty array if no matching elements', function(done) { + fs.readFile(file, 'utf8', function(err, data) { + var flow = [{id:"n1",type:"html",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload'); + msg.payload.should.be.empty; + done(); + }); + n1.receive({payload:data,topic:"bar",select:"h4"}); + }); + }); + }); + + it('should retrieve paragraph contents when specified', function(done) { + fs.readFile(file, 'utf8', function(err, data) { + var flow = [{id:"n1",type:"html",wires:[["n2"]],ret:"text",tag:"p"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + should.equal(msg.payload, 'There\'s nothing to read here.'); + done(); + }); + n1.receive({payload:data,topic: "bar"}); + }); + }); + }); + + it('should retrieve list contents as an array of html as default', function(done) { + fs.readFile(file, 'utf8', function(err, data) { + var flow = [{id:"n1",type:"html",wires:[["n2"]],tag:"ol"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.payload[0].indexOf("<li>Blue</li>").should.be.above(-1); + msg.payload[0].indexOf("<li>Red</li>").should.be.above(-1); + done(); + }); + n1.receive({payload:data,topic: "bar"}); + }); + }); + }); + + it('should retrieve list contents as an array of text', function(done) { + fs.readFile(file, 'utf8', function(err, data) { + var flow = [{id:"n1",type:"html",wires:[["n2"]],tag:"ol",ret:"text"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.payload[0].indexOf("Blue").should.be.above(-1); + msg.payload[0].indexOf("Red").should.be.above(-1); + done(); + + }); + n1.receive({payload:data,topic: "bar"}); + }); + }); + }); + + it('should fix up a unclosed tag', function(done) { + fs.readFile(file, 'utf8', function(err, data) { + var flow = [{id:"n1",type:"html",wires:[["n2"]],tag:"span"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + should.equal(msg.payload, '<img src="foo.png"/>'); + done(); + }); + n1.receive({payload:data,topic: "bar"}); + }); + }); + }); + + it('should retrieve an attribute from a tag', function(done) { + fs.readFile(file, 'utf8', function(err, data) { + var flow = [{id:"n1",type:"html",wires:[["n2"]],ret:"attr",tag:"span img"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload'); + msg.payload[0].should.have.property('src','foo.png'); + msg.should.have.property('topic', 'bar'); + done(); + }); + n1.receive({payload:data,topic: "bar"}); + }); + }); + }); + + it('should log on error', function(done) { + fs.readFile(file,function(err, data) { + var flow = [{id:"n1",type:"html",wires:[["n2"]],tag:"p"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + try { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.receive({payload:null,topic: "bar"}); + setTimeout(function() { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "html"; + }); + logEvents.should.have.length(1); + // Each logEvent is the array of args passed to the function. + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].should.have.a.property('level',helper.log().ERROR); + + done(); + } catch(err) { done(err) } + },50); + } catch(err) { + done(err); + } + }); + }); + }); + + it('should pass through if payload empty', function(done) { + fs.readFile(file, 'utf8', function(err, data) { + var flow = [{id:"n1",type:"html",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.not.have.property('payload'); + done(); + }); + n1.receive({topic: "bar"}); + }); + }); + }); + + describe('multiple messages', function(){ + var cnt = 0; + var parts_id = undefined; + + afterEach(function() { + cnt.should.be.exactly(2); + cnt = 0; + parts_id = undefined; + }); + + function check_parts(msg, index, count) { + msg.should.have.property('parts'); + msg.parts.should.have.property('id'); + if(parts_id === undefined) { + parts_id = msg.parts.id; + } + else { + msg.parts.should.have.property('id', parts_id); + } + msg.parts.should.have.property('index', index); + msg.parts.should.have.property('count', count); + msg.parts.should.have.property('type', 'string'); + msg.parts.should.have.property('ch', ''); + } + + it('should retrieve list contents as html as default with output as multiple msgs', function(done) { + fs.readFile(file, 'utf8', function(err, data) { + var flow = [{id:"n1",type:"html",wires:[["n2"]],tag:"ul",as:"multi"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + cnt++; + msg.should.have.property('topic', 'bar'); + check_parts(msg, cnt -1, 2); + if (cnt !== 1 && cnt !== 2) { + return false; + } + if (cnt === 1) { + msg.payload.indexOf("<li>Apple</li>").should.be.above(-1); + msg.payload.indexOf("<li>Pear</li>").should.be.above(-1); + } else if (cnt === 2) { + msg.payload.indexOf("<li>Potato</li>").should.be.above(-1); + msg.payload.indexOf("<li>Parsnip</li>").should.be.above(-1); + done(); + } + }); + n1.receive({payload:data,topic: "bar"}); + }); + }); + }); + + + it('should retrieve list contents as html as default with output as multiple msgs - alternative property', function(done) { + fs.readFile(file, 'utf8', function(err, data) { + var flow = [{id:"n1",type:"html",property:"foo",wires:[["n2"]],tag:"ul",as:"multi"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + cnt++; + msg.should.have.property('topic', 'bar'); + check_parts(msg, cnt -1, 2); + if (cnt !== 1 && cnt !== 2) { + return false; + } + if (cnt === 1) { + msg.foo.indexOf("<li>Apple</li>").should.be.above(-1); + msg.foo.indexOf("<li>Pear</li>").should.be.above(-1); + } else if (cnt === 2) { + msg.foo.indexOf("<li>Potato</li>").should.be.above(-1); + msg.foo.indexOf("<li>Parsnip</li>").should.be.above(-1); + done(); + } + }); + n1.receive({foo:data, topic:"bar"}); + }); + }); + }); + + it('should retrieve list contents as text with output as multiple msgs ', function(done) { + fs.readFile(file, 'utf8', function(err, data) { + var flow = [{id:"n1",type:"html",wires:[["n2"]],tag:"ul",ret:"text",as:"multi"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + cnt++; + msg.should.have.property('topic', 'bar'); + check_parts(msg, cnt -1, 2); + if (cnt !== 1 && cnt !== 2) { + return false; + } + if (cnt === 1) { + msg.payload.indexOf("Apple").should.be.above(-1); + msg.payload.indexOf("Pear").should.be.above(-1); + } else if (cnt === 2) { + msg.payload.indexOf("Potato").should.be.above(-1); + msg.payload.indexOf("Parsnip").should.be.above(-1); + done(); + } + }); + n1.receive({payload:data,topic: "bar"}); + }); + }); + }); + + it('should retrieve an attribute from a tag', function(done) { + fs.readFile(file, 'utf8', function(err, data) { + var flow = [{id:"n1",type:"html",wires:[["n2"]],ret:"attr",tag:"span img",as:"multi"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload'); + msg.payload.should.have.property('src','foo.png'); + msg.should.have.property('topic', 'bar'); + check_parts(msg, 0, 1); + cnt = 2; // frig the answer as only one img tag + done(); + }); + n1.receive({payload:data,topic: "bar"}); + }); + }); + }); + + it('should not reuse message', function(done) { + fs.readFile(file, 'utf8', function(err, data) { + var flow = [{id:"n1",type:"html",wires:[["n2"]],tag:"ul",ret:"text",as:"multi"}, + {id:"n2", type:"helper"}]; + + helper.load(htmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var prev_msg = undefined; + n2.on("input", function(msg) { + cnt++; + if (prev_msg == undefined) { + prev_msg = msg; + } + else { + msg.should.not.equal(prev_msg); + } + if (cnt == 2) { + done(); + } + }); + n1.receive({payload:data,topic: "bar"}); + }); + }); + }); + + }); + +}); diff --git a/packages/connector/test/nodes/core/parsers/70-JSON_spec.js b/packages/connector/test/nodes/core/parsers/70-JSON_spec.js new file mode 100644 index 0000000..2ec3304 --- /dev/null +++ b/packages/connector/test/nodes/core/parsers/70-JSON_spec.js @@ -0,0 +1,546 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var jsonNode = require("nr-test-utils").require("@node-red/nodes/core/parsers/70-JSON.js"); +var helper = require("node-red-node-test-helper"); + +describe('JSON node', function() { + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + afterEach(function() { + helper.unload(); + }); + + it('should convert a valid json string to a javascript object', function(done) { + var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.payload.should.have.property('employees'); + msg.payload.employees[0].should.have.property('firstName', 'John'); + msg.payload.employees[0].should.have.property('lastName', 'Smith'); + done(); + }); + var jsonString = '{"employees":[{"firstName":"John", "lastName":"Smith"}]}'; + jn1.receive({payload:jsonString,topic: "bar"}); + }); + }); + + it('should convert a javascript object to a json string', function(done) { + var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + should.equal(msg.payload, '{"employees":[{"firstName":"John","lastName":"Smith"}]}'); + done(); + }); + var obj = {employees:[{firstName:"John", lastName:"Smith"}]}; + jn1.receive({payload:obj}); + }); + }); + + it('should convert a array to a json string', function(done) { + var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + should.equal(msg.payload, '[1,2,3]'); + done(); + }); + var obj = [1,2,3]; + jn1.receive({payload:obj}); + }); + }); + + it('should convert a boolean to a json string', function(done) { + var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + should.equal(msg.payload, 'true'); + done(); + }); + var obj = true; + jn1.receive({payload:obj}); + }); + }); + + it('should convert a json string to a boolean', function(done) { + var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + should.equal(msg.payload, true); + done(); + }); + var obj = "true"; + jn1.receive({payload:obj}); + }); + }); + + it('should convert a number to a json string', function(done) { + var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + should.equal(msg.payload, '2019'); + done(); + }); + var obj = 2019; + jn1.receive({payload:obj}); + }); + }); + + it('should convert a json string to a number', function(done) { + var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + should.equal(msg.payload, 1962); + done(); + }); + var obj = '1962'; + jn1.receive({payload:obj}); + }); + }); + + it('should log an error if asked to parse an invalid json string', function(done) { + var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + try { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn1.receive({payload:'foo',topic: "bar"}); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "json"; + }); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.should.startWith("Unexpected token o"); + logEvents[0][0].should.have.a.property('level',helper.log().ERROR); + done(); + } catch(err) { done(err) } + },20); + } catch(err) { + done(err); + } + }); + }); + + it('should log an error if asked to parse something thats not json or js', function(done) { + var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "json"; + }); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.toString().should.eql('json.errors.dropped-object'); + done(); + } catch(err) { + done(err); + } + },50); + jn1.receive({payload:Buffer.from("a")}); + }); + }); + + it('should pass straight through if no payload set', function(done) { + var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.not.have.property('payload'); + done(); + }); + jn1.receive({topic: "bar"}); + }); + }); + + it('should ensure the result is a json string', function(done) { + var flow = [{id:"jn1",type:"json",action:"str",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + var count = 0; + jn2.on("input", function(msg) { + try { + should.equal(msg.payload, '{"employees":[{"firstName":"John","lastName":"Smith"}]}'); + count++; + if (count === 2) { + done(); + } + } catch(err) { + done(err); + } + }); + var obj = {employees:[{firstName:"John", lastName:"Smith"}]}; + jn1.receive({payload:obj,topic: "bar"}); + jn1.receive({payload:JSON.stringify(obj),topic: "bar"}); + }); + }); + + it('should ensure the result is a JS Object', function(done) { + var flow = [{id:"jn1",type:"json",action:"obj",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + var count = 0; + jn2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.payload.should.have.property('employees'); + msg.payload.employees[0].should.have.property('firstName', 'John'); + msg.payload.employees[0].should.have.property('lastName', 'Smith'); + count++; + if (count === 2) { + done(); + } + } catch(err) { + done(err); + } + }); + var obj = {employees:[{firstName:"John", lastName:"Smith"}]}; + jn1.receive({payload:obj,topic: "bar"}); + jn1.receive({payload:JSON.stringify(obj),topic: "bar"}); + }); + }); + + it('should handle any msg property - receive existing string', function(done) { + var flow = [{id:"jn1",type:"json",property:"one.two",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + try { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('one'); + msg.one.should.have.property('two'); + msg.one.two.should.have.property('employees'); + msg.one.two.employees[0].should.have.property('firstName', 'John'); + msg.one.two.employees[0].should.have.property('lastName', 'Smith'); + done(); + } catch(err) { + done(err); + } + }); + var jsonString = '{"employees":[{"firstName":"John", "lastName":"Smith"}]}'; + jn1.receive({payload:"",one:{two:jsonString},topic: "bar"}); + + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "json"; + }); + }); + }); + + it('should handle any msg property - receive existing obj', function(done) { + var flow = [{id:"jn1",type:"json",property:"one.two",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + try { + should.equal(msg.one.two, '{"employees":[{"firstName":"John","lastName":"Smith"}]}'); + done(); + } catch(err) { + done(err); + } + }); + var jsonString = '{"employees":[{"firstName":"John", "lastName":"Smith"}]}'; + jn1.receive({payload:"",one:{two:JSON.parse(jsonString)},topic: "bar"}); + + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "json"; + }); + }); + }); + + it('should pass an object if provided a valid JSON string and schema', function(done) { + var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + should.equal(msg.payload.number, 3); + should.equal(msg.payload.string, "allo"); + done(); + }); + var jsonString = '{"number": 3, "string": "allo"}'; + var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}}; + jn1.receive({payload:jsonString, schema:schema}); + }); + }); + + it('should pass an object if provided a valid object and schema and action is object', function(done) { + var flow = [{id:"jn1",type:"json",action:"obj",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + should.equal(msg.payload.number, 3); + should.equal(msg.payload.string, "allo"); + done(); + }); + var obj = {"number": 3, "string": "allo"}; + var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}}; + jn1.receive({payload:obj, schema:schema}); + }); + }); + + it('should pass a string if provided a valid object and schema', function(done) { + var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + should.equal(msg.payload, '{"number":3,"string":"allo"}'); + done(); + }); + var obj = {"number": 3, "string": "allo"}; + var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}}; + jn1.receive({payload:obj, schema:schema}); + }); + }); + + it('should pass a string if provided a valid JSON string and schema and action is string', function(done) { + var flow = [{id:"jn1",type:"json",action:"str",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + should.equal(msg.payload, '{"number":3,"string":"allo"}'); + done(); + }); + var jsonString = '{"number":3,"string":"allo"}'; + var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}}; + jn1.receive({payload:jsonString, schema:schema}); + }); + }); + + it('should log an error if passed an invalid object and valid schema', function(done) { + var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + try { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}}; + var obj = {"number": "foo", "string": 3}; + jn1.receive({payload:obj, schema:schema}); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "json"; + }); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.should.equal("json.errors.schema-error: data.number should be number, data.string should be string"); + logEvents[0][0].should.have.a.property('level',helper.log().ERROR); + done(); + } catch(err) { done(err) } + },50); + } catch(err) { + done(err); + } + }); + }); + + it('should log an error if passed an invalid object and valid schema and action is object', function(done) { + var flow = [{id:"jn1",type:"json",action:"obj",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + try { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}}; + var obj = {"number": "foo", "string": 3}; + jn1.receive({payload:obj, schema:schema}); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "json"; + }); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.should.equal("json.errors.schema-error: data.number should be number, data.string should be string"); + logEvents[0][0].should.have.a.property('level',helper.log().ERROR); + done(); + } catch(err) { done(err) } + },50); + } catch(err) { + done(err); + } + }); + }); + + it('should log an error if passed an invalid JSON string and valid schema', function(done) { + var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + try { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}}; + var jsonString = '{"number":"Hello","string":3}'; + jn1.receive({payload:jsonString, schema:schema}); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "json"; + }); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.should.equal("json.errors.schema-error: data.number should be number, data.string should be string"); + logEvents[0][0].should.have.a.property('level',helper.log().ERROR); + done(); + } catch(err) { done(err) } + },50); + } catch(err) { + done(err); + } + }); + }); + + it('should log an error if passed an invalid JSON string and valid schema and action is string', function(done) { + var flow = [{id:"jn1",type:"json",action:"str",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + try { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}}; + var jsonString = '{"number":"Hello","string":3}'; + jn1.receive({payload:jsonString, schema:schema}); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "json"; + }); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.should.equal("json.errors.schema-error: data.number should be number, data.string should be string"); + logEvents[0][0].should.have.a.property('level',helper.log().ERROR); + done(); + } catch(err) { done(err) } + },50); + } catch(err) { + done(err); + } + }); + }); + + it('should log an error if passed a valid object and invalid schema', function(done) { + var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + try { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + var schema = "garbage"; + var obj = {"number": "foo", "string": 3}; + jn1.receive({payload:obj, schema:schema}); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "json"; + }); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.should.equal("json.errors.schema-error-compile"); + logEvents[0][0].should.have.a.property('level',helper.log().ERROR); + done(); + } catch(err) { done(err) } + },50); + } catch(err) { + done(err); + } + }); + }); + + it('msg.schema property should be deleted before sending to next node (string input)', function(done) { + var flow = [{id:"jn1",type:"json",action:"str",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + should.equal(msg.schema, undefined); + done(); + }); + var jsonString = '{"number":3,"string":"allo"}'; + var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}}; + jn1.receive({payload:jsonString, schema:schema}); + }); + }); + + it('msg.schema property should be deleted before sending to next node (object input)', function(done) { + var flow = [{id:"jn1",type:"json",action:"str",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + should.equal(msg.schema, undefined); + done(); + }); + var jsonObject = {"number":3,"string":"allo"}; + var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}}; + jn1.receive({payload:jsonObject, schema:schema}); + }); + }); +}); diff --git a/packages/connector/test/nodes/core/parsers/70-XML_spec.js b/packages/connector/test/nodes/core/parsers/70-XML_spec.js new file mode 100644 index 0000000..e8b2818 --- /dev/null +++ b/packages/connector/test/nodes/core/parsers/70-XML_spec.js @@ -0,0 +1,198 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var xmlNode = require("nr-test-utils").require("@node-red/nodes/core/parsers/70-XML.js"); +var helper = require("node-red-node-test-helper"); + +describe('XML node', function() { + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + afterEach(function() { + helper.unload(); + }); + + it('should be loaded', function(done) { + var flow = [{id:"xmlNode1", type:"xml", name: "xmlNode" }]; + helper.load(xmlNode, flow, function() { + var xmlNode1 = helper.getNode("xmlNode1"); + xmlNode1.should.have.property('name', 'xmlNode'); + done(); + }); + }); + + it('should convert a valid xml string to a javascript object', function(done) { + var flow = [{id:"n1",type:"xml",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(xmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.payload.should.have.property('employees'); + msg.payload.employees.should.have.property('firstName'); + should.equal(msg.payload.employees.firstName[0], 'John'); + msg.payload.employees.should.have.property('lastName'); + should.equal(msg.payload.employees.lastName[0], 'Smith'); + done(); + }); + var string = '<employees><firstName>John</firstName><lastName>Smith</lastName></employees>'; + n1.receive({payload:string,topic: "bar"}); + }); + }); + + it('should convert a valid xml string to a javascript object - alternative property', function(done) { + var flow = [{id:"n1",type:"xml",property:"foo",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(xmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.foo.should.have.property('employees'); + msg.foo.employees.should.have.property('firstName'); + should.equal(msg.foo.employees.firstName[0], 'John'); + msg.foo.employees.should.have.property('lastName'); + should.equal(msg.foo.employees.lastName[0], 'Smith'); + done(); + }); + var string = '<employees><firstName>John</firstName><lastName>Smith</lastName></employees>'; + n1.receive({foo:string,topic: "bar"}); + }); + }); + + it('should convert a valid xml string to a javascript object with options', function(done) { + var flow = [{id:"n1",type:"xml",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(xmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.payload.should.have.property('employees'); + msg.payload.employees.should.have.property('firstName'); + should.equal(msg.payload.employees.firstName[0], 'John'); + msg.payload.employees.should.have.property('lastName'); + should.equal(msg.payload.employees.lastName[0], 'Smith'); + done(); + }); + var string = '<employees><firstName>John</firstName><lastName>Smith</lastName></employees>'; + n1.receive({payload:string, topic:"bar", options:{trim:true}}); + }); + }); + + it('should convert a javascript object to an xml string', function(done) { + var flow = [{id:"n1",type:"xml",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(xmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + var index = msg.payload.indexOf('<employees><firstName>John</firstName><lastName>Smith</lastName></employees>'); + index.should.be.above(-1); + done(); + }); + var obj = {"employees":{"firstName":["John"],"lastName":["Smith"] }}; + n1.receive({payload:obj,topic: "bar"}); + }); + }); + + it('should convert a javascript object to an xml string with options - alternative property', function(done) { + var flow = [{id:"n1",type:"xml",property:"foo",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(xmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + var index = msg.foo.indexOf('<employees>\n <firstName>John</firstName>\n <lastName>Smith</lastName>\n</employees>'); + index.should.be.above(-1); + done(); + }); + var obj = {"employees":{"firstName":["John"],"lastName":["Smith"] }}; + n1.receive({foo:obj, topic:"bar", options:{headless:true}}); + }); + }); + + it('should log an error if asked to parse an invalid xml string', function(done) { + var flow = [{id:"n1",type:"xml",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(xmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.receive({payload:'<not valid>',topic: "bar"}); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "xml"; + }); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.toString().should.startWith("Error: Attribute without value"); + done(); + } catch(err) { + done(err); + } + },200); + }); + }); + + it('should log an error if asked to parse something thats not xml or js', function(done) { + var flow = [{id:"n1",type:"xml",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(xmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.receive({payload:1,topic: "bar"}); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "xml"; + }); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg',"xml.errors.xml_js"); + done(); + } catch(err) { + done(err); + } + },200); + }); + }); + + it('should just pass through if payload is missing', function(done) { + var flow = [{id:"n1",type:"xml",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(xmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.not.have.property('payload'); + done(); + }); + n1.receive({topic: "bar"}); + }); + }); + +}); diff --git a/packages/connector/test/nodes/core/parsers/70-YAML_spec.js b/packages/connector/test/nodes/core/parsers/70-YAML_spec.js new file mode 100644 index 0000000..3441e09 --- /dev/null +++ b/packages/connector/test/nodes/core/parsers/70-YAML_spec.js @@ -0,0 +1,195 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var yamlNode = require("nr-test-utils").require("@node-red/nodes/core/parsers/70-YAML.js"); +var helper = require("node-red-node-test-helper"); + +describe('YAML node', function() { + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + afterEach(function() { + helper.unload(); + }); + + it('should be loaded', function(done) { + var flow = [{id:"yamlNode1", type:"yaml", name: "yamlNode" }]; + helper.load(yamlNode, flow, function() { + var yamlNode1 = helper.getNode("yamlNode1"); + yamlNode1.should.have.property('name', 'yamlNode'); + done(); + }); + }); + + it('should convert a valid yaml string to a javascript object', function(done) { + var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"}, + {id:"yn2", type:"helper"}]; + helper.load(yamlNode, flow, function() { + var yn1 = helper.getNode("yn1"); + var yn2 = helper.getNode("yn2"); + yn2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.payload.should.have.property('employees'); + msg.payload.employees[0].should.have.property('firstName', 'John'); + msg.payload.employees[0].should.have.property('lastName', 'Smith'); + done(); + }); + var yamlString = "employees:\n - firstName: John\n lastName: Smith\n"; + yn1.receive({payload:yamlString,topic: "bar"}); + }); + }); + + it('should convert a valid yaml string to a javascript object - using another property', function(done) { + var flow = [{id:"yn1",type:"yaml",property:"foo",wires:[["yn2"]],func:"return msg;"}, + {id:"yn2", type:"helper"}]; + helper.load(yamlNode, flow, function() { + var yn1 = helper.getNode("yn1"); + var yn2 = helper.getNode("yn2"); + yn2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.foo.should.have.property('employees'); + msg.foo.employees[0].should.have.property('firstName', 'John'); + msg.foo.employees[0].should.have.property('lastName', 'Smith'); + done(); + }); + var yamlString = "employees:\n - firstName: John\n lastName: Smith\n"; + yn1.receive({foo:yamlString,topic: "bar"}); + }); + }); + + it('should convert a javascript object to a yaml string', function(done) { + var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"}, + {id:"yn2", type:"helper"}]; + helper.load(yamlNode, flow, function() { + var yn1 = helper.getNode("yn1"); + var yn2 = helper.getNode("yn2"); + yn2.on("input", function(msg) { + should.equal(msg.payload, "employees:\n - firstName: John\n lastName: Smith\n"); + done(); + }); + var obj = {employees:[{firstName:"John", lastName:"Smith"}]}; + yn1.receive({payload:obj}); + }); + }); + + it('should convert a javascript object to a yaml string - using another property', function(done) { + var flow = [{id:"yn1",type:"yaml",property:"foo",wires:[["yn2"]],func:"return msg;"}, + {id:"yn2", type:"helper"}]; + helper.load(yamlNode, flow, function() { + var yn1 = helper.getNode("yn1"); + var yn2 = helper.getNode("yn2"); + yn2.on("input", function(msg) { + should.equal(msg.foo, "employees:\n - firstName: John\n lastName: Smith\n"); + done(); + }); + var obj = {employees:[{firstName:"John", lastName:"Smith"}]}; + yn1.receive({foo:obj}); + }); + }); + + it('should convert an array to a yaml string', function(done) { + var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"}, + {id:"yn2", type:"helper"}]; + helper.load(yamlNode, flow, function() { + var yn1 = helper.getNode("yn1"); + var yn2 = helper.getNode("yn2"); + yn2.on("input", function(msg) { + should.equal(msg.payload, "- 1\n- 2\n- 3\n"); + done(); + }); + var obj = [1,2,3]; + yn1.receive({payload:obj}); + }); + }); + + it('should log an error if asked to parse an invalid yaml string', function(done) { + var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"}, + {id:"yn2", type:"helper"}]; + helper.load(yamlNode, flow, function() { + try { + var yn1 = helper.getNode("yn1"); + var yn2 = helper.getNode("yn2"); + yn1.receive({payload:'employees:\n-firstName: John\n- lastName: Smith\n',topic: "bar"}); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "yaml"; + }); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.should.startWith("end of the stream"); + logEvents[0][0].should.have.a.property('level',helper.log().ERROR); + done(); + } catch(err) { done(err) } + },50); + } catch(err) { + done(err); + } + }); + }); + + it('should log an error if asked to parse something thats not yaml or js', function(done) { + var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"}, + {id:"yn2", type:"helper"}]; + helper.load(yamlNode, flow, function() { + var yn1 = helper.getNode("yn1"); + var yn2 = helper.getNode("yn2"); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "yaml"; + }); + logEvents.should.have.length(3); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.toString().should.eql('yaml.errors.dropped'); + logEvents[1][0].should.have.a.property('msg'); + logEvents[1][0].msg.toString().should.eql('yaml.errors.dropped'); + logEvents[2][0].should.have.a.property('msg'); + logEvents[2][0].msg.toString().should.eql('yaml.errors.dropped-object'); + done(); + } catch(err) { + done(err); + } + },150); + yn1.receive({payload:true}); + yn1.receive({payload:1}); + yn1.receive({payload:Buffer.from("a")}); + }); + }); + + it('should pass straight through if no payload set', function(done) { + var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"}, + {id:"yn2", type:"helper"}]; + helper.load(yamlNode, flow, function() { + var yn1 = helper.getNode("yn1"); + var yn2 = helper.getNode("yn2"); + yn2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.not.have.property('payload'); + done(); + }); + yn1.receive({topic: "bar"}); + }); + }); + +}); diff --git a/packages/connector/test/nodes/core/sequence/17-split_spec.js b/packages/connector/test/nodes/core/sequence/17-split_spec.js new file mode 100644 index 0000000..2c45f0e --- /dev/null +++ b/packages/connector/test/nodes/core/sequence/17-split_spec.js @@ -0,0 +1,1649 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var splitNode = require("nr-test-utils").require("@node-red/nodes/core/sequence/17-split.js"); +var joinNode = require("nr-test-utils").require("@node-red/nodes/core/sequence/17-split.js"); +var helper = require("node-red-node-test-helper"); +var RED = require("nr-test-utils").require("node-red/lib/red.js"); +var Context = require("nr-test-utils").require("@node-red/runtime/lib/nodes/context"); + +var TimeoutForErrorCase = 20; + +describe('SPLIT node', function() { + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + afterEach(function() { + helper.unload(); + }); + + it('should be loaded', function(done) { + var flow = [{id:"splitNode1", type:"split", name:"splitNode" }]; + helper.load(splitNode, flow, function() { + var splitNode1 = helper.getNode("splitNode1"); + splitNode1.should.have.property('name', 'splitNode'); + done(); + }); + }); + + it('should split an array into multiple messages', function(done) { + var flow = [{id:"sn1", type:"split", wires:[["sn2"]]}, + {id:"sn2", type:"helper"}]; + helper.load(splitNode, flow, function() { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + sn2.on("input", function(msg) { + msg.should.have.property("parts"); + msg.parts.should.have.property("count",4); + msg.parts.should.have.property("type","array"); + msg.parts.should.have.property("index"); + if (msg.parts.index === 0) { msg.payload.should.equal(1); } + if (msg.parts.index === 1) { msg.payload.should.equal(2); } + if (msg.parts.index === 2) { msg.payload.should.equal(3); } + if (msg.parts.index === 3) { msg.payload.should.equal(4); done(); } + }); + sn1.receive({payload:[1,2,3,4]}); + }); + }); + + it('should split an array into multiple messages of a specified size', function(done) { + var flow = [{id:"sn1", type:"split", wires:[["sn2"]], arraySplt:3, arraySpltType:"len"}, + {id:"sn2", type:"helper"}]; + helper.load(splitNode, flow, function() { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + sn2.on("input", function(msg) { + msg.should.have.property("parts"); + msg.parts.should.have.property("count",2); + msg.parts.should.have.property("type","array"); + msg.parts.should.have.property("index"); + msg.payload.should.be.an.Array(); + if (msg.parts.index === 0) { msg.payload.length.should.equal(3); } + if (msg.parts.index === 1) { msg.payload.length.should.equal(1); done(); } + }); + sn1.receive({payload:[1,2,3,4]}); + }); + }); + + it('should split an object into pieces', function(done) { + var flow = [{id:"sn1", type:"split", wires:[["sn2"]]}, + {id:"sn2", type:"helper"}]; + helper.load(splitNode, flow, function() { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + var count = 0; + sn2.on("input", function(msg) { + msg.should.have.property("payload"); + msg.should.have.property("parts"); + msg.parts.should.have.property("type","object"); + msg.parts.should.have.property("key"); + msg.parts.should.have.property("count"); + msg.parts.should.have.property("index"); + msg.topic.should.equal("foo"); + if (msg.parts.index === 0) { msg.payload.should.equal(1); } + if (msg.parts.index === 1) { msg.payload.should.equal("2"); } + if (msg.parts.index === 2) { msg.payload.should.equal(true); done(); } + }); + sn1.receive({topic:"foo",payload:{a:1,b:"2",c:true}}); + }); + }); + + it('should split an object into pieces and overwrite their topics', function(done) { + var flow = [{id:"sn1", type:"split", addname:"topic", wires:[["sn2"]]}, + {id:"sn2", type:"helper"}]; + helper.load(splitNode, flow, function() { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + var count = 0; + sn2.on("input", function(msg) { + msg.should.have.property("payload"); + msg.should.have.property("parts"); + msg.parts.should.have.property("type","object"); + msg.parts.should.have.property("key"); + msg.parts.should.have.property("count"); + msg.parts.should.have.property("index"); + if (msg.parts.index === 0) { msg.payload.should.equal(1); msg.topic.should.equal("a"); } + if (msg.parts.index === 1) { msg.payload.should.equal("2"); msg.topic.should.equal("b"); } + if (msg.parts.index === 2) { msg.payload.should.equal(true); msg.topic.should.equal("c"); done(); } + }); + sn1.receive({topic:"foo",payload:{a:1,b:"2",c:true}}); + }); + }); + + it('should split a string into new-lines', function(done) { + var flow = [{id:"sn1", type:"split", wires:[["sn2"]]}, + {id:"sn2", type:"helper"}]; + helper.load(splitNode, flow, function() { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + sn2.on("input", function(msg) { + msg.should.have.property("parts"); + msg.parts.should.have.property("count",4); + msg.parts.should.have.property("type","string"); + msg.parts.should.have.property("index"); + if (msg.parts.index === 0) { msg.payload.should.equal("Da"); } + if (msg.parts.index === 1) { msg.payload.should.equal("ve"); } + if (msg.parts.index === 2) { msg.payload.should.equal(" "); } + if (msg.parts.index === 3) { msg.payload.should.equal("CJ"); done(); } + }); + sn1.receive({payload:"Da\nve\n \nCJ"}); + }); + }); + + it('should split a string on a specified char', function(done) { + var flow = [{id:"sn1", type:"split", wires:[["sn2"]], splt:"\n"}, + {id:"sn2", type:"helper"}]; + helper.load(splitNode, flow, function() { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + sn2.on("input", function(msg) { + msg.should.have.property("parts"); + msg.parts.should.have.property("count",3); + msg.parts.should.have.property("ch","\n"); + msg.parts.should.have.property("index"); + msg.parts.should.have.property("type","string"); + if (msg.parts.index === 0) { msg.payload.should.equal("1"); } + if (msg.parts.index === 1) { msg.payload.should.equal("2"); } + if (msg.parts.index === 2) { msg.payload.should.equal("3"); done(); } + }); + sn1.receive({payload:"1\n2\n3"}); + }); + }); + + it('should split a string into lengths', function(done) { + var flow = [{id:"sn1", type:"split", wires:[["sn2"]], splt:"2", spltType:"len"}, + {id:"sn2", type:"helper"}]; + helper.load(splitNode, flow, function() { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + sn2.on("input", function(msg) { + msg.should.have.property("parts"); + msg.parts.should.have.property("count",4); + msg.parts.should.have.property("ch",""); + msg.parts.should.have.property("index"); + msg.parts.should.have.property("type","string"); + if (msg.parts.index === 0) { msg.payload.should.equal("12"); } + if (msg.parts.index === 1) { msg.payload.should.equal("34"); } + if (msg.parts.index === 2) { msg.payload.should.equal("56"); } + if (msg.parts.index === 3) { msg.payload.should.equal("78"); done(); } + }); + sn1.receive({payload:"12345678"}); + }); + }); + + it('should split a string on a specified char in stream mode', function(done) { + var flow = [{id:"sn1", type:"split", wires:[["sn2"]], splt:"\n", stream:true}, + {id:"sn2", type:"helper"}]; + helper.load(splitNode, flow, function() { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + sn2.on("input", function(msg) { + msg.should.have.property("parts"); + msg.parts.should.have.property("ch","\n"); + msg.parts.should.have.property("index"); + msg.parts.should.have.property("type","string"); + if (msg.parts.index === 0) { msg.payload.should.equal("1"); } + if (msg.parts.index === 1) { msg.payload.should.equal("2"); } + if (msg.parts.index === 2) { msg.payload.should.equal("3"); } + if (msg.parts.index === 3) { msg.payload.should.equal("4"); } + if (msg.parts.index === 4) { msg.payload.should.equal("5"); } + if (msg.parts.index === 5) { msg.payload.should.equal("6"); done(); } + }); + sn1.receive({payload:"1\n2\n3\n"}); + sn1.receive({payload:"4\n5\n6\n"}); + }); + }); + + it('should split a buffer into lengths', function(done) { + var flow = [{id:"sn1", type:"split", wires:[["sn2"]], splt:"2", spltType:"len"}, + {id:"sn2", type:"helper"}]; + helper.load(splitNode, flow, function() { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + sn2.on("input", function(msg) { + try { + //console.log(msg); + msg.should.have.property("parts"); + Buffer.isBuffer(msg.payload).should.be.true(); + msg.parts.should.have.property("count",4); + msg.parts.should.have.property("index"); + msg.parts.should.have.property("type","buffer"); + if (msg.parts.index === 0) { msg.payload.toString().should.equal("12"); } + if (msg.parts.index === 1) { msg.payload.toString().should.equal("34"); } + if (msg.parts.index === 2) { msg.payload.toString().should.equal("56"); } + if (msg.parts.index === 3) { msg.payload.toString().should.equal("78"); done(); } + } catch(err) { + done(err); + } + }); + var b = Buffer.from("12345678"); + sn1.receive({payload:b}); + }); + }); + + it('should split a buffer on another buffer (streaming)', function(done) { + var flow = [{id:"sn1", type:"split", wires:[["sn2"]], splt:"[52]", spltType:"bin", stream:true}, + {id:"sn2", type:"helper"}]; + helper.load(splitNode, flow, function() { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + sn2.on("input", function(msg) { + try { + msg.should.have.property("parts"); + Buffer.isBuffer(msg.payload).should.be.true(); + msg.parts.should.have.property("index"); + msg.parts.should.have.property("type","buffer"); + if (msg.parts.index === 0) { msg.payload.toString().should.equal("123"); } + if (msg.parts.index === 1) { msg.payload.toString().should.equal("123"); } + if (msg.parts.index === 2) { msg.payload.toString().should.equal("123"); done(); } + } catch(err) { + done(err); + } + }); + var b1 = Buffer.from("123412"); + var b2 = Buffer.from("341234"); + sn1.receive({payload:b1}); + sn1.receive({payload:b2}); + }); + }); + + it('should handle invalid spltType (not an array)', function (done) { + var flow = [{ id: "sn1", type: "split", splt: "1", spltType: "bin", wires: [["sn2"]] }, + { id: "sn2", type: "helper" }]; + helper.load(splitNode, flow, function () { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + setTimeout(function () { + done(); + }, TimeoutForErrorCase); + sn2.on("input", function (msg) { + done(new Error("This path does not go through.")); + }); + sn1.receive({ payload: "123" }); + }); + }); + + it('should handle invalid splt length', function (done) { + var flow = [{ id: "sn1", type: "split", splt: 0, spltType: "len", wires: [["sn2"]] }, + { id: "sn2", type: "helper" }]; + helper.load(splitNode, flow, function () { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + setTimeout(function () { + done(); + }, TimeoutForErrorCase); + sn2.on("input", function (msg) { + done(new Error("This path does not go through.")); + }); + sn1.receive({ payload: "123" }); + }); + }); + + it('should handle invalid array splt length', function (done) { + var flow = [{ id: "sn1", type: "split", arraySplt: 0, arraySpltType: "len", wires: [["sn2"]] }, + { id: "sn2", type: "helper" }]; + helper.load(splitNode, flow, function () { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + setTimeout(function () { + done(); + }, TimeoutForErrorCase); + sn2.on("input", function (msg) { + done(new Error("This path does not go through.")); + }); + sn1.receive({ payload: "123" }); + }); + }); + + it('should ceil count value when msg.payload type is string', function (done) { + var flow = [{ id: "sn1", type: "split", splt: "2", spltType: "len", wires: [["sn2"]] }, + { id: "sn2", type: "helper" }]; + helper.load(splitNode, flow, function () { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + sn2.on("input", function (msg) { + msg.should.have.property("parts"); + msg.parts.should.have.property("count", 2); + msg.parts.should.have.property("index"); + if (msg.parts.index === 0) { msg.payload.length.should.equal(2); } + if (msg.parts.index === 1) { msg.payload.length.should.equal(1); done(); } + }); + sn1.receive({ payload: "123" }); + }); + }); + + it('should handle spltBufferString value of undefined', function (done) { + var flow = [{ id: "sn1", type: "split", wires: [["sn2"]], splt: "[52]", spltType: "bin" }, + { id: "sn2", type: "helper" }]; + helper.load(splitNode, flow, function () { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + sn2.on("input", function (msg) { + try { + msg.should.have.property("parts"); + msg.parts.should.have.property("index"); + if (msg.parts.index === 0) { msg.payload.toString().should.equal("123"); done(); } + } catch (err) { + done(err); + } + }); + sn1.receive({ payload: "123" }); + }); + }); + + it('should ceil count value when msg.payload type is Buffer', function (done) { + var flow = [{ id: "sn1", type: "split", splt: "2", spltType: "len", wires: [["sn2"]] }, + { id: "sn2", type: "helper" }]; + helper.load(splitNode, flow, function () { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + sn2.on("input", function (msg) { + msg.should.have.property("parts"); + msg.parts.should.have.property("count", 2); + msg.parts.should.have.property("index"); + if (msg.parts.index === 0) { msg.payload.length.should.equal(2); } + if (msg.parts.index === 1) { msg.payload.length.should.equal(1); done(); } + }); + var b = Buffer.from("123"); + sn1.receive({ payload: b }); + }); + }); + + it('should set msg.parts.ch when node.spltType is str', function (done) { + var flow = [{ id: "sn1", type: "split", splt: "2", spltType: "str", stream: false, wires: [["sn2"]] }, + { id: "sn2", type: "helper" }]; + helper.load(splitNode, flow, function () { + var sn1 = helper.getNode("sn1"); + var sn2 = helper.getNode("sn2"); + sn2.on("input", function (msg) { + msg.should.have.property("parts"); + msg.parts.should.have.property("count", 2); + msg.parts.should.have.property("index"); + if (msg.parts.index === 0) { msg.payload.length.should.equal(2); } + if (msg.parts.index === 1) { msg.payload.length.should.equal(1); done(); } + }); + var b = Buffer.from("123"); + sn1.receive({ payload: b }); + }); + }); + +}); + +describe('JOIN node', function() { + + beforeEach(function(done) { + helper.startServer(done); + }); + + function initContext(done) { + Context.init({ + contextStorage: { + memory: { + module: "memory" + } + } + }); + Context.load().then(function () { + done(); + }); + } + + afterEach(function(done) { + helper.unload().then(function(){ + return Context.clean({allNodes:{}}); + }).then(function(){ + return Context.close(); + }).then(function(){ + RED.settings.nodeMessageBufferMaxLength = 0; + helper.stopServer(done); + }); + }); + + it('should be loaded', function(done) { + var flow = [{id:"joinNode1", type:"join", name:"joinNode" }]; + helper.load(joinNode, flow, function() { + var joinNode1 = helper.getNode("joinNode1"); + joinNode1.should.have.property('name', 'joinNode'); + joinNode1.should.have.property('count', 0); + joinNode1.should.have.property('timer', 0); + joinNode1.should.have.property('build', 'array'); + done(); + }); + }); + + it('should join bits of string back together automatically', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], joiner:",", build:"string", mode:"auto"}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.equal("A,B,C,D"); + done(); + } + catch(e) {done(e);} + }); + n1.receive({payload:"A", parts:{id:1, type:"string", ch:",", index:0, count:4}}); + n1.receive({payload:"B", parts:{id:1, type:"string", ch:",", index:1, count:4}}); + n1.receive({payload:"C", parts:{id:1, type:"string", ch:",", index:2, count:4}}); + n1.receive({payload:"D", parts:{id:1, type:"string", ch:",", index:3, count:4}}); + }); + }); + it('should join bits of string back together automatically with a buffer joiner', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], joiner:"[44]", joinerType:"bin", build:"string", mode:"auto"}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.equal("A,B,C,D"); + done(); + } + catch(e) {done(e);} + }); + n1.receive({payload:"A", parts:{id:1, type:"string", ch:",", index:0, count:4}}); + n1.receive({payload:"B", parts:{id:1, type:"string", ch:",", index:1, count:4}}); + n1.receive({payload:"C", parts:{id:1, type:"string", ch:",", index:2, count:4}}); + n1.receive({payload:"D", parts:{id:1, type:"string", ch:",", index:3, count:4}}); + }); + }); + + it('should join bits of buffer back together automatically', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], joiner:",", build:"buffer", mode:"auto"}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + Buffer.isBuffer(msg.payload).should.be.true(); + msg.payload.toString().should.equal("A-B-C-D"); + done(); + } + catch(e) {done(e);} + }); + n1.receive({payload:Buffer.from("A"), parts:{id:1, type:"buffer", ch:Buffer.from("-"), index:0, count:4}}); + n1.receive({payload:Buffer.from("B"), parts:{id:1, type:"buffer", ch:Buffer.from("-"), index:1, count:4}}); + n1.receive({payload:Buffer.from("C"), parts:{id:1, type:"buffer", ch:Buffer.from("-"), index:2, count:4}}); + n1.receive({payload:Buffer.from("D"), parts:{id:1, type:"buffer", ch:Buffer.from("-"), index:3, count:4}}); + }); + }); + + it('should join things into an array after a count', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], count:3, joiner:",",mode:"custom"}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.be.an.Array(); + msg.payload[0].should.equal(1); + msg.payload[1].should.equal(true); + //msg.payload[2].a.should.equal(1); + done(); + } + catch(e) {done(e);} + }); + n1.receive({payload:1}); + n1.receive({payload:true}); + n1.receive({payload:{a:1}}); + }); + }); + + it('should join things into an array after a count with a buffer join set', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], count:3, joinerType:"bin", joiner:"" ,mode:"custom"}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.be.an.Array(); + msg.payload[0].should.equal(1); + msg.payload[1].should.equal(true); + //msg.payload[2].a.should.equal(1); + done(); + } + catch(e) {done(e);} + }); + n1.receive({payload:1}); + n1.receive({payload:true}); + n1.receive({payload:{a:1}}); + }); + }); + + it('should join strings into a buffer after a count', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], count:2, build:"buffer", joinerType:"bin", joiner:"", mode:"custom"}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.length.should.equal(10); + msg.payload.toString().should.equal("helloworld"); + done(); + } + catch(e) {done(e);} + }); + n1.receive({payload:"hello"}); + n1.receive({payload:"world"}); + }); + }); + + it('should join things into an object after a count', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], count:5, build:"object", mode:"custom"}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.have.property("a",1); + msg.payload.should.have.property("b","2"); + msg.payload.should.have.property("c",true); + msg.payload.should.have.property("d"); + msg.payload.d.should.have.property("e",7); + // msg.payload.should.have.property("g"); + // msg.payload.g.should.have.property("f",6); + done(); + } + catch(e) { done(e)} + }); + n1.receive({payload:1, topic:"a"}); + n1.receive({payload:"2", topic:"b"}); + n1.receive({payload:true, topic:"c"}); + n1.receive({payload:{e:5}, topic:"d"}); + n1.receive({payload:{e:7}, topic:"d"}); + n1.receive({payload:{f:6}, topic:"g"}); + }); + }); + + it('should merge objects', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], count:5, build:"merged", mode:"custom"}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.have.property("a",1); + msg.payload.should.have.property("b",2); + msg.payload.should.have.property("c",3); + msg.payload.should.have.property("d",4); + msg.payload.should.have.property("e",5); + done(); + } + catch(e) { done(e)} + }); + n1.receive({payload:{a:9}, topic:"f"}); + n1.receive({payload:{a:1}, topic:"a"}); + n1.receive({payload:{b:9}, topic:"b"}); + n1.receive({payload:{b:2}, topic:"b"}); + n1.receive({payload:{c:3}, topic:"c"}); + n1.receive({payload:{d:4}, topic:"d"}); + n1.receive({payload:{e:5}, topic:"e"}); + }); + }); + + it('should merge full msg objects', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], count:6, build:"merged", mode:"custom", propertyType:"full", property:""}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.payload.should.have.property("payload",7); + msg.payload.should.have.property("aha",'c'); + msg.payload.should.have.property("bar",'b'); + msg.payload.should.have.property("bingo",'e'); + msg.payload.should.have.property("foo",'d'); + msg.payload.should.have.property("topic",'a'); + done(); + } + catch(e) { done(e)} + }); + n1.receive({payload:1, topic:"f"}); + n1.receive({payload:2, topic:"a"}); + n1.receive({payload:3, foo:"b"}); + n1.receive({payload:4, bar:"b"}); + n1.receive({payload:5, aha:"c"}); + n1.receive({payload:6, foo:"d"}); + n1.receive({payload:7, bingo:"e"}); + }); + }); + + it('should accumulate a merged object', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], build:"merged",mode:"custom",accumulate:true, count:3}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + if (c === 3) { + try { + msg.should.have.property("payload"); + msg.payload.should.have.property("a",3); + msg.payload.should.have.property("b",2); + msg.payload.should.have.property("c",1); + done(); + } + catch(e) { done(e) } + } + c += 1; + }); + n1.receive({payload:{a:1}, topic:"a"}); + n1.receive({payload:{b:2}, topic:"b"}); + n1.receive({payload:{c:3}, topic:"c"}); + n1.receive({payload:{a:3}, topic:"d"}); + n1.receive({payload:{b:2}, topic:"e"}); + n1.receive({payload:{c:1}, topic:"f"}); + }); + }); + + it('should be able to reset an accumulation', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], build:"merged",accumulate:true,mode:"custom", count:3}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + if (c === 1) { + try { + msg.should.have.property("payload"); + msg.payload.should.have.property("a",1); + msg.payload.should.have.property("b",2); + msg.payload.should.have.property("c",3); + msg.payload.should.have.property("d",4); + } + catch(e) { done(e) } + } + if (c === 2) { + try { + msg.should.have.property("payload"); + msg.payload.should.have.property("e",2); + msg.payload.should.have.property("f",1); + } + catch(e) { done(e) } + } + if (c === 3) { + try { + msg.should.have.property("payload"); + msg.payload.should.have.property("g",2); + msg.payload.should.have.property("h",1); + msg.payload.should.have.property("i",3); + done(); + } + catch(e) { done(e) } + } + c += 1; + }); + n1.receive({payload:{a:1}, topic:"a"}); + n1.receive({payload:{b:2}, topic:"b"}); + n1.receive({payload:{c:3}, topic:"c"}); + n1.receive({payload:{d:4}, topic:"d", complete:true}); + n1.receive({payload:{e:2}, topic:"e"}); + n1.receive({payload:{f:1}, topic:"f", complete:true}); + n1.receive({payload:{g:2}, topic:"g"}); + n1.receive({payload:{h:1}, topic:"h"}); + n1.receive({reset:true}); + n1.receive({payload:{g:2}, topic:"g"}); + n1.receive({payload:{h:1}, topic:"h"}); + n1.receive({payload:{i:3}, topic:"i"}); + }); + }); + + it('should accumulate a key/value object', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], build:"object", accumulate:true, mode:"custom", topic:"bar", key:"foo", count:4}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + //msg.should.have.property("topic","bar"); + msg.should.have.property("payload"); + msg.payload.should.have.property("a",1); + msg.payload.should.have.property("b",2); + msg.payload.should.have.property("c",3); + msg.payload.should.have.property("d",4); + done(); + } + catch(e) { done(e) } + }); + n1.receive({payload:2, foo:"b"}); + n1.receive({payload:3, foo:"c"}); + n1.receive({reset:true}); + n1.receive({payload:1, foo:"a"}); + n1.receive({payload:2, foo:"b"}); + n1.receive({payload:3, foo:"c"}); + n1.receive({payload:4, foo:"d"}); + }); + }); + + it('should join strings with a specifed character after a timeout', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], build:"string", timeout:0.05, count:"", joiner:",",mode:"custom"}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.equal("a,b,c"); + done(); + } + catch(e) { done(e) } + }); + n1.receive({payload:"a"}); + n1.receive({payload:"b"}); + n1.receive({payload:"c"}); + }); + }); + + it('should join strings with a specifed character and complete when told to', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], build:"string", timeout:5, count:0, joiner:"\n",mode:"custom"}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.equal("Hello\nNodeRED\nWorld\n"); + done(); + } + catch(e) { done(e) } + }); + n1.receive({payload:"Hello"}); + n1.receive({payload:"NodeRED"}); + n1.receive({payload:"World"}); + n1.receive({payload:'', complete:true}); + }); + }); + + it('should join complete message objects into an array after a count', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], build:"array", timeout:0, count:3, propertyType:"full",mode:"custom"}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.payload.should.be.an.Array(); + msg.payload[0].should.be.an.Object(); + msg.payload[0].should.have.property("payload","a"); + msg.payload[1].should.be.an.Object(); + msg.payload[1].should.have.property("payload","b"); + msg.payload[2].should.be.an.Object(); + msg.payload[2].should.have.property("payload","c"); + done(); + } + catch(e) { done(e); } + }); + n1.receive({payload:"a"}); + n1.receive({payload:"b"}); + n1.receive({payload:"c"}); + }); + }); + + it('should join split things back into an array', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.be.an.Array(); + msg.payload[0].should.equal(1); + msg.payload[1].should.equal(2); + msg.payload[2].should.equal(3); + msg.payload[3].should.equal(4); + done(); + } + catch(e) { done(e); } + }); + n1.receive({payload:3, parts:{index:2, count:4, id:111}}); + n1.receive({payload:2, parts:{index:1, count:4, id:111}}); + n1.receive({payload:4, parts:{index:3, count:4, id:111}}); + n1.receive({payload:1, parts:{index:0, count:4, id:111}}); + }); + }); + + it('should join split things back into an object', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.have.property("a",1); + msg.payload.should.have.property("b",2); + msg.payload.should.have.property("c",3); + msg.payload.should.have.property("d",4); + done(); + } + catch(e) { done(e); } + }); + n1.receive({payload:3, parts:{index:2, count:4, id:222, key:"c", type:"object"}}); + n1.receive({payload:2, parts:{index:1, count:4, id:222, key:"b", type:"object"}}); + n1.receive({payload:4, parts:{index:3, count:4, id:222, key:"d", type:"object"}}); + n1.receive({payload:1, parts:{index:0, count:4, id:222, key:"a", type:"object"}}); + }); + }); + + it('should join split things, send when told complete', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], timeout:0.250}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.be.an.Array(); + (msg.payload[0] === undefined).should.be.true(); + msg.payload[1].should.equal(2); + msg.payload[2].should.equal(3); + msg.payload[3].should.equal(4); + done(); + } + catch(e) { done(e); } + }); + n1.receive({payload:3, parts:{index:2, count:4, id:444} }); + n1.receive({payload:2, parts:{index:1, count:4, id:444} }); + n1.receive({payload:4, parts:{index:3, count:4, id:444}, complete:true}); + }); + }); + + it('should manually join things into an array, send when told complete', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], timeout:1, mode:"custom", build:"array"}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.be.an.Array(); + msg.payload.length.should.equal(3); + msg.payload[0].should.equal(1); + msg.payload[1].should.equal(2); + msg.payload[2].should.equal(3); + done(); + } + catch(e) { done(e); } + }); + n1.receive({payload:1, topic:"A"}); + n1.receive({payload:2, topic:"B"}); + n1.receive({payload:3, topic:"C"}); + n1.receive({complete:true}); + }); + }); + + + it('should manually join things into an object, send when told complete', function(done) { + var flow = [{id:"n1", type:"join", wires:[["n2"]], timeout:1, mode:"custom", build:"object"}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.be.an.Object(); + Object.keys(msg.payload).length.should.equal(3); + msg.payload.A.should.equal(1); + msg.payload.B.should.equal(2); + msg.payload.C.should.equal(3); + done(); + } + catch(e) { done(e); } + }); + n1.receive({payload:1, topic:"A"}); + n1.receive({payload:2, topic:"B"}); + n1.receive({payload:3, topic:"C"}); + n1.receive({complete:true}); + }); + }); + + it('should join split strings back into a word', function(done) { + var flow = [{id:"n1", type:"join", mode:"auto", wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.be.an.String(); + msg.payload.should.equal("abcd"); + done(); + } + catch(e) { done(e); } + }); + n1.receive({payload:"a", parts:{type:'string',index:0, count:4, ch:"", id:555}}); + n1.receive({payload:"d", parts:{type:'string',index:3, count:4, ch:"", id:555}}); + n1.receive({payload:"c", parts:{type:'string',index:2, count:4, ch:"", id:555}}); + n1.receive({payload:"b", parts:{type:'string',index:1, count:4, ch:"", id:555}}); + }); + }); + + it('should allow chained split-split-join-join sequences', function(done) { + var flow = [{id:"s1", type:"split",wires:[["s2"]]}, + {id:"s2", type:"split",wires:[["j1"]]}, + {id:"j1", type:"join", mode:"auto", wires:[["j2"]]}, + {id:"j2", type:"join", mode:"auto", wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var s1 = helper.getNode("s1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.eql([[1,2,3],"a\nb\nc",[7,8,9]]); + done(); + } + catch(e) { done(e); } + }); + s1.receive({payload:[[1,2,3],"a\nb\nc",[7,8,9]]}); + }); + }); + + it('should reduce messages', function(done) { + var flow = [{id:"n1", type:"join", mode:"reduce", + reduceRight:false, + reduceExp:"$A+payload", + reduceInit:"0", + reduceInitType:"num", + reduceFixup:undefined, + wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.equal(10); + done(); + } + catch(e) { done(e); } + }); + n1.receive({payload:3, parts:{index:2, count:4, id:222}}); + n1.receive({payload:2, parts:{index:1, count:4, id:222}}); + n1.receive({payload:4, parts:{index:3, count:4, id:222}}); + n1.receive({payload:1, parts:{index:0, count:4, id:222}}); + }); + }); + + it('should reduce messages - count only in last part', function(done) { + var flow = [{id:"n1", type:"join", mode:"reduce", + reduceRight:false, + reduceExp:"$A+payload", + reduceInit:"0", + reduceInitType:"num", + reduceFixup:undefined, + wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.equal(10); + done(); + } + catch(e) { done(e); } + }); + n1.receive({payload:3, parts:{index:2, id:222}}); + n1.receive({payload:2, parts:{index:1, id:222}}); + n1.receive({payload:4, parts:{index:3, count:4,id:222}}); + n1.receive({payload:1, parts:{index:0, id:222}}); + }); + }); + + function checkInitTypes(itype, ival, rval, initializer, checker, done) { + var flow = [{id:"n1", z:"f0", type:"join", mode:"reduce", + reduceRight:false, + reduceExp:"$A", + reduceInit:ival, + reduceInitType:itype, + reduceFixup:undefined, + wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + if (!initializer) { + initializer = (node, cb) => { + cb(); + }; + } + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + initializer(n1, function () { + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + checker(msg.payload, rval); + done(); + } + catch(e) { done(e); } + }); + n1.receive({payload:3, parts:{index:2, count:4, id:222}}); + n1.receive({payload:2, parts:{index:1, count:4, id:222}}); + n1.receive({payload:4, parts:{index:3, count:4, id:222}}); + n1.receive({payload:1, parts:{index:0, count:4, id:222}}); + }); + }); + } + + function checkInitTypesSimple(itype, val, done) { + checkInitTypes(itype, val, val, undefined, should.equal, done); + } + + function checkInitTypesComplex(itype, ival, rval, done) { + checkInitTypes(itype, ival, rval, undefined, should.deepEqual, done); + } + + it('should reduce messages with init types (str)', function(done) { + checkInitTypesSimple('str', "xyz", done); + }); + + it('should reduce messages with init types (num)', function(done) { + checkInitTypesSimple('num', 10, done); + }); + + it('should reduce messages with init types (bool)', function(done) { + checkInitTypesSimple('bool', true, done); + }); + + it('should reduce messages with init types (json)', function(done) { + var ival = '{"x":"vx", "y":"vy", "z":"vz"}'; + var rval = JSON.parse(ival); + checkInitTypesComplex('json', ival, rval, done); + }); + + it('should reduce messages with init types (bin)', function(done) { + var ival = "[1,2,3]"; + var rval = Buffer.from(JSON.parse(ival)); + checkInitTypesComplex('bin', ival, rval, done); + }); + + it('should reduce messages with init types (JSONata)', function(done) { + var ival = "1+2+3"; + var rval = 6; + checkInitTypesComplex('jsonata', ival, rval, done); + }); + + it('should reduce messages with init types (env)', function(done) { + function init(node, cb) { + process.env.NR_XYZ = "nr_xyz"; + cb(); + } + function fin(err) { + delete process.env.NR_XYZ; + done(err); + } + checkInitTypes('env', "NR_XYZ", "nr_xyz", init, should.equal, fin); + }); + + it('should reduce messages with init types (flow.name)', function(done) { + function init(node, cb) { + var context = node.context(); + context.flow.set("foo", "bar"); + cb(); + } + checkInitTypes('flow', "foo", "bar", init, should.equal, done); + }); + + it('should reduce messages with init types (global.name)', function(done) { + function init(node, cb) { + var context = node.context(); + context.global.set("foo", "bar"); + cb(); + } + checkInitTypes('global', "foo", "bar", init, should.equal, done); + }); + + it('should reduce messages using $I', function(done) { + var flow = [{id:"n1", type:"join", mode:"reduce", + reduceRight:false, + reduceExp:"$A+$I", + reduceInit:"0", + reduceInitType:"num", + reduceFixup:undefined, + wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.equal(6); + done(); + } + catch(e) { done(e); } + }); + n1.receive({payload:3, parts:{index:2, count:4, id:222}}); + n1.receive({payload:2, parts:{index:1, count:4, id:222}}); + n1.receive({payload:4, parts:{index:3, count:4, id:222}}); + n1.receive({payload:1, parts:{index:0, count:4, id:222}}); + }); + }); + + it('should reduce messages with fixup', function(done) { + var flow = [{id:"n1", type:"join", mode:"reduce", + reduceRight:false, + reduceExp:"$A+payload", + reduceInit:"0", + reduceInitType:"num", + reduceFixup:"$A/$N", + wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.equal(2); + done(); + } + catch(e) { done(e); } + }); + n1.receive({payload:3, parts:{index:2, count:5, id:222}}); + n1.receive({payload:2, parts:{index:1, count:5, id:222}}); + n1.receive({payload:4, parts:{index:3, count:5, id:222}}); + n1.receive({payload:1, parts:{index:0, count:5, id:222}}); + n1.receive({payload:0, parts:{index:4, count:5, id:222}}); + }); + }); + + it('should reduce messages (left)', function(done) { + var flow = [{id:"n1", type:"join", mode:"reduce", + reduceRight:false, + reduceExp:"'(' & $A & '+' & payload & ')'", + reduceInit:"0", + reduceInitType:"str", + reduceFixup:undefined, + wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.be.an.String(); + msg.payload.should.equal("((((0+1)+2)+3)+4)"); + done(); + } + catch(e) { done(e); } + }); + n1.receive({payload:'3', parts:{index:2, count:4, id:222}}); + n1.receive({payload:'2', parts:{index:1, count:4, id:222}}); + n1.receive({payload:'4', parts:{index:3, count:4, id:222}}); + n1.receive({payload:'1', parts:{index:0, count:4, id:222}}); + }); + }); + + it('should reduce messages (right)', function(done) { + var flow = [{id:"n1", type:"join", mode:"reduce", + reduceRight:true, + reduceExp:"'(' & $A & '+' & payload & ')'", + reduceInit:"0", + reduceInitType:"str", + reduceFixup:undefined, + wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.be.an.String(); + msg.payload.should.equal("((((0+4)+3)+2)+1)"); + done(); + } + catch(e) { done(e); } + }); + n1.receive({payload:'3', parts:{index:2, count:4, id:222}}); + n1.receive({payload:'2', parts:{index:1, count:4, id:222}}); + n1.receive({payload:'4', parts:{index:3, count:4, id:222}}); + n1.receive({payload:'1', parts:{index:0, count:4, id:222}}); + }); + }); + + it('should reduce messages with array result', function(done) { + var flow = [{id:"n1", type:"join", mode:"reduce", + reduceRight:false, + reduceExp:"$append($A,[payload])", + reduceInit:"[]", + reduceInitType:"json", + reduceFixup:undefined, + wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.be.an.Array(); + var payload = msg.payload; + payload.length.should.equal(2); + if (count == 0) { + payload[0].should.equal(1); + payload[1].should.equal(2); + } + else if (count == 1){ + payload[0].should.equal(3); + payload[1].should.equal(4); + done(); + } + count++; + } + catch(e) { done(e); } + }); + n1.receive({payload:1, parts:{index:0, count:2, id:222}}); + n1.receive({payload:2, parts:{index:1, count:2, id:222}}); + n1.receive({payload:3, parts:{index:2, count:2, id:333}}); + n1.receive({payload:4, parts:{index:3, count:2, id:333}}); + }); + }); + + it('should handle too many pending messages for reduce mode', function(done) { + var flow = [{id:"n1", type:"join", mode:"reduce", + reduceRight:false, + reduceExp:"$A+payload", + reduceInit:"0", + reduceInitType:"num", + reduceFixup:undefined, + wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + RED.settings.nodeMessageBufferMaxLength = 2; + setTimeout(function() { + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "join"; + }); + var evt = logEvents[0][0]; + evt.should.have.property('id', "n1"); + evt.should.have.property('type', "join"); + evt.should.have.property('msg', "join.too-many"); + done(); + }, TimeoutForErrorCase); + n1.receive({payload:3, parts:{index:2, count:4, id:222}}); + n1.receive({payload:2, parts:{index:1, count:4, id:222}}); + n1.receive({payload:4, parts:{index:3, count:4, id:222}}); + n1.receive({payload:1, parts:{index:0, count:4, id:222}}); + }); + }); + + it('should reduce messages with flow context', function(done) { + var flow = [{id:"n1", type:"join", mode:"reduce", + reduceRight:false, + reduceExp:"$A+(payload*$flowContext(\"two\"))", + reduceInit:"$flowContext(\"one\")", + reduceInitType:"jsonata", + reduceFixup:"$A*$flowContext(\"three\")", + wires:[["n2"]],z:"flow"}, + {id:"n2", type:"helper",z:"flow"}, + {id:"flow", type:"tab"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.equal(((((1+1*2)+2*2)+3*2)+4*2)*3); + done(); + } + catch(e) { done(e); } + }); + n1.context().flow.set("one",1); + n1.context().flow.set("two",2); + n1.context().flow.set("three",3); + n1.receive({payload:3, parts:{index:2, count:4, id:222}}); + n1.receive({payload:2, parts:{index:1, count:4, id:222}}); + n1.receive({payload:4, parts:{index:3, count:4, id:222}}); + n1.receive({payload:1, parts:{index:0, count:4, id:222}}); + }); + }); + + it('should reduce messages with global context', function(done) { + var flow = [{id:"n1", type:"join", mode:"reduce", + reduceRight:false, + reduceExp:"$A+(payload/$globalContext(\"two\"))", + reduceInit:"$globalContext(\"one\")", + reduceInitType:"jsonata", + reduceFixup:"$A*$globalContext(\"three\")", + wires:[["n2"]],z:"flow"}, + {id:"n2", type:"helper",z:"flow"}, + {id:"flow", type:"tab"}]; + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.equal(((((1+1/2)+2/2)+3/2)+4/2)*3); + done(); + } + catch(e) { done(e); } + }); + n1.context().global.set("one",1); + n1.context().global.set("two",2); + n1.context().global.set("three",3); + n1.receive({payload:3, parts:{index:2, count:4, id:222}}); + n1.receive({payload:2, parts:{index:1, count:4, id:222}}); + n1.receive({payload:4, parts:{index:3, count:4, id:222}}); + n1.receive({payload:1, parts:{index:0, count:4, id:222}}); + }); + }); + + it('should reduce messages with persistable flow context', function(done) { + var flow = [{id:"n1", type:"join", mode:"reduce", + reduceRight:false, + reduceExp:"$A+(payload*$flowContext(\"two\",\"memory\"))", + reduceInit:"$flowContext(\"one\",\"memory\")", + reduceInitType:"jsonata", + reduceFixup:"$A*$flowContext(\"three\",\"memory\")", + wires:[["n2"]],z:"flow"}, + {id:"n2", type:"helper",z:"flow"}, + {id:"flow", type:"tab"}]; + helper.load(joinNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + try { + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.equal(((((1+1*2)+2*2)+3*2)+4*2)*3); + done(); + } + catch(e) { done(e); } + }); + n1.context().flow.set(["one","two","three"],[1,2,3],"memory",function(err){ + if(err){ + done(err); + } else{ + n1.receive({payload:3, parts:{index:2, count:4, id:222}}); + n1.receive({payload:2, parts:{index:1, count:4, id:222}}); + n1.receive({payload:4, parts:{index:3, count:4, id:222}}); + n1.receive({payload:1, parts:{index:0, count:4, id:222}}); + } + }); + }catch(err) { + done(err); + } + }); + }); + }); + + it('should reduce messages with persistable global context', function(done) { + var flow = [{id:"n1", type:"join", mode:"reduce", + reduceRight:false, + reduceExp:"$A+(payload/$globalContext(\"two\",\"memory\"))", + reduceInit:"$globalContext(\"one\",\"memory\")", + reduceInitType:"jsonata", + reduceFixup:"$A*$globalContext(\"three\",\"memory\")", + wires:[["n2"]],z:"flow"}, + {id:"n2", type:"helper",z:"flow"}, + {id:"flow", type:"tab"}]; + helper.load(joinNode, flow, function() { + initContext(function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.equal(((((1+1/2)+2/2)+3/2)+4/2)*3); + done(); + } + catch(e) { done(e); } + }); + n1.context().global.set(["one","two","three"],[1,2,3],"memory",function(err){ + if(err){ + done(err); + } else{ + n1.receive({payload:3, parts:{index:2, count:4, id:222}}); + n1.receive({payload:2, parts:{index:1, count:4, id:222}}); + n1.receive({payload:4, parts:{index:3, count:4, id:222}}); + n1.receive({payload:1, parts:{index:0, count:4, id:222}}); + } + }); + }); + }); + }); + + it('should handle invalid JSONata reduce expression - syntax error"', function (done) { + var flow = [{ + id: "n1", type: "join", mode: "reduce", + reduceRight: false, + reduceExp: "invalid expr", + reduceInit: "0", + reduceInitType: "num", + reduceFixup: undefined, + wires: [["n2"]] + }, + { id: "n2", type: "helper" }]; + helper.load(joinNode, flow, function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + setTimeout(function () { + done(); + }, TimeoutForErrorCase); + n2.on("input", function (msg) { + done(new Error("This path does not go through.")); + }); + n1.receive({ payload: "A", parts: { id: 1, type: "string", ch: ",", index: 0, count: 1 } }); + }); + }); + + it('should handle invalid JSONata reduce expression - runtime error"', function (done) { + var flow = [{ + id: "n1", type: "join", mode: "reduce", + reduceRight: false, + reduceExp: "$uknown()", + reduceInit: "0", + reduceInitType: "num", + reduceFixup: undefined, + wires: [["n2"]] + }, + { id: "n2", type: "helper" }]; + helper.load(joinNode, flow, function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + setTimeout(function () { + done(); + }, TimeoutForErrorCase); + n2.on("input", function (msg) { + done(new Error("This path does not go through.")); + }); + n1.receive({ payload: "A", parts: { id: 1, type: "string", ch: ",", index: 0, count: 1 } }); + }); + }); + + it('should handle invalid JSONata fixup expression - syntax err"', function (done) { + var flow = [{ + id: "n1", type: "join", mode: "reduce", + reduceRight: false, + reduceExp: "$A", + reduceInit: "0", + reduceInitType: "num", + reduceFixup: "invalid expr", + wires: [["n2"]] + }, + { id: "n2", type: "helper" }]; + helper.load(joinNode, flow, function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + setTimeout(function () { + done(); + }, TimeoutForErrorCase); + n2.on("input", function (msg) { + done(new Error("This path does not go through.")); + }); + n1.receive({ payload: "A", parts: { id: 1, type: "string", ch: ",", index: 0, count: 1 } }); + }); + }); + it('should handle invalid JSONata fixup expression - runtime err"', function (done) { + var flow = [{ + id: "n1", type: "join", mode: "reduce", + reduceRight: false, + reduceExp: "$A", + reduceInit: "0", + reduceInitType: "num", + reduceFixup: "$unknown()", + wires: [["n2"]] + }, + { id: "n2", type: "helper" }]; + helper.load(joinNode, flow, function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + setTimeout(function () { + done(); + }, TimeoutForErrorCase); + n2.on("input", function (msg) { + done(new Error("This path does not go through.")); + }); + n1.receive({ payload: "A", parts: { id: 1, type: "string", ch: ",", index: 0, count: 1 } }); + }); + }); + + it('should concat payload when group.type is array', function (done) { + var flow = [{ id: "n1", type: "join", wires: [["n2"]], build: "array", mode: "auto" }, + { id: "n2", type: "helper" }]; + helper.load(joinNode, flow, function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function (msg) { + try { + msg.should.have.property("payload"); + msg.payload.should.be.an.Array(); + msg.payload[0].should.equal("ab"); + msg.payload[1].should.equal("cd"); + msg.payload[2].should.equal("ef"); + done(); + } + catch (e) { done(e); } + }); + n1.receive({ payload: "ab", parts: { id: 1, type: "array", ch: ",", index: 0, count: 3, len:2}}); + n1.receive({ payload: "cd", parts: { id: 1, type: "array", ch: ",", index: 1, count: 3, len:2}}); + n1.receive({ payload: "ef", parts: { id: 1, type: "array", ch: ",", index: 2, count: 3, len:2}}); + }); + }); + + it('should concat payload when group.type is buffer and group.joinChar is undefined', function (done) { + var flow = [{ id: "n1", type: "join", wires: [["n2"]], joiner: ",", build: "buffer", mode: "auto" }, + { id: "n2", type: "helper" }]; + helper.load(joinNode, flow, function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function (msg) { + try { + msg.should.have.property("payload"); + Buffer.isBuffer(msg.payload).should.be.true(); + msg.payload.toString().should.equal("ABC"); + done(); + } + catch (e) { done(e); } + }); + n1.receive({ payload: Buffer.from("A"), parts: { id: 1, type: "buffer", index: 0, count: 3 } }); + n1.receive({ payload: Buffer.from("B"), parts: { id: 1, type: "buffer", index: 1, count: 3 } }); + n1.receive({ payload: Buffer.from("C"), parts: { id: 1, type: "buffer", index: 2, count: 3 } }); + }); + }); + + it('should concat payload when group.type is string and group.joinChar is not string', function (done) { + var flow = [{ id: "n1", type: "join", wires: [["n2"]], joiner: ",", build: "buffer", mode: "auto" }, + { id: "n2", type: "helper" }]; + helper.load(joinNode, flow, function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function (msg) { + try { + msg.should.have.property("payload"); + msg.payload.toString().should.equal("A0B0C"); + done(); + } + catch (e) { done(e); } + }); + n1.receive({ payload: Buffer.from("A"), parts: { id: 1, type: "string", ch: Buffer.from("0"), index: 0, count: 3 } }); + n1.receive({ payload: Buffer.from("B"), parts: { id: 1, type: "string", ch: Buffer.from("0"), index: 1, count: 3 } }); + n1.receive({ payload: Buffer.from("C"), parts: { id: 1, type: "string", ch: Buffer.from("0"), index: 2, count: 3 } }); + }); + }); + + it('should handle msg.parts property when mode is auto and parts or id are missing', function (done) { + var flow = [{ id: "n1", type: "join", wires: [["n2"]], joiner: "[44]", joinerType: "bin", build: "string", mode: "auto" }, + { id: "n2", type: "helper" }]; + helper.load(joinNode, flow, function () { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function (msg) { + done(new Error("This path does not go through.")); + }); + n1.receive({ payload: "A", parts: { type: "string", ch: ",", index: 0, count: 2 } }); + n1.receive({ payload: "B", parts: { type: "string", ch: ",", index: 1, count: 2 } }); + setTimeout(function () { + done(); + }, TimeoutForErrorCase); + }); + }); + +}); diff --git a/packages/connector/test/nodes/core/sequence/18-sort_spec.js b/packages/connector/test/nodes/core/sequence/18-sort_spec.js new file mode 100644 index 0000000..ac22021 --- /dev/null +++ b/packages/connector/test/nodes/core/sequence/18-sort_spec.js @@ -0,0 +1,496 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sortNode = require("nr-test-utils").require("@node-red/nodes/core/sequence/18-sort.js"); +var helper = require("node-red-node-test-helper"); +var RED = require("nr-test-utils").require("node-red/lib/red.js"); +var Context = require("nr-test-utils").require("@node-red/runtime/lib/nodes/context"); + +describe('SORT node', function() { + + beforeEach(function(done) { + helper.startServer(done); + }); + + function initContext(done) { + Context.init({ + contextStorage: { + memory: { + module: "memory" + } + } + }); + Context.load().then(function () { + done(); + }); + } + + afterEach(function(done) { + helper.unload().then(function(){ + RED.settings.nodeMessageBufferMaxLength = 0; + helper.stopServer(done); + }); + }); + + it('should be loaded', function(done) { + var flow = [{id:"n1", type:"sort", order:"ascending", as_num:false, name: "SortNode", wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(sortNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('name', 'SortNode'); + done(); + }); + }); + + function check_sort0(flow, target, key, key_type, data_in, data_out, done) { + var sort = flow[0]; + sort.target = target; + sort.targetType = "msg"; + sort.msgKey = key; + sort.msgKeyType = key_type; + helper.load(sortNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property(target); + var data = msg[target]; + data.length.should.equal(data_out.length); + for(var i = 0; i < data_out.length; i++) { + var data0 = data[i]; + var data1 = data_out[i]; + if (typeof data0 === "object") { + data0.should.deepEqual(data1); + } + else { + data0.should.equal(data1); + } + } + done(); + } + catch(e) { + console.log(e); + } + }); + var msg = {}; + msg[target] = data_in; + n1.receive(msg); + }); + } + + function check_sort0A(flow, data_in, data_out, done) { + check_sort0(flow, "payload", "", "elem", data_in, data_out, done); + } + + function check_sort0B(flow, data_in, data_out, done) { + check_sort0(flow, "data", "", "elem", data_in, data_out, done); + } + + function check_sort0C(flow, exp, data_in, data_out, done) { + check_sort0(flow, "data", exp, "jsonata", data_in, data_out, done); + } + + function check_sort1(flow, key, key_type, data_in, data_out, done) { + function equals(v0, v1) { + var k0 = Object.keys(v0); + var k1 = Object.keys(v1); + + if (k0.length === k1.length) { + for (var i = 0; i < k0.length; i++) { + var k = k0[i]; + if (!v1.hasOwnProperty(k) || + (v0[k] !== v1[k])) { + return false; + } + } + return true; + } + return false; + } + function indexOf(a, v) { + for(var i = 0; i < a.length; i++) { + var av = a[i]; + if ((typeof v === 'object') && equals(v, av)) { + return i; + } + else if (v === av) { + return i; + } + } + return -1; + } + var sort = flow[0]; + var prop = (key_type === "msg") ? key : "payload"; + sort.targetType = "seq"; + sort.seqKey = key; + sort.seqKeyType = key_type; + helper.load(sortNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + msg.should.have.property(prop); + msg.should.have.property("parts"); + msg.parts.should.have.property("count", data_out.length); + var data = msg[prop]; + var index = indexOf(data_out, data); + msg.parts.should.have.property("index", index); + count++; + if (count === data_out.length) { + done(); + } + }); + var len = data_in.length; + for(var i = 0; i < len; i++) { + var parts = { id: "X", index: i, count: len }; + var msg = {parts: parts}; + msg[prop] = data_in[i]; + n1.receive(msg); + } + }); + } + + function check_sort1A(flow, data_in, data_out, done) { + check_sort1(flow, "payload", "msg", data_in, data_out, done); + } + + function check_sort1B(flow, data_in, data_out, done) { + check_sort1(flow, "data", "msg", data_in, data_out, done); + } + + function check_sort1C(flow, exp, data_in, data_out, done) { + check_sort1(flow, exp, "jsonata", data_in, data_out, done); + } + + (function() { + var flow = [{id:"n1", type:"sort", order:"ascending", as_num:false, wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var data_in = [ "200", "4", "30", "1000" ]; + var data_out = [ "1000", "200", "30", "4" ]; + it('should sort payload (elem, not number, ascending)', function(done) { + check_sort0A(flow, data_in, data_out, done); + }); + it('should sort msg prop (elem, not number, ascending)', function(done) { + check_sort0B(flow, data_in, data_out, done); + }); + it('should sort message group/payload (not number, ascending)', function(done) { + check_sort1A(flow, data_in, data_out, done); + }); + it('should sort message group/prop (not number, ascending)', function(done) { + check_sort1B(flow, data_in, data_out, done); + }); + })(); + + (function() { + var flow = [{id:"n1", type:"sort", order:"descending", as_num:false, wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var data_in = [ "200", "4", "30", "1000" ]; + var data_out = [ "4", "30", "200", "1000" ]; + it('should sort payload (elem, not number, descending)', function(done) { + check_sort0A(flow, data_in, data_out, done); + }); + it('should sort msg prop (elem, not number, descending)', function(done) { + check_sort0B(flow, data_in, data_out, done); + }); + it('should sort message group/payload (not number, descending)', function(done) { + check_sort1A(flow, data_in, data_out, done); + }); + it('should sort message group/prop (not number, descending)', function(done) { + check_sort1B(flow, data_in, data_out, done); + }); + })(); + + (function() { + var flow = [{id:"n1", type:"sort", order:"ascending", as_num:true, wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var data_in = [ "200", "4", "30", "1000" ]; + var data_out = [ "4", "30", "200", "1000" ]; + it('should sort payload (elem, number, ascending)', function(done) { + check_sort0A(flow, data_in, data_out, done); + }); + it('should sort msg prop (elem, number, ascending)', function(done) { + check_sort0B(flow, data_in, data_out, done); + }); + it('should sort message group/payload (number, ascending)', function(done) { + check_sort1A(flow, data_in, data_out, done); + }); + it('should sort message group/prop (number, ascending)', function(done) { + check_sort1B(flow, data_in, data_out, done); + }); + })(); + + (function() { + var flow = [{id:"n1", type:"sort", order:"descending", as_num:true, wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var data_in = [ "200", "4", "30", "1000" ]; + var data_out = [ "1000", "200", "30", "4" ]; + it('should sort payload (elem, number, descending)', function(done) { + check_sort0A(flow, data_in, data_out, done); + }); + it('should sort msg prop (elem, number, descending)', function(done) { + check_sort0B(flow, data_in, data_out, done); + }); + it('should sort message group/payload (number, descending)', function(done) { + check_sort1A(flow, data_in, data_out, done); + }); + it('should sort message group/prop (number, descending)', function(done) { + check_sort1B(flow, data_in, data_out, done); + }); + })(); + + (function() { + var flow = [{id:"n1", type:"sort", order:"ascending", as_num:false, wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var data_in = [ "C200", "A4", "B30", "D1000" ]; + var data_out = [ "D1000", "C200", "B30", "A4" ]; + it('should sort payload (exp, not number, ascending)', function(done) { + check_sort0C(flow, "$substring($,1)", data_in, data_out, done); + }); + it('should sort message group (exp, not number, ascending)', function(done) { + check_sort1C(flow, "$substring(payload,1)", data_in, data_out, done); + }); + })(); + + (function() { + var flow = [{id:"n1", type:"sort", order:"descending", as_num:false, wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var data_in = [ "C200", "A4", "B30", "D1000" ]; + var data_out = [ "A4", "B30", "C200", "D1000" ]; + it('should sort message group (exp, not number, descending)', function(done) { + check_sort0C(flow, "$substring($,1)", data_in, data_out, done); + }); + it('should sort payload (exp, not number, descending)', function(done) { + check_sort1C(flow, "$substring(payload,1)", data_in, data_out, done); + }); + })(); + + (function() { + var flow = [{id:"n1", type:"sort", order:"ascending", as_num:true, wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var conv = function(x) { + return x.map(function(v) { return { val:v }; }); + }; + var data_in = conv([ "200", "4", "30", "1000" ]); + var data_out = conv([ "4", "30", "200", "1000" ]); + it('should sort payload of objects', function(done) { + check_sort0C(flow, "val", data_in, data_out, done); + }); + })(); + + it('should sort payload by context (exp, not number, ascending)', function(done) { + var flow = [{id:"n1", type:"sort", target:"data", targetType:"msg", msgKey:"$flowContext($)", msgKeyType:"jsonata", order:"ascending", as_num:false, wires:[["n2"]],z:"flow"}, + {id:"n2", type:"helper",z:"flow"}, + {id:"flow", type:"tab"}]; + var data_in = [ "first", "second", "third", "fourth" ]; + var data_out = [ "second", "third", "first", "fourth" ]; + helper.load(sortNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context()["flow"].set("first","3"); + n1.context()["flow"].set("second","1"); + n1.context()["flow"].set("third","2"); + n1.context()["flow"].set("fourth","4"); + n2.on("input", function(msg) { + msg.should.have.property("data"); + var data = msg["data"]; + data.length.should.equal(data_out.length); + for(var i = 0; i < data_out.length; i++) { + data[i].should.equal(data_out[i]); + } + done(); + }); + var msg = {}; + msg["data"] = data_in; + n1.receive(msg); + }); + }); + + it('should sort message group by context (exp, not number, ascending)', function(done) { + var flow = [{id:"n1", type:"sort", target:"data", targetType:"seq", seqKey:"$globalContext(payload)", seqKeyType:"jsonata", order:"ascending", as_num:false, wires:[["n2"]],z:"flow"}, + {id:"n2", type:"helper",z:"flow"}, + {id:"flow", type:"tab"}]; + var data_in = [ "first", "second", "third", "fourth" ]; + var data_out = [ "second", "fourth", "third", "first" ]; + helper.load(sortNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n1.context()["global"].set("first","4"); + n1.context()["global"].set("second","1"); + n1.context()["global"].set("third","3"); + n1.context()["global"].set("fourth","2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + msg.should.have.property("parts"); + msg.parts.should.have.property("count", data_out.length); + var data = msg["payload"]; + var index = data_out.indexOf(data); + msg.parts.should.have.property("index", index); + count++; + if (count === data_out.length) { + done(); + } + } + catch(e) { + done(e); + } + }); + var len = data_in.length; + for(var i = 0; i < len; i++) { + var parts = { id: "X", index: i, count: len }; + var msg = {parts: parts}; + msg["payload"] = data_in[i]; + n1.receive(msg); + } + }); + }); + + it('should sort payload by persistable context (exp, not number, descending)', function(done) { + var flow = [{id:"n1", type:"sort", target:"data", targetType:"msg", msgKey:"$globalContext($,\"memory\")", msgKeyType:"jsonata", order:"descending", as_num:false, wires:[["n2"]],z:"flow"}, + {id:"n2", type:"helper",z:"flow"}, + {id:"flow", type:"tab"}]; + var data_in = [ "first", "second", "third", "fourth" ]; + var data_out = [ "fourth", "first", "third", "second" ]; + helper.load(sortNode, flow, function() { + initContext(function(){ + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context()["global"].set(["first","second","third","fourth"],["3","1","2","4"],"memory",function(){ + n2.on("input", function(msg) { + msg.should.have.property("data"); + var data = msg["data"]; + data.length.should.equal(data_out.length); + for(var i = 0; i < data_out.length; i++) { + data[i].should.equal(data_out[i]); + } + done(); + }); + var msg = {}; + msg["data"] = data_in; + n1.receive(msg); + }); + }); + }); + }); + + it('should sort message group by persistable context (exp, not number, descending)', function(done) { + var flow = [{id:"n1", type:"sort", target:"data", targetType:"seq", seqKey:"$flowContext(payload,\"memory\")", seqKeyType:"jsonata", order:"descending", as_num:false, wires:[["n2"]],z:"flow"}, + {id:"n2", type:"helper",z:"flow"}, + {id:"flow", type:"tab"}]; + var data_in = [ "first", "second", "third", "fourth" ]; + var data_out = [ "first", "third", "fourth", "second" ]; + helper.load(sortNode, flow, function() { + initContext(function(){ + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n1.context()["flow"].set(["first","second","third","fourth"],["4","1","3","2"],"memory",function(){ + n2.on("input", function(msg) { + msg.should.have.property("payload"); + msg.should.have.property("parts"); + msg.parts.should.have.property("count", data_out.length); + var data = msg["payload"]; + var index = data_out.indexOf(data); + msg.parts.should.have.property("index", index); + count++; + if (count === data_out.length) { + done(); + } + }); + var len = data_in.length; + for(var i = 0; i < len; i++) { + var parts = { id: "X", index: i, count: len }; + var msg = {parts: parts}; + msg["payload"] = data_in[i]; + n1.receive(msg); + } + }); + }); + }); + }); + + it('should handle JSONata script error', function(done) { + var flow = [{id:"n1", type:"sort", order:"ascending", as_num:false, target:"payload", targetType:"seq", seqKey:"$unknown()", seqKeyType:"jsonata", wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(sortNode, flow, function() { + var n1 = helper.getNode("n1"); + setTimeout(function() { + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "sort"; + }); + var evt = logEvents[0][0]; + evt.should.have.property('id', "n1"); + evt.should.have.property('type', "sort"); + evt.should.have.property('msg', "sort.invalid-exp"); + done(); + }, 150); + var msg0 = { payload: "A", parts: { id: "X", index: 0, count: 2} }; + var msg1 = { payload: "B", parts: { id: "X", index: 1, count: 2} }; + n1.receive(msg0); + n1.receive(msg1); + }); + }); + + it('should handle too many pending messages', function(done) { + var flow = [{id:"n1", type:"sort", order:"ascending", as_num:false, target:"payload", targetType:"seq", seqKey:"payload", seqKeyType:"msg", wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(sortNode, flow, function() { + var n1 = helper.getNode("n1"); + RED.settings.nodeMessageBufferMaxLength = 2; + setTimeout(function() { + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "sort"; + }); + var evt = logEvents[0][0]; + evt.should.have.property('id', "n1"); + evt.should.have.property('type', "sort"); + evt.should.have.property('msg', "sort.too-many"); + done(); + }, 150); + for(var i = 0; i < 4; i++) { + var msg = { payload: "V"+i, + parts: { id: "X", index: i, count: 4} }; + n1.receive(msg); + } + }); + }); + + it('should clear pending messages on close', function(done) { + var flow = [{id:"n1", type:"sort", order:"ascending", as_num:false, target:"payload", targetType:"seq", seqKey:"payload", seqKeyType:"msg", wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(sortNode, flow, function() { + var n1 = helper.getNode("n1"); + var msg = { payload: 0, + parts: { id: "X", index: 0, count: 2} }; + n1.receive(msg); + setTimeout(function() { + n1.close().then(function() { + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "sort"; + }); + var evt = logEvents[0][0]; + evt.should.have.property('id', "n1"); + evt.should.have.property('type', "sort"); + evt.should.have.property('msg', "sort.clear"); + done(); + }); + }, 150); + }); + }); + +}); diff --git a/packages/connector/test/nodes/core/sequence/19-batch_spec.js b/packages/connector/test/nodes/core/sequence/19-batch_spec.js new file mode 100644 index 0000000..3a40ebf --- /dev/null +++ b/packages/connector/test/nodes/core/sequence/19-batch_spec.js @@ -0,0 +1,360 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var batchNode = require("nr-test-utils").require("@node-red/nodes/core/sequence/19-batch.js"); +var helper = require("node-red-node-test-helper"); +var RED = require("nr-test-utils").require("node-red/lib/red.js"); + +describe('BATCH node', function() { + this.timeout(8000); + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + afterEach(function() { + helper.unload(); + RED.settings.nodeMessageBufferMaxLength = 0; + }); + + it('should be loaded with defaults', function(done) { + var flow = [{id:"n1", type:"batch", name: "BatchNode", wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(batchNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('name', 'BatchNode'); + done(); + }); + }); + + function check_parts(msg, id, idx, count) { + msg.should.have.property("parts"); + var parts = msg.parts; + parts.should.have.property("id", id); + parts.should.have.property("index", idx); + parts.should.have.property("count", count); + } + + function check_data(n1, n2, results, done) { + var id = undefined; + var ix0 = 0; // seq no + var ix1 = 0; // loc. in seq + var seq = undefined; + var msgs = []; + n2.on("input", function(msg) { + try { + for (var i = 0; i < msgs.length; i++) { + msg.should.not.equal(msgs[i]); + } + msgs.push(msg); + if (seq === undefined) { + seq = results[ix0]; + } + var val = seq[ix1]; + msg.should.have.property("payload", val); + if (id === undefined) { + id = msg.parts.id; + } + check_parts(msg, id, ix1, seq.length); + ix1++; + if (ix1 === seq.length) { + ix0++; + ix1 = 0; + seq = undefined; + id = undefined; + if (ix0 === results.length) { + done(); + } + } + } + catch (e) { + done(e); + } + }); + } + + function check_count(flow, results, done) { + try { + helper.load(batchNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + check_data(n1, n2, results, done); + for(var i = 0; i < 6; i++) { + n1.receive({payload: i}); + } + }); + } + catch (e) { + done(e); + } + } + + function delayed_send(receiver, index, count, delay) { + if (index < count) { + setTimeout(function() { + receiver.receive({payload: index}); + delayed_send(receiver, index+1, count, delay); + }, delay); + } + } + + function check_interval(flow, results, delay, done) { + helper.load(batchNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + check_data(n1, n2, results, done); + delayed_send(n1, 0, 4, delay); + }); + } + + function check_concat(flow, results, inputs, done) { + try { + helper.load(batchNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + check_data(n1, n2, results, done); + for(var data of inputs) { + var msg = { + topic: data[0], + payload: data[1], + parts: { + id: data[0], + index: data[2], + count: data[3] + } + }; + n1.receive(msg); + } + }); + } + catch (e) { + done(e); + } + } + + describe('mode: count', function() { + + it('should create seq. with count', function(done) { + var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "count", count: 2, overlap: 0, interval: 10, allowEmptySequence: false, topics: [], wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var results = [ + [0, 1], + [2, 3], + [4, 5] + ]; + check_count(flow, results, done); + }); + + it('should create seq. with count and overlap', function(done) { + var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "count", count: 3, overlap: 2, interval: 10, allowEmptySequence: false, topics: [], wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var results = [ + [0, 1, 2], + [1, 2, 3], + [2, 3, 4], + [3, 4, 5] + ]; + check_count(flow, results, done); + }); + + it('should handle too many pending messages', function(done) { + var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "count", count: 5, overlap: 0, interval: 10, allowEmptySequence: false, topics: [], wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(batchNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + RED.settings.nodeMessageBufferMaxLength = 2; + setTimeout(function() { + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "batch"; + }); + var evt = logEvents[0][0]; + evt.should.have.property('id', "n1"); + evt.should.have.property('type', "batch"); + evt.should.have.property('msg', "batch.too-many"); + done(); + }, 150); + for(var i = 0; i < 3; i++) { + n1.receive({payload: i}); + } + }); + }); + + }); + + describe('mode: interval', function() { + + it('should create seq. with interval', function(done) { + var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "interval", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [], wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var results = [ + [0, 1], + [2, 3] + ]; + check_interval(flow, results, 450, done); + }); + + it('should create seq. with interval (in float)', function(done) { + var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "interval", count: 0, overlap: 0, interval: 0.5, allowEmptySequence: false, topics: [], wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var results = [ + [0, 1], + [2, 3] + ]; + check_interval(flow, results, 225, done); + }); + + it('should create seq. with interval & not send empty seq', function(done) { + var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "interval", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [], wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var results = [ + // 1300, 2600, 3900, 5200, + [0], [1], [2], [3] + ]; + check_interval(flow, results, 1300, done); + }); + + it('should create seq. with interval & send empty seq', function(done) { + var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "interval", count: 0, overlap: 0, interval: 1, allowEmptySequence: true, topics: [], wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var results = [ + // 1300, 2600, 3900, 5200, + [null], [0], [1], [2], [null], [3] + ]; + check_interval(flow, results, 1300, done); + }); + + it('should handle too many pending messages', function(done) { + var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "interval", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [], wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(batchNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + RED.settings.nodeMessageBufferMaxLength = 2; + setTimeout(function() { + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "batch"; + }); + var evt = logEvents[0][0]; + evt.should.have.property('id', "n1"); + evt.should.have.property('type', "batch"); + evt.should.have.property('msg', "batch.too-many"); + done(); + }, 150); + for(var i = 0; i < 3; i++) { + n1.receive({payload: i}); + } + }); + }); + + }); + + describe('mode: concat', function() { + + it('should concat two seq. (series)', function(done) { + var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "concat", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [{topic: "TA"}, {topic: "TB"}], wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var results = [ + [2, 3, 0, 1] + ]; + var inputs = [ + ["TB", 0, 0, 2], + ["TB", 1, 1, 2], + ["TA", 2, 0, 2], + ["TA", 3, 1, 2] + ]; + check_concat(flow, results, inputs, done); + }); + + it('should concat two seq. (mixed)', function(done) { + var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "concat", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [{topic: "TA"}, {topic: "TB"}], wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var results = [ + [2, 3, 0, 1] + ]; + var inputs = [ + ["TA", 2, 0, 2], + ["TB", 0, 0, 2], + ["TA", 3, 1, 2], + ["TB", 1, 1, 2] + ]; + check_concat(flow, results, inputs, done); + }); + + it('should concat three seq.', function(done) { + var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "concat", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [{topic: "TA"}, {topic: "TB"}, {topic: "TC"}], wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var results = [ + [2, 3, 0, 1, 4] + ]; + var inputs = [ + ["TC", 4, 0, 1], + ["TB", 0, 0, 2], + ["TB", 1, 1, 2], + ["TA", 2, 0, 2], + ["TA", 3, 1, 2] + ]; + check_concat(flow, results, inputs, done); + }); + + it('should concat same seq.', function(done) { + var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "concat", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [{topic: "TA"}, {topic: "TA"}], wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var results = [ + [9, 8, 9, 8] + ]; + var inputs = [ + ["TA", 9, 0, 2], + ["TA", 8, 1, 2] + ]; + check_concat(flow, results, inputs, done); + }); + + it('should handle too many pending messages', function(done) { + var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "concat", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [{topic: "TA"}, {topic: "TB"}], wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(batchNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + RED.settings.nodeMessageBufferMaxLength = 2; + setTimeout(function() { + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "batch"; + }); + var evt = logEvents[0][0]; + evt.should.have.property('id', "n1"); + evt.should.have.property('type', "batch"); + evt.should.have.property('msg', "batch.too-many"); + done(); + }, 150); + var C = 3; + for(var i = 0; i < C; i++) { + var parts_a = {index:i, count:C, id:"A"}; + var parts_b = {index:i, count:C, id:"B"}; + n1.receive({payload: i, topic: "TA", parts:parts_a}); + n1.receive({payload: i, topic: "TB", parts:parts_b}); + } + }); + }); + + }); + +}); diff --git a/packages/connector/test/nodes/core/storage/10-file_spec.js b/packages/connector/test/nodes/core/storage/10-file_spec.js new file mode 100644 index 0000000..cb3dc5d --- /dev/null +++ b/packages/connector/test/nodes/core/storage/10-file_spec.js @@ -0,0 +1,1628 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var path = require('path'); +var fs = require('fs-extra'); +var os = require('os'); +var sinon = require("sinon"); +var iconv = require("iconv-lite"); +var fileNode = require("nr-test-utils").require("@node-red/nodes/core/storage/10-file.js"); +var helper = require("node-red-node-test-helper"); + +describe('file Nodes', function() { + + function encode(s, enc) { + if (enc === "none") { + return Buffer.from(s); + } + return iconv.encode(s, enc); + } + + function decode(data, enc) { + if (enc === "none") { + return data.toString(); + } + return iconv.decode(data, enc); + } + + describe('file out Node', function() { + + var resourcesDir = path.join(__dirname,"..","..","..","resources"); + var fileToTest = path.join(resourcesDir,"50-file-test-file.txt"); + var wait = 250; + + beforeEach(function(done) { + //fs.writeFileSync(fileToTest, "File message line 1\File message line 2\n"); + helper.startServer(done); + }); + + afterEach(function(done) { + fs.removeSync(path.join(resourcesDir,"file-out-node")); + helper.unload().then(function() { + //fs.unlinkSync(fileToTest); + helper.stopServer(done); + }); + }); + + it('should be loaded', function(done) { + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":true, "overwriteFile":true}]; + helper.load(fileNode, flow, function() { + try { + var fileNode1 = helper.getNode("fileNode1"); + fileNode1.should.have.property('name', 'fileNode'); + done(); + } + catch (e) { + done(e); + } + }); + }); + + it('should write to a file', function(done) { + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":true, wires: [["helperNode1"]]}, + {id:"helperNode1", type:"helper"}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + var n2 = helper.getNode("helperNode1"); + n2.on("input", function(msg) { + try { + var f = fs.readFileSync(fileToTest); + f.should.have.length(4); + fs.unlinkSync(fileToTest); + msg.should.have.property("payload", "test"); + done(); + } + catch (e) { + done(e); + } + }); + n1.receive({payload:"test"}); + }); + }); + + it('should write multi-byte string to a file', function(done) { + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":true, wires: [["helperNode1"]]}, + {id:"helperNode1", type:"helper"}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + var n2 = helper.getNode("helperNode1"); + n2.on("input", function(msg) { + try { + var f = fs.readFileSync(fileToTest).toString(); + f.should.have.length(2); + f.should.equal("試験"); + fs.unlinkSync(fileToTest); + msg.should.have.property("payload", "試験"); + done(); + } + catch (e) { + done(e); + } + }); + n1.receive({payload:"試験"}); + }); + }); + + it('should append to a file and add newline', function(done) { + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":true, "overwriteFile":false, wires: [["helperNode1"]]}, + {id:"helperNode1", type:"helper"}]; + try { + fs.unlinkSync(fileToTest); + } catch(err) { + } + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + var n2 = helper.getNode("helperNode1"); + var count = 0; + var data = ["test2", true, 999, [2]]; + + n2.on("input", function (msg) { + try { + msg.should.have.property("payload"); + data.should.containDeep([msg.payload]); + if (count === 3) { + var f = fs.readFileSync(fileToTest).toString(); + if (os.type() !== "Windows_NT") { + f.should.have.length(19); + f.should.equal("test2\ntrue\n999\n[2]\n"); + } + else { + f.should.have.length(23); + f.should.equal("test2\r\ntrue\r\n999\r\n[2]\r\n"); + } + done(); + } + count++; + } + catch (e) { + done(e); + } + }); + + n1.receive({payload:"test2"}); // string + setTimeout(function() { + n1.receive({payload:true}); // boolean + },30); + setTimeout(function() { + n1.receive({payload:999}); // number + },60); + setTimeout(function() { + n1.receive({payload:[2]}); // object (array) + },90); + }); + }); + + it('should append to a file after it has been deleted ', function(done) { + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":false, wires: [["helperNode1"]]}, + {id:"helperNode1", type:"helper"}]; + try { + fs.unlinkSync(fileToTest); + } catch(err) { + } + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + var n2 = helper.getNode("helperNode1"); + var data = ["one", "two", "three", "four"]; + var count = 0; + + n2.on("input", function (msg) { + try { + msg.should.have.property("payload"); + data.should.containDeep([msg.payload]); + try { + if (count === 1) { + // Check they got appended as expected + var f = fs.readFileSync(fileToTest).toString(); + f.should.equal("onetwo"); + + // Delete the file + fs.unlinkSync(fileToTest); + setTimeout(function() { + // Send two more messages to the file + n1.receive({payload:"three"}); + n1.receive({payload:"four"}); + }, wait); + } + if (count === 3) { + var f = fs.readFileSync(fileToTest).toString(); + f.should.equal("threefour"); + fs.unlinkSync(fileToTest); + done(); + } + } catch(err) { + done(err); + } + count++; + } + catch (e) { + done(e); + } + }); + + // Send two messages to the file + n1.receive({payload:"one"}); + n1.receive({payload:"two"}); + }); + }); + + it('should append to a file after it has been recreated ', function(done) { + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":false, wires: [["helperNode1"]]}, + {id:"helperNode1", type:"helper"}]; + try { + fs.unlinkSync(fileToTest); + } catch(err) { + } + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + var n2 = helper.getNode("helperNode1"); + var data = ["one", "two", "three", "four"]; + var count = 0; + + n2.on("input", function (msg) { + try { + msg.should.have.property("payload"); + data.should.containDeep([msg.payload]); + if (count == 1) { + // Check they got appended as expected + var f = fs.readFileSync(fileToTest).toString(); + f.should.equal("onetwo"); + + if (os.type() === "Windows_NT") { + var dummyFile = path.join(resourcesDir,"50-file-test-dummy.txt"); + fs.rename(fileToTest, dummyFile, function() { + recreateTest(n1, dummyFile); + }); + } else { + recreateTest(n1, fileToTest); + } + } + if (count == 3) { + // Check the file was updated + try { + var f = fs.readFileSync(fileToTest).toString(); + f.should.equal("threefour"); + fs.unlinkSync(fileToTest); + done(); + } catch(err) { + done(err); + } + } + } catch(err) { + done(err); + } + count++; + }); + + // Send two messages to the file + n1.receive({payload:"one"}); + n1.receive({payload:"two"}); + }); + + function recreateTest(n1, fileToDelete) { + // Delete the file + fs.unlinkSync(fileToDelete); + + // Recreate it + fs.writeFileSync(fileToTest,""); + + // Send two more messages to the file + n1.receive({payload:"three"}); + n1.receive({payload:"four"}); + } + }); + + + it('should use msg.filename if filename not set in node', function(done) { + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "appendNewline":true, "overwriteFile":true, wires: [["helperNode1"]]}, + {id:"helperNode1", type:"helper"}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + var n2 = helper.getNode("helperNode1"); + + n2.on("input", function (msg) { + try { + msg.should.have.property("payload", "fine"); + msg.should.have.property("filename", fileToTest); + + var f = fs.readFileSync(fileToTest).toString(); + if (os.type() !== "Windows_NT") { + f.should.have.length(5); + f.should.equal("fine\n"); + } + else { + f.should.have.length(6); + f.should.equal("fine\r\n"); + } + done(); + } + catch (e) { + done(e); + } + }); + + n1.receive({payload:"fine", filename:fileToTest}); + }); + }); + + it('should be able to delete the file', function(done) { + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":"delete", wires: [["helperNode1"]]}, + {id:"helperNode1", type:"helper"}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + var n2 = helper.getNode("helperNode1"); + + n2.on("input", function (msg) { + try { + var f = fs.readFileSync(fileToTest).toString(); + f.should.not.equal("fine"); + //done(); + } + catch(e) { + e.code.should.equal("ENOENT"); + done(); + } + }); + + n1.receive({payload:"fine"}); + }); + }); + + it('should warn if filename not set', function(done) { + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "appendNewline":true, "overwriteFile":false}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + n1.emit("input", {payload:"nofile"}); + setTimeout(function() { + try { + var f = fs.readFileSync(fileToTest).toString(); + f.should.not.equal("fine"); + //done(); + } + catch(e) { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "file"; + }); + //console.log(logEvents); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.toString().should.equal("file.errors.nofilename"); + done(); + } + },wait); + }); + }); + + it('ignore a missing payload', function(done) { + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":true, "overwriteFile":false}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + setTimeout(function() { + try { + var f = fs.readFileSync(fileToTest).toString(); + f.should.not.equal("fine"); + //done(); + } + catch(e) { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "file"; + }); + //console.log(logEvents); + logEvents.should.have.length(0); + done(); + } + },wait); + n1.emit("input", {topic:"test"}); + }); + }); + + it('should fail to write to a ro file', function(done) { + // Stub file write so we can make writes fail + var spy = sinon.stub(fs, 'createWriteStream', function(arg1,arg2) { + var ws = {}; + ws.on = function(e,d) { throw("Stub error message"); } + ws.write = function(e,d) { } + return ws; + }); + + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":true}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "file"; + }); + //console.log(logEvents); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.toString().should.startWith("Stub error message"); + done(); + } + catch(e) { done(e); } + finally { fs.createWriteStream.restore(); } + },wait); + n1.receive({payload:"test"}); + }); + }); + + it('should fail to append to a ro file', function(done) { + // Stub file write so we can make writes fail + var spy = sinon.stub(fs, 'createWriteStream', function(arg1,arg2) { + var ws = {}; + ws.on = function(e,d) { throw("Stub error message"); } + ws.write = function(e,d) { } + return ws; + }); + + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":true, "overwriteFile":false}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "file"; + }); + //console.log(logEvents); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.toString().should.startWith("Stub error message"); + done(); + } + catch(e) { done(e); } + finally { fs.createWriteStream.restore(); } + },wait); + n1.receive({payload:"test2"}); + }); + }); + + it('should cope with failing to delete a file', function(done) { + // Stub file write so we can make writes fail + var spy = sinon.stub(fs, 'unlink', function(arg,arg2) { arg2(new Error("Stub error message")); }); + + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":true, "overwriteFile":"delete"}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "file"; + }); + //console.log(logEvents); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.toString().should.startWith("file.errors.deletefail"); + done(); + } + catch(e) { done(e); } + finally { fs.unlink.restore(); } + },wait); + n1.receive({payload:"test2"}); + }); + }); + + it('should fail to create a new directory if not asked to do so (append)', function(done) { + // Stub file write so we can make writes fail + var fileToTest2 = path.join(resourcesDir,"file-out-node","50-file-test-file.txt"); + //var spy = sinon.stub(fs, 'appendFile', function(arg,arg2,arg3,arg4){ arg4(new Error("Stub error message")); }); + + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest2, "appendNewline":true, "overwriteFile":false}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "file"; + }); + //console.log(logEvents); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.toString().should.startWith("file.errors.appendfail"); + done(); + } + catch(e) { done(e); } + //finally { fs.appendFile.restore(); } + },wait); + n1.receive({payload:"test2"}); + }); + }); + + it('should try to create a new directory if asked to do so (append)', function(done) { + // fs.writeFileSync of afterEach failed on Windows. + if (os.type() === "Windows_NT") { + done(); + return; + } + // Stub file write so we can make writes fail + var fileToTest2 = path.join(resourcesDir,"file-out-node","50-file-test-file.txt"); + var spy = sinon.stub(fs, "ensureDir", function(arg1,arg2,arg3,arg4) { arg2(null); }); + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest2, "appendNewline":true, "overwriteFile":false, "createDir":true}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "file"; + }); + //console.log(logEvents); + logEvents.should.have.length(0); + done(); + } + catch(e) { done(e); } + finally { fs.ensureDir.restore(); } + },wait); + n1.receive({payload:"test2"}); + }); + }); + + it('should fail to create a new directory if not asked to do so (overwrite)', function(done) { + // Stub file write so we can make writes fail + var fileToTest2 = path.join(resourcesDir,"file-out-node","50-file-test-file.txt"); + //var spy = sinon.stub(fs, 'appendFile', function(arg,arg2,arg3,arg4){ arg4(new Error("Stub error message")); }); + + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest2, "appendNewline":false, "overwriteFile":true}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "file"; + }); + //console.log(logEvents); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.toString().should.startWith("file.errors.writefail"); + done(); + } + catch(e) { done(e); } + //finally { fs.appendFile.restore(); } + },wait); + n1.receive({payload:"test2"}); + }); + }); + + it('should try to create a new directory if asked to do so (overwrite)', function(done) { + // Stub file write so we can make writes fail + var fileToTest2 = path.join(resourcesDir,"file-out-node","50-file-test-file.txt"); + var spy = sinon.stub(fs, "ensureDir", function(arg1,arg2,arg3,arg4) { arg2(null); }); + + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest2, "appendNewline":true, "overwriteFile":true, "createDir":true}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "file"; + }); + //console.log(logEvents); + logEvents.should.have.length(0); + done(); + } + catch(e) { done(e); } + finally { fs.ensureDir.restore(); } + },wait); + n1.receive({payload:"test2"}); + }); + }); + + it('should write to multiple files', function(done) { + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "appendNewline":true, "overwriteFile":true, "createDir":true, wires: [["helperNode1"]]}, + {id:"helperNode1", type:"helper"}]; + var tmp_path = path.join(resourcesDir, "tmp"); + var len = 1024*1024*10; + var file_count = 5; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + var n2 = helper.getNode("helperNode1"); + var count = 0; + n2.on("input", function(msg) { + try { + count++; + if (count == file_count) { + for(var i = 0; i < file_count; i++) { + var name = path.join(tmp_path, String(i)); + var f = fs.readFileSync(name); + f.should.have.length(len); + f[0].should.have.equal(i); + } + fs.removeSync(tmp_path); + done(); + } + } + catch (e) { + try { + fs.removeSync(tmp_path); + } + catch (e1) { + } + done(e); + } + }); + for(var i = 0; i < file_count; i++) { + var data = Buffer.alloc?Buffer.alloc(len):new Buffer(len); + data.fill(i); + var name = path.join(tmp_path, String(i)); + var msg = {payload:data, filename:name}; + n1.receive(msg); + } + }); + }); + + it('should write to multiple files if node is closed', function(done) { + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "appendNewline":true, "overwriteFile":true, "createDir":true, wires: [["helperNode1"]]}, + {id:"helperNode1", type:"helper"}]; + var tmp_path = path.join(resourcesDir, "tmp"); + var len = 1024*1024*10; + var file_count = 5; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + var n2 = helper.getNode("helperNode1"); + var count = 0; + n2.on("input", function(msg) { + try { + count++; + if (count == file_count) { + for(var i = 0; i < file_count; i++) { + var name = path.join(tmp_path, String(i)); + var f = fs.readFileSync(name); + f.should.have.length(len); + f[0].should.have.equal(i); + } + fs.removeSync(tmp_path); + done(); + } + } + catch (e) { + try { + fs.removeSync(tmp_path); + } + catch (e1) { + } + done(e); + } + }); + for(var i = 0; i < file_count; i++) { + var data = Buffer.alloc?Buffer.alloc(len):new Buffer(len); + data.fill(i); + var name = path.join(tmp_path, String(i)); + var msg = {payload:data, filename:name}; + n1.receive(msg); + } + n1.close(); + }); + }); + + describe('encodings', function() { + + function checkWriteWithEncoding(enc, data, done) { + var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":true, encoding:enc, wires: [["helperNode1"]]}, + {id:"helperNode1", type:"helper"}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileNode1"); + var n2 = helper.getNode("helperNode1"); + n2.on("input", function(msg) { + try { + var f = fs.readFileSync(fileToTest); + f.equals(encode(data, enc)).should.be.true(); + fs.unlinkSync(fileToTest); + msg.should.have.property("payload", data); + done(); + } + catch (e) { + done(e); + } + }); + n1.receive({payload:data}); + }); + } + + // default + it('should write to a file with "none" encoding', function(done) { + checkWriteWithEncoding("none", "test", done); + }); + + // Native + it('should write to a file with "utf8" encoding', function(done) { + checkWriteWithEncoding("utf8", "試験", done); + }); + + it('should write to a file with "ucs2" encoding', function(done) { + checkWriteWithEncoding("ucs2", "試験", done); + }); + + it('should write to a file with "utf-16le" encoding', function(done) { + checkWriteWithEncoding("utf-16le", "試験", done); + }); + + it('should write to a file with "binary" encoding', function(done) { + checkWriteWithEncoding("binary", "test", done); + }); + + it('should write to a file with "base64" encoding', function(done) { + checkWriteWithEncoding("base64", "5pel5pys6KqeCg==", done); + }); + + it('should write to a file with "hex" encoding', function(done) { + checkWriteWithEncoding("hex", "deadbeef", done); + }); + + // Unicode + it('should write to a file with "utf-16be" encoding', function(done) { + checkWriteWithEncoding("utf-16be", "試験", done); + }); + + // Japanese + it('should write to a file with "Shift_JIS" encoding', function(done) { + checkWriteWithEncoding("Shift_JIS", "試験", done); + }); + + it('should write to a file with "Windows-31j" encoding', function(done) { + checkWriteWithEncoding("Windows-31j", "試験", done); + }); + + it('should write to a file with "Windows932" encoding', function(done) { + checkWriteWithEncoding("Windows932", "試験", done); + }); + + it('should write to a file with "EUC-JP" encoding', function(done) { + checkWriteWithEncoding("EUC-JP", "試験", done); + }); + + // following encoding tests should be more specific + // Chinese + it('should write to a file with "GB2312" encoding', function(done) { + checkWriteWithEncoding("GB2312", "test", done); + }); + + it('should write to a file with "GBK" encoding', function(done) { + checkWriteWithEncoding("GBK", "test", done); + }); + + it('should write to a file with "GB18030" encoding', function(done) { + checkWriteWithEncoding("GB18030", "test", done); + }); + + it('should write to a file with "Windows936" encoding', function(done) { + checkWriteWithEncoding("Windows936", "test", done); + }); + + it('should write to a file with "EUC-CN" encoding', function(done) { + checkWriteWithEncoding("EUC-CN", "test", done); + }); + + // Korean + it('should write to a file with "KS_C_5601" encoding', function(done) { + checkWriteWithEncoding("KS_C_5601", "test", done); + }); + + it('should write to a file with "Windows949" encoding', function(done) { + checkWriteWithEncoding("Windows949", "test", done); + }); + + it('should write to a file with "EUC-KR" encoding', function(done) { + checkWriteWithEncoding("EUC-KR", "test", done); + }); + + // Taiwan/Hong Kong + it('should write to a file with "Big5" encoding', function(done) { + checkWriteWithEncoding("Big5", "test", done); + }); + + it('should write to a file with "Big5-HKSCS" encoding', function(done) { + checkWriteWithEncoding("Big5-HKSCS", "test", done); + }); + + it('should write to a file with "Windows950" encoding', function(done) { + checkWriteWithEncoding("Windows950", "test", done); + }); + + // Windows + it('should write to a file with "cp874" encoding', function(done) { + checkWriteWithEncoding("cp874", "test", done); + }); + + it('should write to a file with "cp1250" encoding', function(done) { + checkWriteWithEncoding("cp1250", "test", done); + }); + + it('should write to a file with "cp1251" encoding', function(done) { + checkWriteWithEncoding("cp1251", "test", done); + }); + + it('should write to a file with "cp1252" encoding', function(done) { + checkWriteWithEncoding("cp1252", "test", done); + }); + + it('should write to a file with "cp1253" encoding', function(done) { + checkWriteWithEncoding("cp1253", "test", done); + }); + + it('should write to a file with "cp1254" encoding', function(done) { + checkWriteWithEncoding("cp1254", "test", done); + }); + + it('should write to a file with "cp1255" encoding', function(done) { + checkWriteWithEncoding("cp1255", "test", done); + }); + + it('should write to a file with "cp1256" encoding', function(done) { + checkWriteWithEncoding("cp1256", "test", done); + }); + + it('should write to a file with "cp1257" encoding', function(done) { + checkWriteWithEncoding("cp1257", "test", done); + }); + + it('should write to a file with "cp1258" encoding', function(done) { + checkWriteWithEncoding("cp1258", "test", done); + }); + + // IBM + it('should write to a file with "cp437" encoding', function(done) { + checkWriteWithEncoding("cp437", "test", done); + }); + + it('should write to a file with "cp737" encoding', function(done) { + checkWriteWithEncoding("cp737", "test", done); + }); + + it('should write to a file with "cp775" encoding', function(done) { + checkWriteWithEncoding("cp775", "test", done); + }); + + it('should write to a file with "cp808" encoding', function(done) { + checkWriteWithEncoding("cp808", "test", done); + }); + + it('should write to a file with "cp850" encoding', function(done) { + checkWriteWithEncoding("cp850", "test", done); + }); + + it('should write to a file with "cp852" encoding', function(done) { + checkWriteWithEncoding("cp852", "test", done); + }); + + it('should write to a file with "cp855" encoding', function(done) { + checkWriteWithEncoding("cp855", "test", done); + }); + + it('should write to a file with "cp856" encoding', function(done) { + checkWriteWithEncoding("cp856", "test", done); + }); + + it('should write to a file with "cp857" encoding', function(done) { + checkWriteWithEncoding("cp857", "test", done); + }); + + it('should write to a file with "cp858" encoding', function(done) { + checkWriteWithEncoding("cp858", "test", done); + }); + + it('should write to a file with "cp860" encoding', function(done) { + checkWriteWithEncoding("cp860", "test", done); + }); + + it('should write to a file with "cp861" encoding', function(done) { + checkWriteWithEncoding("cp861", "test", done); + }); + + it('should write to a file with "cp866" encoding', function(done) { + checkWriteWithEncoding("cp866", "test", done); + }); + + it('should write to a file with "cp869" encoding', function(done) { + checkWriteWithEncoding("cp869", "test", done); + }); + + it('should write to a file with "cp922" encoding', function(done) { + checkWriteWithEncoding("cp922", "test", done); + }); + + it('should write to a file with "cp1046" encoding', function(done) { + checkWriteWithEncoding("cp1046", "test", done); + }); + + it('should write to a file with "cp1124" encoding', function(done) { + checkWriteWithEncoding("cp1124", "test", done); + }); + + it('should write to a file with "cp1125" encoding', function(done) { + checkWriteWithEncoding("cp1125", "test", done); + }); + + it('should write to a file with "cp1129" encoding', function(done) { + checkWriteWithEncoding("cp1129", "test", done); + }); + + it('should write to a file with "cp1133" encoding', function(done) { + checkWriteWithEncoding("cp1133", "test", done); + }); + + it('should write to a file with "cp1161" encoding', function(done) { + checkWriteWithEncoding("cp1161", "test", done); + }); + + it('should write to a file with "cp1162" encoding', function(done) { + checkWriteWithEncoding("cp1162", "test", done); + }); + + it('should write to a file with "cp1163" encoding', function(done) { + checkWriteWithEncoding("cp1163", "test", done); + }); + + // Mac + it('should write to a file with "maccroatian" encoding', function(done) { + checkWriteWithEncoding("maccroatian", "test", done); + }); + + it('should write to a file with "maccyrillic" encoding', function(done) { + checkWriteWithEncoding("maccyrillic", "test", done); + }); + + it('should write to a file with "macgreek" encoding', function(done) { + checkWriteWithEncoding("macgreek", "test", done); + }); + + it('should write to a file with "maciceland" encoding', function(done) { + checkWriteWithEncoding("maciceland", "test", done); + }); + + it('should write to a file with "macroman" encoding', function(done) { + checkWriteWithEncoding("macroman", "test", done); + }); + + it('should write to a file with "macromania" encoding', function(done) { + checkWriteWithEncoding("macromania", "test", done); + }); + + it('should write to a file with "macthai" encoding', function(done) { + checkWriteWithEncoding("macthai", "test", done); + }); + + it('should write to a file with "macturkish" encoding', function(done) { + checkWriteWithEncoding("macturkish", "test", done); + }); + + it('should write to a file with "macukraine" encoding', function(done) { + checkWriteWithEncoding("macukraine", "test", done); + }); + + it('should write to a file with "maccenteuro" encoding', function(done) { + checkWriteWithEncoding("maccenteuro", "test", done); + }); + + it('should write to a file with "macintosh" encoding', function(done) { + checkWriteWithEncoding("macintosh", "test", done); + }); + + // KOI8 + it('should write to a file with "koi8-r" encoding', function(done) { + checkWriteWithEncoding("koi8-r", "test", done); + }); + + it('should write to a file with "koi8-u" encoding', function(done) { + checkWriteWithEncoding("koi8-u", "test", done); + }); + + it('should write to a file with "koi8-ru" encoding', function(done) { + checkWriteWithEncoding("koi8-ru", "test", done); + }); + + it('should write to a file with "koi8-t" encoding', function(done) { + checkWriteWithEncoding("koi8-t", "test", done); + }); + + // Misc + it('should write to a file with "armscii8" encoding', function(done) { + checkWriteWithEncoding("armscii8", "test", done); + }); + + it('should write to a file with "rk1048" encoding', function(done) { + checkWriteWithEncoding("rk1048", "test", done); + }); + + it('should write to a file with "tcvn" encoding', function(done) { + checkWriteWithEncoding("tcvn", "test", done); + }); + + it('should write to a file with "georgianacademy" encoding', function(done) { + checkWriteWithEncoding("georgianacademy", "test", done); + }); + + it('should write to a file with "georgianps" encoding', function(done) { + checkWriteWithEncoding("georgianps", "test", done); + }); + + it('should write to a file with "pt154" encoding', function(done) { + checkWriteWithEncoding("pt154", "test", done); + }); + + it('should write to a file with "viscii" encoding', function(done) { + checkWriteWithEncoding("viscii", "test", done); + }); + + it('should write to a file with "iso646cn" encoding', function(done) { + checkWriteWithEncoding("iso646cn", "test", done); + }); + + it('should write to a file with "iso646jp" encoding', function(done) { + checkWriteWithEncoding("iso646jp", "test", done); + }); + + it('should write to a file with "hproman8" encoding', function(done) { + checkWriteWithEncoding("hproman8", "test", done); + }); + + it('should write to a file with "tis620" encoding', function(done) { + checkWriteWithEncoding("tis620", "test", done); + }); + + }); + }); + + + describe('file in Node', function() { + + var resourcesDir = path.join(__dirname,"..","..","..","resources"); + var fileToTest = path.join(resourcesDir,"50-file-test-file.txt"); + var fileToTest2 = "\t"+path.join(resourcesDir,"50-file-test-file.txt")+"\r\n"; + var wait = 150; + + beforeEach(function(done) { + fs.writeFileSync(fileToTest, "File message line 1\nFile message line 2\n"); + helper.startServer(done); + }); + + afterEach(function(done) { + helper.unload().then(function() { + fs.unlinkSync(fileToTest); + helper.stopServer(done); + }); + }); + + it('should be loaded', function(done) { + var flow = [{id:"fileInNode1", type:"file in", name: "fileInNode", "filename":fileToTest, "format":"utf8"}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileInNode1"); + n1.should.have.property('name', 'fileInNode'); + done(); + }); + }); + + it('should read in a file and output a buffer', function(done) { + var flow = [{id:"fileInNode1", type:"file in", name:"fileInNode", "filename":fileToTest, "format":"", wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileInNode1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload'); + Buffer.isBuffer(msg.payload).should.be.true(); + msg.payload.should.have.length(40); + msg.payload.toString().should.equal('File message line 1\nFile message line 2\n'); + done(); + }); + n1.receive({payload:""}); + }); + }); + + it('should read in a file and output a utf8 string', function(done) { + var flow = [{id:"fileInNode1", type:"file in", name: "fileInNode", "filename":fileToTest, "format":"utf8", wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileInNode1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.should.be.a.String(); + msg.payload.should.have.length(40) + msg.payload.should.equal("File message line 1\nFile message line 2\n"); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:""}); + }); + }); + + it('should read in a file ending in cr and output a utf8 string', function(done) { + var flow = [{id:"fileInNode1", type:"file in", name: "fileInNode", "filename":fileToTest2, "format":"utf8", wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileInNode1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.should.be.a.String(); + msg.payload.should.have.length(40) + msg.payload.should.equal("File message line 1\nFile message line 2\n"); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:""}); + }); + }); + + it('should read in a file and output split lines with parts', function(done) { + var flow = [{id:"fileInNode1", type:"file in", name: "fileInNode", filename:fileToTest, format:"lines", wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileInNode1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.should.be.a.String(); + msg.should.have.property('parts'); + msg.parts.should.have.property('index',c); + msg.parts.should.have.property('type','string'); + msg.parts.should.have.property('ch','\n'); + if (c === 0) { + msg.payload.should.equal("File message line 1"); + } + if (c === 1) { + msg.payload.should.equal("File message line 2"); + } + if (c === 2) { + msg.payload.should.equal(""); + done(); + } + c++; + } + catch(e) { + done(e); + } + }); + n1.receive({payload:""}); + }); + }); + + it('should read in a file with empty line and output split lines with parts', function(done) { + var data = ["-", "", "-", ""]; + var line = data.join("\n"); + fs.writeFileSync(fileToTest, line); + var flow = [{id:"fileInNode1", type:"file in", name: "fileInNode", filename:fileToTest, format:"lines", wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileInNode1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.should.equal(data[c]); + msg.should.have.property('parts'); + var parts = msg.parts; + parts.should.have.property('index',c); + parts.should.have.property('type','string'); + parts.should.have.property('ch','\n'); + c++; + if (c === data.length) { + parts.should.have.property('count', data.length); + done(); + } + else { + parts.should.not.have.property('count'); + } + } + catch(e) { + done(e); + } + }); + n1.receive({payload:""}); + }); + }); + + it('should read in a file and output a buffer with parts', function(done) { + var flow = [{id:"fileInNode1", type:"file in", name: "fileInNode", filename:fileToTest, format:"stream", wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileInNode1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload'); + Buffer.isBuffer(msg.payload).should.be.true(); + msg.payload.should.have.length(40); + msg.should.have.property('parts'); + msg.parts.should.have.property('count',1); + msg.parts.should.have.property('type','buffer'); + msg.parts.should.have.property('ch',''); + done(); + }); + n1.receive({payload:""}); + }); + }); + + it('should warn if no filename set', function(done) { + var flow = [{id:"fileInNode1", type:"file in", name: "fileInNode", "format":""}]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileInNode1"); + setTimeout(function() { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "file in"; + }); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.toString().should.equal("file.errors.nofilename"); + done(); + },wait); + n1.receive({}); + }); + }); + + it('should handle a file read error', function(done) { + var flow = [{id:"fileInNode1", type:"file in", name: "fileInNode", "filename":"badfile", "format":"", wires:[["n2"]]}, + {id:"n2", type:"helper"} + ]; + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileInNode1"); + var n2 = helper.getNode("n2"); + + n2.on("input", function(msg) { + try { + msg.should.not.have.property('payload'); + msg.should.have.property("error"); + msg.error.should.have.property("code","ENOENT"); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "file in"; + }); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.toString().should.startWith("Error"); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:""}); + }); + }); + + describe('encodings', function() { + + function checkReadWithEncoding(enc, data, done) { + var flow = [{id:"fileInNode1", type:"file in", name: "fileInNode", "filename":fileToTest, "format":"utf8", encoding:enc, wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + + fs.writeFileSync(fileToTest, encode(data, enc)); + helper.load(fileNode, flow, function() { + var n1 = helper.getNode("fileInNode1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.should.be.a.String(); + msg.payload.should.equal(data); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:""}); + }); + } + + // default + it('should read in a file with "none" encoding', function(done) { + checkReadWithEncoding("none", "試験", done); + }); + + // Native + it('should read in a file with "utf8" encoding', function(done) { + checkReadWithEncoding("utf8", "試験", done); + }); + + it('should read in a file with "ucs2" encoding', function(done) { + checkReadWithEncoding("ucs2", "試験", done); + }); + + it('should read in a file with "utf-16le" encoding', function(done) { + checkReadWithEncoding("utf-16le", "試験", done); + }); + + it('should read in a file with "binary" encoding', function(done) { + checkReadWithEncoding("binary", "test", done); + }); + + it('should read in a file with "base64" encoding', function(done) { + checkReadWithEncoding("base64", "5pel5pys6KqeCg==", done); + }); + + it('should read in a file with "hex" encoding', function(done) { + checkReadWithEncoding("hex", "deadbeef", done); + }); + + // Unicode + it('should read in a file with "utf-16be" encoding', function(done) { + checkReadWithEncoding("utf-16be", "試験", done); + }); + + // Japanese + it('should read in a file with "Shift_JIS" encoding', function(done) { + checkReadWithEncoding("Shift_JIS", "試験", done); + }); + + it('should read in a file with "Windows-31j" encoding', function(done) { + checkReadWithEncoding("Windows-31j", "試験", done); + }); + + it('should read in a file with "Windows932" encoding', function(done) { + checkReadWithEncoding("Windows932", "試験", done); + }); + + it('should read in a file with "EUC-JP" encoding', function(done) { + checkReadWithEncoding("EUC-JP", "試験", done); + }); + + // following encoding tests should be more specific + // Chinese + it('should read in a file with "GB2312" encoding', function(done) { + checkReadWithEncoding("GB2312", "test", done); + }); + + it('should read in a file with "GBK" encoding', function(done) { + checkReadWithEncoding("GBK", "test", done); + }); + + it('should read in a file with "GB18030" encoding', function(done) { + checkReadWithEncoding("GB18030", "test", done); + }); + + it('should read in a file with "Windows936" encoding', function(done) { + checkReadWithEncoding("Windows936", "test", done); + }); + + it('should read in a file with "EUC-CN" encoding', function(done) { + checkReadWithEncoding("EUC-CN", "test", done); + }); + + // Korean + it('should read in a file with "KS_C_5601" encoding', function(done) { + checkReadWithEncoding("KS_C_5601", "test", done); + }); + + it('should read in a file with "Windows949" encoding', function(done) { + checkReadWithEncoding("Windows949", "test", done); + }); + + it('should read in a file with "EUC-KR" encoding', function(done) { + checkReadWithEncoding("EUC-KR", "test", done); + }); + + // Taiwan/Hong Kong + it('should read in a file with "Big5" encoding', function(done) { + checkReadWithEncoding("Big5", "test", done); + }); + + it('should read in a file with "Big5-HKSCS" encoding', function(done) { + checkReadWithEncoding("Big5-HKSCS", "test", done); + }); + + it('should read in a file with "Windows950" encoding', function(done) { + checkReadWithEncoding("Windows950", "test", done); + }); + + // Windows + it('should read in a file with "cp874" encoding', function(done) { + checkReadWithEncoding("cp874", "test", done); + }); + + it('should read in a file with "cp1250" encoding', function(done) { + checkReadWithEncoding("cp1250", "test", done); + }); + + it('should read in a file with "cp1251" encoding', function(done) { + checkReadWithEncoding("cp1251", "test", done); + }); + + it('should read in a file with "cp1252" encoding', function(done) { + checkReadWithEncoding("cp1252", "test", done); + }); + + it('should read in a file with "cp1253" encoding', function(done) { + checkReadWithEncoding("cp1253", "test", done); + }); + + it('should read in a file with "cp1254" encoding', function(done) { + checkReadWithEncoding("cp1254", "test", done); + }); + + it('should read in a file with "cp1255" encoding', function(done) { + checkReadWithEncoding("cp1255", "test", done); + }); + + it('should read in a file with "cp1256" encoding', function(done) { + checkReadWithEncoding("cp1256", "test", done); + }); + + it('should read in a file with "cp1257" encoding', function(done) { + checkReadWithEncoding("cp1257", "test", done); + }); + + it('should read in a file with "cp1258" encoding', function(done) { + checkReadWithEncoding("cp1258", "test", done); + }); + + // IBM + it('should read in a file with "cp437" encoding', function(done) { + checkReadWithEncoding("cp437", "test", done); + }); + + it('should read in a file with "cp737" encoding', function(done) { + checkReadWithEncoding("cp737", "test", done); + }); + + it('should read in a file with "cp775" encoding', function(done) { + checkReadWithEncoding("cp775", "test", done); + }); + + it('should read in a file with "cp808" encoding', function(done) { + checkReadWithEncoding("cp808", "test", done); + }); + + it('should read in a file with "cp850" encoding', function(done) { + checkReadWithEncoding("cp850", "test", done); + }); + + it('should read in a file with "cp852" encoding', function(done) { + checkReadWithEncoding("cp852", "test", done); + }); + + it('should read in a file with "cp855" encoding', function(done) { + checkReadWithEncoding("cp855", "test", done); + }); + + it('should read in a file with "cp856" encoding', function(done) { + checkReadWithEncoding("cp856", "test", done); + }); + + it('should read in a file with "cp857" encoding', function(done) { + checkReadWithEncoding("cp857", "test", done); + }); + + it('should read in a file with "cp858" encoding', function(done) { + checkReadWithEncoding("cp858", "test", done); + }); + + it('should read in a file with "cp860" encoding', function(done) { + checkReadWithEncoding("cp860", "test", done); + }); + + it('should read in a file with "cp861" encoding', function(done) { + checkReadWithEncoding("cp861", "test", done); + }); + + it('should read in a file with "cp866" encoding', function(done) { + checkReadWithEncoding("cp866", "test", done); + }); + + it('should read in a file with "cp869" encoding', function(done) { + checkReadWithEncoding("cp869", "test", done); + }); + + it('should read in a file with "cp922" encoding', function(done) { + checkReadWithEncoding("cp922", "test", done); + }); + + it('should read in a file with "cp1046" encoding', function(done) { + checkReadWithEncoding("cp1046", "test", done); + }); + + it('should read in a file with "cp1124" encoding', function(done) { + checkReadWithEncoding("cp1124", "test", done); + }); + + it('should read in a file with "cp1125" encoding', function(done) { + checkReadWithEncoding("cp1125", "test", done); + }); + + it('should read in a file with "cp1129" encoding', function(done) { + checkReadWithEncoding("cp1129", "test", done); + }); + + it('should read in a file with "cp1133" encoding', function(done) { + checkReadWithEncoding("cp1133", "test", done); + }); + + it('should read in a file with "cp1161" encoding', function(done) { + checkReadWithEncoding("cp1161", "test", done); + }); + + it('should read in a file with "cp1162" encoding', function(done) { + checkReadWithEncoding("cp1162", "test", done); + }); + + it('should read in a file with "cp1163" encoding', function(done) { + checkReadWithEncoding("cp1163", "test", done); + }); + + // Mac + it('should read in a file with "maccroatian" encoding', function(done) { + checkReadWithEncoding("maccroatian", "test", done); + }); + + it('should read in a file with "maccyrillic" encoding', function(done) { + checkReadWithEncoding("maccyrillic", "test", done); + }); + + it('should read in a file with "macgreek" encoding', function(done) { + checkReadWithEncoding("macgreek", "test", done); + }); + + it('should read in a file with "maciceland" encoding', function(done) { + checkReadWithEncoding("maciceland", "test", done); + }); + + it('should read in a file with "macroman" encoding', function(done) { + checkReadWithEncoding("macroman", "test", done); + }); + + it('should read in a file with "macromania" encoding', function(done) { + checkReadWithEncoding("macromania", "test", done); + }); + + it('should read in a file with "macthai" encoding', function(done) { + checkReadWithEncoding("macthai", "test", done); + }); + + it('should read in a file with "macturkish" encoding', function(done) { + checkReadWithEncoding("macturkish", "test", done); + }); + + it('should read in a file with "macukraine" encoding', function(done) { + checkReadWithEncoding("macukraine", "test", done); + }); + + it('should read in a file with "maccenteuro" encoding', function(done) { + checkReadWithEncoding("maccenteuro", "test", done); + }); + + it('should read in a file with "macintosh" encoding', function(done) { + checkReadWithEncoding("macintosh", "test", done); + }); + + // KOI8 + it('should read in a file with "koi8-r" encoding', function(done) { + checkReadWithEncoding("koi8-r", "test", done); + }); + + it('should read in a file with "koi8-u" encoding', function(done) { + checkReadWithEncoding("koi8-u", "test", done); + }); + + it('should read in a file with "koi8-ru" encoding', function(done) { + checkReadWithEncoding("koi8-ru", "test", done); + }); + + it('should read in a file with "koi8-t" encoding', function(done) { + checkReadWithEncoding("koi8-t", "test", done); + }); + + // Misc + it('should read in a file with "armscii8" encoding', function(done) { + checkReadWithEncoding("armscii8", "test", done); + }); + + it('should read in a file with "rk1048" encoding', function(done) { + checkReadWithEncoding("rk1048", "test", done); + }); + + it('should read in a file with "tcvn" encoding', function(done) { + checkReadWithEncoding("tcvn", "test", done); + }); + + it('should read in a file with "georgianacademy" encoding', function(done) { + checkReadWithEncoding("georgianacademy", "test", done); + }); + + it('should read in a file with "georgianps" encoding', function(done) { + checkReadWithEncoding("georgianps", "test", done); + }); + + it('should read in a file with "pt154" encoding', function(done) { + checkReadWithEncoding("pt154", "test", done); + }); + + it('should read in a file with "viscii" encoding', function(done) { + checkReadWithEncoding("viscii", "test", done); + }); + + it('should read in a file with "iso646cn" encoding', function(done) { + checkReadWithEncoding("iso646cn", "test", done); + }); + + it('should read in a file with "iso646jp" encoding', function(done) { + checkReadWithEncoding("iso646jp", "test", done); + }); + + it('should read in a file with "hproman8" encoding', function(done) { + checkReadWithEncoding("hproman8", "test", done); + }); + + it('should read in a file with "tis620" encoding', function(done) { + checkReadWithEncoding("tis620", "test", done); + }); + + }); + + }); +}); diff --git a/packages/connector/test/nodes/core/storage/23-watch_spec.js b/packages/connector/test/nodes/core/storage/23-watch_spec.js new file mode 100644 index 0000000..a9942d5 --- /dev/null +++ b/packages/connector/test/nodes/core/storage/23-watch_spec.js @@ -0,0 +1,217 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var fs = require("fs-extra"); +var path = require("path"); +var should = require("should"); +var helper = require("node-red-node-test-helper"); +var watchNode = require("nr-test-utils").require("@node-red/nodes/core/storage/23-watch.js"); + + +describe('watch Node', function() { + this.timeout(5000); + + var resourcesDir = path.join(__dirname,"..","..","..","resources"); + var baseDir = path.join(resourcesDir, "23-watch-test-dir"); + var count = 0; + + function prepareDir() { + var dirToWatch = path.join(baseDir, "base"+count); + fs.mkdirSync(dirToWatch); + count++; + return { + dirToWatch:dirToWatch, + file0ToWatch:path.join(dirToWatch, "file0.txt"), + file1ToWatch:path.join(dirToWatch, "file1.txt"), + subDirToWatch:path.join(dirToWatch, "subdir"), + file2ToWatch:path.join(dirToWatch, "subdir", "file2.txt") + } + } + + function wait(msec, func) { + setTimeout(func, msec); + } + + before(function(done) { + fs.ensureDirSync(baseDir); + done(); + }); + + after(function(done) { + fs.removeSync(baseDir); + done(); + }); + + afterEach(function(done) { + helper.unload(); + done(); + }); + + function testWatch(flow, change_func, results, done) { + var processed = {}; + helper.load(watchNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + var len = Object.keys(results).length; + n2.on("input", function(msg) { + try { + // console.log(msg); + msg.should.have.property('file'); + + var file = msg.file; + if (file in processed) { + // multiple messages come in rare case + return; + } + processed[file] = true; + if (file === 'subdir') { + // On OSX, we get a change event on subdir when a file inside changes. + // On Travis, we don't. *sigh* + return; + } + (file in results).should.be.true(); + + var result = results[file]; + msg.should.have.property('payload', result.payload); + msg.should.have.property('type', result.type); + if('size' in result) { + msg.should.have.property('size', result.size); + } + count++; + if(count === len) { + n1.close(); + // wait for close + wait(100, done); + } + }catch(err) { + done(err); + } + }); + // wait for preparation + wait(500, change_func); + }); + } + + it('should watch a file to be changed', function(done) { + var files = prepareDir(); + fs.writeFileSync(files.file0ToWatch, ''); + var flow = [{id:"n1", type:"watch", name: "watch", + files: files.file0ToWatch, recursive: false, + wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var results = { + 'file0.txt' : { + 'payload' : files.file0ToWatch, + 'topic': files.file0ToWatch, + 'type': 'file', + 'size': 5 + } + }; + testWatch(flow, function() { + fs.appendFileSync(files.file0ToWatch, "ABCDE"); + }, results, done); + }); + + it('should watch multiple files to be changed', function(done) { + var files = prepareDir(); + fs.writeFileSync(files.file0ToWatch, ''); + fs.writeFileSync(files.file1ToWatch, ''); + var flow = [{id:"n1", type:"watch", name: "watch", + files: files.file0ToWatch +","+files.file1ToWatch, recursive: false, + wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var results = { + 'file0.txt' : { + 'payload' : files.file0ToWatch, + 'topic': files.file0ToWatch, + 'type': 'file'//, + // 'size': 5 + }, + 'file1.txt' : { + 'payload' : files.file1ToWatch, + 'topic': files.file1ToWatch, + 'type': 'file'//, + // 'size': 3 + } + }; + testWatch(flow, function() { + fs.appendFileSync(files.file0ToWatch, "ABCDE"); + fs.appendFileSync(files.file1ToWatch, "123"); + }, results, done); + }); + + it('should watch attribute of a file to be changed', function(done) { + var files = prepareDir(); + fs.writeFileSync(files.file0ToWatch, ''); + fs.chmodSync(files.file0ToWatch, 0o444); + var flow = [{id:"n1", type:"watch", name: "watch", + files: files.file0ToWatch, recursive: false, + wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var results = { + 'file0.txt' : { + 'payload' : files.file0ToWatch, + 'topic': files.file0ToWatch, + 'type': 'file'//, + // 'size': 0 + } + }; + testWatch(flow, function() { + fs.chmodSync(files.file0ToWatch, 0o777); + }, results, done); + }); + + it('should watch a file in a directory to be changed', function(done) { + var files = prepareDir(); + fs.writeFileSync(files.file0ToWatch, ''); + var flow = [{id:"n1", type:"watch", name: "watch", + files: files.dirToWatch, recursive: true, + wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var results = { + 'file0.txt' : { + 'payload' : files.file0ToWatch, + 'topic': files.file0ToWatch, + 'type': 'file'//, + // 'size': 5 + } + }; + testWatch(flow, function() { + fs.appendFileSync(files.file0ToWatch, "ABCDE"); + }, results, done); + }); + + it('should watch a sub directory in a directory to be changed', function(done) { + var files = prepareDir(); + fs.mkdirSync(files.subDirToWatch); + var flow = [{id:"n1", type:"watch", name: "watch", + files: files.dirToWatch, recursive: true, + wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + var results = { + 'file2.txt': { + payload: files.file2ToWatch, + type: 'file'//, + // size: 5 + } + }; + testWatch(flow, function() { + fs.appendFileSync(files.file2ToWatch, "ABCDE"); + }, results, done); + }); + +}); diff --git a/packages/connector/test/nodes/subflow/subflow_spec.js b/packages/connector/test/nodes/subflow/subflow_spec.js new file mode 100644 index 0000000..39f5f6b --- /dev/null +++ b/packages/connector/test/nodes/subflow/subflow_spec.js @@ -0,0 +1,563 @@ +/** +* Copyright JS Foundation and other contributors, http://js.foundation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + +var should = require("should"); +var functionNode = require("nr-test-utils").require("@node-red/nodes/core/function/10-function.js"); +var helper = require("node-red-node-test-helper"); + +// Notice: +// - nodes should have x, y, z property when defining subflow. + +describe('subflow', function() { + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + afterEach(function() { + helper.unload(); + }); + + it('should define subflow', function(done) { + var flow = [ + {id:"t1", type:"tab"}, + {id:"n1", z:"t1", type:"subflow:s1", wires:[["n2"]]}, + {id:"n2", z:"t1", type:"helper", wires:[]}, + // Subflow + {id:"s1", type:"subflow", name:"Subflow", info:"", + in:[{wires:[ {id:"s1-n1"} ]}], + out:[{wires:[ {id:"s1-n1", port:0} ]}]}, + {id:"s1-n1", z:"s1", type:"function", + func:"return msg;", wires:[]} + ]; + helper.load(functionNode, flow, function() { + done(); + }); + }); + + it('should pass data to/from subflow', function(done) { + var flow = [ + {id:"t0", type:"tab", label:"", disabled:false, info:""}, + {id:"n1", x:10, y:10, z:"t0", type:"subflow:s1", wires:[["n2"]]}, + {id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]}, + // Subflow + {id:"s1", type:"subflow", name:"Subflow", info:"", + in:[{ + x:10, y:10, + wires:[ {id:"s1-n1"} ] + }], + out:[{ + x:10, y:10, + wires:[ {id:"s1-n1", port:0} ] + }] + }, + {id:"s1-n1", x:10, y:10, z:"s1", type:"function", + func:"msg.payload = msg.payload+'bar'; return msg;", wires:[]} + ]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property("payload", "foobar"); + done(); + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should pass data to/from nested subflow', function(done) { + var flow = [ + {id:"t0", type:"tab", label:"", disabled:false, info:""}, + {id:"n1", x:10, y:10, z:"t0", type:"subflow:s1", wires:[["n2"]]}, + {id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]}, + // Subflow1 + {id:"s1", type:"subflow", name:"Subflow1", info:"", + in:[{ + x:10, y:10, + wires:[ {id:"s1-n1"} ] + }], + out:[{ + x:10, y:10, + wires:[ {id:"s1-n2", port:0} ] + }] + }, + {id:"s1-n1", x:10, y:10, z:"s1", type:"subflow:s2", + wires:[["s1-n2"]]}, + {id:"s1-n2", x:10, y:10, z:"s1", type:"function", + func:"msg.payload = msg.payload+'baz'; return msg;", wires:[]}, + // Subflow2 + {id:"s2", type:"subflow", name:"Subflow2", info:"", + in:[{ + x:10, y:10, + wires:[ {id:"s2-n1"} ] + }], + out:[{ + x:10, y:10, + wires:[ {id:"s2-n1", port:0} ] + }] + }, + {id:"s2-n1", x:10, y:10, z:"s2", type:"function", + func:"msg.payload=msg.payload+'bar'; return msg;", wires:[]} + ]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property("payload", "foobarbaz"); + done(); + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should access env var of subflow template', function(done) { + var flow = [ + {id:"t0", type:"tab", label:"", disabled:false, info:""}, + {id:"n1", x:10, y:10, z:"t0", type:"subflow:s1", wires:[["n2"]]}, + {id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]}, + // Subflow + {id:"s1", type:"subflow", name:"Subflow", info:"", + env: [ + {name: "K", type: "str", value: "V"} + ], + in:[{ + x:10, y:10, + wires:[ {id:"s1-n1"} ] + }], + out:[{ + x:10, y:10, + wires:[ {id:"s1-n1", port:0} ] + }] + }, + {id:"s1-n1", x:10, y:10, z:"s1", type:"function", + func:"msg.V = env.get('K'); return msg;", + wires:[]} + ]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("V", "V"); + done(); + } + catch (e) { + console.log(e); + done(e); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should access env var of subflow instance', function(done) { + var flow = [ + {id:"t0", type:"tab", label:"", disabled:false, info:""}, + {id:"n1", x:10, y:10, z:"t0", type:"subflow:s1", + env: [ + {name: "K", type: "str", value: "V"} + ], + wires:[["n2"]]}, + {id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]}, + // Subflow + {id:"s1", type:"subflow", name:"Subflow", info:"", + in:[{ + x:10, y:10, + wires:[ {id:"s1-n1"} ] + }], + out:[{ + x:10, y:10, + wires:[ {id:"s1-n1", port:0} ] + }] + }, + {id:"s1-n1", x:10, y:10, z:"s1", type:"function", + func:"msg.V = env.get('K'); return msg;", + wires:[]} + ]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("V", "V"); + done(); + } + catch (e) { + console.log(e); + done(e); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should access last env var with same name', function(done) { + var flow = [ + {id:"t0", type:"tab", label:"", disabled:false, info:""}, + {id:"n1", x:10, y:10, z:"t0", type:"subflow:s1", + env: [ + {name: "K", type: "str", value: "V0"}, + {name: "X", type: "str", value: "VX"}, + {name: "K", type: "str", value: "V1"} + ], + wires:[["n2"]]}, + {id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]}, + // Subflow + {id:"s1", type:"subflow", name:"Subflow", info:"", + in:[{ + x:10, y:10, + wires:[ {id:"s1-n1"} ] + }], + out:[{ + x:10, y:10, + wires:[ {id:"s1-n1", port:0} ] + }] + }, + {id:"s1-n1", x:10, y:10, z:"s1", type:"function", + func:"msg.V = env.get('K'); return msg;", + wires:[]} + ]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("V", "V1"); + done(); + } + catch (e) { + console.log(e); + done(e); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should access typed value of env var', function(done) { + var flow = [ + {id:"t0", type:"tab", label:"", disabled:false, info:""}, + {id:"n1", x:10, y:10, z:"t0", type:"subflow:s1", + env: [ + {name: "KN", type: "num", value: "100"}, + {name: "KB", type: "bool", value: "true"}, + {name: "KJ", type: "json", value: "[1,2,3]"}, + {name: "Kb", type: "bin", value: "[65,65]"}, + {name: "Ke", type: "env", value: "KS"} + ], + wires:[["n2"]]}, + {id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]}, + // Subflow + {id:"s1", type:"subflow", name:"Subflow", info:"", + in:[{ + x:10, y:10, + wires:[ {id:"s1-n1"} ] + }], + out:[{ + x:10, y:10, + wires:[ {id:"s1-n1", port:0} ] + }], + env: [ + {name: "KS", type: "str", value: "STR"} + ] + }, + {id:"s1-n1", x:10, y:10, z:"s1", type:"function", + func:"msg.VE = env.get('Ke'); msg.VS = env.get('KS'); msg.VN = env.get('KN'); msg.VB = env.get('KB'); msg.VJ = env.get('KJ'); msg.Vb = env.get('Kb'); return msg;", + wires:[]} + ]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("VS", "STR"); + msg.should.have.property("VN", 100); + msg.should.have.property("VB", true); + msg.should.have.property("VJ", [1,2,3]); + msg.should.have.property("Vb"); + should.ok(msg.Vb instanceof Buffer); + msg.should.have.property("VE","STR"); + done(); + } + catch (e) { + done(e); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should overwrite env var of subflow template by env var of subflow instance', function(done) { + var flow = [ + {id:"t0", type:"tab", label:"", disabled:false, info:""}, + {id:"n1", x:10, y:10, z:"t0", type:"subflow:s1", + env: [ + {name: "K", type: "str", value: "V"} + ], + wires:[["n2"]]}, + {id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]}, + // Subflow + {id:"s1", type:"subflow", name:"Subflow", info:"", + env: [ + {name: "K", type: "str", value: "TV"} + ], + in:[{ + x:10, y:10, + wires:[ {id:"s1-n1"} ] + }], + out:[{ + x:10, y:10, + wires:[ {id:"s1-n1", port:0} ] + }] + }, + {id:"s1-n1", x:10, y:10, z:"s1", type:"function", + func:"msg.V = env.get('K'); return msg;", + wires:[]} + ]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("V", "V"); + done(); + } + catch (e) { + console.log(e); + done(e); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should access env var of parent subflow template', function(done) { + var flow = [ + {id:"t0", type:"tab", label:"", disabled:false, info:""}, + {id:"n1", x:10, y:10, z:"t0", type:"subflow:s1", wires:[["n2"]]}, + {id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]}, + // Subflow1 + {id:"s1", type:"subflow", name:"Subflow1", info:"", + env: [ + {name: "K", type: "str", value: "V"}, + ], + in:[{ + x:10, y:10, + wires:[ {id:"s1-n1"} ] + }], + out:[{ + x:10, y:10, + wires:[ {id:"s1-n2", port:0} ] + }] + }, + {id:"s1-n1", x:10, y:10, z:"s1", type:"subflow:s2", + wires:[["s1-n2"]]}, + {id:"s1-n2", x:10, y:10, z:"s1", type:"function", + func:"return msg;", wires:[]}, + // Subflow2 + {id:"s2", type:"subflow", name:"Subflow2", info:"", + in:[{ + x:10, y:10, + wires:[ {id:"s2-n1"} ] + }], + out:[{ + x:10, y:10, + wires:[ {id:"s2-n1", port:0} ] + }] + }, + {id:"s2-n1", x:10, y:10, z:"s2", type:"function", + func:"msg.V = env.get('K'); return msg;", + wires:[]} + ]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property("V", "V"); + done(); + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should access env var of parent subflow instance', function(done) { + var flow = [ + {id:"t0", type:"tab", label:"", disabled:false, info:""}, + {id:"n1", x:10, y:10, z:"t0", type:"subflow:s1", + env: [ + {name: "K", type: "str", value: "V"} + ], + wires:[["n2"]]}, + {id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]}, + // Subflow1 + {id:"s1", type:"subflow", name:"Subflow1", info:"", + in:[{ + x:10, y:10, + wires:[ {id:"s1-n1"} ] + }], + out:[{ + x:10, y:10, + wires:[ {id:"s1-n2", port:0} ] + }] + }, + {id:"s1-n1", x:10, y:10, z:"s1", type:"subflow:s2", + wires:[["s1-n2"]]}, + {id:"s1-n2", x:10, y:10, z:"s1", type:"function", + func:"return msg;", wires:[]}, + // Subflow2 + {id:"s2", type:"subflow", name:"Subflow2", info:"", + in:[{ + x:10, y:10, + wires:[ {id:"s2-n1"} ] + }], + out:[{ + x:10, y:10, + wires:[ {id:"s2-n1", port:0} ] + }] + }, + {id:"s2-n1", x:10, y:10, z:"s2", type:"function", + func:"msg.V = env.get('K'); return msg;", + wires:[]} + ]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property("V", "V"); + done(); + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should access env var type of subflow instance', function(done) { + var flow = [ + {id:"t0", type:"tab", label:"", disabled:false, info:""}, + {id:"n1", x:10, y:10, z:"t0", type:"subflow:s1", + env: [ + {name: "K", type: "str", value: "V"} + ], + wires:[["n2"]]}, + {id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]}, + // Subflow + {id:"s1", type:"subflow", name:"Subflow", info:"", + in:[{ + x:10, y:10, + wires:[ {id:"s1-n1"} ] + }], + out:[{ + x:10, y:10, + wires:[ {id:"s1-n1", port:0} ] + }] + }, + {id:"s1-n1", x:10, y:10, z:"s1", type:"function", + func:"msg.V = env.get('K_type'); return msg;", + wires:[]} + ]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("V", "str"); + done(); + } + catch (e) { + console.log(e); + done(e); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should access env var info of subflow instance', function(done) { + var flow = [ + {id:"t0", type:"tab", label:"", disabled:false, info:""}, + {id:"n1", x:10, y:10, z:"t0", type:"subflow:s1", + env: [ + {name: "K", type: "str", value: "V"} + ], + wires:[["n2"]]}, + {id:"n2", x:10, y:10, z:"t0", type:"helper", wires:[]}, + // Subflow + {id:"s1", type:"subflow", name:"Subflow", info:"", + in:[{ + x:10, y:10, + wires:[ {id:"s1-n1"} ] + }], + out:[{ + x:10, y:10, + wires:[ {id:"s1-n1", port:0} ] + }], + env:[ + { + name: "K", type: "str", value: "", + ui: { + hasUI: true, + icon: "icon", + labels: { + "en-US": "label" + }, + type: "input", + inputTypes: { + str: true + } + } + } + ] + }, + {id:"s1-n1", x:10, y:10, z:"s1", type:"function", + func:"msg.V = env.get('K_info'); return msg;", + wires:[]} + ]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property("V"); + var v = msg.V; + v.should.have.property("name", "K"); + v.should.have.property("value", "V"); + v.should.have.property("type", "str"); + v.should.have.property("ui"); + var ui = v.ui; + ui.should.have.property("hasUI", true); + ui.should.have.property("icon", "icon"); + ui.should.have.property("type", "input"); + ui.should.have.property("labels"); + var labels = ui.labels; + labels.should.have.property("en-US", "label"); + ui.should.have.property("inputTypes"); + var types = ui.inputTypes; + types.should.have.property("str", true); + done(); + } + catch (e) { + console.log(e); + done(e); + } + }); + n1.receive({payload:"foo"}); + }); + }); + +}); diff --git a/packages/connector/test/resources/70-HTML-test-file.html b/packages/connector/test/resources/70-HTML-test-file.html new file mode 100644 index 0000000..2187b8e --- /dev/null +++ b/packages/connector/test/resources/70-HTML-test-file.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<body> + +<h1>This is a test page for node 70-HTML</h1> + +<p>There's nothing to read here.</p> + +<ol id="colours"> + <li>Blue</li> + <li>Red</li> +</ol> + +<ul id="fruits"> + <li>Apple</li> + <li>Pear</li> +</ul> + +<ul id="vegetables"> + <li>Potato</li> + <li>Parsnip</li> +</ul> + +<span> + <img src="foo.png"> +</span> + +</body> +</html> diff --git a/packages/connector/test/resources/file-in-node/test.txt b/packages/connector/test/resources/file-in-node/test.txt new file mode 100644 index 0000000..68ca53b --- /dev/null +++ b/packages/connector/test/resources/file-in-node/test.txt @@ -0,0 +1 @@ +Text file \ No newline at end of file diff --git a/packages/connector/test/resources/icons/test_icon.png b/packages/connector/test/resources/icons/test_icon.png new file mode 100644 index 0000000..4b6b7b5 Binary files /dev/null and b/packages/connector/test/resources/icons/test_icon.png differ diff --git a/packages/connector/test/resources/ssl/server.crt b/packages/connector/test/resources/ssl/server.crt new file mode 100644 index 0000000..493afc2 --- /dev/null +++ b/packages/connector/test/resources/ssl/server.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDMDCCAhgCCQDPGPyu5M6ZaDANBgkqhkiG9w0BAQsFADBZMQswCQYDVQQGEwJB +VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMRIwEAYDVQQDDAlsb2NhbGhvc3QwIBcNMTgwMzE2MDY0ODU1WhgP +MjExODAyMjAwNjQ4NTVaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0 +YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMM +CWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMifGelM +k/b3HeIj98y9P5jS+Qblqpq7+gsCaL+qglMFmG0QXe6Ordkrh3xeY0uTkaFatwLM +WMzoX60nNdaVjC9U9RlQLK/3nncCveexxRUGtI8VpxN04ivBE/ULhtJeStQFrfyt +LWr1WWf8o8P/EWzZnh0Y1oHc0XqhOPHu9Nfd9kn5nfHNd/xbY8KXa4DkVSJ1lLFK +3t/nSWttchF8zKgNpoQznNGqUTjT28l0sS8fyH76DyRj3Ke6xdNxX2NRUU0PnGFI +RMsBG4Qrzo5xY7lQP7uVVgZUlxryw+NuZuC1PBXaUKJOf6CGwrTq5WB9zF1iBZCs +wD68NvtLd0kHEgECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAfqNOg2v90r5x4lFo +SYmPUoX24gdwHd/mfCzDJksB8n98X1eULYZqqRF2Q7LMkYu/twxfR3EKQX1HZxQY +LpGUYX4ubJdVTy13opJs8B4NkhvRuOAP0+b7RVt4RfuxLX9tYOB98tEbf7Mj0ccq +F4sHi+PMCh64K7rNWECHar0F51yNtNXcxJPMuHZVmj0/U7h6ZxNf+GzdTi8YKmVy +5OHI7xol/II/v3QOi1L+BaEIUkqYODKuQouJVIzu4zX6JRfAaxwjJmliYoJm7OEY +dFMEQUw1Ggsos+KbkGi9mCDbveYpWcZTR8nfPwmx+oJtt47DTHUC3KSdRxgtfjGs +otmVSw== +-----END CERTIFICATE----- diff --git a/packages/connector/test/resources/ssl/server.key b/packages/connector/test/resources/ssl/server.key new file mode 100644 index 0000000..4b8d6a1 --- /dev/null +++ b/packages/connector/test/resources/ssl/server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAyJ8Z6UyT9vcd4iP3zL0/mNL5BuWqmrv6CwJov6qCUwWYbRBd +7o6t2SuHfF5jS5ORoVq3AsxYzOhfrSc11pWML1T1GVAsr/eedwK957HFFQa0jxWn +E3TiK8ET9QuG0l5K1AWt/K0tavVZZ/yjw/8RbNmeHRjWgdzReqE48e701932Sfmd +8c13/FtjwpdrgORVInWUsUre3+dJa21yEXzMqA2mhDOc0apRONPbyXSxLx/IfvoP +JGPcp7rF03FfY1FRTQ+cYUhEywEbhCvOjnFjuVA/u5VWBlSXGvLD425m4LU8FdpQ +ok5/oIbCtOrlYH3MXWIFkKzAPrw2+0t3SQcSAQIDAQABAoIBAGmbryUrpZxU24tG +idRiLw9Ax8yEq7lGiMqw2vlCRdZ0VJfdDMVeoE945ZpniXeoV/oLadl0Pq6nCG56 +/JFYKfJkk51eoheDjwxxCgzkfK2j2PqVWF0ao1CLE/ljtvYYouVXlA42D3mFbCoc +SQ0MwVx+dgg1If48gp0+L17T/ll/VOOQumts5UzoKC8YABLL00g5ZL9/jZlVipgl +HfENMPWOfy3q5kSgQqvTWTMdSE6644ryV890mrwcC/RzqQBSNgRh1Lqx3jcXQSdN +x5C19gEK60hZqcvzBkKYudMHUC6I0lcuao1xwBnHUQIVKmLFPZBUIQq3tVar/YUc +d65cJpECgYEA5D9QilQpHxv875wBvBOEbyt9TqDBBN/5JpGQ9sBKpA0eNp3UzrOr ++n0TlyoDZYjkxgNJScS4TpeKde1Hk5j2kkMngjS69dn4G6wmOI79gAOGrCiJd1/I +AWb09KxUKlWBbfKuLHdl1wSMCYQornDdXxYCxhv9sMZKbEJ//tsI420CgYEA4QPf +n/dRAm+6zwNQTWOYWlj5jsG1TilBBCtoRqUqVlrAgR6rS1lgOleHkVrWH0g0Lkmh +9DxWiWuNNXxdU/5zx9AQn/JuHuL8EjDLN5r7idcg2LtEElCkr12y0I9nzS2OOZnj +MTioIh+hghzNuk09NlVJrHi48bJUVL/6Ws7ruGUCgYBT9UJAD+MscVQiI2Wz9A30 +ArBOOu2lSGnSmRsU2PjbzYN+naIJAqhRNK7/HNIxCCD3AYB05SrSpgWliUmZ7ltM +w+0FhTX8d1g/fZx1k4uGCkYAj8y5H39nnKKgWb9/7wH0Gp+c9bJ9XEvSuE1qlVOo +xWTx0JwJ6Xa4yeFhMtrbJQKBgF/FfErjwvEciRBPQsCNoWzi7eUbAYYw/OE/cHSR +HAIBQmoymYnKkrCCTMtLNFPAMaV55ZrEi7iVtFaNhlOXu8PSBSFu1/wBdHRxnC0g +o+s5S1uz6Pc6p72UTeWDBBVKTHyryQ1MJhPQDrgIdm/TLDiR+HeWMnF9C3O++lno +NGAZAoGBAKhsmatxVD9B3jvUDd/CWhXVDSZQECrfJ+Uy1q6b5NO5yMibpIZv14Nj +VT+b2qXoO1wL6htTRJXXNPmrB/JtrLiLg/vxVuA7CPSgot8SDA+/lbRhf1n/SKnD +ECXrEUmq28SgBItbY4vcy5PVEHRvlzqO/LpD6Y7iGNpR7zw9Yk3b +-----END RSA PRIVATE KEY----- diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/admin/context_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/admin/context_spec.js new file mode 100644 index 0000000..a9dc0f7 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/admin/context_spec.js @@ -0,0 +1,230 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var request = require('supertest'); +var express = require('express'); +var bodyParser = require('body-parser'); +var sinon = require('sinon'); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var context = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin/context"); + +describe("api/admin/context", function () { + var app = undefined; + + before(function () { + app = express(); + app.use(bodyParser.json()); + app.get("/context/:scope(global)", context.get); + app.get("/context/:scope(global)/*", context.get); + app.get("/context/:scope(node|flow)/:id", context.get); + app.get("/context/:scope(node|flow)/:id/*", context.get); + + app.delete("/context/:scope(global)/*", context.delete); + app.delete("/context/:scope(node|flow)/:id/*", context.delete); + }); + + describe("get", function () { + var gContext = { + default: { abc: { msg: '111', format: 'number' } }, + file: { abc: { msg: '222', format: 'number' } } + }; + var fContext = { + default: { bool: { msg: 'true', format: 'boolean' } }, + file: { string: { msg: 'aaaa', format: 'string[7]' } } + }; + var nContext = { msg: "1", format: "number" }; + var stub = sinon.stub(); + + before(function () { + context.init({ + context: { + getValue: stub + } + }); + }); + + afterEach(function () { + stub.reset(); + }); + + it('should call context.getValue to get global contexts', function (done) { + stub.returns(Promise.resolve(gContext)); + request(app) + .get('/context/global') + .set('Accept', 'application/json') + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } + stub.args[0][0].should.have.property('user', undefined); + stub.args[0][0].should.have.property('scope', 'global'); + stub.args[0][0].should.have.property('id', undefined); + stub.args[0][0].should.have.property('key', undefined); + stub.args[0][0].should.have.property('store', undefined); + var body = res.body; + body.should.eql(gContext); + done(); + }); + }); + + it('should call context.getValue to get flow contexts', function (done) { + stub.returns(Promise.resolve(fContext)); + request(app) + .get('/context/flow/1234/') + .set('Accept', 'application/json') + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } + stub.args[0][0].should.have.property('user', undefined); + stub.args[0][0].should.have.property('scope', 'flow'); + stub.args[0][0].should.have.property('id', '1234'); + stub.args[0][0].should.have.property('key', undefined); + stub.args[0][0].should.have.property('store', undefined); + var body = res.body; + body.should.eql(fContext); + done(); + }); + }); + + it('should call context.getValue to get a node context', function (done) { + stub.returns(Promise.resolve(nContext)); + request(app) + .get('/context/node/5678/foo?store=file') + .set('Accept', 'application/json') + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } + stub.args[0][0].should.have.property('user', undefined); + stub.args[0][0].should.have.property('scope', 'node'); + stub.args[0][0].should.have.property('id', '5678'); + stub.args[0][0].should.have.property('key', 'foo'); + stub.args[0][0].should.have.property('store', 'file'); + var body = res.body; + body.should.eql(nContext); + done(); + }); + }); + + it('should handle error which context.getValue causes', function (done) { + stub.returns(Promise.reject('error')); + request(app) + .get('/context/global') + .set('Accept', 'application/json') + .expect(400) + .end(function (err, res) { + if (err) { + return done(err); + } + res.body.should.has.a.property('code', 'unexpected_error'); + res.body.should.has.a.property('message', 'error'); + done(); + }); + }); + }); + + describe("delete", function () { + var stub = sinon.stub(); + + before(function () { + context.init({ + context: { + delete: stub + } + }); + }); + + afterEach(function () { + stub.reset(); + }); + + it('should call context.delete to delete a global context', function (done) { + stub.returns(Promise.resolve()); + request(app) + .delete('/context/global/abc?store=default') + .expect(204) + .end(function (err, res) { + if (err) { + return done(err); + } + stub.args[0][0].should.have.property('user', undefined); + stub.args[0][0].should.have.property('scope', 'global'); + stub.args[0][0].should.have.property('id', undefined); + stub.args[0][0].should.have.property('key', 'abc'); + stub.args[0][0].should.have.property('store', 'default'); + done(); + }); + }); + + it('should call context.delete to delete a flow context', function (done) { + stub.returns(Promise.resolve()); + request(app) + .delete('/context/flow/1234/abc?store=file') + .expect(204) + .end(function (err, res) { + if (err) { + return done(err); + } + stub.args[0][0].should.have.property('user', undefined); + stub.args[0][0].should.have.property('scope', 'flow'); + stub.args[0][0].should.have.property('id', '1234'); + stub.args[0][0].should.have.property('key', 'abc'); + stub.args[0][0].should.have.property('store', 'file'); + done(); + }); + }); + + it('should call context.delete to delete a node context', function (done) { + stub.returns(Promise.resolve()); + request(app) + .delete('/context/node/5678/foo?store=file') + .expect(204) + .end(function (err, res) { + if (err) { + return done(err); + } + stub.args[0][0].should.have.property('user', undefined); + stub.args[0][0].should.have.property('scope', 'node'); + stub.args[0][0].should.have.property('id', '5678'); + stub.args[0][0].should.have.property('key', 'foo'); + stub.args[0][0].should.have.property('store', 'file'); + done(); + }); + }); + + it('should handle error which context.delete causes', function (done) { + stub.returns(Promise.reject('error')); + request(app) + .delete('/context/global/abc?store=default') + .expect(400) + .end(function (err, res) { + if (err) { + return done(err); + } + res.body.should.has.a.property('code', 'unexpected_error'); + res.body.should.has.a.property('message', 'error'); + done(); + }); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/admin/flow_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/admin/flow_spec.js new file mode 100644 index 0000000..278c6a3 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/admin/flow_spec.js @@ -0,0 +1,249 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var request = require('supertest'); +var express = require('express'); +var bodyParser = require('body-parser'); +var sinon = require('sinon'); +var when = require('when'); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var flow = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin/flow"); + +describe("api/admin/flow", function() { + + var app; + + before(function() { + app = express(); + app.use(bodyParser.json()); + app.get("/flow/:id",flow.get); + app.post("/flow",flow.post); + app.put("/flow/:id",flow.put); + app.delete("/flow/:id",flow.delete); + }); + + describe("get", function() { + before(function() { + var opts; + flow.init({ + flows: { + getFlow: function(_opts) { + opts = _opts; + if (opts.id === '123') { + return Promise.resolve({id:'123'}); + } else { + var err = new Error("message"); + err.code = "not_found"; + err.status = 404; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } + } + } + }); + }) + it('gets a known flow', function(done) { + request(app) + .get('/flow/123') + .set('Accept', 'application/json') + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.has.a.property('id','123'); + done(); + }); + }) + it('404s an unknown flow', function(done) { + request(app) + .get('/flow/456') + .set('Accept', 'application/json') + .expect(404) + .end(done); + }) + }); + + describe("add", function() { + var opts; + before(function() { + flow.init({ + flows: { + addFlow: function(_opts) { + opts = _opts; + if (opts.flow.id === "123") { + return Promise.resolve('123') + } else { + var err = new Error("random error"); + err.code = "random_error"; + err.status = 400; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } + } + } + }); + }) + it('adds a new flow', function(done) { + request(app) + .post('/flow') + .set('Accept', 'application/json') + .send({id:'123'}) + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.has.a.property('id','123'); + done(); + }); + }) + it('400 an invalid flow', function(done) { + request(app) + .post('/flow') + .set('Accept', 'application/json') + .send({id:'error'}) + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.has.a.property('code','random_error'); + res.body.should.has.a.property('message','random error'); + + done(); + }); + }) + }) + + describe("update", function() { + + var opts; + before(function() { + flow.init({ + flows: { + updateFlow: function(_opts) { + opts = _opts; + if (opts.id === "123") { + return Promise.resolve('123') + } else { + var err = new Error("random error"); + err.code = "random_error"; + err.status = 400; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } + } + } + }); + }) + + it('updates an existing flow', function(done) { + request(app) + .put('/flow/123') + .set('Accept', 'application/json') + .send({id:'123'}) + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.has.a.property('id','123'); + opts.should.have.property('id','123'); + opts.should.have.property('flow',{id:'123'}) + done(); + }); + }) + + it('400 an invalid flow', function(done) { + request(app) + .put('/flow/456') + .set('Accept', 'application/json') + .send({id:'456'}) + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.has.a.property('code','random_error'); + res.body.should.has.a.property('message','random error'); + + done(); + }); + }) + }) + + describe("delete", function() { + + var opts; + before(function() { + flow.init({ + flows: { + deleteFlow: function(_opts) { + opts = _opts; + if (opts.id === "123") { + return Promise.resolve() + } else { + var err = new Error("random error"); + err.code = "random_error"; + err.status = 400; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } + } + } + }); + }) + + it('deletes an existing flow', function(done) { + request(app) + .del('/flow/123') + .set('Accept', 'application/json') + .expect(204) + .end(function(err,res) { + if (err) { + return done(err); + } + opts.should.have.property('id','123'); + done(); + }); + }) + + it('400 an invalid flow', function(done) { + request(app) + .del('/flow/456') + .set('Accept', 'application/json') + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.has.a.property('code','random_error'); + res.body.should.has.a.property('message','random error'); + + done(); + }); + }) + }) + +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/admin/flows_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/admin/flows_spec.js new file mode 100644 index 0000000..ac295a1 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/admin/flows_spec.js @@ -0,0 +1,211 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var request = require('supertest'); +var express = require('express'); +var bodyParser = require('body-parser'); +var sinon = require('sinon'); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var flows = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin/flows"); + +describe("api/admin/flows", function() { + + var app; + + before(function() { + app = express(); + app.use(bodyParser.json()); + app.get("/flows",flows.get); + app.post("/flows",flows.post); + }); + + it('returns flow - v1', function(done) { + flows.init({ + flows:{ + getFlows: function() { return Promise.resolve({rev:"123",flows:[1,2,3]}); } + } + }); + request(app) + .get('/flows') + .set('Accept', 'application/json') + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + try { + res.body.should.have.lengthOf(3); + done(); + } catch(e) { + return done(e); + } + }); + }); + it('returns flow - v2', function(done) { + flows.init({ + flows:{ + getFlows: function() { return Promise.resolve({rev:"123",flows:[1,2,3]}); } + } + }); + request(app) + .get('/flows') + .set('Accept', 'application/json') + .set('Node-RED-API-Version','v2') + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + try { + res.body.should.have.a.property('rev','123'); + res.body.should.have.a.property('flows'); + res.body.flows.should.have.lengthOf(3); + done(); + } catch(e) { + return done(e); + } + }); + }); + it('returns flow - bad version', function(done) { + request(app) + .get('/flows') + .set('Accept', 'application/json') + .set('Node-RED-API-Version','xxx') + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + try { + res.body.should.have.a.property('code','invalid_api_version'); + done(); + } catch(e) { + return done(e); + } + }); + }); + it('sets flows - default - v1', function(done) { + var setFlows = sinon.spy(function() { return Promise.resolve();}); + flows.init({ + flows:{ + setFlows: setFlows + } + }); + request(app) + .post('/flows') + .set('Accept', 'application/json') + .expect(204) + .end(function(err,res) { + if (err) { + return done(err); + } + setFlows.calledOnce.should.be.true(); + setFlows.lastCall.args[0].should.have.property('deploymentType','full'); + done(); + }); + }); + it('sets flows - non-default - v1', function(done) { + var setFlows = sinon.spy(function() { return Promise.resolve();}); + flows.init({ + flows:{ + setFlows: setFlows + } + }); + request(app) + .post('/flows') + .set('Accept', 'application/json') + .set('Node-RED-Deployment-Type','nodes') + .expect(204) + .end(function(err,res) { + if (err) { + return done(err); + } + setFlows.calledOnce.should.be.true(); + setFlows.lastCall.args[0].should.have.property('deploymentType','nodes'); + done(); + }); + }); + + it('set flows - rejects mismatched revision - v2', function(done) { + flows.init({ + flows:{ + setFlows: function() { + var err = new Error("mismatch"); + err.code = "version_mismatch"; + err.status = 409; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } + } + }); + request(app) + .post('/flows') + .set('Accept', 'application/json') + .set('Node-RED-API-Version','v2') + .send({rev:456,flows:[4,5,6]}) + .expect(409) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property("code","version_mismatch"); + done(); + }); + }); + it('sets flow - bad version', function(done) { + request(app) + .post('/flows') + .set('Accept', 'application/json') + .set('Node-RED-API-Version','xxx') + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + try { + res.body.should.have.a.property('code','invalid_api_version'); + done(); + } catch(e) { + return done(e); + } + }); + }); + it('reloads flows', function(done) { + var setFlows = sinon.spy(function() { return Promise.resolve();}); + flows.init({ + flows:{ + setFlows: setFlows + } + }); + request(app) + .post('/flows') + .set('Accept', 'application/json') + .set('Node-RED-Deployment-Type','reload') + .expect(204) + .end(function(err,res) { + if (err) { + return done(err); + } + setFlows.called.should.be.true(); + setFlows.lastCall.args[0].should.not.have.property('flows'); + done(); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/admin/index_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/admin/index_spec.js new file mode 100644 index 0000000..ead5f27 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/admin/index_spec.js @@ -0,0 +1,458 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); +var request = require("supertest"); +var express = require("express"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var adminApi = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin"); +var auth = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth"); +var nodes = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin/nodes"); +var flows = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin/flows"); +var flow = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin/flow"); +var context = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin/context"); + +/** +* Ensure all API routes are correctly mounted, with the expected permissions checks +*/ +describe("api/admin/index", function() { + describe("Ensure all API routes are correctly mounted, with the expected permissions checks", function() { + var app; + var mockList = [ + flows,flow,nodes,context + ]; + var permissionChecks = {}; + var lastRequest; + var stubApp = function(req,res,next) { + lastRequest = req; + res.status(200).end(); + }; + before(function() { + mockList.forEach(function(m) { + sinon.stub(m,"init",function(){}); + }); + sinon.stub(auth,"needsPermission", function(permission) { + return function(req,res,next) { + permissionChecks[permission] = (permissionChecks[permission]||0)+1; + next(); + }; + }); + + sinon.stub(flows,"get",stubApp); + sinon.stub(flows,"post",stubApp); + + sinon.stub(flow,"get",stubApp); + sinon.stub(flow,"post",stubApp); + sinon.stub(flow,"delete",stubApp); + sinon.stub(flow,"put",stubApp); + + sinon.stub(nodes,"getAll",stubApp); + sinon.stub(nodes,"post",stubApp); + sinon.stub(nodes,"getModule",stubApp); + sinon.stub(nodes,"putModule",stubApp); + sinon.stub(nodes,"delete",stubApp); + sinon.stub(nodes,"getSet",stubApp); + sinon.stub(nodes,"putSet",stubApp); + sinon.stub(nodes,"getModuleCatalog",stubApp); + sinon.stub(nodes,"getModuleCatalogs",stubApp); + + sinon.stub(context,"get",stubApp); + sinon.stub(context,"delete",stubApp); + }); + after(function() { + mockList.forEach(function(m) { + m.init.restore(); + }); + auth.needsPermission.restore(); + + flows.get.restore(); + flows.post.restore(); + flow.get.restore(); + flow.post.restore(); + flow.delete.restore(); + flow.put.restore(); + nodes.getAll.restore(); + nodes.post.restore(); + nodes.getModule.restore(); + nodes.putModule.restore(); + nodes.delete.restore(); + nodes.getSet.restore(); + nodes.putSet.restore(); + nodes.getModuleCatalog.restore(); + nodes.getModuleCatalogs.restore(); + context.get.restore(); + context.delete.restore(); + + }); + + before(function() { + app = adminApi.init({}); + }); + + beforeEach(function() { + permissionChecks = {}; + }); + + it('GET /flows', function(done) { + request(app).get("/flows").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('flows.read',1); + done(); + }); + }); + + it('POST /flows', function(done) { + request(app).post("/flows").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('flows.write',1); + done(); + }); + }); + + it('GET /flow/1234', function(done) { + request(app).get("/flow/1234").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('flows.read',1); + lastRequest.params.should.have.property('id','1234'); + done(); + }); + }); + + it('POST /flow', function(done) { + request(app).post("/flow").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('flows.write',1); + done(); + }); + }); + + it('DELETE /flow/1234', function(done) { + request(app).del("/flow/1234").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('flows.write',1); + lastRequest.params.should.have.property('id','1234'); + done(); + }); + }); + + it('PUT /flow/1234', function(done) { + request(app).put("/flow/1234").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('flows.write',1); + lastRequest.params.should.have.property('id','1234'); + done(); + }); + }); + + it('GET /nodes', function(done) { + request(app).get("/nodes").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('nodes.read',1); + done(); + }); + }); + + it('POST /nodes', function(done) { + request(app).post("/nodes").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('nodes.write',1); + done(); + }); + }); + + it('GET /nodes/module', function(done) { + request(app).get("/nodes/module").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('nodes.read',1); + lastRequest.params.should.have.property(0,'module'); + done(); + }); + }); + + it('GET /nodes/@scope/module', function(done) { + request(app).get("/nodes/@scope/module").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('nodes.read',1); + lastRequest.params.should.have.property(0,'@scope/module'); + done(); + }); + }); + + it('PUT /nodes/module', function(done) { + request(app).put("/nodes/module").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('nodes.write',1); + lastRequest.params.should.have.property(0,'module'); + done(); + }); + }); + + it('PUT /nodes/@scope/module', function(done) { + request(app).put("/nodes/@scope/module").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('nodes.write',1); + lastRequest.params.should.have.property(0,'@scope/module'); + done(); + }); + }); + + it('DELETE /nodes/module', function(done) { + request(app).del("/nodes/module").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('nodes.write',1); + lastRequest.params.should.have.property(0,'module'); + done(); + }); + }); + + it('DELETE /nodes/@scope/module', function(done) { + request(app).del("/nodes/@scope/module").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('nodes.write',1); + lastRequest.params.should.have.property(0,'@scope/module'); + done(); + }); + }); + + it('GET /nodes/module/set', function(done) { + request(app).get("/nodes/module/set").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('nodes.read',1); + lastRequest.params.should.have.property(0,'module'); + lastRequest.params.should.have.property(2,'set'); + done(); + }); + }); + + it('GET /nodes/@scope/module/set', function(done) { + request(app).get("/nodes/@scope/module/set").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('nodes.read',1); + lastRequest.params.should.have.property(0,'@scope/module'); + lastRequest.params.should.have.property(2,'set'); + done(); + }); + }); + + it('PUT /nodes/module/set', function(done) { + request(app).put("/nodes/module/set").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('nodes.write',1); + lastRequest.params.should.have.property(0,'module'); + lastRequest.params.should.have.property(2,'set'); + done(); + }); + }); + + it('PUT /nodes/@scope/module/set', function(done) { + request(app).put("/nodes/@scope/module/set").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('nodes.write',1); + lastRequest.params.should.have.property(0,'@scope/module'); + lastRequest.params.should.have.property(2,'set'); + done(); + }); + }); + + it('GET /nodes/messages', function(done) { + request(app).get("/nodes/messages").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('nodes.read',1); + done(); + }); + }); + + it('GET /nodes/module/set/messages', function(done) { + request(app).get("/nodes/module/set/messages").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('nodes.read',1); + lastRequest.params.should.have.property(0,'module/set'); + done(); + }); + }); + + it('GET /nodes/@scope/module/set/messages', function(done) { + request(app).get("/nodes/@scope/module/set/messages").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('nodes.read',1); + lastRequest.params.should.have.property(0,'@scope/module/set'); + done(); + }); + }); + + it('GET /context/global', function(done) { + request(app).get("/context/global").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.read',1); + lastRequest.params.should.have.property('scope','global'); + done(); + }); + }); + + it('GET /context/global/key?store=memory', function(done) { + request(app).get("/context/global/key?store=memory").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.read',1); + lastRequest.params.should.have.property('scope','global'); + lastRequest.params.should.have.property(0,'key'); + lastRequest.query.should.have.property('store','memory'); + done(); + }); + }); + + it('GET /context/flow/1234', function(done) { + request(app).get("/context/flow/1234").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.read',1); + lastRequest.params.should.have.property('scope','flow'); + lastRequest.params.should.have.property('id','1234'); + done(); + }); + }); + + it('GET /context/flow/1234/key?store=memory', function(done) { + request(app).get("/context/flow/1234/key?store=memory").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.read',1); + lastRequest.params.should.have.property('scope','flow'); + lastRequest.params.should.have.property('id','1234'); + lastRequest.params.should.have.property(0,'key'); + lastRequest.query.should.have.property('store','memory'); + done(); + }); + }); + + it('GET /context/node/5678', function(done) { + request(app).get("/context/node/5678").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.read',1); + lastRequest.params.should.have.property('scope','node'); + lastRequest.params.should.have.property('id','5678'); + done(); + }); + }); + + it('GET /context/node/5678/foo?store=memory', function(done) { + request(app).get("/context/node/5678/foo?store=memory").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.read',1); + lastRequest.params.should.have.property('scope','node'); + lastRequest.params.should.have.property('id','5678'); + lastRequest.params.should.have.property(0,'foo'); + lastRequest.query.should.have.property('store','memory'); + done(); + }); + }); + + it('DELETE /context/global/key?store=memory', function(done) { + request(app).del("/context/global/key?store=memory").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.write',1); + lastRequest.params.should.have.property('scope','global'); + lastRequest.params.should.have.property(0,'key'); + lastRequest.query.should.have.property('store','memory'); + done(); + }); + }); + + it('DELETE /context/flow/1234/key?store=memory', function(done) { + request(app).del("/context/flow/1234/key?store=memory").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.write',1); + lastRequest.params.should.have.property('scope','flow'); + lastRequest.params.should.have.property('id','1234'); + lastRequest.params.should.have.property(0,'key'); + lastRequest.query.should.have.property('store','memory'); + done(); + }); + }); + + it('DELETE /context/node/5678/foo?store=memory', function(done) { + request(app).del("/context/node/5678/foo?store=memory").expect(200).end(function(err,res) { + if (err) { + return done(err); + } + permissionChecks.should.have.property('context.write',1); + lastRequest.params.should.have.property('scope','node'); + lastRequest.params.should.have.property('id','5678'); + lastRequest.params.should.have.property(0,'foo'); + lastRequest.query.should.have.property('store','memory'); + done(); + }); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/admin/nodes_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/admin/nodes_spec.js new file mode 100644 index 0000000..ef98fb6 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/admin/nodes_spec.js @@ -0,0 +1,479 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var request = require('supertest'); +var express = require('express'); +var bodyParser = require('body-parser'); +var sinon = require('sinon'); +var when = require('when'); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var nodes = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin/nodes"); +var apiUtil = NR_TEST_UTILS.require("@node-red/editor-api/lib/util"); + +describe("api/admin/nodes", function() { + + var app; + before(function() { + app = express(); + app.use(bodyParser.json()); + app.get("/nodes",nodes.getAll); + app.post("/nodes",nodes.post); + app.get(/\/nodes\/messages/,nodes.getModuleCatalogs); + app.get(/\/nodes\/((@[^\/]+\/)?[^\/]+\/[^\/]+)\/messages/,nodes.getModuleCatalog); + app.get(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,nodes.getModule); + app.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,nodes.putModule); + app.get(/\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,nodes.getSet); + app.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,nodes.putSet); + app.get("/getIcons",nodes.getIcons); + app.delete(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,nodes.delete); + sinon.stub(apiUtil,"determineLangFromHeaders", function() { + return "en-US"; + }); + }); + after(function() { + apiUtil.determineLangFromHeaders.restore(); + }) + + describe('get nodes', function() { + it('returns node list', function(done) { + nodes.init({ + nodes:{ + getNodeList: function() { + return Promise.resolve([1,2,3]); + } + } + }); + request(app) + .get('/nodes') + .set('Accept', 'application/json') + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.be.an.Array(); + res.body.should.have.lengthOf(3); + done(); + }); + }); + + it('returns node configs', function(done) { + nodes.init({ + nodes:{ + getNodeConfigs: function() { + return Promise.resolve("<script></script>"); + } + }, + i18n: { + determineLangFromHeaders: function(){} + } + }); + request(app) + .get('/nodes') + .set('Accept', 'text/html') + .expect(200) + .expect("<script></script>") + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + + it('returns node module info', function(done) { + nodes.init({ + nodes:{ + getModuleInfo: function(opts) { + return Promise.resolve({"node-red":{name:"node-red"}}[opts.module]); + } + } + }); + request(app) + .get('/nodes/node-red') + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("name","node-red"); + done(); + }); + }); + + it('returns 404 for unknown module', function(done) { + nodes.init({ + nodes:{ + getModuleInfo: function(opts) { + var errInstance = new Error("Not Found"); + errInstance.code = "not_found"; + errInstance.status = 404; + var p = Promise.reject(errInstance); + p.catch(()=>{}); + return p; + } + } + }); + request(app) + .get('/nodes/node-blue') + .expect(404) + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + + it('returns individual node info', function(done) { + nodes.init({ + nodes:{ + getNodeInfo: function(opts) { + return Promise.resolve({"node-red/123":{id:"node-red/123"}}[opts.id]); + } + } + }); + request(app) + .get('/nodes/node-red/123') + .set('Accept', 'application/json') + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("id","node-red/123"); + done(); + }); + }); + + it('returns individual node configs', function(done) { + nodes.init({ + nodes:{ + getNodeConfig: function(opts) { + return Promise.resolve({"node-red/123":"<script></script>"}[opts.id]); + } + }, + i18n: { + determineLangFromHeaders: function(){} + } + }); + request(app) + .get('/nodes/node-red/123') + .set('Accept', 'text/html') + .expect(200) + .expect("<script></script>") + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + it('returns 404 for unknown node', function(done) { + nodes.init({ + nodes:{ + getNodeInfo: function(opts) { + var errInstance = new Error("Not Found"); + errInstance.code = "not_found"; + errInstance.status = 404; + var p = Promise.reject(errInstance); + p.catch(()=>{}); + return p; + } + } + }); + request(app) + .get('/nodes/node-red/456') + .set('Accept', 'application/json') + .expect(404) + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + }); + + describe('install', function() { + it('installs the module and returns module info', function(done) { + var opts; + nodes.init({ + nodes:{ + addModule: function(_opts) { + opts = _opts; + return Promise.resolve({ + name:"foo", + nodes:[{id:"123"}] + }); + } + } + }); + request(app) + .post('/nodes') + .send({module: 'foo',version:"1.2.3"}) + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("name","foo"); + res.body.should.have.property("nodes"); + res.body.nodes[0].should.have.property("id","123"); + opts.should.have.property("module","foo"); + opts.should.have.property("version","1.2.3"); + done(); + }); + }); + it('returns error', function(done) { + nodes.init({ + nodes:{ + addModule: function(opts) { + var errInstance = new Error("Message"); + errInstance.code = "random_error"; + errInstance.status = 400; + var p = Promise.reject(errInstance); + p.catch(()=>{}); + return p; + } + } + }); + request(app) + .post('/nodes') + .send({module: 'foo',version:"1.2.3"}) + .expect(400) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.a.property('code','random_error'); + done(); + }); + }); + }); + describe('delete', function() { + it('uninstalls the module', function(done) { + var opts; + nodes.init({ + nodes:{ + removeModule: function(_opts) { + opts = _opts; + return Promise.resolve(); + } + } + }); + request(app) + .del('/nodes/123') + .expect(204) + .end(function(err,res) { + if (err) { + throw err; + } + opts.should.have.property("module","123"); + done(); + }); + }); + it('returns error', function(done) { + nodes.init({ + nodes:{ + removeModule: function(opts) { + var errInstance = new Error("Message"); + errInstance.code = "random_error"; + errInstance.status = 400; + var p = Promise.reject(errInstance); + p.catch(()=>{}); + return p; + } + } + }); + request(app) + .del('/nodes/123') + .expect(400) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.a.property('code','random_error'); + done(); + }); + }); + }); + + describe('enable/disable node set', function() { + it('returns 400 for invalid request payload', function(done) { + nodes.init({ + nodes:{ + setNodeSetState: function(opts) {return Promise.resolve()} + } + }); + request(app) + .put('/nodes/node-red/foo') + .send({}) + .expect(400) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("code","invalid_request"); + res.body.should.have.property("message","Invalid request"); + done(); + }); + }); + + it('sets node state and returns node info', function(done) { + var opts; + nodes.init({ + nodes:{ + setNodeSetState: function(_opts) { + opts = _opts; + return Promise.resolve({id:"123",enabled: true }); + } + } + }); + + request(app) + .put('/nodes/node-red/foo') + .send({enabled:true}) + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("id","123"); + res.body.should.have.property("enabled",true); + opts.should.have.property("enabled",true); + opts.should.have.property("id","node-red/foo"); + + done(); + }); + }); + }); + describe('enable/disable module' ,function() { + it('returns 400 for invalid request payload', function(done) { + nodes.init({ + nodes:{ + setModuleState: function(opts) {return Promise.resolve()} + } + }); + request(app) + .put('/nodes/node-red') + .send({}) + .expect(400) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("code","invalid_request"); + res.body.should.have.property("message","Invalid request"); + done(); + }); + }); + it('sets module state and returns module info', function(done) { + var opts; + nodes.init({ + nodes:{ + setModuleState: function(_opts) { + opts = _opts; + return Promise.resolve({name:"node-red"}); + } + } + }); + + request(app) + .put('/nodes/node-red') + .send({enabled:true}) + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("name","node-red"); + opts.should.have.property("enabled",true); + opts.should.have.property("module","node-red"); + + done(); + }); + }); + }); + + describe('get icons', function() { + it('returns icon list', function(done) { + nodes.init({ + nodes:{ + getIconList: function() { + return Promise.resolve({module:[1,2,3]}); + } + } + }); + request(app) + .get('/getIcons') + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("module"); + res.body.module.should.be.an.Array(); + res.body.module.should.have.lengthOf(3); + done(); + }); + }); + }); + + describe('get module messages', function() { + it('returns message catalog', function(done) { + nodes.init({ + nodes:{ + getModuleCatalog: function(opts) { + return Promise.resolve({a:123}); + } + } + }); + request(app) + .get('/nodes/module/set/messages') + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.eql({a:123}); + done(); + }); + }); + it('returns all node catalogs', function(done) { + nodes.init({ + nodes:{ + getModuleCatalogs: function(opts) { + return Promise.resolve({a:1}); + } + } + }); + request(app) + .get('/nodes/messages') + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.eql({a:1}); + done(); + }); + }); + }) +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/auth/clients_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/auth/clients_spec.js new file mode 100644 index 0000000..1f6263d --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/auth/clients_spec.js @@ -0,0 +1,47 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var NR_TEST_UTILS = require("nr-test-utils"); +var Clients = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/clients"); + +describe("api/auth/clients", function() { + it('finds the known editor client',function(done) { + Clients.get("node-red-editor").then(function(client) { + client.should.have.property("id","node-red-editor"); + client.should.have.property("secret","not_available"); + done(); + }); + }); + it('finds the known admin client',function(done) { + Clients.get("node-red-admin").then(function(client) { + client.should.have.property("id","node-red-admin"); + client.should.have.property("secret","not_available"); + done(); + }).catch(function(err) { + done(err); + }); + }); + it('returns null for unknown client',function(done) { + Clients.get("unknown-client").then(function(client) { + should.not.exist(client); + done(); + }).catch(function(err) { + done(err); + }); + + }); +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/auth/index_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/auth/index_spec.js new file mode 100644 index 0000000..3cf0111 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/auth/index_spec.js @@ -0,0 +1,217 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var when = require("when"); +var sinon = require("sinon"); + +var passport = require("passport"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var auth = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth"); +var Users = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/users"); +var Tokens = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/tokens"); +var Permissions = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/permissions"); + +describe("api/auth/index",function() { + + + + describe("ensureClientSecret", function() { + before(function() { + auth.init({},{}) + }); + it("leaves client_secret alone if not present",function(done) { + var req = { + body: { + client_secret: "test_value" + } + }; + auth.ensureClientSecret(req,null,function() { + req.body.should.have.a.property("client_secret","test_value"); + done(); + }) + }); + it("applies a default client_secret if not present",function(done) { + var req = { + body: { } + }; + auth.ensureClientSecret(req,null,function() { + req.body.should.have.a.property("client_secret","not_available"); + done(); + }) + }); + }); + + describe("revoke", function() { + it("revokes a token", function(done) { + var revokeToken = sinon.stub(Tokens,"revoke",function() { + return when.resolve(); + }); + + var req = { body: { token: "abcdef" } }; + + var res = { status: function(resp) { + revokeToken.restore(); + + resp.should.equal(200); + return { + end: done + } + }}; + + auth.revoke(req,res); + }); + }); + + describe("login", function() { + beforeEach(function() { + sinon.stub(Tokens,"init",function(){}); + sinon.stub(Users,"init",function(){}); + }); + afterEach(function() { + Tokens.init.restore(); + Users.init.restore(); + }); + it("returns login details - credentials", function(done) { + auth.init({adminAuth:{type:"credentials"}},{}) + auth.login(null,{json: function(resp) { + resp.should.have.a.property("type","credentials"); + resp.should.have.a.property("prompts"); + resp.prompts.should.have.a.lengthOf(2); + done(); + }}); + }); + it("returns login details - none", function(done) { + auth.init({},{}) + auth.login(null,{json: function(resp) { + resp.should.eql({}); + done(); + }}); + }); + it("returns login details - strategy", function(done) { + auth.init({adminAuth:{type:"strategy",strategy:{label:"test-strategy",icon:"test-icon"}}},{}) + auth.login(null,{json: function(resp) { + resp.should.have.a.property("type","strategy"); + resp.should.have.a.property("prompts"); + resp.prompts.should.have.a.lengthOf(1); + resp.prompts[0].should.have.a.property("type","button"); + resp.prompts[0].should.have.a.property("label","test-strategy"); + resp.prompts[0].should.have.a.property("icon","test-icon"); + + done(); + }}); + }); + + }); + describe("needsPermission", function() { + beforeEach(function() { + sinon.stub(Tokens,"init",function(){}); + sinon.stub(Users,"init",function(){}); + }); + afterEach(function() { + Tokens.init.restore(); + Users.init.restore(); + if (passport.authenticate.restore) { + passport.authenticate.restore(); + } + if (Permissions.hasPermission.restore) { + Permissions.hasPermission.restore(); + } + }); + + + it('no-ops if adminAuth not set', function(done) { + sinon.stub(passport,"authenticate",function(scopes,opts) { + return function(req,res,next) { + } + }); + auth.init({}); + var func = auth.needsPermission("foo"); + func({},{},function() { + passport.authenticate.called.should.be.false(); + done(); + }) + }); + it('skips auth if req.user undefined', function(done) { + sinon.stub(passport,"authenticate",function(scopes,opts) { + return function(req,res,next) { + next(); + } + }); + sinon.stub(Permissions,"hasPermission",function(perm) { return true }); + auth.init({adminAuth:{}}); + var func = auth.needsPermission("foo"); + func({user:null},{},function() { + try { + passport.authenticate.called.should.be.true(); + Permissions.hasPermission.called.should.be.false(); + done(); + } catch(err) { + done(err); + } + }) + }); + + it('passes for valid user permission', function(done) { + sinon.stub(passport,"authenticate",function(scopes,opts) { + return function(req,res,next) { + next(); + } + }); + sinon.stub(Permissions,"hasPermission",function(perm) { return true }); + auth.init({adminAuth:{}}); + var func = auth.needsPermission("foo"); + func({user:true,authInfo: { scope: "read"}},{},function() { + try { + passport.authenticate.called.should.be.true(); + Permissions.hasPermission.called.should.be.true(); + Permissions.hasPermission.lastCall.args[0].should.eql("read"); + Permissions.hasPermission.lastCall.args[1].should.eql("foo"); + done(); + } catch(err) { + done(err); + } + }) + }); + + it('rejects for invalid user permission', function(done) { + sinon.stub(passport,"authenticate",function(scopes,opts) { + return function(req,res,next) { + next(); + } + }); + sinon.stub(Permissions,"hasPermission",function(perm) { return false }); + auth.init({adminAuth:{}}); + var func = auth.needsPermission("foo"); + func({user:true,authInfo: { scope: "read"}},{ + status: function(status) { + return { end: function() { + try { + status.should.eql(401); + done(); + } catch(err) { + done(err); + } + }} + } + },function() { + done(new Error("hasPermission unexpected passed")) + }); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/auth/permissions_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/auth/permissions_spec.js new file mode 100644 index 0000000..50c249c --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/auth/permissions_spec.js @@ -0,0 +1,59 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var permissions = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/permissions"); + +describe("api/auth/permissions", function() { + describe("hasPermission", function() { + it('a user with no permissions',function() { + permissions.hasPermission([],"*").should.be.false(); + }); + it('a user with global permissions',function() { + permissions.hasPermission("*","read").should.be.true(); + permissions.hasPermission(["*"],"write").should.be.true(); + }); + it('a user with read permissions',function() { + permissions.hasPermission(["read"],"read").should.be.true(); + permissions.hasPermission(["read"],"node.read").should.be.true(); + permissions.hasPermission(["read"],"write").should.be.false(); + permissions.hasPermission(["read"],"node.write").should.be.false(); + permissions.hasPermission(["*.read"],"read").should.be.true(); + permissions.hasPermission(["*.read"],"node.read").should.be.true(); + permissions.hasPermission(["*.read"],"write").should.be.false(); + permissions.hasPermission(["*.read"],"node.write").should.be.false(); + }); + it('a user with foo permissions',function() { + permissions.hasPermission("foo","foo").should.be.true(); + }); + it('an array of permissions', function() { + permissions.hasPermission(["*"],["foo.read","foo.write"]).should.be.true(); + permissions.hasPermission("read",["foo.read","foo.write"]).should.be.false(); + permissions.hasPermission("read",["foo.read","bar.read"]).should.be.true(); + permissions.hasPermission(["flows.read"],["flows.read"]).should.be.true(); + permissions.hasPermission(["flows.read"],["flows.write"]).should.be.false(); + permissions.hasPermission(["flows.read","nodes.write"],["flows.write"]).should.be.false(); + permissions.hasPermission(["flows.read","nodes.write"],["nodes.write"]).should.be.true(); + }); + it('permits an empty permission', function() { + permissions.hasPermission("*","").should.be.true(); + permissions.hasPermission("read",[""]).should.be.true(); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/auth/strategies_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/auth/strategies_spec.js new file mode 100644 index 0000000..d30f619 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/auth/strategies_spec.js @@ -0,0 +1,273 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var when = require('when'); +var sinon = require('sinon'); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var strategies = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/strategies"); +var Users = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/users"); +var Tokens = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/tokens"); +var Clients = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/clients"); + +describe("api/auth/strategies", function() { + describe("Password Token Exchange", function() { + var userAuthentication; + afterEach(function() { + if (userAuthentication) { + userAuthentication.restore(); + userAuthentication = null; + } + }); + + it('Handles authentication failure',function(done) { + userAuthentication = sinon.stub(Users,"authenticate",function(username,password) { + return when.resolve(null); + }); + + strategies.passwordTokenExchange({},"user","password","scope",function(err,token) { + try { + should.not.exist(err); + token.should.be.false(); + done(); + } catch(e) { + done(e); + } + }); + }); + + it('Handles scope overreach',function(done) { + userAuthentication = sinon.stub(Users,"authenticate",function(username,password) { + return when.resolve({username:"user",permissions:"read"}); + }); + + strategies.passwordTokenExchange({},"user","password","*",function(err,token) { + try { + should.not.exist(err); + token.should.be.false(); + done(); + } catch(e) { + done(e); + } + }); + }); + + it('Creates new token on authentication success',function(done) { + userAuthentication = sinon.stub(Users,"authenticate",function(username,password) { + return when.resolve({username:"user",permissions:"*"}); + }); + var tokenDetails = {}; + var tokenCreate = sinon.stub(Tokens,"create",function(username,client,scope) { + tokenDetails.username = username; + tokenDetails.client = client; + tokenDetails.scope = scope; + return when.resolve({accessToken: "123456"}); + }); + + strategies.passwordTokenExchange({id:"myclient"},"user","password","read",function(err,token) { + try { + should.not.exist(err); + token.should.equal("123456"); + tokenDetails.should.have.property("username","user"); + tokenDetails.should.have.property("client","myclient"); + tokenDetails.should.have.property("scope","read"); + done(); + } catch(e) { + done(e); + } finally { + tokenCreate.restore(); + } + }); + + }); + }); + + describe("Anonymous Strategy", function() { + it('Succeeds if anon user enabled',function(done) { + var userDefault = sinon.stub(Users,"default",function() { + return when.resolve("anon"); + }); + strategies.anonymousStrategy._success = strategies.anonymousStrategy.success; + strategies.anonymousStrategy.success = function(user) { + user.should.equal("anon"); + strategies.anonymousStrategy.success = strategies.anonymousStrategy._success; + delete strategies.anonymousStrategy._success; + done(); + }; + strategies.anonymousStrategy.authenticate({}); + }); + it('Fails if anon user not enabled',function(done) { + var userDefault = sinon.stub(Users,"default",function() { + return when.resolve(null); + }); + strategies.anonymousStrategy._fail = strategies.anonymousStrategy.fail; + strategies.anonymousStrategy.fail = function(err) { + err.should.equal(401); + strategies.anonymousStrategy.fail = strategies.anonymousStrategy._fail; + delete strategies.anonymousStrategy._fail; + done(); + }; + strategies.anonymousStrategy.authenticate({}); + }); + afterEach(function() { + Users.default.restore(); + }) + }); + + describe("Bearer Strategy", function() { + it('Rejects invalid token',function(done) { + var getToken = sinon.stub(Tokens,"get",function(token) { + return when.resolve(null); + }); + + strategies.bearerStrategy("1234",function(err,user) { + try { + should.not.exist(err); + user.should.be.false(); + done(); + } catch(e) { + done(e); + } finally { + getToken.restore(); + } + }); + }); + it('Accepts valid token',function(done) { + var getToken = sinon.stub(Tokens,"get",function(token) { + return when.resolve({user:"user",scope:"scope"}); + }); + var getUser = sinon.stub(Users,"get",function(username) { + return when.resolve("aUser"); + }); + + strategies.bearerStrategy("1234",function(err,user,opts) { + try { + should.not.exist(err); + user.should.equal("aUser"); + opts.should.have.a.property("scope","scope"); + done(); + } catch(e) { + done(e); + } finally { + getToken.restore(); + getUser.restore(); + } + }); + }); + it('Fail if no user for token',function(done) { + var getToken = sinon.stub(Tokens,"get",function(token) { + return when.resolve({user:"user",scope:"scope"}); + }); + var getUser = sinon.stub(Users,"get",function(username) { + return when.resolve(null); + }); + + strategies.bearerStrategy("1234",function(err,user,opts) { + try { + should.not.exist(err); + user.should.equal(false); + should.not.exist(opts); + done(); + } catch(e) { + done(e); + } finally { + getToken.restore(); + getUser.restore(); + } + }); + }); + }); + + describe("Client Password Strategy", function() { + it('Accepts valid client',function(done) { + var testClient = {id:"node-red-editor",secret:"not_available"}; + var getClient = sinon.stub(Clients,"get",function(client) { + return when.resolve(testClient); + }); + + strategies.clientPasswordStrategy(testClient.id,testClient.secret,function(err,client) { + try { + should.not.exist(err); + client.should.eql(testClient); + done(); + } catch(e) { + done(e); + } finally { + getClient.restore(); + } + }); + }); + it('Rejects invalid client secret',function(done) { + var testClient = {id:"node-red-editor",secret:"not_available"}; + var getClient = sinon.stub(Clients,"get",function(client) { + return when.resolve(testClient); + }); + + strategies.clientPasswordStrategy(testClient.id,"invalid_secret",function(err,client) { + try { + should.not.exist(err); + client.should.be.false(); + done(); + } catch(e) { + done(e); + } finally { + getClient.restore(); + } + }); + }); + it('Rejects invalid client id',function(done) { + var getClient = sinon.stub(Clients,"get",function(client) { + return when.resolve(null); + }); + strategies.clientPasswordStrategy("invalid_id","invalid_secret",function(err,client) { + try { + should.not.exist(err); + client.should.be.false(); + done(); + } catch(e) { + done(e); + } finally { + getClient.restore(); + } + }); + }); + + var userAuthentication; + it('Blocks after 5 failures',function(done) { + userAuthentication = sinon.stub(Users,"authenticate",function(username,password) { + return when.resolve(null); + }); + for (var z=0; z<5; z++) { + strategies.passwordTokenExchange({},"user","badpassword","scope",function(err,token) { + }); + } + strategies.passwordTokenExchange({},"user","badpassword","scope",function(err,token) { + try { + err.toString().should.equal("Error: Too many login attempts. Wait 10 minutes and try again"); + token.should.be.false(); + done(); + } catch(e) { + done(e); + } finally { + userAuthentication.restore(); + } + }); + }); + + }); +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/auth/tokens_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/auth/tokens_spec.js new file mode 100644 index 0000000..2b06932 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/auth/tokens_spec.js @@ -0,0 +1,181 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var when = require("when"); +var sinon = require("sinon"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var Tokens = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/tokens"); + + +describe("api/auth/tokens", function() { + describe("#init",function() { + it('loads sessions', function(done) { + Tokens.init({}).then(done); + }); + }); + + + describe("#get",function() { + it('returns a valid token', function(done) { + Tokens.init({},{ + getSessions:function() { + return when.resolve({"1234":{"user":"fred","expires":Date.now()+1000}}); + } + }).then(function() { + Tokens.get("1234").then(function(token) { + try { + token.should.have.a.property("user","fred"); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + + it('returns null for an invalid token', function(done) { + Tokens.init({},{ + getSessions:function() { + return when.resolve({}); + } + }).then(function() { + Tokens.get("1234").then(function(token) { + try { + should.not.exist(token); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + it('returns null for an expired token', function(done) { + var saveSessions = sinon.stub().returns(when.resolve()); + var expiryTime = Date.now()+50; + Tokens.init({},{ + getSessions:function() { + return when.resolve({"1234":{"user":"fred","expires":expiryTime}}); + }, + saveSessions: saveSessions + }).then(function() { + Tokens.get("1234").then(function(token) { + try { + should.exist(token); + setTimeout(function() { + Tokens.get("1234").then(function(token) { + try { + should.not.exist(token); + saveSessions.calledOnce.should.be.true(); + done(); + } catch(err) { + done(err); + } + }); + },100); + } catch(err) { + done(err); + } + }); + }); + }); + + it('returns a valid api token', function(done) { + Tokens.init({ + tokens: [{ + token: "1234", + user: "fred", + }] + },{ + getSessions:function() { + return when.resolve({}); + } + }).then(function() { + Tokens.get("1234").then(function(token) { + try { + token.should.have.a.property("user","fred"); + done(); + } catch(err) { + done(err); + } + }); + }); + + }); + }); + + describe("#create",function() { + it('creates a token', function(done) { + var savedSession; + Tokens.init({sessionExpiryTime: 10},{ + getSessions:function() { + return when.resolve({}); + }, + saveSessions:function(sess) { + savedSession = sess; + return when.resolve(); + } + }); + var expectedExpiryTime = Date.now()+10000; + + + Tokens.create("user","client","scope").then(function(token) { + try { + should.exist(savedSession); + var sessionKeys = Object.keys(savedSession); + sessionKeys.should.have.lengthOf(1); + + token.should.have.a.property('accessToken',sessionKeys[0]); + savedSession[sessionKeys[0]].should.have.a.property('user','user'); + savedSession[sessionKeys[0]].should.have.a.property('client','client'); + savedSession[sessionKeys[0]].should.have.a.property('scope','scope'); + savedSession[sessionKeys[0]].should.have.a.property('expires'); + savedSession[sessionKeys[0]].expires.should.be.within(expectedExpiryTime-200,expectedExpiryTime+200); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + + describe("#revoke", function() { + it('revokes a token', function(done) { + var savedSession; + Tokens.init({},{ + getSessions:function() { + return when.resolve({"1234":{"user":"fred","expires":Date.now()+1000}}); + }, + saveSessions:function(sess) { + savedSession = sess; + return when.resolve(); + } + }).then(function() { + Tokens.revoke("1234").then(function() { + try { + savedSession.should.not.have.a.property("1234"); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + }); + +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/auth/users_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/auth/users_spec.js new file mode 100644 index 0000000..515d230 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/auth/users_spec.js @@ -0,0 +1,230 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var when = require('when'); +var sinon = require('sinon'); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var Users = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/users"); + +describe("api/auth/users", function() { + after(function() { + Users.init({}); + }) + describe('Initalised with a credentials object, no anon',function() { + before(function() { + Users.init({ + type:"credentials", + users:{ + username:"fred", + password:'$2a$08$LpYMefvGZ3MjAfZGzcoyR.1BcfHh4wy4NpbN.cEny5aHnWOqjKOXK', + // 'password' -> require('bcryptjs').hashSync('password', 8); + permissions:"*" + } + }); + }); + describe('#get',function() { + it('returns known user',function(done) { + Users.get("fred").then(function(user) { + try { + user.should.have.a.property("username","fred"); + user.should.have.a.property("permissions","*"); + user.should.not.have.a.property("password"); + done(); + } catch(err) { + done(err); + } + }); + }); + + it('returns null for unknown user', function(done) { + Users.get("barney").then(function(user) { + try { + should.not.exist(user); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + + describe('#default',function() { + it('returns null for default user', function(done) { + Users.default().then(function(user) { + try { + should.not.exist(user); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + + describe('#authenticate',function() { + it('authenticates a known user', function(done) { + Users.authenticate('fred','password').then(function(user) { + try { + user.should.have.a.property("username","fred"); + user.should.have.a.property("permissions","*"); + user.should.not.have.a.property("password"); + done(); + } catch(err) { + done(err); + } + }); + }); + it('rejects invalid password for a known user', function(done) { + Users.authenticate('fred','wrong').then(function(user) { + try { + should.not.exist(user); + done(); + } catch(err) { + done(err); + } + }); + }); + + it('rejects invalid user', function(done) { + Users.authenticate('barney','wrong').then(function(user) { + try { + should.not.exist(user); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + }); + + describe('Initalised with a credentials object including anon',function() { + before(function() { + Users.init({ + type:"credentials", + users:[], + default: { permissions: "*" } + }); + }); + describe('#default',function() { + it('returns default user', function(done) { + Users.default().then(function(user) { + try { + user.should.have.a.property('anonymous',true); + user.should.have.a.property('permissions','*'); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + }); + + describe('Initialised with a credentials object with user functions',function() { + var authUsername = ''; + var authPassword = ''; + before(function() { + Users.init({ + type:"credentials", + users:function(username) { + return when.resolve({'username':'dave','permissions':'read'}); + }, + authenticate: function(username,password) { + authUsername = username; + authPassword = password; + return when.resolve({'username':'pete','permissions':'write'}); + } + }); + }); + + describe('#get',function() { + it('delegates get user',function(done) { + Users.get('dave').then(function(user) { + try { + user.should.have.a.property("username","dave"); + user.should.have.a.property("permissions","read"); + user.should.not.have.a.property("password"); + done(); + } catch(err) { + done(err); + } + }); + }); + it('delegates authenticate user',function(done) { + Users.authenticate('pete','secret').then(function(user) { + try { + user.should.have.a.property("username","pete"); + user.should.have.a.property("permissions","write"); + user.should.not.have.a.property("password"); + authUsername.should.equal('pete'); + authPassword.should.equal('secret'); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + }); + + describe('Initialised with bad settings to test else cases',function() { + before(function() { + Users.init({ + type:"foo", + users:{ + username:"fred", + password:'$2a$08$LpYMefvGZ3MjAfZGzcoyR.1BcfHh4wy4NpbN.cEny5aHnWOqjKOXK', + permissions:"*" + } + }); + }); + describe('#get',function() { + it('should fail to return user fred',function(done) { + Users.get("fred").then(function(userf) { + try { + should.not.exist(userf); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + }); + + describe('Initialised with default set as function',function() { + before(function() { + Users.init({ + type:"credentials", + default: function() { return("Done"); } + }); + }); + after(function() { + Users.init({}); + }); + describe('#default',function() { + it('handles api.default being a function',function(done) { + Users.should.have.property('default').which.is.a.Function(); + (Users.default()).should.equal("Done"); + done(); + }); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/editor/comms_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/editor/comms_spec.js new file mode 100644 index 0000000..7237850 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/editor/comms_spec.js @@ -0,0 +1,496 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); +const stoppable = require('stoppable'); + +var when = require("when"); +var http = require('http'); +var express = require('express'); +var app = express(); +var WebSocket = require('ws'); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var comms = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/comms"); +var Users = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/users"); +var Tokens = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth/tokens"); + +var address = '127.0.0.1'; +var listenPort = 0; // use ephemeral port + + +describe("api/editor/comms", function() { + var connections = []; + var mockComms = { + addConnection: function(opts) { + connections.push(opts.client); + return Promise.resolve() + }, + removeConnection: function(opts) { + for (var i=0;i<connections.length;i++) { + if (connections[i] === opts.client) { + connections.splice(i,1); + break; + } + } + return Promise.resolve() + }, + subscribe: function() { return Promise.resolve()}, + unsubscribe: function() { return Promise.resolve(); } + } + + describe("with default keepalive", function() { + var server; + var url; + var port; + before(function(done) { + sinon.stub(Users,"default",function() { return when.resolve(null);}); + server = stoppable(http.createServer(function(req,res){app(req,res)})); + comms.init(server, {}, {comms: mockComms}); + server.listen(listenPort, address); + server.on('listening', function() { + port = server.address().port; + url = 'http://' + address + ':' + port + '/comms'; + comms.start(); + done(); + }); + }); + + after(function(done) { + Users.default.restore(); + comms.stop(); + server.stop(done); + }); + + it('accepts connection', function(done) { + var ws = new WebSocket(url); + connections.length.should.eql(0); + ws.on('open', function() { + try { + connections.length.should.eql(1); + ws.close(); + done(); + } catch(err) { + done(err); + } + }); + }); + + it('publishes message after subscription', function(done) { + var ws = new WebSocket(url); + ws.on('open', function() { + ws.send('{"subscribe":"topic1"}'); + connections.length.should.eql(1); + connections[0].send('topic1', 'foo'); + }); + ws.on('message', function(msg) { + msg.should.equal('[{"topic":"topic1","data":"foo"}]'); + ws.close(); + done(); + }); + }); + + it('malformed messages are ignored',function(done) { + var ws = new WebSocket(url); + ws.on('open', function() { + ws.send('not json'); + ws.send('[]'); + ws.send('{"subscribe":"topic3"}'); + connections[0].send('topic3', 'correct'); + }); + ws.on('message', function(msg) { + console.log(msg); + msg.should.equal('[{"topic":"topic3","data":"correct"}]'); + ws.close(); + done(); + }); + }); + }); + + describe("disabled editor", function() { + var server; + var url; + var port; + before(function(done) { + sinon.stub(Users,"default",function() { return Promise.resolve(null);}); + server = stoppable(http.createServer(function(req,res){app(req,res)})); + comms.init(server, {disableEditor:true}, {comms: mockComms}); + server.listen(listenPort, address); + server.on('listening', function() { + port = server.address().port; + url = 'http://' + address + ':' + port + '/comms'; + comms.start(); + done(); + }); + }); + + after(function(done) { + Users.default.restore(); + comms.stop(); + server.stop(done); + }); + + it('rejects websocket connections',function(done) { + connections.length.should.eql(0); + var ws = new WebSocket(url); + ws.on('open', function() { + done(new Error("Socket connection unexpectedly accepted")); + ws.close(); + }); + ws.on('error', function() { + connections.length.should.eql(0); + done(); + }); + + }); + }); + + describe("non-default httpAdminRoot set: /adminPath", function() { + var server; + var url; + var port; + before(function(done) { + sinon.stub(Users,"default",function() { return when.resolve(null);}); + server = stoppable(http.createServer(function(req,res){app(req,res)})); + comms.init(server, {httpAdminRoot:"/adminPath"}, {comms: mockComms}); + server.listen(listenPort, address); + server.on('listening', function() { + port = server.address().port; + url = 'http://' + address + ':' + port + '/adminPath/comms'; + comms.start(); + done(); + }); + }); + + after(function(done) { + Users.default.restore(); + comms.stop(); + server.stop(done); + }); + + it('accepts connections',function(done) { + connections.length.should.eql(0); + var ws = new WebSocket(url); + ws.on('open', function() { + connections.length.should.eql(1); + ws.close(); + done(); + }); + ws.on('error', function() { + done(new Error("Socket connection failed")); + }); + + }); + }); + + describe("non-default httpAdminRoot set: /adminPath/", function() { + var server; + var url; + var port; + before(function(done) { + sinon.stub(Users,"default",function() { return when.resolve(null);}); + server = stoppable(http.createServer(function(req,res){app(req,res)})); + comms.init(server, {httpAdminRoot:"/adminPath/"}, {comms: mockComms}); + server.listen(listenPort, address); + server.on('listening', function() { + port = server.address().port; + url = 'http://' + address + ':' + port + '/adminPath/comms'; + comms.start(); + done(); + }); + }); + + after(function(done) { + Users.default.restore(); + comms.stop(); + server.stop(done); + }); + + it('accepts connections',function(done) { + connections.length.should.eql(0); + var ws = new WebSocket(url); + ws.on('open', function() { + connections.length.should.eql(1); + ws.close(); + done(); + }); + ws.on('error', function() { + done(new Error("Socket connection failed")); + }); + + }); + }); + + describe("non-default httpAdminRoot set: adminPath", function() { + var server; + var url; + var port; + before(function(done) { + sinon.stub(Users,"default",function() { return when.resolve(null);}); + server = stoppable(http.createServer(function(req,res){app(req,res)})); + comms.init(server, {httpAdminRoot:"adminPath"}, {comms: mockComms}); + server.listen(listenPort, address); + server.on('listening', function() { + port = server.address().port; + url = 'http://' + address + ':' + port + '/adminPath/comms'; + comms.start(); + done(); + }); + }); + + after(function(done) { + Users.default.restore(); + comms.stop(); + server.stop(done); + }); + + it('accepts connections',function(done) { + connections.length.should.eql(0); + var ws = new WebSocket(url); + ws.on('open', function() { + connections.length.should.eql(1); + ws.close(); + done(); + }); + ws.on('error', function() { + done(new Error("Socket connection failed")); + }); + + }); + }); + + describe("keep alives", function() { + var server; + var url; + var port; + before(function(done) { + sinon.stub(Users,"default",function() { return when.resolve(null);}); + server = stoppable(http.createServer(function(req,res){app(req,res)})); + comms.init(server, {webSocketKeepAliveTime: 100}, {comms: mockComms}); + server.listen(listenPort, address); + server.on('listening', function() { + port = server.address().port; + url = 'http://' + address + ':' + port + '/comms'; + comms.start(); + done(); + }); + }); + after(function(done) { + Users.default.restore(); + comms.stop(); + server.stop(done); + }); + it('are sent', function(done) { + var ws = new WebSocket(url); + var count = 0; + ws.on('message', function(data) { + var msg = JSON.parse(data)[0]; + msg.should.have.property('topic','hb'); + msg.should.have.property('data').be.a.Number(); + count++; + if (count == 3) { + ws.close(); + done(); + } + }); + }); + it('are not sent if other messages are sent', function(done) { + var ws = new WebSocket(url); + var count = 0; + var interval; + ws.on('open', function() { + ws.send('{"subscribe":"foo"}'); + interval = setInterval(function() { + connections[0].send('foo', 'bar'); + }, 50); + }); + ws.on('message', function(data) { + var msg = JSON.parse(data)[0]; + // It is possible a heartbeat message may arrive - so ignore them + if (msg.topic != "hb") { + msg.should.have.property('topic', 'foo'); + msg.should.have.property('data', 'bar'); + count++; + if (count == 5) { + clearInterval(interval); + ws.close(); + done(); + } + } + }); + }); + }); + + describe('authentication required, no anonymous',function() { + var server; + var url; + var port; + var getDefaultUser; + var getUser; + var getToken; + before(function(done) { + getDefaultUser = sinon.stub(Users,"default",function() { return when.resolve(null);}); + getUser = sinon.stub(Users,"get", function(username) { + if (username == "fred") { + return when.resolve({permissions:"read"}); + } else { + return when.resolve(null); + } + }); + getToken = sinon.stub(Tokens,"get",function(token) { + if (token == "1234") { + return when.resolve({user:"fred",scope:["*"]}); + } else if (token == "5678") { + return when.resolve({user:"barney",scope:["*"]}); + } else { + return when.resolve(null); + } + }); + + + server = stoppable(http.createServer(function(req,res){app(req,res)})); + comms.init(server, {adminAuth:{}}, {comms: mockComms}); + server.listen(listenPort, address); + server.on('listening', function() { + port = server.address().port; + url = 'http://' + address + ':' + port + '/comms'; + comms.start(); + done(); + }); + }); + after(function(done) { + getDefaultUser.restore(); + getUser.restore(); + getToken.restore(); + comms.stop(); + server.stop(done); + }); + + it('prevents connections that do not authenticate',function(done) { + var ws = new WebSocket(url); + var count = 0; + var interval; + ws.on('open', function() { + ws.send('{"subscribe":"foo"}'); + }); + ws.on('close', function() { + done(); + }); + }); + + it('allows connections that do authenticate',function(done) { + var ws = new WebSocket(url); + var received = 0; + ws.on('open', function() { + ws.send('{"auth":"1234"}'); + }); + ws.on('message', function(msg) { + received++; + if (received == 1) { + msg.should.equal('{"auth":"ok"}'); + ws.send('{"subscribe":"foo"}'); + connections[0].send('foo', 'correct'); + } else { + msg.should.equal('[{"topic":"foo","data":"correct"}]'); + ws.close(); + } + }); + + ws.on('close', function() { + try { + received.should.equal(2); + done(); + } catch(err) { + done(err); + } + }); + }); + + it('rejects connections for non-existant token',function(done) { + var ws = new WebSocket(url); + var received = 0; + ws.on('open', function() { + ws.send('{"auth":"2345"}'); + }); + ws.on('close', function() { + done(); + }); + }); + it('rejects connections for invalid token',function(done) { + var ws = new WebSocket(url); + var received = 0; + ws.on('open', function() { + ws.send('{"auth":"5678"}'); + }); + ws.on('close', function() { + done(); + }); + }); + }); + + describe('authentication required, anonymous enabled',function() { + var server; + var url; + var port; + var getDefaultUser; + before(function(done) { + getDefaultUser = sinon.stub(Users,"default",function() { return when.resolve({permissions:"read"});}); + server = stoppable(http.createServer(function(req,res){app(req,res)})); + comms.init(server, {adminAuth:{}}, {comms: mockComms}); + server.listen(listenPort, address); + server.on('listening', function() { + port = server.address().port; + url = 'http://' + address + ':' + port + '/comms'; + comms.start(); + done(); + }); + }); + after(function(done) { + getDefaultUser.restore(); + comms.stop(); + server.stop(done); + }); + + it('allows anonymous connections that do not authenticate',function(done) { + var ws = new WebSocket(url); + var count = 0; + var interval; + ws.on('open', function() { + ws.send('{"subscribe":"foo"}'); + setTimeout(function() { + connections[0].send('foo', 'correct'); + },200); + }); + ws.on('message', function(msg) { + msg.should.equal('[{"topic":"foo","data":"correct"}]'); + count++; + ws.close(); + }); + ws.on('close', function() { + try { + count.should.equal(1); + done(); + } catch(err) { + done(err); + } + }); + }); + }); + + +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/editor/credentials_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/editor/credentials_spec.js new file mode 100644 index 0000000..2fc1ea5 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/editor/credentials_spec.js @@ -0,0 +1,95 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var request = require('supertest'); +var express = require('express'); +var sinon = require('sinon'); +var when = require('when'); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var credentials = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/credentials"); + +describe('api/editor/credentials', function() { + var app; + + before(function() { + app = express(); + app.get('/credentials/:type/:id',credentials.get); + credentials.init({ + flows: { + getNodeCredentials: function(opts) { + if (opts.type === "known-type" && opts.id === "n1") { + return Promise.resolve({ + user1:"abc", + has_password1: true + }); + } else { + var err = new Error("message"); + err.code = "test_code"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } + } + } + }); + }); + + it('returns stored credentials',function(done) { + request(app) + .get("/credentials/known-type/n1") + .expect("Content-Type",/json/) + .expect(200) + .end(function(err,res) { + if (err) { + done(err); + } else { + try { + res.body.should.have.a.property("user1","abc"); + res.body.should.not.have.a.property("password1"); + res.body.should.have.a.property("has_password1",true); + done(); + } catch(e) { + done(e); + } + } + }) + }); + it('returns any error',function(done) { + request(app) + .get("/credentials/unknown-type/n2") + .expect("Content-Type",/json/) + .expect(400) + .end(function(err,res) { + if (err) { + done(err); + } else { + try { + res.body.should.have.property('code'); + res.body.code.should.be.equal("test_code"); + res.body.should.have.property('message'); + res.body.message.should.be.equal('message'); + done(); + } catch(e) { + done(e); + } + } + }) + }); + +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/editor/index_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/editor/index_spec.js new file mode 100644 index 0000000..e45fcbd --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/editor/index_spec.js @@ -0,0 +1,136 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); +var request = require("supertest"); +var express = require("express"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var editorApi = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor"); +var comms = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/comms"); +var info = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/settings"); +var auth = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth"); + +var log = NR_TEST_UTILS.require("@node-red/util").log; + + +var when = require("when"); + + +describe("api/editor/index", function() { + var app; + describe("disabled the editor", function() { + beforeEach(function() { + sinon.stub(comms,'init', function(){}); + sinon.stub(info,'init', function(){}); + }); + afterEach(function() { + comms.init.restore(); + info.init.restore(); + }); + it("disables the editor", function() { + var editorApp = editorApi.init({},{disableEditor:true},{}); + should.not.exist(editorApp); + comms.init.called.should.be.false(); + info.init.called.should.be.false(); + }); + }); + describe("enables the editor", function() { + var mockList = [ + 'library','theme','locales','credentials','comms',"settings" + ] + var isStarted = true; + var errors = []; + var session_data = {}; + before(function() { + sinon.stub(auth,'needsPermission',function(permission) { + return function(req,res,next) { next(); } + }); + mockList.forEach(function(m) { + sinon.stub(NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/"+m),"init",function(){}); + }); + sinon.stub(NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/theme"),"app",function(){ return express()}); + }); + after(function() { + mockList.forEach(function(m) { + NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/"+m).init.restore(); + }) + NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/theme").app.restore(); + auth.needsPermission.restore(); + log.error.restore(); + }); + + before(function() { + sinon.stub(log,"error",function(err) { errors.push(err)}) + app = editorApi.init({},{httpNodeRoot:true, httpAdminRoot: true,disableEditor:false,exportNodeSettings:function(){}},{ + isStarted: () => Promise.resolve(isStarted) + }); + }); + it('serves the editor', function(done) { + request(app) + .get("/") + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + // Index page should probably mention Node-RED somewhere + res.text.indexOf("Node-RED").should.not.eql(-1); + done(); + }); + }); + it('serves icons', function(done) { + request(app) + .get("/red/images/icons/arrow-in.svg") + .expect(200) + .expect("Content-Type", /image\/svg\+xml/) + .end(function(err,res) { + done(err); + }); + }); + it('handles page not there', function(done) { + request(app) + .get("/foo") + .expect(404,done) + }); + it('warns if runtime not started', function(done) { + isStarted = false; + request(app) + .get("/") + .expect(503) + .end(function(err,res) { + if (err) { + return done(err); + } + res.text.should.eql("Not started"); + errors.should.have.lengthOf(1); + errors[0].should.eql("Node-RED runtime not started"); + done(); + }); + }); + // it.skip('GET /settings', function(done) { + // request(app).get("/settings").expect(200).end(function(err,res) { + // if (err) { + // return done(err); + // } + // // permissionChecks.should.have.property('settings.read',1); + // done(); + // }) + // }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/editor/library_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/editor/library_spec.js new file mode 100644 index 0000000..4a2c281 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/editor/library_spec.js @@ -0,0 +1,263 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); +var request = require('supertest'); +var express = require('express'); +var bodyParser = require('body-parser'); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var library = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/library"); + +var app; + +describe("api/editor/library", function() { + + before(function() { + app = express(); + app.use(bodyParser.json()); + app.get(/library\/([^\/]+)\/([^\/]+)(?:$|\/(.*))/,library.getEntry); + app.post(/library\/([^\/]+)\/([^\/]+)\/(.*)/,library.saveEntry); + }); + after(function() { + }); + + it('returns an individual entry - flow type', function(done) { + var opts; + library.init({ + library: { + getEntry: function(_opts) { + opts = _opts; + return Promise.resolve('{"a":1,"b":2}'); + } + } + }); + request(app) + .get('/library/local/flows/abc') + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('a',1); + res.body.should.have.property('b',2); + opts.should.have.property('library','local'); + opts.should.have.property('type','flows'); + opts.should.have.property('path','abc'); + done(); + }); + }) + it('returns a directory listing - flow type', function(done) { + var opts; + library.init({ + library: { + getEntry: function(_opts) { + opts = _opts; + return Promise.resolve({"a":1,"b":2}); + } + } + }); + request(app) + .get('/library/local/flows/abc/def') + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('a',1); + res.body.should.have.property('b',2); + opts.should.have.property('library','local'); + opts.should.have.property('type','flows'); + opts.should.have.property('path','abc/def'); + done(); + }); + }) + it('returns an individual entry - non-flow type', function(done) { + var opts; + library.init({ + library: { + getEntry: function(_opts) { + opts = _opts; + return Promise.resolve('{"a":1,"b":2}'); + } + } + }); + request(app) + .get('/library/local/non-flow/abc') + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + opts.should.have.property('library','local'); + opts.should.have.property('type','non-flow'); + opts.should.have.property('path','abc'); + res.text.should.eql('{"a":1,"b":2}'); + done(); + }); + }) + it('returns a directory listing - non-flow type', function(done) { + var opts; + library.init({ + library: { + getEntry: function(_opts) { + opts = _opts; + return Promise.resolve({"a":1,"b":2}); + } + } + }); + request(app) + .get('/library/local/non-flow/abc/def') + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('a',1); + res.body.should.have.property('b',2); + opts.should.have.property('library','local'); + opts.should.have.property('type','non-flow'); + opts.should.have.property('path','abc/def'); + done(); + }); + }) + + it('returns an error on individual get', function(done) { + var opts; + library.init({ + library: { + getEntry: function(_opts) { + opts = _opts; + var err = new Error("message"); + err.code = "random_error"; + err.status = 400; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } + } + }); + request(app) + .get('/library/local/flows/123') + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + opts.should.have.property('library','local'); + opts.should.have.property('type','flows'); + opts.should.have.property('path','123'); + + res.body.should.have.property('code'); + res.body.code.should.be.equal("random_error"); + res.body.should.have.property('message'); + res.body.message.should.be.equal("message"); + done(); + }); + }); + + + it('saves an individual entry - flow type', function(done) { + var opts; + library.init({ + library: { + saveEntry: function(_opts) { + opts = _opts; + return Promise.resolve(); + } + } + }); + request(app) + .post('/library/local/flows/abc/def') + .expect(204) + .send({a:1,b:2,c:3}) + .end(function(err,res) { + if (err) { + return done(err); + } + opts.should.have.property('library','local'); + opts.should.have.property('type','flows'); + opts.should.have.property('path','abc/def'); + opts.should.have.property('meta',{}); + opts.should.have.property('body',JSON.stringify({a:1,b:2,c:3})); + done(); + }); + }) + + it('saves an individual entry - non-flow type', function(done) { + var opts; + library.init({ + library: { + saveEntry: function(_opts) { + opts = _opts; + return Promise.resolve(); + } + } + }); + request(app) + .post('/library/local/non-flow/abc/def') + .expect(204) + .send({a:1,b:2,text:"123"}) + .end(function(err,res) { + if (err) { + return done(err); + } + opts.should.have.property('library','local'); + opts.should.have.property('type','non-flow'); + opts.should.have.property('path','abc/def'); + opts.should.have.property('meta',{a:1,b:2}); + opts.should.have.property('body',"123"); + done(); + }); + }) + + it('returns an error on individual save', function(done) { + var opts; + library.init({ + library: { + saveEntry: function(_opts) { + opts = _opts; + var err = new Error("message"); + err.code = "random_error"; + err.status = 400; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } + } + }); + request(app) + .post('/library/local/non-flow/abc/def') + .send({a:1,b:2,text:"123"}) + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + opts.should.have.property('type','non-flow'); + opts.should.have.property('library','local'); + opts.should.have.property('path','abc/def'); + + res.body.should.have.property('code'); + res.body.code.should.be.equal("random_error"); + res.body.should.have.property('message'); + res.body.message.should.be.equal("message"); + done(); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/editor/locales_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/editor/locales_spec.js new file mode 100644 index 0000000..2de9d47 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/editor/locales_spec.js @@ -0,0 +1,165 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var request = require('supertest'); +var express = require('express'); +var sinon = require('sinon'); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var locales = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/locales"); +var i18n = NR_TEST_UTILS.require("@node-red/util").i18n; + +describe("api/editor/locales", function() { + beforeEach(function() { + }) + afterEach(function() { + }) + describe('get named resource catalog',function() { + var app; + before(function() { + // locales.init({ + // i18n: { + // i: { + // language: function() { return 'en-US'}, + // changeLanguage: function(lang,callback) { + // if (callback) { + // callback(); + // } + // }, + // getResourceBundle: function(lang, namespace) { + // return {namespace:namespace, lang:lang}; + // } + // }, + // } + // }); + locales.init({}); + + // bit of a mess of internal workings + sinon.stub(i18n.i,'changeLanguage',function(lang,callback) { if (callback) {callback();}}); + if (i18n.i.getResourceBundle) { + sinon.stub(i18n.i,'getResourceBundle',function(lang, namespace) {return {namespace:namespace, lang:lang};}); + } else { + // If i18n.init has not been called, then getResourceBundle isn't + // defined - so hardcode a stub + i18n.i.getResourceBundle = function(lang, namespace) {return {namespace:namespace, lang:lang};}; + i18n.i.getResourceBundle.restore = function() { delete i18n.i.getResourceBundle }; + } + app = express(); + app.get(/locales\/(.+)\/?$/,locales.get); + }); + after(function() { + i18n.i.changeLanguage.restore(); + i18n.i.getResourceBundle.restore(); + }) + it('returns with default language', function(done) { + request(app) + .get("/locales/message-catalog") + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('namespace','message-catalog'); + done(); + }); + }); + it('returns with selected language', function(done) { + request(app) + .get("/locales/message-catalog?lng=fr-FR") + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('namespace','message-catalog'); + res.body.should.have.property('lang','fr-FR'); + done(); + }); + }); + + it('returns for locale defined only with primary tag ', function(done) { + var orig = i18n.i.getResourceBundle; + i18n.i.getResourceBundle = function (lang, ns) { + if (lang === "ja-JP") { + return undefined; + } + return orig(lang, ns); + }; + request(app) + // returns `ja` instead of `ja-JP` + .get("/locales/message-catalog?lng=ja-JP") + .expect(200) + .end(function(err,res) { + i18n.i.getResourceBundle = orig; + if (err) { + return done(err); + } + res.body.should.have.property('namespace','message-catalog'); + res.body.should.have.property('lang','ja'); + done(); + }); + }); + + }); + + // describe('get all node resource catalogs',function() { + // var app; + // before(function() { + // // bit of a mess of internal workings + // sinon.stub(i18n,'catalog',function(namespace, lang) { + // return { + // "node-red": "should not return", + // "test-module-a-id": "test-module-a-catalog", + // "test-module-b-id": "test-module-b-catalog", + // "test-module-c-id": "test-module-c-catalog" + // }[namespace] + // }); + // locales.init({ + // nodes: { + // getNodeList: function(opts) { + // return Promise.resolve([ + // {module:"node-red",id:"node-red-id"}, + // {module:"test-module-a",id:"test-module-a-id"}, + // {module:"test-module-b",id:"test-module-b-id"} + // ]); + // } + // } + // }); + // app = express(); + // app.get("/locales/nodes",locales.getAllNodes); + // }); + // after(function() { + // i18n.catalog.restore(); + // }) + // it('returns with the node catalogs', function(done) { + // request(app) + // .get("/locales/nodes") + // .expect(200) + // .end(function(err,res) { + // if (err) { + // return done(err); + // } + // res.body.should.eql({ + // 'test-module-a-id': 'test-module-a-catalog', + // 'test-module-b-id': 'test-module-b-catalog' + // }); + // done(); + // }); + // }); + // }); +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/editor/projects_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/editor/projects_spec.js new file mode 100644 index 0000000..52b88d0 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/editor/projects_spec.js @@ -0,0 +1,21 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var NR_TEST_UTILS = require("nr-test-utils"); + +describe("api/editor/projects", function() { + it.skip("NEEDS TESTS WRITING",function() {}); +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/editor/settings_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/editor/settings_spec.js new file mode 100644 index 0000000..8fcdbeb --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/editor/settings_spec.js @@ -0,0 +1,123 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var request = require('supertest'); +var express = require('express'); +var bodyParser = require("body-parser"); +var sinon = require('sinon'); + +var app; + +var NR_TEST_UTILS = require("nr-test-utils"); + +var info = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/settings"); +var theme = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/theme"); + +describe("api/editor/settings", function() { + before(function() { + sinon.stub(theme,"settings",function() { return { existing: 123, test: 456 };}); + app = express(); + app.use(bodyParser.json()); + app.get("/settings",info.runtimeSettings); + app.get("/settings/user",function(req,res,next) {req.user = "fred"; next()}, info.userSettings); + app.post("/settings/user",function(req,res,next) {req.user = "fred"; next()},info.updateUserSettings); + }); + + after(function() { + theme.settings.restore(); + }); + + it('returns the runtime settings', function(done) { + info.init({ + settings: { + getRuntimeSettings: function(opts) { + return Promise.resolve({ + a:1, + b:2, + editorTheme: { existing: 789 } + }) + } + } + }); + request(app) + .get("/settings") + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property("a",1); + res.body.should.have.property("b",2); + res.body.should.have.property("editorTheme",{existing: 789, test:456}); + done(); + }); + }); + it('returns the user settings', function(done) { + info.init({ + settings: { + getUserSettings: function(opts) { + if (opts.user !== "fred") { + return Promise.reject(new Error("Unknown user")); + } + return Promise.resolve({ + c:3, + d:4 + }) + } + } + }); + request(app) + .get("/settings/user") + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.eql({c:3,d:4}); + done(); + }); + }); + it('updates the user settings', function(done) { + var update; + info.init({ + settings: { + updateUserSettings: function(opts) { + if (opts.user !== "fred") { + return Promise.reject(new Error("Unknown user")); + } + update = opts.settings; + return Promise.resolve() + } + } + }); + request(app) + .post("/settings/user") + .send({ + e:4, + f:5 + }) + .expect(204) + .end(function(err,res) { + if (err) { + return done(err); + } + update.should.eql({e:4,f:5}); + done(); + }); + }); + +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/editor/sshkeys_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/editor/sshkeys_spec.js new file mode 100644 index 0000000..1647cd9 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/editor/sshkeys_spec.js @@ -0,0 +1,333 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); +var request = require("supertest"); +var express = require("express"); +var NR_TEST_UTILS = require("nr-test-utils"); +var sshkeys = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/sshkeys"); +var bodyParser = require("body-parser"); + + +describe("api/editor/sshkeys", function() { + var app; + var mockRuntime = { + settings: { + getUserKeys: function() {}, + getUserKey: function() {}, + generateUserKey: function() {}, + removeUserKey: function() {} + } + } + before(function() { + sshkeys.init(mockRuntime); + app = express(); + app.use(bodyParser.json()); + app.use("/settings/user/keys", sshkeys.app()); + }); + + beforeEach(function() { + sinon.stub(mockRuntime.settings, "getUserKeys"); + sinon.stub(mockRuntime.settings, "getUserKey"); + sinon.stub(mockRuntime.settings, "generateUserKey"); + sinon.stub(mockRuntime.settings, "removeUserKey"); + }) + afterEach(function() { + mockRuntime.settings.getUserKeys.restore(); + mockRuntime.settings.getUserKey.restore(); + mockRuntime.settings.generateUserKey.restore(); + mockRuntime.settings.removeUserKey.restore(); + }) + + it('GET /settings/user/keys --- return empty list', function(done) { + mockRuntime.settings.getUserKeys.returns(Promise.resolve([])); + request(app) + .get("/settings/user/keys") + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('keys'); + res.body.keys.should.be.empty(); + done(); + }); + }); + + it('GET /settings/user/keys --- return normal list', function(done) { + var fileList = [ + 'test_key01', + 'test_key02' + ]; + var retList = fileList.map(function(elem) { + return { + name: elem + }; + }); + mockRuntime.settings.getUserKeys.returns(Promise.resolve(retList)); + request(app) + .get("/settings/user/keys") + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('keys'); + for (var item of retList) { + res.body.keys.should.containEql(item); + } + done(); + }); + }); + + it('GET /settings/user/keys --- return Error', function(done) { + var errInstance = new Error("Messages here....."); + errInstance.code = "test_code"; + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.settings.getUserKeys.returns(p); + request(app) + .get("/settings/user/keys") + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('code'); + res.body.code.should.be.equal(errInstance.code); + res.body.should.have.property('message'); + res.body.message.should.be.equal(errInstance.message); + done(); + }); + }); + + it('GET /settings/user/keys/<key_file_name> --- return 404', function(done) { + var errInstance = new Error("Not Found."); + errInstance.code = "not_found"; + errInstance.status = 404; + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.settings.getUserKey.returns(p); + request(app) + .get("/settings/user/keys/NOT_REAL") + .expect(404) + .end(function(err,res) { + if (err) { + return done(err); + } + done(); + }); + }); + it('GET /settings/user/keys --- return Unexpected Error', function(done) { + var errInstance = new Error(); + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.settings.getUserKeys.returns(p) + request(app) + .get("/settings/user/keys") + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('code'); + res.body.code.should.be.equal("unexpected_error"); + res.body.should.have.property('message'); + res.body.message.should.be.equal(errInstance.toString()); + done(); + }); + }); + + it('GET /settings/user/keys/<key_file_name> --- return content', function(done) { + var key_file_name = "test_key"; + var fileContent = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD3a+sgtgzSbbliWxmOq5p6+H/mE+0gjWfLWrkIVmHENd1mifV4uCmIHAR2NfuadUYMQ3+bQ90kpmmEKTMYPsyentsKpHQZxTzG7wOCAIpJnbPTHDMxEJhVTaAwEjbVyMSIzTTPfnhoavWIBu0+uMgKDDlBm+RjlgkFlyhXyCN6UwFrIUUMH6Gw+eQHLiooKIl8ce7uDxIlt+9b7hFCU+sQ3kvuse239DZluu6+8buMWqJvrEHgzS9adRFKku8nSPAEPYn85vDi7OgVAcLQufknNgs47KHBAx9h04LeSrFJ/P5J1b//ItRpMOIme+O9d1BR46puzhvUaCHLdvO9czj+OmW+dIm+QIk6lZIOOMnppG72kZxtLfeKT16ur+2FbwAdL9ItBp4BI/YTlBPoa5mLMxpuWfmX1qHntvtGc9wEwS1P7YFfmF3XiK5apxalzrn0Qlr5UmDNbVIqJb1OlbC0w03Z0oktti1xT+R2DGOLWM4lBbpXDHV1BhQ7oYOvbUD8Cnof55lTP0WHHsOHlQc/BGDti1XA9aBX/OzVyzBUYEf0pkimsD0RYo6aqt7QwehJYdlz9x1NBguBffT0s4NhNb9IWr+ASnFPvNl2sw4XH/8U0J0q8ZkMpKkbLM1Zdp1Fv00GF0f5UNRokai6uM3w/ccantJ3WvZ6GtctqytWrw== \n"; + mockRuntime.settings.getUserKey.returns(Promise.resolve(fileContent)); + request(app) + .get("/settings/user/keys/" + key_file_name) + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + mockRuntime.settings.getUserKey.called.should.be.true(); + mockRuntime.settings.getUserKey.firstCall.args[0].should.eql({ user: undefined, id: 'test_key' }); + res.body.should.be.deepEqual({ publickey: fileContent }); + done(); + }); + }); + + it('GET /settings/user/keys/<key_file_name> --- return Error', function(done) { + var key_file_name = "test_key"; + var errInstance = new Error("Messages....."); + errInstance.code = "test_code"; + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.settings.getUserKey.returns(p); + request(app) + .get("/settings/user/keys/" + key_file_name) + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('code'); + res.body.code.should.be.equal(errInstance.code); + res.body.should.have.property('message'); + res.body.message.should.be.equal(errInstance.message); + done(); + }); + }); + + it('GET /settings/user/keys/<key_file_name> --- return Unexpected Error', function(done) { + var key_file_name = "test_key"; + var errInstance = new Error("Messages....."); + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.settings.getUserKey.returns(p); + request(app) + .get("/settings/user/keys/" + key_file_name) + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('code'); + res.body.code.should.be.equal("unexpected_error"); + res.body.should.have.property('message'); + res.body.message.should.be.equal("Messages....."); + done(); + }); + }); + + it('POST /settings/user/keys --- success', function(done) { + var key_file_name = "test_key"; + mockRuntime.settings.generateUserKey.returns(Promise.resolve(key_file_name)); + request(app) + .post("/settings/user/keys") + .send({ name: key_file_name }) + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + done(); + }); + }); + + it('POST /settings/user/keys --- return Error', function(done) { + var key_file_name = "test_key"; + var errInstance = new Error("Messages....."); + errInstance.code = "test_code"; + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.settings.generateUserKey.returns(p); + request(app) + .post("/settings/user/keys") + .send({ name: key_file_name }) + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('code'); + res.body.code.should.be.equal("test_code"); + res.body.should.have.property('message'); + res.body.message.should.be.equal(errInstance.message); + done(); + }); + }); + + it('POST /settings/user/keys --- return Unexpected error', function(done) { + var key_file_name = "test_key"; + var errInstance = new Error("Messages....."); + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.settings.generateUserKey.returns(p); + request(app) + .post("/settings/user/keys") + .send({ name: key_file_name }) + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('code'); + res.body.code.should.be.equal("unexpected_error"); + res.body.should.have.property('message'); + res.body.message.should.be.equal("Messages....."); + done(); + }); + }); + + it('DELETE /settings/user/keys/<key_file_name> --- success', function(done) { + var key_file_name = "test_key"; + mockRuntime.settings.removeUserKey.returns(Promise.resolve(true)); + request(app) + .delete("/settings/user/keys/" + key_file_name) + .expect(204) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.be.deepEqual({}); + done(); + }); + }); + + it('DELETE /settings/user/keys/<key_file_name> --- return Error', function(done) { + var key_file_name = "test_key"; + var errInstance = new Error("Messages....."); + errInstance.code = "test_code"; + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.settings.removeUserKey.returns(p); + request(app) + .delete("/settings/user/keys/" + key_file_name) + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('code'); + res.body.code.should.be.equal("test_code"); + res.body.should.have.property('message'); + res.body.message.should.be.equal(errInstance.message); + done(); + }); + }); + + it('DELETE /settings/user/keys/<key_file_name> --- return Unexpected Error', function(done) { + var key_file_name = "test_key"; + var errInstance = new Error("Messages....."); + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.settings.removeUserKey.returns(p); + request(app) + .delete("/settings/user/keys/" + key_file_name) + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('code'); + res.body.code.should.be.equal("unexpected_error"); + res.body.should.have.property('message'); + res.body.message.should.be.equal('Messages.....'); + done(); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/editor/theme_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/editor/theme_spec.js new file mode 100644 index 0000000..67e305f --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/editor/theme_spec.js @@ -0,0 +1,146 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var express = require('express'); +var sinon = require('sinon'); +var when = require('when'); +var fs = require("fs"); + +var app = express(); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var theme = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/theme"); + +describe("api/editor/theme", function () { + beforeEach(function () { + sinon.stub(fs, "statSync", function () { return true; }); + }); + afterEach(function () { + theme.init({settings: {}}); + fs.statSync.restore(); + }); + it("applies the default theme", function () { + var result = theme.init({}); + should.not.exist(result); + + var context = theme.context(); + context.should.have.a.property("page"); + context.page.should.have.a.property("title", "Node-RED"); + context.page.should.have.a.property("favicon", "favicon.ico"); + context.page.should.have.a.property("tabicon", "red/images/node-red-icon-black.svg"); + context.should.have.a.property("header"); + context.header.should.have.a.property("title", "Node-RED"); + context.header.should.have.a.property("image", "red/images/node-red.svg"); + context.should.have.a.property("asset"); + context.asset.should.have.a.property("red", "red/red.min.js"); + context.asset.should.have.a.property("main", "red/main.min.js"); + + should.not.exist(theme.settings()); + }); + + it("picks up custom theme", function () { + theme.init({ + editorTheme: { + page: { + title: "Test Page Title", + favicon: "/absolute/path/to/theme/favicon", + tabicon: "/absolute/path/to/theme/tabicon", + css: "/absolute/path/to/custom/css/file.css", + scripts: "/absolute/path/to/script.js" + }, + header: { + title: "Test Header Title", + url: "http://nodered.org", + image: "/absolute/path/to/header/image" // or null to remove image + }, + + deployButton: { + type: "simple", + label: "Save", + icon: "/absolute/path/to/deploy/button/image" // or null to remove image + }, + + menu: { // Hide unwanted menu items by id. see editor/js/main.js:loadEditor for complete list + "menu-item-import-library": false, + "menu-item-export-library": false, + "menu-item-keyboard-shortcuts": false, + "menu-item-help": { + label: "Alternative Help Link Text", + url: "http://example.com" + } + }, + + userMenu: false, // Hide the user-menu even if adminAuth is enabled + + login: { + image: "/absolute/path/to/login/page/big/image" // a 256x256 image + }, + + palette: { + editable: true, + catalogues: ['https://catalogue.nodered.org/catalogue.json'], + theme: [{ category: ".*", type: ".*", color: "#f0f" }] + }, + + projects: { + enabled: false + } + } + }); + + theme.app(); + + var context = theme.context(); + context.should.have.a.property("page"); + context.page.should.have.a.property("title", "Test Page Title"); + context.page.should.have.a.property("favicon", "theme/favicon/favicon"); + context.page.should.have.a.property("tabicon", "theme/tabicon/tabicon"); + context.should.have.a.property("header"); + context.header.should.have.a.property("title", "Test Header Title"); + context.header.should.have.a.property("url", "http://nodered.org"); + context.header.should.have.a.property("image", "theme/header/image"); + context.page.should.have.a.property("css"); + context.page.css.should.have.lengthOf(1); + context.page.css[0].should.eql('theme/css/file.css'); + context.page.should.have.a.property("scripts"); + context.page.scripts.should.have.lengthOf(1); + context.page.scripts[0].should.eql('theme/scripts/script.js'); + context.should.have.a.property("login"); + context.login.should.have.a.property("image", "theme/login/image"); + + var settings = theme.settings(); + settings.should.have.a.property("deployButton"); + settings.deployButton.should.have.a.property("type", "simple"); + settings.deployButton.should.have.a.property("label", "Save"); + settings.deployButton.should.have.a.property("icon", "theme/deploy/image"); + settings.should.have.a.property("userMenu"); + settings.userMenu.should.be.eql(false); + settings.should.have.a.property("menu"); + settings.menu.should.have.a.property("menu-item-import-library", false); + settings.menu.should.have.a.property("menu-item-export-library", false); + settings.menu.should.have.a.property("menu-item-keyboard-shortcuts", false); + settings.menu.should.have.a.property("menu-item-help", { label: "Alternative Help Link Text", url: "http://example.com" }); + settings.should.have.a.property("palette"); + settings.palette.should.have.a.property("editable", true); + settings.palette.should.have.a.property("catalogues", ['https://catalogue.nodered.org/catalogue.json']); + settings.palette.should.have.a.property("theme", [{ category: ".*", type: ".*", color: "#f0f" }]); + settings.should.have.a.property("projects"); + settings.projects.should.have.a.property("enabled", false); + }); + +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/editor/ui_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/editor/ui_spec.js new file mode 100644 index 0000000..2c13125 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/editor/ui_spec.js @@ -0,0 +1,152 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var request = require("supertest"); +var express = require("express"); +var fs = require("fs"); +var path = require("path"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var ui = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/ui"); + + +describe("api/editor/ui", function() { + var app; + + before(function() { + ui.init({ + nodes: { + getIcon: function(opts) { + return new Promise(function(resolve,reject) { + fs.readFile(NR_TEST_UTILS.resolve("@node-red/editor-client/src/images/icons/arrow-in.svg"), function(err,data) { + resolve(data); + }) + }); + } + } + }); + }); + describe("slash handler", function() { + before(function() { + app = express(); + app.get("/foo",ui.ensureSlash,function(req,res) { res.sendStatus(200);}); + }); + it('redirects if the path does not end in a slash',function(done) { + request(app) + .get('/foo') + .expect(301,done); + }); + it('redirects if the path, with query string, does not end in a slash',function(done) { + request(app) + .get('/foo?abc=def') + .expect(301) + .end(function(err,res) { + if (err) { + return done(err); + } + res.header['location'].should.equal("/foo/?abc=def"); + done(); + }); + }); + + it('does not redirect if the path ends in a slash',function(done) { + request(app) + .get('/foo/') + .expect(200,done); + }); + }); + + describe("icon handler", function() { + before(function() { + app = express(); + app.get("/icons/:module/:icon",ui.icon); + }); + + function binaryParser(res, callback) { + res.setEncoding('binary'); + res.data = ''; + res.on('data', function (chunk) { + res.data += chunk; + }); + res.on('end', function () { + callback(null, Buffer.from(res.data, 'binary')); + }); + } + function compareBuffers(b1,b2) { + b1.length.should.equal(b2.length); + for (var i=0;i<b1.length;i++) { + b1[i].should.equal(b2[i]); + } + } + it('returns the requested icon', function(done) { + var defaultIcon = fs.readFileSync(NR_TEST_UTILS.resolve("@node-red/editor-client/src/images/icons/arrow-in.svg")); + request(app) + .get("/icons/module/icon.png") + .expect("Content-Type", /image\/png/) + .expect(200) + .parse(binaryParser) + .end(function(err,res) { + if (err){ + return done(err); + } + Buffer.isBuffer(res.body).should.be.true(); + compareBuffers(res.body,defaultIcon); + done(); + }); + + }); + }); + + describe("editor ui handler", function() { + before(function() { + app = express(); + app.use("/",ui.editor); + }); + it('serves the editor', function(done) { + request(app) + .get("/") + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + // Index page should probably mention Node-RED somewhere + res.text.indexOf("Node-RED").should.not.eql(-1); + done(); + }); + }); + }); + + describe("editor ui resource handler", function() { + before(function() { + app = express(); + app.use("/",ui.editorResources); + }); + it('serves the editor resources', function(done) { + request(app) + .get("/favicon.ico") + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + done(); + }); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/index_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/index_spec.js new file mode 100644 index 0000000..1d5e938 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/index_spec.js @@ -0,0 +1,99 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); +var request = require("supertest"); +var express = require("express"); +var when = require("when"); +var fs = require("fs"); +var path = require("path"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var api = NR_TEST_UTILS.require("@node-red/editor-api"); + +var apiAuth = NR_TEST_UTILS.require("@node-red/editor-api/lib/auth"); +var apiEditor = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor"); +var apiAdmin = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin"); + + +describe("api/index", function() { + var beforeEach = function() { + sinon.stub(apiAuth,"init",function(){}); + sinon.stub(apiEditor,"init",function(){ + var app = express(); + app.get("/editor",function(req,res) { res.status(200).end(); }); + return app; + }); + sinon.stub(apiAdmin,"init",function(){ + var app = express(); + app.get("/admin",function(req,res) { res.status(200).end(); }); + return app; + }); + sinon.stub(apiAuth,"login",function(req,res){ + res.status(200).end(); + }); + }; + var afterEach = function() { + apiAuth.init.restore(); + apiAuth.login.restore(); + apiEditor.init.restore(); + apiAdmin.init.restore(); + }; + + beforeEach(beforeEach); + afterEach(afterEach); + + it("does not setup admin api if httpAdminRoot is false", function(done) { + api.init({ httpAdminRoot: false },{},{},{}); + should.not.exist(api.httpAdmin); + done(); + }); + describe('initalises admin api without adminAuth', function(done) { + before(function() { + beforeEach(); + api.init({},{},{},{}); + }); + after(afterEach); + it('exposes the editor',function(done) { + request(api.httpAdmin).get("/editor").expect(200).end(done); + }) + it('exposes the admin api',function(done) { + request(api.httpAdmin).get("/admin").expect(200).end(done); + }) + it('exposes the auth api',function(done) { + request(api.httpAdmin).get("/auth/login").expect(200).end(done); + }) + }); + + describe('initalises admin api without editor', function(done) { + before(function() { + beforeEach(); + api.init({ disableEditor: true },{},{},{}); + }); + after(afterEach); + it('does not expose the editor',function(done) { + request(api.httpAdmin).get("/editor").expect(404).end(done); + }) + it('exposes the admin api',function(done) { + request(api.httpAdmin).get("/admin").expect(200).end(done); + }) + it('exposes the auth api',function(done) { + request(api.httpAdmin).get("/auth/login").expect(200).end(done) + }) + }); +}); diff --git a/packages/connector/test/unit/@node-red/editor-api/lib/util_spec.js b/packages/connector/test/unit/@node-red/editor-api/lib/util_spec.js new file mode 100644 index 0000000..fb05815 --- /dev/null +++ b/packages/connector/test/unit/@node-red/editor-api/lib/util_spec.js @@ -0,0 +1,110 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); +var request = require('supertest'); +var express = require('express'); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var apiUtil = NR_TEST_UTILS.require("@node-red/editor-api/lib/util"); + +var log = NR_TEST_UTILS.require("@node-red/util").log; +var i18n = NR_TEST_UTILS.require("@node-red/util").i18n; + +describe("api/util", function() { + describe("errorHandler", function() { + var loggedError = null; + var loggedEvent = null; + var app; + before(function() { + app = express(); + sinon.stub(log,'error',function(msg) {loggedError = msg;}); + sinon.stub(log,'audit',function(event) {loggedEvent = event;}); + app.get("/tooLarge", function(req,res) { + var err = new Error(); + err.message = "request entity too large"; + throw err; + },apiUtil.errorHandler) + app.get("/stack", function(req,res) { + var err = new Error(); + err.message = "stacktrace"; + throw err; + },apiUtil.errorHandler) + }); + after(function() { + log.error.restore(); + log.audit.restore(); + }) + beforeEach(function() { + loggedError = null; + loggedEvent = null; + }) + it("logs an error for request entity too large", function(done) { + request(app).get("/tooLarge").expect(400).end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property("error","unexpected_error"); + res.body.should.have.property("message","Error: request entity too large"); + + loggedError.should.have.property("message","request entity too large"); + + loggedEvent.should.have.property("event","api.error"); + loggedEvent.should.have.property("error","unexpected_error"); + loggedEvent.should.have.property("message","Error: request entity too large"); + done(); + }); + }) + it("logs an error plus stack for other errors", function(done) { + request(app).get("/stack").expect(400).end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property("error","unexpected_error"); + res.body.should.have.property("message","Error: stacktrace"); + + /Error: stacktrace\s*at.*util_spec.js/m.test(loggedError).should.be.true(); + + loggedEvent.should.have.property("event","api.error"); + loggedEvent.should.have.property("error","unexpected_error"); + loggedEvent.should.have.property("message","Error: stacktrace"); + + + + done(); + }); + }); + }) + + describe('determineLangFromHeaders', function() { + var oldDefaultLang; + before(function() { + oldDefaultLang = i18n.defaultLang; + i18n.defaultLang = "en-US"; + }) + after(function() { + i18n.defaultLang = oldDefaultLang; + }) + it('returns the default lang if non provided', function() { + apiUtil.determineLangFromHeaders(null).should.eql("en-US"); + }) + it('returns the first language accepted', function() { + apiUtil.determineLangFromHeaders(['fr-FR','en-GB']).should.eql("fr-FR"); + }) + }) +}); diff --git a/packages/connector/test/unit/@node-red/registry/lib/deprecated_spec.js b/packages/connector/test/unit/@node-red/registry/lib/deprecated_spec.js new file mode 100644 index 0000000..b9c35dd --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/deprecated_spec.js @@ -0,0 +1,30 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var deprecated = NR_TEST_UTILS.require("@node-red/registry/lib/deprecated.js"); + +describe('deprecated', function() { + it('should return info on a node',function() { + deprecated.get("irc in").should.eql({module:"node-red-node-irc"}); + }); + it('should return null for non-deprecated node',function() { + should.not.exist(deprecated.get("foo")); + }); +}); diff --git a/packages/connector/test/unit/@node-red/registry/lib/index_spec.js b/packages/connector/test/unit/@node-red/registry/lib/index_spec.js new file mode 100644 index 0000000..753486e --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/index_spec.js @@ -0,0 +1,128 @@ +/** +* Copyright JS Foundation and other contributors, http://js.foundation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + +var should = require("should"); +var sinon = require("sinon"); +var path = require("path"); +var when = require("when"); +var fs = require("fs"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var registry = NR_TEST_UTILS.require("@node-red/registry"); + +var installer = NR_TEST_UTILS.require("@node-red/registry/lib/installer"); +var loader = NR_TEST_UTILS.require("@node-red/registry/lib/loader"); +var typeRegistry = NR_TEST_UTILS.require("@node-red/registry/lib/registry"); + +describe('red/registry/index', function() { + var stubs = []; + afterEach(function() { + while(stubs.length) { + stubs.pop().restore(); + } + }) + describe('#init',function() { + it('intialises components', function() { + stubs.push(sinon.stub(installer,"init")); + stubs.push(sinon.stub(loader,"init")); + stubs.push(sinon.stub(typeRegistry,"init")); + + registry.init({}); + installer.init.called.should.be.true(); + loader.init.called.should.be.true(); + typeRegistry.init.called.should.be.true(); + }) + }); + + describe('#addModule', function() { + it('loads the module and returns its info', function(done) { + stubs.push(sinon.stub(loader,"addModule",function(module) { + return when.resolve(); + })); + stubs.push(sinon.stub(typeRegistry,"getModuleInfo", function(module) { + return "info"; + })); + registry.addModule("foo").then(function(info) { + info.should.eql("info"); + done(); + }).catch(function(err) { done(err); }); + }); + it('rejects if loader rejects', function(done) { + stubs.push(sinon.stub(loader,"addModule",function(module) { + return when.reject("error"); + })); + stubs.push(sinon.stub(typeRegistry,"getModuleInfo", function(module) { + return "info"; + })); + registry.addModule("foo").then(function(info) { + done(new Error("unexpected resolve")); + }).catch(function(err) { + err.should.eql("error"); + done(); + }) + }); + }); + + describe('#enableNode',function() { + it('enables a node set',function(done) { + stubs.push(sinon.stub(typeRegistry,"enableNodeSet",function() { + return when.resolve(); + })); + stubs.push(sinon.stub(typeRegistry,"getNodeInfo", function() { + return {id:"node-set",loaded:true}; + })); + registry.enableNode("node-set").then(function(ns) { + typeRegistry.enableNodeSet.called.should.be.true(); + ns.should.have.a.property('id','node-set'); + done(); + }).catch(function(err) { done(err); }); + }); + + it('rejects if node unknown',function() { + stubs.push(sinon.stub(typeRegistry,"enableNodeSet",function() { + throw new Error('failure'); + })); + /*jshint immed: false */ + (function(){ + registry.enableNode("node-set") + }).should.throw(); + }); + + it('triggers a node load',function(done) { + stubs.push(sinon.stub(typeRegistry,"enableNodeSet",function() { + return when.resolve(); + })); + var calls = 0; + stubs.push(sinon.stub(typeRegistry,"getNodeInfo", function() { + // loaded=false on first call, true on subsequent + return {id:"node-set",loaded:(calls++>0)}; + })); + stubs.push(sinon.stub(loader,"loadNodeSet",function(){return when.resolve();})); + stubs.push(sinon.stub(typeRegistry,"getFullNodeInfo")); + + registry.enableNode("node-set").then(function(ns) { + typeRegistry.enableNodeSet.called.should.be.true(); + loader.loadNodeSet.called.should.be.true(); + ns.should.have.a.property('id','node-set'); + ns.should.have.a.property('loaded',true); + done(); + }).catch(function(err) { done(err); }); + }); + + }); + +}); diff --git a/packages/connector/test/unit/@node-red/registry/lib/installer_spec.js b/packages/connector/test/unit/@node-red/registry/lib/installer_spec.js new file mode 100644 index 0000000..f3bae8b --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/installer_spec.js @@ -0,0 +1,268 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); +var when = require("when"); +var path = require("path"); +var fs = require('fs'); +var EventEmitter = require('events'); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var installer = NR_TEST_UTILS.require("@node-red/registry/lib/installer"); +var registry = NR_TEST_UTILS.require("@node-red/registry/lib/index"); +var typeRegistry = NR_TEST_UTILS.require("@node-red/registry/lib/registry"); + +describe('nodes/registry/installer', function() { + + var mockLog = { + log: sinon.stub(), + debug: sinon.stub(), + trace: sinon.stub(), + warn: sinon.stub(), + info: sinon.stub(), + metric: sinon.stub(), + _: function() { return "abc"} + } + + beforeEach(function() { + installer.init({log:mockLog, settings:{}, events: new EventEmitter(), exec: { + run: function() { + return Promise.resolve(""); + } + }}); + }); + function initInstaller(execResult) { + installer.init({log:mockLog, settings:{}, events: new EventEmitter(), exec: { + run: function() { + return execResult; + } + }}); + } + afterEach(function() { + if (registry.addModule.restore) { + registry.addModule.restore(); + } + if (registry.removeModule.restore) { + registry.removeModule.restore(); + } + if (typeRegistry.removeModule.restore) { + typeRegistry.removeModule.restore(); + } + if (registry.getModuleInfo.restore) { + registry.getModuleInfo.restore(); + } + if (typeRegistry.getModuleInfo.restore) { + typeRegistry.getModuleInfo.restore(); + } + + if (require('fs').statSync.restore) { + require('fs').statSync.restore(); + } + + }); + + describe("installs module", function() { + it("rejects when npm returns a 404", function(done) { + var res = { + code: 1, + stdout:"", + stderr:" 404 this_wont_exist" + } + var p = Promise.reject(res); + p.catch((err)=>{}); + initInstaller(p) + installer.installModule("this_wont_exist").catch(function(err) { + err.should.have.property("code",404); + done(); + }); + }); + it("rejects when npm does not find specified version", function(done) { + var res = { + code: 1, + stdout:"", + stderr:" version not found: this_wont_exist@0.1.2" + } + var p = Promise.reject(res); + p.catch((err)=>{}); + initInstaller(p) + sinon.stub(typeRegistry,"getModuleInfo", function() { + return { + version: "0.1.1" + } + }); + installer.installModule("this_wont_exist","0.1.2").catch(function(err) { + err.code.should.be.eql(404); + done(); + }); + }); + it("rejects when update requested to existing version", function(done) { + sinon.stub(typeRegistry,"getModuleInfo", function() { + return { + version: "0.1.1" + } + }); + installer.installModule("this_wont_exist","0.1.1").catch(function(err) { + err.code.should.be.eql('module_already_loaded'); + done(); + }); + }); + it("rejects with generic error", function(done) { + var res = { + code: 1, + stdout:"", + stderr:" kaboom!" + } + var p = Promise.reject(res); + p.catch((err)=>{}); + initInstaller(p) + installer.installModule("this_wont_exist").then(function() { + done(new Error("Unexpected success")); + }).catch(function(err) { + done(); + }); + }); + it("succeeds when module is found", function(done) { + var nodeInfo = {nodes:{module:"foo",types:["a"]}}; + + var res = { + code: 0, + stdout:"", + stderr:"" + } + var p = Promise.resolve(res); + p.catch((err)=>{}); + initInstaller(p) + + var addModule = sinon.stub(registry,"addModule",function(md) { + return when.resolve(nodeInfo); + }); + + installer.installModule("this_wont_exist").then(function(info) { + info.should.eql(nodeInfo); + // commsMessages.should.have.length(1); + // commsMessages[0].topic.should.equal("node/added"); + // commsMessages[0].msg.should.eql(nodeInfo.nodes); + done(); + }).catch(function(err) { + done(err); + }); + }); + it("rejects when non-existant path is provided", function(done) { + this.timeout(20000); + var resourcesDir = path.resolve(path.join(__dirname,"resources","local","TestNodeModule","node_modules","NonExistant")); + installer.installModule(resourcesDir).then(function() { + done(new Error("Unexpected success")); + }).catch(function(err) { + if (err.hasOwnProperty("code")) { + err.code.should.eql(404); + done(); + } + else { + console.log("ERRROR::"+err.toString()+"::"); + err.toString().should.eql("Error: Install failed"); + done(); + } + }); + }); + it("succeeds when path is valid node-red module", function(done) { + var nodeInfo = {nodes:{module:"foo",types:["a"]}}; + var addModule = sinon.stub(registry,"addModule",function(md) { + return when.resolve(nodeInfo); + }); + var resourcesDir = path.resolve(path.join(__dirname,"resources","local","TestNodeModule","node_modules","TestNodeModule")); + + var res = { + code: 0, + stdout:"", + stderr:"" + } + var p = Promise.resolve(res); + p.catch((err)=>{}); + initInstaller(p) + installer.installModule(resourcesDir).then(function(info) { + info.should.eql(nodeInfo); + done(); + }).catch(function(err) { + done(err); + }); + }); + + }); + describe("uninstalls module", function() { + it("rejects invalid module names", function(done) { + var promises = []; + promises.push(installer.uninstallModule("this_wont_exist ")); + promises.push(installer.uninstallModule("this_wont_exist;no_it_really_wont")); + when.settle(promises).then(function(results) { + results[0].state.should.be.eql("rejected"); + results[1].state.should.be.eql("rejected"); + done(); + }); + }); + + it("rejects with generic error", function(done) { + var nodeInfo = [{module:"foo",types:["a"]}]; + var removeModule = sinon.stub(registry,"removeModule",function(md) { + return when.resolve(nodeInfo); + }); + var res = { + code: 1, + stdout:"", + stderr:"error" + } + var p = Promise.reject(res); + p.catch((err)=>{}); + initInstaller(p) + + installer.uninstallModule("this_wont_exist").then(function() { + done(new Error("Unexpected success")); + }).catch(function(err) { + done(); + }); + }); + it("succeeds when module is found", function(done) { + var nodeInfo = [{module:"foo",types:["a"]}]; + var removeModule = sinon.stub(typeRegistry,"removeModule",function(md) { + return nodeInfo; + }); + var getModuleInfo = sinon.stub(registry,"getModuleInfo",function(md) { + return {nodes:[]}; + }); + var res = { + code: 0, + stdout:"", + stderr:"" + } + var p = Promise.resolve(res); + p.catch((err)=>{}); + initInstaller(p) + + sinon.stub(fs,"statSync", function(fn) { return {}; }); + + installer.uninstallModule("this_wont_exist").then(function(info) { + info.should.eql(nodeInfo); + // commsMessages.should.have.length(1); + // commsMessages[0].topic.should.equal("node/removed"); + // commsMessages[0].msg.should.eql(nodeInfo); + done(); + }).catch(function(err) { + done(err); + }); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/registry/lib/library_spec.js b/packages/connector/test/unit/@node-red/registry/lib/library_spec.js new file mode 100644 index 0000000..2e0e7e9 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/library_spec.js @@ -0,0 +1,62 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); + +var fs = require("fs"); +var path = require("path"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var library = NR_TEST_UTILS.require("@node-red/registry/lib/library"); + +describe("library api", function() { + it('returns null list when no modules have been registered', function() { + library.init(); + should.not.exist(library.getExampleFlows()); + }); + it('returns null path when module is not known', function() { + library.init(); + should.not.exist(library.getExampleFlowPath('foo','bar')); + }); + + it('returns a valid example path', function(done) { + library.init(); + library.addExamplesDir("test-module",path.resolve(__dirname+'/resources/examples')).then(function() { + try { + var flows = library.getExampleFlows(); + flows.should.deepEqual({"test-module":{"f":["one"]}}); + + var examplePath = library.getExampleFlowPath('test-module','one'); + examplePath.should.eql(path.resolve(__dirname+'/resources/examples/one.json')) + + + library.removeExamplesDir('test-module'); + + try { + should.not.exist(library.getExampleFlows()); + should.not.exist(library.getExampleFlowPath('test-module','one')); + done(); + } catch(err) { + done(err); + } + }catch(err) { + done(err); + } + }); + + }) +}); diff --git a/packages/connector/test/unit/@node-red/registry/lib/loader_spec.js b/packages/connector/test/unit/@node-red/registry/lib/loader_spec.js new file mode 100644 index 0000000..9ab2e00 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/loader_spec.js @@ -0,0 +1,654 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var when = require("when"); +var sinon = require("sinon"); +var path = require("path"); +var fs = require("fs"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var loader = NR_TEST_UTILS.require("@node-red/registry/lib/loader"); + +var localfilesystem = NR_TEST_UTILS.require("@node-red/registry/lib/localfilesystem"); +var registry = NR_TEST_UTILS.require("@node-red/registry/lib/registry"); + +var nodes = NR_TEST_UTILS.require("@node-red/registry"); + +var resourcesDir = path.resolve(path.join(__dirname,"resources","local")); + +describe("red/nodes/registry/loader",function() { + var stubs = []; + before(function() { + sinon.stub(localfilesystem,"init"); + }); + after(function() { + localfilesystem.init.restore(); + }); + afterEach(function() { + while(stubs.length) { + stubs.pop().restore(); + } + }) + + describe("#load",function() { + it("load empty set without settings available", function(done) { + stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ return {};})); + stubs.push(sinon.stub(registry,"saveNodeList", function(){ return {};})); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return false;}}}); + loader.load(true).then(function() { + localfilesystem.getNodeFiles.called.should.be.true(); + localfilesystem.getNodeFiles.lastCall.args[0].should.be.true(); + registry.saveNodeList.called.should.be.false(); + done(); + }) + }); + it("load empty set with settings available triggers registery save", function(done) { + stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ return {};})); + stubs.push(sinon.stub(registry,"saveNodeList", function(){ return {};})); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.load(true).then(function() { + registry.saveNodeList.called.should.be.true(); + done(); + }).catch(function(err) { + done(err); + }) + }); + + it("load core node files scanned by lfs - single node single file", function(done) { + stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ + var result = {}; + result["node-red"] = { + "name": "node-red", + "version": "1.2.3", + "nodes": { + "TestNode1": { + "file": path.join(resourcesDir,"TestNode1","TestNode1.js"), + "module": "node-red", + "name": "TestNode1" + } + } + }; + return result; + })); + + stubs.push(sinon.stub(registry,"saveNodeList", function(){ return })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); + // This module isn't already loaded + stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); + + stubs.push(sinon.stub(nodes,"registerType")); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.load().then(function(result) { + registry.addModule.called.should.be.true(); + var module = registry.addModule.lastCall.args[0]; + module.should.have.property("name","node-red"); + module.should.have.property("version","1.2.3"); + module.should.have.property("nodes"); + module.nodes.should.have.property("TestNode1"); + module.nodes.TestNode1.should.have.property("id","node-red/TestNode1"); + module.nodes.TestNode1.should.have.property("module","node-red"); + module.nodes.TestNode1.should.have.property("name","TestNode1"); + module.nodes.TestNode1.should.have.property("file"); + module.nodes.TestNode1.should.have.property("template"); + module.nodes.TestNode1.should.have.property("enabled",true); + module.nodes.TestNode1.should.have.property("loaded",true); + module.nodes.TestNode1.should.have.property("types"); + module.nodes.TestNode1.types.should.have.a.length(1); + module.nodes.TestNode1.types[0].should.eql('test-node-1'); + module.nodes.TestNode1.should.have.property("config"); + module.nodes.TestNode1.should.have.property("help"); + module.nodes.TestNode1.should.have.property("namespace","node-red"); + + nodes.registerType.calledOnce.should.be.true(); + nodes.registerType.lastCall.args[0].should.eql('node-red/TestNode1'); + nodes.registerType.lastCall.args[1].should.eql('test-node-1'); + + done(); + }).catch(function(err) { + done(err); + }); + }); + + it("load core node files scanned by lfs - multiple nodes single file", function(done) { + stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ + var result = {}; + result["node-red"] = { + "name": "node-red", + "version": "4.5.6", + "nodes": { + "MultipleNodes1": { + "file": path.join(resourcesDir,"MultipleNodes1","MultipleNodes1.js"), + "module": "node-red", + "name": "MultipleNodes1" + } + } + }; + return result; + })); + + stubs.push(sinon.stub(registry,"saveNodeList", function(){ return })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); + // This module isn't already loaded + stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); + stubs.push(sinon.stub(nodes,"registerType")); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.load().then(function(result) { + + registry.addModule.called.should.be.true(); + var module = registry.addModule.lastCall.args[0]; + module.should.have.property("name","node-red"); + module.should.have.property("version","4.5.6"); + module.should.have.property("nodes"); + module.nodes.should.have.property("MultipleNodes1"); + module.nodes.MultipleNodes1.should.have.property("id","node-red/MultipleNodes1"); + module.nodes.MultipleNodes1.should.have.property("module","node-red"); + module.nodes.MultipleNodes1.should.have.property("name","MultipleNodes1"); + module.nodes.MultipleNodes1.should.have.property("file"); + module.nodes.MultipleNodes1.should.have.property("template"); + module.nodes.MultipleNodes1.should.have.property("enabled",true); + module.nodes.MultipleNodes1.should.have.property("loaded",true); + module.nodes.MultipleNodes1.should.have.property("types"); + module.nodes.MultipleNodes1.types.should.have.a.length(2); + module.nodes.MultipleNodes1.types[0].should.eql('test-node-multiple-1a'); + module.nodes.MultipleNodes1.types[1].should.eql('test-node-multiple-1b'); + module.nodes.MultipleNodes1.should.have.property("config"); + module.nodes.MultipleNodes1.should.have.property("help"); + module.nodes.MultipleNodes1.should.have.property("namespace","node-red"); + + nodes.registerType.calledTwice.should.be.true(); + nodes.registerType.firstCall.args[0].should.eql('node-red/MultipleNodes1'); + nodes.registerType.firstCall.args[1].should.eql('test-node-multiple-1a'); + nodes.registerType.secondCall.args[0].should.eql('node-red/MultipleNodes1'); + nodes.registerType.secondCall.args[1].should.eql('test-node-multiple-1b'); + + + done(); + }).catch(function(err) { + done(err); + }); + }); + + + it("load core node files scanned by lfs - node with promise", function(done) { + stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ + var result = {}; + result["node-red"] = { + "name": "node-red", + "version":"2.4.6", + "nodes": { + "TestNode2": { + "file": path.join(resourcesDir,"TestNode2","TestNode2.js"), + "module": "node-red", + "name": "TestNode2" + } + } + }; + return result; + })); + + stubs.push(sinon.stub(registry,"saveNodeList", function(){ return })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); + // This module isn't already loaded + stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); + + stubs.push(sinon.stub(nodes,"registerType")); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.load().then(function(result) { + + registry.addModule.called.should.be.true(); + var module = registry.addModule.lastCall.args[0]; + module.should.have.property("name","node-red"); + module.should.have.property("version","2.4.6"); + module.should.have.property("nodes"); + module.nodes.should.have.property("TestNode2"); + module.nodes.TestNode2.should.have.property("id","node-red/TestNode2"); + module.nodes.TestNode2.should.have.property("module","node-red"); + module.nodes.TestNode2.should.have.property("name","TestNode2"); + module.nodes.TestNode2.should.have.property("file"); + module.nodes.TestNode2.should.have.property("template"); + module.nodes.TestNode2.should.have.property("enabled",true); + module.nodes.TestNode2.should.have.property("loaded",true); + module.nodes.TestNode2.should.have.property("types"); + module.nodes.TestNode2.types.should.have.a.length(1); + module.nodes.TestNode2.types[0].should.eql('test-node-2'); + module.nodes.TestNode2.should.have.property("config"); + module.nodes.TestNode2.should.have.property("help"); + module.nodes.TestNode2.should.have.property("namespace","node-red"); + module.nodes.TestNode2.should.not.have.property('err'); + + nodes.registerType.calledOnce.should.be.true(); + nodes.registerType.lastCall.args[0].should.eql('node-red/TestNode2'); + nodes.registerType.lastCall.args[1].should.eql('test-node-2'); + + done(); + }).catch(function(err) { + done(err); + }); + }); + + + it("load core node files scanned by lfs - node with rejecting promise", function(done) { + stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ + var result = {}; + result["node-red"] = { + "name": "node-red", + "version":"1.2.3", + "nodes": { + "TestNode3": { + "file": path.join(resourcesDir,"TestNode3","TestNode3.js"), + "module": "node-red", + "name": "TestNode3" + } + } + }; + return result; + })); + + stubs.push(sinon.stub(registry,"saveNodeList", function(){ return })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); + // This module isn't already loaded + stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); + + stubs.push(sinon.stub(nodes,"registerType")); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.load().then(function(result) { + registry.addModule.called.should.be.true(); + var module = registry.addModule.lastCall.args[0]; + module.should.have.property("name","node-red"); + module.should.have.property("version","1.2.3"); + module.should.have.property("nodes"); + module.nodes.should.have.property("TestNode3"); + module.nodes.TestNode3.should.have.property("id","node-red/TestNode3"); + module.nodes.TestNode3.should.have.property("module","node-red"); + module.nodes.TestNode3.should.have.property("name","TestNode3"); + module.nodes.TestNode3.should.have.property("file"); + module.nodes.TestNode3.should.have.property("template"); + module.nodes.TestNode3.should.have.property("enabled",true); + module.nodes.TestNode3.should.have.property("loaded",false); + module.nodes.TestNode3.should.have.property("types"); + module.nodes.TestNode3.types.should.have.a.length(1); + module.nodes.TestNode3.types[0].should.eql('test-node-3'); + module.nodes.TestNode3.should.have.property("config"); + module.nodes.TestNode3.should.have.property("help"); + module.nodes.TestNode3.should.have.property("namespace","node-red"); + module.nodes.TestNode3.should.have.property('err','fail'); + + nodes.registerType.called.should.be.false(); + + done(); + }).catch(function(err) { + done(err); + }); + }); + + it("load core node files scanned by lfs - missing file", function(done) { + stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ + var result = {}; + result["node-red"] = { + "name": "node-red", + "version":"1.2.3", + "nodes": { + "DoesNotExist": { + "file": path.join(resourcesDir,"doesnotexist"), + "module": "node-red", + "name": "DoesNotExist" + } + } + }; + return result; + })); + + stubs.push(sinon.stub(registry,"saveNodeList", function(){ return })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); + // This module isn't already loaded + stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); + + stubs.push(sinon.stub(nodes,"registerType")); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.load().then(function(result) { + registry.addModule.called.should.be.true(); + var module = registry.addModule.lastCall.args[0]; + module.should.have.property("name","node-red"); + module.should.have.property("version","1.2.3"); + module.should.have.property("nodes"); + module.nodes.should.have.property("DoesNotExist"); + module.nodes.DoesNotExist.should.have.property("id","node-red/DoesNotExist"); + module.nodes.DoesNotExist.should.have.property("module","node-red"); + module.nodes.DoesNotExist.should.have.property("name","DoesNotExist"); + module.nodes.DoesNotExist.should.have.property("file"); + module.nodes.DoesNotExist.should.have.property("template"); + module.nodes.DoesNotExist.should.have.property("enabled",true); + module.nodes.DoesNotExist.should.have.property("loaded",false); + module.nodes.DoesNotExist.should.have.property("types"); + module.nodes.DoesNotExist.types.should.have.a.length(0); + module.nodes.DoesNotExist.should.not.have.property("config"); + module.nodes.DoesNotExist.should.not.have.property("help"); + module.nodes.DoesNotExist.should.not.have.property("namespace","node-red"); + module.nodes.DoesNotExist.should.have.property('err'); + + nodes.registerType.called.should.be.false(); + + done(); + }).catch(function(err) { + done(err); + }); + }); + + it("load core node files scanned by lfs - missing html file", function(done) { + stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ + var result = {}; + result["node-red"] = { + "name": "node-red", + "version": "1.2.3", + "nodes": { + "DuffNode": { + "file": path.join(resourcesDir,"DuffNode","DuffNode.js"), + "module": "node-red", + "name": "DuffNode" + } + } + }; + return result; + })); + + stubs.push(sinon.stub(registry,"saveNodeList", function(){ return })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); + // This module isn't already loaded + stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); + + stubs.push(sinon.stub(nodes,"registerType")); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.load().then(function(result) { + + registry.addModule.called.should.be.true(); + var module = registry.addModule.lastCall.args[0]; + module.should.have.property("name","node-red"); + module.should.have.property("version","1.2.3"); + module.should.have.property("nodes"); + module.nodes.should.have.property("DuffNode"); + module.nodes.DuffNode.should.have.property("id","node-red/DuffNode"); + module.nodes.DuffNode.should.have.property("module","node-red"); + module.nodes.DuffNode.should.have.property("name","DuffNode"); + module.nodes.DuffNode.should.have.property("file"); + module.nodes.DuffNode.should.have.property("template"); + module.nodes.DuffNode.should.have.property("enabled",true); + module.nodes.DuffNode.should.have.property("loaded",false); + module.nodes.DuffNode.should.have.property("types"); + module.nodes.DuffNode.types.should.have.a.length(0); + module.nodes.DuffNode.should.not.have.property("config"); + module.nodes.DuffNode.should.not.have.property("help"); + module.nodes.DuffNode.should.not.have.property("namespace","node-red"); + module.nodes.DuffNode.should.have.property('err'); + module.nodes.DuffNode.err.should.endWith("DuffNode.html does not exist"); + + nodes.registerType.called.should.be.false(); + + done(); + }).catch(function(err) { + done(err); + }); + }); + }); + + describe("#addModule",function() { + it("throws error if settings unavailable", function() { + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return false;}}}); + /*jshint immed: false */ + (function(){ + loader.addModule("test-module"); + }).should.throw("Settings unavailable"); + }); + + it("returns rejected error if module already loaded", function(done) { + stubs.push(sinon.stub(registry,"getModuleInfo",function(){return{}})); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + + loader.addModule("test-module").catch(function(err) { + err.code.should.eql("module_already_loaded"); + done(); + }); + }); + it("returns rejected error if module not found", function(done) { + stubs.push(sinon.stub(registry,"getModuleInfo",function(){return null})); + stubs.push(sinon.stub(localfilesystem,"getModuleFiles",function() { + throw new Error("failure"); + })); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.addModule("test-module").catch(function(err) { + err.message.should.eql("failure"); + done(); + }); + + }); + + it("loads module by name", function(done) { + // This module isn't already loaded + stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); + stubs.push(sinon.stub(registry,"getModuleInfo",function(){ return null; })); + stubs.push(sinon.stub(localfilesystem,"getModuleFiles", function(){ + var result = {}; + result["TestNodeModule"] = { + "name": "TestNodeModule", + "version": "1.2.3", + "nodes": { + "TestNode1": { + "file": path.join(resourcesDir,"TestNodeModule","node_modules","TestNodeModule","TestNodeModule.js"), + "module": "TestNodeModule", + "name": "TestNode1", + "version": "1.2.3" + } + } + }; + return result; + })); + + stubs.push(sinon.stub(registry,"saveNodeList", function(){ return "a node list" })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); + stubs.push(sinon.stub(nodes,"registerType")); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.addModule("TestNodeModule").then(function(result) { + result.should.eql("a node list"); + + registry.addModule.called.should.be.true(); + var module = registry.addModule.lastCall.args[0]; + module.should.have.property("name","TestNodeModule"); + module.should.have.property("version","1.2.3"); + module.should.have.property("nodes"); + module.nodes.should.have.property("TestNode1"); + module.nodes.TestNode1.should.have.property("id","TestNodeModule/TestNode1"); + module.nodes.TestNode1.should.have.property("module","TestNodeModule"); + module.nodes.TestNode1.should.have.property("name","TestNode1"); + module.nodes.TestNode1.should.have.property("file"); + module.nodes.TestNode1.should.have.property("template"); + module.nodes.TestNode1.should.have.property("enabled",true); + module.nodes.TestNode1.should.have.property("loaded",true); + module.nodes.TestNode1.should.have.property("types"); + module.nodes.TestNode1.types.should.have.a.length(1); + module.nodes.TestNode1.types[0].should.eql('test-node-mod-1'); + module.nodes.TestNode1.should.have.property("config"); + module.nodes.TestNode1.should.have.property("help"); + module.nodes.TestNode1.should.have.property("namespace","TestNodeModule"); + module.nodes.TestNode1.should.not.have.property('err'); + + nodes.registerType.calledOnce.should.be.true(); + done(); + }).catch(function(err) { + done(err); + }); + }); + + it("skips module that fails version check", function(done) { + // This module isn't already loaded + stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); + stubs.push(sinon.stub(registry,"getModuleInfo",function(){ return null; })); + stubs.push(sinon.stub(localfilesystem,"getModuleFiles", function(){ + var result = {}; + result["TestNodeModule"] = { + "name": "TestNodeModule", + "version": "1.2.3", + "redVersion":"999.0.0", + "nodes": { + "TestNode1": { + "file": path.join(resourcesDir,"TestNodeModule","node_modules","TestNodeModule","TestNodeModule.js"), + "module": "TestNodeModule", + "name": "TestNode1", + "version": "1.2.3" + } + } + }; + return result; + })); + + stubs.push(sinon.stub(registry,"saveNodeList", function(){ return "a node list" })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); + stubs.push(sinon.stub(nodes,"registerType")); + loader.init({log:{"_":function(){},warn:function(){}},nodes:nodes,version: function() { return "0.12.0"}, settings:{available:function(){return true;}}}); + loader.addModule("TestNodeModule").then(function(result) { + result.should.eql("a node list"); + registry.addModule.called.should.be.false(); + nodes.registerType.called.should.be.false(); + done(); + }).catch(function(err) { + done(err); + }); + }); + + it.skip('registers a message catalog'); + + + }); + describe("#loadNodeSet",function() { + it("no-ops the load if node is not enabled", function(done) { + stubs.push(sinon.stub(nodes,"registerType")); + loader.loadNodeSet({ + "file": path.join(resourcesDir,"TestNode1","TestNode1.js"), + "module": "node-red", + "name": "TestNode1", + "enabled": false + }).then(function(node) { + node.enabled.should.be.false(); + nodes.registerType.called.should.be.false(); + done(); + }).catch(function(err) { + done(err); + }); + }); + + it("handles node that errors on require", function(done) { + stubs.push(sinon.stub(nodes,"registerType")); + loader.loadNodeSet({ + "file": path.join(resourcesDir,"TestNode4","TestNode4.js"), + "module": "node-red", + "name": "TestNode4", + "enabled": true + }).then(function(node) { + node.enabled.should.be.true(); + nodes.registerType.called.should.be.false(); + node.should.have.property('err'); + node.err.toString().should.eql("Error: fail to require (line:1)"); + + done(); + }).catch(function(err) { + done(err); + }); + }); + }); + describe("#getNodeHelp",function() { + it("returns preloaded help", function() { + loader.getNodeHelp({ + help:{ + en:"foo" + } + },"en").should.eql("foo"); + }); + it("loads help, caching result", function() { + stubs.push(sinon.stub(fs,"readFileSync", function(path) { + return 'bar'; + })) + var node = { + template: "/tmp/node/directory/file.html", + help:{ + en:"foo" + } + }; + loader.getNodeHelp(node,"fr").should.eql("bar"); + node.help['fr'].should.eql("bar"); + fs.readFileSync.calledOnce.should.be.true(); + fs.readFileSync.lastCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/fr/file.html")); + loader.getNodeHelp(node,"fr").should.eql("bar"); + fs.readFileSync.calledOnce.should.be.true(); + }); + it("loads help, defaulting to en-US content", function() { + stubs.push(sinon.stub(fs,"readFileSync", function(path) { + throw new Error("not found"); + })) + var node = { + template: "/tmp/node/directory/file.html", + help:{} + }; + node.help['en-US'] = 'foo'; + + loader.getNodeHelp(node,"fr").should.eql("foo"); + node.help['fr'].should.eql("foo"); + fs.readFileSync.calledOnce.should.be.true(); + fs.readFileSync.lastCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/fr/file.html")); + loader.getNodeHelp(node,"fr").should.eql("foo"); + fs.readFileSync.calledOnce.should.be.true(); + }); + it("loads help, defaulting to en-US content for extra nodes", function() { + stubs.push(sinon.stub(fs,"readFileSync", function(path) { + if (path.indexOf("en-US") >= 0) { + return 'bar'; + } + throw new Error("not found"); + })); + var node = { + template: "/tmp/node/directory/file.html", + help:{} + }; + delete node.help['en-US']; + + loader.getNodeHelp(node,"fr").should.eql("bar"); + node.help['fr'].should.eql("bar"); + fs.readFileSync.calledTwice.should.be.true(); + fs.readFileSync.firstCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/fr/file.html")); + fs.readFileSync.lastCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/en-US/file.html")); + loader.getNodeHelp(node,"fr").should.eql("bar"); + fs.readFileSync.calledTwice.should.be.true(); + }); + it("fails to load en-US help content", function() { + stubs.push(sinon.stub(fs,"readFileSync", function(path) { + throw new Error("not found"); + })); + var node = { + template: "/tmp/node/directory/file.html", + help:{} + }; + delete node.help['en-US']; + + should.not.exist(loader.getNodeHelp(node,"en-US")); + should.not.exist(node.help['en-US']); + fs.readFileSync.calledTwice.should.be.true(); + fs.readFileSync.firstCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/en-US/file.html")); + fs.readFileSync.lastCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/en/file.html")); + should.not.exist(loader.getNodeHelp(node,"en-US")); + fs.readFileSync.callCount.should.eql(4); + }); + + }); +}); diff --git a/packages/connector/test/unit/@node-red/registry/lib/localfilesystem_spec.js b/packages/connector/test/unit/@node-red/registry/lib/localfilesystem_spec.js new file mode 100644 index 0000000..41beb8d --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/localfilesystem_spec.js @@ -0,0 +1,304 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var when = require("when"); +var sinon = require("sinon"); +var path = require("path"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var localfilesystem = NR_TEST_UTILS.require("@node-red/registry/lib/localfilesystem"); + +var resourcesDir = path.resolve(path.join(__dirname,"resources","local")); +var userDir = path.resolve(path.join(__dirname,"resources","userDir")); +var moduleDir = path.resolve(path.join(__dirname,"resources","local","TestNodeModule")); + +var i18n = NR_TEST_UTILS.require("@node-red/util").i18n; + +describe("red/nodes/registry/localfilesystem",function() { + beforeEach(function() { + stubs.push(sinon.stub(i18n,"registerMessageCatalog", function() { return Promise.resolve(); })); + }) + + var stubs = []; + afterEach(function() { + while(stubs.length) { + stubs.pop().restore(); + } + }) + function checkNodes(nodes,shouldHaveNodes,shouldNotHaveNodes,module) { + for (var i=0;i<shouldHaveNodes.length;i++) { + nodes.should.have.a.property(shouldHaveNodes[i]); + nodes[shouldHaveNodes[i]].should.have.a.property('file'); + nodes[shouldHaveNodes[i]].file.should.equal(path.resolve(nodes[shouldHaveNodes[i]].file)); + nodes[shouldHaveNodes[i]].should.have.a.property('module',module||'node-red'); + nodes[shouldHaveNodes[i]].should.have.a.property('name',shouldHaveNodes[i]); + } + for (i=0;i<shouldNotHaveNodes.length;i++) { + nodes.should.not.have.a.property(shouldNotHaveNodes[i]); + } + } + describe("#getNodeFiles",function() { + it("Finds all the node files in the resources tree",function(done) { + localfilesystem.init({settings:{coreNodesDir:resourcesDir}}); + var nodeList = localfilesystem.getNodeFiles(true); + nodeList.should.have.a.property("node-red"); + var nm = nodeList['node-red']; + nm.should.have.a.property('name','node-red'); + nm.should.have.a.property("nodes"); + var nodes = nm.nodes; + checkNodes(nm.nodes,['TestNode1','MultipleNodes1','NestedNode','TestNode2','TestNode3','TestNode4'],['TestNodeModule']); + i18n.registerMessageCatalog.called.should.be.true(); + i18n.registerMessageCatalog.lastCall.args[0].should.eql('node-red'); + i18n.registerMessageCatalog.lastCall.args[1].should.eql(path.resolve(path.join(resourcesDir,"locales"))); + i18n.registerMessageCatalog.lastCall.args[2].should.eql('messages.json'); + done(); + }); + it("Includes node files from settings",function(done) { + localfilesystem.init({settings:{nodesIncludes:['TestNode1.js'],coreNodesDir:resourcesDir}}); + var nodeList = localfilesystem.getNodeFiles(true); + nodeList.should.have.a.property("node-red"); + var nm = nodeList['node-red']; + nm.should.have.a.property('name','node-red'); + nm.should.have.a.property("nodes"); + checkNodes(nm.nodes,['TestNode1'],['MultipleNodes1','NestedNode','TestNode2','TestNode3','TestNode4','TestNodeModule']); + done(); + }); + it("Excludes node files from settings",function(done) { + localfilesystem.init({settings:{nodesExcludes:['TestNode1.js'],coreNodesDir:resourcesDir}}); + var nodeList = localfilesystem.getNodeFiles(true); + nodeList.should.have.a.property("node-red"); + var nm = nodeList['node-red']; + nm.should.have.a.property('name','node-red'); + nm.should.have.a.property("nodes"); + checkNodes(nm.nodes,['MultipleNodes1','NestedNode','TestNode2','TestNode3','TestNode4'],['TestNode1','TestNodeModule']); + done(); + }); + it("Finds nodes in userDir/nodes",function(done) { + localfilesystem.init({settings:{userDir:userDir}}); + var nodeList = localfilesystem.getNodeFiles(true); + nodeList.should.have.a.property("node-red"); + var nm = nodeList['node-red']; + nm.should.have.a.property('name','node-red'); + nm.should.have.a.property("nodes"); + checkNodes(nm.nodes,['TestNode5'],['TestNode1']); + done(); + }); + + it("Finds nodes in settings.nodesDir (string)",function(done) { + localfilesystem.init({settings:{nodesDir:userDir}}); + var nodeList = localfilesystem.getNodeFiles(true); + nodeList.should.have.a.property("node-red"); + var nm = nodeList['node-red']; + nm.should.have.a.property('name','node-red'); + nm.should.have.a.property("nodes"); + checkNodes(nm.nodes,['TestNode5'],['TestNode1']); + done(); + }); + it("Finds nodes in settings.nodesDir (string,relative path)",function(done) { + var relativeUserDir = path.join("test","unit","@node-red","registry","lib","resources","userDir"); + localfilesystem.init({settings:{nodesDir:relativeUserDir}}); + var nodeList = localfilesystem.getNodeFiles(true); + nodeList.should.have.a.property("node-red"); + var nm = nodeList['node-red']; + nm.should.have.a.property('name','node-red'); + nm.should.have.a.property("nodes"); + checkNodes(nm.nodes,['TestNode5'],['TestNode1']); + done(); + }); + it("Finds nodes in settings.nodesDir (array)",function(done) { + localfilesystem.init({settings:{nodesDir:[userDir]}}); + var nodeList = localfilesystem.getNodeFiles(true); + nodeList.should.have.a.property("node-red"); + var nm = nodeList['node-red']; + nm.should.have.a.property('name','node-red'); + nm.should.have.a.property("nodes"); + checkNodes(nm.nodes,['TestNode5'],['TestNode1']); + done(); + }); + it("Finds nodes module path",function(done) { + var _join = path.join; + stubs.push(sinon.stub(path,"join",function() { + if (arguments[0] == resourcesDir) { + // This stops the module tree scan from going any higher + // up the tree than resourcesDir. + return arguments[0]; + } + return _join.apply(null,arguments); + })); + localfilesystem.init({settings:{coreNodesDir:moduleDir}}); + var nodeList = localfilesystem.getNodeFiles(); + nodeList.should.have.a.property("node-red"); + var nm = nodeList['node-red']; + nm.should.have.a.property('name','node-red'); + nm.should.have.a.property("nodes"); + checkNodes(nm.nodes,[],['TestNode1']); + + nm = nodeList['TestNodeModule']; + nm.should.have.a.property('name','TestNodeModule'); + nm.should.have.a.property("nodes"); + checkNodes(nm.nodes,['TestNodeMod1','TestNodeMod2'],[],'TestNodeModule'); + + nm = nodeList['VersionMismatchModule']; + nm.should.have.a.property('name','VersionMismatchModule'); + nm.should.have.a.property("nodes"); + checkNodes(nm.nodes,['VersionMismatchMod1','VersionMismatchMod2'],[],'VersionMismatchModule'); + + i18n.registerMessageCatalog.called.should.be.true(); + i18n.registerMessageCatalog.lastCall.args[0].should.eql('node-red'); + i18n.registerMessageCatalog.lastCall.args[1].should.eql(path.resolve(path.join(moduleDir,"locales"))); + i18n.registerMessageCatalog.lastCall.args[2].should.eql('messages.json'); + + + + done(); + }); + it.skip("finds locales directory"); + it.skip("finds icon path directory"); + it("scans icon files in the resources tree",function(done) { + var count = 0; + localfilesystem.init({ + + // events:{emit:function(eventName,dir){ + // if (count === 0) { + // eventName.should.equal("node-icon-dir"); + // dir.name.should.equal("node-red"); + // dir.icons.should.be.an.Array(); + // count = 1; + // } else if (count === 1) { + // done(); + // } + // }}, + settings:{coreNodesDir:resourcesDir} + }); + var list = localfilesystem.getNodeFiles(true); + list.should.have.property("node-red"); + list["node-red"].should.have.property("icons"); + list["node-red"].icons.should.have.length(1); + list["node-red"].icons[0].should.have.property("path",path.join(__dirname,"resources/local/NestedDirectoryNode/NestedNode/icons")) + list["node-red"].icons[0].should.have.property("icons"); + list["node-red"].icons[0].icons.should.have.length(1); + list["node-red"].icons[0].icons[0].should.eql("arrow-in.png"); + done(); + }); + it("scans icons dir in library",function(done) { + var count = 0; + localfilesystem.init({ + // + // events:{emit:function(eventName,dir){ + // eventName.should.equal("node-icon-dir"); + // if (count === 0) { + // dir.name.should.equal("node-red"); + // dir.icons.should.be.an.Array(); + // count = 1; + // } else if (count === 1) { + // dir.name.should.equal("Library"); + // dir.icons.should.be.an.Array(); + // dir.icons.length.should.equal(1); + // dir.icons[0].should.be.equal("test_icon.png"); + // done(); + // } + // }}, + settings:{userDir:userDir} + }); + var list = localfilesystem.getNodeFiles(true); + list.should.have.property("node-red"); + list["node-red"].should.have.property("icons"); + list["node-red"].icons.should.have.length(1); + list["node-red"].icons[0].should.have.property("path",path.join(__dirname,"resources/userDir/lib/icons")) + list["node-red"].icons[0].should.have.property("icons"); + list["node-red"].icons[0].icons.should.have.length(1); + list["node-red"].icons[0].icons[0].should.eql("test_icon.png"); + done(); + }); + }); + describe("#getModuleFiles",function() { + it("gets a nodes module files",function(done) { + var _join = path.join; + stubs.push(sinon.stub(path,"join",function() { + if (arguments[0] == resourcesDir) { + // This stops the module tree scan from going any higher + // up the tree than resourcesDir. + return arguments[0]; + } + return _join.apply(null,arguments); + })); + localfilesystem.init({settings:{coreNodesDir:moduleDir}}); + var nodeModule = localfilesystem.getModuleFiles('TestNodeModule'); + nodeModule.should.have.a.property('TestNodeModule'); + nodeModule['TestNodeModule'].should.have.a.property('name','TestNodeModule'); + nodeModule['TestNodeModule'].should.have.a.property('version','0.0.1'); + nodeModule['TestNodeModule'].should.have.a.property('nodes'); + checkNodes(nodeModule['TestNodeModule'].nodes,['TestNodeMod1','TestNodeMod2'],[],'TestNodeModule'); + + nodeModule = localfilesystem.getModuleFiles('VersionMismatchModule'); + nodeModule.should.have.a.property('VersionMismatchModule'); + nodeModule['VersionMismatchModule'].should.have.a.property('redVersion','100.0.0'); + + done(); + }); + it("throws an error if a node isn't found",function(done) { + var _join = path.join; + stubs.push(sinon.stub(path,"join",function() { + if (arguments[0] == resourcesDir) { + // This stops the module tree scan from going any higher + // up the tree than resourcesDir. + return arguments[0]; + } + return _join.apply(null,arguments); + })); + localfilesystem.init({settings:{coreNodesDir:moduleDir}}); + /*jshint immed: false */ + (function(){ + localfilesystem.getModuleFiles('WontExistModule'); + }).should.throw(); + done(); + }); + it.skip("finds locales directory"); + it.skip("finds icon path directory"); + it("scans icon files with a module file",function(done) { + var _join = path.join; + stubs.push(sinon.stub(path,"join",function() { + if (arguments[0] == resourcesDir) { + // This stops the module tree scan from going any higher + // up the tree than resourcesDir. + return arguments[0]; + } + return _join.apply(null,arguments); + })); + localfilesystem.init({ + + // events:{emit:function(eventName,dir){ + // eventName.should.equal("node-icon-dir"); + // dir.name.should.equal("TestNodeModule"); + // dir.icons.should.be.an.Array(); + // done(); + // }}, + settings:{coreNodesDir:moduleDir} + }); + var nodeModule = localfilesystem.getModuleFiles('TestNodeModule'); + nodeModule.should.have.property("TestNodeModule"); + nodeModule.TestNodeModule.should.have.property('icons'); + + nodeModule.TestNodeModule.icons.should.have.length(1); + nodeModule.TestNodeModule.icons[0].should.have.property("path"); + nodeModule.TestNodeModule.icons[0].should.have.property("icons"); + nodeModule.TestNodeModule.icons[0].icons[0].should.eql("arrow-in.png"); + done(); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/registry/lib/registry_spec.js b/packages/connector/test/unit/@node-red/registry/lib/registry_spec.js new file mode 100644 index 0000000..c7ad930 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/registry_spec.js @@ -0,0 +1,580 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var when = require("when"); +var sinon = require("sinon"); +var path = require("path"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var typeRegistry = NR_TEST_UTILS.require("@node-red/registry/lib/registry"); +var EventEmitter = require('events'); + +var events = new EventEmitter(); + +describe("red/nodes/registry/registry",function() { + + afterEach(function() { + typeRegistry.clear(); + }); + + function stubSettings(s,available,initialConfig) { + s.available = function() {return available;}; + s.set = sinon.spy(function(s,v) { return when.resolve();}); + s.get = function(s) { return initialConfig;}; + return s; + } + + var settings = stubSettings({},false,null); + var settingsWithStorageAndInitialConfig = stubSettings({},true,{"node-red":{module:"testModule",name:"testName",version:"testVersion",nodes:{"node":{id:"node-red/testName",name:"test",types:["a","b"],enabled:true}}}}); + + var testNodeSet1 = { + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + config: "configA", + types: [ "test-a","test-b"] + }; + + var testNodeSet2 = { + id: "test-module/test-name-2", + module: "test-module", + name: "test-name-2", + enabled: true, + loaded: false, + config: "configB", + types: [ "test-c","test-d"] + }; + var testNodeSet2WithError = { + id: "test-module/test-name-2", + module: "test-module", + name: "test-name-2", + enabled: true, + loaded: false, + err: "I have an error", + config: "configC", + types: [ "test-c","test-d"] + }; + var testNodeSet3 = { + id: "test-module-2/test-name-3", + module: "test-module-2", + name: "test-name-3", + enabled: true, + loaded: false, + config: "configB", + types: [ "test-a","test-e"] + }; + + + + describe('#init/load', function() { + it('loads initial config', function(done) { + typeRegistry.init(settingsWithStorageAndInitialConfig,null,events); + typeRegistry.getNodeList().should.have.lengthOf(0); + typeRegistry.load(); + typeRegistry.getNodeList().should.have.lengthOf(1); + done(); + }); + + it('migrates legacy format', function(done) { + var legacySettings = { + available: function() { return true; }, + set: sinon.stub().returns(when.resolve()), + get: function() { return { + "123": { + "name": "72-sentiment.js", + "types": [ + "sentiment" + ], + "enabled": true + }, + "456": { + "name": "20-inject.js", + "types": [ + "inject" + ], + "enabled": true + }, + "789": { + "name": "testModule:a-module.js", + "types": [ + "example" + ], + "enabled":true, + "module":"testModule" + } + }} + }; + var expected = JSON.parse('{"node-red":{"name":"node-red","nodes":{"sentiment":{"name":"sentiment","types":["sentiment"],"enabled":true,"module":"node-red"},"inject":{"name":"inject","types":["inject"],"enabled":true,"module":"node-red"}}},"testModule":{"name":"testModule","nodes":{"a-module.js":{"name":"a-module.js","types":["example"],"enabled":true,"module":"testModule"}}}}'); + typeRegistry.init(legacySettings,null,events); + typeRegistry.load(); + legacySettings.set.calledOnce.should.be.true(); + legacySettings.set.args[0][1].should.eql(expected); + done(); + }); + }); + + + describe.skip('#addNodeSet', function() { + it('adds a node set for an unknown module', function() { + + typeRegistry.init(settings,null,events); + + typeRegistry.getNodeList().should.have.lengthOf(0); + typeRegistry.getModuleList().should.eql({}); + + typeRegistry.addNodeSet("test-module/test-name",testNodeSet1, "0.0.1"); + + typeRegistry.getNodeList().should.have.lengthOf(1); + var moduleList = typeRegistry.getModuleList(); + moduleList.should.have.a.property("test-module"); + moduleList["test-module"].should.have.a.property("name","test-module"); + moduleList["test-module"].should.have.a.property("version","0.0.1"); + moduleList["test-module"].should.have.a.property("nodes"); + moduleList["test-module"].nodes.should.have.a.property("test-name"); + + moduleList["test-module"].nodes["test-name"].should.eql({ + config: 'configA', + id: 'test-module/test-name', + module: 'test-module', + name: 'test-name', + enabled: true, + loaded: false, + types: [ 'test-a', 'test-b' ] + }); + + }); + + it('adds a node set to an existing module', function() { + + typeRegistry.init(settings,null,events); + typeRegistry.getNodeList().should.have.lengthOf(0); + typeRegistry.getModuleList().should.eql({}); + + typeRegistry.addNodeSet("test-module/test-name",testNodeSet1, "0.0.1"); + + typeRegistry.getNodeList().should.have.lengthOf(1); + var moduleList = typeRegistry.getModuleList(); + Object.keys(moduleList).should.have.a.lengthOf(1); + moduleList.should.have.a.property("test-module"); + moduleList["test-module"].should.have.a.property("name","test-module"); + moduleList["test-module"].should.have.a.property("version","0.0.1"); + moduleList["test-module"].should.have.a.property("nodes"); + + Object.keys(moduleList["test-module"].nodes).should.have.a.lengthOf(1); + moduleList["test-module"].nodes.should.have.a.property("test-name"); + + + typeRegistry.addNodeSet("test-module/test-name-2",testNodeSet2); + + typeRegistry.getNodeList().should.have.lengthOf(2); + moduleList = typeRegistry.getModuleList(); + Object.keys(moduleList).should.have.a.lengthOf(1); + Object.keys(moduleList["test-module"].nodes).should.have.a.lengthOf(2); + moduleList["test-module"].nodes.should.have.a.property("test-name"); + moduleList["test-module"].nodes.should.have.a.property("test-name-2"); + }); + + it('doesnt add node set types if node set has an error', function() { + typeRegistry.init(settings,null,events); + typeRegistry.getNodeList().should.have.lengthOf(0); + typeRegistry.getModuleList().should.eql({}); + + typeRegistry.addNodeSet("test-module/test-name",testNodeSet1, "0.0.1"); + + typeRegistry.getTypeId("test-a").should.eql("test-module/test-name"); + + should.not.exist(typeRegistry.getTypeId("test-c")); + + typeRegistry.addNodeSet("test-module/test-name-2",testNodeSet2WithError, "0.0.1"); + + should.not.exist(typeRegistry.getTypeId("test-c")); + }); + + it('doesnt add node set if type already exists', function() { + typeRegistry.init(settings,null,events); + typeRegistry.getNodeList().should.have.lengthOf(0); + typeRegistry.getModuleList().should.eql({}); + + should.not.exist(typeRegistry.getTypeId("test-e")); + + typeRegistry.addNodeSet("test-module/test-name",testNodeSet1, "0.0.1"); + typeRegistry.getNodeList().should.have.lengthOf(1); + should.exist(typeRegistry.getTypeId("test-a")); + typeRegistry.addNodeSet(testNodeSet3.id,testNodeSet3, "0.0.1"); + typeRegistry.getNodeList().should.have.lengthOf(2); + + // testNodeSet3 registers a duplicate test-a and unique test-e + // as test-a is a duplicate, test-e should not get registered + should.not.exist(typeRegistry.getTypeId("test-e")); + + var testNodeSet3Result = typeRegistry.getNodeList()[1]; + should.exist(testNodeSet3Result.err); + testNodeSet3Result.err.code.should.equal("type_already_registered"); + testNodeSet3Result.err.details.type.should.equal("test-a"); + testNodeSet3Result.err.details.moduleA.should.equal("test-module"); + testNodeSet3Result.err.details.moduleB.should.equal("test-module-2"); + + // + // typeRegistry.addNodeSet("test-module/test-name-2",testNodeSet2WithError, "0.0.1"); + // + // should.not.exist(typeRegistry.getTypeId("test-c")); + }); + + + }); + + describe("#enableNodeSet", function() { + it('throws error if settings unavailable', function() { + typeRegistry.init(settings,null,events); + /*jshint immed: false */ + (function(){ + typeRegistry.enableNodeSet("test-module/test-name"); + }).should.throw("Settings unavailable"); + }); + + it('throws error if module unknown', function() { + typeRegistry.init(settingsWithStorageAndInitialConfig,null,events); + /*jshint immed: false */ + (function(){ + typeRegistry.enableNodeSet("test-module/unknown"); + }).should.throw("Unrecognised id: test-module/unknown"); + }); + it.skip('enables the node',function(){}) + + }); + describe("#disableNodeSet", function() { + it('throws error if settings unavailable', function() { + typeRegistry.init(settings,null,events); + /*jshint immed: false */ + (function(){ + typeRegistry.disableNodeSet("test-module/test-name"); + }).should.throw("Settings unavailable"); + }); + + it('throws error if module unknown', function() { + typeRegistry.init(settingsWithStorageAndInitialConfig,null,events); + /*jshint immed: false */ + (function(){ + typeRegistry.disableNodeSet("test-module/unknown"); + }).should.throw("Unrecognised id: test-module/unknown"); + }); + it.skip('disables the node',function(){}) + }); + + describe('#getNodeConfig', function() { + it('returns nothing for an unregistered type config', function(done) { + typeRegistry.init(settings,null,events); + var config = typeRegistry.getNodeConfig("imaginary-shark"); + (config === null).should.be.true(); + done(); + }); + }); + + describe('#saveNodeList',function() { + it('rejects when settings unavailable',function(done) { + typeRegistry.init(stubSettings({},false,{}),null,events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: {"test-name":{module:"test-module",name:"test-name",types:[]}}}); + typeRegistry.saveNodeList().catch(function(err) { + done(); + }); + }); + it('saves the list',function(done) { + var s = stubSettings({},true,{}); + typeRegistry.init(s,null,events); + + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":testNodeSet1, + "test-name-2":testNodeSet2WithError + }}); + + typeRegistry.saveNodeList().then(function() { + s.set.called.should.be.true(); + s.set.lastCall.args[0].should.eql('nodes'); + var nodes = s.set.lastCall.args[1]; + nodes.should.have.property('test-module'); + for (var n in nodes['test-module'].nodes) { + if (nodes['test-module'].nodes.hasOwnProperty(n)) { + var nn = nodes['test-module'].nodes[n]; + nn.should.not.have.property('err'); + nn.should.not.have.property('id'); + } + } + done(); + }).catch(function(err) { + done(err); + }); + }); + }); + + describe('#removeModule',function() { + it('throws error for unknown module', function() { + var s = stubSettings({},true,{}); + typeRegistry.init(s,null,events); + /*jshint immed: false */ + (function(){ + typeRegistry.removeModule("test-module/unknown"); + }).should.throw("Unrecognised module: test-module/unknown"); + }); + it('throws error for unavaiable settings', function() { + var s = stubSettings({},false,{}); + typeRegistry.init(s,null,events); + /*jshint immed: false */ + (function(){ + typeRegistry.removeModule("test-module/unknown"); + }).should.throw("Settings unavailable"); + }); + it('removes a known module', function() { + var s = stubSettings({},true,{}); + typeRegistry.init(s,null,events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":testNodeSet1 + }}); + var moduleList = typeRegistry.getModuleList(); + moduleList.should.have.a.property("test-module"); + typeRegistry.getNodeList().should.have.lengthOf(1); + + var info = typeRegistry.removeModule('test-module'); + moduleList = typeRegistry.getModuleList(); + moduleList.should.not.have.a.property("test-module"); + typeRegistry.getNodeList().should.have.lengthOf(0); + }); + }); + + describe('#get[All]NodeConfigs', function() { + it('returns node config', function() { + typeRegistry.init(settings,{ + getNodeHelp: function(config) { return "HE"+config.name+"LP" } + },events); + + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":{ + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + config: "configA", + types: [ "test-a","test-b"] + }, + "test-name-2":{ + id: "test-module/test-name-2", + module: "test-module", + name: "test-name-2", + enabled: true, + loaded: false, + config: "configB", + types: [ "test-c","test-d"] + } + }}); + typeRegistry.getNodeConfig("test-module/test-name").should.eql('<!-- --- [red-module:test-module/test-name] --- -->\nconfigAHEtest-nameLP'); + typeRegistry.getNodeConfig("test-module/test-name-2").should.eql('<!-- --- [red-module:test-module/test-name-2] --- -->\nconfigBHEtest-name-2LP'); + typeRegistry.getAllNodeConfigs().should.eql('\n<!-- --- [red-module:test-module/test-name] --- -->\nconfigAHEtest-nameLP\n<!-- --- [red-module:test-module/test-name-2] --- -->\nconfigBHEtest-name-2LP'); + }); + }); + describe('#getModuleInfo', function() { + it('returns module info', function() { + typeRegistry.init(settings,{},events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":{ + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + config: "configA", + types: [ "test-a","test-b"], + file: "abc" + } + }}); + var moduleInfo = typeRegistry.getModuleInfo("test-module"); + moduleInfo.should.have.a.property('name','test-module'); + moduleInfo.should.have.a.property('version','0.0.1'); + moduleInfo.should.have.a.property('nodes'); + moduleInfo.nodes.should.have.a.lengthOf(1); + moduleInfo.nodes[0].should.have.a.property('id','test-module/test-name'); + moduleInfo.nodes[0].should.not.have.a.property('file'); + }); + }); + describe('#getNodeInfo', function() { + it('returns node info', function() { + typeRegistry.init(settings,{},events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":{ + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + config: "configA", + types: [ "test-a","test-b"], + file: "abc" + } + }}); + var nodeSetInfo = typeRegistry.getNodeInfo("test-module/test-name"); + nodeSetInfo.should.have.a.property('id',"test-module/test-name"); + nodeSetInfo.should.not.have.a.property('config'); + nodeSetInfo.should.not.have.a.property('file'); + }); + }); + describe('#getFullNodeInfo', function() { + it('returns node info', function() { + typeRegistry.init(settings,{},events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":{ + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + config: "configA", + types: [ "test-a","test-b"], + file: "abc" + + } + }}); + var nodeSetInfo = typeRegistry.getFullNodeInfo("test-module/test-name"); + nodeSetInfo.should.have.a.property('id',"test-module/test-name"); + nodeSetInfo.should.have.a.property('config'); + nodeSetInfo.should.have.a.property('file'); + }); + }); + describe('#cleanModuleList', function() { + it.skip("cleans the module list"); + }); + describe('#getNodeList', function() { + it("returns a filtered list", function() { + typeRegistry.init(settings,{},events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":{ + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + config: "configA", + types: [ "test-a","test-b"], + file: "abc" + }, + "test-name-2":{ + id: "test-module/test-name-2", + module: "test-module", + name: "test-name-2", + enabled: true, + loaded: false, + config: "configB", + types: [ "test-c","test-d"], + file: "def" + } + }}); + var filterCallCount = 0; + var filteredList = typeRegistry.getNodeList(function(n) { filterCallCount++; return n.name === 'test-name-2';}); + filterCallCount.should.eql(2); + filteredList.should.have.a.lengthOf(1); + filteredList[0].should.have.a.property('id',"test-module/test-name-2"); + }); + }); + + describe('#registerNodeConstructor', function() { + var TestNodeConstructor; + beforeEach(function() { + TestNodeConstructor = function TestNodeConstructor() {}; + sinon.stub(events,'emit'); + }); + afterEach(function() { + events.emit.restore(); + }); + it('registers a node constructor', function() { + typeRegistry.registerNodeConstructor('node-set','node-type',TestNodeConstructor); + events.emit.calledOnce.should.be.true(); + events.emit.lastCall.args[0].should.eql('type-registered'); + events.emit.lastCall.args[1].should.eql('node-type'); + }) + it('throws error on duplicate node registration', function() { + typeRegistry.registerNodeConstructor('node-set','node-type',TestNodeConstructor); + events.emit.calledOnce.should.be.true(); + events.emit.lastCall.args[0].should.eql('type-registered'); + events.emit.lastCall.args[1].should.eql('node-type'); + /*jshint immed: false */ + (function(){ + typeRegistry.registerNodeConstructor('node-set','node-type',TestNodeConstructor); + }).should.throw("node-type already registered"); + events.emit.calledOnce.should.be.true(); + }); + }); + + describe('#getNodeIconPath', function() { + it('returns the null when getting an unknown icon', function() { + var iconPath = typeRegistry.getNodeIconPath('random-module','youwonthaveme.png'); + should.not.exist(iconPath); + }); + + it('returns a registered icon' , function() { + var testIcon = path.resolve(__dirname+'/resources/userDir/lib/icons/'); + typeRegistry.init(settings,{},events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":{ + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + config: "configA", + types: [ "test-a","test-b"], + file: "abc" + } + },icons: [{path:testIcon,icons:['test_icon.png']}]}); + var iconPath = typeRegistry.getNodeIconPath('test-module','test_icon.png'); + iconPath.should.eql(path.resolve(testIcon+"/test_icon.png")); + }); + + it('returns null when getting an unknown module', function() { + var debugIcon = path.resolve(__dirname+'/../../../public/icons/debug.png'); + var iconPath = typeRegistry.getNodeIconPath('unknown-module', 'debug.png'); + should.not.exist(iconPath); + }); + }); + + describe('#getNodeIcons', function() { + it('returns empty icon list when no modules are registered', function() { + var iconList = typeRegistry.getNodeIcons(); + iconList.should.eql({}); + }); + + it('returns an icon list of registered node module', function() { + var testIcon = path.resolve(__dirname+'/resources/userDir/lib/icons/'); + typeRegistry.init(settings,{},events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":{ + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + config: "configA", + types: [ "test-a","test-b"], + file: "abc" + } + },icons: [{path:testIcon,icons:['test_icon.png']}]}); + var iconList = typeRegistry.getNodeIcons(); + iconList.should.eql({"test-module":["test_icon.png"]}); + }); + }); + +}); diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/examples/one.json b/packages/connector/test/unit/@node-red/registry/lib/resources/examples/one.json new file mode 100644 index 0000000..e69de29 diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/DuffNode/DuffNode.js b/packages/connector/test/unit/@node-red/registry/lib/resources/local/DuffNode/DuffNode.js new file mode 100644 index 0000000..41e2a00 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/DuffNode/DuffNode.js @@ -0,0 +1,5 @@ +// A test node that exports a function +module.exports = function(RED) { + function DuffNode(n) {} + RED.nodes.registerType("duff-node",DuffNode); +} diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/DuplicateTestNode/TestNode1.html b/packages/connector/test/unit/@node-red/registry/lib/resources/local/DuplicateTestNode/TestNode1.html new file mode 100644 index 0000000..b637ede --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/DuplicateTestNode/TestNode1.html @@ -0,0 +1,3 @@ +<script type="text/x-red" data-template-name="test-node-1"></script> +<script type="text/x-red" data-help-name="test-node-1"></script> +<script type="text/javascript">RED.nodes.registerType('test-node-1',{});</script> diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/DuplicateTestNode/TestNode1.js b/packages/connector/test/unit/@node-red/registry/lib/resources/local/DuplicateTestNode/TestNode1.js new file mode 100644 index 0000000..e812141 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/DuplicateTestNode/TestNode1.js @@ -0,0 +1,5 @@ +// A test node that exports a function +module.exports = function(RED) { + function DuplicateTestNode(n) {} + RED.nodes.registerType("test-node-1",DuplicateTestNode); +} diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/MultipleNodes1/MultipleNodes1.html b/packages/connector/test/unit/@node-red/registry/lib/resources/local/MultipleNodes1/MultipleNodes1.html new file mode 100644 index 0000000..5359644 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/MultipleNodes1/MultipleNodes1.html @@ -0,0 +1,6 @@ +<script type="text/x-red" data-template-name="test-node-multiple-1a"></script> +<script type="text/x-red" data-help-name="test-node-multiple-1a"></script> +<script type="text/javascript">RED.nodes.registerType('test-node-multiple-1a',{});</script> +<script type="text/x-red" data-template-name="test-node-multiple-1b"></script> +<script type="text/x-red" data-help-name="test-node-multiple-1b"></script> +<script type="text/javascript">RED.nodes.registerType('test-node-multiple-1b',{});</script> diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/MultipleNodes1/MultipleNodes1.js b/packages/connector/test/unit/@node-red/registry/lib/resources/local/MultipleNodes1/MultipleNodes1.js new file mode 100644 index 0000000..55747c0 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/MultipleNodes1/MultipleNodes1.js @@ -0,0 +1,7 @@ +// A test node that exports a function +module.exports = function(RED) { + function TestNode1(n) {} + RED.nodes.registerType("test-node-multiple-1a",TestNode1); + function TestNode2(n) {} + RED.nodes.registerType("test-node-multiple-1b",TestNode2); +} diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/NestedNode.html b/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/NestedNode.html new file mode 100644 index 0000000..abc823e --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/NestedNode.html @@ -0,0 +1,4 @@ +<script type="text/x-red" data-template-name="nested-node-1"></script> +<script type="text/x-red" data-help-name="nested-node-1"></script> +<script type="text/javascript">RED.nodes.registerType('nested-node-1',{});</script> +<style></style> diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/NestedNode.js b/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/NestedNode.js new file mode 100644 index 0000000..cd3148a --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/NestedNode.js @@ -0,0 +1,5 @@ +// A test node that exports a function +module.exports = function(RED) { + function TestNode(n) {} + RED.nodes.registerType("nested-node-1",TestNode); +} diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/icons/arrow-in.png b/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/icons/arrow-in.png new file mode 100644 index 0000000..e38f391 Binary files /dev/null and b/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/icons/arrow-in.png differ diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.html b/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.html new file mode 100644 index 0000000..ac9235d --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.html @@ -0,0 +1,4 @@ +<script type="text/x-red" data-template-name="should-not-load-1"></script> +<script type="text/x-red" data-help-name="should-not-load-1"></script> +<script type="text/javascript">RED.nodes.registerType('should-not-load-1',{});</script> +<style></style> diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.js b/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.js new file mode 100644 index 0000000..8af249b --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.js @@ -0,0 +1,5 @@ +// A test node that exports a function +module.exports = function(RED) { + function TestNode(n) {} + RED.nodes.registerType("should-not-load-1",TestNode); +} diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.html b/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.html new file mode 100644 index 0000000..4212fd5 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.html @@ -0,0 +1,4 @@ +<script type="text/x-red" data-template-name="should-not-load-3"></script> +<script type="text/x-red" data-help-name="should-not-load-3"></script> +<script type="text/javascript">RED.nodes.registerType('should-not-load-3',{});</script> +<style></style> diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.js b/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.js new file mode 100644 index 0000000..5856ada --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.js @@ -0,0 +1,5 @@ +// A test node that exports a function +module.exports = function(RED) { + function TestNode(n) {} + RED.nodes.registerType("should-not-load-3",TestNode); +} diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode1/TestNode1.html b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode1/TestNode1.html new file mode 100644 index 0000000..97dbf17 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode1/TestNode1.html @@ -0,0 +1,5 @@ +<script type="text/x-red" data-template-name="test-node-1"></script> +<script type="text/x-red" data-help-name="test-node-1"></script> +<script type="text/javascript">RED.nodes.registerType('test-node-1',{});</script> +<style></style> +<p>this should be filtered out</p> diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode1/TestNode1.js b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode1/TestNode1.js new file mode 100644 index 0000000..bfa3b65 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode1/TestNode1.js @@ -0,0 +1,5 @@ +// A test node that exports a function +module.exports = function(RED) { + function TestNode(n) {} + RED.nodes.registerType("test-node-1",TestNode); +} diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode2/TestNode2.html b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode2/TestNode2.html new file mode 100644 index 0000000..66b6590 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode2/TestNode2.html @@ -0,0 +1,4 @@ +<script type="text/x-red" data-template-name="test-node-2"></script> +<script type="text/x-red" data-help-name="test-node-2"></script> +<script type="text/javascript">RED.nodes.registerType('test-node-2',{});</script> +<style></style> diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode2/TestNode2.js b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode2/TestNode2.js new file mode 100644 index 0000000..faf61a8 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode2/TestNode2.js @@ -0,0 +1,10 @@ +// A test node that exports a function which returns a resolving promise + +var when = require("when"); +module.exports = function(RED) { + return when.promise(function(resolve,reject) { + function TestNode(n) {} + RED.nodes.registerType("test-node-2",TestNode); + resolve(); + }); +} diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode3/TestNode3.html b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode3/TestNode3.html new file mode 100644 index 0000000..9a0f6f7 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode3/TestNode3.html @@ -0,0 +1,3 @@ +<script type="text/x-red" data-template-name="test-node-3"></script> +<script type="text/x-red" data-help-name="test-node-3"></script> +<script type="text/javascript">RED.nodes.registerType('test-node-3',{});</script> diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode3/TestNode3.js b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode3/TestNode3.js new file mode 100644 index 0000000..756dc13 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode3/TestNode3.js @@ -0,0 +1,8 @@ +// A test node that exports a function which returns a rejecting promise + +var when = require("when"); +module.exports = function(RED) { + return when.promise(function(resolve,reject) { + reject("fail"); + }); +} diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode4/TestNode4.html b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode4/TestNode4.html new file mode 100644 index 0000000..9a0f6f7 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode4/TestNode4.html @@ -0,0 +1,3 @@ +<script type="text/x-red" data-template-name="test-node-3"></script> +<script type="text/x-red" data-help-name="test-node-3"></script> +<script type="text/javascript">RED.nodes.registerType('test-node-3',{});</script> diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode4/TestNode4.js b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode4/TestNode4.js new file mode 100644 index 0000000..c312558 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/local/TestNode4/TestNode4.js @@ -0,0 +1 @@ +throw new Error("fail to require"); diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/userDir/lib/icons/file.txt b/packages/connector/test/unit/@node-red/registry/lib/resources/userDir/lib/icons/file.txt new file mode 100644 index 0000000..e69de29 diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/userDir/lib/icons/test_icon.png b/packages/connector/test/unit/@node-red/registry/lib/resources/userDir/lib/icons/test_icon.png new file mode 100644 index 0000000..4b6b7b5 Binary files /dev/null and b/packages/connector/test/unit/@node-red/registry/lib/resources/userDir/lib/icons/test_icon.png differ diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/userDir/nodes/TestNode5/TestNode5.html b/packages/connector/test/unit/@node-red/registry/lib/resources/userDir/nodes/TestNode5/TestNode5.html new file mode 100644 index 0000000..f38a3a2 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/userDir/nodes/TestNode5/TestNode5.html @@ -0,0 +1,5 @@ +<script type="text/x-red" data-template-name="test-node-5"></script> +<script type="text/x-red" data-help-name="test-node-5"></script> +<script type="text/javascript">RED.nodes.registerType('test-node-5',{});</script> +<style></style> +<p>this should be filtered out</p> diff --git a/packages/connector/test/unit/@node-red/registry/lib/resources/userDir/nodes/TestNode5/TestNode5.js b/packages/connector/test/unit/@node-red/registry/lib/resources/userDir/nodes/TestNode5/TestNode5.js new file mode 100644 index 0000000..c312558 --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/resources/userDir/nodes/TestNode5/TestNode5.js @@ -0,0 +1 @@ +throw new Error("fail to require"); diff --git a/packages/connector/test/unit/@node-red/registry/lib/util_spec.js b/packages/connector/test/unit/@node-red/registry/lib/util_spec.js new file mode 100644 index 0000000..a82519d --- /dev/null +++ b/packages/connector/test/unit/@node-red/registry/lib/util_spec.js @@ -0,0 +1,20 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +describe("red/nodes/registry/util",function() { + it.skip("NEEDS TESTS"); +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/api/comms_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/api/comms_spec.js new file mode 100644 index 0000000..df423b7 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/api/comms_spec.js @@ -0,0 +1,246 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); + +var NR_TEST_UTILS = require("nr-test-utils"); +var comms = NR_TEST_UTILS.require("@node-red/runtime/lib/api/comms"); + +describe("runtime-api/comms", function() { + describe("listens for events", function() { + var messages = []; + var clientConnection = { + send: function(topic,data) { + messages.push({topic,data}) + } + } + var eventHandlers = {}; + before(function(done) { + comms.init({ + log: { + trace: function(){} + }, + events: { + removeListener: function() {}, + on: function(evt,handler) { + eventHandlers[evt] = handler; + } + } + }) + comms.addConnection({client: clientConnection}).then(done); + }) + after(function(done) { + comms.removeConnection({client: clientConnection}).then(done); + }) + afterEach(function() { + messages = []; + }) + + it('runtime events',function(){ + eventHandlers.should.have.property('runtime-event'); + eventHandlers['runtime-event']({ + id: "my-event", + payload: "my-payload" + }) + messages.should.have.length(1); + messages[0].should.have.property("topic","notification/my-event"); + messages[0].should.have.property("data","my-payload") + }) + it('status events',function(){ + eventHandlers.should.have.property('node-status'); + eventHandlers['node-status']({ + id: "my-event", + status: {text:"my-status",badProperty:"should be filtered"} + }) + messages.should.have.length(1); + messages[0].should.have.property("topic","status/my-event"); + messages[0].should.have.property("data"); + messages[0].data.should.have.property("text","my-status"); + messages[0].data.should.not.have.property("badProperty"); + + }) + it('comms events',function(){ + eventHandlers.should.have.property('runtime-event'); + eventHandlers['comms']({ + topic: "my-topic", + data: "my-payload" + }) + messages.should.have.length(1); + messages[0].should.have.property("topic","my-topic"); + messages[0].should.have.property("data","my-payload") + }) + }); + describe("manages connections", function() { + var eventHandlers = {}; + var messages = []; + var clientConnection1 = { + send: function(topic,data) { + messages.push({topic,data}) + } + } + var clientConnection2 = { + send: function(topic,data) { + messages.push({topic,data}) + } + } + before(function() { + comms.init({ + log: { + trace: function(){} + }, + events: { + removeListener: function() {}, + on: function(evt,handler) { + eventHandlers[evt] = handler; + } + } + }) + }) + afterEach(function(done) { + comms.removeConnection({client: clientConnection1}).then(function() { + comms.removeConnection({client: clientConnection2}).then(done); + }); + messages = []; + }) + it('adds new connections',function(done){ + eventHandlers['comms']({ + topic: "my-topic", + data: "my-payload" + }) + messages.should.have.length(0); + comms.addConnection({client: clientConnection1}).then(function() { + eventHandlers['comms']({ + topic: "my-topic", + data: "my-payload" + }) + messages.should.have.length(1); + comms.addConnection({client: clientConnection2}).then(function() { + eventHandlers['comms']({ + topic: "my-topic", + data: "my-payload" + }) + messages.should.have.length(3); + done(); + }).catch(done); + }); + }); + it('removes connections',function(done){ + eventHandlers['comms']({ + topic: "my-topic", + data: "my-payload" + }) + messages.should.have.length(0); + comms.addConnection({client: clientConnection1}).then(function() { + comms.addConnection({client: clientConnection2}).then(function() { + eventHandlers['comms']({ + topic: "my-topic", + data: "my-payload" + }) + messages.should.have.length(2); + comms.removeConnection({client: clientConnection1}).then(function() { + eventHandlers['comms']({ + topic: "my-topic", + data: "my-payload" + }) + messages.should.have.length(3); + done(); + }); + }).catch(done); + }); + }) + }) + + describe("subscriptions", function() { + var messages = []; + var clientConnection = { + send: function(topic,data) { + messages.push({topic,data}) + } + } + var clientConnection2 = { + send: function(topic,data) { + messages.push({topic,data}) + } + } + var eventHandlers = {}; + before(function() { + comms.init({ + log: { + trace: function(){} + }, + events: { + removeListener: function() {}, + on: function(evt,handler) { + eventHandlers[evt] = handler; + } + } + }) + }) + afterEach(function(done) { + messages = []; + comms.removeConnection({client: clientConnection}).then(done); + }) + + it('subscribe triggers retained messages',function(done){ + eventHandlers['comms']({ + topic: "my-event", + data: "my-payload", + retain: true + }) + messages.should.have.length(0); + comms.addConnection({client: clientConnection}).then(function() { + return comms.subscribe({client: clientConnection, topic: "my-event"}).then(function() { + messages.should.have.length(1); + messages[0].should.have.property("topic","my-event"); + messages[0].should.have.property("data","my-payload"); + done(); + }); + }).catch(done); + }) + it('retained messages get cleared',function(done) { + eventHandlers['comms']({ + topic: "my-event", + data: "my-payload", + retain: true + }) + messages.should.have.length(0); + comms.addConnection({client: clientConnection}).then(function() { + return comms.subscribe({client: clientConnection, topic: "my-event"}).then(function() { + messages.should.have.length(1); + messages[0].should.have.property("topic","my-event"); + messages[0].should.have.property("data","my-payload"); + // Now we have a retained message, clear it + eventHandlers['comms']({ + topic: "my-event", + data: "my-payload-cleared" + }); + messages.should.have.length(2); + messages[1].should.have.property("topic","my-event"); + messages[1].should.have.property("data","my-payload-cleared"); + // Now add a second client and subscribe - no message should arrive + return comms.addConnection({client: clientConnection2}).then(function() { + return comms.subscribe({client: clientConnection2, topic: "my-event"}).then(function() { + messages.should.have.length(2); + done(); + }); + }); + }); + }).catch(done); + }); + }) + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/api/context_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/api/context_spec.js new file mode 100644 index 0000000..bf23e9c --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/api/context_spec.js @@ -0,0 +1,353 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +var should = require("should"); +var sinon = require("sinon"); + +var NR_TEST_UTILS = require("nr-test-utils"); +var context = NR_TEST_UTILS.require("@node-red/runtime/lib/api/context"); + +var mockLog = () => ({ + log: sinon.stub(), + debug: sinon.stub(), + trace: sinon.stub(), + warn: sinon.stub(), + info: sinon.stub(), + metric: sinon.stub(), + audit: sinon.stub(), + _: function() { return "abc";} +}); + +var mockContext = function(contents) { + return { + get: function(key,store,callback) { + if (contents.hasOwnProperty(store) && contents[store].hasOwnProperty(key)) { + callback(null,contents[store][key]); + } else { + callback(null,undefined); + } + }, + set: function (key, value, store, callback) { + if (contents.hasOwnProperty(store)) { + if (!value) { + delete contents[store][key]; + callback(null); + } + } else { + callback("err store"); + } + }, + keys: function (store, callback) { + if (contents.hasOwnProperty(store)) { + callback(null, Object.keys(contents[store])); + } else { + callback("err store"); + } + } + }; +}; + +describe("runtime-api/context", function() { + var globalContext, flowContext, nodeContext, contexts; + + beforeEach(function() { + globalContext = { default: { abc: 111 }, file: { abc: 222 } }; + flowContext = { default: { abc: 333 }, file: { abc: 444 } }; + nodeContext = { default: { abc: 555 }, file: { abc: 666 } }; + contexts = { + global: mockContext(globalContext), + flow1: mockContext(flowContext) + }; + context.init({ + nodes: { + listContextStores: function() { + return { default: 'default', stores: [ 'default', 'file' ] }; + }, + getContext: function(id) { + return contexts[id]; + }, + getNode: function(id) { + if (id === 'known') { + return { + context: function() { return mockContext(nodeContext); } + }; + } else { + return null; + } + } + }, + settings: { + functionGlobalContext: { + fgc:1234 + } + }, + log: mockLog() + }); + }); + + describe("getValue", function() { + it('gets global value of default store', function() { + return context.getValue({ + scope: 'global', + id: undefined, + store: undefined, // use default + key: 'abc' + }).then(function(result) { + result.should.have.property('msg','111'); + result.should.have.property('format','number'); + }); + }); + + it('gets global value of specified store', function() { + return context.getValue({ + scope: 'global', + id: undefined, + store: 'file', + key: 'abc' + }).then(function(result) { + result.should.have.property('msg','222'); + result.should.have.property('format','number'); + }); + }); + + it('gets flow value of default store', function() { + return context.getValue({ + scope: 'flow', + id: 'flow1', + store: undefined, // use default + key: 'abc' + }).then(function(result) { + result.should.have.property('msg','333'); + result.should.have.property('format','number'); + }); + }); + + it('gets flow value of specified store', function() { + return context.getValue({ + scope: 'flow', + id: 'flow1', + store: 'file', + key: 'abc' + }).then(function(result) { + result.should.have.property('msg','444'); + result.should.have.property('format','number'); + }); + }); + + it('gets node value of default store', function() { + return context.getValue({ + scope: 'node', + id: 'known', + store: undefined, // use default + key: 'abc' + }).then(function(result) { + result.should.have.property('msg','555'); + result.should.have.property('format','number'); + }); + }); + + it('gets node value of specified store', function() { + return context.getValue({ + scope: 'node', + id: 'known', + store: 'file', + key: 'abc' + }).then(function(result) { + result.should.have.property('msg','666'); + result.should.have.property('format','number'); + }); + }); + + it('404s for unknown store', function(done) { + context.getValue({ + scope: 'global', + id: undefined, + store: 'unknown', + key: 'abc' + }).then(function(result) { + done("getValue for unknown store should not resolve"); + }).catch(function(err) { + err.should.have.property('code','not_found'); + err.should.have.property('status',404); + done(); + }); + }); + + it('gets all global value properties', function() { + return context.getValue({ + scope: 'global', + id: undefined, + store: undefined, // use default + key: undefined, // + }).then(function(result) { + result.should.eql({ + default: { abc: { msg: '111', format: 'number' } }, + file: { abc: { msg: '222', format: 'number' } } + }); + }); + }); + + it('gets all flow value properties', function() { + return context.getValue({ + scope: 'flow', + id: 'flow1', + store: undefined, // use default + key: undefined, // + }).then(function(result) { + result.should.eql({ + default: { abc: { msg: '333', format: 'number' } }, + file: { abc: { msg: '444', format: 'number' } } + }); + }); + }); + + it('gets all node value properties', function() { + return context.getValue({ + scope: 'node', + id: 'known', + store: undefined, // use default + key: undefined, // + }).then(function(result) { + result.should.eql({ + default: { abc: { msg: '555', format: 'number' } }, + file: { abc: { msg: '666', format: 'number' } } + }); + }); + }); + + it('gets empty object when specified context doesn\'t exist', function() { + return context.getValue({ + scope: 'node', + id: 'non-existent', + store: 'file', + key: 'abc' + }).then(function(result) { + result.should.be.an.Object(); + result.should.be.empty(); + }); + }); + }); + + describe("delete", function () { + it('deletes global value of default store', function () { + return context.delete({ + scope: 'global', + id: undefined, + store: undefined, // use default + key: 'abc' + }).then(function () { + globalContext.should.eql({ + default: {}, file: { abc: 222 } + }); + }); + }); + + it('deletes global value of specified store', function () { + return context.delete({ + scope: 'global', + id: undefined, + store: 'file', + key: 'abc' + }).then(function () { + globalContext.should.eql({ + default: { abc: 111 }, file: {} + }); + }); + }); + + it('deletes flow value of default store', function () { + return context.delete({ + scope: 'flow', + id: 'flow1', + store: undefined, // use default + key: 'abc' + }).then(function () { + flowContext.should.eql({ + default: {}, file: { abc: 444 } + }); + }); + }); + + it('deletes flow value of specified store', function () { + return context.delete({ + scope: 'flow', + id: 'flow1', + store: 'file', + key: 'abc' + }).then(function () { + flowContext.should.eql({ + default: { abc: 333 }, file: {} + }); + }); + }); + + it('deletes node value of default store', function () { + return context.delete({ + scope: 'node', + id: 'known', + store: undefined, // use default + key: 'abc' + }).then(function () { + nodeContext.should.eql({ + default: {}, file: { abc: 666 } + }); + }); + }); + + it('deletes node value of specified store', function () { + return context.delete({ + scope: 'node', + id: 'known', + store: 'file', + key: 'abc' + }).then(function () { + nodeContext.should.eql({ + default: { abc: 555 }, file: {} + }); + }); + }); + + it('does nothing when specified context doesn\'t exist', function() { + return context.delete({ + scope: 'node', + id: 'non-existent', + store: 'file', + key: 'abc' + }).then(function(result) { + should.not.exist(result); + nodeContext.should.eql({ + default: { abc: 555 }, file: { abc: 666 } + }); + }); + }); + + it('404s for unknown store', function (done) { + context.delete({ + scope: 'global', + id: undefined, + store: 'unknown', + key: 'abc' + }).then(function () { + done("delete for unknown store should not resolve"); + }).catch(function (err) { + err.should.have.property('code', 'not_found'); + err.should.have.property('status', 404); + done(); + }); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/api/flows_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/api/flows_spec.js new file mode 100644 index 0000000..dafbbc6 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/api/flows_spec.js @@ -0,0 +1,426 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +var should = require("should"); +var sinon = require("sinon"); + +var NR_TEST_UTILS = require("nr-test-utils"); +var flows = NR_TEST_UTILS.require("@node-red/runtime/lib/api/flows") + +var mockLog = () => ({ + log: sinon.stub(), + debug: sinon.stub(), + trace: sinon.stub(), + warn: sinon.stub(), + info: sinon.stub(), + metric: sinon.stub(), + audit: sinon.stub(), + _: function() { return "abc"} +}) + +describe("runtime-api/flows", function() { + describe("getFlows", function() { + it("returns the current flow configuration", function(done) { + flows.init({ + log: mockLog(), + nodes: { + getFlows: function() { return [1,2,3] } + } + }); + flows.getFlows({}).then(function(result) { + result.should.eql([1,2,3]); + done(); + }).catch(done); + }); + }); + + describe("setFlows", function() { + var setFlows; + var loadFlows; + var reloadError = false; + beforeEach(function() { + setFlows = sinon.spy(function(flows,credentials,type) { + if (flows[0] === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } + return Promise.resolve("newRev"); + }); + loadFlows = sinon.spy(function() { + if (!reloadError) { + return Promise.resolve("newLoadRev"); + } else { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } + }) + flows.init({ + log: mockLog(), + nodes: { + getFlows: function() { return {rev:"currentRev",flows:[]} }, + setFlows: setFlows, + loadFlows: loadFlows + } + }) + + }) + it("defaults to full deploy", function(done) { + flows.setFlows({ + flows: {flows:[4,5,6]} + }).then(function(result) { + result.should.eql({rev:"newRev"}); + setFlows.called.should.be.true(); + setFlows.lastCall.args[0].should.eql([4,5,6]); + setFlows.lastCall.args[2].should.eql("full"); + done(); + }).catch(done); + }); + it("includes credentials when part of the request", function(done) { + flows.setFlows({ + flows: {flows:[4,5,6], credentials: {$:"creds"}}, + }).then(function(result) { + result.should.eql({rev:"newRev"}); + setFlows.called.should.be.true(); + setFlows.lastCall.args[0].should.eql([4,5,6]); + setFlows.lastCall.args[1].should.eql({$:"creds"}); + setFlows.lastCall.args[2].should.eql("full"); + done(); + }).catch(done); + }); + it("passes through other deploy types", function(done) { + flows.setFlows({ + deploymentType: "nodes", + flows: {flows:[4,5,6]} + }).then(function(result) { + result.should.eql({rev:"newRev"}); + setFlows.called.should.be.true(); + setFlows.lastCall.args[0].should.eql([4,5,6]); + setFlows.lastCall.args[2].should.eql("nodes"); + done(); + }).catch(done); + }); + it("triggers a flow reload", function(done) { + flows.setFlows({ + deploymentType: "reload" + }).then(function(result) { + result.should.eql({rev:"newLoadRev"}); + setFlows.called.should.be.false(); + loadFlows.called.should.be.true(); + done(); + }).catch(done); + }); + it("allows update when revision matches", function(done) { + flows.setFlows({ + deploymentType: "nodes", + flows: {flows:[4,5,6],rev:"currentRev"} + }).then(function(result) { + result.should.eql({rev:"newRev"}); + setFlows.called.should.be.true(); + setFlows.lastCall.args[0].should.eql([4,5,6]); + setFlows.lastCall.args[2].should.eql("nodes"); + done(); + }).catch(done); + }); + it("rejects update when revision does not match", function(done) { + flows.setFlows({ + deploymentType: "nodes", + flows: {flows:[4,5,6],rev:"notTheCurrentRev"} + }).then(function(result) { + done(new Error("Did not reject rev mismatch")); + }).catch(function(err) { + err.should.have.property('code','version_mismatch'); + err.should.have.property('status',409); + done(); + }).catch(done); + }); + it("rejects when reload fails",function(done) { + reloadError = true; + flows.setFlows({ + deploymentType: "reload" + }).then(function(result) { + done(new Error("Did not return internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + done(); + }).catch(done); + }); + it("rejects when update fails",function(done) { + flows.setFlows({ + deploymentType: "full", + flows: {flows:["error",5,6]} + }).then(function(result) { + done(new Error("Did not return internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + done(); + }).catch(done); + }); + }); + + describe("addFlow", function() { + var addFlow; + beforeEach(function() { + addFlow = sinon.spy(function(flow) { + if (flow === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } + return Promise.resolve("newId"); + }); + flows.init({ + log: mockLog(), + nodes: { + addFlow: addFlow + } + }); + }) + it("adds a flow", function(done) { + flows.addFlow({flow:{a:"123"}}).then(function(id) { + addFlow.called.should.be.true(); + addFlow.lastCall.args[0].should.eql({a:"123"}); + id.should.eql("newId"); + done() + }).catch(done); + }); + it("rejects when add fails", function(done) { + flows.addFlow({flow:"error"}).then(function(id) { + done(new Error("Did not return internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + done(); + }).catch(done); + }); + }); + describe("getFlow", function() { + var getFlow; + beforeEach(function() { + getFlow = sinon.spy(function(flow) { + if (flow === "unknown") { + return null; + } + return [1,2,3]; + }); + flows.init({ + log: mockLog(), + nodes: { + getFlow: getFlow + } + }); + }) + it("gets a flow", function(done) { + flows.getFlow({id:"123"}).then(function(flow) { + flow.should.eql([1,2,3]); + done() + }).catch(done); + }); + it("rejects when flow not found", function(done) { + flows.getFlow({id:"unknown"}).then(function(flow) { + done(new Error("Did not return internal error")); + }).catch(function(err) { + err.should.have.property('code','not_found'); + err.should.have.property('status',404); + done(); + }).catch(done); + }); + }); + + describe("updateFlow", function() { + var updateFlow; + beforeEach(function() { + updateFlow = sinon.spy(function(id,flow) { + if (id === "unknown") { + var err = new Error(); + // TODO: quirk of internal api - uses .code for .status + err.code = 404; + throw err; + } else if (id === "error") { + var err = new Error(); + // TODO: quirk of internal api - uses .code for .status + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } + return Promise.resolve(); + }); + flows.init({ + log: mockLog(), + nodes: { + updateFlow: updateFlow + } + }); + }) + it("updates a flow", function(done) { + flows.updateFlow({id:"123",flow:[1,2,3]}).then(function(id) { + id.should.eql("123"); + updateFlow.called.should.be.true(); + updateFlow.lastCall.args[0].should.eql("123"); + updateFlow.lastCall.args[1].should.eql([1,2,3]); + done() + }).catch(done); + }); + it("rejects when flow not found", function(done) { + flows.updateFlow({id:"unknown"}).then(function(flow) { + done(new Error("Did not return internal error")); + }).catch(function(err) { + err.should.have.property('code','not_found'); + err.should.have.property('status',404); + done(); + }).catch(done); + }); + it("rejects when update fails", function(done) { + flows.updateFlow({id:"error"}).then(function(flow) { + done(new Error("Did not return internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + + describe("deleteFlow", function() { + var removeFlow; + beforeEach(function() { + removeFlow = sinon.spy(function(flow) { + if (flow === "unknown") { + var err = new Error(); + // TODO: quirk of internal api - uses .code for .status + err.code = 404; + throw err; + } else if (flow === "error") { + var err = new Error(); + // TODO: quirk of internal api - uses .code for .status + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } + return Promise.resolve(); + }); + flows.init({ + log: mockLog(), + nodes: { + removeFlow: removeFlow + } + }); + }) + it("deletes a flow", function(done) { + flows.deleteFlow({id:"123"}).then(function() { + removeFlow.called.should.be.true(); + removeFlow.lastCall.args[0].should.eql("123"); + done() + }).catch(done); + }); + it("rejects when flow not found", function(done) { + flows.deleteFlow({id:"unknown"}).then(function(flow) { + done(new Error("Did not return internal error")); + }).catch(function(err) { + err.should.have.property('code','not_found'); + err.should.have.property('status',404); + done(); + }).catch(done); + }); + it("rejects when delete fails", function(done) { + flows.deleteFlow({id:"error"}).then(function(flow) { + done(new Error("Did not return internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("getNodeCredentials", function() { + beforeEach(function() { + flows.init({ + log: mockLog(), + nodes: { + getCredentials: function(id) { + if (id === "unknown") { + return undefined; + } else if (id === "known") { + return { + username: "abc", + password: "123" + } + } else if (id === "known2") { + return { + username: "abc", + password: "" + } + } else { + return {}; + } + }, + getCredentialDefinition: function(type) { + if (type === "node") { + return { + username: {type:"text"}, + password: {type:"password"} + } + } else { + return null; + } + } + } + }); + }) + it("returns an empty object for an unknown node", function(done) { + flows.getNodeCredentials({id:"unknown", type:"node"}).then(function(result) { + result.should.eql({}); + done(); + }).catch(done); + }); + it("gets the filtered credentials for a known node with password", function(done) { + flows.getNodeCredentials({id:"known", type:"node"}).then(function(result) { + result.should.eql({ + username: "abc", + has_password: true + }); + done(); + }).catch(done); + }); + it("gets the filtered credentials for a known node without password", function(done) { + flows.getNodeCredentials({id:"known2", type:"node"}).then(function(result) { + result.should.eql({ + username: "abc", + has_password: false + }); + done(); + }).catch(done); + }); + it("gets the empty credentials for a known node without a registered definition", function(done) { + flows.getNodeCredentials({id:"known2", type:"unknown-type"}).then(function(result) { + result.should.eql({}); + done(); + }).catch(done); + }); + }); + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/api/index_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/api/index_spec.js new file mode 100644 index 0000000..3cb0d56 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/api/index_spec.js @@ -0,0 +1,55 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); + +var NR_TEST_UTILS = require("nr-test-utils"); +var index = NR_TEST_UTILS.require("@node-red/runtime/lib/api/index"); + + +describe("runtime-api/index", function() { + before(function() { + ["comms","flows","nodes","settings","library","projects"].forEach(n => { + sinon.stub(NR_TEST_UTILS.require(`@node-red/runtime/lib/api/${n}`),"init",()=>{}); + }) + }); + after(function() { + ["comms","flows","nodes","settings","library","projects"].forEach(n => { + NR_TEST_UTILS.require(`@node-red/runtime/lib/api/${n}`).init.restore() + }) + }) + it('isStarted', function(done) { + index.init({ + isStarted: ()=>true + }); + index.isStarted({}).then(function(started) { + started.should.be.true(); + done(); + }).catch(done); + }) + + it('isStarted', function(done) { + index.init({ + version: ()=>"1.2.3.4" + }); + index.version({}).then(function(version) { + version.should.eql("1.2.3.4"); + done(); + }).catch(done); + }) + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/api/library_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/api/library_spec.js new file mode 100644 index 0000000..3fa5291 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/api/library_spec.js @@ -0,0 +1,167 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +var should = require("should"); +var sinon = require("sinon"); + +var NR_TEST_UTILS = require("nr-test-utils"); +var library = NR_TEST_UTILS.require("@node-red/runtime/lib/api/library") + +var mockLog = { + log: sinon.stub(), + debug: sinon.stub(), + trace: sinon.stub(), + warn: sinon.stub(), + info: sinon.stub(), + metric: sinon.stub(), + audit: sinon.stub(), + _: function() { return "abc"} +} + +describe("runtime-api/library", function() { + describe("getEntry", function() { + before(function() { + library.init({ + log: mockLog, + library: { + getEntry: function(library, type,path) { + if (type === "known") { + return Promise.resolve("known"); + } else if (type === "forbidden") { + var err = new Error("forbidden"); + err.code = "forbidden"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else if (type === "not_found") { + var err = new Error("forbidden"); + err.code = "not_found"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else if (type === "error") { + var err = new Error("error"); + err.code = "unknown_error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else if (type === "blank") { + return Promise.reject(); + } + } + } + }) + }) + it("returns a known entry", function(done) { + library.getEntry({library: "local",type: "known", path: "/abc"}).then(function(result) { + result.should.eql("known") + done(); + }).catch(done) + }) + it("rejects a forbidden entry", function(done) { + library.getEntry({library: "local",type: "forbidden", path: "/abc"}).then(function(result) { + done(new Error("did not reject")); + }).catch(function(err) { + err.should.have.property("code","forbidden"); + err.should.have.property("status",403); + done(); + }).catch(done) + }) + it("rejects an unknown entry", function(done) { + library.getEntry({library: "local",type: "not_found", path: "/abc"}).then(function(result) { + done(new Error("did not reject")); + }).catch(function(err) { + err.should.have.property("code","not_found"); + err.should.have.property("status",404); + done(); + }).catch(done) + }) + it("rejects a blank (unknown) entry", function(done) { + library.getEntry({library: "local",type: "blank", path: "/abc"}).then(function(result) { + done(new Error("did not reject")); + }).catch(function(err) { + err.should.have.property("code","not_found"); + err.should.have.property("status",404); + done(); + }).catch(done) + }) + it("rejects unexpected error", function(done) { + library.getEntry({library: "local",type: "error", path: "/abc"}).then(function(result) { + done(new Error("did not reject")); + }).catch(function(err) { + err.should.have.property("status",400); + done(); + }).catch(done) + }) + }) + describe("saveEntry", function() { + var opts; + before(function() { + library.init({ + log: mockLog, + library: { + saveEntry: function(library,type,path,meta,body) { + opts = {type,path,meta,body}; + if (type === "known") { + return Promise.resolve(); + } else if (type === "forbidden") { + var err = new Error("forbidden"); + err.code = "forbidden"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else if (type === "not_found") { + var err = new Error("forbidden"); + err.code = "not_found"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } + } + } + }) + }) + + it("saves an entry", function(done) { + library.saveEntry({library: "local",type: "known", path: "/abc", meta: {a:1}, body:"123"}).then(function() { + opts.should.have.property("type","known"); + opts.should.have.property("path","/abc"); + opts.should.have.property("meta",{a:1}); + opts.should.have.property("body","123"); + done(); + }).catch(done) + }) + it("rejects a forbidden entry", function(done) { + library.saveEntry({library: "local",type: "forbidden", path: "/abc", meta: {a:1}, body:"123"}).then(function() { + done(new Error("did not reject")); + }).catch(function(err) { + err.should.have.property("code","forbidden"); + err.should.have.property("status",403); + done(); + }).catch(done) + }) + it("rejects an unknown entry", function(done) { + library.saveEntry({library: "local",type: "not_found", path: "/abc", meta: {a:1}, body:"123"}).then(function() { + done(new Error("did not reject")); + }).catch(function(err) { + err.should.have.property("status",400); + done(); + }).catch(done) + }) + }) + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/api/nodes_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/api/nodes_spec.js new file mode 100644 index 0000000..6481c65 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/api/nodes_spec.js @@ -0,0 +1,1006 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); + +var NR_TEST_UTILS = require("nr-test-utils"); +var nodes = NR_TEST_UTILS.require("@node-red/runtime/lib/api/nodes") + +var mockLog = () => ({ + log: sinon.stub(), + debug: sinon.stub(), + trace: sinon.stub(), + warn: sinon.stub(), + info: sinon.stub(), + metric: sinon.stub(), + audit: sinon.stub(), + _: function() { return "abc"} +}) + +describe("runtime-api/nodes", function() { + describe("getNodeInfo", function() { + beforeEach(function() { + nodes.init({ + log: mockLog(), + nodes: { + getNodeInfo: function(id) { + if (id === "known") { + return {id:"known"}; + } else { + return null; + } + } + } + }); + }) + it("returns node info", function(done) { + nodes.getNodeInfo({id:"known"}).then(function(result) { + result.should.eql({id:"known"}); + done(); + }).catch(done); + }); + it("returns 404 if node not known", function(done) { + nodes.getNodeInfo({id:"unknown"}).then(function(result) { + done(new Error("Did not return internal error")); + }).catch(function(err) { + err.should.have.property('code','not_found'); + err.should.have.property('status',404); + done(); + }).catch(done); + }); + }); + describe("getNodeList", function() { + beforeEach(function() { + nodes.init({ + log: mockLog(), + nodes: { + getNodeList: function() { + return [1,2,3]; + } + } + }); + }) + it("returns node list", function(done) { + nodes.getNodeList({}).then(function(result) { + result.should.eql([1,2,3]); + done(); + }).catch(done); + }); + }); + + describe("getNodeConfig", function() { + beforeEach(function() { + nodes.init({ + log: mockLog(), + nodes: { + getNodeConfig: function(id,lang) { + if (id === "known") { + return id+lang; + } else { + return null; + } + } + } + }); + }) + it("returns node config", function(done) { + nodes.getNodeConfig({id:"known",lang:'lang'}).then(function(result) { + result.should.eql("knownlang"); + done(); + }).catch(done); + }); + it("returns 404 if node not known", function(done) { + nodes.getNodeConfig({id:"unknown",lang:'lang'}).then(function(result) { + done(new Error("Did not return internal error")); + }).catch(function(err) { + err.should.have.property('code','not_found'); + err.should.have.property('status',404); + done(); + }).catch(done); + }); + }); + + describe("getNodeConfigs", function() { + beforeEach(function() { + nodes.init({ + log: mockLog(), + nodes: { + getNodeConfigs: function(lang) { + return lang; + } + } + }); + }) + it("returns all node configs", function(done) { + nodes.getNodeConfigs({lang:'lang'}).then(function(result) { + result.should.eql("lang"); + done(); + }).catch(done); + }); + }); + + describe("getModuleInfo", function() { + beforeEach(function() { + nodes.init({ + log: mockLog(), + nodes: { + getModuleInfo: function(id) { + if (id === "known") { + return {module:"known"}; + } else { + return null; + } + } + } + }); + }) + it("returns node info", function(done) { + nodes.getModuleInfo({module:"known"}).then(function(result) { + result.should.eql({module:"known"}); + done(); + }).catch(done); + }); + it("returns 404 if node not known", function(done) { + nodes.getModuleInfo({module:"unknown"}).then(function(result) { + done(new Error("Did not return internal error")); + }).catch(function(err) { + err.should.have.property('code','not_found'); + err.should.have.property('status',404); + done(); + }).catch(done); + }); + }); + + describe.skip("addModule", function() {}); + describe.skip("removeModule", function() {}); + describe.skip("setModuleState", function() {}); + describe.skip("setNodeSetState", function() {}); + + describe.skip("getModuleCatalogs", function() {}); + describe.skip("getModuleCatalog", function() {}); + + describe.skip("getIconList", function() {}); + describe.skip("getIcon", function() {}); + + +}); + +/* +var should = require("should"); +var request = require('supertest'); +var express = require('express'); +var bodyParser = require('body-parser'); +var sinon = require('sinon'); +var when = require('when'); + +var nodes = require("../../../../red/api/admin/nodes"); +var apiUtil = require("../../../../red/api/util"); + +describe("api/admin/nodes", function() { + + var app; + function initNodes(runtime) { + runtime.log = { + audit:function(e){},//console.log(e)}, + _:function(){}, + info: function(){}, + warn: function(){} + } + runtime.events = { + emit: function(){} + } + nodes.init(runtime); + + } + + before(function() { + app = express(); + app.use(bodyParser.json()); + app.get("/nodes",nodes.getAll); + app.post("/nodes",nodes.post); + app.get(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,nodes.getModule); + app.get(/\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,nodes.getSet); + app.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,nodes.putModule); + app.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,nodes.putSet); + app.get("/getIcons",nodes.getIcons); + app.delete("/nodes/:id",nodes.delete); + sinon.stub(apiUtil,"determineLangFromHeaders", function() { + return "en-US"; + }); + }); + after(function() { + apiUtil.determineLangFromHeaders.restore(); + }) + + describe('get nodes', function() { + it('returns node list', function(done) { + initNodes({ + nodes:{ + getNodeList: function() { + return [1,2,3]; + } + } + }); + request(app) + .get('/nodes') + .set('Accept', 'application/json') + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.be.an.Array(); + res.body.should.have.lengthOf(3); + done(); + }); + }); + + it('returns node configs', function(done) { + initNodes({ + nodes:{ + getNodeConfigs: function() { + return "<script></script>"; + } + }, + i18n: { + determineLangFromHeaders: function(){} + } + }); + request(app) + .get('/nodes') + .set('Accept', 'text/html') + .expect(200) + .expect("<script></script>") + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + + it('returns node module info', function(done) { + initNodes({ + nodes:{ + getModuleInfo: function(id) { + return {"node-red":{name:"node-red"}}[id]; + } + } + }); + request(app) + .get('/nodes/node-red') + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("name","node-red"); + done(); + }); + }); + + it('returns 404 for unknown module', function(done) { + initNodes({ + nodes:{ + getModuleInfo: function(id) { + return {"node-red":{name:"node-red"}}[id]; + } + } + }); + request(app) + .get('/nodes/node-blue') + .expect(404) + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + + it('returns individual node info', function(done) { + initNodes({ + nodes:{ + getNodeInfo: function(id) { + return {"node-red/123":{id:"node-red/123"}}[id]; + } + } + }); + request(app) + .get('/nodes/node-red/123') + .set('Accept', 'application/json') + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("id","node-red/123"); + done(); + }); + }); + + it('returns individual node configs', function(done) { + initNodes({ + nodes:{ + getNodeConfig: function(id) { + return {"node-red/123":"<script></script>"}[id]; + } + }, + i18n: { + determineLangFromHeaders: function(){} + } + }); + request(app) + .get('/nodes/node-red/123') + .set('Accept', 'text/html') + .expect(200) + .expect("<script></script>") + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + + it('returns 404 for unknown node', function(done) { + initNodes({ + nodes:{ + getNodeInfo: function(id) { + return {"node-red/123":{id:"node-red/123"}}[id]; + } + } + }); + request(app) + .get('/nodes/node-red/456') + .set('Accept', 'application/json') + .expect(404) + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + }); + + describe('install', function() { + + it('returns 400 if settings are unavailable', function(done) { + initNodes({ + settings:{available:function(){return false}} + }); + request(app) + .post('/nodes') + .expect(400) + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + + it('returns 400 if request is invalid', function(done) { + initNodes({ + settings:{available:function(){return true}} + }); + request(app) + .post('/nodes') + .send({}) + .expect(400) + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + + describe('by module', function() { + it('installs the module and returns module info', function(done) { + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getModuleInfo: function(id) { return null; }, + installModule: function() { + return when.resolve({ + name:"foo", + nodes:[{id:"123"}] + }); + } + } + }); + request(app) + .post('/nodes') + .send({module: 'foo'}) + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("name","foo"); + res.body.should.have.property("nodes"); + res.body.nodes[0].should.have.property("id","123"); + done(); + }); + }); + + it('fails the install if already installed', function(done) { + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getModuleInfo: function(id) { return {nodes:{id:"123"}}; }, + installModule: function() { + return when.resolve({id:"123"}); + } + } + }); + request(app) + .post('/nodes') + .send({module: 'foo'}) + .expect(400) + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + + it('fails the install if module error', function(done) { + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getModuleInfo: function(id) { return null }, + installModule: function() { + return when.reject(new Error("test error")); + } + } + }); + request(app) + .post('/nodes') + .send({module: 'foo'}) + .expect(400) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("message","Error: test error"); + done(); + }); + }); + it('fails the install if module not found', function(done) { + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getModuleInfo: function(id) { return null }, + installModule: function() { + var err = new Error("test error"); + err.code = 404; + return when.reject(err); + } + } + }); + request(app) + .post('/nodes') + .send({module: 'foo'}) + .expect(404) + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + }); + }); + describe('delete', function() { + it('returns 400 if settings are unavailable', function(done) { + initNodes({ + settings:{available:function(){return false}} + }); + + request(app) + .del('/nodes/123') + .expect(400) + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + + describe('by module', function() { + it('uninstalls the module', function(done) { + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getModuleInfo: function(id) { return {nodes:[{id:"123"}]} }, + getNodeInfo: function() { return null }, + uninstallModule: function() { return when.resolve({id:"123"});} + } + }); + request(app) + .del('/nodes/foo') + .expect(204) + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + + it('fails the uninstall if the module is not installed', function(done) { + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getModuleInfo: function(id) { return null }, + getNodeInfo: function() { return null } + } + }); + request(app) + .del('/nodes/foo') + .expect(404) + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + + it('fails the uninstall if the module is not installed', function(done) { + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getModuleInfo: function(id) { return {nodes:[{id:"123"}]} }, + getNodeInfo: function() { return null }, + uninstallModule: function() { return when.reject(new Error("test error"));} + } + }); + request(app) + .del('/nodes/foo') + .expect(400) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("message","Error: test error"); + done(); + }); + }); + }); + + }); + + describe('enable/disable', function() { + it('returns 400 if settings are unavailable', function(done) { + initNodes({ + settings:{available:function(){return false}} + }); + request(app) + .put('/nodes/123') + .expect(400) + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + + it('returns 400 for invalid node payload', function(done) { + initNodes({ + settings:{available:function(){return true}} + }); + request(app) + .put('/nodes/node-red/foo') + .send({}) + .expect(400) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("message","Invalid request"); + done(); + }); + }); + + it('returns 400 for invalid module payload', function(done) { + initNodes({ + settings:{available:function(){return true}} + }); + request(app) + .put('/nodes/foo') + .send({}) + .expect(400) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("message","Invalid request"); + + done(); + }); + }); + + it('returns 404 for unknown node', function(done) { + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getNodeInfo: function() { return null } + } + }); + + request(app) + .put('/nodes/node-red/foo') + .send({enabled:false}) + .expect(404) + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + + it('returns 404 for unknown module', function(done) { + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getModuleInfo: function(id) { return null } + } + }); + + request(app) + .put('/nodes/node-blue') + .send({enabled:false}) + .expect(404) + .end(function(err,res) { + if (err) { + throw err; + } + done(); + }); + }); + + it('enables disabled node', function(done) { + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getNodeInfo: function() { return {id:"123",enabled: false} }, + enableNode: function() { return when.resolve({id:"123",enabled: true,types:['a']}); } + } + }); + request(app) + .put('/nodes/node-red/foo') + .send({enabled:true}) + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("id","123"); + res.body.should.have.property("enabled",true); + + done(); + }); + }); + + it('disables enabled node', function(done) { + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getNodeInfo: function() { return {id:"123",enabled: true} }, + disableNode: function() { return when.resolve({id:"123",enabled: false,types:['a']}); } + } + }); + request(app) + .put('/nodes/node-red/foo') + .send({enabled:false}) + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("id","123"); + res.body.should.have.property("enabled",false); + + done(); + }); + }); + + describe('no-ops if already in the right state', function() { + function run(state,done) { + var enableNode = sinon.spy(function() { return when.resolve({id:"123",enabled: true,types:['a']}) }); + var disableNode = sinon.spy(function() { return when.resolve({id:"123",enabled: false,types:['a']}) }); + + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getNodeInfo: function() { return {id:"123",enabled: state} }, + enableNode: enableNode, + disableNode: disableNode + } + }); + request(app) + .put('/nodes/node-red/foo') + .send({enabled:state}) + .expect(200) + .end(function(err,res) { + var enableNodeCalled = enableNode.called; + var disableNodeCalled = disableNode.called; + if (err) { + throw err; + } + enableNodeCalled.should.be.false(); + disableNodeCalled.should.be.false(); + res.body.should.have.property("id","123"); + res.body.should.have.property("enabled",state); + + done(); + }); + } + it('already enabled', function(done) { + run(true,done); + }); + it('already disabled', function(done) { + run(false,done); + }); + }); + + describe('does not no-op if err on node', function() { + function run(state,done) { + var enableNode = sinon.spy(function() { return when.resolve({id:"123",enabled: true,types:['a']}) }); + var disableNode = sinon.spy(function() { return when.resolve({id:"123",enabled: false,types:['a']}) }); + + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getNodeInfo: function() { return {id:"123",enabled: state, err:"foo"} }, + enableNode: enableNode, + disableNode: disableNode + } + }); + request(app) + .put('/nodes/node-red/foo') + .send({enabled:state}) + .expect(200) + .end(function(err,res) { + var enableNodeCalled = enableNode.called; + var disableNodeCalled = disableNode.called; + if (err) { + throw err; + } + enableNodeCalled.should.be.equal(state); + disableNodeCalled.should.be.equal(!state); + res.body.should.have.property("id","123"); + res.body.should.have.property("enabled",state); + + done(); + }); + } + it('already enabled', function(done) { + run(true,done); + }); + it('already disabled', function(done) { + run(false,done); + }); + }); + + it('enables disabled module', function(done) { + var n1 = {id:"123",enabled:false,types:['a']}; + var n2 = {id:"456",enabled:false,types:['b']}; + var enableNode = sinon.stub(); + enableNode.onFirstCall().returns((function() { + n1.enabled = true; + return when.resolve(n1); + })()); + enableNode.onSecondCall().returns((function() { + n2.enabled = true; + return when.resolve(n2); + })()); + enableNode.returns(null); + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getModuleInfo: function() { return {name:"node-red", nodes:[n1, n2]} }, + enableNode: enableNode + } + }); + + request(app) + .put('/nodes/node-red') + .send({enabled:true}) + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("name","node-red"); + res.body.should.have.property("nodes"); + res.body.nodes[0].should.have.property("enabled",true); + res.body.nodes[1].should.have.property("enabled",true); + + done(); + }); + }); + + it('disables enabled module', function(done) { + var n1 = {id:"123",enabled:true,types:['a']}; + var n2 = {id:"456",enabled:true,types:['b']}; + var disableNode = sinon.stub(); + disableNode.onFirstCall().returns((function() { + n1.enabled = false; + return when.resolve(n1); + })()); + disableNode.onSecondCall().returns((function() { + n2.enabled = false; + return when.resolve(n2); + })()); + disableNode.returns(null); + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getModuleInfo: function() { return {name:"node-red", nodes:[n1, n2]} }, + disableNode: disableNode + } + }); + + request(app) + .put('/nodes/node-red') + .send({enabled:false}) + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + res.body.should.have.property("name","node-red"); + res.body.should.have.property("nodes"); + res.body.nodes[0].should.have.property("enabled",false); + res.body.nodes[1].should.have.property("enabled",false); + + done(); + }); + }); + + describe('no-ops if a node in module already in the right state', function() { + function run(state,done) { + var node = {id:"123",enabled:state,types:['a']}; + var enableNode = sinon.spy(function(id) { + node.enabled = true; + return when.resolve(node); + }); + var disableNode = sinon.spy(function(id) { + node.enabled = false; + return when.resolve(node); + }); + + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getModuleInfo: function() { return {name:"node-red", nodes:[node]}; }, + enableNode: enableNode, + disableNode: disableNode + } + }); + request(app) + .put('/nodes/node-red') + .send({enabled:state}) + .expect(200) + .end(function(err,res) { + var enableNodeCalled = enableNode.called; + var disableNodeCalled = disableNode.called; + if (err) { + throw err; + } + enableNodeCalled.should.be.false(); + disableNodeCalled.should.be.false(); + res.body.should.have.property("name","node-red"); + res.body.should.have.property("nodes"); + res.body.nodes[0].should.have.property("enabled",state); + + done(); + }); + } + it('already enabled', function(done) { + run(true,done); + }); + it('already disabled', function(done) { + run(false,done); + }); + }); + + describe('does not no-op if err on a node in module', function() { + function run(state,done) { + var node = {id:"123",enabled:state,types:['a'],err:"foo"}; + var enableNode = sinon.spy(function(id) { + node.enabled = true; + return when.resolve(node); + }); + var disableNode = sinon.spy(function(id) { + node.enabled = false; + return when.resolve(node); + }); + + initNodes({ + settings:{available:function(){return true}}, + nodes:{ + getModuleInfo: function() { return {name:"node-red", nodes:[node]}; }, + enableNode: enableNode, + disableNode: disableNode + } + }); + + request(app) + .put('/nodes/node-red') + .send({enabled:state}) + .expect(200) + .end(function(err,res) { + var enableNodeCalled = enableNode.called; + var disableNodeCalled = disableNode.called; + if (err) { + throw err; + } + enableNodeCalled.should.be.equal(state); + disableNodeCalled.should.be.equal(!state); + res.body.should.have.property("name","node-red"); + res.body.should.have.property("nodes"); + res.body.nodes[0].should.have.property("enabled",state); + + done(); + }); + } + it('already enabled', function(done) { + run(true,done); + }); + it('already disabled', function(done) { + run(false,done); + }); + }); + }); + + describe('get icons', function() { + it('returns icon list', function(done) { + initNodes({ + nodes:{ + getNodeIcons: function() { + return {"module":["1.png","2.png","3.png"]}; + } + } + }); + request(app) + .get('/getIcons') + .expect(200) + .end(function(err,res) { + if (err) { + throw err; + } + console.log(res.body); + res.body.should.have.property("module"); + res.body.module.should.be.an.Array(); + res.body.module.should.have.lengthOf(3); + done(); + }); + }); + }); +}); + +*/ diff --git a/packages/connector/test/unit/@node-red/runtime/lib/api/projects_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/api/projects_spec.js new file mode 100644 index 0000000..2fe7ca2 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/api/projects_spec.js @@ -0,0 +1,1170 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); + +var NR_TEST_UTILS = require("nr-test-utils"); +var projects = NR_TEST_UTILS.require("@node-red/runtime/lib/api/projects") + +var mockLog = () => ({ + log: sinon.stub(), + debug: sinon.stub(), + trace: sinon.stub(), + warn: sinon.stub(), + info: sinon.stub(), + metric: sinon.stub(), + audit: sinon.stub(), + _: function() { return "abc"} +}) + +describe("runtime-api/settings", function() { + describe("available", function() { + it("resolves true if projects available", function(done) { + projects.init({ + storage: { + projects: {} + } + }); + projects.available().then(function(result) { + result.should.be.true(); + done(); + }).catch(done); + }) + it("resolves false if projects unavailable", function(done) { + projects.init({ + storage: { + } + }); + projects.available().then(function(result) { + result.should.be.false(); + done(); + }).catch(done); + }) + + }); + describe("listProjects", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + listProjects: sinon.spy(function(user) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve([1,2,3]); + } + }), + getActiveProject: function(user) { + if (user === "noActive") { + return null; + } + return {name:"aProject"}; + } + }}}; + before(function() { + projects.init(runtime); + }) + it("lists the projects, without an active project", function(done) { + projects.listProjects({user:"noActive"}).then(function(result) { + result.should.have.property('projects',[1,2,3]); + result.should.not.have.property('active'); + done(); + }).catch(done); + }); + it("lists the projects, with an active project", function(done) { + projects.listProjects({user:"foo"}).then(function(result) { + result.should.have.property('projects',[1,2,3]); + result.should.have.property('active','aProject'); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.listProjects({user:"error"}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + err.should.have.property('status',400); + done(); + }).catch(done); + }); + + }); + describe("createProject", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + createProject: sinon.spy(function(user,project) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve(project); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("create project", function(done) { + projects.createProject({user:"known",project:{a:1}}).then(function(result) { + result.should.eql({a:1}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.createProject({user:"error"}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + describe("initialiseProject", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + initialiseProject: sinon.spy(function(user,id,project) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({id,project}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("intialise project", function(done) { + projects.initialiseProject({user:"known",id:123, project:{a:1}}).then(function(result) { + result.should.eql({id:123, project:{a:1}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.initialiseProject({user:"error"}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("getActiveProject", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + getActiveProject: sinon.spy(function(user) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve("123"); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("returns active project", function(done) { + projects.getActiveProject({user:"known"}).then(function(result) { + result.should.eql("123"); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.getActiveProject({user:"error"}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("setActiveProject", function() { + var activeProject; + var runtime; + beforeEach(function() { + runtime = { + log: mockLog(), + storage: {projects: { + getActiveProject: sinon.spy(function() { return activeProject;}), + setActiveProject: sinon.spy(function(user,id) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id}); + } + }) + }}}; + projects.init(runtime); + }) + it("sets project if current project is unset", function(done) { + activeProject = null; + projects.setActiveProject({user:"known",id:123}).then(function(result) { + result.should.eql({user:"known",id:123}); + done(); + }).catch(done); + }); + it("sets project if current project is different", function(done) { + activeProject = {name:456}; + projects.setActiveProject({user:"known",id:123}).then(function(result) { + result.should.eql({user:"known",id:123}); + done(); + }).catch(done); + }); + it("no-ops if current project is same", function(done) { + activeProject = {name:123}; + projects.setActiveProject({user:"known",id:123}).then(function(result) { + (result === undefined).should.be.true(); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.setActiveProject({user:"error"}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("getProject", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + getProject: sinon.spy(function(user,id) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("returns project", function(done) { + projects.getProject({user:"known",id:123}).then(function(result) { + result.should.eql({user:"known",id:123}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.getProject({user:"error"}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + describe("updateProject", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + updateProject: sinon.spy(function(user,id,project) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,project}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("updates project", function(done) { + projects.updateProject({user:"known",id:123,project:{a:1}}).then(function(result) { + result.should.eql({user:"known",id:123,project:{a:1}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.updateProject({user:"error",id:123,project:{a:1}}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("deleteProject", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + deleteProject: sinon.spy(function(user,id) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("deletes project", function(done) { + projects.deleteProject({user:"known",id:123}).then(function(result) { + result.should.eql({user:"known",id:123}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.deleteProject({user:"error",id:123}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("getStatus", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + getStatus: sinon.spy(function(user,id,remote) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,remote}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("gets status", function(done) { + projects.getStatus({user:"known",id:123,remote:{a:1}}).then(function(result) { + result.should.eql({user:"known",id:123,remote:{a:1}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.getStatus({user:"error",id:123,project:{a:1}}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + describe("getBranches", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + getBranches: sinon.spy(function(user,id,remote) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,remote}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("gets branches", function(done) { + projects.getBranches({user:"known",id:123,remote:{a:1}}).then(function(result) { + result.should.eql({user:"known",id:123,remote:{a:1}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.getBranches({user:"error",id:123,remote:{a:1}}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + describe("getBranchStatus", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + getBranchStatus: sinon.spy(function(user,id,branch) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,branch}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("gets branch status", function(done) { + projects.getBranchStatus({user:"known",id:123,branch:{a:1}}).then(function(result) { + result.should.eql({user:"known",id:123,branch:{a:1}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.getBranchStatus({user:"error",id:123,branch:{a:1}}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("setBranch", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + setBranch: sinon.spy(function(user,id,branch,create) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,branch,create}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("commits", function(done) { + projects.setBranch({user:"known",id:123,branch:{a:1},create:true}).then(function(result) { + result.should.eql({user:"known",id:123,branch:{a:1},create:true}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.setBranch({user:"error",id:123,branch:{a:1},create:true}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("deleteBranch", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + deleteBranch: sinon.spy(function(user,id,branch,something,force) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,branch,force}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("commits", function(done) { + projects.deleteBranch({user:"known",id:123,branch:{a:1},force:true}).then(function(result) { + result.should.eql({user:"known",id:123,branch:{a:1},force:true}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.deleteBranch({user:"error",id:123,branch:{a:1},force:true}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("commit", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + commit: sinon.spy(function(user,id,message) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,message}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("commits", function(done) { + projects.commit({user:"known",id:123,message:{a:1}}).then(function(result) { + result.should.eql({user:"known",id:123,message:{message:{a:1}}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.commit({user:"error",id:123,message:{a:1}}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + describe("getCommit", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + getCommit: sinon.spy(function(user,id,sha) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,sha}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("gets commit", function(done) { + projects.getCommit({user:"known",id:123,sha:{a:1}}).then(function(result) { + result.should.eql({user:"known",id:123,sha:{a:1}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.getCommit({user:"error",id:123,sha:{a:1}}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("getCommits", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + getCommits: sinon.spy(function(user,id,options) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,options}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("gets commits with default limit/before", function(done) { + projects.getCommits({user:"known",id:123}).then(function(result) { + result.should.eql({user:"known",id:123,options:{limit:20,before:undefined}}); + done(); + }).catch(done); + }); + it("gets commits with provided limit/before", function(done) { + projects.getCommits({user:"known",id:123,limit:10,before:456}).then(function(result) { + result.should.eql({user:"known",id:123,options:{limit:10,before:456}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.getCommits({user:"error"}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("abortMerge", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + abortMerge: sinon.spy(function(user,id) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("aborts merge", function(done) { + projects.abortMerge({user:"known",id:123}).then(function(result) { + result.should.eql({user:"known",id:123}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.abortMerge({user:"error"}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("resolveMerge", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + resolveMerge: sinon.spy(function(user,id,path,resolution) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,path,resolution}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("resolves merge", function(done) { + projects.resolveMerge({user:"known",id:123,path:"/abc",resolution:{a:1}}).then(function(result) { + result.should.eql({user:"known",id:123,path:"/abc",resolution:{a:1}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.resolveMerge({user:"error",id:123,path:"/abc",resolution:{a:1}}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("getFiles", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + getFiles: sinon.spy(function(user,id) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("gets files", function(done) { + projects.getFiles({user:"known",id:123}).then(function(result) { + result.should.eql({user:"known",id:123}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.getFiles({user:"error"}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("getFile", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + getFile: sinon.spy(function(user,id,path,tree) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,path,tree}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("gets file", function(done) { + projects.getFile({user:"known",id:123,path:"/abc",tree:{a:1}}).then(function(result) { + result.should.eql({user:"known",id:123,path:"/abc",tree:{a:1}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.getFile({user:"error",id:123,path:"/abc",tree:{a:1}}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("stageFile", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + stageFile: sinon.spy(function(user,id,path) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,path}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("stages a file", function(done) { + projects.stageFile({user:"known",id:123,path:{a:1}}).then(function(result) { + result.should.eql({user:"known",id:123,path:{a:1}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.stageFile({user:"error",id:123,path:{a:1}}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + describe("unstageFile", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + unstageFile: sinon.spy(function(user,id,path) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,path}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("unstages a file", function(done) { + projects.unstageFile({user:"known",id:123,path:{a:1}}).then(function(result) { + result.should.eql({user:"known",id:123,path:{a:1}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.unstageFile({user:"error",id:123,path:{a:1}}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("revertFile", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + revertFile: sinon.spy(function(user,id,path) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,path}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("reverts a file", function(done) { + projects.revertFile({user:"known",id:123,path:{a:1}}).then(function(result) { + result.should.eql({user:"known",id:123,path:{a:1}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.revertFile({user:"error",id:123,path:{a:1}}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("getFileDiff", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + getFileDiff: sinon.spy(function(user,id,path,type) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,path,type}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("gets file diff", function(done) { + projects.getFileDiff({user:"known",id:123,path:{a:1},type:"abc"}).then(function(result) { + result.should.eql({user:"known",id:123,path:{a:1},type:"abc"}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.getFileDiff({user:"error",id:123,path:{a:1},type:"abc"}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("getRemotes", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + getRemotes: sinon.spy(function(user,id) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("gets remotes", function(done) { + projects.getRemotes({user:"known",id:123}).then(function(result) { + result.should.eql({user:"known",id:123}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.getRemotes({user:"error"}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("addRemote", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + addRemote: sinon.spy(function(user,id,remote) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,remote}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("adds a remote", function(done) { + projects.addRemote({user:"known",id:123,remote:{a:1}}).then(function(result) { + result.should.eql({user:"known",id:123,remote:{a:1}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.addRemote({user:"error",id:123,remote:{a:1}}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("removeRemote", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + removeRemote: sinon.spy(function(user,id,remote) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,remote}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("removes a remote", function(done) { + projects.removeRemote({user:"known",id:123,remote:{a:1}}).then(function(result) { + result.should.eql({user:"known",id:123,remote:{a:1}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.removeRemote({user:"error",id:123,remote:{a:1}}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + describe("updateRemote", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + updateRemote: sinon.spy(function(user,id,name,remote) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,name,remote}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("updates a remote", function(done) { + projects.updateRemote({user:"known",id:123,remote:{name:"abc",a:1}}).then(function(result) { + result.should.eql({user:"known",id:123,name:"abc",remote:{name:"abc",a:1}}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.updateRemote({user:"error",id:123,remote:{name:"abc",a:1}}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + describe("pull", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + pull: sinon.spy(function(user,id,remote,track,allowUnrelatedHistories) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,remote,track,allowUnrelatedHistories}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("pulls", function(done) { + projects.pull({user:"known",id:123,remote:"abc",track:false,allowUnrelatedHistories:true}).then(function(result) { + result.should.eql({user:"known",id:123,remote:"abc",track:false,allowUnrelatedHistories:true}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.pull({user:"error",id:123,remote:"abc",track:false,allowUnrelatedHistories:true}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + describe("push", function() { + var runtime = { + log: mockLog(), + storage: {projects: { + push: sinon.spy(function(user,id,remote,track) { + if (user === "error") { + var err = new Error("error"); + err.code = "error"; + var p = Promise.reject(err); + p.catch(()=>{}); + return p; + } else { + return Promise.resolve({user,id,remote,track}); + } + }) + }}}; + before(function() { + projects.init(runtime); + }) + it("pulls", function(done) { + projects.push({user:"known",id:123,remote:"abc",track:false}).then(function(result) { + result.should.eql({user:"known",id:123,remote:"abc",track:false}); + done(); + }).catch(done); + }); + it("rejects with internal error", function(done) { + projects.push({user:"error",id:123,remote:"abc",track:false}).then(function(result) { + done(new Error("Did not reject internal error")); + }).catch(function(err) { + err.should.have.property('code','error'); + // err.should.have.property('status',400); + done(); + }).catch(done); + }); + }); + + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/api/settings_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/api/settings_spec.js new file mode 100644 index 0000000..dbc5567 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/api/settings_spec.js @@ -0,0 +1,900 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +var should = require("should"); +var sinon = require("sinon"); +var clone = require("clone"); + +var NR_TEST_UTILS = require("nr-test-utils"); +var settings = NR_TEST_UTILS.require("@node-red/runtime/lib/api/settings") + +var mockLog = () => ({ + log: sinon.stub(), + debug: sinon.stub(), + trace: sinon.stub(), + warn: sinon.stub(), + info: sinon.stub(), + metric: sinon.stub(), + audit: sinon.stub(), + _: function() { return "abc"} +}) + +describe("runtime-api/settings", function() { + describe("getRuntimeSettings", function() { + it("gets the runtime settings", function() { + settings.init({ + settings: { + foo: 123, + httpNodeRoot: "testHttpNodeRoot", + version: "testVersion", + paletteCategories :["red","blue","green"], + exportNodeSettings: (obj) => { + obj.testNodeSetting = "helloWorld"; + } + }, + nodes: { + listContextStores: () => { return {stores:["file","memory"], default: "file"} }, + paletteEditorEnabled: () => false, + getCredentialKeyType: () => "test-key-type" + }, + storage: {} + }) + return settings.getRuntimeSettings({}).then(result => { + result.should.have.property("httpNodeRoot","testHttpNodeRoot"); + result.should.have.property("version","testVersion"); + result.should.have.property("paletteCategories",["red","blue","green"]); + result.should.have.property("testNodeSetting","helloWorld"); + result.should.not.have.property("foo",123); + result.should.have.property("flowEncryptionType","test-key-type"); + result.should.not.have.property("user"); + result.should.have.property("editorTheme"); + result.editorTheme.should.eql({palette:{editable:false}}); + + }) + }); + it("gets the filtered user settings", function() { + settings.init({ + settings: { + foo: 123, + httpNodeRoot: "testHttpNodeRoot", + version: "testVersion", + paletteCategories :["red","blue","green"], + exportNodeSettings: (obj) => { + obj.testNodeSetting = "helloWorld"; + } + }, + nodes: { + listContextStores: () => { return {stores:["file","memory"], default: "file"} }, + paletteEditorEnabled: () => false, + getCredentialKeyType: () => "test-key-type" + }, + storage: {} + }) + return settings.getRuntimeSettings({ + user: { + username: "nick", + anonymous: false, + image: "http://example.com", + permissions: "*", + private: "secret" + } + }).then(result => { + result.should.have.property("user"); + result.user.should.have.property("username","nick"); + result.user.should.have.property("permissions","*"); + result.user.should.have.property("image","http://example.com"); + result.user.should.have.property("anonymous",false); + result.user.should.not.have.property("private"); + }) + }); + + it('includes project settings if projects available', function() { + settings.init({ + settings: { + foo: 123, + httpNodeRoot: "testHttpNodeRoot", + version: "testVersion", + paletteCategories :["red","blue","green"], + exportNodeSettings: (obj) => { + obj.testNodeSetting = "helloWorld"; + } + }, + nodes: { + listContextStores: () => { return {stores:["file","memory"], default: "file"} }, + paletteEditorEnabled: () => false, + getCredentialKeyType: () => "test-key-type" + }, + storage: { + projects: { + getActiveProject: () => 'test-active-project', + getFlowFilename: () => 'test-flow-file', + getCredentialsFilename: () => 'test-creds-file', + getGlobalGitUser: () => {return {name:'foo',email:'foo@example.com'}} + } + } + }) + return settings.getRuntimeSettings({ + user: { + username: "nick", + anonymous: false, + image: "http://example.com", + permissions: "*", + private: "secret" + } + }).then(result => { + result.should.have.property("project","test-active-project"); + result.should.not.have.property("files"); + result.should.have.property("git"); + result.git.should.have.property("globalUser",{name:'foo',email:'foo@example.com'}); + }); + }); + + it('includes existing files details if projects enabled but no active project and files exist', function() { + settings.init({ + settings: { + foo: 123, + httpNodeRoot: "testHttpNodeRoot", + version: "testVersion", + paletteCategories :["red","blue","green"], + exportNodeSettings: (obj) => { + obj.testNodeSetting = "helloWorld"; + } + }, + nodes: { + listContextStores: () => { return {stores:["file","memory"], default: "file"} }, + paletteEditorEnabled: () => false, + getCredentialKeyType: () => "test-key-type" + }, + storage: { + projects: { + flowFileExists: () => true, + getActiveProject: () => false, + getFlowFilename: () => 'test-flow-file', + getCredentialsFilename: () => 'test-creds-file', + getGlobalGitUser: () => {return {name:'foo',email:'foo@example.com'}} + } + } + }) + return settings.getRuntimeSettings({ + user: { + username: "nick", + anonymous: false, + image: "http://example.com", + permissions: "*", + private: "secret" + } + }).then(result => { + result.git.should.have.property("globalUser",{name:'foo',email:'foo@example.com'}); + result.should.not.have.property("project"); + result.should.have.property("files"); + result.files.should.have.property("flow",'test-flow-file'); + result.files.should.have.property("credentials",'test-creds-file'); + result.should.have.property("git"); + result.git.should.have.property("globalUser",{name:'foo',email:'foo@example.com'}); + }); + }); + + it('does not include file details if projects enabled but no active project and files do not exist', function() { + settings.init({ + settings: { + foo: 123, + httpNodeRoot: "testHttpNodeRoot", + version: "testVersion", + paletteCategories :["red","blue","green"], + exportNodeSettings: (obj) => { + obj.testNodeSetting = "helloWorld"; + } + }, + nodes: { + listContextStores: () => { return {stores:["file","memory"], default: "file"} }, + paletteEditorEnabled: () => false, + getCredentialKeyType: () => "test-key-type" + }, + storage: { + projects: { + flowFileExists: () => false, + getActiveProject: () => false, + getFlowFilename: () => 'test-flow-file', + getCredentialsFilename: () => 'test-creds-file', + getGlobalGitUser: () => {return {name:'foo',email:'foo@example.com'}} + } + } + }) + return settings.getRuntimeSettings({ + user: { + username: "nick", + anonymous: false, + image: "http://example.com", + permissions: "*", + private: "secret" + } + }).then(result => { + result.should.not.have.property("project"); + result.should.not.have.property("files"); + result.should.have.property("git"); + result.git.should.have.property("globalUser",{name:'foo',email:'foo@example.com'}); + }); + }); + }); + describe("getUserSettings", function() { + before(function() { + settings.init({ + settings: { + getUserSettings: username => username + } + }); + }) + it("returns default user settings", function() { + return settings.getUserSettings({}).then(result => { + result.should.eql("_"); + }) + }) + it("returns default user settings for anonymous", function() { + return settings.getUserSettings({user:{anonymous:true}}).then(result => { + result.should.eql("_"); + }) + }) + it("returns user settings", function() { + return settings.getUserSettings({user:{username:'nick'}}).then(result => { + result.should.eql("nick"); + }) + }) + }); + + describe("updateUserSettings", function() { + var userSettings; + before(function() { + settings.init({ + settings: { + getUserSettings: username => clone(userSettings[username]), + setUserSettings: (username, settings) => { + if (username === 'error') { + var p = Promise.reject(new Error("unknown user")); + p.catch(()=>{}); + return p; + } else if (username === 'throw') { + throw new Error("thrown error"); + } + userSettings[username] = clone(settings); + return Promise.resolve(); + } + }, + log: mockLog() + }); + }) + beforeEach(function() { + userSettings = { + "_": { abc: 123 }, + "nick": {abc: 456} + } + }) + it('sets default user settings', function() { + return settings.updateUserSettings({settings:{abc:789}}).then(function() { + userSettings._.abc.should.eql(789) + }) + }) + it('merges user settings', function() { + return settings.updateUserSettings({settings:{def:789}}).then(function() { + userSettings._.abc.should.eql(123) + userSettings._.def.should.eql(789) + }) + }) + it('sets default user settings for anonymous user', function() { + return settings.updateUserSettings({user:{anonymous:true},settings:{def:789}}).then(function() { + userSettings._.abc.should.eql(123) + userSettings._.def.should.eql(789) + }) + }) + it('sets named user settings', function() { + return settings.updateUserSettings({user:{username:'nick'},settings:{def:789}}).then(function() { + userSettings.nick.abc.should.eql(456) + userSettings.nick.def.should.eql(789) + }) + }) + it('rejects with suitable error', function(done) { + settings.updateUserSettings({user:{username:'error'},settings:{def:789}}).then(result => { + done("Unexpected resolve for error case"); + }).catch(err => { + err.should.have.property('status', 400); + done(); + }).catch(done); + }) + it('rejects with suitable error - thrown', function(done) { + settings.updateUserSettings({user:{username:'throw'},settings:{def:789}}).then(result => { + done("Unexpected resolve for error case"); + }).catch(err => { + err.should.have.property('status', 400); + done(); + }).catch(done); + }) + }); + describe("getUserKeys", function() { + before(function() { + settings.init({ + storage: { + projects: { + ssh: { + listSSHKeys: username => { + if (username === 'error') { + var p = Promise.reject(new Error("unknown user")); + p.catch(()=>{}); + return p; + } + return Promise.resolve([username]) + } + } + } + } + }) + }) + it('returns the default users keys', function() { + return settings.getUserKeys({}).then(result => { + result.should.eql(['__default']); + }) + }) + it('returns the default users keys for anonymous', function() { + return settings.getUserKeys({user:{anonymous:true}}).then(result => { + result.should.eql(['__default']); + }) + }) + it('returns the users keys', function() { + return settings.getUserKeys({user:{username:'nick'}}).then(result => { + result.should.eql(['nick']); + }) + }) + it('rejects with suitable error', function(done) { + settings.getUserKeys({user:{username:'error'}}).then(result => { + done("Unexpected resolve for error case"); + }).catch(err => { + err.should.have.property('status', 400); + done(); + }).catch(done); + }) + }); + + describe("getUserKey", function() { + before(function() { + settings.init({ + storage: { + projects: { + ssh: { + getSSHKey: (username, id) => { + if (username === 'error') { + var p = Promise.reject(new Error("unknown user")); + p.catch(()=>{}); + return p; + } else if (username === '404') { + return Promise.resolve(null); + } + return Promise.resolve({username,id}) + } + } + } + } + }) + }) + it('returns the default user key', function() { + return settings.getUserKey({id:'keyid'}).then(result => { + result.should.eql({id:'keyid',username:"__default"}); + }) + }) + it('returns the default user key - anonymous', function() { + return settings.getUserKey({user:{anonymous:true},id:'keyid'}).then(result => { + result.should.eql({id:'keyid',username:"__default"}); + }) + }) + it('returns the user key', function() { + return settings.getUserKey({user:{username:'nick'},id:'keyid'}).then(result => { + result.should.eql({id:'keyid',username:"nick"}); + }) + }) + it('404s for unknown key', function(done) { + settings.getUserKey({user:{username:'404'},id:'keyid'}).then(result => { + done("Unexpected resolve for error case"); + }).catch(err => { + err.should.have.property('status', 404); + err.should.have.property('code', 'not_found'); + done(); + }).catch(done); + }) + it('rejects with suitable error', function(done) { + settings.getUserKey({user:{username:'error'}}).then(result => { + done("Unexpected resolve for error case"); + }).catch(err => { + err.should.have.property('status', 400); + done(); + }).catch(done); + }) + }); + describe("generateUserKey", function() { + before(function() { + settings.init({ + storage: { + projects: { + ssh: { + generateSSHKey: (username, opts) => { + if (username === 'error') { + var p = Promise.reject(new Error("unknown user")); + p.catch(()=>{}); + return p; + } + return Promise.resolve(JSON.stringify({username,opts})) + } + } + } + } + }) + }) + it('generates for the default user', function() { + return settings.generateUserKey({id:'keyid'}).then(result => { + var data = JSON.parse(result); + data.should.eql({opts:{id:'keyid'},username:"__default"}); + }) + }) + it('generates for the default user - anonymous', function() { + return settings.generateUserKey({user:{anonymous:true},id:'keyid'}).then(result => { + var data = JSON.parse(result); + data.should.eql({opts:{user:{anonymous:true},id:'keyid'},username:"__default"}); + }) + }) + it('generates for the user', function() { + return settings.generateUserKey({user:{username:'nick'},id:'keyid'}).then(result => { + var data = JSON.parse(result); + data.should.eql({opts:{user:{username:'nick'},id:'keyid'},username:"nick"}); + }) + }) + it('rejects with suitable error', function(done) { + settings.generateUserKey({user:{username:'error'}}).then(result => { + done("Unexpected resolve for error case"); + }).catch(err => { + err.should.have.property('status', 400); + done(); + }).catch(done); + }) + + }); + describe("removeUserKey", function() { + var received = {}; + before(function() { + settings.init({ + storage: { + projects: { + ssh: { + deleteSSHKey: (username, id) => { + if (username === 'error') { + var p = Promise.reject(new Error("unknown user")); + p.catch(()=>{}); + return p; + } + received.username = username; + received.id = id; + return Promise.resolve(); + } + } + } + } + }) + }); + beforeEach(function() { + received.username = ""; + received.id = ""; + }) + it('removes for the default user', function() { + return settings.removeUserKey({id:'keyid'}).then(() => { + received.username.should.eql("__default"); + received.id.should.eql("keyid"); + }) + }) + it('removes for the default user key - anonymous', function() { + return settings.removeUserKey({user:{anonymous:true},id:'keyid'}).then(() => { + received.username.should.eql("__default"); + received.id.should.eql("keyid"); + }) + }) + it('returns the user key', function() { + return settings.removeUserKey({user:{username:'nick'},id:'keyid'}).then(() => { + received.username.should.eql("nick"); + received.id.should.eql("keyid"); + }) + }) + it('rejects with suitable error', function(done) { + settings.removeUserKey({user:{username:'error'}}).then(result => { + done("Unexpected resolve for error case"); + }).catch(err => { + err.should.have.property('status', 400); + done(); + }).catch(done); + }) + }); + +}); + + + +/* + + +var should = require("should"); +var sinon = require("sinon"); +var request = require("supertest"); +var express = require("express"); +var editorApi = require("../../../../red/api/editor"); +var comms = require("../../../../red/api/editor/comms"); +var info = require("../../../../red/api/editor/settings"); +var auth = require("../../../../red/api/auth"); +var sshkeys = require("../../../../red/api/editor/sshkeys"); +var when = require("when"); +var bodyParser = require("body-parser"); +var fs = require("fs-extra"); +var fspath = require("path"); + + +describe("api/editor/sshkeys", function() { + var app; + var mockList = [ + 'library','theme','locales','credentials','comms' + ] + var isStarted = true; + var errors = []; + var session_data = {}; + + var mockRuntime = { + settings:{ + httpNodeRoot: true, + httpAdminRoot: true, + disableEditor: false, + exportNodeSettings:function(){}, + storage: { + getSessions: function(){ + return when.resolve(session_data); + }, + setSessions: function(_session) { + session_data = _session; + return when.resolve(); + } + } + }, + log:{audit:function(){},error:function(msg){errors.push(msg)},trace:function(){}}, + storage: { + projects: { + ssh: { + init: function(){}, + listSSHKeys: function(){}, + getSSHKey: function(){}, + generateSSHKey: function(){}, + deleteSSHKey: function(){} + } + } + }, + events:{on:function(){},removeListener:function(){}}, + isStarted: function() { return isStarted; }, + nodes: {paletteEditorEnabled: function() { return false }} + }; + + before(function() { + auth.init(mockRuntime); + app = express(); + app.use(bodyParser.json()); + app.use(editorApi.init({},mockRuntime)); + }); + after(function() { + }) + + beforeEach(function() { + sinon.stub(mockRuntime.storage.projects.ssh, "listSSHKeys"); + sinon.stub(mockRuntime.storage.projects.ssh, "getSSHKey"); + sinon.stub(mockRuntime.storage.projects.ssh, "generateSSHKey"); + sinon.stub(mockRuntime.storage.projects.ssh, "deleteSSHKey"); + }) + afterEach(function() { + mockRuntime.storage.projects.ssh.listSSHKeys.restore(); + mockRuntime.storage.projects.ssh.getSSHKey.restore(); + mockRuntime.storage.projects.ssh.generateSSHKey.restore(); + mockRuntime.storage.projects.ssh.deleteSSHKey.restore(); + }) + + it('GET /settings/user/keys --- return empty list', function(done) { + mockRuntime.storage.projects.ssh.listSSHKeys.returns(Promise.resolve([])); + request(app) + .get("/settings/user/keys") + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('keys'); + res.body.keys.should.be.empty(); + done(); + }); + }); + + it('GET /settings/user/keys --- return normal list', function(done) { + var fileList = [ + 'test_key01', + 'test_key02' + ]; + var retList = fileList.map(function(elem) { + return { + name: elem + }; + }); + mockRuntime.storage.projects.ssh.listSSHKeys.returns(Promise.resolve(retList)); + request(app) + .get("/settings/user/keys") + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('keys'); + for (var item of retList) { + res.body.keys.should.containEql(item); + } + done(); + }); + }); + + it('GET /settings/user/keys --- return Error', function(done) { + var errInstance = new Error("Messages here....."); + errInstance.code = "test_code"; + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.storage.projects.ssh.listSSHKeys.returns(p); + request(app) + .get("/settings/user/keys") + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('error'); + res.body.error.should.be.equal(errInstance.code); + res.body.should.have.property('message'); + res.body.message.should.be.equal(errInstance.message); + done(); + }); + }); + + it('GET /settings/user/keys/<key_file_name> --- return 404', function(done) { + mockRuntime.storage.projects.ssh.getSSHKey.returns(Promise.resolve(null)); + request(app) + .get("/settings/user/keys/NOT_REAL") + .expect(404) + .end(function(err,res) { + if (err) { + return done(err); + } + done(); + }); + }); + it('GET /settings/user/keys --- return Unexpected Error', function(done) { + var errInstance = new Error("Messages....."); + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.storage.projects.ssh.listSSHKeys.returns(p); + request(app) + .get("/settings/user/keys") + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('error'); + res.body.error.should.be.equal("unexpected_error"); + res.body.should.have.property('message'); + res.body.message.should.be.equal(errInstance.toString()); + done(); + }); + }); + + it('GET /settings/user/keys/<key_file_name> --- return content', function(done) { + var key_file_name = "test_key"; + var fileContent = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD3a+sgtgzSbbliWxmOq5p6+H/mE+0gjWfLWrkIVmHENd1mifV4uCmIHAR2NfuadUYMQ3+bQ90kpmmEKTMYPsyentsKpHQZxTzG7wOCAIpJnbPTHDMxEJhVTaAwEjbVyMSIzTTPfnhoavWIBu0+uMgKDDlBm+RjlgkFlyhXyCN6UwFrIUUMH6Gw+eQHLiooKIl8ce7uDxIlt+9b7hFCU+sQ3kvuse239DZluu6+8buMWqJvrEHgzS9adRFKku8nSPAEPYn85vDi7OgVAcLQufknNgs47KHBAx9h04LeSrFJ/P5J1b//ItRpMOIme+O9d1BR46puzhvUaCHLdvO9czj+OmW+dIm+QIk6lZIOOMnppG72kZxtLfeKT16ur+2FbwAdL9ItBp4BI/YTlBPoa5mLMxpuWfmX1qHntvtGc9wEwS1P7YFfmF3XiK5apxalzrn0Qlr5UmDNbVIqJb1OlbC0w03Z0oktti1xT+R2DGOLWM4lBbpXDHV1BhQ7oYOvbUD8Cnof55lTP0WHHsOHlQc/BGDti1XA9aBX/OzVyzBUYEf0pkimsD0RYo6aqt7QwehJYdlz9x1NBguBffT0s4NhNb9IWr+ASnFPvNl2sw4XH/8U0J0q8ZkMpKkbLM1Zdp1Fv00GF0f5UNRokai6uM3w/ccantJ3WvZ6GtctqytWrw== \n"; + mockRuntime.storage.projects.ssh.getSSHKey.returns(Promise.resolve(fileContent)); + request(app) + .get("/settings/user/keys/" + key_file_name) + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + mockRuntime.storage.projects.ssh.getSSHKey.called.should.be.true(); + res.body.should.be.deepEqual({ publickey: fileContent }); + done(); + }); + }); + + it('GET /settings/user/keys/<key_file_name> --- return Error', function(done) { + var key_file_name = "test_key"; + var errInstance = new Error("Messages....."); + errInstance.code = "test_code"; + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.storage.projects.ssh.getSSHKey.returns(p); + request(app) + .get("/settings/user/keys/" + key_file_name) + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('error'); + res.body.error.should.be.equal(errInstance.code); + res.body.should.have.property('message'); + res.body.message.should.be.equal(errInstance.message); + done(); + }); + }); + + it('GET /settings/user/keys/<key_file_name> --- return Unexpected Error', function(done) { + var key_file_name = "test_key"; + var errInstance = new Error("Messages....."); + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.storage.projects.ssh.getSSHKey.returns(p); + request(app) + .get("/settings/user/keys/" + key_file_name) + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('error'); + res.body.error.should.be.equal("unexpected_error"); + res.body.should.have.property('message'); + res.body.message.should.be.equal(errInstance.toString()); + done(); + }); + }); + + it('POST /settings/user/keys --- success', function(done) { + var key_file_name = "test_key"; + mockRuntime.storage.projects.ssh.generateSSHKey.returns(Promise.resolve(key_file_name)); + request(app) + .post("/settings/user/keys") + .send({ name: key_file_name }) + .expect(200) + .end(function(err,res) { + if (err) { + return done(err); + } + done(); + }); + }); + + it('POST /settings/user/keys --- return parameter error', function(done) { + var key_file_name = "test_key"; + mockRuntime.storage.projects.ssh.generateSSHKey.returns(Promise.resolve(key_file_name)); + request(app) + .post("/settings/user/keys") + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('error'); + res.body.error.should.be.equal("unexpected_error"); + res.body.should.have.property('message'); + res.body.message.should.be.equal("You need to have body or body.name"); + done(); + }); + }); + + it('POST /settings/user/keys --- return Error', function(done) { + var key_file_name = "test_key"; + var errInstance = new Error("Messages....."); + errInstance.code = "test_code"; + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.storage.projects.ssh.generateSSHKey.returns(p); + request(app) + .post("/settings/user/keys") + .send({ name: key_file_name }) + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('error'); + res.body.error.should.be.equal("test_code"); + res.body.should.have.property('message'); + res.body.message.should.be.equal(errInstance.message); + done(); + }); + }); + + it('POST /settings/user/keys --- return Unexpected error', function(done) { + var key_file_name = "test_key"; + var errInstance = new Error("Messages....."); + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.storage.projects.ssh.generateSSHKey.returns(p); + request(app) + .post("/settings/user/keys") + .send({ name: key_file_name }) + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('error'); + res.body.error.should.be.equal("unexpected_error"); + res.body.should.have.property('message'); + res.body.message.should.be.equal(errInstance.toString()); + done(); + }); + }); + + it('DELETE /settings/user/keys/<key_file_name> --- success', function(done) { + var key_file_name = "test_key"; + mockRuntime.storage.projects.ssh.deleteSSHKey.returns(Promise.resolve(true)); + request(app) + .delete("/settings/user/keys/" + key_file_name) + .expect(204) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.be.deepEqual({}); + done(); + }); + }); + + it('DELETE /settings/user/keys/<key_file_name> --- return Error', function(done) { + var key_file_name = "test_key"; + var errInstance = new Error("Messages....."); + errInstance.code = "test_code"; + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.storage.projects.ssh.deleteSSHKey.returns(p); + request(app) + .delete("/settings/user/keys/" + key_file_name) + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('error'); + res.body.error.should.be.equal("test_code"); + res.body.should.have.property('message'); + res.body.message.should.be.equal(errInstance.message); + done(); + }); + }); + + it('DELETE /settings/user/keys/<key_file_name> --- return Unexpected Error', function(done) { + var key_file_name = "test_key"; + var errInstance = new Error("Messages....."); + var p = Promise.reject(errInstance); + p.catch(()=>{}); + mockRuntime.storage.projects.ssh.deleteSSHKey.returns(p); + request(app) + .delete("/settings/user/keys/" + key_file_name) + .expect(400) + .end(function(err,res) { + if (err) { + return done(err); + } + res.body.should.have.property('error'); + res.body.error.should.be.equal("unexpected_error"); + res.body.should.have.property('message'); + res.body.message.should.be.equal(errInstance.toString()); + done(); + }); + }); +}); +*/ diff --git a/packages/connector/test/unit/@node-red/runtime/lib/events_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/events_spec.js new file mode 100644 index 0000000..09b4769 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/events_spec.js @@ -0,0 +1,25 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +var should = require("should"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +describe("runtime/events", function() { + it('can be required without errors', function() { + NR_TEST_UTILS.require("@node-red/runtime/lib/events"); + }); + it.skip('more tests needed', function(){}) +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/exec_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/exec_spec.js new file mode 100644 index 0000000..1e37b7c --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/exec_spec.js @@ -0,0 +1,138 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +var should = require("should"); +var sinon = require("sinon"); +var path = require("path"); +var events = require("events"); + + +var child_process = require('child_process'); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var exec = NR_TEST_UTILS.require("@node-red/runtime/lib/exec"); + +describe("runtime/exec", function() { + var logEvents; + var mockProcess; + + beforeEach(function() { + var logEventHandler = new events.EventEmitter(); + logEvents = []; + logEventHandler.on('event-log', function(ev) { + logEvents.push(ev); + }); + exec.init({events:logEventHandler}); + + mockProcess = new events.EventEmitter(); + mockProcess.stdout = new events.EventEmitter(); + mockProcess.stderr = new events.EventEmitter(); + sinon.stub(child_process,'spawn',function(command,args,options) { + mockProcess._args = {command,args,options}; + return mockProcess; + }); + }); + + afterEach(function() { + if (child_process.spawn.restore) { + child_process.spawn.restore(); + } + }); + + it("runs command and resolves on success - no emit", function(done) { + var command = "cmd"; + var args = [1,2,3]; + var opts = { a: true }; + exec.run(command,args,opts).then(function(result) { + command.should.eql(mockProcess._args.command); + args.should.eql(mockProcess._args.args); + opts.should.eql(mockProcess._args.options); + logEvents.length.should.eql(0); + result.code.should.eql(0); + result.stdout.should.eql("123"); + result.stderr.should.eql("abc"); + done(); + }).catch(done); + + mockProcess.stdout.emit('data',"1"); + mockProcess.stderr.emit('data',"a"); + mockProcess.stderr.emit('data',"b"); + mockProcess.stdout.emit('data',"2"); + mockProcess.stdout.emit('data',"3"); + mockProcess.stderr.emit('data',"c"); + mockProcess.emit('close',0); + }); + + it("runs command and resolves on success - emit", function(done) { + var command = "cmd"; + var args = [1,2,3]; + var opts = { a: true }; + exec.run(command,args,opts,true).then(function(result) { + logEvents.length.should.eql(8); + done(); + }).catch(done); + + mockProcess.stdout.emit('data',"1"); + mockProcess.stderr.emit('data',"a"); + mockProcess.stderr.emit('data',"b"); + mockProcess.stdout.emit('data',"2"); + mockProcess.stdout.emit('data',"3"); + mockProcess.stderr.emit('data',"c"); + mockProcess.emit('close',0); + }) + + it("runs command and rejects on error - close", function(done) { + var command = "cmd"; + var args = [1,2,3]; + var opts = { a: true }; + exec.run(command,args,opts).then(function() { + done("Command should have rejected"); + }).catch(function(result) { + result + result.code.should.eql(123); + result.stdout.should.eql("123"); + result.stderr.should.eql("abc"); + done(); + }).catch(done); + + mockProcess.stdout.emit('data',"1"); + mockProcess.stderr.emit('data',"a"); + mockProcess.stderr.emit('data',"b"); + mockProcess.stdout.emit('data',"2"); + mockProcess.stdout.emit('data',"3"); + mockProcess.stderr.emit('data',"c"); + mockProcess.emit('close',123); + }) + + it("runs command and rejects on error - error", function(done) { + var command = "cmd"; + var args = [1,2,3]; + var opts = { a: true }; + exec.run(command,args,opts).then(function() { + done("Command should have rejected"); + }).catch(function(result) { + result + result.code.should.eql(456); + result.stdout.should.eql(""); + result.stderr.should.eql("test-error"); + done(); + }).catch(done); + + mockProcess.emit('error',"test-error"); + mockProcess.emit('close',456); + }) + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/index_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/index_spec.js new file mode 100644 index 0000000..f6a506d --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/index_spec.js @@ -0,0 +1,251 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +var should = require("should"); +var sinon = require("sinon"); +var path = require("path"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var api = NR_TEST_UTILS.require("@node-red/runtime/lib/api"); +var runtime = NR_TEST_UTILS.require("@node-red/runtime"); + +var redNodes = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes"); +var storage = NR_TEST_UTILS.require("@node-red/runtime/lib/storage"); +var settings = NR_TEST_UTILS.require("@node-red/runtime/lib/settings"); +var util = NR_TEST_UTILS.require("@node-red/util"); + +var log = NR_TEST_UTILS.require("@node-red/util").log; + +describe("runtime", function() { + afterEach(function() { + if (console.log.restore) { + console.log.restore(); + } + }) + + before(function() { + process.env.NODE_RED_HOME = NR_TEST_UTILS.resolve("node-red"); + }); + after(function() { + delete process.env.NODE_RED_HOME; + }); + function mockUtil(metrics) { + + return { + log:{ + log: sinon.stub(), + warn: sinon.stub(), + info: sinon.stub(), + trace: sinon.stub(), + metric: sinon.stub().returns(!!metrics), + _: function() { return "abc"} + }, + i18n: { + registerMessageCatalog: function(){ + return Promise.resolve(); + } + } + } + } + describe("init", function() { + beforeEach(function() { + sinon.stub(log,"init",function() {}); + sinon.stub(settings,"init",function() {}); + sinon.stub(redNodes,"init",function() {}) + }); + afterEach(function() { + log.init.restore(); + settings.init.restore(); + redNodes.init.restore(); + }) + + it("initialises components", function() { + runtime.init({testSettings: true, httpAdminRoot:"/"},mockUtil()); + settings.init.called.should.be.true(); + redNodes.init.called.should.be.true(); + }); + + it("returns version", function() { + runtime.init({testSettings: true, httpAdminRoot:"/"},mockUtil()); + return runtime.version().then(version => { + /^\d+\.\d+\.\d+(-.*)?$/.test(version).should.be.true(); + }); + + + }) + }); + + describe("start",function() { + var storageInit; + var settingsLoad; + var redNodesInit; + var redNodesLoad; + var redNodesCleanModuleList; + var redNodesGetNodeList; + var redNodesLoadFlows; + var redNodesStartFlows; + var redNodesLoadContextsPlugin; + var i18nRegisterMessageCatalog; + + beforeEach(function() { + storageInit = sinon.stub(storage,"init",function(settings) {return Promise.resolve();}); + redNodesInit = sinon.stub(redNodes,"init", function() {}); + redNodesLoad = sinon.stub(redNodes,"load", function() {return Promise.resolve()}); + redNodesCleanModuleList = sinon.stub(redNodes,"cleanModuleList",function(){}); + redNodesLoadFlows = sinon.stub(redNodes,"loadFlows",function() {return Promise.resolve()}); + redNodesStartFlows = sinon.stub(redNodes,"startFlows",function() {}); + redNodesLoadContextsPlugin = sinon.stub(redNodes,"loadContextsPlugin",function() {return Promise.resolve()}); + i18nRegisterMessageCatalog = sinon.stub(util.i18n,"registerMessageCatalog",function() {return Promise.resolve()}); + }); + afterEach(function() { + storageInit.restore(); + redNodesInit.restore(); + redNodesLoad.restore(); + redNodesGetNodeList.restore(); + redNodesCleanModuleList.restore(); + redNodesLoadFlows.restore(); + redNodesStartFlows.restore(); + redNodesLoadContextsPlugin.restore(); + i18nRegisterMessageCatalog.restore(); + }); + it("reports errored/missing modules",function(done) { + redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function(cb) { + return [ + { err:"errored",name:"errName" }, // error + { module:"module",enabled:true,loaded:false,types:["typeA","typeB"]} // missing + ].filter(cb); + }); + var util = mockUtil(); + runtime.init({testSettings: true, httpAdminRoot:"/", load:function() { return Promise.resolve();}},util); + // sinon.stub(console,"log"); + runtime.start().then(function() { + // console.log.restore(); + try { + storageInit.calledOnce.should.be.true(); + redNodesInit.calledOnce.should.be.true(); + redNodesLoad.calledOnce.should.be.true(); + redNodesLoadFlows.calledOnce.should.be.true(); + + util.log.warn.calledWithMatch("Failed to register 1 node type"); + util.log.warn.calledWithMatch("Missing node modules"); + util.log.warn.calledWithMatch(" - module: typeA, typeB"); + redNodesCleanModuleList.calledOnce.should.be.true(); + done(); + } catch(err) { + done(err); + } + }).catch(err=>{done(err)}); + }); + it("initiates load of missing modules",function(done) { + redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function(cb) { + return [ + { err:"errored",name:"errName" }, // error + { err:"errored",name:"errName" }, // error + { module:"module",enabled:true,loaded:false,types:["typeA","typeB"]}, // missing + { module:"node-red",enabled:true,loaded:false,types:["typeC","typeD"]} // missing + ].filter(cb); + }); + var serverInstallModule = sinon.stub(redNodes,"installModule",function(name) { return Promise.resolve({nodes:[]});}); + var util = mockUtil(); + runtime.init({testSettings: true, autoInstallModules:true, httpAdminRoot:"/", load:function() { return Promise.resolve();}},util); + sinon.stub(console,"log"); + runtime.start().then(function() { + console.log.restore(); + try { + util.log.warn.calledWithMatch("Failed to register 2 node types"); + util.log.warn.calledWithMatch("Missing node modules"); + util.log.warn.calledWithMatch(" - module: typeA, typeB"); + util.log.warn.calledWithMatch(" - node-red: typeC, typeD"); + redNodesCleanModuleList.calledOnce.should.be.false(); + serverInstallModule.calledOnce.should.be.true(); + serverInstallModule.calledWithMatch("module"); + done(); + } catch(err) { + done(err); + } finally { + serverInstallModule.restore(); + } + }).catch(err=>{done(err)}); + }); + it("reports errored modules when verbose is enabled",function(done) { + redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function(cb) { + return [ + { err:"errored",name:"errName" } // error + ].filter(cb); + }); + var util = mockUtil(); + runtime.init({testSettings: true, verbose:true, httpAdminRoot:"/", load:function() { return Promise.resolve();}},util); + sinon.stub(console,"log"); + runtime.start().then(function() { + console.log.restore(); + try { + util.log.warn.neverCalledWithMatch("Failed to register 1 node type"); + util.log.warn.calledWithMatch("[errName] errored"); + done(); + } catch(err) { + done(err); + } + }).catch(err=>{done(err)}); + }); + + it("reports runtime metrics",function(done) { + var stopFlows = sinon.stub(redNodes,"stopFlows",function() { return Promise.resolve();} ); + redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function() {return []}); + var util = mockUtil(true); + runtime.init( + {testSettings: true, runtimeMetricInterval:200, httpAdminRoot:"/", load:function() { return Promise.resolve();}}, + {}, + undefined, + util); + // sinon.stub(console,"log"); + runtime.start().then(function() { + // console.log.restore(); + setTimeout(function() { + try { + util.log.log.args.should.have.lengthOf(3); + util.log.log.args[0][0].should.have.property("event","runtime.memory.rss"); + util.log.log.args[1][0].should.have.property("event","runtime.memory.heapTotal"); + util.log.log.args[2][0].should.have.property("event","runtime.memory.heapUsed"); + done(); + } catch(err) { + done(err); + } finally { + runtime.stop(); + stopFlows.restore(); + } + },300); + }).catch(err=>{done(err)}); + }); + + + }); + + it("stops components", function(done) { + var stopFlows = sinon.stub(redNodes,"stopFlows",function() { return Promise.resolve();} ); + var closeContextsPlugin = sinon.stub(redNodes,"closeContextsPlugin",function() { return Promise.resolve();} ); + runtime.stop().then(function(){ + stopFlows.called.should.be.true(); + closeContextsPlugin.called.should.be.true(); + stopFlows.restore(); + closeContextsPlugin.restore(); + done(); + }).catch(function(err){ + stopFlows.restore(); + closeContextsPlugin.restore(); + return done(err) + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/library/examples_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/library/examples_spec.js new file mode 100644 index 0000000..16d917c --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/library/examples_spec.js @@ -0,0 +1,138 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); +var fs = require("fs"); + +var NR_TEST_UTILS = require("nr-test-utils"); +var examplesLibrary = NR_TEST_UTILS.require("@node-red/runtime/lib/library/examples") + +var mockLog = { + log: sinon.stub(), + debug: sinon.stub(), + trace: sinon.stub(), + warn: sinon.stub(), + info: sinon.stub(), + metric: sinon.stub(), + audit: sinon.stub(), + _: function() { return "abc"} +} + +describe("runtime/library/examples", function() { + describe("getEntry", function() { + before(function() { + examplesLibrary.init({ + log: mockLog, + storage: { + getLibraryEntry: function(type,path) { + return Promise.resolve({type,path}); + }, + getFlow: function(path) { + return Promise.resolve({path}); + } + }, + nodes: { + getNodeExampleFlows: function() { + return { + "test-module": { + f: ["abc"] + }, + "@scope/test-module": { + f: ["abc","throw"] + } + + } + }, + getNodeExampleFlowPath: function(module,entryPath) { + if (module === "unknown") { + return null; + } + return "/tmp/"+module+"/"+entryPath; + } + } + }); + sinon.stub(fs,"readFile", function(path,opts,callback) { + if (path === "/tmp/test-module/abc") { + callback(null,"Example flow result"); + } else if (path === "/tmp/@scope/test-module/abc") { + callback(null,"Example scope flow result"); + } else if (path === "/tmp/test-module/throw") { + throw new Error("Instant error") + } else { + callback(new Error("Unexpected path:"+path)) + } + }) + }); + after(function() { + fs.readFile.restore(); + }) + + it ('returns a flow example entry', function(done) { + examplesLibrary.getEntry("flows","test-module/abc").then(function(result) { + result.should.eql("Example flow result"); + done(); + }).catch(done); + }); + + it ('returns a flow example listing - top level', function(done) { + examplesLibrary.getEntry("flows","").then(function(result) { + result.should.eql([ 'test-module', '@scope/test-module' ]) + done(); + }).catch(done); + }); + it ('returns a flow example listing - in module', function(done) { + examplesLibrary.getEntry("flows","test-module").then(function(result) { + result.should.eql([{ fn: 'abc' }]) + done(); + }).catch(done); + }); + it ('returns a flow example listing - in scoped module', function(done) { + examplesLibrary.getEntry("flows","@scope/test-module").then(function(result) { + result.should.eql([{ fn: 'abc' }, {fn: 'throw'}]) + done(); + }).catch(done); + }); + it ('returns a flow example entry from scoped module', function(done) { + examplesLibrary.getEntry("flows","@scope/test-module/abc").then(function(result) { + result.should.eql("Example scope flow result"); + done(); + }).catch(done); + }); + it ('returns an error for unknown flow example entry', function(done) { + examplesLibrary.getEntry("flows","unknown/abc").then(function(result) { + done(new Error("No error thrown")) + }).catch(function(err) { + err.should.have.property("code","not_found"); + done(); + }); + }); + it ('returns an error for file load error - async', function(done) { + examplesLibrary.getEntry("flows","test-module/unknown").then(function(result) { + done(new Error("No error thrown")) + }).catch(function(err) { + done(); + }); + }); + it ('returns an error for file load error - sync', function(done) { + examplesLibrary.getEntry("flows","test-module/throw").then(function(result) { + done(new Error("No error thrown")) + }).catch(function(err) { + done(); + }); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/library/index_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/library/index_spec.js new file mode 100644 index 0000000..ac2608a --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/library/index_spec.js @@ -0,0 +1,145 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); + +var NR_TEST_UTILS = require("nr-test-utils"); +var library = NR_TEST_UTILS.require("@node-red/runtime/lib/library/index") +var localLibrary = NR_TEST_UTILS.require("@node-red/runtime/lib/library/local") +var examplesLibrary = NR_TEST_UTILS.require("@node-red/runtime/lib/library/examples") + +var mockLog = { + log: sinon.stub(), + debug: sinon.stub(), + trace: sinon.stub(), + warn: sinon.stub(), + info: sinon.stub(), + metric: sinon.stub(), + audit: sinon.stub(), + _: function() { return "abc"} +} + + +describe("runtime/library", function() { + before(function() { + sinon.stub(localLibrary,"getEntry",function(type,path) { + return Promise.resolve({ + library: "local", + type:type, + path:path + }) + }); + sinon.stub(localLibrary,"saveEntry",function(type, path, meta, body) { + return Promise.resolve({ + library: "local", + type:type, + path:path, + meta:meta, + body:body + }) + }); + sinon.stub(examplesLibrary,"getEntry",function(type,path) { + return Promise.resolve({ + library: "_examples_", + type:type, + path:path + }) + }); + }); + after(function() { + localLibrary.getEntry.restore(); + localLibrary.saveEntry.restore(); + examplesLibrary.getEntry.restore(); + }) + describe("register", function() { + // it("throws error for duplicate type", function() { + // library.init({}); + // library.register("unknown","/abc"); + // should(()=>{library.register("unknown","/abc")} ).throw(); + // }) + }) + describe("getEntry", function() { + before(function() { + library.init({}); + }); + it('throws error for unregistered type', function() { + should(()=>{library.getEntry("local","unknown","/abc")} ).throw(); + }); + it('throws error for unknown library', function() { + should(()=>{library.getEntry("unknown","unknown","/abc")} ).throw(); + }); + + it('returns a registered non-flow entry', function(done) { + library.register("test-module","test-type"); + library.getEntry("local","test-type","/abc").then(function(result) { + result.should.have.property("library","local") + result.should.have.property("type","test-type") + result.should.have.property("path","/abc") + done(); + }).catch(done); + }); + + it ('returns a flow entry', function(done) { + library.getEntry("local","flows","/abc").then(function(result) { + result.should.have.property("library","local") + result.should.have.property("path","/abc") + done(); + }).catch(done); + }); + + it ('returns a flow example entry', function(done) { + library.getEntry("_examples_","flows","/test-module/abc").then(function(result) { + result.should.have.property("library","_examples_") + result.should.have.property("path","/test-module/abc") + done(); + }).catch(done); + }); + }); + + describe("saveEntry", function() { + before(function() { + library.init({}); + }); + it('throws error for unknown library', function() { + should(()=>{library.saveEntry("unknown","unknown","/abc",{id:"meta"},{id:"body"})} ).throw(); + }); + it('throws error for unregistered type', function() { + should(()=>{library.saveEntry("local","unknown","/abc",{id:"meta"},{id:"body"})} ).throw(); + }); + it('throws error for save to readonly library', function() { + should(()=>{library.saveEntry("_examples_","unknown","/abc",{id:"meta"},{id:"body"})} ).throw(); + }); + it('saves a flow entry', function(done) { + library.saveEntry('local','flows','/abc',{id:"meta"},{id:"body"}).then(function(result) { + result.should.have.property("path","/abc"); + result.should.have.property("body",{id:"body"}); + done(); + }).catch(done); + }) + it('saves a non-flow entry', function(done) { + library.register("test-module","test-type"); + library.saveEntry('local','test-type','/abc',{id:"meta"},{id:"body"}).then(function(result) { + result.should.have.property("type","test-type"); + result.should.have.property("path","/abc"); + result.should.have.property("meta",{id:"meta"}); + result.should.have.property("body",{id:"body"}); + done(); + }).catch(done); + }) + + }); +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/library/local_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/library/local_spec.js new file mode 100644 index 0000000..965e5c8 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/library/local_spec.js @@ -0,0 +1,93 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); + +var NR_TEST_UTILS = require("nr-test-utils"); +var localLibrary = NR_TEST_UTILS.require("@node-red/runtime/lib/library/local") + +var mockLog = { + log: sinon.stub(), + debug: sinon.stub(), + trace: sinon.stub(), + warn: sinon.stub(), + info: sinon.stub(), + metric: sinon.stub(), + audit: sinon.stub(), + _: function() { return "abc"} +} + +describe("runtime/library/local", function() { + + describe("getEntry", function() { + before(function() { + localLibrary.init({ + log: mockLog, + storage: { + getLibraryEntry: function(type,path) { + return Promise.resolve({type,path}); + } + } + }); + }); + + it('returns a registered non-flow entry', function(done) { + localLibrary.getEntry("test-type","/abc").then(function(result) { + result.should.have.property("type","test-type") + result.should.have.property("path","/abc") + done(); + }).catch(done); + }); + + it ('returns a flow entry', function(done) { + localLibrary.getEntry("flows","/abc").then(function(result) { + result.should.have.property("path","/abc") + done(); + }).catch(done); + }); + }); + + describe("saveEntry", function() { + before(function() { + localLibrary.init({ + log: mockLog, + storage: { + saveLibraryEntry: function(type, path, meta, body) { + return Promise.resolve({type,path,meta,body}) + } + } + }); + }); + it('saves a flow entry', function(done) { + localLibrary.saveEntry('flows','/abc',{id:"meta"},{id:"body"}).then(function(result) { + result.should.have.property("path","/abc"); + result.should.have.property("body",{id:"body"}); + done(); + }).catch(done); + }) + it('saves a non-flow entry', function(done) { + localLibrary.saveEntry('test-type','/abc',{id:"meta"},{id:"body"}).then(function(result) { + result.should.have.property("type","test-type"); + result.should.have.property("path","/abc"); + result.should.have.property("meta",{id:"meta"}); + result.should.have.property("body",{id:"body"}); + done(); + }).catch(done); + }) + + }); +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/nodes/Node_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/nodes/Node_spec.js new file mode 100644 index 0000000..1f9ca04 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/nodes/Node_spec.js @@ -0,0 +1,653 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require('sinon'); +var NR_TEST_UTILS = require("nr-test-utils"); +var RedNode = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/Node"); +var Log = NR_TEST_UTILS.require("@node-red/util").log; +var flows = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/flows"); + +describe('Node', function() { + describe('#constructor',function() { + it('is called with an id and a type',function() { + var n = new RedNode({id:'123',type:'abc'}); + n.should.have.property('id','123'); + n.should.have.property('type','abc'); + n.should.not.have.property('name'); + n.wires.should.be.empty(); + }); + + it('is called with an id, a type and a name',function() { + var n = new RedNode({id:'123',type:'abc',name:'barney'}); + n.should.have.property('id','123'); + n.should.have.property('type','abc'); + n.should.have.property('name','barney'); + n.wires.should.be.empty(); + }); + + it('is called with an id, a type and some wires',function() { + var n = new RedNode({id:'123',type:'abc',wires:['123','456']}); + n.should.have.property('id','123'); + n.should.have.property('type','abc'); + n.should.not.have.property('name'); + n.wires.should.have.length(2); + }); + + }); + + describe('#close', function() { + it('emits close event when closed',function(done) { + var n = new RedNode({id:'123',type:'abc'}); + n.on('close',function() { + done(); + }); + n.close(); + }); + + it('returns a promise when provided a callback with a done parameter',function(testdone) { + var n = new RedNode({id:'123',type:'abc'}); + n.on('close',function(done) { + setTimeout(function() { + done(); + },50); + }); + var p = n.close(); + should.exist(p); + p.then(function() { + testdone(); + }); + }); + it('accepts a callback with "removed" and "done" parameters', function(testdone) { + var n = new RedNode({id:'123',type:'abc'}); + var receivedRemoved; + n.on('close',function(removed,done) { + receivedRemoved = removed; + setTimeout(function() { + done(); + },50); + }); + var p = n.close(true); + should.exist(p); + (receivedRemoved).should.be.true(); + p.then(function() { + testdone(); + }); + }) + it('allows multiple close handlers to be registered',function(testdone) { + var n = new RedNode({id:'123',type:'abc'}); + var callbacksClosed = 0; + n.on('close',function(done) { + setTimeout(function() { + callbacksClosed++; + done(); + },50); + }); + n.on('close',function(done) { + setTimeout(function() { + callbacksClosed++; + done(); + },75); + }); + n.on('close',function() { + callbacksClosed++; + }); + var p = n.close(); + should.exist(p); + p.then(function() { + callbacksClosed.should.eql(3); + testdone(); + }).catch(function(e) { + testdone(e); + }); + }); + }); + + + describe('#receive', function() { + it('emits input event when called', function(done) { + var n = new RedNode({id:'123',type:'abc'}); + var message = {payload:"hello world"}; + n.on('input',function(msg) { + should.deepEqual(msg,message); + done(); + }); + n.receive(message); + }); + + it('writes metric info with undefined msg', function(done){ + var n = new RedNode({id:'123',type:'abc'}); + n.on('input',function(msg) { + (typeof msg).should.not.be.equal("undefined"); + (typeof msg._msgid).should.not.be.equal("undefined"); + done(); + }); + n.receive(); + }); + + it('writes metric info with null msg', function(done){ + var n = new RedNode({id:'123',type:'abc'}); + n.on('input',function(msg) { + (typeof msg).should.not.be.equal("undefined"); + (typeof msg._msgid).should.not.be.equal("undefined"); + done(); + }); + n.receive(null); + }); + + it('handles thrown errors', function(done) { + var n = new RedNode({id:'123',type:'abc'}); + sinon.stub(n,"error",function(err,msg) {}); + var message = {payload:"hello world"}; + n.on('input',function(msg) { + throw new Error("test error"); + }); + n.receive(message); + setTimeout(function() { + n.error.called.should.be.true(); + n.error.firstCall.args[1].should.equal(message); + done(); + },50); + }); + + it('calls parent flow handleComplete when callback provided', function(done) { + var n = new RedNode({id:'123',type:'abc', _flow: { + handleComplete: function(node,msg) { + try { + msg.should.deepEqual(message); + done(); + } catch(err) { + done(err); + } + } + }}); + + var message = {payload:"hello world"}; + n.on('input',function(msg, nodeSend, nodeDone) { + nodeDone(); + }); + n.receive(message); + }); + it('logs error if callback provides error', function(done) { + var n = new RedNode({id:'123',type:'abc'}); + sinon.stub(n,"error",function(err,msg) {}); + + var message = {payload:"hello world"}; + n.on('input',function(msg, nodeSend, nodeDone) { + nodeDone(new Error("test error")); + setTimeout(function() { + try { + n.error.called.should.be.true(); + n.error.firstCall.args[0].toString().should.equal("Error: test error"); + n.error.firstCall.args[1].should.equal(message); + done(); + } catch(err) { + done(err); + } + },50); + }); + n.receive(message); + }); + }); + + describe('#send', function() { + + it('emits a single message', function(done) { + var flow = { + getNode: (id) => { return {'n1':n1,'n2':n2}[id]}, + }; + var n1 = new RedNode({_flow:flow,id:'n1',type:'abc',wires:[['n2']]}); + var n2 = new RedNode({_flow:flow,id:'n2',type:'abc'}); + var message = {payload:"hello world"}; + var messageReceived = false; + n2.on('input',function(msg) { + // msg equals message, and is not a new copy + messageReceived = true; + should.deepEqual(msg,message); + should.strictEqual(msg,message); + done(); + }); + n1.send(message); + messageReceived.should.be.false(); + }); + + it('emits a single message - synchronous mode', function(done) { + var flow = { + getNode: (id) => { return {'n1':n1,'n2':n2}[id]}, + asyncMessageDelivery: false + }; + var n1 = new RedNode({_flow:flow,id:'n1',type:'abc',wires:[['n2']]}); + var n2 = new RedNode({_flow:flow,id:'n2',type:'abc'}); + var message = {payload:"hello world"}; + var messageReceived = false; + var notSyncErr; + n2.on('input',function(msg) { + try { + // msg equals message, and is not a new copy + messageReceived = true; + should.deepEqual(msg,message); + should.strictEqual(msg,message); + done(notSyncErr); + } catch(err) { + done(err); + } + }); + n1.send(message); + try { + messageReceived.should.be.true(); + } catch(err) { + notSyncErr = err; + } + }); + + it('emits a message with callback provided send', function(done) { + var flow = { + getNode: (id) => { return {'n1':n1,'n2':n2}[id]}, + handleComplete: (node,msg) => {} + }; + var n1 = new RedNode({_flow:flow,id:'n1',type:'abc',wires:[['n2']]}); + var n2 = new RedNode({_flow:flow,id:'n2',type:'abc'}); + var message = {payload:"hello world"}; + var messageReceived = false; + n1.on('input',function(msg,nodeSend,nodeDone) { + nodeSend(msg); + nodeDone(); + }); + n2.on('input',function(msg) { + // msg equals message, and is not a new copy + messageReceived = true; + should.deepEqual(msg,message); + should.strictEqual(msg,message); + done(); + }); + n1.receive(message); + messageReceived.should.be.false(); + }); + + it('emits multiple messages on a single output', function(done) { + var flow = { + getNode: (id) => { return {'n1':n1,'n2':n2}[id]}, + }; + var n1 = new RedNode({_flow:flow,id:'n1',type:'abc',wires:[['n2']]}); + var n2 = new RedNode({_flow:flow,id:'n2',type:'abc'}); + + var messages = [ + {payload:"hello world"}, + {payload:"hello world again"} + ]; + + var rcvdCount = 0; + + n2.on('input',function(msg) { + if (rcvdCount === 0) { + // first msg sent, don't clone + should.deepEqual(msg,messages[rcvdCount]); + should.strictEqual(msg,messages[rcvdCount]); + rcvdCount += 1; + } else { + // second msg sent, clone + msg.payload.should.equal(messages[rcvdCount].payload); + should.notStrictEqual(msg,messages[rcvdCount]); + done(); + } + }); + n1.send([messages]); + }); + + it('emits messages to multiple outputs', function(done) { + var flow = { + getNode: (id) => { return {'n1':n1,'n2':n2,'n3':n3,'n4':n4,'n5':n5}[id]}, + }; + var n1 = new RedNode({_flow:flow, id:'n1',type:'abc',wires:[['n2'],['n3'],['n4','n5']]}); + var n2 = new RedNode({_flow:flow, id:'n2',type:'abc'}); + var n3 = new RedNode({_flow:flow, id:'n3',type:'abc'}); + var n4 = new RedNode({_flow:flow, id:'n4',type:'abc'}); + var n5 = new RedNode({_flow:flow, id:'n5',type:'abc'}); + + var messages = [ + {payload:"hello world"}, + null, + {payload:"hello world again"} + ]; + + var rcvdCount = 0; + + // first message sent, don't clone + // message uuids should match + n2.on('input',function(msg) { + should.deepEqual(msg,messages[0]); + should.strictEqual(msg,messages[0]); + rcvdCount += 1; + if (rcvdCount == 3) { + done(); + } + }); + + n3.on('input',function(msg) { + should.fail(null,null,"unexpected message"); + }); + + // second message sent, clone + // message uuids wont match since we've cloned + n4.on('input',function(msg) { + msg.payload.should.equal(messages[2].payload); + should.notStrictEqual(msg,messages[2]); + rcvdCount += 1; + if (rcvdCount == 3) { + done(); + } + }); + + // third message sent, clone + // message uuids wont match since we've cloned + n5.on('input',function(msg) { + msg.payload.should.equal(messages[2].payload); + should.notStrictEqual(msg,messages[2]); + rcvdCount += 1; + if (rcvdCount == 3) { + done(); + } + }); + + n1.send(messages); + }); + + it('emits no messages', function(done) { + var flow = { + getNode: (id) => { return {'n1':n1,'n2':n2}[id]}, + }; + var n1 = new RedNode({_flow:flow,id:'n1',type:'abc',wires:[['n2']]}); + var n2 = new RedNode({_flow:flow,id:'n2',type:'abc'}); + + n2.on('input',function(msg) { + should.fail(null,null,"unexpected message"); + }); + + setTimeout(function() { + done(); + }, 200); + + n1.send(); + }); + + it('emits messages ignoring non-existent nodes', function(done) { + var flow = { + getNode: (id) => { return {'n1':n1,'n2':n2}[id]}, + }; + var n1 = new RedNode({_flow:flow,id:'n1',type:'abc',wires:[['n9'],['n2']]}); + var n2 = new RedNode({_flow:flow,id:'n2',type:'abc'}); + + var messages = [ + {payload:"hello world"}, + {payload:"hello world again"} + ]; + + // only one message sent, so no copy needed + n2.on('input',function(msg) { + should.deepEqual(msg,messages[1]); + should.strictEqual(msg,messages[1]); + done(); + }); + + n1.send(messages); + }); + + it('emits messages without cloning req or res', function(done) { + var flow = { + getNode: (id) => { return {'n1':n1,'n2':n2,'n3':n3}[id]}, + }; + var n1 = new RedNode({_flow:flow,id:'n1',type:'abc',wires:[[['n2'],['n3']]]}); + var n2 = new RedNode({_flow:flow,id:'n2',type:'abc'}); + var n3 = new RedNode({_flow:flow,id:'n3',type:'abc'}); + + var req = {}; + var res = {}; + var cloned = {}; + var message = {payload: "foo", cloned: cloned, req: req, res: res}; + + var rcvdCount = 0; + + // first message to be sent, so should not be cloned + n2.on('input',function(msg) { + should.deepEqual(msg, message); + msg.cloned.should.be.exactly(message.cloned); + msg.req.should.be.exactly(message.req); + msg.res.should.be.exactly(message.res); + rcvdCount += 1; + if (rcvdCount == 2) { + done(); + } + }); + + // second message to be sent, so should be cloned + // message uuids wont match since we've cloned + n3.on('input',function(msg) { + msg.payload.should.equal(message.payload); + msg.cloned.should.not.be.exactly(message.cloned); + msg.req.should.be.exactly(message.req); + msg.res.should.be.exactly(message.res); + rcvdCount += 1; + if (rcvdCount == 2) { + done(); + } + }); + + n1.send(message); + }); + + it("logs the uuid for all messages sent", function(done) { + var logHandler = { + msgIds:[], + messagesSent: 0, + emit: function(event, msg) { + if (msg.event == "node.abc.send" && msg.level == Log.METRIC) { + this.messagesSent++; + this.msgIds.push(msg.msgid); + (typeof msg.msgid).should.not.be.equal("undefined"); + } + } + }; + + Log.addHandler(logHandler); + var flow = { + getNode: (id) => { return {'n1':sender,'n2':receiver1,'n3':receiver2}[id]}, + }; + + var sender = new RedNode({_flow:flow,id:'n1',type:'abc', wires:[['n2', 'n3']]}); + var receiver1 = new RedNode({_flow:flow,id:'n2',type:'abc'}); + var receiver2 = new RedNode({_flow:flow,id:'n3',type:'abc'}); + sender.send({"some": "message"}); + setTimeout(function() { + try { + logHandler.messagesSent.should.equal(1); + should.exist(logHandler.msgIds[0]) + Log.removeHandler(logHandler); + done(); + } catch(err) { + Log.removeHandler(logHandler); + done(err); + } + },50) + }) + }); + + + describe('#log', function() { + it('produces a log message', function(done) { + var n = new RedNode({id:'123',type:'abc',z:'789'}); + var loginfo = {}; + sinon.stub(Log, 'log', function(msg) { + loginfo = msg; + }); + n.log("a log message"); + should.deepEqual({level:Log.INFO, id:n.id, + type:n.type, msg:"a log message",z:'789'}, loginfo); + Log.log.restore(); + done(); + }); + it('produces a log message with a name', function(done) { + var n = new RedNode({id:'123', type:'abc', name:"barney", z:'789'}); + var loginfo = {}; + sinon.stub(Log, 'log', function(msg) { + loginfo = msg; + }); + n.log("a log message"); + should.deepEqual({level:Log.INFO, id:n.id, name: "barney", + type:n.type, msg:"a log message",z:'789'}, loginfo); + Log.log.restore(); + done(); + }); + }); + + describe('#warn', function() { + it('produces a warning message', function(done) { + var n = new RedNode({id:'123',type:'abc',z:'789'}); + var loginfo = {}; + sinon.stub(Log, 'log', function(msg) { + loginfo = msg; + }); + n.warn("a warning"); + should.deepEqual({level:Log.WARN, id:n.id, + type:n.type, msg:"a warning",z:'789'}, loginfo); + Log.log.restore(); + done(); + }); + }); + + describe('#error', function() { + it('handles a null error message', function(done) { + var flow = { + handleError: sinon.stub() + } + var n = new RedNode({_flow:flow, id:'123',type:'abc',z:'789'}); + var message = {a:1}; + n.error(null,message); + + flow.handleError.called.should.be.true(); + flow.handleError.args[0][0].should.eql(n); + flow.handleError.args[0][1].should.eql(""); + flow.handleError.args[0][2].should.eql(message); + + done(); + }); + + it('produces an error message', function(done) { + var flow = { + handleError: sinon.stub() + } + var n = new RedNode({_flow:flow, id:'123',type:'abc',z:'789'}); + var message = {a:2}; + + n.error("This is an error",message); + + flow.handleError.called.should.be.true(); + flow.handleError.args[0][0].should.eql(n); + flow.handleError.args[0][1].should.eql("This is an error"); + flow.handleError.args[0][2].should.eql(message); + + done(); + }); + + }); + + describe('#metric', function() { + it('produces a metric message', function(done) { + var n = new RedNode({id:'123',type:'abc'}); + var loginfo = {}; + sinon.stub(Log, 'log', function(msg) { + loginfo = msg; + }); + var msg = {payload:"foo", _msgid:"987654321"}; + n.metric("test.metric",msg,"15mb"); + should.deepEqual({value:"15mb", level:Log.METRIC, nodeid:n.id, + event:"node.abc.test.metric",msgid:"987654321"}, loginfo); + Log.log.restore(); + done(); + }); + }); + + describe('#metric', function() { + it('returns metric value if eventname undefined', function(done) { + var n = new RedNode({id:'123',type:'abc'}); + var loginfo = {}; + sinon.stub(Log, 'log', function(msg) { + loginfo = msg; + }); + var msg = {payload:"foo", _msgid:"987654321"}; + var m = n.metric(undefined,msg,"15mb"); + m.should.be.a.Boolean(); + Log.log.restore(); + done(); + }); + it('returns not defined if eventname defined', function(done) { + var n = new RedNode({id:'123',type:'abc'}); + var loginfo = {}; + sinon.stub(Log, 'log', function(msg) { + loginfo = msg; + }); + var msg = {payload:"foo", _msgid:"987654321"}; + var m = n.metric("info",msg,"15mb"); + should(m).be.undefined; + Log.log.restore(); + done(); + }); + }); + + describe('#status', function() { + it('publishes status', function(done) { + var flow = { + handleStatus: sinon.stub() + } + var n = new RedNode({_flow:flow,id:'123',type:'abc'}); + var status = {fill:"green",shape:"dot",text:"connected"}; + + n.status(status); + + flow.handleStatus.called.should.be.true(); + flow.handleStatus.args[0][0].should.eql(n); + flow.handleStatus.args[0][1].should.eql(status); + done(); + }); + it('publishes status for plain string', function(done) { + var flow = { handleStatus: sinon.stub() } + var n = new RedNode({_flow:flow,id:'123',type:'abc'}); + n.status("text status"); + flow.handleStatus.called.should.be.true(); + flow.handleStatus.args[0][0].should.eql(n); + flow.handleStatus.args[0][1].should.eql({text:"text status"}); + done(); + }); + it('publishes status for plain boolean', function(done) { + var flow = { handleStatus: sinon.stub() } + var n = new RedNode({_flow:flow,id:'123',type:'abc'}); + n.status(false); + flow.handleStatus.called.should.be.true(); + flow.handleStatus.args[0][0].should.eql(n); + flow.handleStatus.args[0][1].should.eql({text:"false"}); + done(); + }); + it('publishes status for plain number', function(done) { + var flow = { handleStatus: sinon.stub() } + var n = new RedNode({_flow:flow,id:'123',type:'abc'}); + n.status(123); + flow.handleStatus.called.should.be.true(); + flow.handleStatus.args[0][0].should.eql(n); + flow.handleStatus.args[0][1].should.eql({text:"123"}); + done(); + }); + }); + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/nodes/context/index_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/nodes/context/index_spec.js new file mode 100644 index 0000000..3c9030b --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/nodes/context/index_spec.js @@ -0,0 +1,985 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require('sinon'); +var path = require("path"); +var fs = require('fs-extra'); +var NR_TEST_UTILS = require("nr-test-utils"); +var Context = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/context/index"); + +describe('context', function() { + describe('local memory',function() { + beforeEach(function() { + Context.init({}); + Context.load(); + }); + afterEach(function() { + Context.clean({allNodes:{}}); + return Context.close(); + }); + it('stores local property',function() { + var context1 = Context.get("1","flowA"); + should.not.exist(context1.get("foo")); + context1.set("foo","test"); + context1.get("foo").should.equal("test"); + }); + it('stores local property - creates parent properties',function() { + var context1 = Context.get("1","flowA"); + context1.set("foo.bar","test"); + context1.get("foo").should.eql({bar:"test"}); + }); + it('deletes local property',function() { + var context1 = Context.get("1","flowA"); + context1.set("foo.abc.bar1","test1"); + context1.set("foo.abc.bar2","test2"); + context1.get("foo.abc").should.eql({bar1:"test1",bar2:"test2"}); + context1.set("foo.abc.bar1",undefined); + context1.get("foo.abc").should.eql({bar2:"test2"}); + context1.set("foo.abc",undefined); + should.not.exist(context1.get("foo.abc")); + context1.set("foo",undefined); + should.not.exist(context1.get("foo")); + }); + it('stores flow property',function() { + var context1 = Context.get("1","flowA"); + should.not.exist(context1.flow.get("foo")); + context1.flow.set("foo","test"); + context1.flow.get("foo").should.equal("test"); + }); + it('stores global property',function() { + var context1 = Context.get("1","flowA"); + should.not.exist(context1.global.get("foo")); + context1.global.set("foo","test"); + context1.global.get("foo").should.equal("test"); + }); + + it('keeps local context local', function() { + var context1 = Context.get("1","flowA"); + var context2 = Context.get("2","flowA"); + + should.not.exist(context1.get("foo")); + should.not.exist(context2.get("foo")); + context1.set("foo","test"); + + context1.get("foo").should.equal("test"); + should.not.exist(context2.get("foo")); + }); + it('flow context accessible to all flow nodes', function() { + var context1 = Context.get("1","flowA"); + var context2 = Context.get("2","flowA"); + + should.not.exist(context1.flow.get("foo")); + should.not.exist(context2.flow.get("foo")); + + context1.flow.set("foo","test"); + context1.flow.get("foo").should.equal("test"); + context2.flow.get("foo").should.equal("test"); + }); + + it('flow context not shared to nodes on other flows', function() { + var context1 = Context.get("1","flowA"); + var context2 = Context.get("2","flowB"); + + should.not.exist(context1.flow.get("foo")); + should.not.exist(context2.flow.get("foo")); + + context1.flow.set("foo","test"); + context1.flow.get("foo").should.equal("test"); + should.not.exist(context2.flow.get("foo")); + }); + + it('global context shared to all nodes', function() { + var context1 = Context.get("1","flowA"); + var context2 = Context.get("2","flowB"); + + should.not.exist(context1.global.get("foo")); + should.not.exist(context2.global.get("foo")); + + context1.global.set("foo","test"); + context1.global.get("foo").should.equal("test"); + context2.global.get("foo").should.equal("test"); + }); + + it('context.flow/global are not enumerable', function() { + var context1 = Context.get("1","flowA"); + Object.keys(context1).length.should.equal(0); + Object.keys(context1.flow).length.should.equal(0); + Object.keys(context1.global).length.should.equal(0); + }) + + it('context.flow/global cannot be deleted', function() { + var context1 = Context.get("1","flowA"); + delete context1.flow; + should.exist(context1.flow); + delete context1.global; + should.exist(context1.global); + }) + + it('deletes context',function() { + var context = Context.get("1","flowA"); + should.not.exist(context.get("foo")); + context.set("foo","abc"); + context.get("foo").should.equal("abc"); + + return Context.delete("1","flowA").then(function(){ + context = Context.get("1","flowA"); + should.not.exist(context.get("foo")); + }); + }); + + it('enumerates context keys - sync', function() { + var context = Context.get("1","flowA"); + + var keys = context.keys(); + keys.should.be.an.Array(); + keys.should.be.empty(); + + context.set("foo","bar"); + keys = context.keys(); + keys.should.have.length(1); + keys[0].should.equal("foo"); + + context.set("abc.def","bar"); + keys = context.keys(); + keys.should.have.length(2); + keys[1].should.equal("abc"); + }); + + it('enumerates context keys - async', function(done) { + var context = Context.get("1","flowA"); + + var keys = context.keys(function(err,keys) { + keys.should.be.an.Array(); + keys.should.be.empty(); + context.set("foo","bar"); + keys = context.keys(function(err,keys) { + keys.should.have.length(1); + keys[0].should.equal("foo"); + + context.set("abc.def","bar"); + keys = context.keys(function(err,keys) { + keys.should.have.length(2); + keys[1].should.equal("abc"); + done(); + }); + }); + }); + }); + + it('should enumerate only context keys when GlobalContext was given - sync', function() { + Context.init({functionGlobalContext: {foo:"bar"}}); + Context.load().then(function(){ + var context = Context.get("1","flowA"); + context.global.set("foo2","bar2"); + var keys = context.global.keys(); + keys.should.have.length(2); + keys[0].should.equal("foo"); + keys[1].should.equal("foo2"); + }); + }); + + it('should enumerate only context keys when GlobalContext was given - async', function(done) { + Context.init({functionGlobalContext: {foo:"bar"}}); + Context.load().then(function(){ + var context = Context.get("1","flowA"); + context.global.set("foo2","bar2"); + context.global.keys(function(err,keys) { + keys.should.have.length(2); + keys[0].should.equal("foo"); + keys[1].should.equal("foo2"); + done(); + }); + }).catch(done); + }); + + + it('returns functionGlobalContext value if store value undefined', function() { + Context.init({functionGlobalContext: {foo:"bar"}}); + return Context.load().then(function(){ + var context = Context.get("1","flowA"); + var v = context.global.get('foo'); + v.should.equal('bar'); + }); + }) + + it('returns functionGlobalContext sub-value if store value undefined', function() { + Context.init({functionGlobalContext: {foo:{bar:123}}}); + return Context.load().then(function(){ + var context = Context.get("1","flowA"); + var v = context.global.get('foo.bar'); + should.equal(v,123); + }); + }) + + describe("$parent", function() { + it('should get undefined for $parent without key', function() { + var context0 = Context.get("0","flowA"); + var context1 = Context.get("1","flowB", context0); + var parent = context1.get("$parent"); + should.equal(parent, undefined); + }); + + it('should get undefined for $parent of root', function() { + var context0 = Context.get("0","flowA"); + var context1 = Context.get("1","flowB", context0); + var parent = context1.get("$parent.$parent.K"); + should.equal(parent, undefined); + }); + + it('should get value in $parent', function() { + var context0 = Context.get("0","flowA"); + var context1 = Context.get("1","flowB", context0); + context0.set("K", "v"); + var v = context1.get("$parent.K"); + should.equal(v, "v"); + }); + + it('should set value in $parent', function() { + var context0 = Context.get("0","flowA"); + var context1 = Context.get("1","flowB", context0); + context1.set("$parent.K", "v"); + var v = context0.get("K"); + should.equal(v, "v"); + }); + + it('should not contain $parent in keys', function() { + var context0 = Context.get("0","flowA"); + var context1 = Context.get("1","flowB", context0); + var parent = context1.get("$parent"); + context0.set("K0", "v0"); + context1.set("K1", "v1"); + var keys = context1.keys(); + keys.should.have.length(1); + keys[0].should.equal("K1"); + }); + }); + + }); + + describe('external context storage',function() { + var resourcesDir = path.resolve(path.join(__dirname,"..","resources","context")); + var sandbox = sinon.sandbox.create(); + var stubGet = sandbox.stub(); + var stubSet = sandbox.stub(); + var stubKeys = sandbox.stub(); + var stubDelete = sandbox.stub().returns(Promise.resolve()); + var stubClean = sandbox.stub().returns(Promise.resolve()); + var stubOpen = sandbox.stub().returns(Promise.resolve()); + var stubClose = sandbox.stub().returns(Promise.resolve()); + var stubGet2 = sandbox.stub(); + var stubSet2 = sandbox.stub(); + var stubKeys2 = sandbox.stub(); + var stubDelete2 = sandbox.stub().returns(Promise.resolve()); + var stubClean2 = sandbox.stub().returns(Promise.resolve()); + var stubOpen2 = sandbox.stub().returns(Promise.resolve()); + var stubClose2 = sandbox.stub().returns(Promise.resolve()); + var testPlugin = function(config){ + function Test(){} + Test.prototype.get = stubGet; + Test.prototype.set = stubSet; + Test.prototype.keys = stubKeys; + Test.prototype.delete = stubDelete; + Test.prototype.clean = stubClean; + Test.prototype.open = stubOpen; + Test.prototype.close = stubClose; + return new Test(config); + }; + var testPlugin2 = function(config){ + function Test2(){} + Test2.prototype.get = stubGet2; + Test2.prototype.set = stubSet2; + Test2.prototype.keys = stubKeys2; + Test2.prototype.delete = stubDelete2; + Test2.prototype.clean = stubClean2; + Test2.prototype.open = stubOpen2; + Test2.prototype.close = stubClose2; + return new Test2(config); + }; + var contextStorage={ + test:{ + module: testPlugin, + config:{} + } + }; + var contextDefaultStorage={ + default: { + module: testPlugin2, + config:{} + }, + test:{ + module: testPlugin, + config:{} + } + }; + var contextAlias={ + default: "test", + test:{ + module: testPlugin, + config:{} + } + }; + var memoryStorage ={ + memory:{ + module: "memory" + } + }; + + afterEach(function() { + sandbox.reset(); + return Context.clean({allNodes:{}}).then(function(){ + return Context.close(); + }).then(function(){ + return fs.remove(resourcesDir); + }); + }); + + describe('load modules',function(){ + it('should call open()', function() { + Context.init({contextStorage:contextDefaultStorage}); + Context.load().then(function(){ + stubOpen.called.should.be.true(); + stubOpen2.called.should.be.true(); + }); + }); + it('should load memory module', function() { + Context.init({contextStorage:{memory:{module:"memory"}}}); + return Context.load(); + }); + it('should load localfilesystem module', function() { + Context.init({contextStorage:{file:{module:"localfilesystem",config:{dir:resourcesDir}}}}); + return Context.load(); + }); + it('should ignore reserved storage name `_`', function(done) { + Context.init({contextStorage:{_:{module:testPlugin}}}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + var cb = function(){} + context.set("foo","bar","_",cb); + context.get("foo","_",cb); + context.keys("_",cb); + stubSet.called.should.be.false(); + stubGet.called.should.be.false(); + stubKeys.called.should.be.false(); + done(); + }).catch(done); + }); + + it('should fail when using invalid store name', function(done) { + Context.init({contextStorage:{'Invalid name':{module:testPlugin}}}); + Context.load().then(function(){ + done("An error was not thrown"); + }).catch(function(){ + done(); + }); + }); + it('should fail when using invalid sign character', function (done) { + Context.init({ contextStorage:{'abc-123':{module:testPlugin}}}); + Context.load().then(function () { + done("An error was not thrown"); + }).catch(function () { + done(); + }); + }); + it('should fail when using invalid default context', function(done) { + Context.init({contextStorage:{default:"noexist"}}); + Context.load().then(function(){ + done("An error was not thrown"); + }).catch(function(){ + done(); + }); + }); + it('should fail for the storage with no module', function(done) { + Context.init({ contextStorage: { test: {}}}); + Context.load().then(function(){ + done("An error was not thrown"); + }).catch(function(){ + done(); + }); + }); + it('should fail to load non-existent module', function(done) { + Context.init({contextStorage:{ file:{module:"nonexistent"} }}); + Context.load().then(function(){ + done("An error was not thrown"); + }).catch(function(){ + done(); + }); + }); + it('should fail to load invalid module', function (done) { + Context.init({contextStorage: { + test: { + module: function (config) { + throw new Error("invalid plugin was loaded."); + } + } + }}); + Context.load().then(function () { + done("An error was not thrown"); + }).catch(function () { + done(); + }); + }); + }); + + describe('close modules',function(){ + it('should call close()', function(done) { + Context.init({contextStorage:contextDefaultStorage}); + Context.load().then(function(){ + return Context.close().then(function(){ + stubClose.called.should.be.true(); + stubClose2.called.should.be.true(); + done(); + }); + }).catch(done); + }); + }); + + describe('store context',function() { + it('should store local property to external context storage',function(done) { + Context.init({contextStorage:contextStorage}); + var cb = function(){done("An error occurred")} + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.set("foo","bar","test",cb); + context.get("foo","test",cb); + context.keys("test",cb); + stubSet.calledWithExactly("1:flow","foo","bar",cb).should.be.true(); + stubGet.calledWith("1:flow","foo").should.be.true(); + stubKeys.calledWithExactly("1:flow",cb).should.be.true(); + done(); + }).catch(done); + }); + it('should store flow property to external context storage',function(done) { + Context.init({contextStorage:contextStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + var cb = function(){done("An error occurred")} + context.flow.set("foo","bar","test",cb); + context.flow.get("foo","test",cb); + context.flow.keys("test",cb); + stubSet.calledWithExactly("flow","foo","bar",cb).should.be.true(); + stubGet.calledWith("flow","foo").should.be.true(); + stubKeys.calledWithExactly("flow",cb).should.be.true(); + done(); + }).catch(done); + }); + it('should store global property to external context storage',function(done) { + Context.init({contextStorage:contextStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + var cb = function(){done("An error occurred")} + context.global.set("foo","bar","test",cb); + context.global.get("foo","test",cb); + context.global.keys("test",cb); + stubSet.calledWithExactly("global","foo","bar",cb).should.be.true(); + stubGet.calledWith("global","foo").should.be.true(); + stubKeys.calledWith("global").should.be.true(); + done(); + }).catch(done); + }); + it('should store data to the default context when non-existent context storage was specified', function(done) { + Context.init({contextStorage:contextDefaultStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + var cb = function(){done("An error occurred")} + context.set("foo","bar","nonexist",cb); + context.get("foo","nonexist",cb); + context.keys("nonexist",cb); + stubGet.called.should.be.false(); + stubSet.called.should.be.false(); + stubKeys.called.should.be.false(); + stubSet2.calledWithExactly("1:flow","foo","bar",cb).should.be.true(); + stubGet2.calledWith("1:flow","foo").should.be.true(); + stubKeys2.calledWithExactly("1:flow",cb).should.be.true(); + done(); + }).catch(done); + }); + it('should use the default context', function(done) { + Context.init({contextStorage:contextDefaultStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + var cb = function(){done("An error occurred")} + context.set("foo","bar","default",cb); + context.get("foo","default",cb); + context.keys("default",cb); + stubGet.called.should.be.false(); + stubSet.called.should.be.false(); + stubKeys.called.should.be.false(); + stubSet2.calledWithExactly("1:flow","foo","bar",cb).should.be.true(); + stubGet2.calledWith("1:flow","foo").should.be.true(); + stubKeys2.calledWithExactly("1:flow",cb).should.be.true(); + done(); + }).catch(done); + }); + it('should use the alias of default context', function(done) { + Context.init({contextStorage:contextDefaultStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + var cb = function(){done("An error occurred")} + context.set("foo","alias",cb); + context.get("foo",cb); + context.keys(cb); + stubGet.called.should.be.false(); + stubSet.called.should.be.false(); + stubKeys.called.should.be.false(); + stubSet2.calledWithExactly("1:flow","foo","alias",cb).should.be.true(); + stubGet2.calledWith("1:flow","foo").should.be.true(); + stubKeys2.calledWithExactly("1:flow",cb).should.be.true(); + done(); + }).catch(done); + }); + + it('should allow the store name to be provide in the key', function(done) { + Context.init({contextStorage:contextDefaultStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + var cb = function(){done("An error occurred")} + context.set("#:(test)::foo","bar"); + context.get("#:(test)::foo"); + stubGet2.called.should.be.false(); + stubSet2.called.should.be.false(); + stubSet.calledWithExactly("1:flow","foo","bar",undefined).should.be.true(); + stubGet.calledWith("1:flow","foo").should.be.true(); + done(); + }).catch(done); + }); + + + it('should use default as the alias of other context', function(done) { + Context.init({contextStorage:contextAlias}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + var cb = function(){done("An error occurred")} + context.set("foo","alias",cb); + context.get("foo",cb); + context.keys(cb); + stubSet.calledWithExactly("1:flow","foo","alias",cb).should.be.true(); + stubGet.calledWith("1:flow","foo").should.be.true(); + stubKeys.calledWithExactly("1:flow",cb).should.be.true(); + done(); + }).catch(done); + }); + it('should not throw an error using undefined storage for local context', function(done) { + Context.init({contextStorage:contextStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + var cb = function(){done("An error occurred")} + context.get("local","nonexist",cb); + done() + }).catch(done); + }); + it('should throw an error using undefined storage for flow context', function(done) { + Context.init({contextStorage:contextStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + var cb = function(){done("An error occurred")} + context.flow.get("flow","nonexist",cb); + done(); + }).catch(done); + }); + + it('should return functionGlobalContext value as a default - synchronous', function(done) { + var fGC = { "foo": 456 }; + Context.init({contextStorage:memoryStorage, functionGlobalContext:fGC }); + Context.load().then(function() { + var context = Context.get("1","flow"); + // Get foo - should be value from fGC + var v = context.global.get("foo"); + v.should.equal(456); + + // Update foo - should not touch fGC object + context.global.set("foo","new value"); + fGC.foo.should.equal(456); + + // Get foo - should be the updated value + v = context.global.get("foo"); + v.should.equal("new value"); + done(); + }).catch(done); + }) + + it('should return functionGlobalContext value as a default - async', function(done) { + var fGC = { "foo": 456 }; + Context.init({contextStorage:memoryStorage, functionGlobalContext:fGC }); + Context.load().then(function() { + var context = Context.get("1","flow"); + // Get foo - should be value from fGC + context.global.get("foo", function(err, v) { + if (err) { + done(err) + } else { + v.should.equal(456); + // Update foo - should not touch fGC object + context.global.set("foo","new value", function(err) { + if (err) { + done(err) + } else { + fGC.foo.should.equal(456); + // Get foo - should be the updated value + context.global.get("foo", function(err, v) { + if (err) { + done(err) + } else { + v.should.equal("new value"); + done(); + } + }); + } + }); + } + }); + }).catch(done); + }) + + it('should return multiple values if key is an array', function(done) { + Context.init({contextStorage:memoryStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.set("foo1","bar1","memory"); + context.set("foo2","bar2","memory"); + context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err) { + done(err); + } else { + foo1.should.be.equal("bar1"); + foo2.should.be.equal("bar2"); + should.not.exist(foo3); + done(); + } + }); + }).catch(function(err){ done(err); }); + }); + + it('should return multiple functionGlobalContext values if key is an array', function(done) { + var fGC = { "foo1": 456, "foo2": {"bar":789} }; + Context.init({contextStorage:memoryStorage, functionGlobalContext:fGC }); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.global.get(["foo1","foo2.bar","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err) { + done(err); + } else { + should.equal(foo1, 456); + should.equal(foo2, 789); + should.not.exist(foo3); + done(); + } + }); + }).catch(function(err){ done(err); }); + }); + + it('should return an error if an error occurs in getting multiple store values', function(done) { + Context.init({contextStorage:contextStorage}); + stubGet.onFirstCall().callsArgWith(2, "error2", "bar1"); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.global.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err === "error2") { + done(); + } else { + done("An error occurred"); + } + }); + }).catch(function(err){ done(err); }); + }); + + it('should return a first error if some errors occur in getting multiple store values', function(done) { + Context.init({contextStorage:contextStorage}); + stubGet.onFirstCall().callsArgWith(2, "error1"); + stubGet.onSecondCall().callsArgWith(2, null, "bar2"); + stubGet.onThirdCall().callsArgWith(2, "error3"); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err === "error1") { + done(); + } else { + done("An error occurred"); + } + }); + }).catch(function(err){ done(err); }); + }); + + it('should store multiple properties if key and value are arrays', function(done) { + Context.init({contextStorage:memoryStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.set(["foo1","foo2","foo3"], ["bar1","bar2","bar3"], "memory", function(err){ + if (err) { + done(err); + } else { + context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err) { + done(err); + } else { + foo1.should.be.equal("bar1"); + foo2.should.be.equal("bar2"); + foo3.should.be.equal("bar3"); + done(); + } + }); + } + }); + }); + }); + + it('should deletes multiple properties', function(done) { + Context.init({contextStorage:memoryStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.set(["foo1","foo2","foo3"], ["bar1","bar2","bar3"], "memory", function(err){ + if (err) { + done(err); + } else { + context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err) { + done(err); + } else { + foo1.should.be.equal("bar1"); + foo2.should.be.equal("bar2"); + foo3.should.be.equal("bar3"); + context.set(["foo1","foo2","foo3"], new Array(3), "memory", function(err){ + if (err) { + done(err); + } else { + context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err) { + done(err); + } else { + should.not.exist(foo1); + should.not.exist(foo2); + should.not.exist(foo3); + done(); + } + }); + } + }); + } + }); + } + }); + }); + }); + + it('should use null for missing values if the value array is shorter than the key array', function(done) { + Context.init({contextStorage:memoryStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.set(["foo1","foo2","foo3"], ["bar1","bar2"], "memory", function(err){ + if (err) { + done(err); + } else { + context.keys(function(err, keys){ + keys.should.have.length(3); + keys.should.eql(["foo1","foo2","foo3"]); + context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err) { + done(err); + } else { + foo1.should.be.equal("bar1"); + foo2.should.be.equal("bar2"); + should(foo3).be.null(); + done(); + } + }); + }); + } + }); + }); + }); + + it('should use null for missing values if the value is not array', function(done) { + Context.init({contextStorage:memoryStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.set(["foo1","foo2","foo3"], "bar1", "memory", function(err){ + if (err) { + done(err); + } else { + context.keys(function(err, keys){ + keys.should.have.length(3); + keys.should.eql(["foo1","foo2","foo3"]); + context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err) { + done(err); + } else { + foo1.should.be.equal("bar1"); + should(foo2).be.null(); + should(foo3).be.null(); + done(); + } + }); + }); + } + }); + }); + }); + + it('should ignore the extra values if the value array is longer than the key array', function(done) { + Context.init({contextStorage:memoryStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.set(["foo1","foo2","foo3"], ["bar1","bar2","bar3","ignored"], "memory", function(err){ + if (err) { + done(err); + } else { + context.keys(function(err, keys){ + keys.should.have.length(3); + keys.should.eql(["foo1","foo2","foo3"]); + context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err) { + done(err); + } else { + foo1.should.be.equal("bar1"); + foo2.should.be.equal("bar2"); + foo3.should.be.equal("bar3"); + done(); + } + }); + }); + } + }); + }); + }); + + it('should return an error if an error occurs in storing multiple values', function(done) { + Context.init({contextStorage:contextStorage}); + stubSet.onFirstCall().callsArgWith(3, "error2"); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.set(["foo1","foo2","foo3"], ["bar1","bar2","bar3"], "memory", function(err){ + if (err === "error2") { + done(); + } else { + done("An error occurred"); + } + }); + }).catch(function(err){ done(err); }); + }); + + it('should throw an error if callback of context.get is not a function', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.get("foo", "memory", "callback"); + done("should throw an error."); + }).catch(function () { + done(); + }); + }); + + it('should not throw an error if callback of context.get is not specified', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.get("foo", "memory"); + done(); + }).catch(done); + }); + + it('should throw an error if callback of context.set is not a function', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.set("foo", "bar", "memory", "callback"); + done("should throw an error."); + }).catch(function () { + done(); + }); + }); + + it('should not throw an error if callback of context.set is not specified', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.set("foo", "bar", "memory"); + done(); + }).catch(done); + }); + + it('should throw an error if callback of context.keys is not a function', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.keys("memory", "callback"); + done("should throw an error."); + }).catch(function () { + done(); + }); + }); + + it('should not throw an error if callback of context.keys is not specified', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.keys("memory"); + done(); + }).catch(done); + }); + + }); + + describe('listStores', function () { + it('should list context storages', function (done) { + Context.init({ contextStorage: contextDefaultStorage }); + Context.load().then(function () { + var list = Context.listStores(); + list.default.should.equal("default"); + list.stores.should.eql(["default", "test"]); + done(); + }).catch(done); + }); + + it('should list context storages without default storage', function (done) { + Context.init({ contextStorage: contextStorage }); + Context.load().then(function () { + var list = Context.listStores(); + list.default.should.equal("test"); + list.stores.should.eql(["test"]); + done(); + }).catch(done); + }); + }); + + describe('delete context',function(){ + it('should not call delete() when external context storage is used', function(done) { + Context.init({contextStorage:contextDefaultStorage}); + Context.load().then(function(){ + Context.get("flowA"); + return Context.delete("flowA").then(function(){ + stubDelete.called.should.be.false(); + stubDelete2.called.should.be.false(); + done(); + }); + }).catch(done); + }); + }); + + describe('clean context',function(){ + it('should call clean()', function(done) { + Context.init({contextStorage:contextDefaultStorage}); + Context.load().then(function(){ + return Context.clean({allNodes:{}}).then(function(){ + stubClean.calledWithExactly([]).should.be.true(); + stubClean2.calledWithExactly([]).should.be.true(); + done(); + }); + }).catch(done); + }); + }); + }); + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/nodes/context/localfilesystem_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/nodes/context/localfilesystem_spec.js new file mode 100644 index 0000000..26f9789 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/nodes/context/localfilesystem_spec.js @@ -0,0 +1,883 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require('should'); +var fs = require('fs-extra'); +var path = require("path"); +var NR_TEST_UTILS = require("nr-test-utils"); +var LocalFileSystem = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/context/localfilesystem"); + +var resourcesDir = path.resolve(path.join(__dirname,"..","resources","context")); + +var defaultContextBase = "context"; + +describe('localfilesystem',function() { + + before(function() { + return fs.remove(resourcesDir); + }); + + describe('#get/set',function() { + var context; + beforeEach(function() { + context = LocalFileSystem({dir: resourcesDir, cache: false}); + return context.open(); + }); + + afterEach(function() { + return context.clean([]).then(function(){ + return context.close(); + }).then(function(){ + return fs.remove(resourcesDir); + }); + }); + + it('should store property',function(done) { + context.get("nodeX","foo",function(err, value){ + if (err) { return done(err); } + should.not.exist(value); + context.set("nodeX","foo","test",function(err){ + if (err) { return done(err); } + context.get("nodeX","foo",function(err, value){ + if (err) { return done(err); } + value.should.be.equal("test"); + done(); + }); + }); + }); + }); + + it('should store property - creates parent properties',function(done) { + context.set("nodeX","foo.bar","test",function(err){ + context.get("nodeX","foo",function(err, value){ + value.should.be.eql({bar:"test"}); + done(); + }); + }); + }); + + it('should store local scope property', function (done) { + context.set("abc:def", "foo.bar", "test", function (err) { + context.get("abc:def", "foo", function (err, value) { + value.should.be.eql({ bar: "test" }); + done(); + }); + }); + }); + + it('should delete property',function(done) { + context.set("nodeX","foo.abc.bar1","test1",function(err){ + context.set("nodeX","foo.abc.bar2","test2",function(err){ + context.get("nodeX","foo.abc",function(err, value){ + value.should.be.eql({bar1:"test1",bar2:"test2"}); + context.set("nodeX","foo.abc.bar1",undefined,function(err){ + context.get("nodeX","foo.abc",function(err, value){ + value.should.be.eql({bar2:"test2"}); + context.set("nodeX","foo.abc",undefined,function(err){ + context.get("nodeX","foo.abc",function(err, value){ + should.not.exist(value); + context.set("nodeX","foo",undefined,function(err){ + context.get("nodeX","foo",function(err, value){ + should.not.exist(value); + done(); + }); + }); + }); + }); + }); + }); + }); + }); + }); + }); + + it('should not shared context with other scope', function(done) { + context.get("nodeX","foo",function(err, value){ + should.not.exist(value); + context.get("nodeY","foo",function(err, value){ + should.not.exist(value); + context.set("nodeX","foo","testX",function(err){ + context.set("nodeY","foo","testY",function(err){ + context.get("nodeX","foo",function(err, value){ + value.should.be.equal("testX"); + context.get("nodeY","foo",function(err, value){ + value.should.be.equal("testY"); + done(); + }); + }); + }); + }); + }); + }); + }); + + it('should store string',function(done) { + context.get("nodeX","foo",function(err, value){ + should.not.exist(value); + context.set("nodeX","foo","bar",function(err){ + context.get("nodeX","foo",function(err, value){ + value.should.be.String(); + value.should.be.equal("bar"); + context.set("nodeX","foo","1",function(err){ + context.get("nodeX","foo",function(err, value){ + value.should.be.String(); + value.should.be.equal("1"); + done(); + }); + }); + }); + }); + }); + }); + + it('should store number',function(done) { + context.get("nodeX","foo",function(err, value){ + should.not.exist(value); + context.set("nodeX","foo",1,function(err){ + context.get("nodeX","foo",function(err, value){ + value.should.be.Number(); + value.should.be.equal(1); + done(); + }); + }); + }); + }); + + it('should store null',function(done) { + context.get("nodeX","foo",function(err, value){ + should.not.exist(value); + context.set("nodeX","foo",null,function(err){ + context.get("nodeX","foo",function(err, value){ + should(value).be.null(); + done(); + }); + }); + }); + }); + + it('should store boolean',function(done) { + context.get("nodeX","foo",function(err, value){ + should.not.exist(value); + context.set("nodeX","foo",true,function(err){ + context.get("nodeX","foo",function(err, value){ + value.should.be.Boolean().and.true(); + context.set("nodeX","foo",false,function(err){ + context.get("nodeX","foo",function(err, value){ + value.should.be.Boolean().and.false(); + done(); + }); + }); + }); + }); + }); + }); + + it('should store object',function(done) { + context.get("nodeX","foo",function(err, value){ + should.not.exist(value); + context.set("nodeX","foo",{obj:"bar"},function(err){ + context.get("nodeX","foo",function(err, value){ + value.should.be.Object(); + value.should.eql({obj:"bar"}); + done(); + }); + }); + }); + }); + + it('should store array',function(done) { + context.get("nodeX","foo",function(err, value){ + should.not.exist(value); + context.set("nodeX","foo",["a","b","c"],function(err){ + context.get("nodeX","foo",function(err, value){ + value.should.be.Array(); + value.should.eql(["a","b","c"]); + context.get("nodeX","foo[1]",function(err, value){ + value.should.be.String(); + value.should.equal("b"); + done(); + }); + }); + }); + }); + }); + + it('should store array of arrays',function(done) { + context.get("nodeX","foo",function(err, value){ + should.not.exist(value); + context.set("nodeX","foo",[["a","b","c"],[1,2,3,4],[true,false]],function(err){ + context.get("nodeX","foo",function(err, value){ + value.should.be.Array(); + value.should.have.length(3); + value[0].should.have.length(3); + value[1].should.have.length(4); + value[2].should.have.length(2); + context.get("nodeX","foo[1]",function(err, value){ + value.should.be.Array(); + value.should.have.length(4); + value.should.be.eql([1,2,3,4]); + done(); + }); + }); + }); + }); + }); + + it('should store array of objects',function(done) { + context.get("nodeX","foo",function(err, value){ + should.not.exist(value); + context.set("nodeX","foo",[{obj:"bar1"},{obj:"bar2"},{obj:"bar3"}],function(err){ + context.get("nodeX","foo",function(err, value){ + value.should.be.Array(); + value.should.have.length(3); + value[0].should.be.Object(); + value[1].should.be.Object(); + value[2].should.be.Object(); + context.get("nodeX","foo[1]",function(err, value){ + value.should.be.Object(); + value.should.be.eql({obj:"bar2"}); + done(); + }); + }); + }); + }); + }); + + it('should set/get multiple values', function(done) { + context.set("nodeX",["one","two","three"],["test1","test2","test3"], function(err) { + context.get("nodeX",["one","two"], function() { + Array.prototype.slice.apply(arguments).should.eql([undefined,"test1","test2"]) + done(); + }); + }); + }) + it('should set/get multiple values - get unknown', function(done) { + context.set("nodeX",["one","two","three"],["test1","test2","test3"], function(err) { + context.get("nodeX",["one","two","unknown"], function() { + Array.prototype.slice.apply(arguments).should.eql([undefined,"test1","test2",undefined]) + done(); + }); + }); + }) + it('should set/get multiple values - single value providd', function(done) { + context.set("nodeX",["one","two","three"],"test1", function(err) { + context.get("nodeX",["one","two"], function() { + Array.prototype.slice.apply(arguments).should.eql([undefined,"test1",null]) + done(); + }); + }); + }) + + it('should throw error if bad key included in multiple keys - get', function(done) { + context.set("nodeX",["one","two","three"],["test1","test2","test3"], function(err) { + context.get("nodeX",["one",".foo","three"], function(err) { + should.exist(err); + done(); + }); + }); + }) + + it('should throw error if bad key included in multiple keys - set', function(done) { + context.set("nodeX",["one",".foo","three"],["test1","test2","test3"], function(err) { + should.exist(err); + // Check 'one' didn't get set as a result + context.get("nodeX","one",function(err,one) { + should.not.exist(one); + done(); + }) + }); + }) + + it('should throw an error when getting a value with invalid key', function (done) { + context.set("nodeX","foo","bar",function(err) { + context.get("nodeX"," ",function(err,value) { + should.exist(err); + done(); + }); + }); + }); + + it('should throw an error when setting a value with invalid key',function (done) { + context.set("nodeX"," ","bar",function (err) { + should.exist(err); + done(); + }); + }); + + it('should throw an error when callback of get() is not a function',function (done) { + try { + context.get("nodeX","foo","callback"); + done("should throw an error."); + } catch (err) { + done(); + } + }); + + it('should throw an error when callback of get() is not specified',function (done) { + try { + context.get("nodeX","foo"); + done("should throw an error."); + } catch (err) { + done(); + } + }); + + it('should throw an error when callback of set() is not a function',function (done) { + try { + context.set("nodeX","foo","bar","callback"); + done("should throw an error."); + } catch (err) { + done(); + } + }); + + it('should not throw an error when callback of set() is not specified', function (done) { + try { + context.set("nodeX"," ","bar"); + done(); + } catch (err) { + done("should not throw an error."); + } + }); + + it('should handle empty context file', function (done) { + fs.outputFile(path.join(resourcesDir,defaultContextBase,"nodeX","flow.json"),"",function(){ + context.get("nodeX", "foo", function (err, value) { + should.not.exist(value); + context.set("nodeX", "foo", "test", function (err) { + context.get("nodeX", "foo", function (err, value) { + value.should.be.equal("test"); + done(); + }); + }); + }); + }); + }); + + it('should throw an error when reading corrupt context file', function (done) { + fs.outputFile(path.join(resourcesDir, defaultContextBase, "nodeX", "flow.json"),"{abc",function(){ + context.get("nodeX", "foo", function (err, value) { + should.exist(err); + done(); + }); + }); + }); + }); + + describe('#keys',function() { + var context; + beforeEach(function() { + context = LocalFileSystem({dir: resourcesDir, cache: false}); + return context.open(); + }); + + afterEach(function() { + return context.clean([]).then(function(){ + return context.close(); + }).then(function(){ + return fs.remove(resourcesDir); + }); + }); + + it('should enumerate context keys', function(done) { + context.keys("nodeX",function(err, value){ + value.should.be.an.Array(); + value.should.be.empty(); + context.set("nodeX","foo","bar",function(err){ + context.keys("nodeX",function(err, value){ + value.should.have.length(1); + value[0].should.equal("foo"); + context.set("nodeX","abc.def","bar",function(err){ + context.keys("nodeX",function(err, value){ + value.should.have.length(2); + value[1].should.equal("abc"); + done(); + }); + }); + }); + }); + }); + }); + + it('should enumerate context keys in each scopes', function(done) { + context.keys("nodeX",function(err, value){ + value.should.be.an.Array(); + value.should.be.empty(); + context.keys("nodeY",function(err, value){ + value.should.be.an.Array(); + value.should.be.empty(); + context.set("nodeX","foo","bar",function(err){ + context.set("nodeY","hoge","piyo",function(err){ + context.keys("nodeX",function(err, value){ + value.should.have.length(1); + value[0].should.equal("foo"); + context.keys("nodeY",function(err, value){ + value.should.have.length(1); + value[0].should.equal("hoge"); + done(); + }); + }); + }); + }); + }); + }); + }); + + it('should throw an error when callback of keys() is not a function', function (done) { + try { + context.keys("nodeX", "callback"); + done("should throw an error."); + } catch (err) { + done(); + } + }); + + it('should throw an error when callback of keys() is not specified', function (done) { + try { + context.keys("nodeX"); + done("should throw an error."); + } catch (err) { + done(); + } + }); + }); + + describe('#delete',function() { + var context; + beforeEach(function() { + context = LocalFileSystem({dir: resourcesDir, cache: false}); + return context.open(); + }); + + afterEach(function() { + return context.clean([]).then(function(){ + return context.close(); + }).then(function(){ + return fs.remove(resourcesDir); + }); + }); + + it('should delete context',function(done) { + context.get("nodeX","foo",function(err, value){ + should.not.exist(value); + context.get("nodeY","foo",function(err, value){ + should.not.exist(value); + context.set("nodeX","foo","testX",function(err){ + context.set("nodeY","foo","testY",function(err){ + context.get("nodeX","foo",function(err, value){ + value.should.be.equal("testX"); + context.get("nodeY","foo",function(err, value){ + value.should.be.equal("testY"); + context.delete("nodeX").then(function(){ + context.get("nodeX","foo",function(err, value){ + should.not.exist(value); + context.get("nodeY","foo",function(err, value){ + value.should.be.equal("testY"); + done(); + }); + }); + }).catch(done); + }); + }); + }); + }); + }); + }); + }); + }); + + describe('#clean',function() { + var context; + var contextGet; + var contextSet; + beforeEach(function() { + context = LocalFileSystem({dir: resourcesDir, cache: false}); + contextGet = function(scope,key) { + return new Promise((res,rej) => { + context.get(scope,key, function(err,value) { + if (err) { + rej(err); + } else { + res(value); + } + }) + }); + } + contextSet = function(scope,key,value) { + return new Promise((res,rej) => { + context.set(scope,key,value, function(err) { + if (err) { + rej(err); + } else { + res(); + } + }) + }); + } + return context.open(); + }); + + afterEach(function() { + return context.clean([]).then(function(){ + return context.close().then(function(){ + return fs.remove(resourcesDir); + }); + }); + }); + it('should clean unnecessary context',function(done) { + contextSet("global","foo","testGlobal").then(function() { + return contextSet("nodeX:flow1","foo","testX"); + }).then(function() { + return contextSet("nodeY:flow2","foo","testY"); + }).then(function() { + return contextGet("nodeX:flow1","foo"); + }).then(function(value) { + value.should.be.equal("testX"); + }).then(function() { + return contextGet("nodeY:flow2","foo"); + }).then(function(value) { + value.should.be.equal("testY"); + }).then(function() { + return context.clean([]) + }).then(function() { + return contextGet("nodeX:flow1","foo"); + }).then(function(value) { + should.not.exist(value); + }).then(function() { + return contextGet("nodeY:flow2","foo"); + }).then(function(value) { + should.not.exist(value); + }).then(function() { + return contextGet("global","foo"); + }).then(function(value) { + value.should.eql("testGlobal"); + }).then(done).catch(done); + }); + + it('should not clean active context',function(done) { + contextSet("global","foo","testGlobal").then(function() { + return contextSet("nodeX:flow1","foo","testX"); + }).then(function() { + return contextSet("nodeY:flow2","foo","testY"); + }).then(function() { + return contextGet("nodeX:flow1","foo"); + }).then(function(value) { + value.should.be.equal("testX"); + }).then(function() { + return contextGet("nodeY:flow2","foo"); + }).then(function(value) { + value.should.be.equal("testY"); + }).then(function() { + return context.clean(["flow1","nodeX"]) + }).then(function() { + return contextGet("nodeX:flow1","foo"); + }).then(function(value) { + value.should.be.equal("testX"); + }).then(function() { + return contextGet("nodeY:flow2","foo"); + }).then(function(value) { + should.not.exist(value); + }).then(function() { + return contextGet("global","foo"); + }).then(function(value) { + value.should.eql("testGlobal"); + }).then(done).catch(done); + }); + }); + + describe('#if cache is enabled',function() { + + var context; + beforeEach(function() { + context = LocalFileSystem({dir: resourcesDir, cache: false}); + return context.open(); + }); + + afterEach(function() { + return context.clean([]).then(function(){ + return context.close(); + }).then(function(){ + return fs.remove(resourcesDir); + }); + }); + + + + it('should load contexts into the cache',function() { + var globalData = {key:"global"}; + var flowData = {key:"flow"}; + var nodeData = {key:"node"}; + return Promise.all([ + fs.outputFile(path.join(resourcesDir,defaultContextBase,"global","global.json"), JSON.stringify(globalData,null,4), "utf8"), + fs.outputFile(path.join(resourcesDir,defaultContextBase,"flow","flow.json"), JSON.stringify(flowData,null,4), "utf8"), + fs.outputFile(path.join(resourcesDir,defaultContextBase,"flow","node.json"), JSON.stringify(nodeData,null,4), "utf8") + ]).then(function(){ + context = LocalFileSystem({dir: resourcesDir, cache: true}); + return context.open(); + }).then(function(){ + return Promise.all([ + fs.remove(path.join(resourcesDir,defaultContextBase,"global","global.json")), + fs.remove(path.join(resourcesDir,defaultContextBase,"flow","flow.json")), + fs.remove(path.join(resourcesDir,defaultContextBase,"flow","node.json")) + ]); + }).then(function(){ + context.get("global","key").should.be.equal("global"); + context.get("flow","key").should.be.equal("flow"); + context.get("node:flow","key").should.be.equal("node"); + }); + }); + + it('should store property to the cache',function() { + context = LocalFileSystem({dir: resourcesDir, cache: true, flushInterval: 1}); + return context.open().then(function(){ + return new Promise(function(resolve, reject){ + context.set("global","foo","bar",function(err){ + if(err){ + reject(err); + } else { + fs.readJson(path.join(resourcesDir,defaultContextBase,"global","global.json")).then(function(data) { + // File should not exist as flush hasn't happened + reject("File global/global.json should not exist"); + }).catch(function(err) { + setTimeout(function() { + fs.readJson(path.join(resourcesDir,defaultContextBase,"global","global.json")).then(function(data) { + data.should.eql({foo:'bar'}); + resolve(); + }).catch(function(err) { + reject(err); + }); + },1100) + }) + } + }); + }); + }).then(function(){ + return fs.remove(path.join(resourcesDir,defaultContextBase,"global","global.json")); + }).then(function(){ + context.get("global","foo").should.be.equal("bar"); + }) + }); + + it('should enumerate context keys in the cache',function() { + var globalData = {foo:"bar"}; + return fs.outputFile(path.join(resourcesDir,defaultContextBase,"global","global.json"), JSON.stringify(globalData,null,4), "utf8").then(function(){ + context = LocalFileSystem({dir: resourcesDir, cache: true, flushInterval: 2}); + return context.open() + }).then(function(){ + return fs.remove(path.join(resourcesDir,defaultContextBase,"global","global.json")); + }).then(function(){ + var keys = context.keys("global"); + keys.should.have.length(1); + keys[0].should.equal("foo"); + return new Promise(function(resolve, reject){ + context.set("global","foo2","bar2",function(err){ + if(err){ + reject(err); + } else { + resolve(); + } + }); + }); + }).then(function(){ + return fs.remove(path.join(resourcesDir,defaultContextBase,"global","global.json")); + }).then(function(){ + var keys = context.keys("global"); + keys.should.have.length(2); + keys[1].should.equal("foo2"); + }) + }); + + it('should delete context in the cache',function() { + context = LocalFileSystem({dir: resourcesDir, cache: true, flushInterval: 2}); + return context.open().then(function(){ + return new Promise(function(resolve, reject){ + context.set("global","foo","bar",function(err){ + if(err){ + reject(err); + } else { + resolve(); + } + }); + }); + }).then(function(){ + context.get("global","foo").should.be.equal("bar"); + return context.delete("global"); + }).then(function(){ + should.not.exist(context.get("global","foo")) + }) + }); + + it('should clean unnecessary context in the cache',function() { + var flowAData = {key:"flowA"}; + var flowBData = {key:"flowB"}; + return Promise.all([ + fs.outputFile(path.join(resourcesDir,defaultContextBase,"flowA","flow.json"), JSON.stringify(flowAData,null,4), "utf8"), + fs.outputFile(path.join(resourcesDir,defaultContextBase,"flowB","flow.json"), JSON.stringify(flowBData,null,4), "utf8") + ]).then(function(){ + context = LocalFileSystem({dir: resourcesDir, cache: true, flushInterval: 2}); + return context.open(); + }).then(function(){ + context.get("flowA","key").should.be.equal("flowA"); + context.get("flowB","key").should.be.equal("flowB"); + return context.clean(["flowA"]); + }).then(function(){ + context.get("flowA","key").should.be.equal("flowA"); + should.not.exist(context.get("flowB","key")); + }); + }); + }); + + describe('Configuration', function () { + var context; + beforeEach(function() { + context = LocalFileSystem({dir: resourcesDir, cache: false}); + return context.open(); + }); + + afterEach(function() { + return context.clean([]).then(function(){ + return context.close(); + }).then(function(){ + return fs.remove(resourcesDir); + }); + }); + it('should change a base directory', function (done) { + var differentBaseContext = LocalFileSystem({ + base: "contexts2", + dir: resourcesDir, + cache: false + }); + differentBaseContext.open().then(function () { + differentBaseContext.set("node2", "foo2", "bar2", function (err) { + differentBaseContext.get("node2", "foo2", function (err, value) { + value.should.be.equal("bar2"); + context.get("node2", "foo2", function(err, value) { + should.not.exist(value); + done(); + }); + }); + }); + }); + }); + + it('should use userDir', function (done) { + var userDirContext = LocalFileSystem({ + base: "contexts2", + cache: false, + settings: { + userDir: resourcesDir + } + }); + userDirContext.open().then(function () { + userDirContext.set("node2", "foo2", "bar2", function (err) { + userDirContext.get("node2", "foo2", function (err, value) { + value.should.be.equal("bar2"); + context.get("node2", "foo2", function (err, value) { + should.not.exist(value); + done(); + }); + }); + }); + }); + }); + + it('should use NODE_RED_HOME', function (done) { + var oldNRH = process.env.NODE_RED_HOME; + process.env.NODE_RED_HOME = resourcesDir; + fs.ensureDirSync(resourcesDir); + fs.writeFileSync(path.join(resourcesDir,".config.json"),""); + var nrHomeContext = LocalFileSystem({ + base: "contexts2", + cache: false + }); + try { + nrHomeContext.open().then(function () { + nrHomeContext.set("node2", "foo2", "bar2", function (err) { + nrHomeContext.get("node2", "foo2", function (err, value) { + value.should.be.equal("bar2"); + context.get("node2", "foo2", function (err, value) { + should.not.exist(value); + done(); + }); + }); + }); + }); + } finally { + process.env.NODE_RED_HOME = oldNRH; + } + }); + + it('should use HOME_PATH', function (done) { + var oldNRH = process.env.NODE_RED_HOME; + var oldHOMEPATH = process.env.HOMEPATH; + process.env.NODE_RED_HOME = resourcesDir; + process.env.HOMEPATH = resourcesDir; + var homePath = path.join(resourcesDir, ".node-red"); + fs.outputFile(path.join(homePath, ".config.json"),"",function(){ + var homeContext = LocalFileSystem({ + base: "contexts2", + cache: false + }); + try { + homeContext.open().then(function () { + homeContext.set("node2", "foo2", "bar2", function (err) { + homeContext.get("node2", "foo2", function (err, value) { + value.should.be.equal("bar2"); + context.get("node2", "foo2", function (err, value) { + should.not.exist(value); + done(); + }); + }); + }); + }); + } finally { + process.env.NODE_RED_HOME = oldNRH; + process.env.HOMEPATH = oldHOMEPATH; + } + }); + }); + + it('should use HOME_PATH', function (done) { + var oldNRH = process.env.NODE_RED_HOME; + var oldHOMEPATH = process.env.HOMEPATH; + var oldHOME = process.env.HOME; + process.env.NODE_RED_HOME = resourcesDir; + process.env.HOMEPATH = resourcesDir; + process.env.HOME = resourcesDir; + var homeContext = LocalFileSystem({ + base: "contexts2", + cache: false + }); + try { + homeContext.open().then(function () { + homeContext.set("node2", "foo2", "bar2", function (err) { + homeContext.get("node2", "foo2", function (err, value) { + value.should.be.equal("bar2"); + context.get("node2", "foo2", function (err, value) { + should.not.exist(value); + done(); + }); + }); + }); + }); + } finally { + process.env.NODE_RED_HOME = oldNRH; + process.env.HOMEPATH = oldHOMEPATH; + process.env.HOME = oldHOME; + } + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/nodes/context/memory_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/nodes/context/memory_spec.js new file mode 100644 index 0000000..663ee46 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/nodes/context/memory_spec.js @@ -0,0 +1,321 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require('should'); +var NR_TEST_UTILS = require("nr-test-utils"); + +var Memory = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/context/memory"); + +describe('memory',function() { + var context; + + beforeEach(function() { + context = Memory({}); + return context.open(); + }); + + afterEach(function() { + return context.clean([]).then(function(){ + return context.close(); + }); + }); + + describe('#get/set',function() { + describe('sync',function() { + it('should store property',function() { + should.not.exist(context.get("nodeX","foo")); + context.set("nodeX","foo","test"); + context.get("nodeX","foo").should.equal("test"); + }); + + it('should store property - creates parent properties',function() { + context.set("nodeX","foo.bar","test"); + context.get("nodeX","foo").should.eql({bar:"test"}); + }); + + it('should delete property',function() { + context.set("nodeX","foo.abc.bar1","test1"); + context.set("nodeX","foo.abc.bar2","test2"); + context.get("nodeX","foo.abc").should.eql({bar1:"test1",bar2:"test2"}); + context.set("nodeX","foo.abc.bar1",undefined); + context.get("nodeX","foo.abc").should.eql({bar2:"test2"}); + context.set("nodeX","foo.abc",undefined); + should.not.exist(context.get("nodeX","foo.abc")); + context.set("nodeX","foo",undefined); + should.not.exist(context.get("nodeX","foo")); + }); + + it('should not shared context with other scope', function() { + should.not.exist(context.get("nodeX","foo")); + should.not.exist(context.get("nodeY","foo")); + context.set("nodeX","foo","testX"); + context.set("nodeY","foo","testY"); + + context.get("nodeX","foo").should.equal("testX"); + context.get("nodeY","foo").should.equal("testY"); + }); + + it('should throw the error if the error occurs', function() { + try{ + context.set("nodeX",".foo","test"); + should.fail("Error was not thrown"); + }catch(err){ + should.exist(err); + try{ + context.get("nodeX",".foo"); + should.fail("Error was not thrown"); + }catch(err){ + should.exist(err); + } + } + }); + + it('should get multiple values - all known', function() { + context.set("nodeX","one","test1"); + context.set("nodeX","two","test2"); + context.set("nodeX","three","test3"); + context.set("nodeX","four","test4"); + + var values = context.get("nodeX",["one","two","four"]); + values.should.eql(["test1","test2","test4"]) + }) + it('should get multiple values - include unknown', function() { + context.set("nodeX","one","test1"); + context.set("nodeX","two","test2"); + context.set("nodeX","three","test3"); + context.set("nodeX","four","test4"); + + var values = context.get("nodeX",["one","unknown.with.multiple.levels"]); + values.should.eql(["test1",undefined]) + }) + it('should throw error if bad key included in multiple keys', function() { + context.set("nodeX","one","test1"); + context.set("nodeX","two","test2"); + context.set("nodeX","three","test3"); + context.set("nodeX","four","test4"); + + try{ + var values = context.get("nodeX",["one",".foo","three"]); + should.fail("Error was not thrown"); + }catch(err){ + should.exist(err); + } + }) + + + }); + + describe('async',function() { + it('should store property',function(done) { + context.get("nodeX","foo",function(err, value){ + should.not.exist(value); + context.set("nodeX","foo","test",function(err){ + context.get("nodeX","foo",function(err, value){ + value.should.equal("test"); + done(); + }); + }); + }); + }); + + it('should pass the error to callback if the error occurs',function(done) { + context.set("nodeX",".foo","test",function(err, value){ + should.exist(err); + context.get("nodeX",".foo",function(err){ + should.exist(err); + done(); + }); + }); + }); + + it('should get multiple values - all known', function(done) { + context.set("nodeX","one","test1"); + context.set("nodeX","two","test2"); + context.set("nodeX","three","test3"); + context.set("nodeX","four","test4"); + + context.get("nodeX",["one","two","four"],function() { + Array.prototype.slice.apply(arguments).should.eql([undefined,"test1","test2","test4"]) + done(); + }); + }) + it('should get multiple values - include unknown', function(done) { + context.set("nodeX","one","test1"); + context.set("nodeX","two","test2"); + context.set("nodeX","three","test3"); + context.set("nodeX","four","test4"); + + context.get("nodeX",["one","unknown"],function() { + Array.prototype.slice.apply(arguments).should.eql([undefined,"test1",undefined]) + done(); + }); + }) + it('should throw error if bad key included in multiple keys', function(done) { + context.set("nodeX","one","test1"); + context.set("nodeX","two","test2"); + context.set("nodeX","three","test3"); + context.set("nodeX","four","test4"); + + context.get("nodeX",["one",".foo","three"], function(err) { + should.exist(err); + done(); + }); + }) + }); + }); + + describe('#keys',function() { + describe('sync',function() { + it('should enumerate context keys', function() { + var keys = context.keys("nodeX"); + keys.should.be.an.Array(); + keys.should.be.empty(); + + context.set("nodeX","foo","bar"); + keys = context.keys("nodeX"); + keys.should.have.length(1); + keys[0].should.equal("foo"); + + context.set("nodeX","abc.def","bar"); + keys = context.keys("nodeX"); + keys.should.have.length(2); + keys[1].should.equal("abc"); + }); + + it('should enumerate context keys in each scopes', function() { + var keysX = context.keys("nodeX"); + keysX.should.be.an.Array(); + keysX.should.be.empty(); + + var keysY = context.keys("nodeY"); + keysY.should.be.an.Array(); + keysY.should.be.empty(); + + context.set("nodeX","foo","bar"); + context.set("nodeY","hoge","piyo"); + keysX = context.keys("nodeX"); + keysX.should.have.length(1); + keysX[0].should.equal("foo"); + + keysY = context.keys("nodeY"); + keysY.should.have.length(1); + keysY[0].should.equal("hoge"); + }); + + it('should enumerate global context keys', function () { + var keys = context.keys("global"); + keys.should.be.an.Array(); + keys.should.be.empty(); + + context.set("global", "foo", "bar"); + keys = context.keys("global"); + keys.should.have.length(1); + keys[0].should.equal("foo"); + + context.set("global", "abc.def", "bar"); + keys = context.keys("global"); + keys.should.have.length(2); + keys[1].should.equal("abc"); + }); + + it('should not return specific keys as global context keys', function () { + var keys = context.keys("global"); + + context.set("global", "set", "bar"); + context.set("global", "get", "bar"); + context.set("global", "keys", "bar"); + keys = context.keys("global"); + keys.should.have.length(0); + }); + }); + + describe('async',function() { + it('should enumerate context keys', function(done) { + context.keys("nodeX", function(err, keys) { + keys.should.be.an.Array(); + keys.should.be.empty(); + context.set("nodeX", "foo", "bar", function(err) { + context.keys("nodeX", function(err, keys) { + keys.should.have.length(1); + keys[0].should.equal("foo"); + context.set("nodeX","abc.def","bar",function(err){ + context.keys("nodeX",function(err, keys){ + keys.should.have.length(2); + keys[1].should.equal("abc"); + done(); + }); + }); + }); + }); + }); + }); + }); + }); + + describe('#delete',function() { + it('should delete context',function() { + should.not.exist(context.get("nodeX","foo")); + should.not.exist(context.get("nodeY","foo")); + context.set("nodeX","foo","abc"); + context.set("nodeY","foo","abc"); + context.get("nodeX","foo").should.equal("abc"); + context.get("nodeY","foo").should.equal("abc"); + + return context.delete("nodeX").then(function(){ + should.not.exist(context.get("nodeX","foo")); + should.exist(context.get("nodeY","foo")); + }); + }); + }); + + describe('#clean',function() { + it('should clean unnecessary context',function() { + should.not.exist(context.get("nodeX","foo")); + should.not.exist(context.get("nodeY","foo")); + context.set("nodeX","foo","abc"); + context.set("nodeY","foo","abc"); + context.get("nodeX","foo").should.equal("abc"); + context.get("nodeY","foo").should.equal("abc"); + + return context.clean([]).then(function(){ + should.not.exist(context.get("nodeX","foo")); + should.not.exist(context.get("nodeY","foo")); + }); + }); + it('should not clean active context',function() { + should.not.exist(context.get("nodeX","foo")); + should.not.exist(context.get("nodeY","foo")); + context.set("nodeX","foo","abc"); + context.set("nodeY","foo","abc"); + context.get("nodeX","foo").should.equal("abc"); + context.get("nodeY","foo").should.equal("abc"); + + return context.clean(["nodeX"]).then(function(){ + should.exist(context.get("nodeX","foo")); + should.not.exist(context.get("nodeY","foo")); + }); + }); + it('should not clean global context', function () { + context.set("global", "foo", "abc"); + context.get("global", "foo").should.equal("abc"); + + return context.clean(["global"]).then(function () { + should.exist(context.get("global", "foo")); + }); + }); + }); + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/nodes/credentials_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/nodes/credentials_spec.js new file mode 100644 index 0000000..63050a8 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/nodes/credentials_spec.js @@ -0,0 +1,478 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); +var when = require("when"); +var util = require("util"); + +var NR_TEST_UTILS = require("nr-test-utils"); +var index = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/index"); +var credentials = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/credentials"); +var log = NR_TEST_UTILS.require("@node-red/util").log; + + +describe('red/runtime/nodes/credentials', function() { + + var encryptionDisabledSettings = { + get: function(key) { + return false; + } + } + + afterEach(function() { + index.clearRegistry(); + }); + + it('loads provided credentials',function(done) { + credentials.init({ + log: log, + settings: encryptionDisabledSettings + }); + + credentials.load({"a":{"b":1,"c":2}}).then(function() { + + credentials.get("a").should.have.property('b',1); + credentials.get("a").should.have.property('c',2); + + done(); + }); + }); + it('adds a new credential',function(done) { + credentials.init({ + log: log, + settings: encryptionDisabledSettings + }); + credentials.load({"a":{"b":1,"c":2}}).then(function() { + credentials.dirty().should.be.false(); + should.not.exist(credentials.get("b")); + credentials.add("b",{"foo":"bar"}).then(function() { + credentials.get("b").should.have.property("foo","bar"); + credentials.dirty().should.be.true(); + done(); + }); + }); + }); + it('deletes an existing credential',function(done) { + credentials.init({ + log: log, + settings: encryptionDisabledSettings + }); + credentials.load({"a":{"b":1,"c":2}}).then(function() { + credentials.dirty().should.be.false(); + credentials.delete("a"); + should.not.exist(credentials.get("a")); + credentials.dirty().should.be.true(); + done(); + }); + }); + + it('exports the credentials, clearing dirty flag', function(done) { + credentials.init({ + log: log, + settings: encryptionDisabledSettings + }); + var creds = {"a":{"b":1,"c":2}}; + credentials.load(creds).then(function() { + credentials.add("b",{"foo":"bar"}).then(function() { + credentials.dirty().should.be.true(); + credentials.export().then(function(exported) { + exported.should.eql(creds); + credentials.dirty().should.be.false(); + done(); + }) + }); + }); + }) + + describe("#clean",function() { + it("removes credentials of unknown nodes",function(done) { + credentials.init({ + log: log, + settings: encryptionDisabledSettings + }); + var creds = {"a":{"b":1,"c":2},"b":{"d":3}}; + credentials.load(creds).then(function() { + credentials.dirty().should.be.false(); + should.exist(credentials.get("a")); + should.exist(credentials.get("b")); + credentials.clean([{id:"b"}]).then(function() { + credentials.dirty().should.be.true(); + should.not.exist(credentials.get("a")); + should.exist(credentials.get("b")); + done(); + }); + }); + }); + it("extracts credentials of known nodes",function(done) { + credentials.init({ + log: log, + settings: encryptionDisabledSettings + }); + credentials.register("testNode",{"b":"text","c":"password"}) + var creds = {"a":{"b":1,"c":2}}; + var newConfig = [{id:"a",type:"testNode",credentials:{"b":"newBValue","c":"newCValue"}}]; + credentials.load(creds).then(function() { + credentials.dirty().should.be.false(); + credentials.clean(newConfig).then(function() { + credentials.dirty().should.be.true(); + credentials.get("a").should.have.property('b',"newBValue"); + credentials.get("a").should.have.property('c',"newCValue"); + should.not.exist(newConfig[0].credentials); + done(); + }); + }); + }); + + + }); + + it('warns if a node has no credential definition', function(done) { + credentials.init({ + log: log, + settings: encryptionDisabledSettings + }); + credentials.load({}).then(function() { + var node = {id:"node",type:"test",credentials:{ + user1:"newUser", + password1:"newPassword" + }}; + sinon.spy(log,"warn"); + credentials.extract(node); + log.warn.called.should.be.true(); + should.not.exist(node.credentials); + log.warn.restore(); + done(); + }); + }) + + it('extract credential updates in the provided node', function(done) { + credentials.init({ + log: log, + settings: encryptionDisabledSettings + }); + var defintion = { + user1:{type:"text"}, + password1:{type:"password"}, + user2:{type:"text"}, + password2:{type:"password"}, + user3:{type:"text"}, + password3:{type:"password"} + + }; + credentials.register("test",defintion); + var def = credentials.getDefinition("test"); + defintion.should.eql(def); + + credentials.load({"node":{user1:"abc",password1:"123",user2:"def",password2:"456",user3:"ghi",password3:"789"}}).then(function() { + var node = {id:"node",type:"test",credentials:{ + // user1 unchanged + password1:"__PWRD__", + user2: "", + password2:" ", + user3:"newUser", + password3:"newPassword" + }}; + credentials.dirty().should.be.false(); + credentials.extract(node); + + node.should.not.have.a.property("credentials"); + + credentials.dirty().should.be.true(); + var newCreds = credentials.get("node"); + newCreds.should.have.a.property("user1","abc"); + newCreds.should.have.a.property("password1","123"); + newCreds.should.not.have.a.property("user2"); + newCreds.should.not.have.a.property("password2"); + newCreds.should.have.a.property("user3","newUser"); + newCreds.should.have.a.property("password3","newPassword"); + + done(); + }); + }); + it('extract ignores node without credentials', function(done) { + credentials.init({ + log: log, + settings: encryptionDisabledSettings + }); + credentials.load({"node":{user1:"abc",password1:"123"}}).then(function() { + var node = {id:"node",type:"test"}; + + credentials.dirty().should.be.false(); + credentials.extract(node); + credentials.dirty().should.be.false(); + done(); + }); + }); + + describe("encryption",function() { + var settings = {}; + var runtime = { + log: log, + settings: { + get: function(key) { + return settings[key]; + }, + set: function(key,value) { + settings[key] = value; + return when.resolve(); + }, + delete: function(key) { + delete settings[key]; + return when.resolve(); + } + } + } + it('migrates to encrypted and generates default key', function(done) { + settings = {}; + credentials.init(runtime); + credentials.load({"node":{user1:"abc",password1:"123"}}).then(function() { + settings.should.have.a.property("_credentialSecret"); + settings._credentialSecret.should.have.a.length(64); + credentials.dirty().should.be.true(); + credentials.export().then(function(result) { + result.should.have.a.property("$"); + // reset everything - but with _credentialSecret still set + credentials.init(runtime); + // load the freshly encrypted version + credentials.load(result).then(function() { + should.exist(credentials.get("node")); + done(); + }) + }); + }); + }); + it('uses default key', function(done) { + settings = { + _credentialSecret: "e3a36f47f005bf2aaa51ce3fc6fcaafd79da8d03f2b1a9281f8fb0a285e6255a" + }; + // {"node":{user1:"abc",password1:"123"}} + var cryptedFlows = {"$":"5b89d8209b5158a3c313675561b1a5b5phN1gDBe81Zv98KqS/hVDmc9EKvaKqRIvcyXYvBlFNzzzJtvN7qfw06i"}; + credentials.init(runtime); + credentials.load(cryptedFlows).then(function() { + should.exist(credentials.get("node")); + credentials.dirty().should.be.false(); + credentials.add("node",{user1:"def",password1:"456"}); + credentials.export().then(function(result) { + result.should.have.a.property("$"); + // reset everything - but with _credentialSecret still set + credentials.init(runtime); + // load the freshly encrypted version + credentials.load(result).then(function() { + should.exist(credentials.get("node")); + credentials.get("node").should.have.a.property("user1","def"); + credentials.get("node").should.have.a.property("password1","456"); + done(); + }) + }); + }); + }); + it('uses user key', function(done) { + settings = { + credentialSecret: "e3a36f47f005bf2aaa51ce3fc6fcaafd79da8d03f2b1a9281f8fb0a285e6255a" + }; + // {"node":{user1:"abc",password1:"123"}} + var cryptedFlows = {"$":"5b89d8209b5158a3c313675561b1a5b5phN1gDBe81Zv98KqS/hVDmc9EKvaKqRIvcyXYvBlFNzzzJtvN7qfw06i"}; + credentials.init(runtime); + credentials.load(cryptedFlows).then(function() { + credentials.dirty().should.be.false(); + should.exist(credentials.get("node")); + credentials.add("node",{user1:"def",password1:"456"}); + credentials.export().then(function(result) { + result.should.have.a.property("$"); + + // reset everything - but with _credentialSecret still set + credentials.init(runtime); + // load the freshly encrypted version + credentials.load(result).then(function() { + should.exist(credentials.get("node")); + credentials.get("node").should.have.a.property("user1","def"); + credentials.get("node").should.have.a.property("password1","456"); + done(); + }) + }); + }); + }); + it('uses user key - when settings are otherwise unavailable', function(done) { + var runtime = { + log: log, + settings: { + get: function(key) { + if (key === 'credentialSecret') { + return "e3a36f47f005bf2aaa51ce3fc6fcaafd79da8d03f2b1a9281f8fb0a285e6255a"; + } + throw new Error(); + }, + set: function(key,value) { + throw new Error(); + } + } + } + // {"node":{user1:"abc",password1:"123"}} + var cryptedFlows = {"$":"5b89d8209b5158a3c313675561b1a5b5phN1gDBe81Zv98KqS/hVDmc9EKvaKqRIvcyXYvBlFNzzzJtvN7qfw06i"}; + credentials.init(runtime); + credentials.load(cryptedFlows).then(function() { + should.exist(credentials.get("node")); + credentials.add("node",{user1:"def",password1:"456"}); + credentials.export().then(function(result) { + result.should.have.a.property("$"); + + // reset everything - but with _credentialSecret still set + credentials.init(runtime); + // load the freshly encrypted version + credentials.load(result).then(function() { + should.exist(credentials.get("node")); + credentials.get("node").should.have.a.property("user1","def"); + credentials.get("node").should.have.a.property("password1","456"); + done(); + }) + }); + }); + }); + it('migrates from default key to user key', function(done) { + settings = { + _credentialSecret: "e3a36f47f005bf2aaa51ce3fc6fcaafd79da8d03f2b1a9281f8fb0a285e6255a", + credentialSecret: "aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbcccccccccccccddddddddddddeeeee" + }; + // {"node":{user1:"abc",password1:"123"}} + var cryptedFlows = {"$":"5b89d8209b5158a3c313675561b1a5b5phN1gDBe81Zv98KqS/hVDmc9EKvaKqRIvcyXYvBlFNzzzJtvN7qfw06i"}; + credentials.init(runtime); + credentials.load(cryptedFlows).then(function() { + credentials.dirty().should.be.true(); + should.exist(credentials.get("node")); + credentials.export().then(function(result) { + result.should.have.a.property("$"); + settings.should.not.have.a.property("_credentialSecret"); + + // reset everything - but with _credentialSecret still set + credentials.init(runtime); + // load the freshly encrypted version + credentials.load(result).then(function() { + should.exist(credentials.get("node")); + credentials.get("node").should.have.a.property("user1","abc"); + credentials.get("node").should.have.a.property("password1","123"); + done(); + }) + }); + }); + }); + + it('migrates from default key to user key - unencrypted original', function(done) { + settings = { + _credentialSecret: "e3a36f47f005bf2aaa51ce3fc6fcaafd79da8d03f2b1a9281f8fb0a285e6255a", + credentialSecret: "aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbcccccccccccccddddddddddddeeeee" + }; + // {"node":{user1:"abc",password1:"123"}} + var unencryptedFlows = {"node":{user1:"abc",password1:"123"}}; + credentials.init(runtime); + credentials.load(unencryptedFlows).then(function() { + credentials.dirty().should.be.true(); + should.exist(credentials.get("node")); + credentials.export().then(function(result) { + result.should.have.a.property("$"); + settings.should.not.have.a.property("_credentialSecret"); + + // reset everything - but with _credentialSecret still set + credentials.init(runtime); + // load the freshly encrypted version + credentials.load(result).then(function() { + should.exist(credentials.get("node")); + credentials.get("node").should.have.a.property("user1","abc"); + credentials.get("node").should.have.a.property("password1","123"); + done(); + }) + }); + }); + }); + + it('migrates from default key to unencrypted', function(done) { + settings = { + _credentialSecret: "e3a36f47f005bf2aaa51ce3fc6fcaafd79da8d03f2b1a9281f8fb0a285e6255a", + credentialSecret: false + }; + // {"node":{user1:"abc",password1:"123"}} + var cryptedFlows = {"$":"5b89d8209b5158a3c313675561b1a5b5phN1gDBe81Zv98KqS/hVDmc9EKvaKqRIvcyXYvBlFNzzzJtvN7qfw06i"}; + credentials.init(runtime); + credentials.load(cryptedFlows).then(function() { + credentials.dirty().should.be.true(); + should.exist(credentials.get("node")); + credentials.export().then(function(result) { + result.should.not.have.a.property("$"); + settings.should.not.have.a.property("_credentialSecret"); + result.should.eql({"node":{user1:"abc",password1:"123"}}); + done(); + }); + }); + }); + it('handles bad default key - resets credentials', function(done) { + settings = { + _credentialSecret: "badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadb" + }; + // {"node":{user1:"abc",password1:"123"}} + var cryptedFlows = {"$":"5b89d8209b5158a3c313675561b1a5b5phN1gDBe81Zv98KqS/hVDmc9EKvaKqRIvcyXYvBlFNzzzJtvN7qfw06i"}; + credentials.init(runtime); + credentials.load(cryptedFlows).then(function() { + // credentials.dirty().should.be.true(); + // should.not.exist(credentials.get("node")); + done(); + }).catch(function(err) { + err.should.have.property('code','credentials_load_failed'); + done(); + }); + }); + it('handles bad user key - resets credentials', function(done) { + settings = { + credentialSecret: "badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadb" + }; + // {"node":{user1:"abc",password1:"123"}} + var cryptedFlows = {"$":"5b89d8209b5158a3c313675561b1a5b5phN1gDBe81Zv98KqS/hVDmc9EKvaKqRIvcyXYvBlFNzzzJtvN7qfw06i"}; + credentials.init(runtime); + credentials.load(cryptedFlows).then(function() { + // credentials.dirty().should.be.true(); + // should.not.exist(credentials.get("node")); + done(); + }).catch(function(err) { + err.should.have.property('code','credentials_load_failed'); + done(); + }); + }); + + it('handles unavailable settings - leaves creds unencrypted', function(done) { + var runtime = { + log: log, + settings: { + get: function(key) { + throw new Error(); + }, + set: function(key,value) { + throw new Error(); + } + } + } + // {"node":{user1:"abc",password1:"123"}} + credentials.init(runtime); + credentials.load({"node":{user1:"abc",password1:"123"}}).then(function() { + credentials.dirty().should.be.false(); + should.exist(credentials.get("node")); + credentials.export().then(function(result) { + result.should.not.have.a.property("$"); + result.should.have.a.property("node"); + done(); + }); + }); + }); + }) +}) diff --git a/packages/connector/test/unit/@node-red/runtime/lib/nodes/flows/Flow_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/nodes/flows/Flow_spec.js new file mode 100644 index 0000000..e1315dc --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/nodes/flows/Flow_spec.js @@ -0,0 +1,829 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +var should = require("should"); +var sinon = require('sinon'); +var clone = require('clone'); +var util = require("util"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var flowUtils = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/flows/util"); +var Flow = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/flows/Flow"); +var flows = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/flows"); +var Node = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/Node"); +var typeRegistry = NR_TEST_UTILS.require("@node-red/registry"); + + +describe('Flow', function() { + var getType; + + var stoppedNodes = {}; + var currentNodes = {}; + var rewiredNodes = {}; + var createCount = 0; + + beforeEach(function() { + currentNodes = {}; + stoppedNodes = {}; + rewiredNodes = {}; + createCount = 0; + Flow.init({settings:{},log:{ + log: sinon.stub(), // function() { console.log("l",[...arguments].map(a => JSON.stringify(a)).join(" ")) },// + debug: sinon.stub(), // function() { console.log("d",[...arguments].map(a => JSON.stringify(a)).join(" ")) },//sinon.stub(), + trace: sinon.stub(), // function() { console.log("t",[...arguments].map(a => JSON.stringify(a)).join(" ")) },//sinon.stub(), + warn: sinon.stub(), // function() { console.log("w",[...arguments].map(a => JSON.stringify(a)).join(" ")) },//sinon.stub(), + info: sinon.stub(), // function() { console.log("i",[...arguments].map(a => JSON.stringify(a)).join(" ")) },//sinon.stub(), + metric: sinon.stub(), + _: function() { return "abc"} + }}); + }); + + var TestNode = function(n) { + Node.call(this,n); + this._index = createCount++; + this.scope = n.scope; + var node = this; + this.foo = n.foo; + this.handled = 0; + this.stopped = false; + currentNodes[node.id] = node; + this.on('input',function(msg) { + // console.log(this.id,msg.payload); + node.handled++; + node.send(msg); + }); + this.on('close',function() { + node.stopped = true; + stoppedNodes[node.id] = node; + delete currentNodes[node.id]; + }); + this.__updateWires = this.updateWires; + this.updateWires = function(newWires) { + rewiredNodes[node.id] = node; + node.newWires = newWires; + node.__updateWires(newWires); + }; + } + util.inherits(TestNode,Node); + + var TestErrorNode = function(n) { + Node.call(this,n); + this._index = createCount++; + this.scope = n.scope; + this.name = n.name; + var node = this; + this.foo = n.foo; + this.handled = 0; + this.stopped = false; + currentNodes[node.id] = node; + this.on('input',function(msg) { + node.handled++; + node.error("test error",msg); + }); + this.on('close',function() { + node.stopped = true; + stoppedNodes[node.id] = node; + delete currentNodes[node.id]; + }); + this.__updateWires = this.updateWires; + this.updateWires = function(newWires) { + rewiredNodes[node.id] = node; + node.newWires = newWires; + node.__updateWires(newWires); + }; + } + util.inherits(TestErrorNode,Node); + + var TestAsyncNode = function(n) { + Node.call(this,n); + var node = this; + this.scope = n.scope; + this.uncaught = n.uncaught; + this.foo = n.foo; + this.handled = 0; + this.messages = []; + this.stopped = false; + this.closeDelay = n.closeDelay || 50; + currentNodes[node.id] = node; + this.on('input',function(msg) { + node.handled++; + msg.handled = node.handled; + node.messages.push(msg); + node.send(msg); + }); + this.on('close',function(done) { + setTimeout(function() { + node.stopped = true; + stoppedNodes[node.id] = node; + delete currentNodes[node.id]; + done(); + },node.closeDelay); + }); + } + util.inherits(TestAsyncNode,Node); + + var TestDoneNode = function(n) { + Node.call(this,n); + var node = this; + this.scope = n.scope; + this.uncaught = n.uncaught; + this.foo = n.foo; + this.handled = 0; + this.messages = []; + this.stopped = false; + this.closeDelay = n.closeDelay || 50; + currentNodes[node.id] = node; + this.on('input',function(msg, send, done) { + node.handled++; + node.messages.push(msg); + send(msg); + done(); + }); + this.on('close',function(done) { + setTimeout(function() { + node.stopped = true; + stoppedNodes[node.id] = node; + delete currentNodes[node.id]; + done(); + },node.closeDelay); + }); + } + util.inherits(TestDoneNode,Node); + + before(function() { + getType = sinon.stub(typeRegistry,"get",function(type) { + if (type=="test") { + return TestNode; + } else if (type=="testError"){ + return TestErrorNode; + } else if (type=="testDone"){ + return TestDoneNode; + } else { + return TestAsyncNode; + } + }); + }); + after(function() { + getType.restore(); + }); + + describe('#constructor',function() { + it('called with an empty flow',function() { + var config = flowUtils.parseConfig([]); + var flow = Flow.create({},config); + + var nodeCount = 0; + Object.keys(flow.getActiveNodes()).length.should.equal(0); + }); + }); + + describe('#start',function() { + it("instantiates an initial configuration and stops it",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"4",z:"t1",type:"test",foo:"a"} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + flow.start(); + + Object.keys(flow.getActiveNodes()).should.have.length(4); + + flow.getNode('1').should.have.a.property('id','1'); + flow.getNode('2').should.have.a.property('id','2'); + flow.getNode('3').should.have.a.property('id','3'); + flow.getNode('4').should.have.a.property('id','4'); + + currentNodes.should.have.a.property("1"); + currentNodes.should.have.a.property("2"); + currentNodes.should.have.a.property("3"); + currentNodes.should.have.a.property("4"); + + currentNodes["1"].should.have.a.property("handled",0); + currentNodes["2"].should.have.a.property("handled",0); + currentNodes["3"].should.have.a.property("handled",0); + + currentNodes["3"].on("input", function() { + currentNodes["1"].should.have.a.property("handled",1); + currentNodes["2"].should.have.a.property("handled",1); + currentNodes["3"].should.have.a.property("handled",1); + + flow.stop().then(function() { + try { + currentNodes.should.not.have.a.property("1"); + currentNodes.should.not.have.a.property("2"); + currentNodes.should.not.have.a.property("3"); + currentNodes.should.not.have.a.property("4"); + stoppedNodes.should.have.a.property("1"); + stoppedNodes.should.have.a.property("2"); + stoppedNodes.should.have.a.property("3"); + stoppedNodes.should.have.a.property("4"); + done(); + } catch(err) { + done(err); + } + }); + }); + currentNodes["1"].receive({payload:"test"}); + }); + + it("instantiates config nodes in the right order",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"4",z:"t1",type:"test",foo:"5"}, // This node depends on #5 + {id:"5",z:"t1",type:"test"} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + flow.start(); + + Object.keys(flow.getActiveNodes()).should.have.length(5); + + + currentNodes.should.have.a.property("1"); + currentNodes.should.have.a.property("2"); + currentNodes.should.have.a.property("3"); + currentNodes.should.have.a.property("4"); + currentNodes.should.have.a.property("5"); + + currentNodes["1"].should.have.a.property("_index",2); + currentNodes["2"].should.have.a.property("_index",3); + currentNodes["3"].should.have.a.property("_index",4); + currentNodes["4"].should.have.a.property("_index",1); + currentNodes["5"].should.have.a.property("_index",0); + + flow.stop().then(function() { + currentNodes.should.not.have.a.property("1"); + currentNodes.should.not.have.a.property("2"); + currentNodes.should.not.have.a.property("3"); + currentNodes.should.not.have.a.property("4"); + currentNodes.should.not.have.a.property("5"); + stoppedNodes.should.have.a.property("1"); + stoppedNodes.should.have.a.property("2"); + stoppedNodes.should.have.a.property("3"); + stoppedNodes.should.have.a.property("4"); + stoppedNodes.should.have.a.property("5"); + done(); + }); + }); + + + it("detects dependency loops in config nodes",function() { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"node1",z:"t1",type:"test",foo:"node2"}, // This node depends on #5 + {id:"node2",z:"t1",type:"test",foo:"node1"} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + /*jshint immed: false */ + (function(){ + flow.start(); + }).should.throw("Circular config node dependency detected: node1"); + }); + + it("rewires nodes specified by diff",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]} + ]); + + var flow = Flow.create({},config,config.flows["t1"]); + createCount.should.equal(0); + flow.start(); + //TODO: use update to pass in new wiring and verify the change + createCount.should.equal(3); + flow.start({rewired:["2"]}); + createCount.should.equal(3); + rewiredNodes.should.have.a.property("2"); + done(); + }); + + it("instantiates a node with environment variable property values",function(done) { + after(function() { + delete process.env.NODE_RED_TEST_VALUE; + }) + process.env.NODE_RED_TEST_VALUE = "a-value"; + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"$(NODE_RED_TEST_VALUE)",wires:[]}, + {id:"2",x:10,y:10,z:"t1",type:"test",foo:{a:"$(NODE_RED_TEST_VALUE)"},wires:[]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:" $(NODE_RED_TEST_VALUE)",wires:[]}, + {id:"4",x:10,y:10,z:"t1",type:"test",foo:"$(NODE_RED_TEST_VALUE) ",wires:[]}, + {id:"5",x:10,y:10,z:"t1",type:"test",foo:"$(NODE_RED_TEST_VALUE_NONE)",wires:[]}, + {id:"6",x:10,y:10,z:"t1",type:"test",foo:["$(NODE_RED_TEST_VALUE)"],wires:[]} + ]); + var flow = Flow.create({getSetting:v=>process.env[v]},config,config.flows["t1"]); + flow.start(); + + var activeNodes = flow.getActiveNodes(); + + activeNodes["1"].foo.should.equal("a-value"); + activeNodes["2"].foo.a.should.equal("a-value"); + activeNodes["3"].foo.should.equal(" $(NODE_RED_TEST_VALUE)"); + activeNodes["4"].foo.should.equal("$(NODE_RED_TEST_VALUE) "); + activeNodes["5"].foo.should.equal("$(NODE_RED_TEST_VALUE_NONE)"); + activeNodes["6"].foo[0].should.equal("a-value"); + + flow.stop().then(function() { + done(); + }); + }); + + it("ignores disabled nodes",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",d:true,type:"test",foo:"a",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"4",z:"t1",type:"test",foo:"a"}, + {id:"5",z:"t1",type:"test",d:true,foo:"a"} + + ]); + var flow = Flow.create({},config,config.flows["t1"]); + flow.start(); + + Object.keys(flow.getActiveNodes()).should.have.length(3); + + flow.getNode('1').should.have.a.property('id','1'); + should.not.exist(flow.getNode('2')); + flow.getNode('3').should.have.a.property('id','3'); + flow.getNode('4').should.have.a.property('id','4'); + should.not.exist(flow.getNode('5')); + + currentNodes.should.have.a.property("1"); + currentNodes.should.not.have.a.property("2"); + currentNodes.should.have.a.property("3"); + currentNodes.should.have.a.property("4"); + + currentNodes["1"].should.have.a.property("handled",0); + currentNodes["3"].should.have.a.property("handled",0); + + currentNodes["1"].receive({payload:"test"}); + + setTimeout(function() { + currentNodes["1"].should.have.a.property("handled",1); + // Message doesn't reach 3 as 2 is disabled + currentNodes["3"].should.have.a.property("handled",0); + + flow.stop().then(function() { + try { + currentNodes.should.not.have.a.property("1"); + currentNodes.should.not.have.a.property("2"); + currentNodes.should.not.have.a.property("3"); + currentNodes.should.not.have.a.property("4"); + stoppedNodes.should.have.a.property("1"); + stoppedNodes.should.not.have.a.property("2"); + stoppedNodes.should.have.a.property("3"); + stoppedNodes.should.have.a.property("4"); + done(); + } catch(err) { + done(err); + } + }); + },50); + }); + + }); + + describe('#stop', function() { + + + it("stops all nodes",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"asyncTest",foo:"a",wires:[]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + flow.start(); + + + currentNodes.should.have.a.property("1"); + currentNodes.should.have.a.property("2"); + currentNodes.should.have.a.property("3"); + + flow.stop().then(function() { + currentNodes.should.not.have.a.property("1"); + currentNodes.should.not.have.a.property("2"); + currentNodes.should.not.have.a.property("3"); + stoppedNodes.should.have.a.property("1"); + stoppedNodes.should.have.a.property("2"); + stoppedNodes.should.have.a.property("3"); + done(); + }).catch(done); + }); + + it("stops specified nodes",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + flow.start(); + + currentNodes.should.have.a.property("1"); + currentNodes.should.have.a.property("2"); + currentNodes.should.have.a.property("3"); + + flow.stop(["2"]).then(function() { + currentNodes.should.have.a.property("1"); + currentNodes.should.not.have.a.property("2"); + currentNodes.should.have.a.property("3"); + stoppedNodes.should.not.have.a.property("1"); + stoppedNodes.should.have.a.property("2"); + stoppedNodes.should.not.have.a.property("3"); + done(); + }); + }); + + it("Times out a node that fails to close", function(done) { + Flow.init({settings:{nodeCloseTimeout:50},log:{ + log: sinon.stub(), + debug: sinon.stub(), + trace: sinon.stub(), + warn: sinon.stub(), + info: sinon.stub(), + metric: sinon.stub(), + _: function() { return "abc"} + }}); + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"testAsync",closeDelay: 80, foo:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + flow.start(); + + currentNodes.should.have.a.property("1"); + currentNodes.should.have.a.property("2"); + currentNodes.should.have.a.property("3"); + + flow.stop().then(function() { + currentNodes.should.have.a.property("1"); + currentNodes.should.not.have.a.property("2"); + currentNodes.should.not.have.a.property("3"); + stoppedNodes.should.not.have.a.property("1"); + stoppedNodes.should.have.a.property("2"); + stoppedNodes.should.have.a.property("3"); + setTimeout(function() { + currentNodes.should.not.have.a.property("1"); + stoppedNodes.should.have.a.property("1"); + done(); + },40) + }); + }); + + }); + + describe('#getNode',function() { + it("gets a node known to the flow",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"4",z:"t1",type:"test",foo:"a"} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + flow.start(); + + Object.keys(flow.getActiveNodes()).should.have.length(4); + + flow.getNode('1').should.have.a.property('id','1'); + + flow.stop().then(() => { done() }); + }); + + it("passes to parent if node not known locally",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"4",z:"t1",type:"test",foo:"a"} + ]); + var flow = Flow.create({ + getNode: id => { return {id:id}} + },config,config.flows["t1"]); + flow.start(); + + Object.keys(flow.getActiveNodes()).should.have.length(4); + + flow.getNode('1').should.have.a.property('id','1'); + + flow.getNode('parentNode').should.have.a.property('id','parentNode'); + + + flow.stop().then(() => { done() }); + }); + + it("does not pass to parent if cancelBubble set",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"4",z:"t1",type:"test",foo:"a"} + ]); + var flow = Flow.create({ + getNode: id => { return {id:id}} + },config,config.flows["t1"]); + flow.start(); + + Object.keys(flow.getActiveNodes()).should.have.length(4); + + flow.getNode('1').should.have.a.property('id','1'); + + should.not.exist(flow.getNode('parentNode',true)); + flow.stop().then(() => { done() }); + }); + }); + + describe("#handleStatus",function() { + it("passes a status event to the adjacent status node",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"test",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"sn",x:10,y:10,z:"t1",type:"status",foo:"a",wires:[]}, + {id:"sn2",x:10,y:10,z:"t1",type:"status",foo:"a",wires:[]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + Object.keys(activeNodes).should.have.length(5); + + + flow.handleStatus(config.flows["t1"].nodes["1"],{text:"my-status",random:"otherProperty"}); + + setTimeout(function() { + + currentNodes["sn"].should.have.a.property("handled",1); + var statusMessage = currentNodes["sn"].messages[0]; + + statusMessage.should.have.a.property("status"); + statusMessage.status.should.have.a.property("text","my-status"); + statusMessage.status.should.have.a.property("source"); + statusMessage.status.source.should.have.a.property("id","1"); + statusMessage.status.source.should.have.a.property("type","test"); + statusMessage.status.source.should.have.a.property("name","a"); + + currentNodes["sn2"].should.have.a.property("handled",1); + statusMessage = currentNodes["sn2"].messages[0]; + + statusMessage.should.have.a.property("status"); + statusMessage.status.should.have.a.property("text","my-status"); + statusMessage.status.should.have.a.property("random","otherProperty"); + statusMessage.status.should.have.a.property("source"); + statusMessage.status.source.should.have.a.property("id","1"); + statusMessage.status.source.should.have.a.property("type","test"); + statusMessage.status.source.should.have.a.property("name","a"); + + + flow.stop().then(function() { + done(); + }); + },50) + }); + it("passes a status event to the adjacent scoped status node ",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"test",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"sn",x:10,y:10,z:"t1",type:"status",scope:["2"],foo:"a",wires:[]}, + {id:"sn2",x:10,y:10,z:"t1",type:"status",scope:["1"],foo:"a",wires:[]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + Object.keys(activeNodes).should.have.length(5); + + + flow.handleStatus(config.flows["t1"].nodes["1"],{text:"my-status"}); + + setTimeout(function() { + currentNodes["sn"].should.have.a.property("handled",0); + currentNodes["sn2"].should.have.a.property("handled",1); + var statusMessage = currentNodes["sn2"].messages[0]; + + statusMessage.should.have.a.property("status"); + statusMessage.status.should.have.a.property("text","my-status"); + statusMessage.status.should.have.a.property("source"); + statusMessage.status.source.should.have.a.property("id","1"); + statusMessage.status.source.should.have.a.property("type","test"); + statusMessage.status.source.should.have.a.property("name","a"); + + + flow.stop().then(function() { + done(); + }); + },50); + }); + + }); + + describe("#handleError",function() { + it("passes an error event to the adjacent catch node",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"test",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"sn",x:10,y:10,z:"t1",type:"catch",foo:"a",wires:[]}, + {id:"sn2",x:10,y:10,z:"t1",type:"catch",foo:"a",wires:[]}, + {id:"sn3",x:10,y:10,z:"t1",type:"catch",uncaught:true,wires:[]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + Object.keys(activeNodes).should.have.length(6); + + + flow.handleError(config.flows["t1"].nodes["1"],"my-error",{a:"foo"}); + + setTimeout(function() { + currentNodes["sn"].should.have.a.property("handled",1); + var statusMessage = currentNodes["sn"].messages[0]; + + statusMessage.should.have.a.property("error"); + statusMessage.error.should.have.a.property("message","my-error"); + statusMessage.error.should.have.a.property("source"); + statusMessage.error.source.should.have.a.property("id","1"); + statusMessage.error.source.should.have.a.property("type","test"); + statusMessage.error.source.should.have.a.property("name","a"); + + currentNodes["sn2"].should.have.a.property("handled",1); + statusMessage = currentNodes["sn2"].messages[0]; + + statusMessage.should.have.a.property("error"); + statusMessage.error.should.have.a.property("message","my-error"); + statusMessage.error.should.have.a.property("source"); + statusMessage.error.source.should.have.a.property("id","1"); + statusMessage.error.source.should.have.a.property("type","test"); + statusMessage.error.source.should.have.a.property("name","a"); + + // Node sn3 has uncaught:true - so should not get called + currentNodes["sn3"].should.have.a.property("handled",0); + + + flow.stop().then(function() { + done(); + }); + },50); + }); + it("passes an error event to the adjacent scoped catch node ",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"test",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"sn",x:10,y:10,z:"t1",type:"catch",scope:["2"],foo:"a",wires:[]}, + {id:"sn2",x:10,y:10,z:"t1",type:"catch",scope:["1"],foo:"a",wires:[]}, + {id:"sn3",x:10,y:10,z:"t1",type:"catch",uncaught:true,wires:[]}, + {id:"sn4",x:10,y:10,z:"t1",type:"catch",uncaught:true,wires:[]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + Object.keys(activeNodes).should.have.length(7); + + flow.handleError(config.flows["t1"].nodes["1"],"my-error",{a:"foo"}); + + setTimeout(function() { + currentNodes["sn"].should.have.a.property("handled",0); + currentNodes["sn2"].should.have.a.property("handled",1); + var statusMessage = currentNodes["sn2"].messages[0]; + + statusMessage.should.have.a.property("error"); + statusMessage.error.should.have.a.property("message","my-error"); + statusMessage.error.should.have.a.property("source"); + statusMessage.error.source.should.have.a.property("id","1"); + statusMessage.error.source.should.have.a.property("type","test"); + statusMessage.error.source.should.have.a.property("name","a"); + + // Node sn3/4 have uncaught:true - so should not get called + currentNodes["sn3"].should.have.a.property("handled",0); + currentNodes["sn4"].should.have.a.property("handled",0); + + // Inject error that sn1/2 will ignore - so should get picked up by sn3 + flow.handleError(config.flows["t1"].nodes["3"],"my-error-2",{a:"foo-2"}); + setTimeout(function() { + currentNodes["sn"].should.have.a.property("handled",0); + currentNodes["sn2"].should.have.a.property("handled",1); + currentNodes["sn3"].should.have.a.property("handled",1); + currentNodes["sn4"].should.have.a.property("handled",1); + + statusMessage = currentNodes["sn3"].messages[0]; + statusMessage.should.have.a.property("error"); + statusMessage.error.should.have.a.property("message","my-error-2"); + statusMessage.error.should.have.a.property("source"); + statusMessage.error.source.should.have.a.property("id","3"); + statusMessage.error.source.should.have.a.property("type","test"); + + flow.stop().then(function() { + done(); + }); + },50); + },50); + }); + it("moves any existing error object sideways",function(done){ + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"test",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"sn",x:10,y:10,z:"t1",type:"catch",foo:"a",wires:[]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + + flow.handleError(config.flows["t1"].nodes["1"],"my-error",{a:"foo",error:"existing"}); + setTimeout(function() { + currentNodes["sn"].should.have.a.property("handled",1); + var statusMessage = currentNodes["sn"].messages[0]; + + statusMessage.should.have.a.property("_error","existing"); + statusMessage.should.have.a.property("error"); + statusMessage.error.should.have.a.property("message","my-error"); + statusMessage.error.should.have.a.property("source"); + statusMessage.error.source.should.have.a.property("id","1"); + statusMessage.error.source.should.have.a.property("type","test"); + statusMessage.error.source.should.have.a.property("name","a"); + + flow.stop().then(function() { + done(); + }); + },50); + }); + it("prevents an error looping more than 10 times",function(){}); + }); + + describe("#handleComplete",function() { + it("passes a complete event to the adjacent Complete node",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"testDone",name:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"test",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"testDone",foo:"a",wires:[]}, + {id:"cn",x:10,y:10,z:"t1",type:"complete",scope:["1","3"],foo:"a",wires:[]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + Object.keys(activeNodes).should.have.length(4); + + var msg = {payload: "hello world"} + var n1 = currentNodes["1"].receive(msg); + setTimeout(function() { + currentNodes["cn"].should.have.a.property("handled",2); + currentNodes["cn"].messages[0].should.have.a.property("handled",1); + currentNodes["cn"].messages[1].should.have.a.property("handled",2); + flow.stop().then(function() { + done(); + }); + },50); + }); + }); + + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/nodes/flows/Subflow_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/nodes/flows/Subflow_spec.js new file mode 100644 index 0000000..71bd9ad --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/nodes/flows/Subflow_spec.js @@ -0,0 +1,885 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +var should = require("should"); +var sinon = require('sinon'); +var clone = require('clone'); +var util = require("util"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var Subflow = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/flows/Subflow"); +var Flow = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/flows/Flow"); + +var flowUtils = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/flows/util"); +var flows = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/flows"); +var Node = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/Node"); +var typeRegistry = NR_TEST_UTILS.require("@node-red/registry"); + +describe('Subflow', function() { + var getType; + + var stoppedNodes = {}; + var currentNodes = {}; + var rewiredNodes = {}; + var createCount = 0; + + beforeEach(function() { + currentNodes = {}; + stoppedNodes = {}; + rewiredNodes = {}; + createCount = 0; + var runtime = { + settings:{}, + log:{ + log: sinon.stub(), // function() { console.log("l",[...arguments].map(a => JSON.stringify(a)).join(" ")) },// + debug: sinon.stub(), // function() { console.log("d",[...arguments].map(a => JSON.stringify(a)).join(" ")) },//sinon.stub(), + trace: sinon.stub(), // function() { console.log("t",[...arguments].map(a => JSON.stringify(a)).join(" ")) },//sinon.stub(), + warn: sinon.stub(), // function() { console.log("w",[...arguments].map(a => JSON.stringify(a)).join(" ")) },//sinon.stub(), + info: sinon.stub(), // function() { console.log("i",[...arguments].map(a => JSON.stringify(a)).join(" ")) },//sinon.stub(), + metric: sinon.stub(), + _: function() { return "abc"} + } + } + Flow.init(runtime); + Subflow.init(runtime); + }); + + var TestNode = function(n) { + Node.call(this,n); + this._index = createCount++; + this.scope = n.scope; + var node = this; + this.foo = n.foo; + this.handled = 0; + this.stopped = false; + this.received = null; + currentNodes[node.id] = node; + this.on('input',function(msg) { + // console.log(this.id,msg.payload); + node.handled++; + node.received = msg.payload; + node.send(msg); + }); + this.on('close',function() { + node.stopped = true; + stoppedNodes[node.id] = node; + delete currentNodes[node.id]; + }); + this.__updateWires = this.updateWires; + this.updateWires = function(newWires) { + rewiredNodes[node.id] = node; + node.newWires = newWires; + node.__updateWires(newWires); + }; + } + util.inherits(TestNode,Node); + + var TestErrorNode = function(n) { + Node.call(this,n); + this._index = createCount++; + this.scope = n.scope; + this.name = n.name; + var node = this; + this.foo = n.foo; + this.handled = 0; + this.stopped = false; + currentNodes[node.id] = node; + this.on('input',function(msg) { + node.handled++; + node.error("test error",msg); + }); + this.on('close',function() { + node.stopped = true; + stoppedNodes[node.id] = node; + delete currentNodes[node.id]; + }); + this.__updateWires = this.updateWires; + this.updateWires = function(newWires) { + rewiredNodes[node.id] = node; + node.newWires = newWires; + node.__updateWires(newWires); + }; + } + util.inherits(TestErrorNode,Node); + + + var TestStatusNode = function(n) { + Node.call(this,n); + this._index = createCount++; + this.scope = n.scope; + this.name = n.name; + var node = this; + this.foo = n.foo; + this.handled = 0; + this.stopped = false; + currentNodes[node.id] = node; + this.on('input',function(msg) { + node.handled++; + node.status({text:"test status"}); + }); + this.on('close',function() { + node.stopped = true; + stoppedNodes[node.id] = node; + delete currentNodes[node.id]; + }); + this.__updateWires = this.updateWires; + this.updateWires = function(newWires) { + rewiredNodes[node.id] = node; + node.newWires = newWires; + node.__updateWires(newWires); + }; + } + util.inherits(TestStatusNode,Node); + + var TestAsyncNode = function(n) { + Node.call(this,n); + var node = this; + this.scope = n.scope; + this.foo = n.foo; + this.handled = 0; + this.messages = []; + this.stopped = false; + this.closeDelay = n.closeDelay || 50; + currentNodes[node.id] = node; + this.on('input',function(msg) { + node.handled++; + node.messages.push(msg); + node.send(msg); + }); + this.on('close',function(done) { + setTimeout(function() { + node.stopped = true; + stoppedNodes[node.id] = node; + delete currentNodes[node.id]; + done(); + },node.closeDelay); + }); + } + util.inherits(TestAsyncNode,Node); + + var TestEnvNode = function(n) { + Node.call(this,n); + this._index = createCount++; + this.scope = n.scope; + this.foo = n.foo; + var node = this; + this.stopped = false; + this.received = null; + currentNodes[node.id] = node; + this.on('input',function(msg) { + var flow = node._flow; + var val = flow.getSetting("__KEY__"); + node.received = val; + node.send({payload: val}); + }); + this.on('close',function() { + node.stopped = true; + stoppedNodes[node.id] = node; + delete currentNodes[node.id]; + }); + this.__updateWires = this.updateWires; + this.updateWires = function(newWires) { + rewiredNodes[node.id] = node; + node.newWires = newWires; + node.__updateWires(newWires); + }; + } + util.inherits(TestEnvNode,Node); + + before(function() { + getType = sinon.stub(typeRegistry,"get",function(type) { + if (type=="test") { + return TestNode; + } else if (type=="testError"){ + return TestErrorNode; + } else if (type=="testStatus"){ + return TestStatusNode; + } else if (type=="testEnv"){ + return TestEnvNode; + } else { + return TestAsyncNode; + } + }); + }); + after(function() { + getType.restore(); + }); + describe('#start',function() { + it("instantiates a subflow and stops it",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"subflow:sf1",wires:["3","4"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"4",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"sf1",type:"subflow","name":"Subflow 2","info":"", + "in":[{"wires":[{"id":"sf1-1"}]}],"out":[{"wires":[{"id":"sf1-2","port":0}]},{"wires":[{"id":"sf1","port":0}]}]}, + {id:"sf1-1",type:"test","z":"sf1",x:166,y:99,"wires":[["sf1-2"]]}, + {id:"sf1-2",type:"test","z":"sf1",foo:"sf1-cn",x:166,y:99,"wires":[[]]}, + {id:"sf1-cn",type:"test","z":"sf1"} + ]); + var flow = Flow.create({handleError: (a,b,c) => { console.log(a,b,c); }},config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + Object.keys(activeNodes).should.have.length(4); + // var sfInstanceId = Object.keys(activeNodes)[5]; + // var sfInstanceId2 = Object.keys(activeNodes)[6]; + var sfConfigId = Object.keys(activeNodes)[4]; + + flow.getNode('1').should.have.a.property('id','1'); + flow.getNode('2').should.have.a.property('id','2'); + flow.getNode('3').should.have.a.property('id','3'); + flow.getNode('4').should.have.a.property('id','4'); + // flow.getNode(sfInstanceId).should.have.a.property('id',sfInstanceId); + // flow.getNode(sfInstanceId2).should.have.a.property('id',sfInstanceId2); + // flow.getNode(sfConfigId).should.have.a.property('id',sfConfigId); + + // flow.getNode(sfInstanceId2).should.have.a.property('foo',sfConfigId); + + Object.keys(currentNodes).should.have.length(6); + + currentNodes.should.have.a.property("1"); + currentNodes.should.not.have.a.property("2"); + currentNodes.should.have.a.property("3"); + currentNodes.should.have.a.property("4"); + // currentNodes.should.have.a.property(sfInstanceId); + // currentNodes.should.have.a.property(sfInstanceId2); + // currentNodes.should.have.a.property(sfConfigId); + + currentNodes["1"].should.have.a.property("handled",0); + currentNodes["3"].should.have.a.property("handled",0); + currentNodes["4"].should.have.a.property("handled",0); + // currentNodes[sfInstanceId].should.have.a.property("handled",0); + // currentNodes[sfInstanceId2].should.have.a.property("handled",0); + + currentNodes["1"].receive({payload:"test"}); + + setTimeout(function() { + currentNodes["1"].should.have.a.property("handled",1); + // currentNodes[sfInstanceId].should.have.a.property("handled",1); + // currentNodes[sfInstanceId2].should.have.a.property("handled",1); + currentNodes["3"].should.have.a.property("handled",1); + currentNodes["4"].should.have.a.property("handled",1); + + + + flow.stop().then(function() { + Object.keys(currentNodes).should.have.length(0); + Object.keys(stoppedNodes).should.have.length(6); + + // currentNodes.should.not.have.a.property("1"); + // currentNodes.should.not.have.a.property("3"); + // currentNodes.should.not.have.a.property("4"); + // // currentNodes.should.not.have.a.property(sfInstanceId); + // // currentNodes.should.not.have.a.property(sfInstanceId2); + // // currentNodes.should.not.have.a.property(sfConfigId); + // stoppedNodes.should.have.a.property("1"); + // stoppedNodes.should.have.a.property("3"); + // stoppedNodes.should.have.a.property("4"); + // // stoppedNodes.should.have.a.property(sfInstanceId); + // // stoppedNodes.should.have.a.property(sfInstanceId2); + // // stoppedNodes.should.have.a.property(sfConfigId); + done(); + }); + },150); + }); + it("instantiates a subflow inside a subflow and stops it",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"subflow:sf1",wires:["3","4"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"4",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"sf1",type:"subflow","name":"Subflow 1","info":"", + "in":[{"wires":[{"id":"sf1-1"}]}],"out":[{"wires":[{"id":"sf1-2","port":0}]}]}, + {id:"sf2",type:"subflow","name":"Subflow 2","info":"", + "in":[{wires:[]}],"out":[{"wires":[{"id":"sf2","port":0}]}]}, + {id:"sf1-1",type:"test","z":"sf1",x:166,y:99,"wires":[["sf1-2"]]}, + {id:"sf1-2",type:"subflow:sf2","z":"sf1",x:166,y:99,"wires":[[]]} + + ]); + var flow = Flow.create({},config,config.flows["t1"]); + + flow.start(); + + currentNodes["1"].should.have.a.property("handled",0); + currentNodes["3"].should.have.a.property("handled",0); + + currentNodes["1"].receive({payload:"test"}); + + setTimeout(function() { + currentNodes["1"].should.have.a.property("handled",1); + currentNodes["3"].should.have.a.property("handled",1); + flow.stop().then(function() { + Object.keys(currentNodes).should.have.length(0); + done(); + }); + },150); + }); + it("rewires a subflow node on update/start",function(done){ + + var rawConfig = [ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"subflow:sf1",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"4",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"sf1",type:"subflow","name":"Subflow 2","info":"", + "in":[{"wires":[{"id":"sf1-1"}]}],"out":[{"wires":[{"id":"sf1-2","port":0}]}]}, + {id:"sf1-1",type:"test1","z":"sf1",x:166,y:99,"wires":[["sf1-2"]]}, + {id:"sf1-2",type:"test2","z":"sf1",x:166,y:99,"wires":[[]]} + ]; + + var config = flowUtils.parseConfig(clone(rawConfig)); + + rawConfig[2].wires = [["4"]]; + + var newConfig = flowUtils.parseConfig(rawConfig); + var diff = flowUtils.diffConfigs(config,newConfig); + var flow = Flow.create({},config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + Object.keys(activeNodes).should.have.length(4); + // var sfInstanceId = Object.keys(activeNodes)[4]; + // var sfInstanceId2 = Object.keys(activeNodes)[5]; + + currentNodes["1"].should.have.a.property("handled",0); + currentNodes["3"].should.have.a.property("handled",0); + currentNodes["4"].should.have.a.property("handled",0); + + currentNodes["1"].receive({payload:"test"}); + + setTimeout(function() { + currentNodes["1"].should.have.a.property("handled",1); + // currentNodes[sfInstanceId].should.have.a.property("handled",1); + // currentNodes[sfInstanceId2].should.have.a.property("handled",1); + currentNodes["3"].should.have.a.property("handled",1); + currentNodes["4"].should.have.a.property("handled",0); + + flow.update(newConfig,newConfig.flows["t1"]); + flow.start(diff) + + currentNodes["1"].receive({payload:"test2"}); + setTimeout(function() { + + currentNodes["1"].should.have.a.property("handled",2); + // currentNodes[sfInstanceId].should.have.a.property("handled",2); + // currentNodes[sfInstanceId2].should.have.a.property("handled",2); + currentNodes["3"].should.have.a.property("handled",1); + currentNodes["4"].should.have.a.property("handled",1); + + + flow.stop().then(function() { + done(); + }); + },150); + },150); + }); + }); + describe('#stop', function() { + it("stops subflow instance nodes",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"subflow:sf1",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"sf1",type:"subflow","name":"Subflow 2","info":"", + "in":[{"wires":[{"id":"sf1-1"}]}],"out":[{"wires":[{"id":"sf1-1","port":0}]}]}, + {id:"sf1-1",type:"test","z":"sf1",x:166,y:99,"wires":[[]]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + Object.keys(activeNodes).should.have.length(3); + Object.keys(stoppedNodes).should.have.length(0); + flow.stop(["2"]).then(function() { + Object.keys(currentNodes).should.have.length(2); + Object.keys(stoppedNodes).should.have.length(1); + done(); + }).catch(done); + }); + }); + describe("#handleStatus",function() { + it("passes a status event to the subflow's parent tab status node - all scope",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"subflow:sf1",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"sf1",type:"subflow","name":"Subflow 2","info":"", + "in":[{"wires":[{"id":"sf1-1"}]}],"out":[{"wires":[{"id":"sf1-1","port":0}]}]}, + {id:"sf1-1",type:"testStatus",name:"test-status-node","z":"sf1",x:166,y:99,"wires":[[]]}, + {id:"sn",x:10,y:10,z:"t1",type:"status",foo:"a",wires:[]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + + activeNodes["1"].receive({payload:"test"}); + setTimeout(function() { + currentNodes["sn"].should.have.a.property("handled",1); + var statusMessage = currentNodes["sn"].messages[0]; + + statusMessage.should.have.a.property("status"); + statusMessage.status.should.have.a.property("text","test status"); + statusMessage.status.should.have.a.property("source"); + statusMessage.status.source.should.have.a.property("type","testStatus"); + statusMessage.status.source.should.have.a.property("name","test-status-node"); + + flow.stop().then(function() { + done(); + }); + },150); + }); + it("passes a status event to the subflow's parent tab status node - targetted scope",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"subflow:sf1",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"sf1",type:"subflow","name":"Subflow 2","info":"", + "in":[{"wires":[{"id":"sf1-1"}]}],"out":[{"wires":[{"id":"sf1-1","port":0}]}]}, + {id:"sf1-1",type:"testStatus",name:"test-status-node","z":"sf1",x:166,y:99,"wires":[[]]}, + {id:"sn",x:10,y:10,z:"t1",type:"status",scope:["2"],wires:[]} + ]); + var parentFlowStatusCalled = false; + + var flow = Flow.create({handleStatus:() => { parentFlowStatusCalled = true} },config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + + activeNodes["1"].receive({payload:"test"}); + + setTimeout(function() { + parentFlowStatusCalled.should.be.false(); + + currentNodes["sn"].should.have.a.property("handled",1); + var statusMessage = currentNodes["sn"].messages[0]; + + statusMessage.should.have.a.property("status"); + statusMessage.status.should.have.a.property("text","test status"); + statusMessage.status.should.have.a.property("source"); + statusMessage.status.source.should.have.a.property("type","testStatus"); + statusMessage.status.source.should.have.a.property("name","test-status-node"); + + flow.stop().then(function() { + + done(); + }); + },150); + }); + }); + + describe("status node", function() { + it("emits a status event when a message is passed to a subflow-status node - msg.payload as string", function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"subflow:sf1",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + { + id:"sf1", + type:"subflow", + name:"Subflow 2", + info:"", + in:[{wires:[{id:"sf1-1"}]}], + out:[{wires:[{id:"sf1-1",port:0}]}], + status:{wires:[{id:"sf1-1", port:0}]} + }, + {id:"sf1-1",type:"test",name:"test","z":"sf1",x:166,y:99,"wires":[[]]}, + {id:"sn",x:10,y:10,z:"t1",type:"status",foo:"a",wires:[]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + + activeNodes["1"].receive({payload:"test-payload"}); + + setTimeout(function() { + currentNodes["sn"].should.have.a.property("handled",1); + var statusMessage = currentNodes["sn"].messages[0]; + + statusMessage.should.have.a.property("status"); + statusMessage.status.should.have.a.property("text","test-payload"); + statusMessage.status.should.have.a.property("source"); + statusMessage.status.source.should.have.a.property("id","2"); + statusMessage.status.source.should.have.a.property("type","subflow:sf1"); + + flow.stop().then(function() { + + done(); + }); + },150); + }); + it("emits a status event when a message is passed to a subflow-status node - msg.payload as status obj", function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"subflow:sf1",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + { + id:"sf1", + type:"subflow", + name:"Subflow 2", + info:"", + in:[{wires:[{id:"sf1-1"}]}], + out:[{wires:[{id:"sf1-1",port:0}]}], + status:{wires:[{id:"sf1-1", port:0}]} + }, + {id:"sf1-1",type:"test",name:"test","z":"sf1",x:166,y:99,"wires":[[]]}, + {id:"sn",x:10,y:10,z:"t1",type:"status",foo:"a",wires:[]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + + activeNodes["1"].receive({payload:{text:"payload-obj"}}); + + setTimeout(function() { + currentNodes["sn"].should.have.a.property("handled",1); + var statusMessage = currentNodes["sn"].messages[0]; + + statusMessage.should.have.a.property("status"); + statusMessage.status.should.have.a.property("text","payload-obj"); + statusMessage.status.should.have.a.property("source"); + statusMessage.status.source.should.have.a.property("id","2"); + statusMessage.status.source.should.have.a.property("type","subflow:sf1"); + + flow.stop().then(function() { + + done(); + }); + },150); + }); + it("emits a status event when a message is passed to a subflow-status node - msg.status", function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"subflow:sf1",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + { + id:"sf1", + type:"subflow", + name:"Subflow 2", + info:"", + in:[{wires:[{id:"sf1-1"}]}], + out:[{wires:[{id:"sf1-1",port:0}]}], + status:{wires:[{id:"sf1-1", port:0}]} + }, + {id:"sf1-1",type:"test",name:"test","z":"sf1",x:166,y:99,"wires":[[]]}, + {id:"sn",x:10,y:10,z:"t1",type:"status",foo:"a",wires:[]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + + activeNodes["1"].receive({status:{text:"status-obj"}}); + + setTimeout(function() { + currentNodes["sn"].should.have.a.property("handled",1); + var statusMessage = currentNodes["sn"].messages[0]; + + statusMessage.should.have.a.property("status"); + statusMessage.status.should.have.a.property("text","status-obj"); + statusMessage.status.should.have.a.property("source"); + statusMessage.status.source.should.have.a.property("id","2"); + statusMessage.status.source.should.have.a.property("type","subflow:sf1"); + + flow.stop().then(function() { + + done(); + }); + },150); + }); + it("does not emit a regular status event if it contains a subflow-status node", function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"subflow:sf1",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + { + id:"sf1", + type:"subflow", + name:"Subflow 2", + info:"", + in:[{wires:[{id:"sf1-1"}]}], + out:[{wires:[{id:"sf1-1",port:0}]}], + status:{wires:[]} + }, + {id:"sf1-1",type:"testStatus",name:"test-status-node","z":"sf1",x:166,y:99,"wires":[[]]}, + {id:"sn",x:10,y:10,z:"t1",type:"status",foo:"a",wires:[]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + + activeNodes["1"].receive({payload:"test-payload"}); + + currentNodes["sn"].should.have.a.property("handled",0); + + flow.stop().then(function() { + + done(); + }); + }); + }) + + describe("#handleError",function() { + it("passes an error event to the subflow's parent tab catch node - all scope",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"subflow:sf1",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"sf1",type:"subflow","name":"Subflow 2","info":"", + "in":[{"wires":[{"id":"sf1-1"}]}],"out":[{"wires":[{"id":"sf1-1","port":0}]}]}, + {id:"sf1-1",name:"test-error-node",type:"testError","z":"sf1",x:166,y:99,"wires":[[]]}, + {id:"sn",x:10,y:10,z:"t1",type:"catch",foo:"a",wires:[]} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + + activeNodes["1"].receive({payload:"test"}); + + setTimeout(function() { + currentNodes["sn"].should.have.a.property("handled",1); + var statusMessage = currentNodes["sn"].messages[0]; + + statusMessage.should.have.a.property("error"); + statusMessage.error.should.have.a.property("message","test error"); + statusMessage.error.should.have.a.property("source"); + statusMessage.error.source.should.have.a.property("type","testError"); + statusMessage.error.source.should.have.a.property("name","test-error-node"); + + flow.stop().then(function() { + done(); + }); + },150); + }); + it("passes an error event to the subflow's parent tab catch node - targetted scope",function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",name:"a",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"subflow:sf1",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"sf1",type:"subflow","name":"Subflow 2","info":"", + "in":[{"wires":[{"id":"sf1-1"}]}],"out":[{"wires":[{"id":"sf1-1","port":0}]}]}, + {id:"sf1-1",name:"test-error-node",type:"testError","z":"sf1",x:166,y:99,"wires":[[]]}, + {id:"sn",x:10,y:10,z:"t1",type:"catch",scope:["2"],wires:[]} + ]); + var parentFlowErrorCalled = false; + var flow = Flow.create({handleError:() => { parentFlowErrorCalled = true} },config,config.flows["t1"]); + + flow.start(); + + var activeNodes = flow.getActiveNodes(); + + activeNodes["1"].receive({payload:"test"}); + + setTimeout(function() { + parentFlowErrorCalled.should.be.false(); + + currentNodes["sn"].should.have.a.property("handled",1); + var statusMessage = currentNodes["sn"].messages[0]; + + statusMessage.should.have.a.property("error"); + statusMessage.error.should.have.a.property("message","test error"); + statusMessage.error.should.have.a.property("source"); + statusMessage.error.source.should.have.a.property("type","testError"); + statusMessage.error.source.should.have.a.property("name","test-error-node"); + + flow.stop().then(function() { + done(); + }); + },150); + + }); + }); + + describe("#env var", function() { + // should be changed according to internal env var representation + function setEnv(node, key, val) { + var flow = node._flow; + if (flow) { + var env = flow.env; + if (!env) { + env = flow.env = {}; + } + env[key] = { + name: key, + type: "str", + value: val + }; + } + } + + it("can access process env var", function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"t1.1",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"subflow:sf1",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"t1.3",wires:[]}, + {id:"sf1",type:"subflow",name:"Subflow 2",info:"", + "in":[ {wires:[{id:"sf1-1"}]} ], + "out":[ {wires:[{id:"sf1-2",port:0}]} ]}, + {id:"sf1-1",type:"test",z:"sf1",foo:"sf1.1",x:166,y:99,wires:[["sf1-2"]]}, + {id:"sf1-2",type:"testEnv",z:"sf1",foo:"sf1-cn",x:166,y:99,wires:[[]]} + ]); + var flow = Flow.create({ + getSetting: k=> process.env[k], + handleError: (a,b,c) => { console.log(a,b,c); } + },config,config.flows["t1"]); + + flow.start(); + + process.env["__KEY__"] = "__VAL__"; + + currentNodes["1"].receive({payload: "test"}); + setTimeout(function() { + currentNodes["3"].should.have.a.property("received", "__VAL__"); + + flow.stop().then(function() { + done(); + }); + },150); + }); + + it("can access subflow env var", function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"t1.1",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"subflow:sf1",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"t1.3",wires:[]}, + {id:"sf1",type:"subflow",name:"Subflow 2",info:"", + "in":[ {wires:[{id:"sf1-1"}]} ], + "out":[ {wires:[{id:"sf1-2",port:0}]} ]}, + {id:"sf1-1",type:"test",z:"sf1",foo:"sf1.1",x:166,y:99,wires:[["sf1-2"]]}, + {id:"sf1-2",type:"testEnv",z:"sf1",foo:"sf1.2",x:166,y:99,wires:[[]]} + ]); + var flow = Flow.create({ + getSetting: k=> process.env[k], + handleError: (a,b,c) => { console.log(a,b,c); } + },config,config.flows["t1"]); + + flow.start(); + + var testenv_node = null; + for (var n in currentNodes) { + var node = currentNodes[n]; + if (node.type === "testEnv") { + testenv_node = node; + break; + } + } + process.env["__KEY__"] = "__VAL0__"; + setEnv(testenv_node, "__KEY__", "__VAL1__"); + + currentNodes["1"].receive({payload: "test"}); + setTimeout(function() { + currentNodes["3"].should.have.a.property("received", "__VAL1__"); + + flow.stop().then(function() { + done(); + }); + },150); + }); + + it("can access nested subflow env var", function(done) { + var config = flowUtils.parseConfig([ + {id:"t1",type:"tab"}, + {id:"1",x:10,y:10,z:"t1",type:"test",foo:"t1.1",wires:["2"]}, + {id:"2",x:10,y:10,z:"t1",type:"subflow:sf1",wires:["3"]}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"t1.3",wires:[]}, + {id:"sf1",type:"subflow",name:"Subflow 1",info:"", + in:[{wires:[{id:"sf1-1"}]}], + out:[{wires:[{id:"sf1-2",port:0}]}]}, + {id:"sf2",type:"subflow",name:"Subflow 2",info:"", + in:[{wires:[{id:"sf2-1"}]}], + out:[{wires:[{id:"sf2-2",port:0}]}]}, + {id:"sf1-1",type:"test",z:"sf1",foo:"sf1.1",x:166,y:99,wires:[["sf1-2"]]}, + {id:"sf1-2",type:"subflow:sf2",z:"sf1",x:166,y:99,wires:[[]]}, + {id:"sf2-1",type:"test",z:"sf2",foo:"sf2.1",x:166,y:99,wires:[["sf2-2"]]}, + {id:"sf2-2",type:"testEnv",z:"sf2",foo:"sf2.2",x:166,y:99,wires:[[]]}, + ]); + var flow = Flow.create({ + getSetting: k=> process.env[k], + handleError: (a,b,c) => { console.log(a,b,c); } + },config,config.flows["t1"]); + + flow.start(); + + var node_sf1_1 = null; + var node_sf2_1 = null; + var testenv_node = null; + for (var n in currentNodes) { + var node = currentNodes[n]; + if (node.foo === "sf1.1") { + node_sf1_1 = node; + } + if (node.foo === "sf2.1") { + node_sf2_1 = node; + } + } + + process.env["__KEY__"] = "__VAL0__"; + currentNodes["1"].receive({payload: "test"}); + setTimeout(function() { + currentNodes["3"].should.have.a.property("received", "__VAL0__"); + + setEnv(node_sf1_1, "__KEY__", "__VAL1__"); + currentNodes["1"].receive({payload: "test"}); + setTimeout(function() { + currentNodes["3"].should.have.a.property("received", "__VAL1__"); + + setEnv(node_sf2_1, "__KEY__", "__VAL2__"); + currentNodes["1"].receive({payload: "test"}); + setTimeout(function() { + currentNodes["3"].should.have.a.property("received", "__VAL2__"); + + flow.stop().then(function() { + done(); + }); + },150); + },150); + },150); + }); + + }); + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/nodes/flows/index_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/nodes/flows/index_spec.js new file mode 100644 index 0000000..8865c5d --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/nodes/flows/index_spec.js @@ -0,0 +1,617 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); +var when = require("when"); +var clone = require("clone"); +var NR_TEST_UTILS = require("nr-test-utils"); + +var flows = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/flows"); +var RedNode = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/Node"); +var RED = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes"); +var events = NR_TEST_UTILS.require("@node-red/runtime/lib/events"); +var credentials = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/credentials"); +var typeRegistry = NR_TEST_UTILS.require("@node-red/registry") +var Flow = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/flows/Flow"); + +describe('flows/index', function() { + + var storage; + var eventsOn; + var credentialsClean; + var credentialsLoad; + + var flowCreate; + var getType; + + var mockLog = { + log: sinon.stub(), + debug: sinon.stub(), + trace: sinon.stub(), + warn: sinon.stub(), + info: sinon.stub(), + metric: sinon.stub(), + _: function() { return "abc"} + } + + + before(function() { + getType = sinon.stub(typeRegistry,"get",function(type) { + return type.indexOf('missing') === -1; + }); + }); + after(function() { + getType.restore(); + }); + + + beforeEach(function() { + eventsOn = sinon.spy(events,"on"); + credentialsClean = sinon.stub(credentials,"clean",function(conf) { + conf.forEach(function(n) { + delete n.credentials; + }); + return when.resolve(); + }); + credentialsLoad = sinon.stub(credentials,"load",function(creds) { + if (creds && creds.hasOwnProperty("$") && creds['$'] === "fail") { + return when.reject("creds error"); + } + return when.resolve(); + }); + flowCreate = sinon.stub(Flow,"create",function(parent, global, flow) { + var id; + if (typeof flow === 'undefined') { + flow = global; + id = '_GLOBAL_'; + } else { + id = flow.id; + } + flowCreate.flows[id] = { + flow: flow, + global: global, + start: sinon.spy(), + update: sinon.spy(), + stop: sinon.spy(), + getActiveNodes: function() { + return flow.nodes||{}; + }, + handleError: sinon.spy(), + handleStatus: sinon.spy() + + } + return flowCreate.flows[id]; + }); + flowCreate.flows = {}; + + storage = { + saveFlows: function(conf) { + storage.conf = conf; + return when.resolve(); + } + } + }); + + afterEach(function(done) { + eventsOn.restore(); + credentialsClean.restore(); + credentialsLoad.restore(); + flowCreate.restore(); + + flows.stopFlows().then(done); + + }); + // describe('#init',function() { + // it('registers the type-registered handler', function() { + // flows.init({},{}); + // eventsOn.calledOnce.should.be.true(); + // }); + // }); + + describe('#setFlows', function() { + it('sets the full flow', function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1",type:"tab"} + ]; + flows.init({log:mockLog, settings:{},storage:storage}); + flows.setFlows(originalConfig).then(function() { + credentialsClean.called.should.be.true(); + storage.hasOwnProperty('conf').should.be.true(); + flows.getFlows().flows.should.eql(originalConfig); + done(); + }); + + }); + it('loads the full flow for type load', function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1",type:"tab"} + ]; + var loadStorage = { + saveFlows: function(conf) { + loadStorage.conf = conf; + return when.resolve(456); + }, + getFlows: function() { + return when.resolve({flows:originalConfig,rev:123}) + } + } + flows.init({log:mockLog, settings:{},storage:loadStorage}); + flows.setFlows(originalConfig,"load").then(function() { + credentialsClean.called.should.be.false(); + // 'load' type does not trigger a save + loadStorage.hasOwnProperty('conf').should.be.false(); + flows.getFlows().flows.should.eql(originalConfig); + done(); + }); + + }); + + it('extracts credentials from the full flow', function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[],credentials:{"a":1}}, + {id:"t1",type:"tab"} + ]; + flows.init({log:mockLog, settings:{},storage:storage}); + flows.setFlows(originalConfig).then(function() { + credentialsClean.called.should.be.true(); + storage.hasOwnProperty('conf').should.be.true(); + var cleanedFlows = flows.getFlows(); + storage.conf.flows.should.eql(cleanedFlows.flows); + cleanedFlows.flows.should.not.eql(originalConfig); + cleanedFlows.flows[0].credentials = {"a":1}; + cleanedFlows.flows.should.eql(originalConfig); + done(); + }); + }); + + it('sets the full flow including credentials', function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1",type:"tab"} + ]; + var credentials = {"t1-1":{"a":1}}; + + flows.init({log:mockLog, settings:{},storage:storage}); + flows.setFlows(originalConfig,credentials).then(function() { + credentialsClean.called.should.be.false(); + credentialsLoad.called.should.be.true(); + credentialsLoad.lastCall.args[0].should.eql(credentials); + flows.getFlows().flows.should.eql(originalConfig); + done(); + }); + }); + + it('updates existing flows with partial deployment - nodes', function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1",type:"tab"} + ]; + var newConfig = clone(originalConfig); + newConfig.push({id:"t1-2",x:10,y:10,z:"t1",type:"test",wires:[]}); + newConfig.push({id:"t2",type:"tab"}); + newConfig.push({id:"t2-1",x:10,y:10,z:"t2",type:"test",wires:[]}); + storage.getFlows = function() { + return when.resolve({flows:originalConfig}); + } + + events.once('nodes-started',function() { + flows.setFlows(newConfig,"nodes").then(function() { + flows.getFlows().flows.should.eql(newConfig); + flowCreate.flows['t1'].update.called.should.be.true(); + flowCreate.flows['t2'].start.called.should.be.true(); + flowCreate.flows['_GLOBAL_'].update.called.should.be.true(); + done(); + }) + }); + + flows.init({log:mockLog, settings:{},storage:storage}); + flows.load().then(function() { + flows.startFlows(); + }); + }); + + it('updates existing flows with partial deployment - flows', function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1",type:"tab"} + ]; + var newConfig = clone(originalConfig); + newConfig.push({id:"t1-2",x:10,y:10,z:"t1",type:"test",wires:[]}); + newConfig.push({id:"t2",type:"tab"}); + newConfig.push({id:"t2-1",x:10,y:10,z:"t2",type:"test",wires:[]}); + storage.getFlows = function() { + return when.resolve({flows:originalConfig}); + } + + events.once('nodes-started',function() { + flows.setFlows(newConfig,"nodes").then(function() { + flows.getFlows().flows.should.eql(newConfig); + flowCreate.flows['t1'].update.called.should.be.true(); + flowCreate.flows['t2'].start.called.should.be.true(); + flowCreate.flows['_GLOBAL_'].update.called.should.be.true(); + flows.stopFlows().then(done); + }) + }); + + flows.init({log:mockLog, settings:{},storage:storage}); + flows.load().then(function() { + flows.startFlows(); + }); + }); + + it('returns error if it cannot decrypt credentials', function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1",type:"tab"} + ]; + var credentials = {"$":"fail"}; + + flows.init({log:mockLog, settings:{},storage:storage}); + flows.setFlows(originalConfig,credentials).then(function() { + done("Unexpected success when credentials couldn't be decrypted") + }).catch(function(err) { + done(); + }); + }); + }); + + describe('#load', function() { + it('loads the flow config', function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1",type:"tab"} + ]; + storage.getFlows = function() { + return when.resolve({flows:originalConfig}); + } + flows.init({log:mockLog, settings:{},storage:storage}); + flows.load().then(function() { + credentialsLoad.called.should.be.true(); + // 'load' type does not trigger a save + storage.hasOwnProperty('conf').should.be.false(); + flows.getFlows().flows.should.eql(originalConfig); + done(); + }); + }); + }); + + describe('#startFlows', function() { + it('starts the loaded config', function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1",type:"tab"} + ]; + storage.getFlows = function() { + return when.resolve({flows:originalConfig}); + } + + events.once('nodes-started',function() { + Object.keys(flowCreate.flows).should.eql(['_GLOBAL_','t1']); + done(); + }); + + flows.init({log:mockLog, settings:{},storage:storage}); + flows.load().then(function() { + flows.startFlows(); + }); + }); + it('does not start if nodes missing', function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1-2",x:10,y:10,z:"t1",type:"missing",wires:[]}, + {id:"t1",type:"tab"} + ]; + storage.getFlows = function() { + return when.resolve({flows:originalConfig}); + } + + flows.init({log:mockLog, settings:{},storage:storage}); + flows.load().then(function() { + flows.startFlows(); + flowCreate.called.should.be.false(); + done(); + }); + }); + + it('starts when missing nodes registered', function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1-2",x:10,y:10,z:"t1",type:"missing",wires:[]}, + {id:"t1-3",x:10,y:10,z:"t1",type:"missing2",wires:[]}, + {id:"t1",type:"tab"} + ]; + storage.getFlows = function() { + return when.resolve({flows:originalConfig}); + } + flows.init({log:mockLog, settings:{},storage:storage}); + flows.load().then(function() { + flows.startFlows(); + flowCreate.called.should.be.false(); + + events.emit("type-registered","missing"); + setTimeout(function() { + flowCreate.called.should.be.false(); + events.emit("type-registered","missing2"); + setTimeout(function() { + flowCreate.called.should.be.true(); + done(); + },10); + },10); + }); + }); + + + + }); + + describe.skip('#get',function() { + + }); + + describe('#eachNode', function() { + it('iterates the flow nodes', function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1",type:"tab"} + ]; + storage.getFlows = function() { + return when.resolve({flows:originalConfig}); + } + flows.init({log:mockLog, settings:{},storage:storage}); + flows.load().then(function() { + var c = 0; + flows.eachNode(function(node) { + c++ + }) + c.should.equal(2); + done(); + }); + }); + }); + + describe('#stopFlows', function() { + + }); + // describe('#handleError', function() { + // it('passes error to correct flow', function(done) { + // var originalConfig = [ + // {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + // {id:"t1",type:"tab"} + // ]; + // storage.getFlows = function() { + // return when.resolve({flows:originalConfig}); + // } + // + // events.once('nodes-started',function() { + // flows.handleError(originalConfig[0],"message",{}); + // flowCreate.flows['t1'].handleError.called.should.be.true(); + // done(); + // }); + // + // flows.init({log:mockLog, settings:{},storage:storage}); + // flows.load().then(function() { + // flows.startFlows(); + // }); + // }); + // it('passes error to flows that use the originating global config', function(done) { + // var originalConfig = [ + // {id:"configNode",type:"test"}, + // {id:"t1",type:"tab"}, + // {id:"t1-1",x:10,y:10,z:"t1",type:"test",config:"configNode",wires:[]}, + // {id:"t2",type:"tab"}, + // {id:"t2-1",x:10,y:10,z:"t2",type:"test",wires:[]}, + // {id:"t3",type:"tab"}, + // {id:"t3-1",x:10,y:10,z:"t3",type:"test",config:"configNode",wires:[]} + // ]; + // storage.getFlows = function() { + // return when.resolve({flows:originalConfig}); + // } + // + // events.once('nodes-started',function() { + // flows.handleError(originalConfig[0],"message",{}); + // try { + // flowCreate.flows['t1'].handleError.called.should.be.true(); + // flowCreate.flows['t2'].handleError.called.should.be.false(); + // flowCreate.flows['t3'].handleError.called.should.be.true(); + // done(); + // } catch(err) { + // done(err); + // } + // }); + // + // flows.init({log:mockLog, settings:{},storage:storage}); + // flows.load().then(function() { + // flows.startFlows(); + // }); + // }); + // }); + // describe('#handleStatus', function() { + // it('passes status to correct flow', function(done) { + // var originalConfig = [ + // {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + // {id:"t1",type:"tab"} + // ]; + // storage.getFlows = function() { + // return when.resolve({flows:originalConfig}); + // } + // + // events.once('nodes-started',function() { + // flows.handleStatus(originalConfig[0],"message"); + // flowCreate.flows['t1'].handleStatus.called.should.be.true(); + // done(); + // }); + // + // flows.init({log:mockLog, settings:{},storage:storage}); + // flows.load().then(function() { + // flows.startFlows(); + // }); + // }); + // + // it('passes status to flows that use the originating global config', function(done) { + // var originalConfig = [ + // {id:"configNode",type:"test"}, + // {id:"t1",type:"tab"}, + // {id:"t1-1",x:10,y:10,z:"t1",type:"test",config:"configNode",wires:[]}, + // {id:"t2",type:"tab"}, + // {id:"t2-1",x:10,y:10,z:"t2",type:"test",wires:[]}, + // {id:"t3",type:"tab"}, + // {id:"t3-1",x:10,y:10,z:"t3",type:"test",config:"configNode",wires:[]} + // ]; + // storage.getFlows = function() { + // return when.resolve({flows:originalConfig}); + // } + // + // events.once('nodes-started',function() { + // flows.handleStatus(originalConfig[0],"message"); + // try { + // flowCreate.flows['t1'].handleStatus.called.should.be.true(); + // flowCreate.flows['t2'].handleStatus.called.should.be.false(); + // flowCreate.flows['t3'].handleStatus.called.should.be.true(); + // done(); + // } catch(err) { + // done(err); + // } + // }); + // + // flows.init({log:mockLog, settings:{},storage:storage}); + // flows.load().then(function() { + // flows.startFlows(); + // }); + // }); + // }); + + describe('#checkTypeInUse', function() { + + before(function() { + sinon.stub(typeRegistry,"getNodeInfo",function(id) { + if (id === 'unused-module') { + return {types:['one','two','three']} + } else { + return {types:['one','test','three']} + } + }); + }); + + after(function() { + typeRegistry.getNodeInfo.restore(); + }); + + it('returns cleanly if type not is use', function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1",type:"tab"} + ]; + flows.init({log:mockLog, settings:{},storage:storage}); + flows.setFlows(originalConfig).then(function() { + flows.checkTypeInUse("unused-module"); + done(); + }); + }); + it('throws error if type is in use', function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1",type:"tab"} + ]; + flows.init({log:mockLog, settings:{},storage:storage}); + flows.setFlows(originalConfig).then(function() { + /*jshint immed: false */ + try { + flows.checkTypeInUse("used-module"); + done("type_in_use error not thrown"); + } catch(err) { + err.code.should.eql("type_in_use"); + done(); + } + }); + }); + }); + + describe('#addFlow', function() { + it("rejects duplicate node id",function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1",type:"tab"} + ]; + storage.getFlows = function() { + return when.resolve({flows:originalConfig}); + } + flows.init({log:mockLog, settings:{},storage:storage}); + flows.load().then(function() { + flows.addFlow({ + label:'new flow', + nodes:[ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]} + ] + }).then(function() { + done(new Error('failed to reject duplicate node id')); + }).catch(function(err) { + done(); + }) + }); + + }); + + it("addFlow",function(done) { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1",type:"tab"} + ]; + storage.getFlows = function() { + return when.resolve({flows:originalConfig}); + } + storage.setFlows = function() { + return when.resolve(); + } + flows.init({log:mockLog, settings:{},storage:storage}); + flows.load().then(function() { + return flows.startFlows(); + }).then(function() { + flows.addFlow({ + label:'new flow', + nodes:[ + {id:"t2-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t2-2",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t2-3",z:"t1",type:"test"} + ] + }).then(function(id) { + flows.getFlows().flows.should.have.lengthOf(6); + var createdFlows = Object.keys(flowCreate.flows); + createdFlows.should.have.lengthOf(3); + createdFlows[2].should.eql(id); + done(); + }).catch(function(err) { + done(err); + }) + }); + + }); + }) + describe('#updateFlow', function() { + it.skip("updateFlow"); + }) + describe('#removeFlow', function() { + it.skip("removeFlow"); + }) + describe('#disableFlow', function() { + it.skip("disableFlow"); + }) + describe('#enableFlow', function() { + it.skip("enableFlow"); + }) +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/nodes/flows/util_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/nodes/flows/util_spec.js new file mode 100644 index 0000000..ac8efef --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/nodes/flows/util_spec.js @@ -0,0 +1,771 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); +var when = require("when"); +var clone = require("clone"); +var NR_TEST_UTILS = require("nr-test-utils"); +var flowUtil = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/flows/util"); +var typeRegistry = NR_TEST_UTILS.require("@node-red/registry"); +var redUtil = NR_TEST_UTILS.require("@node-red/util").util; + +describe('flows/util', function() { + var getType; + + before(function() { + getType = sinon.stub(typeRegistry,"get",function(type) { + return type!=='missing'; + }); + }); + after(function() { + getType.restore(); + }); + + describe('#mapEnvVarProperties',function() { + before(function() { + process.env.foo1 = "bar1"; + process.env.foo2 = "bar2"; + process.env.foo3 = "bar3"; + }) + after(function() { + delete process.env.foo1; + delete process.env.foo2; + delete process.env.foo3; + }) + it('handles ENV substitutions in an object - $()', function() { + var foo = {a:"$(foo1)",b:"$(foo2)",c:{d:"$(foo3)"}}; + for (var p in foo) { + if (foo.hasOwnProperty(p)) { + flowUtil.mapEnvVarProperties(foo,p,{getSetting: p => process.env[p]}); + } + } + foo.should.eql({ a: 'bar1', b: 'bar2', c: { d: 'bar3' } } ); + }); + it('handles ENV substitutions in an object - ${}', function() { + var foo = {a:"${foo1}",b:"${foo2}",c:{d:"${foo3}"}}; + for (var p in foo) { + if (foo.hasOwnProperty(p)) { + flowUtil.mapEnvVarProperties(foo,p,{getSetting: p => process.env[p]}); + } + } + foo.should.eql({ a: 'bar1', b: 'bar2', c: { d: 'bar3' } } ); + }); + + it('gets ENV from parent flow', function() { + var foo = {a:"$(unknown)",b:"$(foo2)",c:{d:"$(foo3)"}}; + for (var p in foo) { + if (foo.hasOwnProperty(p)) { + flowUtil.mapEnvVarProperties(foo,p,{ + getSetting: name => name[0]==='f'?name.toUpperCase():undefined + }); + } + } + foo.should.eql({ a: '$(unknown)', b: 'FOO2', c: { d: 'FOO3' } } ); + }); + }); + describe('#getEnvVar',function() { + before(function() { + process.env.foo1 = "bar1"; + }) + after(function() { + delete process.env.foo1; + }) + it('returns a known env var', function() { + flowUtil.init({settings:{}}); + flowUtil.getEnvVar("foo1").should.equal("bar1") + }) + it('returns undefined for an unknown env var', function() { + flowUtil.init({settings:{}}); + (flowUtil.getEnvVar("foo2") === undefined).should.be.true() + }) + it('returns undefined for an excluded env var', function() { + flowUtil.init({settings:{envVarExcludes:['foo1']}}); + (flowUtil.getEnvVar("foo1") === undefined).should.be.true() + }) + + }); + + describe('#diffNodes',function() { + it('handles a null old node', function() { + flowUtil.diffNodes(null,{}).should.be.true(); + }); + it('ignores x/y changes', function() { + flowUtil.diffNodes({x:10,y:10},{x:20,y:10}).should.be.false(); + flowUtil.diffNodes({x:10,y:10},{x:10,y:20}).should.be.false(); + }); + it('ignores wiring changes', function() { + flowUtil.diffNodes({wires:[]},{wires:[1,2,3]}).should.be.false(); + }); + it('spots existing property change - string', function() { + flowUtil.diffNodes({a:"foo"},{a:"bar"}).should.be.true(); + }); + it('spots existing property change - number', function() { + flowUtil.diffNodes({a:0},{a:1}).should.be.true(); + }); + it('spots existing property change - boolean', function() { + flowUtil.diffNodes({a:true},{a:false}).should.be.true(); + }); + it('spots existing property change - truthy', function() { + flowUtil.diffNodes({a:true},{a:1}).should.be.true(); + }); + it('spots existing property change - falsey', function() { + flowUtil.diffNodes({a:false},{a:0}).should.be.true(); + }); + it('spots existing property change - array', function() { + flowUtil.diffNodes({a:[0,1,2]},{a:[0,2,3]}).should.be.true(); + }); + it('spots existing property change - object', function() { + flowUtil.diffNodes({a:{a:[0,1,2]}},{a:{a:[0,2,3]}}).should.be.true(); + flowUtil.diffNodes({a:{a:[0,1,2]}},{a:{b:[0,1,2]}}).should.be.true(); + }); + it('spots added property', function() { + flowUtil.diffNodes({a:"foo"},{a:"foo",b:"bar"}).should.be.true(); + }); + it('spots removed property', function() { + flowUtil.diffNodes({a:"foo",b:"bar"},{a:"foo"}).should.be.true(); + }); + + + }); + + describe('#parseConfig',function() { + + it('parses a single-tab flow', function() { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t1",type:"tab"} + ]; + var parsedConfig = flowUtil.parseConfig(originalConfig); + var expectedConfig = {"allNodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]},"t1":{"id":"t1","type":"tab"}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]}}}},"missingTypes":[]}; + parsedConfig.should.eql(expectedConfig); + }); + + it('parses a single-tab flow with global config node', function() { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",foo:"cn", wires:[]}, + {id:"cn",type:"test"}, + {id:"t1",type:"tab"} + ]; + var parsedConfig = flowUtil.parseConfig(originalConfig); + var expectedConfig = {"allNodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]},"cn":{"id":"cn","type":"test"},"t1":{"id":"t1","type":"tab"}},"subflows":{},"configs":{"cn":{"id":"cn","type":"test","_users":["t1-1"]}},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]}}}},"missingTypes":[]}; + parsedConfig.should.eql(expectedConfig); + }); + + it('parses a multi-tab flow', function() { + var originalConfig = [ + {id:"t1",type:"tab"}, + {id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]}, + {id:"t2",type:"tab"}, + {id:"t2-1",x:10,y:10,z:"t2",type:"test",wires:[]} + ]; + var parsedConfig = flowUtil.parseConfig(originalConfig); + var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]},"t2":{"id":"t2","type":"tab"},"t2-1":{"id":"t2-1","x":10,"y":10,"z":"t2","type":"test","wires":[]}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]}}},"t2":{"id":"t2","type":"tab","subflows":{},"configs":{},"nodes":{"t2-1":{"id":"t2-1","x":10,"y":10,"z":"t2","type":"test","wires":[]}}}},"missingTypes":[]}; + parsedConfig.should.eql(expectedConfig); + }); + + it('parses a subflow flow', function() { + var originalConfig = [ + {id:"t1",type:"tab"}, + {id:"t1-1",x:10,y:10,z:"t1",type:"subflow:sf1",wires:[]}, + {id:"sf1",type:"subflow"}, + {id:"sf1-1",x:10,y:10,z:"sf1",type:"test",wires:[]} + ]; + var parsedConfig = flowUtil.parseConfig(originalConfig); + var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"subflow:sf1","wires":[]},"sf1":{"id":"sf1","type":"subflow"},"sf1-1":{"id":"sf1-1","x":10,"y":10,"z":"sf1","type":"test","wires":[]}},"subflows":{"sf1":{"id":"sf1","type":"subflow","configs":{},"nodes":{"sf1-1":{"id":"sf1-1","x":10,"y":10,"z":"sf1","type":"test","wires":[]}},"instances":[{"id":"t1-1","x":10,"y":10,"z":"t1","type":"subflow:sf1","wires":[],"subflow":"sf1"}]}},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"subflow:sf1","wires":[],"subflow":"sf1"}}}},"missingTypes":[]}; + parsedConfig.should.eql(expectedConfig); + }); + + it('parses a flow with a missing type', function() { + var originalConfig = [ + {id:"t1",type:"tab"}, + {id:"t1-1",x:10,y:10,z:"t1",type:"sf1",wires:[]}, + {id:"t1-2",x:10,y:10,z:"t1",type:"missing",wires:[]}, + ]; + var parsedConfig = flowUtil.parseConfig(originalConfig); + parsedConfig.missingTypes.should.eql(['missing']); + var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"sf1","wires":[]},"t1-2":{"id":"t1-2","x":10,"y":10,"z":"t1","type":"missing","wires":[]}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"sf1","wires":[]},'t1-2': { id: 't1-2', x: 10, y: 10, z: 't1', type: 'missing', wires: [] }}}},"missingTypes":["missing"]}; + redUtil.compareObjects(parsedConfig,expectedConfig).should.be.true(); + }); + + it('parses a flow with a missing flow', function() { + var originalConfig = [ + {id:"t1-1",x:10,y:10,z:"t1",type:"test",foo:"cn", wires:[]}, + {id:"cn",type:"test"}, + ]; + var parsedConfig = flowUtil.parseConfig(originalConfig); + var expectedConfig = {"allNodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]},"cn":{"id":"cn","type":"test"}},"subflows":{},"configs":{"cn":{"id":"cn","type":"test","_users":["t1-1"]}},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]}}}},"missingTypes":[]}; + parsedConfig.should.eql(expectedConfig); + }); + + + }); + + describe('#diffConfigs', function() { + + it('handles an identical configuration', function() { + var config = [{id:"123",type:"test",foo:"a",wires:[]}]; + + var originalConfig = flowUtil.parseConfig(clone(config)); + var changedConfig = flowUtil.parseConfig(clone(config)); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + + diffResult.added.should.have.length(0); + diffResult.changed.should.have.length(0); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.should.have.length(0); + }); + + it('identifies nodes with changed properties, including downstream linked', function() { + var config = [{id:"1",type:"test",foo:"a",wires:[]},{id:"2",type:"test",bar:"b",wires:[[1]]},{id:"3",type:"test",foo:"a",wires:[]}]; + var newConfig = clone(config); + newConfig[0].foo = "b"; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.should.eql(["1"]); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.should.eql(["2"]); + + }); + it('identifies nodes with changed properties, including upstream linked', function() { + var config = [{id:"1",type:"test",foo:"a",wires:[]},{id:"2",type:"test",bar:"b",wires:[["1"]]},{id:"3",type:"test",foo:"a",wires:[]}]; + var newConfig = clone(config); + newConfig[1].bar = "c"; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.should.eql(["2"]); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.should.eql(["1"]); + }); + + it('identifies nodes with changed credentials, including downstream linked', function() { + var config = [{id:"1",type:"test",wires:[]},{id:"2",type:"test",bar:"b",wires:[["1"]]},{id:"3",type:"test",foo:"a",wires:[]}]; + var newConfig = clone(config); + newConfig[0].credentials = {}; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.should.eql(["1"]); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.should.eql(["2"]); + }); + + it('identifies nodes with changed wiring', function() { + var config = [{id:"1",type:"test",foo:"a",wires:[]},{id:"2",type:"test",bar:"b",wires:[["1"]]},{id:"3",type:"test",foo:"a",wires:[]}]; + var newConfig = clone(config); + newConfig[1].wires[0][0] = "3"; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.should.have.length(0); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.eql(["2"]); + diffResult.linked.sort().should.eql(["1","3"]); + }); + + it('identifies nodes with changed wiring - second connection added', function() { + var config = [{id:"1",type:"test",foo:"a",wires:[]},{id:"2",type:"test",bar:"b",wires:[["1"]]},{id:"3",type:"test",foo:"a",wires:[]}]; + var newConfig = clone(config); + newConfig[1].wires[0].push("1"); + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.should.have.length(0); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.eql(["2"]); + diffResult.linked.sort().should.eql(["1"]); + }); + + it('identifies nodes with changed wiring - node connected', function() { + var config = [{id:"1",type:"test",foo:"a",wires:[["2"]]},{id:"2",type:"test",bar:"b",wires:[[]]},{id:"3",type:"test",foo:"a",wires:[]}]; + var newConfig = clone(config); + newConfig[1].wires.push("3"); + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.should.have.length(0); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.eql(["2"]); + diffResult.linked.sort().should.eql(["1","3"]); + }); + + it('identifies new nodes', function() { + var config = [{id:"1",type:"test",foo:"a",wires:[]},{id:"3",type:"test",foo:"a",wires:[]}]; + var newConfig = clone(config); + newConfig.push({id:"2",type:"test",bar:"b",wires:[["1"]]}); + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.eql(["2"]); + diffResult.changed.should.have.length(0); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.sort().should.eql(["1"]); + }); + + it('identifies deleted nodes', function() { + var config = [{id:"1",type:"test",foo:"a",wires:[["2"]]},{id:"2",type:"test",bar:"b",wires:[["3"]]},{id:"3",type:"test",foo:"a",wires:[]}]; + var newConfig = clone(config); + newConfig.splice(1,1); + newConfig[0].wires = []; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.should.have.length(0); + diffResult.removed.should.eql(["2"]); + diffResult.rewired.should.eql(["1"]); + diffResult.linked.sort().should.eql(["3"]); + }); + + it('identifies config nodes changes, node->config', function() { + var config = [ + {id:"1",type:"test",foo:"configNode",wires:[["2"]]}, + {id:"2",type:"test",bar:"b",wires:[["3"]]}, + {id:"3",type:"test",foo:"a",wires:[]}, + {id:"configNode",type:"testConfig"} + ]; + var newConfig = clone(config); + newConfig[3].foo = "bar"; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.sort().should.eql(["1","configNode"]); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.sort().should.eql(["2","3"]); + }); + + it('identifies config nodes changes, node->config->config', function() { + var config = [ + {id:"1",type:"test",foo:"configNode1",wires:[["2"]]}, + {id:"2",type:"test",bar:"b",wires:[["3"]]}, + {id:"3",type:"test",foo:"a",wires:[]}, + {id:"configNode1",foo:"configNode2",type:"testConfig"}, + {id:"configNode2",type:"testConfig"} + ]; + var newConfig = clone(config); + newConfig[4].foo = "bar"; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.sort().should.eql(["1","configNode1","configNode2"]); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.sort().should.eql(["2","3"]); + }); + + it('marks a parent subflow as changed for an internal property change', function() { + var config = [ + {id:"1",type:"test",wires:[["2"]]}, + {id:"2",type:"subflow:sf1",wires:[["3"]]}, + {id:"3",type:"test",wires:[]}, + {id:"sf1",type:"subflow"}, + {id:"sf1-1",z:"sf1",type:"test",foo:"a",wires:[]}, + {id:"4",type:"subflow:sf1",wires:[]} + ]; + + var newConfig = clone(config); + newConfig[4].foo = "b"; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.sort().should.eql(['2', '4', 'sf1']); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.sort().should.eql(["1","3"]); + + + }); + + it('marks a parent subflow as changed for an internal wiring change', function() { + var config = [ + {id:"1",type:"test",wires:[["2"]]}, + {id:"2",type:"subflow:sf1",wires:[["3"]]}, + {id:"3",type:"test",wires:[]}, + {id:"sf1",type:"subflow"}, + {id:"sf1-1",z:"sf1",type:"test",wires:[]}, + {id:"sf1-2",z:"sf1",type:"test",wires:[]} + ]; + + var newConfig = clone(config); + newConfig[4].wires = [["sf1-2"]]; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.sort().should.eql(['2', 'sf1']); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.sort().should.eql(["1","3"]); + }); + + it('marks a parent subflow as changed for an internal node add', function() { + var config = [ + {id:"1",type:"test",wires:[["2"]]}, + {id:"2",type:"subflow:sf1",wires:[["3"]]}, + {id:"3",type:"test",wires:[]}, + {id:"sf1",type:"subflow"}, + {id:"sf1-1",z:"sf1",type:"test",wires:[]}, + {id:"sf1-2",z:"sf1",type:"test",wires:[]} + ]; + + var newConfig = clone(config); + newConfig.push({id:"sf1-3",z:"sf1",type:"test",wires:[]}); + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.sort().should.eql(['2', 'sf1']); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.sort().should.eql(["1","3"]); + + }); + + it('marks a parent subflow as changed for an internal node delete', function() { + var config = [ + {id:"1",type:"test",wires:[["2"]]}, + {id:"2",type:"subflow:sf1",wires:[["3"]]}, + {id:"3",type:"test",wires:[]}, + {id:"sf1",type:"subflow"}, + {id:"sf1-1",z:"sf1",type:"test",wires:[]}, + {id:"sf1-2",z:"sf1",type:"test",wires:[]} + ]; + + var newConfig = clone(config); + newConfig.splice(5,1); + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.sort().should.eql(['2', 'sf1']); + diffResult.removed.should.have.length(1); + diffResult.removed.sort().should.eql(['sf1-2']); + diffResult.rewired.should.have.length(0); + diffResult.linked.sort().should.eql(["1","3"]); + + }); + + it('marks a parent subflow as changed for an internal subflow wiring change - input removed', function() { + var config = [ + {id:"1",type:"test",wires:[["2"]]}, + {id:"2",type:"subflow:sf1",wires:[["3"]]}, + {id:"3",type:"test",wires:[]}, + {id:"sf1",type:"subflow","in": [{"wires": [{"id": "sf1-1"}]}],"out": [{"wires": [{"id": "sf1-2","port": 0}]}]}, + {id:"sf1-1",z:"sf1",type:"test",wires:[]}, + {id:"sf1-2",z:"sf1",type:"test",wires:[]} + ]; + + var newConfig = clone(config); + newConfig[3].in[0].wires = []; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.sort().should.eql(['2', 'sf1']); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.sort().should.eql(["1","3"]); + }); + + it('marks a parent subflow as changed for an internal subflow wiring change - input added', function() { + var config = [ + {id:"1",type:"test",wires:[["2"]]}, + {id:"2",type:"subflow:sf1",wires:[["3"]]}, + {id:"3",type:"test",wires:[]}, + {id:"sf1",type:"subflow","in": [{"wires": [{"id": "sf1-1"}]}],"out": [{"wires": [{"id": "sf1-2","port": 0}]}]}, + {id:"sf1-1",z:"sf1",type:"test",wires:[]}, + {id:"sf1-2",z:"sf1",type:"test",wires:[]} + ]; + + var newConfig = clone(config); + newConfig[3].in[0].wires.push({"id":"sf1-2"}); + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.sort().should.eql(['2', 'sf1']); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.sort().should.eql(["1","3"]); + }); + + it('marks a parent subflow as changed for an internal subflow wiring change - output added', function() { + var config = [ + {id:"1",type:"test",wires:[["2"]]}, + {id:"2",type:"subflow:sf1",wires:[["3"]]}, + {id:"3",type:"test",wires:[]}, + {id:"sf1",type:"subflow","in": [{"wires": [{"id": "sf1-1"}]}],"out": [{"wires": [{"id": "sf1-2","port": 0}]}]}, + {id:"sf1-1",z:"sf1",type:"test",wires:[]}, + {id:"sf1-2",z:"sf1",type:"test",wires:[]} + ]; + + var newConfig = clone(config); + newConfig[3].out[0].wires.push({"id":"sf1-2","port":0}); + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.sort().should.eql(['2', 'sf1']); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.sort().should.eql(["1","3"]); + }); + + it('marks a parent subflow as changed for an internal subflow wiring change - output removed', function() { + var config = [ + {id:"1",type:"test",wires:[["2"]]}, + {id:"2",type:"subflow:sf1",wires:[["3"]]}, + {id:"3",type:"test",wires:[]}, + {id:"sf1",type:"subflow","in": [{"wires": [{"id": "sf1-1"}]}],"out": [{"wires": [{"id": "sf1-2","port": 0}]}]}, + {id:"sf1-1",z:"sf1",type:"test",wires:[]}, + {id:"sf1-2",z:"sf1",type:"test",wires:[]} + ]; + + var newConfig = clone(config); + newConfig[3].out[0].wires = []; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.sort().should.eql(['2', 'sf1']); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.sort().should.eql(["1","3"]); + }); + + it('marks a parent subflow as changed for a global config node change', function() { + var config = [ + {id:"1",type:"test",wires:[["2"]]}, + {id:"2",type:"subflow:sf1",wires:[["3"]]}, + {id:"3",type:"test",wires:[]}, + {id:"sf1",type:"subflow"}, + {id:"sf1-1",z:"sf1",prop:"configNode",type:"test",wires:[]}, + {id:"sf1-2",z:"sf1",type:"test",wires:[]}, + {id:"configNode",a:"foo",type:"test",wires:[]} + ]; + + var newConfig = clone(config); + newConfig[6].a = "bar"; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.sort().should.eql(['2', "configNode", 'sf1']); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.sort().should.eql(["1","3"]); + }); + + it('marks a parent subflow as changed for an internal subflow instance change', function() { + var config = [ + {id:"1",type:"test",wires:[["2"]]}, + {id:"2",type:"subflow:sf1",wires:[["3"]]}, + {id:"3",type:"test",wires:[]}, + {id:"sf1",type:"subflow"}, + {id:"sf2",type:"subflow"}, + {id:"sf1-1",z:"sf1",type:"test",wires:[]}, + {id:"sf1-2",z:"sf1",type:"subflow:sf2",wires:[]}, + {id:"sf2-1",z:"sf2",type:"test",wires:[]}, + {id:"sf2-2",z:"sf2",type:"test",wires:[]}, + ]; + + var newConfig = clone(config); + newConfig[8].a = "bar"; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.sort().should.eql(['2', 'sf1', 'sf2']); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + diffResult.linked.sort().should.eql(["1","3"]); + }); + + + it('ignores tab changes that are immaterial', function() { + var config = [{id:"1",type:"tab",label:"fred"},{id:"2",type:"test",bar:"b",wires:[["1"]],z:"1"}]; + var newConfig = clone(config); + newConfig[0].label = "barney"; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.should.have.length(0); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + }); + + + it('marks a deleted tab as removed', function() { + var config = [{id:"f1",type:"tab",label:"fred"},{id:"n1",type:"test",bar:"b",wires:[["1"]],z:"f1"}, + {id:"f2",type:"tab",label:"fred"},{id:"n2",type:"test",bar:"b",wires:[["1"]],z:"f2"}]; + var newConfig = clone(config); + newConfig = newConfig.slice(0,2); + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + diffResult.added.should.have.length(0); + diffResult.changed.should.have.length(0); + diffResult.removed.sort().should.eql(['f2', 'n2']); + diffResult.rewired.should.have.length(0); + }); + + it('marks all nodes as added when tab state changes disabled to enabled', function() { + var config = [{id:"1",type:"tab",disabled:true,label:"fred"},{id:"2",type:"test",bar:"b",wires:[["1"]],z:"1"},{id:"3",type:"test"}]; + var newConfig = clone(config); + newConfig[0].disabled = false; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + + diffResult.added.should.have.length(2); + diffResult.added.sort().should.eql(["1","2"]); + diffResult.changed.should.have.length(0); + diffResult.removed.should.have.length(0); + diffResult.rewired.should.have.length(0); + }); + it('marks all nodes as removed when tab state changes enabled to disabled', function() { + var config = [{id:"1",type:"tab",disabled:false,label:"fred"},{id:"2",type:"test",bar:"b",wires:[["1"]],z:"1"},{id:"3",type:"test"}]; + var newConfig = clone(config); + newConfig[0].disabled = true; + + var originalConfig = flowUtil.parseConfig(config); + var changedConfig = flowUtil.parseConfig(newConfig); + + originalConfig.missingTypes.should.have.length(0); + + var diffResult = flowUtil.diffConfigs(originalConfig,changedConfig); + + diffResult.added.should.have.length(0); + diffResult.changed.should.have.length(0); + diffResult.removed.should.have.length(2); + diffResult.removed.sort().should.eql(["1","2"]); + diffResult.rewired.should.have.length(0); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/nodes/index_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/nodes/index_spec.js new file mode 100644 index 0000000..6695819 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/nodes/index_spec.js @@ -0,0 +1,405 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var fs = require('fs-extra'); +var path = require('path'); +var when = require("when"); +var sinon = require('sinon'); +var inherits = require("util").inherits; + +var NR_TEST_UTILS = require("nr-test-utils"); +var index = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/index"); +var flows = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/flows"); +var registry = NR_TEST_UTILS.require("@node-red/registry") +var Node = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/Node"); + +describe("red/nodes/index", function() { + before(function() { + sinon.stub(index,"startFlows"); + process.env.NODE_RED_HOME = NR_TEST_UTILS.resolve("node-red"); + process.env.foo="bar"; + }); + after(function() { + index.startFlows.restore(); + delete process.env.NODE_RED_HOME; + delete process.env.foo; + }); + + afterEach(function() { + index.clearRegistry(); + }); + + var testFlows = [{"type":"test","id":"tab1","label":"Sheet 1"}]; + var testCredentials = {"tab1":{"b":1, "c":"2", "d":"$(foo)"}}; + var storage = { + getFlows: function() { + return when({red:123,flows:testFlows,credentials:testCredentials}); + }, + saveFlows: function(conf) { + should.deepEqual(testFlows, conf.flows); + return when.resolve(123); + } + }; + + var settings = { + available: function() { return false }, + get: function() { return false } + }; + + var EventEmitter = require('events').EventEmitter; + var runtime = { + settings: settings, + storage: storage, + log: {debug:function() {}, warn:function() {}}, + events: new EventEmitter() + }; + + function TestNode(n) { + this._flow = {getSetting: p => process.env[p]}; + index.createNode(this, n); + this.on("log", function() { + // do nothing + }); + } + + it('nodes are initialised with credentials',function(done) { + index.init(runtime); + index.registerType('test-node-set','test', TestNode); + index.loadFlows().then(function() { + var testnode = new TestNode({id:'tab1',type:'test',name:'barney'}); + testnode.credentials.should.have.property('b',1); + testnode.credentials.should.have.property('c',"2"); + testnode.credentials.should.have.property('d',"bar"); + done(); + }).catch(function(err) { + done(err); + }); + }); + + it('flows should be initialised',function(done) { + index.init(runtime); + index.loadFlows().then(function() { + // console.log(testFlows); + // console.log(index.getFlows()); + should.deepEqual(testFlows, index.getFlows().flows); + done(); + }).catch(function(err) { + done(err); + }); + + }); + describe("registerType", function() { + describe("logs deprecated usage", function() { + before(function() { + sinon.stub(registry,"registerType"); + }); + after(function() { + registry.registerType.restore(); + }); + it("called without node-set name", function() { + var runtime = { + settings: settings, + storage: storage, + log: {debug:function() {}, warn:sinon.spy()}, + events: new EventEmitter() + } + index.init(runtime); + + index.registerType(/*'test-node-set',*/'test', TestNode, {}); + runtime.log.warn.called.should.be.true(); + registry.registerType.called.should.be.true(); + registry.registerType.firstCall.args[0].should.eql(''); + registry.registerType.firstCall.args[1].should.eql('test'); + registry.registerType.firstCall.args[2].should.eql(TestNode); + }); + }); + describe("extends constructor with Node constructor", function() { + var TestNodeConstructor; + before(function() { + sinon.stub(registry,"registerType"); + }); + after(function() { + registry.registerType.restore(); + }); + beforeEach(function() { + TestNodeConstructor = function TestNodeConstructor() {}; + var runtime = { + settings: settings, + storage: storage, + log: {debug:function() {}, warn:sinon.spy()}, + events: new EventEmitter() + } + index.init(runtime); + }) + it('extends a constructor with the Node constructor', function() { + TestNodeConstructor.prototype.should.not.be.an.instanceOf(Node); + index.registerType('node-set','node-type',TestNodeConstructor); + TestNodeConstructor.prototype.should.be.an.instanceOf(Node); + }); + it('does not override a constructor prototype', function() { + function Foo(){}; + inherits(TestNodeConstructor,Foo); + TestNodeConstructor.prototype.should.be.an.instanceOf(Foo); + TestNodeConstructor.prototype.should.not.be.an.instanceOf(Node); + + index.registerType('node-set','node-type',TestNodeConstructor); + + TestNodeConstructor.prototype.should.be.an.instanceOf(Node); + TestNodeConstructor.prototype.should.be.an.instanceOf(Foo); + + index.registerType('node-set','node-type2',TestNodeConstructor); + TestNodeConstructor.prototype.should.be.an.instanceOf(Node); + TestNodeConstructor.prototype.should.be.an.instanceOf(Foo); + }); + }); + describe("register credentials definition", function() { + var http = require('http'); + var express = require('express'); + var app = express(); + var runtime = NR_TEST_UTILS.require("@node-red/runtime"); + var credentials = NR_TEST_UTILS.require("@node-red/runtime/lib/nodes/credentials"); + var localfilesystem = NR_TEST_UTILS.require("@node-red/runtime/lib/storage/localfilesystem"); + var log = NR_TEST_UTILS.require("@node-red/util").log; + var RED = NR_TEST_UTILS.require("node-red/lib/red.js"); + + var userDir = path.join(__dirname,".testUserHome"); + before(function(done) { + sinon.stub(log,"log",function(){}); + fs.remove(userDir,function(err) { + fs.mkdir(userDir,function() { + sinon.stub(index, 'load', function() { + return when.promise(function(resolve,reject){ + resolve([]); + }); + }); + sinon.stub(localfilesystem, 'getCredentials', function() { + return when.promise(function(resolve,reject) { + resolve({"tab1":{"b":1,"c":2}}); + }); + }) ; + RED.init(http.createServer(function(req,res){app(req,res)}), + {userDir: userDir}); + runtime.start().then(function () { + done(); + }); + }); + }); + }); + + after(function(done) { + fs.remove(userDir,function() { + runtime.stop().then(function() { + index.load.restore(); + localfilesystem.getCredentials.restore(); + log.log.restore(); + done(); + }); + }); + }); + + it('definition defined',function() { + index.registerType('test-node-set','test', TestNode, { + credentials: { + foo: {type:"test"} + } + }); + var testnode = new TestNode({id:'tab1',type:'test',name:'barney', '_alias':'tab1'}); + index.getCredentialDefinition("test").should.have.property('foo'); + }); + }); + + describe("register settings definition", function() { + beforeEach(function() { + sinon.stub(registry,"registerType"); + }) + afterEach(function() { + registry.registerType.restore(); + }) + it('registers valid settings',function() { + var runtime = { + settings: settings, + storage: storage, + log: {debug:function() {}, warn:function() {}}, + events: new EventEmitter() + } + runtime.settings.registerNodeSettings = sinon.spy(); + index.init(runtime); + + index.registerType('test-node-set','test', TestNode, { + settings: { + testOne: {} + } + }); + runtime.settings.registerNodeSettings.called.should.be.true(); + runtime.settings.registerNodeSettings.firstCall.args[0].should.eql('test'); + runtime.settings.registerNodeSettings.firstCall.args[1].should.eql({testOne: {}}); + }); + it('logs invalid settings',function() { + var runtime = { + settings: settings, + storage: storage, + log: {debug:function() {}, warn:sinon.spy()}, + events: new EventEmitter() + } + runtime.settings.registerNodeSettings = function() { throw new Error("pass");} + index.init(runtime); + + index.registerType('test-node-set','test', TestNode, { + settings: { + testOne: {} + } + }); + runtime.log.warn.called.should.be.true(); + }); + }); + }); + + describe('allows nodes to be added/removed/enabled/disabled from the registry', function() { + var randomNodeInfo = {id:"5678",types:["random"]}; + + beforeEach(function() { + sinon.stub(registry,"getNodeInfo",function(id) { + if (id == "test") { + return {id:"1234",types:["test"]}; + } else if (id == "doesnotexist") { + return null; + } else { + return randomNodeInfo; + } + }); + sinon.stub(registry,"disableNode",function(id) { + return when.resolve(randomNodeInfo); + }); + }); + afterEach(function() { + registry.getNodeInfo.restore(); + registry.disableNode.restore(); + }); + + it('allows an unused node type to be disabled',function(done) { + index.init(runtime); + index.registerType('test-node-set','test', TestNode); + index.loadFlows().then(function() { + return index.disableNode("5678").then(function(info) { + registry.disableNode.calledOnce.should.be.true(); + registry.disableNode.calledWith("5678").should.be.true(); + info.should.eql(randomNodeInfo); + done(); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('prevents disabling a node type that is in use',function(done) { + index.init(runtime); + index.registerType('test-node-set','test', TestNode); + index.loadFlows().then(function() { + /*jshint immed: false */ + (function() { + index.disabledNode("test"); + }).should.throw(); + + done(); + }).catch(function(err) { + done(err); + }); + }); + + it('prevents disabling a node type that is unknown',function(done) { + index.init(runtime); + index.registerType('test-node-set','test', TestNode); + index.loadFlows().then(function() { + /*jshint immed: false */ + (function() { + index.disableNode("doesnotexist"); + }).should.throw(); + + done(); + }).catch(function(err) { + done(err); + }); + }); + }); + + describe('allows modules to be removed from the registry', function() { + var randomNodeInfo = {id:"5678",types:["random"]}; + var randomModuleInfo = { + name:"random", + nodes: [randomNodeInfo] + }; + + before(function() { + sinon.stub(registry,"getNodeInfo",function(id) { + if (id == "node-red/foo") { + return {id:"1234",types:["test"]}; + } else if (id == "doesnotexist") { + return null; + } else { + return randomNodeInfo; + } + }); + sinon.stub(registry,"getModuleInfo",function(module) { + if (module == "node-red") { + return {nodes:[{name:"foo"}]}; + } else if (module == "doesnotexist") { + return null; + } else { + return randomModuleInfo; + } + }); + sinon.stub(registry,"removeModule",function(id) { + return randomModuleInfo; + }); + }); + after(function() { + registry.getNodeInfo.restore(); + registry.getModuleInfo.restore(); + registry.removeModule.restore(); + }); + + it('prevents removing a module that is in use',function(done) { + index.init(runtime); + index.registerType('test-node-set','test', TestNode); + index.loadFlows().then(function() { + /*jshint immed: false */ + (function() { + index.removeModule("node-red"); + }).should.throw(); + + done(); + }).catch(function(err) { + done(err); + }); + }); + + it('prevents removing a module that is unknown',function(done) { + index.init(runtime); + index.registerType('test-node-set','test', TestNode); + index.loadFlows().then(function() { + /*jshint immed: false */ + (function() { + index.removeModule("doesnotexist"); + }).should.throw(); + + done(); + }).catch(function(err) { + done(err); + }); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/nodes/resources/local/NestedDirectoryNode/NestedNode/icons/arrow-in.png b/packages/connector/test/unit/@node-red/runtime/lib/nodes/resources/local/NestedDirectoryNode/NestedNode/icons/arrow-in.png new file mode 100644 index 0000000..e38f391 Binary files /dev/null and b/packages/connector/test/unit/@node-red/runtime/lib/nodes/resources/local/NestedDirectoryNode/NestedNode/icons/arrow-in.png differ diff --git a/packages/connector/test/unit/@node-red/runtime/lib/settings_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/settings_spec.js new file mode 100644 index 0000000..51c190f --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/settings_spec.js @@ -0,0 +1,333 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +var should = require("should"); + +var NR_TEST_UTILS = require("nr-test-utils"); +var settings = NR_TEST_UTILS.require("@node-red/runtime/lib/settings"); + + +describe("runtime/settings", function() { + + afterEach(function() { + settings.reset(); + }); + + it('wraps the user settings as read-only properties', function() { + var userSettings = { + a: 123, + b: "test", + c: [1,2,3] + } + settings.init(userSettings); + + settings.available().should.be.false(); + + settings.a.should.equal(123); + settings.b.should.equal("test"); + settings.c.should.be.an.Array(); + settings.c.should.have.lengthOf(3); + + settings.get("a").should.equal(123); + settings.get("b").should.equal("test"); + settings.get("c").should.be.an.Array(); + settings.get("c").should.have.lengthOf(3); + + /*jshint immed: false */ + (function() { + settings.a = 456; + }).should.throw(); + + settings.c.push(5); + settings.c.should.be.an.Array(); + settings.c.should.have.lengthOf(4); + + /*jshint immed: false */ + (function() { + settings.set("a",456); + }).should.throw(); + + /*jshint immed: false */ + (function() { + settings.set("a",456); + }).should.throw(); + + /*jshint immed: false */ + (function() { + settings.get("unknown"); + }).should.throw(); + + /*jshint immed: false */ + (function() { + settings.set("unknown",456); + }).should.throw(); + + }); + + it('loads global settings from storage', function(done) { + var userSettings = { + a: 123, + b: "test", + c: [1,2,3] + } + var savedSettings = null; + var saveCount = 0; + var storage = { + getSettings: function() { + return Promise.resolve({globalA:789}); + }, + saveSettings: function(settings) { + saveCount++; + savedSettings = settings; + return Promise.resolve(); + } + } + settings.init(userSettings); + + settings.available().should.be.false(); + + /*jshint immed: false */ + (function() { + settings.get("unknown"); + }).should.throw(); + settings.load(storage).then(function() { + settings.available().should.be.true(); + settings.get("globalA").should.equal(789); + settings.set("globalA","abc").then(function() { + savedSettings.globalA.should.equal("abc"); + saveCount.should.equal(1); + settings.set("globalA","abc").then(function() { + savedSettings.globalA.should.equal("abc"); + // setting to existing value should not trigger save + saveCount.should.equal(1); + done(); + }); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('removes persistent settings when reset', function() { + var userSettings = { + a: 123, + b: "test", + c: [1,2,3] + } + settings.init(userSettings); + + settings.available().should.be.false(); + + settings.should.have.property("a",123); + settings.should.have.property("b","test"); + settings.c.should.be.an.Array(); + settings.c.should.have.lengthOf(3); + + settings.reset(); + + settings.should.not.have.property("a"); + settings.should.not.have.property("d"); + settings.should.not.have.property("c"); + + }); + + it('registers node settings and exports them', function() { + var userSettings = {}; + settings.init(userSettings); + settings.registerNodeSettings("inject", {injectColor:{value:"red", exportable:true}, injectSize:{value:"100", exportable:true}} ); + settings.registerNodeSettings("mqtt", {mqttColor:{value:"purple", exportable:false}, mqttSize:{value:"50", exportable:true}} ); + settings.registerNodeSettings("http request", {httpRequest1:{value:"a1", exportable:true}} ); + settings.registerNodeSettings(" http--request<> ", {httpRequest2:{value:"a2", exportable:true}} ); + settings.registerNodeSettings("_http_request_", {httpRequest3:{value:"a3", exportable:true}} ); + settings.registerNodeSettings("mQtT", {mQtTColor:{value:"purple", exportable:true}} ); + settings.registerNodeSettings("abc123", {abc123:{value:"def456", exportable:true}} ); + settings.registerNodeSettings("noValue", {noValueHasValue:{value:"123", exportable:true}, noValueNoValue:{exportable:true}} ); + + var safeSettings = {}; + settings.exportNodeSettings(safeSettings); + safeSettings.should.have.property("injectColor", "red"); + safeSettings.should.have.property("injectSize", "100"); + safeSettings.should.not.have.property("mqttColor"); + safeSettings.should.have.property("mqttSize", "50"); + safeSettings.should.have.property("httpRequest1", "a1"); + safeSettings.should.have.property("httpRequest2", "a2"); + safeSettings.should.have.property("httpRequest3", "a3"); + safeSettings.should.have.property("mQtTColor", "purple"); + safeSettings.should.have.property("abc123", "def456"); + + safeSettings.should.have.property("noValueHasValue", "123"); + safeSettings.should.not.have.property("noValueNoValue"); + }); + + it('prohibits registering the property whose name do not start with type name', function() { + var userSettings = {}; + settings.init(userSettings); + (function() { + settings.registerNodeSettings("inject", {color:{value:"red", exportable:true}} ); + }).should.throw(); + (function() { + settings.registerNodeSettings("_a_b_1_", {ab1Color:{value:"red", exportable:true}} ); + }).should.throw(); + (function() { + settings.registerNodeSettings("AB2", {AB2Color:{value:"red", exportable:true}} ); + }).should.throw(); + (function() { + settings.registerNodeSettings("abcDef", {abcColor:{value:"red", exportable:true}} ); + }).should.throw(); + var safeSettings = {}; + settings.exportNodeSettings(safeSettings); + safeSettings.should.not.have.property("color"); + safeSettings.should.not.have.property("ab1Color", "blue"); + safeSettings.should.not.have.property("AB2Color"); + safeSettings.should.not.have.property("abcColor"); + }); + + it('overwrites node settings with user settings', function() { + var userSettings = { + injectColor: "green", + mqttColor: "yellow", + abColor: [1,2,3] + } + settings.init(userSettings); + settings.registerNodeSettings("inject", {injectColor:{value:"red", exportable:true}} ); + settings.registerNodeSettings("ab", {abColor:{value:"red", exportable:false}} ); + var safeSettings = {}; + settings.exportNodeSettings(safeSettings); + safeSettings.should.have.property("injectColor", "green"); + safeSettings.should.not.have.property("mqttColor"); + safeSettings.should.not.have.property("abColor"); + }); + + it('disables/enables node settings', function() { + var userSettings = {}; + settings.init(userSettings); + + var safeSettings = {}; + settings.registerNodeSettings("inject", {injectColor:{value:"red", exportable:true}} ); + settings.registerNodeSettings("mqtt", {mqttColor:{value:"purple", exportable:true}} ); + settings.registerNodeSettings("http request", {httpRequestColor:{value:"yellow", exportable:true}} ); + settings.exportNodeSettings(safeSettings); + safeSettings.should.have.property("injectColor", "red"); + safeSettings.should.have.property("mqttColor", "purple"); + safeSettings.should.have.property("httpRequestColor", "yellow"); + + safeSettings = {}; + var types = ["inject", "mqtt"]; + settings.disableNodeSettings(types); + settings.exportNodeSettings(safeSettings); + safeSettings.should.not.have.property("injectColor"); + safeSettings.should.not.have.property("mqttColor"); + safeSettings.should.have.property("httpRequestColor", "yellow"); + + safeSettings = {}; + types = ["inject"]; + settings.enableNodeSettings(types); + settings.exportNodeSettings(safeSettings); + safeSettings.should.have.property("injectColor", "red"); + safeSettings.should.not.have.property("mqttColor"); + safeSettings.should.have.property("httpRequestColor", "yellow"); + }); + + + it('delete global setting', function() { + // read-only + var localSettings = {a:1}; + // read-write + var globalSettings = {b:2}; + var storage = { + getSettings: function() { + return Promise.resolve(globalSettings); + }, + saveSettings: function() { + return Promise.resolve(); + } + } + settings.init(localSettings); + return settings.load(storage).then(function() { + settings.get('a').should.eql(1); + settings.get('b').should.eql(2); + return settings.delete('b') + }).then(function() { + should.not.exist(settings.get('b')); + }) + }); + + it('refused to delete local setting', function(done) { + // read-only + var localSettings = {a:1}; + // read-write + var globalSettings = {b:2}; + var storage = { + getSettings: function() { + return Promise.resolve(globalSettings); + } + } + settings.init(localSettings); + settings.load(storage).then(function() { + settings.get('a').should.eql(1); + settings.get('b').should.eql(2); + try { + settings.delete('a'); + return done("Did not throw error"); + } catch(err) { + // expected + } + done(); + }).catch(done) + }); + + + it('get user settings', function() { + var userSettings = { + admin: {a:1} + } + var storage = { + getSettings: function() { + return Promise.resolve({a:1,users:userSettings}); + } + } + settings.init(userSettings); + return settings.load(storage).then(function() { + var result = settings.getUserSettings('admin'); + result.should.eql(userSettings.admin); + // Check it has been cloned + result.should.not.equal(userSettings.admin); + }) + }) + it('set user settings', function() { + var userSettings = { + admin: {a:1} + } + var savedSettings; + var storage = { + getSettings: function() { + return Promise.resolve({c:3,users:userSettings}); + }, + saveSettings: function(s) { + savedSettings = s; + return Promise.resolve(); + } + } + settings.init(userSettings); + return settings.load(storage).then(function() { + return settings.setUserSettings('admin',{b:2}) + }).then(function() { + savedSettings.should.have.property("c",3); + savedSettings.should.have.property('users'); + savedSettings.users.should.eql({admin:{b:2}}) + }) + }) + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/storage/index_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/storage/index_spec.js new file mode 100644 index 0000000..3ede68c --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/storage/index_spec.js @@ -0,0 +1,272 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +var when = require("when"); +var should = require("should"); +var paff = require('path'); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var storage = NR_TEST_UTILS.require("@node-red/runtime/lib/storage/index"); + +describe("red/storage/index", function() { + + it('rejects the promise when settings suggest loading a bad module', function(done) { + + var wrongModule = { + settings:{ + storageModule : "thisaintloading" + } + }; + + storage.init(wrongModule).then( function() { + var one = 1; + var zero = 0; + try { + zero.should.equal(one, "The initialization promise should never get resolved"); + } catch(err) { + done(err); + } + }).catch(function(e) { + done(); //successfully rejected promise + }); + }); + + it('non-string storage module', function(done) { + var initSetsMeToTrue = false; + + var moduleWithBooleanSettingInit = { + init : function() { + initSetsMeToTrue = true; + } + }; + + var setsBooleanModule = { + settings: { + storageModule : moduleWithBooleanSettingInit + } + }; + + storage.init(setsBooleanModule); + initSetsMeToTrue.should.be.true(); + done(); + }); + + it('respects storage interface', function(done) { + var calledFlagGetFlows = false; + var calledFlagGetCredentials = false; + var calledFlagGetAllFlows = false; + var calledInit = false; + var calledFlagGetSettings = false; + var calledFlagGetSessions = false; + + var interfaceCheckerModule = { + init : function (settings) { + settings.should.be.an.Object(); + calledInit = true; + }, + getFlows : function() { + calledFlagGetFlows = true; + return when.resolve([]); + }, + saveFlows : function (flows) { + flows.should.be.an.Array(); + flows.should.have.lengthOf(0); + return when.resolve(""); + }, + getCredentials : function() { + calledFlagGetCredentials = true; + return when.resolve({}); + }, + saveCredentials : function(credentials) { + credentials.should.be.true(); + }, + getSettings : function() { + calledFlagGetSettings = true; + }, + saveSettings : function(settings) { + settings.should.be.true(); + }, + getSessions : function() { + calledFlagGetSessions = true; + }, + saveSessions : function(sessions) { + sessions.should.be.true(); + }, + getAllFlows : function() { + calledFlagGetAllFlows = true; + }, + getFlow : function(fn) { + fn.should.equal("name"); + }, + saveFlow : function(fn, data) { + fn.should.equal("name"); + data.should.be.true(); + }, + getLibraryEntry : function(type, path) { + type.should.be.true(); + path.should.equal("name"); + }, + saveLibraryEntry : function(type, path, meta, body) { + type.should.be.true(); + path.should.equal("name"); + meta.should.be.true(); + body.should.be.true(); + } + }; + + var moduleToLoad = { + settings: { + storageModule : interfaceCheckerModule + } + }; + + var promises = []; + storage.init(moduleToLoad); + promises.push(storage.getFlows()); + promises.push(storage.saveFlows({flows:[],credentials:{}})); + storage.getSettings(); + storage.saveSettings(true); + storage.getSessions(); + storage.saveSessions(true); + storage.getAllFlows(); + storage.getFlow("name"); + storage.saveFlow("name", true); + storage.getLibraryEntry(true, "name"); + storage.saveLibraryEntry(true, "name", true, true); + + when.settle(promises).then(function() { + try { + calledInit.should.be.true(); + calledFlagGetFlows.should.be.true(); + calledFlagGetCredentials.should.be.true(); + calledFlagGetAllFlows.should.be.true(); + done(); + } catch(err) { + done(err); + } + }); + }); + + describe('respects deprecated flow library functions', function() { + + var savePath; + var saveContent; + var saveMeta; + var saveType; + + var interfaceCheckerModule = { + init : function (settings) { + settings.should.be.an.Object(); + }, + getLibraryEntry : function(type, path) { + if (type === "flows") { + if (path === "/" || path === "\\") { + return when.resolve(["a",{fn:"test.json"}]); + } else if (path == "/a" || path == "\\a") { + return when.resolve([{fn:"test2.json"}]); + } else if (path == paff.join("","a","test2.json")) { + return when.resolve("test content"); + } + } + }, + saveLibraryEntry : function(type, path, meta, body) { + saveType = type; + savePath = path; + saveContent = body; + saveMeta = meta; + return when.resolve(); + } + }; + + var moduleToLoad = { + settings: { + storageModule : interfaceCheckerModule + } + }; + before(function() { + storage.init(moduleToLoad); + }); + it('getAllFlows',function(done) { + storage.getAllFlows().then(function (res) { + try { + res.should.eql({ d: { a: { f: ['test2'] } }, f: [ 'test' ] }); + done(); + } catch(err) { + done(err); + } + }); + }); + + it('getFlow',function(done) { + storage.getFlow(paff.join("a","test2.json")).then(function(res) { + try { + res.should.eql("test content"); + done(); + } catch(err) { + done(err); + } + }); + }); + + it ('saveFlow', function (done) { + storage.saveFlow(paff.join("a","test2.json"),"new content").then(function(res) { + try { + savePath.should.eql(paff.join("a","test2.json")); + saveContent.should.eql("new content"); + saveMeta.should.eql({}); + saveType.should.eql("flows"); + done(); + } catch(err) { + done(err); + } + }); + + }); + }); + + describe('handles missing settings/sessions interface', function() { + before(function() { + var interfaceCheckerModule = { + init : function () {} + }; + storage.init({settings:{storageModule: interfaceCheckerModule}}); + }); + + it('defaults missing getSettings',function(done) { + storage.getSettings().then(function(settings) { + should.not.exist(settings); + done(); + }); + }); + it('defaults missing saveSettings',function(done) { + storage.saveSettings({}).then(function() { + done(); + }); + }); + it('defaults missing getSessions',function(done) { + storage.getSessions().then(function(settings) { + should.not.exist(settings); + done(); + }); + }); + it('defaults missing saveSessions',function(done) { + storage.saveSessions({}).then(function() { + done(); + }); + }); + }); + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/index_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/index_spec.js new file mode 100644 index 0000000..acfe3db --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/index_spec.js @@ -0,0 +1,518 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var fs = require('fs-extra'); +var path = require('path'); +var sinon = require('sinon'); +var NR_TEST_UTILS = require("nr-test-utils"); +var process = require("process"); + +var localfilesystem = NR_TEST_UTILS.require("@node-red/runtime/lib/storage/localfilesystem"); +var log = NR_TEST_UTILS.require("@node-red/util").log; + +describe('storage/localfilesystem', function() { + var mockRuntime = { + log:{ + _:function() { return "placeholder message"}, + info: function() { }, + warn: function() { }, + trace: function() {} + } + }; + var userDir = path.join(__dirname,".testUserHome"); + var testFlow = [{"type":"tab","id":"d8be2a6d.2741d8","label":"Sheet 1"}]; + beforeEach(function(done) { + fs.remove(userDir,function(err) { + fs.mkdir(userDir,done); + }); + }); + afterEach(function(done) { + fs.remove(userDir,done); + }); + + it('should initialise the user directory',function(done) { + localfilesystem.init({userDir:userDir}, mockRuntime).then(function() { + fs.existsSync(path.join(userDir,"lib")).should.be.true(); + fs.existsSync(path.join(userDir,"lib",'flows')).should.be.true(); + done(); + }).catch(function(err) { + done(err); + }); + }); + + + it('should set userDir to NRH if .config.json presents',function(done) { + var oldNRH = process.env.NODE_RED_HOME; + process.env.NODE_RED_HOME = path.join(userDir,"NRH"); + fs.mkdirSync(process.env.NODE_RED_HOME); + fs.writeFileSync(path.join(process.env.NODE_RED_HOME,".config.json"),"{}","utf8"); + var settings = {}; + localfilesystem.init(settings, mockRuntime).then(function() { + try { + fs.existsSync(path.join(process.env.NODE_RED_HOME,"lib")).should.be.true(); + fs.existsSync(path.join(process.env.NODE_RED_HOME,"lib",'flows')).should.be.true(); + settings.userDir.should.equal(process.env.NODE_RED_HOME); + done(); + } catch(err) { + done(err); + } finally { + process.env.NODE_RED_HOME = oldNRH; + } + }).catch(function(err) { + done(err); + }); + }); + + it('should set userDir to HOMEPATH/.node-red if .config.json presents',function(done) { + var oldNRH = process.env.NODE_RED_HOME; + process.env.NODE_RED_HOME = path.join(userDir,"NRH"); + var oldHOMEPATH = process.env.HOMEPATH; + process.env.HOMEPATH = path.join(userDir,"HOMEPATH"); + fs.mkdirSync(process.env.HOMEPATH); + fs.mkdirSync(path.join(process.env.HOMEPATH,".node-red")); + fs.writeFileSync(path.join(process.env.HOMEPATH,".node-red",".config.json"),"{}","utf8"); + var settings = {}; + localfilesystem.init(settings, mockRuntime).then(function() { + try { + fs.existsSync(path.join(process.env.HOMEPATH,".node-red","lib")).should.be.true(); + fs.existsSync(path.join(process.env.HOMEPATH,".node-red","lib",'flows')).should.be.true(); + settings.userDir.should.equal(path.join(process.env.HOMEPATH,".node-red")); + done(); + } catch(err) { + done(err); + } finally { + process.env.NODE_RED_HOME = oldNRH; + process.env.NODE_HOMEPATH = oldHOMEPATH; + } + }).catch(function(err) { + done(err); + }); + }); + + it('should set userDir to HOME/.node-red',function(done) { + var oldNRH = process.env.NODE_RED_HOME; + process.env.NODE_RED_HOME = path.join(userDir,"NRH"); + var oldHOME = process.env.HOME; + process.env.HOME = path.join(userDir,"HOME"); + var oldHOMEPATH = process.env.HOMEPATH; + process.env.HOMEPATH = path.join(userDir,"HOMEPATH"); + + fs.mkdirSync(process.env.HOME); + var settings = {}; + localfilesystem.init(settings, mockRuntime).then(function() { + try { + fs.existsSync(path.join(process.env.HOME,".node-red","lib")).should.be.true(); + fs.existsSync(path.join(process.env.HOME,".node-red","lib",'flows')).should.be.true(); + settings.userDir.should.equal(path.join(process.env.HOME,".node-red")); + done(); + } catch(err) { + done(err); + } finally { + process.env.NODE_RED_HOME = oldNRH; + process.env.HOME = oldHOME; + process.env.HOMEPATH = oldHOMEPATH; + } + }).catch(function(err) { + done(err); + }); + }); + + it('should set userDir to USERPROFILE/.node-red',function(done) { + var oldNRH = process.env.NODE_RED_HOME; + process.env.NODE_RED_HOME = path.join(userDir,"NRH"); + var oldHOME = process.env.HOME; + process.env.HOME = ""; + var oldHOMEPATH = process.env.HOMEPATH; + process.env.HOMEPATH = path.join(userDir,"HOMEPATH"); + var oldUSERPROFILE = process.env.USERPROFILE; + process.env.USERPROFILE = path.join(userDir,"USERPROFILE"); + + fs.mkdirSync(process.env.USERPROFILE); + var settings = {}; + localfilesystem.init(settings, mockRuntime).then(function() { + try { + fs.existsSync(path.join(process.env.USERPROFILE,".node-red","lib")).should.be.true(); + fs.existsSync(path.join(process.env.USERPROFILE,".node-red","lib",'flows')).should.be.true(); + settings.userDir.should.equal(path.join(process.env.USERPROFILE,".node-red")); + done(); + } catch(err) { + done(err); + } finally { + process.env.NODE_RED_HOME = oldNRH; + process.env.HOME = oldHOME; + process.env.HOMEPATH = oldHOMEPATH; + process.env.USERPROFILE = oldUSERPROFILE; + } + }).catch(function(err) { + done(err); + }); + }); + + it('should handle missing flow file',function(done) { + localfilesystem.init({userDir:userDir}, mockRuntime).then(function() { + var flowFile = 'flows_'+require('os').hostname()+'.json'; + var flowFilePath = path.join(userDir,flowFile); + fs.existsSync(flowFilePath).should.be.false(); + localfilesystem.getFlows().then(function(flows) { + flows.should.eql([]); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should handle empty flow file, no backup',function(done) { + localfilesystem.init({userDir:userDir}, mockRuntime).then(function() { + var flowFile = 'flows_'+require('os').hostname()+'.json'; + var flowFilePath = path.join(userDir,flowFile); + var flowFileBackupPath = path.join(userDir,"."+flowFile+".backup"); + fs.closeSync(fs.openSync(flowFilePath, 'w')); + fs.existsSync(flowFilePath).should.be.true(); + localfilesystem.getFlows().then(function(flows) { + flows.should.eql([]); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should handle empty flow file, restores backup',function(done) { + localfilesystem.init({userDir:userDir}, mockRuntime).then(function() { + var flowFile = 'flows_'+require('os').hostname()+'.json'; + var flowFilePath = path.join(userDir,flowFile); + var flowFileBackupPath = path.join(userDir,"."+flowFile+".backup"); + fs.closeSync(fs.openSync(flowFilePath, 'w')); + fs.existsSync(flowFilePath).should.be.true(); + fs.existsSync(flowFileBackupPath).should.be.false(); + fs.writeFileSync(flowFileBackupPath,JSON.stringify(testFlow)); + fs.existsSync(flowFileBackupPath).should.be.true(); + setTimeout(function() { + localfilesystem.getFlows().then(function(flows) { + flows.should.eql(testFlow); + done(); + }).catch(function(err) { + done(err); + }); + },50); + }).catch(function(err) { + done(err); + }); + }); + + it('should save flows to the default file',function(done) { + localfilesystem.init({userDir:userDir}, mockRuntime).then(function() { + var flowFile = 'flows_'+require('os').hostname()+'.json'; + var flowFilePath = path.join(userDir,flowFile); + var flowFileBackupPath = path.join(userDir,"."+flowFile+".backup"); + fs.existsSync(flowFilePath).should.be.false(); + fs.existsSync(flowFileBackupPath).should.be.false(); + localfilesystem.saveFlows(testFlow).then(function() { + fs.existsSync(flowFilePath).should.be.true(); + fs.existsSync(flowFileBackupPath).should.be.false(); + localfilesystem.getFlows().then(function(flows) { + flows.should.eql(testFlow); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should save flows to the specified file',function(done) { + var defaultFlowFile = 'flows_'+require('os').hostname()+'.json'; + var defaultFlowFilePath = path.join(userDir,defaultFlowFile); + var flowFile = 'test.json'; + var flowFilePath = path.join(userDir,flowFile); + + localfilesystem.init({userDir:userDir, flowFile:flowFilePath}, mockRuntime).then(function() { + fs.existsSync(defaultFlowFilePath).should.be.false(); + fs.existsSync(flowFilePath).should.be.false(); + + localfilesystem.saveFlows(testFlow).then(function() { + fs.existsSync(defaultFlowFilePath).should.be.false(); + fs.existsSync(flowFilePath).should.be.true(); + localfilesystem.getFlows().then(function(flows) { + flows.should.eql(testFlow); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should format the flows file when flowFilePretty specified',function(done) { + var flowFile = 'test.json'; + var flowFilePath = path.join(userDir,flowFile); + localfilesystem.init({userDir:userDir, flowFile:flowFilePath,flowFilePretty:true}, mockRuntime).then(function() { + localfilesystem.saveFlows(testFlow).then(function() { + var content = fs.readFileSync(flowFilePath,"utf8"); + content.split("\n").length.should.be.above(1); + localfilesystem.getFlows().then(function(flows) { + flows.should.eql(testFlow); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should fsync the flows file',function(done) { + var flowFile = 'test.json'; + var flowFilePath = path.join(userDir,flowFile); + localfilesystem.init({editorTheme:{projects:{enabled:false}},userDir:userDir, flowFile:flowFilePath}, mockRuntime).then(function() { + sinon.spy(fs,"fsync"); + localfilesystem.saveFlows(testFlow).then(function() { + fs.fsync.callCount.should.be.greaterThan(0); + fs.fsync.restore(); + done(); + }).catch(function(err) { + fs.fsync.restore(); + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should log fsync errors and continue',function(done) { + var flowFile = 'test.json'; + var flowFilePath = path.join(userDir,flowFile); + localfilesystem.init({userDir:userDir, flowFile:flowFilePath}, mockRuntime).then(function() { + sinon.stub(fs,"fsync", function(fd, cb) { + cb(new Error()); + }); + sinon.spy(log,"warn"); + localfilesystem.saveFlows(testFlow).then(function() { + fs.fsync.callCount.should.be.greaterThan(0); + log.warn.restore(); + fs.fsync.callCount.should.be.greaterThan(0); + fs.fsync.restore(); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should backup the flows file', function(done) { + var defaultFlowFile = 'flows_'+require('os').hostname()+'.json'; + var defaultFlowFilePath = path.join(userDir,defaultFlowFile); + var flowFile = 'test.json'; + var flowFilePath = path.join(userDir,flowFile); + var flowFileBackupPath = path.join(userDir,"."+flowFile+".backup"); + + localfilesystem.init({userDir:userDir, flowFile:flowFilePath}, mockRuntime).then(function() { + fs.existsSync(defaultFlowFilePath).should.be.false(); + fs.existsSync(flowFilePath).should.be.false(); + fs.existsSync(flowFileBackupPath).should.be.false(); + + localfilesystem.saveFlows(testFlow).then(function() { + fs.existsSync(flowFileBackupPath).should.be.false(); + fs.existsSync(defaultFlowFilePath).should.be.false(); + fs.existsSync(flowFilePath).should.be.true(); + var content = fs.readFileSync(flowFilePath,'utf8'); + var testFlow2 = [{"type":"tab","id":"bc5672ad.2741d8","label":"Sheet 2"}]; + + localfilesystem.saveFlows(testFlow2).then(function() { + fs.existsSync(flowFileBackupPath).should.be.true(); + fs.existsSync(defaultFlowFilePath).should.be.false(); + fs.existsSync(flowFilePath).should.be.true(); + var backupContent = fs.readFileSync(flowFileBackupPath,'utf8'); + content.should.equal(backupContent); + var content2 = fs.readFileSync(flowFilePath,'utf8'); + content2.should.not.equal(backupContent); + done(); + + }).catch(function(err) { + done(err); + }); + + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + + + }); + + it('should handle missing credentials', function(done) { + var flowFile = 'test.json'; + var flowFilePath = path.join(userDir,flowFile); + var credFile = path.join(userDir,"test_cred.json"); + localfilesystem.init({userDir:userDir, flowFile:flowFilePath}, mockRuntime).then(function() { + fs.existsSync(credFile).should.be.false(); + + localfilesystem.getCredentials().then(function(creds) { + creds.should.eql({}); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should handle credentials', function(done) { + var flowFile = 'test.json'; + var flowFilePath = path.join(userDir,flowFile); + var credFile = path.join(userDir,"test_cred.json"); + + localfilesystem.init({userDir:userDir, flowFile:flowFilePath}, mockRuntime).then(function() { + + fs.existsSync(credFile).should.be.false(); + + var credentials = {"abc":{"type":"creds"}}; + + localfilesystem.saveCredentials(credentials).then(function() { + fs.existsSync(credFile).should.be.true(); + localfilesystem.getCredentials().then(function(creds) { + creds.should.eql(credentials); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + + it('should backup existing credentials', function(done) { + var flowFile = 'test.json'; + var flowFilePath = path.join(userDir,flowFile); + var credFile = path.join(userDir,"test_cred.json"); + var credFileBackup = path.join(userDir,".test_cred.json.backup"); + + localfilesystem.init({userDir:userDir, flowFile:flowFilePath}, mockRuntime).then(function() { + + fs.writeFileSync(credFile,"{}","utf8"); + + fs.existsSync(credFile).should.be.true(); + fs.existsSync(credFileBackup).should.be.false(); + + var credentials = {"abc":{"type":"creds"}}; + + localfilesystem.saveCredentials(credentials).then(function() { + fs.existsSync(credFile).should.be.true(); + fs.existsSync(credFileBackup).should.be.true(); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should format the creds file when flowFilePretty specified',function(done) { + var flowFile = 'test.json'; + var flowFilePath = path.join(userDir,flowFile); + var credFile = path.join(userDir,"test_cred.json"); + + localfilesystem.init({userDir:userDir, flowFile:flowFilePath, flowFilePretty:true}, mockRuntime).then(function() { + + fs.existsSync(credFile).should.be.false(); + + var credentials = {"abc":{"type":"creds"}}; + + localfilesystem.saveCredentials(credentials).then(function() { + fs.existsSync(credFile).should.be.true(); + var content = fs.readFileSync(credFile,"utf8"); + content.split("\n").length.should.be.above(1); + localfilesystem.getCredentials().then(function(creds) { + creds.should.eql(credentials); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should handle flow file in random unc path and non-existent subfolder',function(done) { + // only test on win32 + if (process.platform !== 'win32') { + console.log('skipped test as not win32'); + done(); + return; + } + + // get a real windows path + var flowFile = path.win32.resolve(userDir+'/some/random/path'); + var rootdir = path.win32.resolve(userDir+'/some'); + // make it into a local UNC path + flowFile = flowFile.replace('C:\\', '\\\\localhost\\c$\\'); + localfilesystem.init({userDir:userDir, flowFile:flowFile}, mockRuntime).then(function() { + fs.existsSync(flowFile).should.be.false(); + localfilesystem.saveFlows(testFlow).then(function() { + fs.existsSync(flowFile).should.be.true(); + localfilesystem.getFlows().then(function(flows) { + flows.should.eql(testFlow); + // cleanup + fs.removeSync(rootdir); + done(); + }).catch(function(err) { + // cleanup + fs.removeSync(rootdir); + done(err); + }); + }).catch(function(err) { + // cleanup + fs.removeSync(rootdir); + done(err); + }); + }).catch(function(err) { + // cleanup + fs.removeSync(rootdir); + done(err); + }); + }); + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/library_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/library_spec.js new file mode 100644 index 0000000..69b6e3d --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/library_spec.js @@ -0,0 +1,244 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var fs = require('fs-extra'); +var path = require('path'); +var NR_TEST_UTILS = require("nr-test-utils"); + +var localfilesystemLibrary = NR_TEST_UTILS.require("@node-red/runtime/lib/storage/localfilesystem/library"); + +describe('storage/localfilesystem/library', function() { + var userDir = path.join(__dirname,".testUserHome"); + beforeEach(function(done) { + fs.remove(userDir,function(err) { + fs.mkdir(userDir,done); + }); + }); + afterEach(function(done) { + fs.remove(userDir,done); + }); + + it('should return an empty list of library objects',function(done) { + localfilesystemLibrary.init({userDir:userDir}).then(function() { + localfilesystemLibrary.getLibraryEntry('object','').then(function(flows) { + flows.should.eql([]); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should return an empty list of library objects (path=/)',function(done) { + localfilesystemLibrary.init({userDir:userDir}).then(function() { + localfilesystemLibrary.getLibraryEntry('object','/').then(function(flows) { + flows.should.eql([]); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should return an error for a non-existent library object',function(done) { + localfilesystemLibrary.init({userDir:userDir}).then(function() { + localfilesystemLibrary.getLibraryEntry('object','A/B').then(function(flows) { + should.fail(null,null,"non-existent flow"); + }).catch(function(err) { + should.exist(err); + done(); + }); + }).catch(function(err) { + done(err); + }); + }); + + function createObjectLibrary(type) { + type = type || "object"; + var objLib = path.join(userDir, "lib", type); + try { + fs.mkdirSync(objLib); + } catch (err) { + } + fs.mkdirSync(path.join(objLib, "A")); + fs.mkdirSync(path.join(objLib, "B")); + fs.mkdirSync(path.join(objLib, "B", "C")); + fs.mkdirSync(path.join(objLib, "D")); + if (type === "functions" || type === "object") { + fs.writeFileSync(path.join(objLib, "file1.js"), "// abc: def\n// not a metaline \n\n Hi", 'utf8'); + fs.writeFileSync(path.join(objLib, "B", "file2.js"), "// ghi: jkl\n// not a metaline \n\n Hi", 'utf8'); + fs.writeFileSync(path.join(objLib, "D", "file3.js"), "// mno: 日本語テスト\n\nこんにちわ", 'utf8'); + } + if (type === "flows" || type === "object") { + fs.writeFileSync(path.join(objLib, "B", "flow.json"), "Hi", 'utf8'); + } + } + + it('should return a directory listing of library objects', function (done) { + localfilesystemLibrary.init({userDir: userDir}).then(function () { + createObjectLibrary(); + + localfilesystemLibrary.getLibraryEntry('object', '').then(function (flows) { + flows.should.eql([ 'A', 'B', 'D', { abc: 'def', fn: 'file1.js' }]); + localfilesystemLibrary.getLibraryEntry('object', 'B').then(function (flows) { + flows.should.eql([ 'C', { ghi: 'jkl', fn: 'file2.js' }, { fn: 'flow.json' }]); + localfilesystemLibrary.getLibraryEntry('object', 'B/C').then(function (flows) { + flows.should.eql([]); + localfilesystemLibrary.getLibraryEntry('object', 'D').then(function (flows) { + flows.should.eql([{ mno: '日本語テスト', fn: 'file3.js' }]); + done(); + }).catch(function (err) { + done(err); + }); + }).catch(function (err) { + done(err); + }); + }).catch(function (err) { + done(err); + }); + }).catch(function (err) { + done(err); + }); + }).catch(function (err) { + done(err); + }); + }); + + it('should load a flow library object with .json unspecified', function(done) { + localfilesystemLibrary.init({userDir:userDir}).then(function() { + createObjectLibrary("flows"); + localfilesystemLibrary.getLibraryEntry('flows','B/flow').then(function(flows) { + flows.should.eql("Hi"); + done(); + }).catch(function(err) { + done(err); + }); + }); + + }); + + it('should return a library object',function(done) { + localfilesystemLibrary.init({userDir:userDir}).then(function() { + createObjectLibrary(); + localfilesystemLibrary.getLibraryEntry('object','B/file2.js').then(function(body) { + body.should.eql("// not a metaline \n\n Hi"); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should return a newly saved library function',function(done) { + localfilesystemLibrary.init({userDir:userDir}).then(function() { + createObjectLibrary("functions"); + localfilesystemLibrary.getLibraryEntry('functions','B').then(function(flows) { + flows.should.eql([ 'C', { ghi: 'jkl', fn: 'file2.js' } ]); + var ft = path.join("B","D","file3.js"); + localfilesystemLibrary.saveLibraryEntry('functions',ft,{mno:'pqr'},"// another non meta line\n\n Hi There").then(function() { + setTimeout(function() { + localfilesystemLibrary.getLibraryEntry('functions',path.join("B","D")).then(function(flows) { + flows.should.eql([ { mno: 'pqr', fn: 'file3.js' } ]); + localfilesystemLibrary.getLibraryEntry('functions',ft).then(function(body) { + body.should.eql("// another non meta line\n\n Hi There"); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }) + }, 50); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should return a newly saved library flow',function(done) { + localfilesystemLibrary.init({userDir:userDir}).then(function() { + createObjectLibrary("flows"); + localfilesystemLibrary.getLibraryEntry('flows','B').then(function(flows) { + flows.should.eql([ 'C', {fn:'flow.json'} ]); + var ft = path.join("B","D","file3"); + localfilesystemLibrary.saveLibraryEntry('flows',ft,{mno:'pqr'},"Hi").then(function() { + setTimeout(function() { + localfilesystemLibrary.getLibraryEntry('flows',path.join("B","D")).then(function(flows) { + flows.should.eql([ { mno: 'pqr', fn: 'file3.json' } ]); + localfilesystemLibrary.getLibraryEntry('flows',ft+".json").then(function(body) { + body.should.eql("Hi"); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }) + }, 50); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should return a newly saved library flow (multi-byte character)',function(done) { + localfilesystemLibrary.init({userDir:userDir}).then(function() { + createObjectLibrary("flows"); + localfilesystemLibrary.getLibraryEntry('flows','B').then(function(flows) { + flows.should.eql([ 'C', {fn:'flow.json'} ]); + var ft = path.join("B","D","file4"); + localfilesystemLibrary.saveLibraryEntry('flows',ft,{mno:'pqr'},"こんにちわこんにちわこんにちわ").then(function() { + setTimeout(function() { + localfilesystemLibrary.getLibraryEntry('flows',path.join("B","D")).then(function(flows) { + flows.should.eql([ { mno: 'pqr', fn: 'file4.json' } ]); + localfilesystemLibrary.getLibraryEntry('flows',ft+".json").then(function(body) { + body.should.eql("こんにちわこんにちわこんにちわ"); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }) + }, 50); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/Project_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/Project_spec.js new file mode 100644 index 0000000..ecf24cf --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/Project_spec.js @@ -0,0 +1,21 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var NR_TEST_UTILS = require("nr-test-utils"); + +describe("storage/localfilesystem/projects/Project", function() { + it.skip("NEEDS TESTS WRITING",function() {}); +}) diff --git a/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/defaultFileSet_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/defaultFileSet_spec.js new file mode 100644 index 0000000..3fab5a4 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/defaultFileSet_spec.js @@ -0,0 +1,64 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +var should = require("should"); +var NR_TEST_UTILS = require("nr-test-utils"); +var defaultFileSet = NR_TEST_UTILS.require("@node-red/runtime/lib/storage/localfilesystem/projects/defaultFileSet"); + +describe('storage/localfilesystem/projects/defaultFileSet', function() { + var runtime = { + i18n: { + "_": function(name) { + return name; + } + } + }; + it('generates package.json for a project', function() { + var generated = defaultFileSet["package.json"]({ + name: "A TEST NAME", + summary: "A TEST SUMMARY", + files: { + flow: "MY FLOW FILE", + credentials: "MY CREDENTIALS FILE" + } + }, runtime); + + var parsed = JSON.parse(generated); + parsed.should.have.property('name',"A TEST NAME"); + parsed.should.have.property('description',"A TEST SUMMARY"); + parsed.should.have.property('node-red'); + parsed['node-red'].should.have.property('settings'); + parsed['node-red'].settings.should.have.property('flowFile',"MY FLOW FILE"); + parsed['node-red'].settings.should.have.property('credentialsFile',"MY CREDENTIALS FILE"); + }); + + it('generates README.md for a project', function() { + var generated = defaultFileSet["README.md"]({ + name: "A TEST NAME", + summary: "A TEST SUMMARY" + }, runtime); + generated.should.match(/A TEST NAME/); + generated.should.match(/A TEST SUMMARY/); + }); + it('generates .gitignore for a project', function() { + var generated = defaultFileSet[".gitignore"]({ + name: "A TEST NAME", + summary: "A TEST SUMMARY" + }, runtime); + generated.length.should.be.greaterThan(0); + }); +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/git/authCache_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/git/authCache_spec.js new file mode 100644 index 0000000..c1617bf --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/git/authCache_spec.js @@ -0,0 +1,84 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); + +var NR_TEST_UTILS = require("nr-test-utils"); +var authCache = NR_TEST_UTILS.require("@node-red/runtime/lib/storage/localfilesystem/projects/git/authCache") + +describe("localfilesystem/projects/git/authCache", function() { + + beforeEach(function() { + authCache.init(); + }); + afterEach(function() { + authCache.init(); + }); + + it('sets/clears auth details for a given project/remote/user', function() { + should.not.exist(authCache.get("project","remote1","user1")); + should.not.exist(authCache.get("project","remote1","user2")); + + authCache.set("project","remote1","user1",{foo1:"bar1"}); + authCache.set("project","remote1","user2",{foo2:"bar2"}); + + var result = authCache.get("project","remote1","user1"); + result.should.have.property("foo1","bar1"); + + result = authCache.get("project","remote1","user2"); + result.should.have.property("foo2","bar2"); + + authCache.clear("project","remote1","user1"); + should.not.exist(authCache.get("project","remote1","user1")); + should.exist(authCache.get("project","remote1","user2")); + + }); + + + it('clears auth details for all users on a given project/remote', function() { + + authCache.set("project","remote1","user1",{foo1:"bar1"}); + authCache.set("project","remote1","user2",{foo2:"bar2"}); + authCache.set("project","remote2","user1",{foo3:"bar3"}); + + should.exist(authCache.get("project","remote1","user1")); + should.exist(authCache.get("project","remote1","user2")); + should.exist(authCache.get("project","remote2","user1")); + + authCache.clear("project","remote1"); + should.not.exist(authCache.get("project","remote1","user1")); + should.not.exist(authCache.get("project","remote1","user2")); + should.exist(authCache.get("project","remote2","user1")); + }); + + it('clears auth details for all remotes/users on a given project', function() { + + authCache.set("project1","remote1","user1",{foo1:"bar1"}); + authCache.set("project1","remote1","user2",{foo2:"bar2"}); + authCache.set("project2","remote2","user1",{foo3:"bar3"}); + + should.exist(authCache.get("project1","remote1","user1")); + should.exist(authCache.get("project1","remote1","user2")); + should.exist(authCache.get("project2","remote2","user1")); + + authCache.clear("project2"); + should.exist(authCache.get("project1","remote1","user1")); + should.exist(authCache.get("project1","remote1","user2")); + should.not.exist(authCache.get("project2","remote2","user1")); + }); + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/git/authServer_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/git/authServer_spec.js new file mode 100644 index 0000000..9b789a6 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/git/authServer_spec.js @@ -0,0 +1,83 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var net = require("net"); +var path = require("path"); +var os = require("os"); +var should = require("should"); +var sinon = require("sinon"); +var child_process = require("child_process"); +var fs = require("fs-extra"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var authServer = NR_TEST_UTILS.require("@node-red/runtime/lib/storage/localfilesystem/projects/git/authServer"); + + +var sendPrompt = function(localPath, prompt) { + return new Promise(function(resolve,reject) { + var response; + var socket = net.connect(localPath, function() { + socket.on('data', function(data) { response = data; socket.end() }); + socket.on('end', function() { + resolve(response); + }); + socket.on('error',reject); + socket.write(prompt+"\n", 'utf8'); + }); + socket.setEncoding('utf8'); + }); +} + + +describe("localfilesystem/projects/git/authServer", function() { + it("listens for user/pass prompts and returns provided auth", function(done) { + authServer.ResponseServer({username: "TEST_USER", password: "TEST_PASS"}).then(function(rs) { + sendPrompt(rs.path,"Username").then(function(response) { + response.should.eql("TEST_USER"); + return sendPrompt(rs.path,"Password"); + }).then(function(response) { + response.should.eql("TEST_PASS"); + }).then(() => { + rs.close(); + done(); + }).catch(function(err) { + rs.close(); + done(err); + }) + + }) + }); + + it("listens for ssh prompts and returns provided auth", function(done) { + authServer.ResponseSSHServer({passphrase: "TEST_PASSPHRASE"}).then(function(rs) { + sendPrompt(rs.path,"The").then(function(response) { + // TODO: + response.should.eql("yes"); + return sendPrompt(rs.path,"Enter"); + }).then(function(response) { + response.should.eql("TEST_PASSPHRASE"); + }).then(() => { + rs.close(); + done(); + }).catch(function(err) { + rs.close(); + done(err); + }) + + }) + }) +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/git/authWriter_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/git/authWriter_spec.js new file mode 100644 index 0000000..c80cb8a --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/git/authWriter_spec.js @@ -0,0 +1,83 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var net = require("net"); +var path = require("path"); +var os = require("os"); +var should = require("should"); +var sinon = require("sinon"); +var child_process = require("child_process"); +var fs = require("fs-extra"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var authWriter = NR_TEST_UTILS.resolve("@node-red/runtime/lib/storage/localfilesystem/projects/git/authWriter"); + +function getListenPath() { + var seed = (0x100000+Math.random()*0x999999).toString(16); + var fn = 'node-red-git-askpass-'+seed+'-sock'; + var listenPath; + if (process.platform === 'win32') { + listenPath = '\\\\.\\pipe\\'+fn; + } else { + listenPath = path.join(process.env['XDG_RUNTIME_DIR'] || os.tmpdir(), fn); + } + // console.log(listenPath); + return listenPath; +} + + +describe("localfilesystem/projects/git/authWriter", function() { + it("connects to port and sends passphrase", function(done) { + var receivedData = ""; + var server = net.createServer(function(connection) { + connection.setEncoding('utf8'); + connection.on('data', function(data) { + receivedData += data; + var m = data.indexOf("\n"); + if (m !== -1) { + connection.end(); + } + }); + }); + + var listenPath = getListenPath(); + + server.listen(listenPath, function(ready) { + child_process.exec('"'+process.execPath+'" "'+authWriter+'" "'+listenPath+'" TEST_PHRASE_FOO',{cwd:__dirname}, (error,stdout,stderr) => { + server.close(); + try { + should.not.exist(error); + receivedData.should.eql("TEST_PHRASE_FOO\n"); + done(); + } catch(err) { + done(err); + } + }); + }); + server.on('close', function() { + // console.log("Closing response server"); + fs.removeSync(listenPath); + }); + server.on('error',function(err) { + console.log("ResponseServer unexpectedError:",err.toString()); + server.close(); + done(err); + }); + + + }) +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/git/index_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/git/index_spec.js new file mode 100644 index 0000000..773342f --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/git/index_spec.js @@ -0,0 +1,21 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var NR_TEST_UTILS = require("nr-test-utils"); + +describe("storage/localfilesystem/projects/git/index", function() { + it.skip("NEEDS TESTS WRITING",function() {}); +}) diff --git a/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/index_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/index_spec.js new file mode 100644 index 0000000..f63a205 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/index_spec.js @@ -0,0 +1,21 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var NR_TEST_UTILS = require("nr-test-utils"); + +describe("storage/localfilesystem/projects/index", function() { + it.skip("NEEDS TESTS WRITING",function() {}); +}) diff --git a/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/index_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/index_spec.js new file mode 100644 index 0000000..c6d0c53 --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/index_spec.js @@ -0,0 +1,433 @@ +/** +* Copyright JS Foundation and other contributors, http://js.foundation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ +var should = require("should"); +var fs = require('fs-extra'); +var path = require('path'); + +var NR_TEST_UTILS = require("nr-test-utils"); +var sshkeys = NR_TEST_UTILS.require("@node-red/runtime/lib/storage/localfilesystem/projects/ssh"); + +describe("storage/localfilesystem/projects/ssh", function() { + var userDir = path.join(__dirname,".testSSHKeyUserHome"); + var mockSettings = { + userDir: userDir + }; + var mockRuntime = { + log:{ + _:function() { return "placeholder message"}, + info: function() { }, + log: function() { }, + trace: function() { } + } + }; + var oldHOME; + + beforeEach(function(done) { + oldHOME = process.env.HOME; + process.env.HOME = "/tmp/doesnt/exist"; + fs.remove(userDir,function(err) { + fs.mkdir(userDir,done); + }); + }); + afterEach(function(done) { + process.env.HOME = oldHOME; + fs.remove(userDir,done); + }); + + it('should create sshkey directory when sshkey initializes', function(done) { + var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys'); + sshkeys.init(mockSettings, mockRuntime).then(function() { + var ret = fs.existsSync(sshkeyDirPath); + ret.should.be.true(); + done(); + }).catch(function(err) { + done(err); + }); + }); + + it('should get sshkey empty list if there is no sshkey file', function(done) { + var username = 'test'; + sshkeys.init(mockSettings, mockRuntime).then(function() { + sshkeys.listSSHKeys(username).then(function(retObj) { + retObj.should.be.instanceOf(Array).and.have.lengthOf(0); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should get sshkey list', function(done) { + var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys'); + var username = 'test'; + var filenameList = ['test-key01', 'test-key02']; + sshkeys.init(mockSettings, mockRuntime).then(function() { + for(var filename of filenameList) { + fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename),"","utf8"); + fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename+".pub"),"","utf8"); + } + sshkeys.listSSHKeys(username).then(function(retObj) { + retObj.should.be.instanceOf(Array).and.have.lengthOf(filenameList.length); + for(var filename of filenameList) { + retObj.should.containEql({ name: filename }); + } + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should not get sshkey file if there is only private key', function(done) { + var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys'); + var username = 'test'; + var filenameList = ['test-key01', 'test-key02']; + var onlyPrivateKeyFilenameList = ['test-key03', 'test-key04']; + sshkeys.init(mockSettings, mockRuntime).then(function() { + for(var filename of filenameList) { + fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename),"","utf8"); + fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename+".pub"),"","utf8"); + } + for(var filename of onlyPrivateKeyFilenameList) { + fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename),"","utf8"); + } + sshkeys.listSSHKeys(username).then(function(retObj) { + retObj.should.be.instanceOf(Array).and.have.lengthOf(filenameList.length); + for(var filename of filenameList) { + retObj.should.containEql({ name: filename }); + } + for(var filename of onlyPrivateKeyFilenameList) { + retObj.should.not.containEql({ name: filename }); + } + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should not get sshkey file if there is only public key', function(done) { + var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys'); + var username = 'test'; + var filenameList = ['test-key01', 'test-key02']; + var directoryList = ['test-key03', '.test-key04']; + sshkeys.init(mockSettings, mockRuntime).then(function() { + for(var filename of filenameList) { + fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename),"","utf8"); + fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename+".pub"),"","utf8"); + } + for(var filename of directoryList) { + fs.ensureDirSync(path.join(sshkeyDirPath,filename)); + } + sshkeys.listSSHKeys(username).then(function(retObj) { + retObj.should.be.instanceOf(Array).and.have.lengthOf(filenameList.length); + for(var filename of filenameList) { + retObj.should.containEql({ name: filename }); + } + for(var directoryname of directoryList) { + retObj.should.not.containEql({ name: directoryname }); + } + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should get sshkey list that does not have directory', function(done) { + var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys'); + var username = 'test'; + var otherUsername = 'other'; + var filenameList = ['test-key01', 'test-key02']; + var otherUserFilenameList = ['test-key03', 'test-key04']; + sshkeys.init(mockSettings, mockRuntime).then(function() { + for(var filename of filenameList) { + fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename),"","utf8"); + fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename+".pub"),"","utf8"); + } + for(var filename of otherUserFilenameList) { + fs.writeFileSync(path.join(sshkeyDirPath,otherUsername+"_"+filename),"","utf8"); + fs.writeFileSync(path.join(sshkeyDirPath,otherUsername+"_"+filename+".pub"),"","utf8"); + } + sshkeys.listSSHKeys(username).then(function(retObj) { + retObj.should.be.instanceOf(Array).and.have.lengthOf(filenameList.length); + for(var filename of filenameList) { + retObj.should.containEql({ name: filename }); + } + for(var filename of otherUserFilenameList) { + retObj.should.not.containEql({ name: filename }); + } + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should get sshkey list that have keys of specified user', function(done) { + var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys'); + var username = 'test'; + var otherUsername = 'other'; + var filenameList = ['test-key01', 'test-key02']; + var otherUserFilenameList = ['test-key03', 'test-key04']; + sshkeys.init(mockSettings, mockRuntime).then(function() { + for(var filename of filenameList) { + fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename),"","utf8"); + fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename+".pub"),"","utf8"); + } + for(var filename of otherUserFilenameList) { + fs.writeFileSync(path.join(sshkeyDirPath,otherUsername+"_"+filename),"","utf8"); + fs.writeFileSync(path.join(sshkeyDirPath,otherUsername+"_"+filename+".pub"),"","utf8"); + } + sshkeys.listSSHKeys(username).then(function(retObj) { + retObj.should.be.instanceOf(Array).and.have.lengthOf(filenameList.length); + for(var filename of filenameList) { + retObj.should.containEql({ name: filename }); + } + for(var filename of otherUserFilenameList) { + retObj.should.not.containEql({ name: filename }); + } + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should generate sshkey file with empty data', function(done) { + this.timeout(10000); + var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys'); + var username = 'test'; + var options = { + name: 'test-key01' + }; + sshkeys.init(mockSettings, mockRuntime).then(function() { + sshkeys.generateSSHKey(username, options).then(function(retObj) { + retObj.should.be.equal(options.name); + fs.existsSync(path.join(sshkeyDirPath,username+'_'+options.name)).should.be.true(); + fs.existsSync(path.join(sshkeyDirPath,username+'_'+options.name+'.pub')).should.be.true(); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should generate sshkey file with only comment data', function(done) { + this.timeout(10000); + var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys'); + var username = 'test'; + var options = { + comment: 'test@test.com', + name: 'test-key01' + }; + + sshkeys.init(mockSettings, mockRuntime).then(function() { + sshkeys.generateSSHKey(username, options).then(function(retObj) { + retObj.should.be.equal(options.name); + fs.existsSync(path.join(sshkeyDirPath,username+'_'+options.name)).should.be.true(); + fs.existsSync(path.join(sshkeyDirPath,username+'_'+options.name+'.pub')).should.be.true(); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should generate sshkey file with password data', function(done) { + this.timeout(10000); + var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys'); + var username = 'test'; + var options = { + comment: 'test@test.com', + name: 'test-key01', + password: 'testtest' + }; + + sshkeys.init(mockSettings, mockRuntime).then(function() { + sshkeys.generateSSHKey(username, options).then(function(retObj) { + retObj.should.be.equal(options.name); + fs.existsSync(path.join(sshkeyDirPath,username+'_'+options.name)).should.be.true(); + fs.existsSync(path.join(sshkeyDirPath,username+'_'+options.name+'.pub')).should.be.true(); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should generate sshkey file with size data', function(done) { + this.timeout(20000); + var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys'); + var username = 'test'; + var options = { + comment: 'test@test.com', + name: 'test-key01', + size: 4096 + }; + + sshkeys.init(mockSettings, mockRuntime).then(function() { + sshkeys.generateSSHKey(username, options).then(function(retObj) { + retObj.should.be.equal(options.name); + fs.existsSync(path.join(sshkeyDirPath,username+'_'+options.name)).should.be.true(); + fs.existsSync(path.join(sshkeyDirPath,username+'_'+options.name+'.pub')).should.be.true(); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should generate sshkey file with password & size data', function(done) { + this.timeout(20000); + var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys'); + var username = 'test'; + var options = { + comment: 'test@test.com', + name: 'test-key01', + password: 'testtest', + size: 4096 + }; + + sshkeys.init(mockSettings, mockRuntime).then(function() { + sshkeys.generateSSHKey(username, options).then(function(retObj) { + retObj.should.be.equal(options.name); + fs.existsSync(path.join(sshkeyDirPath,username+'_'+options.name)).should.be.true(); + fs.existsSync(path.join(sshkeyDirPath,username+'_'+options.name+'.pub')).should.be.true(); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should not generate sshkey file with illegal size data', function(done) { + this.timeout(10000); + var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys'); + var username = 'test'; + var options = { + comment: 'test@test.com', + name: 'test-key01', + size: 1023 + }; + + sshkeys.init(mockSettings, mockRuntime).then(function() { + sshkeys.generateSSHKey(username, options).then(function(retObj) { + done(new Error('Does NOT throw error!')); + }).catch(function(err) { + try { + err.should.have.property('code', 'key_length_too_short'); + done(); + } + catch (error) { + done(error); + } + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should not generate sshkey file with illegal password', function(done) { + this.timeout(10000); + var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys'); + var username = 'test'; + var options = { + comment: 'test@test.com', + name: 'test-key01', + password: 'aa' + }; + + sshkeys.init(mockSettings, mockRuntime).then(function() { + sshkeys.generateSSHKey(username, options).then(function(retObj) { + done(new Error('Does NOT throw error!')); + }).catch(function(err) { + try { + err.should.have.property('code', 'key_passphrase_too_short'); + done(); + } + catch (error) { + done(error); + } + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should get sshkey file content', function(done) { + var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys'); + var username = 'test'; + var filename = 'test-key01'; + var fileContent = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD3a+sgtgzSbbliWxmOq5p6+H/mE+0gjWfLWrkIVmHENd1mifV4uCmIHAR2NfuadUYMQ3+bQ90kpmmEKTMYPsyentsKpHQZxTzG7wOCAIpJnbPTHDMxEJhVTaAwEjbVyMSIzTTPfnhoavWIBu0+uMgKDDlBm+RjlgkFlyhXyCN6UwFrIUUMH6Gw+eQHLiooKIl8ce7uDxIlt+9b7hFCU+sQ3kvuse239DZluu6+8buMWqJvrEHgzS9adRFKku8nSPAEPYn85vDi7OgVAcLQufknNgs47KHBAx9h04LeSrFJ/P5J1b//ItRpMOIme+O9d1BR46puzhvUaCHLdvO9czj+OmW+dIm+QIk6lZIOOMnppG72kZxtLfeKT16ur+2FbwAdL9ItBp4BI/YTlBPoa5mLMxpuWfmX1qHntvtGc9wEwS1P7YFfmF3XiK5apxalzrn0Qlr5UmDNbVIqJb1OlbC0w03Z0oktti1xT+R2DGOLWM4lBbpXDHV1BhQ7oYOvbUD8Cnof55lTP0WHHsOHlQc/BGDti1XA9aBX/OzVyzBUYEf0pkimsD0RYo6aqt7QwehJYdlz9x1NBguBffT0s4NhNb9IWr+ASnFPvNl2sw4XH/8U0J0q8ZkMpKkbLM1Zdp1Fv00GF0f5UNRokai6uM3w/ccantJ3WvZ6GtctqytWrw== \n"; + + sshkeys.init(mockSettings, mockRuntime).then(function() { + fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename),"","utf8"); + fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename+".pub"),fileContent,"utf8"); + sshkeys.getSSHKey(username, filename).then(function(retObj) { + retObj.should.be.equal(fileContent); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); + + it('should delete sshkey files', function(done) { + var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys'); + var username = 'test'; + var filename = 'test-key01'; + var fileContent = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD3a+sgtgzSbbliWxmOq5p6+H/mE+0gjWfLWrkIVmHENd1mifV4uCmIHAR2NfuadUYMQ3+bQ90kpmmEKTMYPsyentsKpHQZxTzG7wOCAIpJnbPTHDMxEJhVTaAwEjbVyMSIzTTPfnhoavWIBu0+uMgKDDlBm+RjlgkFlyhXyCN6UwFrIUUMH6Gw+eQHLiooKIl8ce7uDxIlt+9b7hFCU+sQ3kvuse239DZluu6+8buMWqJvrEHgzS9adRFKku8nSPAEPYn85vDi7OgVAcLQufknNgs47KHBAx9h04LeSrFJ/P5J1b//ItRpMOIme+O9d1BR46puzhvUaCHLdvO9czj+OmW+dIm+QIk6lZIOOMnppG72kZxtLfeKT16ur+2FbwAdL9ItBp4BI/YTlBPoa5mLMxpuWfmX1qHntvtGc9wEwS1P7YFfmF3XiK5apxalzrn0Qlr5UmDNbVIqJb1OlbC0w03Z0oktti1xT+R2DGOLWM4lBbpXDHV1BhQ7oYOvbUD8Cnof55lTP0WHHsOHlQc/BGDti1XA9aBX/OzVyzBUYEf0pkimsD0RYo6aqt7QwehJYdlz9x1NBguBffT0s4NhNb9IWr+ASnFPvNl2sw4XH/8U0J0q8ZkMpKkbLM1Zdp1Fv00GF0f5UNRokai6uM3w/ccantJ3WvZ6GtctqytWrw== \n"; + + sshkeys.init(mockSettings, mockRuntime).then(function() { + fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename),"","utf8"); + fs.writeFileSync(path.join(sshkeyDirPath,username+"_"+filename+".pub"),fileContent,"utf8"); + sshkeys.deleteSSHKey(username, filename).then(function() { + fs.existsSync(path.join(sshkeyDirPath,username+'_'+filename)).should.be.false(); + fs.existsSync(path.join(sshkeyDirPath,username+'_'+filename+'.pub')).should.be.false(); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/keygen_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/keygen_spec.js new file mode 100644 index 0000000..02bf80c --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/keygen_spec.js @@ -0,0 +1,110 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var sinon = require("sinon"); +var child_process = require('child_process'); +var EventEmitter = require("events"); + +var NR_TEST_UTILS = require("nr-test-utils"); +var keygen = NR_TEST_UTILS.require("@node-red/runtime/lib/storage/localfilesystem/projects/ssh/keygen") + +describe("localfilesystem/projects/ssh/keygen", function() { + + afterEach(function() { + if (child_process.spawn.restore) { + child_process.spawn.restore(); + } + }) + + it("invokes sshkeygen", function(done) { + var command; + var args; + var opts; + sinon.stub(child_process,"spawn", function(_command,_args,_opts) { + _command = command; + _args = args; + _opts = opts; + + var e = new EventEmitter(); + e.stdout = new EventEmitter(); + e.stderr = new EventEmitter(); + setTimeout(function() { + e.stdout.emit("data","result"); + e.emit("close",0); + },50) + return e; + }); + + keygen.generateKey({ + size: 1024, + location: 'location', + comment: 'comment', + password: 'password' + }).then(function(output) { + output.should.equal("result"); + done(); + }).catch(function(err) { + done(err); + }) + }) + + it("reports passphrase too short", function(done) { + var command; + var args; + var opts; + + try { + keygen.generateKey({ + size: 1024, + location: 'location', + comment: 'comment', + password: '123' + }).then(function(output) { + done(new Error("Error not thrown")); + }).catch(function(err) { + done(new Error("Error not thrown")); + }) + } catch(err) { + err.should.have.property("code","key_passphrase_too_short"); + done(); + } + }); + + it("reports key length too short", function(done) { + var command; + var args; + var opts; + try { + keygen.generateKey({ + size: 123, + location: 'location', + comment: 'comment', + password: 'password' + }).then(function(output) { + done(new Error("Error not thrown")); + }).catch(function(err) { + done(new Error("Error not thrown")); + }) + } catch(err) { + err.should.have.property("code","key_length_too_short"); + done(); + + } + }); + + +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/sessions_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/sessions_spec.js new file mode 100644 index 0000000..685886d --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/sessions_spec.js @@ -0,0 +1,80 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var fs = require('fs-extra'); +var path = require('path'); + +var NR_TEST_UTILS = require("nr-test-utils"); +var localfilesystemSessions = NR_TEST_UTILS.require("@node-red/runtime/lib/storage/localfilesystem/sessions"); + +describe('storage/localfilesystem/sessions', function() { + var userDir = path.join(__dirname,".testUserHome"); + beforeEach(function(done) { + fs.remove(userDir,function(err) { + fs.mkdir(userDir,done); + }); + }); + afterEach(function(done) { + fs.remove(userDir,done); + }); + it('should handle non-existent sessions', function(done) { + var sessionsFile = path.join(userDir,".sessions.json"); + + localfilesystemSessions.init({userDir:userDir}); + fs.existsSync(sessionsFile).should.be.false(); + localfilesystemSessions.getSessions().then(function(sessions) { + sessions.should.eql({}); + done(); + }).catch(function(err) { + done(err); + }); + }); + + it('should handle corrupt sessions', function(done) { + var sessionsFile = path.join(userDir,".sessions.json"); + fs.writeFileSync(sessionsFile,"[This is not json","utf8"); + localfilesystemSessions.init({userDir:userDir}); + fs.existsSync(sessionsFile).should.be.true(); + localfilesystemSessions.getSessions().then(function(sessions) { + sessions.should.eql({}); + done(); + }).catch(function(err) { + done(err); + }); + }); + + it('should handle sessions', function(done) { + var sessionsFile = path.join(userDir,".sessions.json"); + + localfilesystemSessions.init({userDir:userDir}); + fs.existsSync(sessionsFile).should.be.false(); + + var sessions = {"abc":{"type":"creds"}}; + + localfilesystemSessions.saveSessions(sessions).then(function() { + fs.existsSync(sessionsFile).should.be.true(); + localfilesystemSessions.getSessions().then(function(_sessions) { + _sessions.should.eql(sessions); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/settings_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/settings_spec.js new file mode 100644 index 0000000..0be96ed --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/settings_spec.js @@ -0,0 +1,82 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var fs = require('fs-extra'); +var path = require('path'); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var localfilesystemSettings = NR_TEST_UTILS.require("@node-red/runtime/lib/storage/localfilesystem/settings"); + +describe('storage/localfilesystem/settings', function() { + var userDir = path.join(__dirname,".testUserHome"); + beforeEach(function(done) { + fs.remove(userDir,function(err) { + fs.mkdir(userDir,done); + }); + }); + afterEach(function(done) { + fs.remove(userDir,done); + }); + + it('should handle non-existent settings', function(done) { + var settingsFile = path.join(userDir,".settings.json"); + + localfilesystemSettings.init({userDir:userDir}); + fs.existsSync(settingsFile).should.be.false(); + localfilesystemSettings.getSettings().then(function(settings) { + settings.should.eql({}); + done(); + }).catch(function(err) { + done(err); + }); + }); + + it('should handle corrupt settings', function(done) { + var settingsFile = path.join(userDir,".config.json"); + fs.writeFileSync(settingsFile,"[This is not json","utf8"); + localfilesystemSettings.init({userDir:userDir}); + fs.existsSync(settingsFile).should.be.true(); + localfilesystemSettings.getSettings().then(function(settings) { + settings.should.eql({}); + done(); + }).catch(function(err) { + done(err); + }); + }); + + it('should handle settings', function(done) { + var settingsFile = path.join(userDir,".config.json"); + + localfilesystemSettings.init({userDir:userDir}); + fs.existsSync(settingsFile).should.be.false(); + + var settings = {"abc":{"type":"creds"}}; + + localfilesystemSettings.saveSettings(settings).then(function() { + fs.existsSync(settingsFile).should.be.true(); + localfilesystemSettings.getSettings().then(function(_settings) { + _settings.should.eql(settings); + done(); + }).catch(function(err) { + done(err); + }); + }).catch(function(err) { + done(err); + }); + }); +}); diff --git a/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/util_spec.js b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/util_spec.js new file mode 100644 index 0000000..fa1e4bd --- /dev/null +++ b/packages/connector/test/unit/@node-red/runtime/lib/storage/localfilesystem/util_spec.js @@ -0,0 +1,32 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var NR_TEST_UTILS = require("nr-test-utils"); +var util = NR_TEST_UTILS.require("@node-red/runtime/lib/storage/localfilesystem/util"); + +describe('storage/localfilesystem/util', function() { + describe('parseJSON', function() { + it('returns parsed JSON', function() { + var result = util.parseJSON('{"a":123}'); + result.should.eql({a:123}); + }) + it('ignores BOM character', function() { + var result = util.parseJSON('\uFEFF{"a":123}'); + result.should.eql({a:123}); + }) + }) +}); diff --git a/packages/connector/test/unit/@node-red/util/index_spec.js b/packages/connector/test/unit/@node-red/util/index_spec.js new file mode 100644 index 0000000..ee46fc5 --- /dev/null +++ b/packages/connector/test/unit/@node-red/util/index_spec.js @@ -0,0 +1,21 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var NR_TEST_UTILS = require("nr-test-utils"); + +describe("node-red/red", function() { + it.skip("NEEDS TESTS WRITING",function() {}); +}); diff --git a/packages/connector/test/unit/@node-red/util/lib/i18n_spec.js b/packages/connector/test/unit/@node-red/util/lib/i18n_spec.js new file mode 100644 index 0000000..5deaba0 --- /dev/null +++ b/packages/connector/test/unit/@node-red/util/lib/i18n_spec.js @@ -0,0 +1,26 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + + + var NR_TEST_UTILS = require("nr-test-utils"); + + var i18n = NR_TEST_UTILS.require("@node-red/util").i18n; + + +describe("@node-red/util/i18n", function() { + it.skip('more tests needed', function(){}) +}); diff --git a/packages/connector/test/unit/@node-red/util/lib/index_spec.js b/packages/connector/test/unit/@node-red/util/lib/index_spec.js new file mode 100644 index 0000000..3cf2347 --- /dev/null +++ b/packages/connector/test/unit/@node-red/util/lib/index_spec.js @@ -0,0 +1,19 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +describe("@node-red/util", function() { + it.skip('more tests needed', function(){}) +}); diff --git a/packages/connector/test/unit/@node-red/util/lib/log_spec.js b/packages/connector/test/unit/@node-red/util/lib/log_spec.js new file mode 100644 index 0000000..c882dd2 --- /dev/null +++ b/packages/connector/test/unit/@node-red/util/lib/log_spec.js @@ -0,0 +1,252 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +var should = require("should"); +var sinon = require("sinon"); +var util = require("util"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var log = NR_TEST_UTILS.require("@node-red/util").log; + + +describe("@node-red/util/log", function() { + beforeEach(function () { + var spy = sinon.stub(util, 'log', function(arg){}); + var settings = {logging: { console: { level: 'metric', metrics: true } } }; + log.init(settings); + }); + + afterEach(function() { + util.log.restore(); + }); + + it('it can raise an error', function() { + var ret = log.error("This is an error"); + sinon.assert.calledWithMatch(util.log,"[error] This is an error"); + }); + + it('it can raise a trace', function() { + var ret = log.trace("This is a trace"); + sinon.assert.calledWithMatch(util.log,"[trace] This is a trace"); + }); + + it('it can raise a debug', function() { + var ret = log.debug("This is a debug"); + sinon.assert.calledWithMatch(util.log,"[debug] This is a debug"); + }); + + it('it can raise a info', function() { + var ret = log.info("This is an info"); + sinon.assert.calledWithMatch(util.log,"[info] This is an info"); + }); + + it('it can raise a warn', function() { + var ret = log.warn("This is a warn"); + sinon.assert.calledWithMatch(util.log,"[warn] This is a warn"); + }); + + it('it can raise a metric', function() { + var metrics = {}; + metrics.level = log.METRIC; + metrics.nodeid = "testid"; + metrics.event = "node.test.testevent"; + metrics.msgid = "12345"; + metrics.value = "the metric payload"; + var ret = log.log(metrics); + util.log.calledOnce.should.be.true(); + util.log.firstCall.args[0].indexOf("[metric] ").should.equal(0); + var body = JSON.parse(util.log.firstCall.args[0].substring(9)); + body.should.have.a.property("nodeid","testid"); + body.should.have.a.property("event","node.test.testevent"); + body.should.have.a.property("msgid","12345"); + body.should.have.a.property("value","the metric payload"); + body.should.have.a.property("timestamp"); + body.should.have.a.property("level",log.METRIC); + }); + + it('it checks metrics are enabled', function() { + log.metric().should.equal(true); + var sett = {logging: { console: { level: 'info', metrics: false } } }; + log.init(sett); + log.metric().should.equal(false); + }); + + it('it logs node type and name if provided',function() { + log.log({level:log.INFO,type:"nodeType",msg:"test",name:"nodeName",id:"nodeId"}); + util.log.calledOnce.should.be.true(); + util.log.firstCall.args[0].indexOf("[nodeType:nodeName]").should.not.equal(-1); + }); + it('it logs node type and id if no name provided',function() { + log.log({level:log.INFO,type:"nodeType",msg:"test",id:"nodeId"}); + util.log.calledOnce.should.be.true(); + util.log.firstCall.args[0].indexOf("[nodeType:nodeId]").should.not.equal(-1); + }); + + it('ignores lower level messages and metrics', function() { + var settings = {logging: { console: { level: 'warn', metrics: false } } }; + log.init(settings); + log.error("This is an error"); + log.warn("This is a warn"); + log.info("This is an info"); + log.debug("This is a debug"); + log.trace("This is a trace"); + log.log({level:log.METRIC,msg:"testMetric"}); + sinon.assert.calledWithMatch(util.log,"[error] This is an error"); + sinon.assert.calledWithMatch(util.log,"[warn] This is a warn"); + sinon.assert.neverCalledWithMatch(util.log,"[info] This is an info"); + sinon.assert.neverCalledWithMatch(util.log,"[debug] This is a debug"); + sinon.assert.neverCalledWithMatch(util.log,"[trace] This is a trace"); + sinon.assert.neverCalledWithMatch(util.log,"[metric] "); + }); + it('ignores lower level messages but accepts metrics', function() { + var settings = {logging: { console: { level: 'log', metrics: true } } }; + log.init(settings); + log.error("This is an error"); + log.warn("This is a warn"); + log.info("This is an info"); + log.debug("This is a debug"); + log.trace("This is a trace"); + log.log({level:log.METRIC,msg:"testMetric"}); + sinon.assert.calledWithMatch(util.log,"[error] This is an error"); + sinon.assert.calledWithMatch(util.log,"[warn] This is a warn"); + sinon.assert.calledWithMatch(util.log,"[info] This is an info"); + sinon.assert.neverCalledWithMatch(util.log,"[debug] This is a debug"); + sinon.assert.neverCalledWithMatch(util.log,"[trace] This is a trace"); + sinon.assert.calledWithMatch(util.log,"[metric] "); + }); + + it('default settings set to INFO and metrics off', function() { + log.init({logging:{}}); + log.error("This is an error"); + log.warn("This is a warn"); + log.info("This is an info"); + log.debug("This is a debug"); + log.trace("This is a trace"); + log.log({level:log.METRIC,msg:"testMetric"}); + sinon.assert.calledWithMatch(util.log,"[error] This is an error"); + sinon.assert.calledWithMatch(util.log,"[warn] This is a warn"); + sinon.assert.calledWithMatch(util.log,"[info] This is an info"); + sinon.assert.neverCalledWithMatch(util.log,"[debug] This is a debug"); + sinon.assert.neverCalledWithMatch(util.log,"[trace] This is a trace"); + sinon.assert.neverCalledWithMatch(util.log,"[metric] "); + }); + it('no logger used if custom logger handler does not exist', function() { + var settings = {logging: { customLogger: { level: 'trace', metrics: true } } }; + log.init(settings); + log.error("This is an error"); + log.warn("This is a warn"); + log.info("This is an info"); + log.debug("This is a debug"); + log.trace("This is a trace"); + log.log({level:log.METRIC,msg:"testMetric"}); + sinon.assert.neverCalledWithMatch(util.log,"[error] This is an error"); + sinon.assert.neverCalledWithMatch(util.log,"[warn] This is a warn"); + sinon.assert.neverCalledWithMatch(util.log,"[info] This is an info"); + sinon.assert.neverCalledWithMatch(util.log,"[debug] This is a debug"); + sinon.assert.neverCalledWithMatch(util.log,"[trace] This is a trace"); + sinon.assert.neverCalledWithMatch(util.log,"[metric] "); + }); + + it('add a custom log handler directly', function() { + var settings = {}; + log.init(settings); + + var logEvents = []; + var loggerOne = { + emit: function(event,msg) { + logEvents.push({logger:1,msg:msg}); + } + }; + var loggerTwo = { + emit: function(event,msg) { + logEvents.push({logger:2,msg:msg}); + } + }; + log.addHandler(loggerOne); + log.addHandler(loggerTwo); + + log.error("This is an error"); + log.warn("This is a warn"); + log.info("This is an info"); + log.debug("This is a debug"); + log.trace("This is a trace"); + log.log({level:log.METRIC,msg:"testMetric"}); + + logEvents.filter(function(evt) { return evt.logger === 1}).should.have.lengthOf(6); + logEvents.filter(function(evt) { return evt.logger === 2}).should.have.lengthOf(6); + }); + + it('remove a custom log handler directly', function() { + var settings = {}; + log.init(settings); + + var logEvents = []; + var loggerOne = { + emit: function(event,msg) { + logEvents.push({logger:1,msg:msg}); + } + }; + var loggerTwo = { + emit: function(event,msg) { + logEvents.push({logger:2,msg:msg}); + } + }; + log.addHandler(loggerOne); + log.addHandler(loggerTwo); + + log.info("This is an info"); + logEvents.filter(function(evt) { return evt.logger === 1}).should.have.lengthOf(1); + logEvents.filter(function(evt) { return evt.logger === 2}).should.have.lengthOf(1); + + + log.removeHandler(loggerTwo); + log.info("This is an info"); + logEvents.filter(function(evt) { return evt.logger === 1}).should.have.lengthOf(2); + logEvents.filter(function(evt) { return evt.logger === 2}).should.have.lengthOf(1); + + log.removeHandler(loggerOne); + log.info("This is an info"); + logEvents.filter(function(evt) { return evt.logger === 1}).should.have.lengthOf(2); + logEvents.filter(function(evt) { return evt.logger === 2}).should.have.lengthOf(1); + + + }); + it('it can log without exception', function() { + var msg = { + msg: { + mystrangeobj:"hello", + }, + }; + msg.msg.toString = function(){ + throw new Error('Exception in toString - should have been caught'); + } + msg.msg.constructor = { name: "strangeobj" }; + var ret = log.info(msg.msg); + }); + it('it can log an object but use .message', function() { + var msg = { + msg: { + message: "my special message", + mystrangeobj:"hello", + }, + }; + var ret = log.info(msg.msg); + sinon.assert.calledWithMatch(util.log,"my special message"); + }); + + + +}); diff --git a/packages/connector/test/unit/@node-red/util/lib/util_spec.js b/packages/connector/test/unit/@node-red/util/lib/util_spec.js new file mode 100644 index 0000000..261dbc5 --- /dev/null +++ b/packages/connector/test/unit/@node-red/util/lib/util_spec.js @@ -0,0 +1,892 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +var should = require("should"); + +var NR_TEST_UTILS = require("nr-test-utils"); + +var util = NR_TEST_UTILS.require("@node-red/util").util; + +describe("@node-red/util/util", function() { + describe('generateId', function() { + it('generates an id', function() { + var id = util.generateId(); + var id2 = util.generateId(); + id.should.not.eql(id2); + }); + }); + describe('compareObjects', function() { + it('numbers', function() { + util.compareObjects(0,0).should.equal(true); + util.compareObjects(0,1).should.equal(false); + util.compareObjects(1000,1001).should.equal(false); + util.compareObjects(1000,1000).should.equal(true); + util.compareObjects(0,"0").should.equal(false); + util.compareObjects(1,"1").should.equal(false); + util.compareObjects(0,null).should.equal(false); + util.compareObjects(0,undefined).should.equal(false); + }); + it('strings', function() { + util.compareObjects("","").should.equal(true); + util.compareObjects("a","a").should.equal(true); + util.compareObjects("",null).should.equal(false); + util.compareObjects("",undefined).should.equal(false); + }); + + it('arrays', function() { + util.compareObjects(["a"],["a"]).should.equal(true); + util.compareObjects(["a"],["a","b"]).should.equal(false); + util.compareObjects(["a","b"],["b"]).should.equal(false); + util.compareObjects(["a"],"a").should.equal(false); + util.compareObjects([[1],["a"]],[[1],["a"]]).should.equal(true); + util.compareObjects([[1],["a"]],[["a"],[1]]).should.equal(false); + }); + it('objects', function() { + util.compareObjects({"a":1},{"a":1,"b":1}).should.equal(false); + util.compareObjects({"a":1,"b":1},{"a":1,"b":1}).should.equal(true); + util.compareObjects({"b":1,"a":1},{"a":1,"b":1}).should.equal(true); + }); + it('Buffer', function() { + util.compareObjects(Buffer.from("hello"),Buffer.from("hello")).should.equal(true); + util.compareObjects(Buffer.from("hello"),Buffer.from("hello ")).should.equal(false); + util.compareObjects(Buffer.from("hello"),"hello").should.equal(false); + }); + + }); + + describe('ensureString', function() { + it('strings are preserved', function() { + util.ensureString('string').should.equal('string'); + }); + it('Buffer is converted', function() { + var s = util.ensureString(Buffer.from('foo')); + s.should.equal('foo'); + (typeof s).should.equal('string'); + }); + it('Object is converted to JSON', function() { + var s = util.ensureString({foo: "bar"}); + (typeof s).should.equal('string'); + should.deepEqual(JSON.parse(s), {foo:"bar"}); + }); + it('stringifies other things', function() { + var s = util.ensureString(123); + (typeof s).should.equal('string'); + s.should.equal('123'); + }); + }); + + describe('ensureBuffer', function() { + it('Buffers are preserved', function() { + var b = Buffer.from(''); + util.ensureBuffer(b).should.equal(b); + }); + it('string is converted', function() { + var b = util.ensureBuffer('foo'); + var expected = Buffer.from('foo'); + for (var i = 0; i < expected.length; i++) { + b[i].should.equal(expected[i]); + } + Buffer.isBuffer(b).should.equal(true); + }); + it('Object is converted to JSON', function() { + var obj = {foo: "bar"} + var b = util.ensureBuffer(obj); + Buffer.isBuffer(b).should.equal(true); + should.deepEqual(JSON.parse(b), obj); + }); + it('stringifies other things', function() { + var b = util.ensureBuffer(123); + Buffer.isBuffer(b).should.equal(true); + var expected = Buffer.from('123'); + for (var i = 0; i < expected.length; i++) { + b[i].should.equal(expected[i]); + } + }); + }); + + describe('cloneMessage', function() { + it('clones a simple message', function() { + var msg = {string:"hi",array:[1,2,3],object:{a:1,subobject:{b:2}}}; + + var cloned = util.cloneMessage(msg); + + cloned.should.eql(msg); + + cloned.should.not.equal(msg); + cloned.array.should.not.equal(msg.string); + cloned.object.should.not.equal(msg.object); + cloned.object.subobject.should.not.equal(msg.object.subobject); + + cloned.should.not.have.property("req"); + cloned.should.not.have.property("res"); + }); + it('does not clone http req/res properties', function() { + var msg = {req:{a:1},res:{b:2}}; + + var cloned = util.cloneMessage(msg); + + cloned.should.eql(msg); + cloned.should.not.equal(msg); + + cloned.req.should.equal(msg.req); + cloned.res.should.equal(msg.res); + }); + it('handles undefined values without throwing an error', function() { + var result = util.cloneMessage(undefined); + should.not.exist(result); + }) + }); + describe('getObjectProperty', function() { + it('gets a property beginning with "msg."', function() { + // getMessageProperty strips off `msg.` prefixes. + // getObjectProperty does not + var obj = { msg: { a: "foo"}, a: "bar"}; + var v = util.getObjectProperty(obj,"msg.a"); + v.should.eql("foo"); + }) + }); + describe('getMessageProperty', function() { + it('retrieves a simple property', function() { + var v = util.getMessageProperty({a:"foo"},"msg.a"); + v.should.eql("foo"); + var v2 = util.getMessageProperty({a:"foo"},"a"); + v2.should.eql("foo"); + }); + it('should return undefined if property does not exist', function() { + var v = util.getMessageProperty({a:"foo"},"msg.b"); + should.not.exist(v); + }); + it('should throw error if property parent does not exist', function() { + /*jshint immed: false */ + (function() { + util.getMessageProperty({a:"foo"},"msg.a.b.c"); + }).should.throw(); + }); + it('retrieves a property with array syntax', function() { + var v = util.getMessageProperty({a:["foo","bar"]},"msg.a[0]"); + v.should.eql("foo"); + var v2 = util.getMessageProperty({a:[null,{b:"foo"}]},"a[1].b"); + v2.should.eql("foo"); + var v3 = util.getMessageProperty({a:[[["foo"]]]},"a[0][0][0]"); + v3.should.eql("foo"); + }); + + }); + describe('setObjectProperty', function() { + it('set a property beginning with "msg."', function() { + // setMessageProperty strips off `msg.` prefixes. + // setObjectProperty does not + var obj = {}; + util.setObjectProperty(obj,"msg.a","bar"); + obj.should.have.property("msg"); + obj.msg.should.have.property("a","bar"); + }) + }); + describe('setMessageProperty', function() { + it('sets a property', function() { + var msg = {a:"foo"}; + util.setMessageProperty(msg,"msg.a","bar"); + msg.a.should.eql('bar'); + }); + it('sets a deep level property', function() { + var msg = {a:{b:{c:"foo"}}}; + util.setMessageProperty(msg,"msg.a.b.c","bar"); + msg.a.b.c.should.eql('bar'); + }); + it('creates missing parent properties by default', function() { + var msg = {a:{}}; + util.setMessageProperty(msg,"msg.a.b.c","bar"); + msg.a.b.c.should.eql('bar'); + }) + it('does not create missing parent properties', function() { + var msg = {a:{}}; + util.setMessageProperty(msg,"msg.a.b.c","bar",false); + should.not.exist(msg.a.b); + }) + it('does not create missing parent properties with array', function () { + var msg = {a:{}}; + util.setMessageProperty(msg, "msg.a.b[1].c", "bar", false); + should.not.exist(msg.a.b); + }) + it('deletes property if value is undefined', function() { + var msg = {a:{b:{c:"foo"}}}; + util.setMessageProperty(msg,"msg.a.b.c",undefined); + should.not.exist(msg.a.b.c); + }) + it('does not create missing parent properties if value is undefined', function() { + var msg = {a:{}}; + util.setMessageProperty(msg,"msg.a.b.c",undefined); + should.not.exist(msg.a.b); + }); + it('sets a property with array syntax', function() { + var msg = {a:{b:["foo",{c:["",""]}]}}; + util.setMessageProperty(msg,"msg.a.b[1].c[1]","bar"); + msg.a.b[1].c[1].should.eql('bar'); + }); + it('creates missing array elements - final property', function() { + var msg = {a:[]}; + util.setMessageProperty(msg,"msg.a[2]","bar"); + msg.a.should.have.length(3); + msg.a[2].should.eql("bar"); + }); + it('creates missing array elements - mid property', function() { + var msg = {}; + util.setMessageProperty(msg,"msg.a[2].b","bar"); + msg.a.should.have.length(3); + msg.a[2].b.should.eql("bar"); + }); + it('creates missing array elements - multi-arrays', function() { + var msg = {}; + util.setMessageProperty(msg,"msg.a[2][2]","bar"); + msg.a.should.have.length(3); + msg.a.should.be.instanceOf(Array); + msg.a[2].should.have.length(3); + msg.a[2].should.be.instanceOf(Array); + msg.a[2][2].should.eql("bar"); + }); + it('does not create missing array elements - mid property', function () { + var msg = {a:[]}; + util.setMessageProperty(msg, "msg.a[1][1]", "bar", false); + msg.a.should.empty(); + }); + it('does not create missing array elements - final property', function() { + var msg = {a:{}}; + util.setMessageProperty(msg,"msg.a.b[2]","bar",false); + should.not.exist(msg.a.b); + // check it has not been misinterpreted + msg.a.should.not.have.property("b[2]"); + }); + it('deletes property inside array if value is undefined', function() { + var msg = {a:[1,2,3]}; + util.setMessageProperty(msg,"msg.a[1]",undefined); + msg.a.should.have.length(2); + msg.a[0].should.eql(1); + msg.a[1].should.eql(3); + }) + + }); + + describe('evaluateNodeProperty', function() { + it('returns string',function() { + var result = util.evaluateNodeProperty('hello','str'); + result.should.eql('hello'); + }); + it('returns number',function() { + var result = util.evaluateNodeProperty('0123','num'); + result.should.eql(123); + }); + it('returns evaluated json',function() { + var result = util.evaluateNodeProperty('{"a":123}','json'); + result.should.eql({a:123}); + }); + it('returns regex',function() { + var result = util.evaluateNodeProperty('^abc$','re'); + result.toString().should.eql("/^abc$/"); + }); + it('returns boolean',function() { + var result = util.evaluateNodeProperty('true','bool'); + result.should.be.true(); + result = util.evaluateNodeProperty('TrUe','bool'); + result.should.be.true(); + result = util.evaluateNodeProperty('false','bool'); + result.should.be.false(); + result = util.evaluateNodeProperty('','bool'); + result.should.be.false(); + }); + it('returns date',function() { + var result = util.evaluateNodeProperty('','date'); + (Date.now() - result).should.be.approximately(0,50); + }); + it('returns bin', function () { + var result = util.evaluateNodeProperty('[1, 2]','bin'); + result[0].should.eql(1); + result[1].should.eql(2); + }); + it('returns msg property',function() { + var result = util.evaluateNodeProperty('foo.bar','msg',{},{foo:{bar:"123"}}); + result.should.eql("123"); + }); + it('throws an error if callback is not defined', function (done) { + try { + util.evaluateNodeProperty(' ','msg',{},{foo:{bar:"123"}}); + done("should throw an error"); + } catch (err) { + done(); + } + }); + it('returns flow property',function() { + var result = util.evaluateNodeProperty('foo.bar','flow',{ + context:function() { return { + flow: { get: function(k) { + if (k === 'foo.bar') { + return '123'; + } else { + return null; + } + }} + }} + },{}); + result.should.eql("123"); + }); + it('returns global property',function() { + var result = util.evaluateNodeProperty('foo.bar','global',{ + context:function() { return { + global: { get: function(k) { + if (k === 'foo.bar') { + return '123'; + } else { + return null; + } + }} + }} + },{}); + result.should.eql("123"); + }); + it('returns jsonata result', function () { + var result = util.evaluateNodeProperty('$abs(-1)','jsonata',{},{}); + result.should.eql(1); + }); + it('returns null', function() { + var result = util.evaluateNodeProperty(null,'null'); + (result === null).should.be.true(); + }) + describe('environment variable', function() { + before(function() { + process.env.NR_TEST_A = "foo"; + process.env.NR_TEST_B = "${NR_TEST_A}"; + }) + after(function() { + delete process.env.NR_TEST_A; + delete process.env.NR_TEST_B; + }) + + it('returns an environment variable - NR_TEST_A', function() { + var result = util.evaluateNodeProperty('NR_TEST_A','env'); + result.should.eql('foo'); + }); + it('returns an environment variable - ${NR_TEST_A}', function() { + var result = util.evaluateNodeProperty('${NR_TEST_A}','env'); + result.should.eql('foo'); + }); + it('returns an environment variable - ${NR_TEST_A', function() { + var result = util.evaluateNodeProperty('${NR_TEST_A','env'); + result.should.eql(''); + }); + it('returns an environment variable - foo${NR_TEST_A}bar', function() { + var result = util.evaluateNodeProperty('123${NR_TEST_A}456','env'); + result.should.eql('123foo456'); + }); + it('returns an environment variable - foo${NR_TEST_B}bar', function() { + var result = util.evaluateNodeProperty('123${NR_TEST_B}456','env'); + result.should.eql('123${NR_TEST_A}456'); + }); + + }); + }); + + describe('normalisePropertyExpression', function() { + function testABC(input,expected) { + var result = util.normalisePropertyExpression(input); + // console.log("+",input); + // console.log(result); + result.should.eql(expected); + } + + function testInvalid(input) { + /*jshint immed: false */ + (function() { + util.normalisePropertyExpression(input); + }).should.throw(); + } + it('pass a.b.c',function() { testABC('a.b.c',['a','b','c']); }) + it('pass a["b"]["c"]',function() { testABC('a["b"]["c"]',['a','b','c']); }) + it('pass a["b"].c',function() { testABC('a["b"].c',['a','b','c']); }) + it("pass a['b'].c",function() { testABC("a['b'].c",['a','b','c']); }) + + it("pass a[0].c",function() { testABC("a[0].c",['a',0,'c']); }) + it("pass a.0.c",function() { testABC("a.0.c",['a',0,'c']); }) + it("pass a['a.b[0]'].c",function() { testABC("a['a.b[0]'].c",['a','a.b[0]','c']); }) + it("pass a[0][0][0]",function() { testABC("a[0][0][0]",['a',0,0,0]); }) + it("pass '1.2.3.4'",function() { testABC("'1.2.3.4'",['1.2.3.4']); }) + it("pass 'a.b'[1]",function() { testABC("'a.b'[1]",['a.b',1]); }) + it("pass 'a.b'.c",function() { testABC("'a.b'.c",['a.b','c']); }) + + + it('pass a.$b.c',function() { testABC('a.$b.c',['a','$b','c']); }) + it('pass a["$b"].c',function() { testABC('a["$b"].c',['a','$b','c']); }) + it('pass a._b.c',function() { testABC('a._b.c',['a','_b','c']); }) + it('pass a["_b"].c',function() { testABC('a["_b"].c',['a','_b','c']); }) + + it("fail a'b'.c",function() { testInvalid("a'b'.c"); }) + it("fail a['b'.c",function() { testInvalid("a['b'.c"); }) + it("fail a[]",function() { testInvalid("a[]"); }) + it("fail a]",function() { testInvalid("a]"); }) + it("fail a[",function() { testInvalid("a["); }) + it("fail a[0d]",function() { testInvalid("a[0d]"); }) + it("fail a['",function() { testInvalid("a['"); }) + it("fail a[']",function() { testInvalid("a[']"); }) + it("fail a[0']",function() { testInvalid("a[0']"); }) + it("fail a.[0]",function() { testInvalid("a.[0]"); }) + it("fail [0]",function() { testInvalid("[0]"); }) + it("fail a[0",function() { testInvalid("a[0"); }) + it("fail a.",function() { testInvalid("a."); }) + it("fail .a",function() { testInvalid(".a"); }) + it("fail a. b",function() { testInvalid("a. b"); }) + it("fail a.b",function() { testInvalid(" a.b"); }) + it("fail a[0].[1]",function() { testInvalid("a[0].[1]"); }) + it("fail a['']",function() { testInvalid("a['']"); }) + it("fail 'a.b'c",function() { testInvalid("'a.b'c"); }) + it("fail <blank>",function() { testInvalid("");}) + + }); + + describe('normaliseNodeTypeName', function() { + function normalise(input, expected) { + var result = util.normaliseNodeTypeName(input); + result.should.eql(expected); + } + + it('pass blank',function() { normalise("", "") }); + it('pass ab1',function() { normalise("ab1", "ab1") }); + it('pass AB1',function() { normalise("AB1", "aB1") }); + it('pass a b 1',function() { normalise("a b 1", "aB1") }); + it('pass a-b-1',function() { normalise("a-b-1", "aB1") }); + it('pass ab1 ',function() { normalise(" ab1 ", "ab1") }); + it('pass _a_b_1_',function() { normalise("_a_b_1_", "aB1") }); + it('pass http request',function() { normalise("http request", "httpRequest") }); + it('pass HttpRequest',function() { normalise("HttpRequest", "httpRequest") }); + }); + + describe('prepareJSONataExpression', function() { + it('prepares an expression', function() { + var result = util.prepareJSONataExpression('payload',{}); + result.should.have.property('evaluate'); + result.should.have.property('assign'); + result.should.have.property('_legacyMode', false); + }); + it('prepares a legacyMode expression', function() { + var result = util.prepareJSONataExpression('msg.payload',{}); + result.should.have.property('evaluate'); + result.should.have.property('assign'); + result.should.have.property('_legacyMode', true); + }); + }); + describe('evaluateJSONataExpression', function() { + it('evaluates an expression', function() { + var expr = util.prepareJSONataExpression('payload',{}); + var result = util.evaluateJSONataExpression(expr,{payload:"hello"}); + result.should.eql("hello"); + }); + it('evaluates a legacyMode expression', function() { + var expr = util.prepareJSONataExpression('msg.payload',{}); + var result = util.evaluateJSONataExpression(expr,{payload:"hello"}); + result.should.eql("hello"); + }); + it('accesses flow context from an expression', function() { + var expr = util.prepareJSONataExpression('$flowContext("foo")',{context:function() { return {flow:{get: function(key) { return {'foo':'bar'}[key]}}}}}); + var result = util.evaluateJSONataExpression(expr,{payload:"hello"}); + result.should.eql("bar"); + }); + it('accesses environment variable from an expression', function() { + process.env.UTIL_ENV = 'foo'; + var expr = util.prepareJSONataExpression('$env("UTIL_ENV")',{}); + var result = util.evaluateJSONataExpression(expr,{}); + result.should.eql('foo'); + }); + it('handles non-existant flow context variable', function() { + var expr = util.prepareJSONataExpression('$flowContext("nonExistant")',{context:function() { return {flow:{get: function(key) { return {'foo':'bar'}[key]}}}}}); + var result = util.evaluateJSONataExpression(expr,{payload:"hello"}); + should.not.exist(result); + }); + it('handles non-existant global context variable', function() { + var expr = util.prepareJSONataExpression('$globalContext("nonExistant")',{context:function() { return {global:{get: function(key) { return {'foo':'bar'}[key]}}}}}); + var result = util.evaluateJSONataExpression(expr,{payload:"hello"}); + should.not.exist(result); + }); + it('handles async flow context access', function(done) { + var expr = util.prepareJSONataExpression('$flowContext("foo")',{context:function() { return {flow:{get: function(key,store,callback) { setTimeout(()=>{callback(null,{'foo':'bar'}[key])},10)}}}}}); + util.evaluateJSONataExpression(expr,{payload:"hello"},function(err,value) { + try { + should.not.exist(err); + value.should.eql("bar"); + done(); + } catch(err2) { + done(err2); + } + }); + }) + it('handles async global context access', function(done) { + var expr = util.prepareJSONataExpression('$globalContext("foo")',{context:function() { return {global:{get: function(key,store,callback) { setTimeout(()=>{callback(null,{'foo':'bar'}[key])},10)}}}}}); + util.evaluateJSONataExpression(expr,{payload:"hello"},function(err,value) { + try { + should.not.exist(err); + value.should.eql("bar"); + done(); + } catch(err2) { + done(err2); + } + }); + }) + it('handles persistable store in flow context access', function(done) { + var storeName; + var expr = util.prepareJSONataExpression('$flowContext("foo", "flowStoreName")',{context:function() { return {flow:{get: function(key,store,callback) { storeName = store;setTimeout(()=>{callback(null,{'foo':'bar'}[key])},10)}}}}}); + util.evaluateJSONataExpression(expr,{payload:"hello"},function(err,value) { + try { + should.not.exist(err); + value.should.eql("bar"); + storeName.should.equal("flowStoreName"); + done(); + } catch(err2) { + done(err2); + } + }); + }) + it('handles persistable store in global context access', function(done) { + var storeName; + var expr = util.prepareJSONataExpression('$globalContext("foo", "globalStoreName")',{context:function() { return {global:{get: function(key,store,callback) { storeName = store;setTimeout(()=>{callback(null,{'foo':'bar'}[key])},10)}}}}}); + util.evaluateJSONataExpression(expr,{payload:"hello"},function(err,value) { + try { + should.not.exist(err); + value.should.eql("bar"); + storeName.should.equal("globalStoreName"); + done(); + } catch(err2) { + done(err2); + } + }); + }) + it('callbacks with error when invalid expression was specified', function (done) { + var expr = util.prepareJSONataExpression('$abc(1)',{}); + var result = util.evaluateJSONataExpression(expr,{payload:"hello"},function(err,value){ + should.exist(err); + done(); + }); + }); + }); + + describe('encodeObject', function () { + it('encodes Error with message', function() { + var err = new Error("encode error"); + err.name = 'encodeError'; + var msg = {msg:err}; + var result = util.encodeObject(msg); + result.format.should.eql("error"); + var resultJson = JSON.parse(result.msg); + resultJson.name.should.eql('encodeError'); + resultJson.message.should.eql('encode error'); + }); + it('encodes Error without message', function() { + var err = new Error(); + err.name = 'encodeError'; + err.toString = function(){return 'error message';} + var msg = {msg:err}; + var result = util.encodeObject(msg); + result.format.should.eql("error"); + var resultJson = JSON.parse(result.msg); + resultJson.name.should.eql('encodeError'); + resultJson.message.should.eql('error message'); + }); + it('encodes Buffer', function() { + var msg = {msg:Buffer.from("abc")}; + var result = util.encodeObject(msg,{maxLength:4}); + result.format.should.eql("buffer[3]"); + result.msg[0].should.eql('6'); + result.msg[1].should.eql('1'); + result.msg[2].should.eql('6'); + result.msg[3].should.eql('2'); + }); + it('encodes function', function() { + var msg = {msg:function(){}}; + var result = util.encodeObject(msg); + result.format.should.eql("function"); + result.msg.should.eql('[function]'); + }); + it('encodes boolean', function() { + var msg = {msg:true}; + var result = util.encodeObject(msg); + result.format.should.eql("boolean"); + result.msg.should.eql('true'); + }); + it('encodes number', function() { + var msg = {msg:123}; + var result = util.encodeObject(msg); + result.format.should.eql("number"); + result.msg.should.eql('123'); + }); + it('encodes 0', function() { + var msg = {msg:0}; + var result = util.encodeObject(msg); + result.format.should.eql("number"); + result.msg.should.eql('0'); + }); + it('encodes null', function() { + var msg = {msg:null}; + var result = util.encodeObject(msg); + result.format.should.eql("null"); + result.msg.should.eql('(undefined)'); + }); + it('encodes undefined', function() { + var msg = {msg:undefined}; + var result = util.encodeObject(msg); + result.format.should.eql("undefined"); + result.msg.should.eql('(undefined)'); + }); + it('encodes string', function() { + var msg = {msg:'1234567890'}; + var result = util.encodeObject(msg,{maxLength:6}); + result.format.should.eql("string[10]"); + result.msg.should.eql('123456...'); + }); + describe('encode object', function() { + it('object', function() { + var msg = { msg:{"foo":"bar"} }; + var result = util.encodeObject(msg); + result.format.should.eql("Object"); + var resultJson = JSON.parse(result.msg); + resultJson.foo.should.eql('bar'); + }); + it('object whose name includes error', function() { + function MyErrorObj(){ + this.name = 'my error obj'; + this.message = 'my error message'; + }; + var msg = { msg:new MyErrorObj() }; + var result = util.encodeObject(msg); + result.format.should.eql("MyErrorObj"); + var resultJson = JSON.parse(result.msg); + resultJson.name.should.eql('my error obj'); + resultJson.message.should.eql('my error message'); + }); + it('constructor of IncomingMessage', function() { + function IncomingMessage(){}; + var msg = { msg:new IncomingMessage() }; + var result = util.encodeObject(msg); + result.format.should.eql("Object"); + var resultJson = JSON.parse(result.msg); + resultJson.should.empty(); + }); + it('_req key in msg', function() { + function Socket(){}; + var msg = { msg:{"_req":123} }; + var result = util.encodeObject(msg); + result.format.should.eql("Object"); + var resultJson = JSON.parse(result.msg); + resultJson._req.__enc__.should.eql(true); + resultJson._req.type.should.eql('internal'); + }); + it('_res key in msg', function() { + function Socket(){}; + var msg = { msg:{"_res":123} }; + var result = util.encodeObject(msg); + result.format.should.eql("Object"); + var resultJson = JSON.parse(result.msg); + resultJson._res.__enc__.should.eql(true); + resultJson._res.type.should.eql('internal'); + }); + it('array of error', function() { + var msg = { msg:[new Error("encode error")] }; + var result = util.encodeObject(msg); + result.format.should.eql("array[1]"); + var resultJson = JSON.parse(result.msg); + resultJson[0].should.eql('Error: encode error'); + }); + it('long array in msg', function() { + var msg = {msg:{array:[1,2,3,4]}}; + var result = util.encodeObject(msg,{maxLength:2}); + result.format.should.eql("Object"); + var resultJson = JSON.parse(result.msg); + resultJson.array.__enc__.should.eql(true); + resultJson.array.data[0].should.eql(1); + resultJson.array.data[1].should.eql(2); + resultJson.array.length.should.eql(4); + }); + it('array of string', function() { + var msg = { msg:["abcde","12345"] }; + var result = util.encodeObject(msg,{maxLength:3}); + result.format.should.eql("array[2]"); + var resultJson = JSON.parse(result.msg); + resultJson[0].should.eql('abc...'); + resultJson[1].should.eql('123...'); + }); + it('array of function', function() { + var msg = { msg:[function(){}] }; + var result = util.encodeObject(msg); + result.format.should.eql("array[1]"); + var resultJson = JSON.parse(result.msg); + resultJson[0].__enc__.should.eql(true); + resultJson[0].type.should.eql('function'); + }); + it('array of number', function() { + var msg = { msg:[1,2,3] }; + var result = util.encodeObject(msg,{maxLength:2}); + result.format.should.eql("array[3]"); + var resultJson = JSON.parse(result.msg); + resultJson.__enc__.should.eql(true); + resultJson.data[0].should.eql(1); + resultJson.data[1].should.eql(2); + resultJson.data.length.should.eql(2); + resultJson.length.should.eql(3); + }); + it('array of special number', function() { + var msg = { msg:[NaN,Infinity,-Infinity] }; + var result = util.encodeObject(msg); + result.format.should.eql("array[3]"); + var resultJson = JSON.parse(result.msg); + resultJson[0].__enc__.should.eql(true); + resultJson[0].type.should.eql('number'); + resultJson[0].data.should.eql('NaN'); + resultJson[1].data.should.eql('Infinity'); + resultJson[2].data.should.eql('-Infinity'); + }); + it('constructor of Buffer in msg', function() { + var msg = { msg:{buffer:Buffer.from([1,2,3,4])} }; + var result = util.encodeObject(msg,{maxLength:2}); + result.format.should.eql("Object"); + var resultJson = JSON.parse(result.msg); + resultJson.buffer.__enc__.should.eql(true); + resultJson.buffer.length.should.eql(4); + resultJson.buffer.data[0].should.eql(1); + resultJson.buffer.data[1].should.eql(2); + }); + it('constructor of ServerResponse', function() { + function ServerResponse(){}; + var msg = { msg: new ServerResponse() }; + var result = util.encodeObject(msg); + result.format.should.eql("Object"); + var resultJson = JSON.parse(result.msg); + resultJson.should.eql('[internal]'); + }); + it('constructor of Socket in msg', function() { + function Socket(){}; + var msg = { msg: { socket: new Socket() } }; + var result = util.encodeObject(msg); + result.format.should.eql("Object"); + var resultJson = JSON.parse(result.msg); + resultJson.socket.should.eql('[internal]'); + }); + it('object which fails to serialise', function(done) { + var msg = { + msg: { + obj:{ + cantserialise:{ + message:'this will not be displayed', + toJSON: function(val) { + throw 'this exception should have been caught'; + return 'should not display because we threw first'; + }, + }, + canserialise:{ + message:'this should be displayed', + } + }, + } + }; + var result = util.encodeObject(msg); + result.format.should.eql("error"); + var success = (result.msg.indexOf('cantserialise') > 0); + success &= (result.msg.indexOf('this exception should have been caught') > 0); + success &= (result.msg.indexOf('canserialise') > 0); + success.should.eql(1); + done(); + }); + it('object which fails to serialise - different error type', function(done) { + var msg = { + msg: { + obj:{ + cantserialise:{ + message:'this will not be displayed', + toJSON: function(val) { + throw new Error('this exception should have been caught'); + return 'should not display because we threw first'; + }, + }, + canserialise:{ + message:'this should be displayed', + } + }, + } + }; + var result = util.encodeObject(msg); + result.format.should.eql("error"); + var success = (result.msg.indexOf('cantserialise') > 0); + success &= (result.msg.indexOf('this exception should have been caught') > 0); + success &= (result.msg.indexOf('canserialise') > 0); + success.should.eql(1); + done(); + }); + it('very large object which fails to serialise should be truncated', function(done) { + var msg = { + msg: { + obj:{ + big:"", + cantserialise:{ + message:'this will not be displayed', + toJSON: function(val) { + throw new Error('this exception should have been caught'); + return 'should not display because we threw first'; + }, + }, + canserialise:{ + message:'this should be displayed', + } + }, + } + }; + + for (var i = 0; i < 1000; i++) { + msg.msg.obj.big += 'some more string '; + } + + var result = util.encodeObject(msg); + result.format.should.eql("error"); + var resultJson = JSON.parse(result.msg); + var success = (resultJson.message.length <= 1000); + success.should.eql(true); + done(); + }); + it('test bad toString', function(done) { + var msg = { + msg: { + mystrangeobj:"hello", + }, + }; + msg.msg.toString = function(){ + throw new Error('Exception in toString - should have been caught'); + } + msg.msg.constructor = { name: "strangeobj" }; + + var result = util.encodeObject(msg); + var success = (result.msg.indexOf('[Type not printable]') >= 0); + success.should.eql(true); + done(); + }); + it('test bad object constructor', function(done) { + var msg = { + msg: { + mystrangeobj:"hello", + constructor: { + get name(){ + throw new Error('Exception in constructor name'); + } + } + }, + }; + var result = util.encodeObject(msg); + done(); + }); + + }); + }); +}); diff --git a/packages/connector/test/unit/_spec.js b/packages/connector/test/unit/_spec.js new file mode 100644 index 0000000..d099836 --- /dev/null +++ b/packages/connector/test/unit/_spec.js @@ -0,0 +1,87 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +/** + * This test simply checks that for every .js file there exists + * a *_spec.js file under ./test correspondingly. + */ + +/** + * Currently we're only checking the core components under ./red + * TODO: Increase the scope of this check + */ + +var fs = require("fs-extra"); +var should = require("should"); +var path = require('path'); + +// Directories to check with .js files and _spec.js files respectively +var rootdir = path.resolve(__dirname, "../.."); +var jsdir = path.resolve(__dirname, "../../packages/node_modules/"); +var testdir = path.resolve(__dirname); + +var walkDirectory = function(dir) { + var p = fs.readdir(dir); + var errors = []; + return p.then(function(list) { + var promises = []; + list.forEach(function(file) { + var filePath = path.join(dir,file); + + if (!/@node-red\/(editor-client|nodes)/.test(filePath) && !/node-red\/settings\.js/.test(filePath) && !/\/docs\//.test(filePath)) { + promises.push(fs.stat(filePath).then(function(stat){ + if (stat.isDirectory()) { + return walkDirectory(filePath).then(function(results) { + if (results) { + errors = errors.concat(results); + } + }); + } else if (/\.js$/.test(filePath)) { + var testFile = filePath.replace(jsdir, testdir).replace(".js", "_spec.js"); + return fs.exists(testFile).then(function(exists) { + if (!exists) { + errors.push(testFile.substring(rootdir.length+1)); + } else { + return fs.stat(testFile).then(function(stat) { + if (stat.size === 0) { + errors.push("[empty] "+testFile.substring(rootdir.length+1)); + } + }) + } + }); + } + })); + } + }); + return Promise.all(promises).then(function() { + return errors; + }) + }); +} + +describe('_spec.js', function() { + this.timeout(50000); // we might not finish within the Mocha default timeout limit, project will also grow + it('is checking if all .js files have a corresponding _spec.js test file.', function(done) { + walkDirectory(jsdir).then(function(errors) { + if (errors.length > 0) { + var error = new Error("Missing/empty _spec files:\n\t"+errors.join("\n\t")); + done(error); + } else { + done(); + } + }); + }); +}); diff --git a/packages/connector/test/unit/node-red/lib/red_spec.js b/packages/connector/test/unit/node-red/lib/red_spec.js new file mode 100644 index 0000000..e5d986f --- /dev/null +++ b/packages/connector/test/unit/node-red/lib/red_spec.js @@ -0,0 +1,76 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +var should = require("should"); +var sinon = require("sinon"); +var fs = require("fs"); +var path = require("path"); + + +var NR_TEST_UTILS = require("nr-test-utils"); + +var api = NR_TEST_UTILS.require("@node-red/runtime/lib/api"); + +var RED = NR_TEST_UTILS.require("node-red"); + +var runtime = NR_TEST_UTILS.require("@node-red/runtime"); +var api = NR_TEST_UTILS.require("@node-red/runtime/lib/api"); + + +describe("red/red", function() { + + // describe("check build", function() { + // beforeEach(function() { + // sinon.stub(runtime,"init",function() {}); + // sinon.stub(api,"init",function() {}); + // // sinon.stub(RED,"version",function() { return "version";}); + // }); + // afterEach(function() { + // runtime.init.restore(); + // api.init.restore(); + // fs.statSync.restore(); + // // RED.version.restore(); + // }); + // it.skip('warns if build has not been run',function() { + // sinon.stub(fs,"statSync",function() { throw new Error();}); + // + // /*jshint immed: false */ + // (function() { + // RED.init({},{}); + // }).should.throw("Node-RED not built"); + // }); + // it('passed if build has been run',function() { + // sinon.stub(fs,"statSync",function() { }); + // RED.init({},{}); + // }); + // }); + + describe("externals", function() { + it('reports version', function() { + /\d+\.\d+\.\d+(-git)?/.test(RED.version()).should.be.true(); + }); + it.skip('access server externals', function() { + // TODO: unstubable accessors - need to make this testable + // RED.app; + // RED.httpAdmin; + // RED.httpNode; + // RED.server; + }); + it.skip('only initialises api component if httpAdmin enabled'); + it.skip('stubs httpAdmin if httpAdmin disabled'); + it.skip('stubs httpNode if httpNode disabled'); + }); + +}); diff --git a/packages/connector/test/unit/node-red/red_spec.js b/packages/connector/test/unit/node-red/red_spec.js new file mode 100644 index 0000000..ee46fc5 --- /dev/null +++ b/packages/connector/test/unit/node-red/red_spec.js @@ -0,0 +1,21 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var NR_TEST_UTILS = require("nr-test-utils"); + +describe("node-red/red", function() { + it.skip("NEEDS TESTS WRITING",function() {}); +}); diff --git a/packages/connector/yarn.lock b/packages/connector/yarn.lock new file mode 100644 index 0000000..6eb1ab1 --- /dev/null +++ b/packages/connector/yarn.lock @@ -0,0 +1,7754 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/parser@^7.4.4": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8" + integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA== + +"@babel/runtime@^7.3.1": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" + integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== + dependencies: + regenerator-runtime "^0.13.4" + +"@prantlf/jsonlint@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@prantlf/jsonlint/-/jsonlint-6.2.1.tgz#6a2b42b9909d1f18051d7892ae107807add4a368" + integrity sha512-/qPFlMyAYpebu+xS7W9XUlpBrpWyHq9ElslIxfOpfKOxWy+p++gicvxtn7f4GJQ3ikyM738/IIDf6Ngl9ta18w== + dependencies: + ajv "6.10.0" + commander "2.20.0" + +"@sinonjs/commons@^1", "@sinonjs/commons@^1.3.0", "@sinonjs/commons@^1.7.0": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.1.tgz#da5fd19a5f71177a53778073978873964f49acf1" + integrity sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/formatio@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2" + integrity sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg== + dependencies: + samsam "1.3.0" + +"@sinonjs/formatio@^3.2.1": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-3.2.2.tgz#771c60dfa75ea7f2d68e3b94c7e888a78781372c" + integrity sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ== + dependencies: + "@sinonjs/commons" "^1" + "@sinonjs/samsam" "^3.1.0" + +"@sinonjs/samsam@^3.1.0": + version "3.3.3" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-3.3.3.tgz#46682efd9967b259b81136b9f120fd54585feb4a" + integrity sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ== + dependencies: + "@sinonjs/commons" "^1.3.0" + array-from "^2.1.1" + lodash "^4.17.15" + +"@sinonjs/text-encoding@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" + integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +abbrev@1.0.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= + +abstract-leveldown@^2.0.3: + version "2.7.2" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz#87a44d7ebebc341d59665204834c8b7e0932cc93" + integrity sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w== + dependencies: + xtend "~4.0.0" + +abstract-leveldown@~0.12.1: + version "0.12.4" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-0.12.4.tgz#29e18e632e60e4e221d5810247852a63d7b2e410" + integrity sha1-KeGOYy5g5OIh1YECR4UqY9ey5BA= + dependencies: + xtend "~3.0.0" + +abstract-leveldown@~2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.4.1.tgz#b3bfedb884eb693a12775f0c55e9f0a420ccee64" + integrity sha1-s7/tuITraToSd18MVenwpCDM7mQ= + dependencies: + xtend "~4.0.0" + +abstract-leveldown@~2.6.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz#1c5e8c6a5ef965ae8c35dfb3a8770c476b82c4b8" + integrity sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA== + dependencies: + xtend "~4.0.0" + +accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" + integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== + +after@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= + +agent-base@6: + version "6.0.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.0.tgz#5d0101f19bbfaed39980b22ae866de153b93f09a" + integrity sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw== + dependencies: + debug "4" + +ajv@6.10.0: + version "6.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" + integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@6.12.0, ajv@^6.5.5: + version "6.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" + integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + +amqp@~0.2.4: + version "0.2.7" + resolved "https://registry.yarnpkg.com/amqp/-/amqp-0.2.7.tgz#738cfc45fd9c99260b45d5fafc32ed000841e1b1" + integrity sha1-c4z8Rf2cmSYLRdX6/DLtAAhB4bE= + dependencies: + lodash "^4.0.0" + +amqplib@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/amqplib/-/amqplib-0.4.2.tgz#5e4a2a914ccb3125f9cb91f6da07c97aa4cb13a6" + integrity sha1-XkoqkUzLMSX5y5H22gfJeqTLE6Y= + dependencies: + bitsyntax "~0.0.4" + buffer-more-ints "0.0.2" + readable-stream "1.x >=1.1.9" + when "~3.6.2" + +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= + dependencies: + string-width "^2.0.0" + +ansi-escape-sequences@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz#2483c8773f50dd9174dd9557e92b1718f1816097" + integrity sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw== + dependencies: + array-back "^3.0.1" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi@^0.3.0, ansi@~0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/ansi/-/ansi-0.3.1.tgz#0c42d4fb17160d5a9af1e484bace1c66922c1b21" + integrity sha1-DELU+xcWDVqa8eSEus4cZpIsGyE= + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +append-field@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" + integrity sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY= + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +archiver-utils@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-1.3.0.tgz#e50b4c09c70bf3d680e32ff1b7994e9f9d895174" + integrity sha1-5QtMCccL89aA4y/xt5lOn52JUXQ= + dependencies: + glob "^7.0.0" + graceful-fs "^4.1.0" + lazystream "^1.0.0" + lodash "^4.8.0" + normalize-path "^2.0.0" + readable-stream "^2.0.0" + +archiver@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/archiver/-/archiver-1.3.0.tgz#4f2194d6d8f99df3f531e6881f14f15d55faaf22" + integrity sha1-TyGU1tj5nfP1MeaIHxTxXVX6ryI= + dependencies: + archiver-utils "^1.3.0" + async "^2.0.0" + buffer-crc32 "^0.2.1" + glob "^7.0.0" + lodash "^4.8.0" + readable-stream "^2.0.0" + tar-stream "^1.5.0" + walkdir "^0.0.11" + zip-stream "^1.1.0" + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-back@^1.0.2, array-back@^1.0.3, array-back@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-1.0.4.tgz#644ba7f095f7ffcf7c43b5f0dc39d3c1f03c063b" + integrity sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs= + dependencies: + typical "^2.6.0" + +array-back@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-2.0.0.tgz#6877471d51ecc9c9bfa6136fb6c7d5fe69748022" + integrity sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw== + dependencies: + typical "^2.6.1" + +array-back@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" + integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== + +array-each@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" + integrity sha1-p5SvDAWrF1KEbudTofIRoFugxE8= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-from@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" + integrity sha1-z+nYwmYoudxa7MYqn12PHzUsEZU= + +array-index@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-index/-/array-index-1.0.0.tgz#ec56a749ee103e4e08c790b9c353df16055b97f9" + integrity sha1-7FanSe4QPk4Ix5C5w1PfFgVbl/k= + dependencies: + debug "^2.2.0" + es6-symbol "^3.0.2" + +array-slice@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4" + integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w== + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +ascoltatori@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ascoltatori/-/ascoltatori-3.2.0.tgz#1683bd87e308a73c918e3b99ab2683b0253c8967" + integrity sha1-FoO9h+MIpzyRjjuZqyaDsCU8iWc= + dependencies: + debug "^2.2.0" + node-uuid "~1.4.3" + qlobber "~0.7.0" + steed "^1.1.3" + optionalDependencies: + amqp "~0.2.4" + amqplib "~0.4.1" + eventemitter2 "^2.1.3" + ioredis "^2.3.0" + kafka-node "~0.5.8" + kerberos "~0.0" + mongodb "^2.1.18" + mqtt "^1.10.0" + msgpack-lite "^0.1.20" + qlobber-fsq "~3.2.4" + zmq "^2.14.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +async-cache@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/async-cache/-/async-cache-1.1.0.tgz#4a9a5a89d065ec5d8e5254bd9ee96ba76c532b5a" + integrity sha1-SppaidBl7F2OUlS9nulrp2xTK1o= + dependencies: + lru-cache "^4.0.0" + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-foreach@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" + integrity sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI= + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async@1.x, "async@>0.9 <2.0", async@^1.2.1, async@^1.4.0, async@~1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + +async@^2.0.0, async@^2.6.0, async@^2.6.1: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +async@~0.1.22: + version "0.1.22" + resolved "https://registry.yarnpkg.com/async/-/async-0.1.22.tgz#0fc1aaa088a0e3ef0ebe2d8831bab0dcf8845061" + integrity sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE= + +async@~0.2.7: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E= + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" + integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== + +babylon@7.0.0-beta.19: + version "7.0.0-beta.19" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.19.tgz#e928c7e807e970e0536b078ab3e0c48f9e052503" + integrity sha512-Vg0C9s/REX6/WIXN37UKpv5ZhRi6A4pjHlpkE34+8/a6c2W1Q692n3hmc+SZG5lKRnaExLUbxtJ1SVT+KaCQ/A== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +basic-auth@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" + integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== + dependencies: + safe-buffer "5.1.2" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +bcrypt@3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-3.0.6.tgz#f607846df62d27e60d5e795612c4f67d70206eb2" + integrity sha512-taA5bCTfXe7FUjKroKky9EXpdhkVvhE5owfxfLYodbrAR1Ul3juLmIQmIQBK4L9a5BuUcE6cqmwT+Da20lF9tg== + dependencies: + nan "2.13.2" + node-pre-gyp "0.12.0" + +bcryptjs@2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" + integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms= + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" + integrity sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk= + dependencies: + buffers "~0.1.1" + chainsaw "~0.1.0" + +bindings@1.2.1, bindings@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.2.1.tgz#14ad6113812d2d37d72e67b4cacb4bb726505f11" + integrity sha1-FK1hE4EtLTfXLme0ystLtyZQXxE= + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bitsyntax@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/bitsyntax/-/bitsyntax-0.0.4.tgz#eb10cc6f82b8c490e3e85698f07e83d46e0cba82" + integrity sha1-6xDMb4K4xJDj6FaY8H6D1G4MuoI= + dependencies: + buffer-more-ints "0.0.2" + +bl@^1.0.0, bl@^1.2.1, bl@~1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" + integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + +bl@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-0.8.2.tgz#c9b6bca08d1bc2ea00fc8afb4f1a5fd1e1c66e4e" + integrity sha1-yba8oI0bwuoA/Ir7Txpf0eHGbk4= + dependencies: + readable-stream "~1.0.26" + +bl@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-3.0.0.tgz#3611ec00579fd18561754360b21e9f784500ff88" + integrity sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A== + dependencies: + readable-stream "^3.0.1" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +bluebird@^2.9.34: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" + integrity sha1-U0uQM8AiyVecVro7Plpcqvu2UOE= + +bluebird@^3.3.4, bluebird@^3.5.4: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bluebird@~3.5.0: + version "3.5.5" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f" + integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w== + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + 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.17" + +body@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/body/-/body-5.1.0.tgz#e4ba0ce410a46936323367609ecb4e6553125069" + integrity sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk= + dependencies: + continuable-cache "^0.3.1" + error "^7.0.0" + raw-body "~1.1.0" + safe-json-parse "~1.0.1" + +boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +boxen@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brfs@~1.4.2: + version "1.4.4" + resolved "https://registry.yarnpkg.com/brfs/-/brfs-1.4.4.tgz#fc316bc4880180fa8ee25bcaab65f86910ce1dd5" + integrity sha512-rX2qc9hkpLPiwdu1HkLY642rwwo3X6N+ZPyEPdNn3OUKV/B2BRP7dHdnkhGantOJLVoTluNYBi4VecHb2Kq2hw== + dependencies: + quote-stream "^1.0.1" + resolve "^1.1.5" + static-module "^2.1.1" + through2 "^2.0.0" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +bson@~0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/bson/-/bson-0.4.23.tgz#e65a2e3c7507ffade4109bc7575a76e50f8da915" + integrity sha1-5louPHUH/63kEJvHV1p25Q+NqRU= + +bson@~1.0.4: + version "1.0.9" + resolved "https://registry.yarnpkg.com/bson/-/bson-1.0.9.tgz#12319f8323b1254739b7c6bef8d3e89ae05a2f57" + integrity sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg== + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-crc32@^0.2.1, buffer-crc32@~0.2.5: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +buffer-equal@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" + integrity sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs= + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + +buffer-from@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-0.1.2.tgz#15f4b9bcef012044df31142c14333caf6e0260d0" + integrity sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg== + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-more-ints@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz#26b3885d10fa13db7fc01aae3aab870199e0124c" + integrity sha1-JrOIXRD6E9t/wBquOquHAZngEkw= + +buffer-shims@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + integrity sha1-mXjOMXOIxkmth5MCjDR37wRKi1E= + +buffer@^5.1.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.5.0.tgz#9c3caa3d623c33dd1c7ef584b89b88bf9c9bc1ce" + integrity sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +buffermaker@~1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/buffermaker/-/buffermaker-1.2.1.tgz#0631f92b891a84b750f1036491ac857c734429f4" + integrity sha512-IdnyU2jDHU65U63JuVQNTHiWjPRH0CS3aYd/WPaEwyX84rFdukhOduAVb1jwUScmb5X0JWPw8NZOrhoLMiyAHQ== + dependencies: + long "1.1.2" + +buffers@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" + integrity sha1-skV5w77U1tOWru5tmorn9Ugqt7s= + +busboy@^0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" + integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM= + dependencies: + dicer "0.2.5" + readable-stream "1.1.x" + +bytes@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-1.0.0.tgz#3569ede8ba34315fab99c3e92cb04c7220de1fa8" + integrity sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g= + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +bytewise-core@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/bytewise-core/-/bytewise-core-1.2.3.tgz#3fb410c7e91558eb1ab22a82834577aa6bd61d42" + integrity sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI= + dependencies: + typewise-core "^1.2" + +bytewise@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/bytewise/-/bytewise-1.1.0.tgz#1d13cbff717ae7158094aa881b35d081b387253e" + integrity sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4= + dependencies: + bytewise-core "^1.2.2" + typewise "^1.0.3" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cache-point@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cache-point/-/cache-point-0.4.1.tgz#cc8c9cbd99d90d7b0c66910cd33d77a1aab8840e" + integrity sha512-4TgWfe9SF+bUy5cCql8gWHqKNrviufNwSYxLjf2utB0pY4+bdcuFwMmY1hDB+67Gz/L1vmhFNhePAjJTFBtV+Q== + dependencies: + array-back "^2.0.0" + fs-then-native "^2.0.0" + mkdirp2 "^1.0.3" + +callback-stream@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/callback-stream/-/callback-stream-1.1.0.tgz#4701a51266f06e06eaa71fc17233822d875f4908" + integrity sha1-RwGlEmbwbgbqpx/BcjOCLYdfSQg= + dependencies: + inherits "^2.0.1" + readable-stream "> 1.0.0 < 3.0.0" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= + +camelcase@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +capture-stack-trace@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +catharsis@^0.8.11, catharsis@~0.8.9: + version "0.8.11" + resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.8.11.tgz#d0eb3d2b82b7da7a3ce2efb1a7b00becc6643468" + integrity sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g== + dependencies: + lodash "^4.17.14" + +chainsaw@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" + integrity sha1-XqtQsor+WAdNDVgpE4iCi15fvJg= + dependencies: + traverse ">=0.3.0 <0.4" + +chalk@^1.0.0, chalk@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.1, chalk@^2.4.1, chalk@^2.4.2, chalk@~2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +cheerio@0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" + integrity sha1-qbqoYKP5tZWmuBsahocxIe06Jp4= + dependencies: + css-select "~1.2.0" + dom-serializer "~0.1.0" + entities "~1.1.1" + htmlparser2 "^3.9.1" + lodash.assignin "^4.0.9" + lodash.bind "^4.1.4" + lodash.defaults "^4.0.1" + lodash.filter "^4.4.0" + lodash.flatten "^4.2.0" + lodash.foreach "^4.3.0" + lodash.map "^4.4.0" + lodash.merge "^4.4.0" + lodash.pick "^4.2.1" + lodash.reduce "^4.4.0" + lodash.reject "^4.4.0" + lodash.some "^4.4.0" + +chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chownr@^1.0.1, chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= + +cli@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cli/-/cli-1.0.1.tgz#22817534f24bfa4950c34d532d48ecbc621b8c14" + integrity sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ= + dependencies: + exit "0.1.2" + glob "^7.1.1" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +clone@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +cluster-key-slot@^1.0.6: + version "1.1.0" + resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d" + integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw== + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +coffeescript@~1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-1.10.0.tgz#e7aa8301917ef621b35d8a39f348dcdd1db7e33e" + integrity sha1-56qDAZF+9iGzXYo580jc3R234z4= + +collect-all@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/collect-all/-/collect-all-1.0.3.tgz#1abcc20448b58a1447487fcf34130e9512b0acf8" + integrity sha512-0y0rBgoX8IzIjBAUnO73SEtSb4Mhk3IoceWJq5zZSxb9mWORhWH8xLYo4EDSOE1jRBk1LhmfjqWFFt10h/+MEA== + dependencies: + stream-connect "^1.0.2" + stream-via "^1.0.4" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +colors@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM= + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +command-line-args@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.1.1.tgz#88e793e5bb3ceb30754a86863f0401ac92fd369a" + integrity sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg== + dependencies: + array-back "^3.0.1" + find-replace "^3.0.0" + lodash.camelcase "^4.3.0" + typical "^4.0.0" + +command-line-tool@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/command-line-tool/-/command-line-tool-0.8.0.tgz#b00290ef1dfc11cc731dd1f43a92cfa5f21e715b" + integrity sha512-Xw18HVx/QzQV3Sc5k1vy3kgtOeGmsKIqwtFFoyjI4bbcpSgnw2CWVULvtakyw4s6fhyAdI6soQQhXc2OzJy62g== + dependencies: + ansi-escape-sequences "^4.0.0" + array-back "^2.0.0" + command-line-args "^5.0.0" + command-line-usage "^4.1.0" + typical "^2.6.1" + +command-line-usage@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-4.1.0.tgz#a6b3b2e2703b4dcf8bd46ae19e118a9a52972882" + integrity sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g== + dependencies: + ansi-escape-sequences "^4.0.0" + array-back "^2.0.0" + table-layout "^0.4.2" + typical "^2.6.1" + +commander@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" + integrity sha1-+mihT2qUXVTbvlDYzbMyDp47GgY= + +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== + +commander@2.20.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + +commander@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" + integrity sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM= + +commander@~2.20.3: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@~2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= + dependencies: + graceful-readlink ">= 1.0.0" + +commist@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/commist/-/commist-1.1.0.tgz#17811ec6978f6c15ee4de80c45c9beb77cee35d5" + integrity sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg== + dependencies: + leven "^2.1.0" + minimist "^1.1.0" + +common-sequence@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/common-sequence/-/common-sequence-1.0.2.tgz#30e07f3f8f6f7f9b3dee854f20b2d39eee086de8" + integrity sha1-MOB/P49vf5s97oVPILLTnu4Ibeg= + +component-emitter@^1.2.0, component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +compress-commons@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-1.2.2.tgz#524a9f10903f3a813389b0225d27c48bb751890f" + integrity sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8= + dependencies: + buffer-crc32 "^0.2.1" + crc32-stream "^2.0.0" + normalize-path "^2.0.0" + readable-stream "^2.0.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.4.7, concat-stream@^1.5.2, concat-stream@^1.6.2, concat-stream@~1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +config-master@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/config-master/-/config-master-3.1.0.tgz#667663590505a283bf26a484d68489d74c5485da" + integrity sha1-ZnZjWQUFooO/JqSE1oSJ10xUhdo= + dependencies: + walk-back "^2.0.1" + +configstore@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" + integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw== + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + +console-browserify@1.1.x: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@1.0.4, content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +continuable-cache@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/continuable-cache/-/continuable-cache-0.3.1.tgz#bd727a7faed77e71ff3985ac93351a912733ad0f" + integrity sha1-vXJ6f67XfnH/OYWskzUakSczrQ8= + +convert-source-map@^1.5.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +cookie-parser@1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.4.tgz#e6363de4ea98c3def9697b93421c09f30cf5d188" + integrity sha512-lo13tqF3JEtFO7FyA49CqbhaFkskRJ0u/UAiINgrIXeRCY41c88/zxtrECl8AKH3B0hj9q10+h3Kt8I7KlW4tw== + dependencies: + cookie "0.3.1" + cookie-signature "1.0.6" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +cookiejar@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" + integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cors@2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +crc32-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-2.0.0.tgz#e3cdd3b4df3168dd74e3de3fbbcb7b297fe908f4" + integrity sha1-483TtN8xaN10494/u8t7KX/pCPQ= + dependencies: + crc "^3.4.4" + readable-stream "^2.0.0" + +crc@^3.4.4: + version "3.8.0" + resolved "https://registry.yarnpkg.com/crc/-/crc-3.8.0.tgz#ad60269c2c856f8c299e2c4cc0de4556914056c6" + integrity sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ== + dependencies: + buffer "^5.1.0" + +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= + dependencies: + capture-stack-trace "^1.0.0" + +cron@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/cron/-/cron-1.8.2.tgz#4ac5e3c55ba8c163d84f3407bde94632da8370ce" + integrity sha512-Gk2c4y6xKEO8FSAUTklqtfSr7oTq0CiPQeLBG5Fl0qoXpZyMcj1SG59YL+hqq04bu6/IuEA7lMkYDAplQNKkyg== + dependencies: + moment-timezone "^0.5.x" + +cross-env@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9" + integrity sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw== + dependencies: + cross-spawn "^7.0.1" + +cross-spawn@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" + integrity sha1-ElYDfsufDF9549bvE14wdwGEuYI= + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" + integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= + +css-select@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-what@2.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= + +dateformat@~1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" + integrity sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk= + dependencies: + get-stdin "^4.0.1" + meow "^3.3.0" + +debug@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + integrity sha1-+HBX6ZWxofauaklgZkE3vFbwOdo= + dependencies: + ms "0.7.1" + +debug@2.6.9, debug@2.x.x, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@4: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +debug@^3.0.0, debug@^3.1.0, debug@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +decamelize@^1.1.1, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +deep-extend@^0.6.0, deep-extend@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +deepcopy@^0.6.1: + version "0.6.3" + resolved "https://registry.yarnpkg.com/deepcopy/-/deepcopy-0.6.3.tgz#634780f2f8656ab771af8fa8431ed1ccee55c7b0" + integrity sha1-Y0eA8vhlardxr4+oQx7RzO5Vx7A= + +deferred-leveldown@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-0.2.0.tgz#2cef1f111e1c57870d8bbb8af2650e587cd2f5b4" + integrity sha1-LO8fER4cV4cNi7uK8mUOWHzS9bQ= + dependencies: + abstract-leveldown "~0.12.1" + +deferred-leveldown@~1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz#3acd2e0b75d1669924bc0a4b642851131173e1eb" + integrity sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA== + dependencies: + abstract-leveldown "~2.6.0" + +define-properties@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +denque@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/denque/-/denque-1.4.1.tgz#6744ff7641c148c3f8a69c307e51235c1f4a37cf" + integrity sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +depd@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + +detect-libc@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-0.2.0.tgz#47fdf567348a17ec25fcbf0b9e446348a76f9fb5" + integrity sha1-R/31ZzSKF+wl/L8LnkRjSKdvn7U= + +detect-libc@^1.0.2, detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +dicer@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" + integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8= + dependencies: + readable-stream "1.1.x" + streamsearch "0.1.2" + +diff@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" + integrity sha1-fyjS657nsVqX79ic5j3P2qPMur8= + +diff@3.5.0, diff@^3.1.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +dmd@^3.0.10: + version "3.0.13" + resolved "https://registry.yarnpkg.com/dmd/-/dmd-3.0.13.tgz#73294e8fae1a7a1a1c849d86b027adf04fbd5662" + integrity sha512-FV/417bH2c/CYpe8BjFEAHoaHaItcJnPlKELi/qyPZdmUom8joyuC78OhhfPUdyKD/WcouTQ2LxQT4M/RoiJ3w== + dependencies: + array-back "^2.0.0" + cache-point "^0.4.1" + common-sequence "^1.0.2" + file-set "^2.0.0" + handlebars "^4.0.11" + marked "^0.3.16" + object-get "^2.1.0" + reduce-flatten "^1.0.1" + reduce-unique "^1.0.0" + reduce-without "^1.0.1" + test-value "^3.0.0" + walk-back "^3.0.0" + +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-serializer@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" + integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== + dependencies: + domelementtype "^1.3.0" + entities "^1.1.1" + +domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + +domhandler@2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738" + integrity sha1-LeWaCCLVAn+r/28DLCsloqir5zg= + dependencies: + domelementtype "1" + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +dompurify@2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.0.8.tgz#6ef89d2d227d041af139c7b01d9f67ed59c2eb3c" + integrity sha512-vIOSyOXkMx81ghEalh4MLBtDHMx1bhKlaqHDMqM2yeitJ996SLOk5mGdDpI9ifJAgokred8Rmu219fX4OltqXw== + +domutils@1.5, domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +dot-prop@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== + dependencies: + is-obj "^1.0.0" + +double-ended-queue@^2.1.0-0: + version "2.1.0-0" + resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" + integrity sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw= + +duplexer2@~0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + integrity sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds= + dependencies: + readable-stream "~1.1.9" + +duplexer2@~0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + integrity sha1-ixLauHjA1p4+eJEFFmKjL8a93ME= + dependencies: + readable-stream "^2.0.2" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +duplexify@^3.2.0, duplexify@^3.5.1, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +entities@1.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26" + integrity sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY= + +entities@^1.1.1, entities@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" + integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== + +errno@~0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +error@^7.0.0: + version "7.2.1" + resolved "https://registry.yarnpkg.com/error/-/error-7.2.1.tgz#eab21a4689b5f684fc83da84a0e390de82d94894" + integrity sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA== + dependencies: + string-template "~0.2.1" + +es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@~0.10.14: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@~2.0.1, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-map@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + +es6-promise@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.0.2.tgz#010d5858423a5f118979665f46486a95c6ee2bb6" + integrity sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y= + +es6-promise@3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.2.1.tgz#ec56233868032909207170c39448e24449dd1fc4" + integrity sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q= + +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-symbol@^3.0.2, es6-symbol@^3.1.1, es6-symbol@~3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" + integrity sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE= + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5, escape-string-regexp@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escodegen@1.8.x: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + +escodegen@^1.11.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.1.tgz#ba01d0c8278b5e95a9a45350142026659027a457" + integrity sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +escodegen@~1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.1.tgz#dbae17ef96c8e4bedb1356f4504fa4cc2f7cb7e2" + integrity sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q== + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +esprima@2.7.x, esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= + +esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= + +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= + +estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= + dependencies: + d "1" + es5-ext "~0.10.14" + +event-lite@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/event-lite/-/event-lite-0.1.2.tgz#838a3e0fdddef8cc90f128006c8e55a4e4e4c11b" + integrity sha512-HnSYx1BsJ87/p6swwzv+2v6B4X+uxUteoDfRxsAb1S1BePzQqOLevVmkdA15GHJVd9A9Ok6wygUR18Hu0YeV9g== + +eventemitter2@^2.1.3: + version "2.2.2" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-2.2.2.tgz#407ea71c2020cd57538203ab7e7a6bdcfb7692d5" + integrity sha1-QH6nHCAgzVdTggOrfnpr3Pt2ktU= + +eventemitter2@~0.4.13: + version "0.4.14" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab" + integrity sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas= + +eventemitter3@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb" + integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg== + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execspawn@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/execspawn/-/execspawn-1.0.1.tgz#8286f9dde7cecde7905fbdc04e24f368f23f8da6" + integrity sha1-gob53efOzeeQX73ATiTzaPI/jaY= + dependencies: + util-extend "^1.0.1" + +exit@0.1.2, exit@0.1.x, exit@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-template@^1.0.0, expand-template@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-1.1.1.tgz#981f188c0c3a87d2e28f559bc541426ff94f21dd" + integrity sha512-cebqLtV8KOZfw0UI8TEFWxtczxxC1jvyUvx6H4fyp1K1FN7A4Q+uggVUlOsI1K8AGU0rwOGqP8nCapdrw8CYQg== + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + +express-session@1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.0.tgz#9b50dbb5e8a03c3537368138f072736150b7f9b3" + integrity sha512-t4oX2z7uoSqATbMfsxWMbNjAL0T5zpvcJCk3Z9wnPPN7ibddhnmDZXHfEcoBMG2ojKXZoCyPMc5FbtK+G7SoDg== + dependencies: + cookie "0.4.0" + 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.0" + uid-safe "~2.1.5" + +express@4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" + integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== + dependencies: + type "^2.0.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +falafel@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/falafel/-/falafel-2.2.4.tgz#b5d86c060c2412a43166243cb1bce44d1abd2819" + integrity sha512-0HXjo8XASWRmsS0X1EkhwEMZaD3Qvp7FfURwjLKjG1ghfRm/MGZl2r4cWUTv41KdNghTw4OUMmVtdGQp3+H+uQ== + dependencies: + acorn "^7.1.1" + foreach "^2.0.5" + isarray "^2.0.1" + object-keys "^1.0.6" + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + +fast-future@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/fast-future/-/fast-future-1.0.2.tgz#8435a9aaa02d79248d17d704e76259301d99280a" + integrity sha1-hDWpqqAteSSNF9cE52JZMB2ZKAo= + +fast-json-parse@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d" + integrity sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fast-safe-stringify@^1.0.8, fast-safe-stringify@^1.1.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-1.2.3.tgz#9fe22c37fb2f7f86f06b8f004377dbf8f1ee7bc1" + integrity sha512-QJYT/i0QYoiZBQ71ivxdyTqkwKkQ0oxACXHYxH2zYHJEgzi2LsbjgvtzTbLi1SZcF190Db2YP7I7eTsU2egOlw== + +fastfall@^1.2.3, fastfall@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/fastfall/-/fastfall-1.5.1.tgz#3fee03331a49d1d39b3cdf7a5e9cd66f475e7b94" + integrity sha1-P+4DMxpJ0dObPN96XpzWb0dee5Q= + dependencies: + reusify "^1.0.0" + +fastparallel@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/fastparallel/-/fastparallel-2.3.0.tgz#1e709bfb6a03993f3857e3ce7f01311ce7602613" + integrity sha1-HnCb+2oDmT84V+POfwExHOdgJhM= + dependencies: + reusify "^1.0.0" + xtend "^4.0.1" + +fastq@^1.3.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.1.tgz#4570c74f2ded173e71cf0beb08ac70bb85826791" + integrity sha512-mpIH5sKYueh3YyeJwqtVo8sORi0CgtmkVbK6kZStpQlZBYQuTzG2CZ7idSiJuA7bY0SFCWUc5WIs+oYumGCQNw== + dependencies: + reusify "^1.0.4" + +fastseries@^1.7.0: + version "1.7.2" + resolved "https://registry.yarnpkg.com/fastseries/-/fastseries-1.7.2.tgz#d22ce13b9433dff3388d91dbd6b8bda9b21a0f4b" + integrity sha1-0izhO5Qz3/M4jZHb1ri9qbIaD0s= + dependencies: + reusify "^1.0.0" + xtend "^4.0.0" + +faye-websocket@~0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= + dependencies: + websocket-driver ">=0.5.1" + +fd@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/fd/-/fd-0.0.3.tgz#b3240de86dbf5a345baae7382a07d4713566ff0c" + integrity sha512-iAHrIslQb3U68OcMSP0kkNWabp7sSN6d2TBSb2JO3gcLJVDd4owr/hKM4SFJovFOUeeXeItjYgouEDTMWiVAnA== + +figures@^1.0.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +file-set@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/file-set/-/file-set-2.0.1.tgz#db9bc4b70a7e5ba81c9d279c20a37f13369c7850" + integrity sha512-XgOUUpgR6FbbfYcniLw0qm1Am7PnNYIAkd+eXxRt42LiYhjaso0WiuQ+VmrNdtwotyM+cLCfZ56AZrySP3QnKA== + dependencies: + array-back "^2.0.0" + glob "^7.1.3" + +file-sync-cmp@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz#a5e7a8ffbfa493b43b923bbd4ca89a53b63b612b" + integrity sha1-peeo/7+kk7Q7kju9TKiaU7Y7YSs= + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + 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" + +find-replace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" + integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== + dependencies: + array-back "^3.0.1" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +findup-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" + integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw= + dependencies: + detect-file "^1.0.0" + is-glob "^3.1.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +findup-sync@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.3.0.tgz#37930aa5d816b777c03445e1966cc6790a4c0b16" + integrity sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY= + dependencies: + glob "~5.0.0" + +fined@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b" + integrity sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng== + dependencies: + expand-tilde "^2.0.2" + is-plain-object "^2.0.3" + object.defaults "^1.1.0" + object.pick "^1.2.0" + parse-filepath "^1.0.1" + +flagged-respawn@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41" + integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q== + +flatstr@^1.0.4: + version "1.0.12" + resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.12.tgz#c2ba6a08173edbb6c9640e3055b95e287ceb5931" + integrity sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw== + +flexbuffer@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/flexbuffer/-/flexbuffer-0.0.6.tgz#039fdf23f8823e440c38f3277e6fef1174215b30" + integrity sha1-A5/fI/iCPkQMOPMnfm/vEXQhWzA= + +follow-redirects@^1.0.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.10.0.tgz#01f5263aee921c6a54fb91667f08f4155ce169eb" + integrity sha512-4eyLK6s6lH32nOvLLwlIOnr9zrL8Sm+OvW4pVTJNoXeGzYIkHVf+pADQi+OJ0E67hiuSLezPVPyBcIZO50TmmQ== + dependencies: + debug "^3.0.0" + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs= + dependencies: + for-in "^1.0.1" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@^2.3.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +formatio@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.1.1.tgz#5ed3ccd636551097383465d996199100e86161e9" + integrity sha1-XtPM1jZVEJc4NGXZlhmRAOhhYek= + dependencies: + samsam "~1.1" + +formidable@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9" + integrity sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q== + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-ext@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/fs-ext/-/fs-ext-0.5.0.tgz#9c1f9a20b8e7e012e0a914b5e19132724f44f69e" + integrity sha1-nB+aILjn4BLgqRS14ZEyck9E9p4= + dependencies: + nan "^2.0" + +fs-extra@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^1.2.5: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + +fs-then-native@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fs-then-native/-/fs-then-native-2.0.0.tgz#19a124d94d90c22c8e045f2e8dd6ebea36d48c67" + integrity sha1-GaEk2U2QwiyOBF8ujdbr6jbUjGc= + +fs.notify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/fs.notify/-/fs.notify-0.0.4.tgz#63284d45a34b52ce60088a6ddbec5b776d3c013d" + integrity sha1-YyhNRaNLUs5gCIpt2+xbd208AT0= + dependencies: + async "~0.1.22" + retry "~0.6.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.7: + version "1.2.12" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.12.tgz#db7e0d8ec3b0b45724fd4d83d43554a8f1f0de5c" + integrity sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +fstream@^1.0.0, fstream@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +gauge@~1.2.5: + version "1.2.7" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-1.2.7.tgz#e9cec5483d3d4ee0ef44b60a7d99e4935e136d93" + integrity sha1-6c7FSD09TuDvRLYKfZnkk14TbZM= + dependencies: + ansi "^0.3.0" + has-unicode "^2.0.0" + lodash.pad "^4.1.0" + lodash.padend "^4.1.0" + lodash.padstart "^4.1.0" + +gauge@~2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.6.0.tgz#d35301ad18e96902b4751dcbbe40f4218b942a46" + integrity sha1-01MBrRjpaQK0dR3LvkD0IYuUKkY= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-color "^0.1.7" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gaze@^1.0.0, gaze@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" + integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== + dependencies: + globule "^1.0.0" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getobject@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/getobject/-/getobject-0.1.0.tgz#047a449789fa160d018f5486ed91320b6ec7885c" + integrity sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +ghreleases@^1.0.2: + version "1.0.7" + resolved "https://registry.yarnpkg.com/ghreleases/-/ghreleases-1.0.7.tgz#78214443d91ac3c651a4a7687a63da8651efa379" + integrity sha512-1lFGyLLF38Q6cFCDyebN5vzQ2P9DEaAgxPIDLmQwQDVDmUe2Wgv+6dhAIoHeA+My4HLpaJ+dKF73xtuykN2cbQ== + dependencies: + after "~0.8.1" + ghrepos "~2.1.0" + ghutils "~3.2.0" + simple-mime "~0.1.0" + url-template "~2.0.6" + xtend "~4.0.0" + +ghrepos@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ghrepos/-/ghrepos-2.1.0.tgz#abaf558b690b722c70c7ad45076f6f9be8e495e1" + integrity sha512-6GM0ohSDTAv7xD6GsKfxJiV/CajoofRyUwu0E8l29d1o6lFAUxmmyMP/FH33afA20ZrXzxxcTtN6TsYvudMoAg== + dependencies: + ghutils "~3.2.0" + +ghutils@~3.2.0: + version "3.2.6" + resolved "https://registry.yarnpkg.com/ghutils/-/ghutils-3.2.6.tgz#d43986e267da02787464d97a6489659e4609bb1f" + integrity sha512-WpYHgLQkqU7Cv147wKUEThyj6qKHCdnAG2CL9RRsRQImVdLGdVqblJ3JUnj3ToQwgm1ALPS+FXgR0448AgGPUg== + dependencies: + jsonist "~2.1.0" + xtend "~4.0.1" + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-stream@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" + integrity sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ= + dependencies: + extend "^3.0.0" + glob "^7.1.1" + glob-parent "^3.1.0" + is-negated-glob "^1.0.0" + ordered-read-streams "^1.0.0" + pumpify "^1.3.5" + readable-stream "^2.1.5" + remove-trailing-separator "^1.0.1" + to-absolute-glob "^2.0.0" + unique-stream "^2.0.2" + +"glob@3 || 4 || 5 || 6 || 7", glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@~7.1.1: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@3.2.11: + version "3.2.11" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" + integrity sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0= + dependencies: + inherits "2" + minimatch "0.3" + +glob@7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^5.0.15, glob@~5.0.0: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@~7.0.0: + version "7.0.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" + integrity sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo= + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= + dependencies: + ini "^1.3.4" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +globule@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.3.1.tgz#90a25338f22b7fbeb527cee63c629aea754d33b9" + integrity sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g== + dependencies: + glob "~7.1.1" + lodash "~4.17.12" + minimatch "~3.0.2" + +got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + +graceful-fs@^4.1.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" + integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== + +graceful-fs@~4.1.11, graceful-fs@~4.1.3: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + integrity sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8= + +grunt-chmod@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/grunt-chmod/-/grunt-chmod-1.1.1.tgz#d1865c5a84e7ed9aefe509ffbf5290f97a257840" + integrity sha1-0YZcWoTn7Zrv5Qn/v1KQ+XoleEA= + dependencies: + shelljs "^0.5.3" + +grunt-cli@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/grunt-cli/-/grunt-cli-1.2.0.tgz#562b119ebb069ddb464ace2845501be97b35b6a8" + integrity sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg= + dependencies: + findup-sync "~0.3.0" + grunt-known-options "~1.1.0" + nopt "~3.0.6" + resolve "~1.1.0" + +grunt-cli@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/grunt-cli/-/grunt-cli-1.3.2.tgz#60f12d12c1b5aae94ae3469c6b5fe24e960014e8" + integrity sha512-8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ== + dependencies: + grunt-known-options "~1.1.0" + interpret "~1.1.0" + liftoff "~2.5.0" + nopt "~4.0.1" + v8flags "~3.1.1" + +grunt-concurrent@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/grunt-concurrent/-/grunt-concurrent-2.3.1.tgz#1e3db38ccef5a3da1195e61d631fe7e321344d23" + integrity sha1-Hj2zjM71o9oRleYdYx/n4yE0TSM= + dependencies: + arrify "^1.0.1" + async "^1.2.1" + indent-string "^2.0.0" + pad-stream "^1.0.0" + +grunt-contrib-clean@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/grunt-contrib-clean/-/grunt-contrib-clean-2.0.0.tgz#3be7ca480da4b740aa5e9d863e2f7e8b24f8a68b" + integrity sha512-g5ZD3ORk6gMa5ugZosLDQl3dZO7cI3R14U75hTM+dVLVxdMNJCPVmwf9OUt4v4eWgpKKWWoVK9DZc1amJp4nQw== + dependencies: + async "^2.6.1" + rimraf "^2.6.2" + +grunt-contrib-compress@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/grunt-contrib-compress/-/grunt-contrib-compress-1.5.0.tgz#ba5f80e22acf192897ce43cb60250cab2cb1f09b" + integrity sha512-RcCyetnvTJ7jvnDCSm05wOndAd00HWZTHeVGDVVmCM+K/PEivL0yx8vKyi8uzy0492l2dJgtzR0Ucid7roKg6A== + dependencies: + archiver "^1.3.0" + chalk "^1.1.1" + lodash "^4.7.0" + pretty-bytes "^4.0.2" + stream-buffers "^2.1.0" + optionalDependencies: + iltorb "^1.3.10" + +grunt-contrib-concat@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/grunt-contrib-concat/-/grunt-contrib-concat-1.0.1.tgz#61509863084e871d7e86de48c015259ed97745bd" + integrity sha1-YVCYYwhOhx1+ht5IwBUlntl3Rb0= + dependencies: + chalk "^1.0.0" + source-map "^0.5.3" + +grunt-contrib-copy@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/grunt-contrib-copy/-/grunt-contrib-copy-1.0.0.tgz#7060c6581e904b8ab0d00f076e0a8f6e3e7c3573" + integrity sha1-cGDGWB6QS4qw0A8HbgqPbj58NXM= + dependencies: + chalk "^1.1.1" + file-sync-cmp "^0.1.0" + +grunt-contrib-jshint@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/grunt-contrib-jshint/-/grunt-contrib-jshint-2.1.0.tgz#3d789807579034299da1b41c4d70e1ba722973ed" + integrity sha512-65S2/C/6RfjY/umTxfwXXn+wVvaYmykHkHSsW6Q6rhkbv3oudTEgqnFFZvWzWCoHUb+3GMZLbP3oSrNyvshmIQ== + dependencies: + chalk "^2.4.2" + hooker "^0.2.3" + jshint "~2.10.2" + +grunt-contrib-uglify@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/grunt-contrib-uglify/-/grunt-contrib-uglify-4.0.1.tgz#68a7b62fa045ce8e2c7574d1bdcd3b96b8a686b1" + integrity sha512-dwf8/+4uW1+7pH72WButOEnzErPGmtUvc8p08B0eQS/6ON0WdeQu0+WFeafaPTbbY1GqtS25lsHWaDeiTQNWPg== + dependencies: + chalk "^2.4.1" + maxmin "^2.1.0" + uglify-js "^3.5.0" + uri-path "^1.0.0" + +grunt-contrib-watch@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/grunt-contrib-watch/-/grunt-contrib-watch-1.1.0.tgz#c143ca5b824b288a024b856639a5345aedb78ed4" + integrity sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg== + dependencies: + async "^2.6.0" + gaze "^1.1.0" + lodash "^4.17.10" + tiny-lr "^1.1.1" + +grunt-jsdoc-to-markdown@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/grunt-jsdoc-to-markdown/-/grunt-jsdoc-to-markdown-4.0.0.tgz#a554d2f97ca996dc4501b43facb34eebfaa3d274" + integrity sha512-af48xh3SvVx4wmaM1wWC3qRjKSwuresfEb6znDbd+tBo60UaHPVuDJ2PSmYlgb/4c8/mcnd40aW4awn8XOf03Q== + dependencies: + jsdoc-to-markdown "^4.0.1" + +grunt-jsdoc@^2.2.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/grunt-jsdoc/-/grunt-jsdoc-2.4.1.tgz#2ba3eb98a058af82d74623ebd0f5bcac38991813" + integrity sha512-S0zxU0wDewRu7z+vijEItOWe/UttxWVmvz0qz2ZVcAYR2GpXjsiski2CAVN0b18t2qeVLdmxZkJaEWCOsKzcAw== + dependencies: + cross-spawn "^7.0.1" + jsdoc "^3.6.3" + +grunt-jsonlint@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/grunt-jsonlint/-/grunt-jsonlint-2.0.0.tgz#9fdfca392439c75b7f9743053d7441457f3294e3" + integrity sha512-bCodmPAoHxujSST/Pn5FdR6K1QytaZhlYW3dyU5Ut27h1usDBPnoBLWb7EoPE2EmW1UgQTrSNu/qP9tUMBSrZg== + dependencies: + "@prantlf/jsonlint" "6.2.1" + +grunt-known-options@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/grunt-known-options/-/grunt-known-options-1.1.1.tgz#6cc088107bd0219dc5d3e57d91923f469059804d" + integrity sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ== + +grunt-legacy-log-utils@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz#d2f442c7c0150065d9004b08fd7410d37519194e" + integrity sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA== + dependencies: + chalk "~2.4.1" + lodash "~4.17.10" + +grunt-legacy-log@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz#c8cd2c6c81a4465b9bbf2d874d963fef7a59ffb9" + integrity sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw== + dependencies: + colors "~1.1.2" + grunt-legacy-log-utils "~2.0.0" + hooker "~0.2.3" + lodash "~4.17.5" + +grunt-legacy-util@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz#e10624e7c86034e5b870c8a8616743f0a0845e42" + integrity sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A== + dependencies: + async "~1.5.2" + exit "~0.1.1" + getobject "~0.1.0" + hooker "~0.2.3" + lodash "~4.17.10" + underscore.string "~3.3.4" + which "~1.3.0" + +grunt-mkdir@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/grunt-mkdir/-/grunt-mkdir-1.0.0.tgz#73e1a26ac24a08596363f4dd954b0d32485e58e9" + integrity sha1-c+GiasJKCFljY/TdlUsNMkheWOk= + +grunt-mocha-istanbul@5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/grunt-mocha-istanbul/-/grunt-mocha-istanbul-5.0.2.tgz#23929a8b3f45a66c5fab1f6146e62b58418b7882" + integrity sha1-I5Kaiz9Fpmxfqx9hRuYrWEGLeII= + +grunt-nodemon@~0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/grunt-nodemon/-/grunt-nodemon-0.4.2.tgz#aebc12ab66d7b5b3b054cdd8c5f822ec1a423ef9" + integrity sha1-rrwSq2bXtbOwVM3Yxfgi7BpCPvk= + dependencies: + nodemon "^1.7.1" + +grunt-npm-command@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/grunt-npm-command/-/grunt-npm-command-0.1.2.tgz#4168f836e2cf7b7f0bcc153933bacaf4f0903a58" + integrity sha1-QWj4NuLPe38LzBU5M7rK9PCQOlg= + +grunt-sass@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/grunt-sass/-/grunt-sass-3.1.0.tgz#a5936cc2a80ec08092d9f31c101dc307d1e4f71c" + integrity sha512-90s27H7FoCDcA8C8+R0GwC+ntYD3lG6S/jqcavWm3bn9RiJTmSfOvfbFa1PXx4NbBWuiGQMLfQTj/JvvqT5w6A== + +grunt-simple-mocha@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/grunt-simple-mocha/-/grunt-simple-mocha-0.4.1.tgz#579449249eaf0a81878fa72f3edab5145d45fd77" + integrity sha1-V5RJJJ6vCoGHj6cvPtq1FF1F/Xc= + dependencies: + mocha "^2.3.4" + +grunt@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grunt/-/grunt-1.0.4.tgz#c799883945a53a3d07622e0737c8f70bfe19eb38" + integrity sha512-PYsMOrOC+MsdGEkFVwMaMyc6Ob7pKmq+deg1Sjr+vvMWp35sztfwKE7qoN51V+UEtHsyNuMcGdgMLFkBHvMxHQ== + dependencies: + coffeescript "~1.10.0" + dateformat "~1.0.12" + eventemitter2 "~0.4.13" + exit "~0.1.1" + findup-sync "~0.3.0" + glob "~7.0.0" + grunt-cli "~1.2.0" + grunt-known-options "~1.1.0" + grunt-legacy-log "~2.0.0" + grunt-legacy-util "~1.1.1" + iconv-lite "~0.4.13" + js-yaml "~3.13.0" + minimatch "~3.0.2" + mkdirp "~0.5.1" + nopt "~3.0.6" + path-is-absolute "~1.0.0" + rimraf "~2.6.2" + +gzip-size@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-3.0.0.tgz#546188e9bdc337f673772f81660464b389dce520" + integrity sha1-VGGI6b3DN/Zzdy+BZgRks4nc5SA= + dependencies: + duplexer "^0.1.1" + +handlebars@^4.0.1, handlebars@^4.0.11: + version "4.7.3" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.3.tgz#8ece2797826886cf8082d1726ff21d2a022550ee" + integrity sha512-SRGwSYuNfx8DwHD/6InAPzD6RgeruWLT+B8e8a7gGs8FWgHzlExpTFMEq2IA6QpAfOClpKHy6+8IqTjeBCu6Kg== + dependencies: + neo-async "^2.6.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.0, har-validator@~5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-color@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + integrity sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8= + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbols@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-sum@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" + integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg== + +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= + +help-me@^1.0.0, help-me@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/help-me/-/help-me-1.1.0.tgz#8f2d508d0600b4a456da2f086556e7e5c056a3c6" + integrity sha1-jy1QjQYAtKRW2i8IZVbn5cBWo8Y= + dependencies: + callback-stream "^1.0.2" + glob-stream "^6.1.0" + through2 "^2.0.1" + xtend "^4.0.0" + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hooker@^0.2.3, hooker@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/hooker/-/hooker-0.2.3.tgz#b834f723cc4a242aa65963459df6d984c5d3d959" + integrity sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk= + +hosted-git-info@^2.1.4: + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + +htmlparser2@3.8.x: + version "3.8.3" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068" + integrity sha1-mWwosZFRaovoZQGn15dX5ccMEGg= + dependencies: + domelementtype "1" + domhandler "2.3" + domutils "1.5" + entities "1.0" + readable-stream "1.1" + +htmlparser2@^3.9.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@1.7.3, http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +"http-parser-js@>=0.4.0 <0.4.11": + version "0.4.10" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" + integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= + +http-proxy@1.18.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a" + integrity sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-proxy-agent@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +hyperquest@~2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/hyperquest/-/hyperquest-2.1.3.tgz#523127d7a343181b40bf324e231d2576edf52633" + integrity sha512-fUuDOrB47PqNK/BAMOS13v41UoaqIxqSLHX6CAbOD7OfT+/GCWO1/vPLfTNutOeXrv1ikuaZ3yux+33Z9vh+rw== + dependencies: + buffer-from "^0.1.1" + duplexer2 "~0.0.2" + through2 "~0.6.3" + +i18next@15.1.2: + version "15.1.2" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-15.1.2.tgz#635b7bc688cf36620cab8fa1c3af97817a47f95a" + integrity sha512-98ELn/dqep00DQ/v1E1gpM21HNN6nqU3mS85mYKd9P7lXrhfUcuysPaa3HviKSFb3WPdjf7avuAST3P0dhNp/A== + dependencies: + "@babel/runtime" "^7.3.1" + +iconv-lite@0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.5.1.tgz#b2425d3c7b18f7219f2ca663d103bddb91718d64" + integrity sha512-ONHr16SQvKZNSqjQT9gy5z24Jw+uqfO02/ngBSBoqChZ+W8qXX7GPRa1RoUnzGADw8K63R1BXUMzarCVQBpY8Q== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.4, ieee754@^1.1.8: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= + +ignore-walk@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" + integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== + dependencies: + minimatch "^3.0.4" + +iltorb@^1.3.10: + version "1.3.10" + resolved "https://registry.yarnpkg.com/iltorb/-/iltorb-1.3.10.tgz#a0d9e4e7d52bf510741442236cbe0cc4230fc9f8" + integrity sha512-nyB4+ru1u8CQqQ6w7YjasboKN3NQTN8GH/V/eEssNRKhW6UbdxdWhB9fJ5EEdjJfezKY0qPrcwLyIcgjL8hHxA== + dependencies: + detect-libc "^0.2.0" + nan "^2.6.2" + node-gyp "^3.6.2" + prebuild-install "^2.3.0" + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +in-publish@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.1.tgz#948b1a535c8030561cea522f73f78f4be357e00c" + integrity sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ== + +indent-string@^2.0.0, indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +int64-buffer@^0.1.9: + version "0.1.10" + resolved "https://registry.yarnpkg.com/int64-buffer/-/int64-buffer-0.1.10.tgz#277b228a87d95ad777d07c13832022406a473423" + integrity sha1-J3siiofZWtd30HwTgyAiQGpHNCM= + +interpret@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ= + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + +ioredis@^1.15.1: + version "1.15.1" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-1.15.1.tgz#525255cccd557bdd38a0ed3466199f59eb0b9d1c" + integrity sha1-UlJVzM1Ve904oO00ZhmfWesLnRw= + dependencies: + bluebird "^2.9.34" + debug "^2.2.0" + double-ended-queue "^2.1.0-0" + flexbuffer "0.0.6" + lodash "^3.6.0" + +ioredis@^2.3.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-2.5.0.tgz#fb6fdf0a1a7e0974614c67b6e5e11308a8cf95b9" + integrity sha1-+2/fChp+CXRhTGe25eETCKjPlbk= + dependencies: + bluebird "^3.3.4" + cluster-key-slot "^1.0.6" + debug "^2.2.0" + double-ended-queue "^2.1.0-0" + flexbuffer "0.0.6" + lodash "^4.8.2" + redis-commands "^1.2.0" + redis-parser "^1.3.0" + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" + integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-ci@^1.0.10: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== + dependencies: + ci-info "^1.5.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-generator-function@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" + integrity sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw== + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + +is-negated-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" + integrity sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI= + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= + dependencies: + path-is-inside "^1.0.1" + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= + +is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== + dependencies: + is-unc-path "^1.0.0" + +is-retry-allowed@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + +is-stream@^1.0.0, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== + dependencies: + unc-path-regex "^0.1.2" + +is-utf8@0.2.1, is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isarray@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +istanbul@0.4.5: + version "0.4.5" + resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" + integrity sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs= + dependencies: + abbrev "1.0.x" + async "1.x" + escodegen "1.8.x" + esprima "2.7.x" + glob "^5.0.15" + handlebars "^4.0.1" + js-yaml "3.x" + mkdirp "0.5.x" + nopt "3.x" + once "1.x" + resolve "1.1.x" + supports-color "^3.1.0" + which "^1.1.1" + wordwrap "^1.0.0" + +jade@0.26.3: + version "0.26.3" + resolved "https://registry.yarnpkg.com/jade/-/jade-0.26.3.tgz#8f10d7977d8d79f2f6ff862a81b0513ccb25686c" + integrity sha1-jxDXl32NefL2/4YqgbBRPMslaGw= + dependencies: + commander "0.6.1" + mkdirp "0.3.0" + +js-base64@^2.1.8: + version "2.5.2" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.2.tgz#313b6274dda718f714d00b3330bbae6e38e90209" + integrity sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ== + +js-yaml@3.13.1, js-yaml@3.x, js-yaml@~3.13.0: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js2xmlparser@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/js2xmlparser/-/js2xmlparser-4.0.1.tgz#670ef71bc5661f089cc90481b99a05a1227ae3bd" + integrity sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw== + dependencies: + xmlcreate "^2.0.3" + +js2xmlparser@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/js2xmlparser/-/js2xmlparser-3.0.0.tgz#3fb60eaa089c5440f9319f51760ccd07e2499733" + integrity sha1-P7YOqgicVED5MZ9RdgzNB+JJlzM= + dependencies: + xmlcreate "^1.0.1" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsdoc-api@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/jsdoc-api/-/jsdoc-api-4.0.3.tgz#f87357856349a0be40a03e64711c34c74754ba20" + integrity sha512-dfYq9JgB+XahY0XfSEw93PmXmocjwYcvJ5aMuQUJ/OdDRGWamf2SSOk3W06Bsj8qdjp/UdefzqpP/mpwsvHuvA== + dependencies: + array-back "^2.0.0" + cache-point "^0.4.1" + collect-all "^1.0.3" + file-set "^2.0.0" + fs-then-native "^2.0.0" + jsdoc "~3.5.5" + object-to-spawn-args "^1.1.1" + temp-path "^1.0.0" + walk-back "^3.0.0" + +"jsdoc-nr-template@github:node-red/jsdoc-nr-template": + version "1.0.0" + resolved "https://codeload.github.com/node-red/jsdoc-nr-template/tar.gz/acc4e8ddd5b2e34f0d9bc64071c091269bd8bc3b" + +jsdoc-parse@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/jsdoc-parse/-/jsdoc-parse-3.0.1.tgz#1194d6a16a2dfbe5fb8cccfeb5058ea808759893" + integrity sha512-btZLp4wYl90vcAfgk4hoGQbO17iBVrhh3LJRMKZNtZgniO3F8H2CjxXld0owBIB1XxN+j3bAcWZnZKMnSj3iMA== + dependencies: + array-back "^2.0.0" + lodash.omit "^4.5.0" + lodash.pick "^4.4.0" + reduce-extract "^1.0.0" + sort-array "^2.0.0" + test-value "^3.0.0" + +jsdoc-to-markdown@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsdoc-to-markdown/-/jsdoc-to-markdown-4.0.1.tgz#247f7d977ecc209428972ec92ca14bd4e610355d" + integrity sha512-LHJRoLoLyDdxNcColgkLoB/rFG5iRP+PNJjMILI0x+95IdEAtyjSt0wJ6ZlKxRpkhBYtQXTQQ119hMqPIUZzTQ== + dependencies: + array-back "^2.0.0" + command-line-tool "^0.8.0" + config-master "^3.1.0" + dmd "^3.0.10" + jsdoc-api "^4.0.1" + jsdoc-parse "^3.0.1" + walk-back "^3.0.0" + +jsdoc@^3.6.3: + version "3.6.3" + resolved "https://registry.yarnpkg.com/jsdoc/-/jsdoc-3.6.3.tgz#dccea97d0e62d63d306b8b3ed1527173b5e2190d" + integrity sha512-Yf1ZKA3r9nvtMWHO1kEuMZTlHOF8uoQ0vyo5eH7SQy5YeIiHM+B0DgKnn+X6y6KDYZcF7G2SPkKF+JORCXWE/A== + dependencies: + "@babel/parser" "^7.4.4" + bluebird "^3.5.4" + catharsis "^0.8.11" + escape-string-regexp "^2.0.0" + js2xmlparser "^4.0.0" + klaw "^3.0.0" + markdown-it "^8.4.2" + markdown-it-anchor "^5.0.2" + marked "^0.7.0" + mkdirp "^0.5.1" + requizzle "^0.2.3" + strip-json-comments "^3.0.1" + taffydb "2.6.2" + underscore "~1.9.1" + +jsdoc@~3.5.5: + version "3.5.5" + resolved "https://registry.yarnpkg.com/jsdoc/-/jsdoc-3.5.5.tgz#484521b126e81904d632ff83ec9aaa096708fa4d" + integrity sha512-6PxB65TAU4WO0Wzyr/4/YhlGovXl0EVYfpKbpSroSj0qBxT4/xod/l40Opkm38dRHRdQgdeY836M0uVnJQG7kg== + dependencies: + babylon "7.0.0-beta.19" + bluebird "~3.5.0" + catharsis "~0.8.9" + escape-string-regexp "~1.0.5" + js2xmlparser "~3.0.0" + klaw "~2.0.0" + marked "~0.3.6" + mkdirp "~0.5.1" + requizzle "~0.2.1" + strip-json-comments "~2.0.1" + taffydb "2.6.2" + underscore "~1.8.3" + +jshint@~2.10.2: + version "2.10.3" + resolved "https://registry.yarnpkg.com/jshint/-/jshint-2.10.3.tgz#98dc765bf6920b41bc2719f76b8739d6f6e93a9c" + integrity sha512-d8AoXcNNYzmm7cdmulQ3dQApbrPYArtVBO6n4xOICe4QsXGNHCAKDcFORzqP52LhK61KX0VhY39yYzCsNq+bxQ== + dependencies: + cli "~1.0.0" + console-browserify "1.1.x" + exit "0.1.x" + htmlparser2 "3.8.x" + lodash "~4.17.11" + minimatch "~3.0.2" + shelljs "0.3.x" + strip-json-comments "1.0.x" + +json-buffer@~2.0.11: + version "2.0.11" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-2.0.11.tgz#3e441fda3098be8d1e3171ad591bc62a33e2d55f" + integrity sha1-PkQf2jCYvo0eMXGtWRvGKjPi1V8= + +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stringify-safe@5.0.1, json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +jsonata@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/jsonata/-/jsonata-1.8.1.tgz#75f942971a1fe1019c86690e1ddc2af7e21dbec9" + integrity sha512-Lw1ApNtYH9i/lWBuRSm1I/xfhPyTvlVslVIaGLW/bxFimxQYzQx2y3+DNRmbx5mmCmRb+bCLdIJasEFyb+aUlQ== + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonist@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/jsonist/-/jsonist-2.1.2.tgz#c1377311e8fc857abe7aa3df197116a911f95324" + integrity sha512-8yqmWJAC2VaYoSKQAbsfgCpGY5o/1etWzx6ZxaZrC4iGaHrHUZEo+a2MyF8w+2uTavTlHdLWaZUoR19UfBstxQ== + dependencies: + bl "~3.0.0" + hyperquest "~2.1.3" + json-stringify-safe "~5.0.1" + xtend "~4.0.1" + +jsonschema@^1.0.3: + version "1.2.5" + resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.2.5.tgz#bab69d97fa28946aec0a56a9cc266d23fe80ae61" + integrity sha512-kVTF+08x25PQ0CjuVc0gRM9EUPb0Fe9Ln/utFOgcdxEIOHuU7ooBk/UPTd7t1M91pP35m0MU1T8M5P7vP1bRRw== + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +just-extend@^4.0.2: + version "4.1.0" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.1.0.tgz#7278a4027d889601640ee0ce0e5a00b992467da4" + integrity sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA== + +kafka-node@~0.5.8: + version "0.5.9" + resolved "https://registry.yarnpkg.com/kafka-node/-/kafka-node-0.5.9.tgz#9a9c29d09237ee892b6f56640e0d32a80391a212" + integrity sha1-mpwp0JI37okrb1ZkDg0yqAORohI= + dependencies: + async ">0.9 <2.0" + binary "~0.3.0" + buffer-crc32 "~0.2.5" + buffermaker "~1.2.0" + debug "^2.1.3" + lodash ">3.0 <4.0" + minimatch "^3.0.2" + nested-error-stacks "^1.0.2" + node-uuid "~1.4.3" + node-zookeeper-client "~0.2.2" + optional "^0.1.3" + retry "~0.6.1" + optionalDependencies: + snappy "^5.0.5" + +kerberos@~0.0: + version "0.0.24" + resolved "https://registry.yarnpkg.com/kerberos/-/kerberos-0.0.24.tgz#67e5fe0f0dbe240a505eb45de411d6031e7b381b" + integrity sha512-QO6bFq9eETHB5zcA0OJiQtw137TH45OuUcGtI+QGg2ZJQIPCvwXL2kjCqZZMColcIdbPhj4X40EY5f3oOiBfiw== + dependencies: + nan "~2.10.0" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klaw@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-3.0.0.tgz#b11bec9cf2492f06756d6e809ab73a2910259146" + integrity sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g== + dependencies: + graceful-fs "^4.1.9" + +klaw@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-2.0.0.tgz#59c128e0dc5ce410201151194eeb9cbf858650f6" + integrity sha1-WcEo4Nxc5BAgEVEZTuucv4WGUPY= + dependencies: + graceful-fs "^4.1.9" + +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= + dependencies: + package-json "^4.0.0" + +lazystream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" + integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= + dependencies: + readable-stream "^2.0.5" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + +level-codec@~7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7" + integrity sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ== + +level-errors@^1.0.3: + version "1.1.2" + resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.2.tgz#4399c2f3d3ab87d0625f7e3676e2d807deff404d" + integrity sha512-Sw/IJwWbPKF5Ai4Wz60B52yj0zYeqzObLh8k1Tk88jVmD51cJSKWSYpRyhVIvFzZdvsPqlH5wfhp/yxdsaQH4w== + dependencies: + errno "~0.1.1" + +level-errors@~1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.0.5.tgz#83dbfb12f0b8a2516bdc9a31c4876038e227b859" + integrity sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig== + dependencies: + errno "~0.1.1" + +level-iterator-stream@~1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz#e43b78b1a8143e6fa97a4f485eb8ea530352f2ed" + integrity sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0= + dependencies: + inherits "^2.0.1" + level-errors "^1.0.3" + readable-stream "^1.0.33" + xtend "^4.0.0" + +level-post@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/level-post/-/level-post-1.0.7.tgz#19ccca9441a7cc527879a0635000f06d5e8f27d0" + integrity sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew== + dependencies: + ltgt "^2.1.2" + +level-sublevel@^6.5.2: + version "6.6.5" + resolved "https://registry.yarnpkg.com/level-sublevel/-/level-sublevel-6.6.5.tgz#acddfa2be033b9e503544e2c647f3c03d5a23fbd" + integrity sha512-SBSR60x+dghhwGUxPKS+BvV1xNqnwsEUBKmnFepPaHJ6VkBXyPK9SImGc3K2BkwBfpxlt7GKkBNlCnrdufsejA== + dependencies: + bytewise "~1.1.0" + levelup "~0.19.0" + ltgt "~2.1.1" + pull-defer "^0.2.2" + pull-level "^2.0.3" + pull-stream "^3.6.8" + typewiselite "~1.0.0" + xtend "~4.0.0" + +leveldown@~1.4.3: + version "1.4.6" + resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-1.4.6.tgz#c627baa4c6765fd3ebf94f3b30a7aefdb9c893fb" + integrity sha1-xie6pMZ2X9Pr+U87MKeu/bnIk/s= + dependencies: + abstract-leveldown "~2.4.0" + bindings "~1.2.1" + fast-future "~1.0.0" + nan "~2.3.0" + prebuild "^4.1.1" + +levelup@^1.3.8: + version "1.3.9" + resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.9.tgz#2dbcae845b2bb2b6bea84df334c475533bbd82ab" + integrity sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ== + dependencies: + deferred-leveldown "~1.2.1" + level-codec "~7.0.0" + level-errors "~1.0.3" + level-iterator-stream "~1.3.0" + prr "~1.0.1" + semver "~5.4.1" + xtend "~4.0.0" + +levelup@~0.19.0: + version "0.19.1" + resolved "https://registry.yarnpkg.com/levelup/-/levelup-0.19.1.tgz#f3a6a7205272c4b5f35e412ff004a03a0aedf50b" + integrity sha1-86anIFJyxLXzXkEv8ASgOgrt9Qs= + dependencies: + bl "~0.8.1" + deferred-leveldown "~0.2.0" + errno "~0.1.1" + prr "~0.0.0" + readable-stream "~1.0.26" + semver "~5.1.0" + xtend "~3.0.0" + +leven@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +liftoff@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec" + integrity sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew= + dependencies: + extend "^3.0.0" + findup-sync "^2.0.0" + fined "^1.0.1" + flagged-respawn "^1.0.0" + is-plain-object "^2.0.4" + object.map "^1.0.0" + rechoir "^0.6.2" + resolve "^1.1.7" + +linkify-it@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" + integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw== + dependencies: + uc.micro "^1.0.1" + +livereload-js@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.4.0.tgz#447c31cf1ea9ab52fc20db615c5ddf678f78009c" + integrity sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw== + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash.assignin@^4.0.9: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" + integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI= + +lodash.bind@^4.1.4: + version "4.2.1" + resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" + integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU= + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + +lodash.defaults@^4.0.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= + +lodash.filter@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" + integrity sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4= + +lodash.flatten@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= + +lodash.foreach@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" + integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM= + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + +lodash.map@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" + integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= + +lodash.merge@^4.4.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.omit@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60" + integrity sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA= + +lodash.pad@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/lodash.pad/-/lodash.pad-4.5.1.tgz#4330949a833a7c8da22cc20f6a26c4d59debba70" + integrity sha1-QzCUmoM6fI2iLMIPaibE1Z3runA= + +lodash.padend@^4.1.0, lodash.padend@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" + integrity sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4= + +lodash.padstart@^4.1.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b" + integrity sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs= + +lodash.pick@^4.2.1, lodash.pick@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" + integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= + +lodash.reduce@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" + integrity sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs= + +lodash.reject@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" + integrity sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU= + +lodash.some@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" + integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= + +"lodash@>3.0 <4.0", lodash@^3.6.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y= + +lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.7.0, lodash@^4.8.0, lodash@^4.8.2, lodash@~4.17.10, lodash@~4.17.11, lodash@~4.17.12, lodash@~4.17.5: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +lolex@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31" + integrity sha1-fD2mL/yzDw9agKJWbKJORdigHzE= + +lolex@^2.2.0: + version "2.7.5" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.7.5.tgz#113001d56bfc7e02d56e36291cc5c413d1aa0733" + integrity sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q== + +lolex@^5.0.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367" + integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A== + dependencies: + "@sinonjs/commons" "^1.7.0" + +long@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/long/-/long-1.1.2.tgz#eaef5951ca7551d96926b82da242db9d6b28fb53" + integrity sha1-6u9ZUcp1UdlpJrgtokLbnWso+1M= + +looper@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/looper/-/looper-2.0.0.tgz#66cd0c774af3d4fedac53794f742db56da8f09ec" + integrity sha1-Zs0Md0rz1P7axTeU90LbVtqPCew= + +looper@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/looper/-/looper-3.0.0.tgz#2efa54c3b1cbaba9b94aee2e5914b0be57fbb749" + integrity sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k= + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + integrity sha1-bUUk6LlV+V1PW1iFHOId1y+06VI= + +lru-cache@^4.0.0, lru-cache@^4.0.1, lru-cache@^4.0.3: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" + integrity sha1-HRdnnAac2l0ECZGgnbwsDbN35V4= + dependencies: + pseudomap "^1.0.1" + yallist "^2.0.0" + +ltgt@^2.1.2: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" + integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU= + +ltgt@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-1.0.2.tgz#e6817eb29ad204fc0c9e96ef8b0fee98ef6b9aa3" + integrity sha1-5oF+sprSBPwMnpbviw/umO9rmqM= + +ltgt@~2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.1.3.tgz#10851a06d9964b971178441c23c9e52698eece34" + integrity sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ= + +magic-string@^0.22.4: + version "0.22.5" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.5.tgz#8e9cf5afddf44385c1da5bc2a6a0dbd10b03657e" + integrity sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w== + dependencies: + vlq "^0.2.2" + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +make-iterator@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" + integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw== + dependencies: + kind-of "^6.0.2" + +map-cache@^0.2.0, map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +markdown-it-anchor@^5.0.2: + version "5.2.5" + resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-5.2.5.tgz#dbf13cfcdbffd16a510984f1263e1d479a47d27a" + integrity sha512-xLIjLQmtym3QpoY9llBgApknl7pxAcN3WDRc2d3rwpl+/YvDZHPmKscGs+L6E05xf2KrCXPBvosWt7MZukwSpQ== + +markdown-it@^8.4.2: + version "8.4.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54" + integrity sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ== + dependencies: + argparse "^1.0.7" + entities "~1.1.1" + linkify-it "^2.0.0" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +marked@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.8.0.tgz#ec5c0c9b93878dc52dd54be8d0e524097bd81a99" + integrity sha512-MyUe+T/Pw4TZufHkzAfDj6HarCBWia2y27/bhuYkTaiUnfDYFnCP3KUN+9oM7Wi6JA2rymtVYbQu3spE0GCmxQ== + +marked@^0.3.16, marked@~0.3.6: + version "0.3.19" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.19.tgz#5d47f709c4c9fc3c216b6d46127280f40b39d790" + integrity sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg== + +marked@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.7.0.tgz#b64201f051d271b1edc10a04d1ae9b74bb8e5c0e" + integrity sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg== + +maxmin@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/maxmin/-/maxmin-2.1.0.tgz#4d3b220903d95eee7eb7ac7fa864e72dc09a3166" + integrity sha1-TTsiCQPZXu5+t6x/qGTnLcCaMWY= + dependencies: + chalk "^1.0.0" + figures "^1.0.1" + gzip-size "^3.0.0" + pretty-bytes "^3.0.0" + +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +media-typer@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.0.tgz#6ab74b8f2d3320f2064b2a87a38e7931ff3a5561" + integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== + +memdown@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.1.2.tgz#3b8c24580db23e47b3c672f2ccf0b193187844cb" + integrity sha1-O4wkWA2yPkezxnLyzPCxkxh4RMs= + dependencies: + abstract-leveldown "^2.0.3" + functional-red-black-tree "^1.0.1" + inherits "~2.0.1" + ltgt "~1.0.2" + +memorystore@1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/memorystore/-/memorystore-1.6.2.tgz#66e7190d7d54885372c1aec3e256b92e3bf1d163" + integrity sha512-HQM+cZB/kY1+jj57It22FsptJ3nuZRYxnwh3rWZEvDZO1zuzhIrX9uyFcjP9AhFQvM5WS6vZKtn3veohDH4S7w== + dependencies: + debug "3.1.0" + lru-cache "^4.0.3" + +meow@^3.0.0, meow@^3.3.0, meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-source-map@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.4.tgz#a5de46538dae84d4114cc5ea02b4772a6346701f" + integrity sha1-pd5GU42uhNQRTMXqArR3KmNGcB8= + dependencies: + source-map "^0.5.6" + +methods@^1.1.1, methods@^1.1.2, methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +mime-db@1.43.0: + version "1.43.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" + integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== + +mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.26" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" + integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== + dependencies: + mime-db "1.43.0" + +mime@1.6.0, mime@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" + integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== + +mime@~1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +minami@1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/minami/-/minami-1.2.3.tgz#99b6dcdfb2f0a54da1c9c8f7aa3a327787aaf9f8" + integrity sha1-mbbc37LwpU2hycj3qjoyd4eq+fg= + +minimatch@0.3: + version "0.3.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" + integrity sha1-J12O2qxPG7MyZHIInnlJyDlGmd0= + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +"minimatch@2 || 3", minimatch@3, minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.0, minimatch@~3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@^1.1.0, minimist@^1.1.2, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + +minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp2@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp2/-/mkdirp2-1.0.4.tgz#56de1f8f5c93cf2199906362eba0f9f262ee4437" + integrity sha512-Q2PKB4ZR4UPtjLl76JfzlgSCUZhSV1AXQgAZa1qt5RiaALFjP/CDrGvFBrOz7Ck6McPcwMAxTsJvWOUjOU8XMw== + +mkdirp@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" + integrity sha1-G79asbqCevI1dRQ0kEJkVfSB/h4= + +mkdirp@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: + version "0.5.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.4.tgz#fd01504a6797ec5c9be81ff43d204961ed64a512" + integrity sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw== + dependencies: + minimist "^1.2.5" + +mocha@^2.3.4: + version "2.5.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-2.5.3.tgz#161be5bdeb496771eb9b35745050b622b5aefc58" + integrity sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg= + dependencies: + commander "2.3.0" + debug "2.2.0" + diff "1.4.0" + escape-string-regexp "1.0.2" + glob "3.2.11" + growl "1.9.2" + jade "0.26.3" + mkdirp "0.5.1" + supports-color "1.2.0" + to-iso-string "0.0.2" + +mocha@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" + integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== + dependencies: + browser-stdout "1.3.1" + commander "2.15.1" + debug "3.1.0" + diff "3.5.0" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.5" + he "1.1.1" + minimatch "3.0.4" + mkdirp "0.5.1" + supports-color "5.4.0" + +moment-timezone@^0.5.x: + version "0.5.28" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.28.tgz#f093d789d091ed7b055d82aa81a82467f72e4338" + integrity sha512-TDJkZvAyKIVWg5EtVqRzU97w0Rb0YVbfpqyjgu6GwXCAohVRqwZjf4fOzDE6p1Ch98Sro/8hQQi65WDXW5STPw== + dependencies: + moment ">= 2.9.0" + +"moment@>= 2.9.0": + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== + +mongodb-core@1.3.21: + version "1.3.21" + resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-1.3.21.tgz#fe129e7bee2b3b26c1409de02ab60d03f6291cca" + integrity sha1-/hKee+4rOybBQJ3gKrYNA/YpHMo= + dependencies: + bson "~0.4.23" + require_optional "~1.0.0" + +mongodb-core@2.1.20: + version "2.1.20" + resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.20.tgz#fece8dd76b59ee7d7f2d313b65322c160492d8f1" + integrity sha512-IN57CX5/Q1bhDq6ShAR6gIv4koFsZP7L8WOK1S0lR0pVDQaScffSMV5jxubLsmZ7J+UdqmykKw4r9hG3XQEGgQ== + dependencies: + bson "~1.0.4" + require_optional "~1.0.0" + +mongodb@^2.1.18: + version "2.2.36" + resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.36.tgz#1c573680b2849fb0f47acbba3dc5fa228de975f5" + integrity sha512-P2SBLQ8Z0PVx71ngoXwo12+FiSfbNfGOClAao03/bant5DgLNkOPAck5IaJcEk4gKlQhDEURzfR3xuBG1/B+IA== + dependencies: + es6-promise "3.2.1" + mongodb-core "2.1.20" + readable-stream "2.2.7" + +mongodb@~2.1.4: + version "2.1.21" + resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.1.21.tgz#764709dbcceb5825b4eb31f95395f965fd442272" + integrity sha1-dkcJ28zrWCW06zH5U5X5Zf1EInI= + dependencies: + es6-promise "3.0.2" + mongodb-core "1.3.21" + readable-stream "1.0.31" + +mosca@^2.8.3: + version "2.8.3" + resolved "https://registry.yarnpkg.com/mosca/-/mosca-2.8.3.tgz#8cf01546c58ad7a7a120be98c9e52cde02d17d1d" + integrity sha512-jjhbk7DZjSRq8JaGhcdQQVReMXlgcIzKvlfxTZfZksnvhiZH0EEy4hNYefQokaa9f6zqdkc09u2dbUJ/ZTFlag== + dependencies: + array-from "^2.1.1" + ascoltatori "^3.0.0" + brfs "~1.4.2" + clone "^1.0.2" + commander "~2.9.0" + deepcopy "^0.6.1" + escape-string-regexp "^1.0.5" + extend "^3.0.0" + json-buffer "~2.0.11" + jsonschema "^1.0.3" + level-sublevel "^6.5.2" + levelup "^1.3.8" + lru-cache "~4.0.0" + memdown "~1.1.1" + minimatch "~3.0.0" + moving-average "0.1.1" + mqtt "^1.6.3" + mqtt-connection "^2.1.1" + msgpack5 "^3.3.0" + nanoid "^0.2.2" + pbkdf2-password "^1.1.0" + pino "^2.4.2" + qlobber "~0.7.0" + retimer "^1.0.1" + st "^1.1.0" + steed "^1.0.0" + uuid "^2.0.1" + websocket-stream "~3.1.0" + optionalDependencies: + amqp "~0.2.4" + ioredis "^1.15.1" + leveldown "~1.4.3" + mongodb "~2.1.4" + +moving-average@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/moving-average/-/moving-average-0.1.1.tgz#9b19c376978e21b945ed777678ed954d4b7b5475" + integrity sha1-mxnDdpeOIblF7Xd2eO2VTUt7VHU= + +mqtt-connection@^2.0.0, mqtt-connection@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/mqtt-connection/-/mqtt-connection-2.1.1.tgz#7b2e985a74e196619430bebd35da162c34c4e56a" + integrity sha1-ey6YWnThlmGUML69NdoWLDTE5Wo= + dependencies: + inherits "^2.0.1" + mqtt-packet "^3.0.0" + reduplexer "^1.1.0" + through2 "^0.6.3" + +mqtt-packet@^3.0.0, mqtt-packet@^3.4.7: + version "3.5.1" + resolved "https://registry.yarnpkg.com/mqtt-packet/-/mqtt-packet-3.5.1.tgz#49b3688478ca3325fe45841fad7c88bc31042aeb" + integrity sha512-9mHaa4MltqT/VEzeO/3iAqduao/aCzx4qcC3SyXi0FPd3AFJ7lDeBUMsKaTQw0wWX7rLCQbClKOsuCURaii+ww== + dependencies: + bl "^1.0.0" + inherits "^2.0.1" + +mqtt-packet@^5.6.0: + version "5.6.1" + resolved "https://registry.yarnpkg.com/mqtt-packet/-/mqtt-packet-5.6.1.tgz#8ecafce091f5af460664268a22b22091c8915f7b" + integrity sha512-eaF9rO2uFrIYEHomJxziuKTDkbWW5psLBaIGCazQSKqYsTaB3n4SpvJ1PexKaDBiPnMLPIFWBIiTYT3IfEJfww== + dependencies: + bl "^1.2.1" + inherits "^2.0.3" + process-nextick-args "^2.0.0" + safe-buffer "^5.1.0" + +mqtt@2.18.8: + version "2.18.8" + resolved "https://registry.yarnpkg.com/mqtt/-/mqtt-2.18.8.tgz#9d213ccab92151accfb21ee8c0860dc6866ab259" + integrity sha512-3h6oHlPY/yWwtC2J3geraYRtVVoRM6wdI+uchF4nvSSafXPZnaKqF8xnX+S22SU/FcgEAgockVIlOaAX3fkMpA== + dependencies: + commist "^1.0.0" + concat-stream "^1.6.2" + end-of-stream "^1.4.1" + es6-map "^0.1.5" + help-me "^1.0.1" + inherits "^2.0.3" + minimist "^1.2.0" + mqtt-packet "^5.6.0" + pump "^3.0.0" + readable-stream "^2.3.6" + reinterval "^1.1.0" + split2 "^2.1.1" + websocket-stream "^5.1.2" + xtend "^4.0.1" + +mqtt@^1.10.0, mqtt@^1.6.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/mqtt/-/mqtt-1.14.1.tgz#7e376987153d01793e946d26d46122ebf0c03554" + integrity sha1-fjdphxU9AXk+lG0m1GEi6/DANVQ= + dependencies: + commist "^1.0.0" + concat-stream "^1.4.7" + end-of-stream "^1.1.0" + help-me "^1.0.0" + inherits "^2.0.1" + minimist "^1.1.0" + mqtt-connection "^2.0.0" + mqtt-packet "^3.4.7" + pump "^1.0.1" + readable-stream "~1.0.2" + reinterval "^1.0.1" + split2 "^2.0.1" + websocket-stream "^3.0.1" + xtend "^4.0.0" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + integrity sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg= + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +msgpack-lite@^0.1.20: + version "0.1.26" + resolved "https://registry.yarnpkg.com/msgpack-lite/-/msgpack-lite-0.1.26.tgz#dd3c50b26f059f25e7edee3644418358e2a9ad89" + integrity sha1-3TxQsm8FnyXn7e42REGDWOKprYk= + dependencies: + event-lite "^0.1.1" + ieee754 "^1.1.8" + int64-buffer "^0.1.9" + isarray "^1.0.0" + +msgpack5@^3.3.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/msgpack5/-/msgpack5-3.6.0.tgz#13912ee47cb0ad037f70def7924ebf38afa19b4f" + integrity sha512-6HuCZHA57WtNUzrKIvjJ8OMxigzveJ6D5i13y6TsgGu3X3zxABpuBvChpppOoGdB9SyWZcmqUs1fwUV/PpSQ7Q== + dependencies: + bl "^1.2.1" + inherits "^2.0.3" + readable-stream "^2.3.3" + safe-buffer "^5.1.1" + +multer@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.2.tgz#2f1f4d12dbaeeba74cb37e623f234bf4d3d2057a" + integrity sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg== + dependencies: + append-field "^1.0.0" + busboy "^0.2.11" + concat-stream "^1.5.2" + mkdirp "^0.5.1" + object-assign "^4.1.1" + on-finished "^2.3.0" + type-is "^1.6.4" + xtend "^4.0.0" + +mustache@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.0.0.tgz#7f02465dbb5b435859d154831c032acdfbbefb31" + integrity sha512-FJgjyX/IVkbXBXYUwH+OYwQKqWpFPLaLVESd70yHjSDunwzV2hZOoTBvPf4KLoxesUzzyfTH6F784Uqd7Wm5yA== + +nan@2.13.2: + version "2.13.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" + integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== + +nan@2.3.5, nan@~2.3.0: + version "2.3.5" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.3.5.tgz#822a0dc266290ce4cd3a12282ca3e7e364668a08" + integrity sha1-gioNwmYpDOTNOhIoLKPn42Rmigg= + +nan@^2.0, nan@^2.12.1, nan@^2.13.2, nan@^2.6.2: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + +nan@~2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" + integrity sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA== + +nanoid@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-0.2.2.tgz#e2ebc6ad3db5e0454fd8124d30ca39b06555fe56" + integrity sha512-GHoRrvNEKiwdkwQ/enKL8AhQkkrBC/2KxMZkDvQzp8OtkpX8ZAmoYJWFVl7l8F2+HcEJUfdg21Ab2wXXfrvACQ== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +needle@^2.2.1: + version "2.3.3" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.3.3.tgz#a041ad1d04a871b0ebb666f40baaf1fb47867117" + integrity sha512-EkY0GeSq87rWp1hoq/sH/wnTWgFVhYlnIkbJ0YJFfRgEFlz2RraCjBpFQ+vrEgEdp0ThfyHADmkChEhcb7PKyw== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.2, negotiator@~0.6.1: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +nested-error-stacks@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-1.0.2.tgz#19f619591519f096769a5ba9a86e6eeec823c3cf" + integrity sha1-GfYZWRUZ8JZ2mlupqG5u7sgjw88= + dependencies: + inherits "~2.0.1" + +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +nise@^1.2.0: + version "1.5.3" + resolved "https://registry.yarnpkg.com/nise/-/nise-1.5.3.tgz#9d2cfe37d44f57317766c6e9408a359c5d3ac1f7" + integrity sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ== + dependencies: + "@sinonjs/formatio" "^3.2.1" + "@sinonjs/text-encoding" "^0.7.1" + just-extend "^4.0.2" + lolex "^5.0.1" + path-to-regexp "^1.7.0" + +node-abi@^2.2.0: + version "2.15.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.15.0.tgz#51d55cc711bd9e4a24a572ace13b9231945ccb10" + integrity sha512-FeLpTS0F39U7hHZU1srAK4Vx+5AHNVOTP+hxBNQknR/54laTHSFIJkDWDqiquY1LeLUgTfPN7sLPhMubx0PLAg== + dependencies: + semver "^5.4.1" + +node-gyp@3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.4.0.tgz#dda558393b3ecbbe24c9e6b8703c71194c63fa36" + integrity sha1-3aVYOTs+y74kyea4cDxxGUxj+jY= + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + minimatch "^3.0.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3" + osenv "0" + path-array "^1.0.0" + request "2" + rimraf "2" + semver "2.x || 3.x || 4 || 5" + tar "^2.0.0" + which "1" + +node-gyp@^3.0.3, node-gyp@^3.6.2, node-gyp@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "^2.87.0" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + +node-ninja@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/node-ninja/-/node-ninja-1.0.2.tgz#20a09e57b92e2df591993d4bf098ac3e727062b6" + integrity sha1-IKCeV7kuLfWRmT1L8JisPnJwYrY= + dependencies: + fstream "^1.0.0" + glob "3 || 4 || 5 || 6 || 7" + graceful-fs "^4.1.2" + minimatch "3" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2" + osenv "0" + path-array "^1.0.0" + request "2" + rimraf "2" + semver "2.x || 3.x || 4 || 5" + tar "^2.0.0" + which "1" + +node-pre-gyp@0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" + integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +node-red-node-rbe@^0.2.6: + version "0.2.8" + resolved "https://registry.yarnpkg.com/node-red-node-rbe/-/node-red-node-rbe-0.2.8.tgz#b421a7e5a00e4b8f4d3a7101b43911444c40973b" + integrity sha512-v2pZOn/raE87JLB86l5fH2JkU7uthqzV3lLI9WcL+fA+vDlg5iN2p/eQfhUy1DhgEmqmGrLu03h5efv+Sly5Vg== + +node-red-node-sentiment@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/node-red-node-sentiment/-/node-red-node-sentiment-0.1.6.tgz#91ccb35a1462958db1e453bed0432d217ec14f69" + integrity sha512-u0+5U51/cHCGtREwqbOHtkwPB9lTejvQ/Q2ZTNf2acbFUujzcZf8UvQGTTil0yiVspL4Su2JTCa/Ng7b1vfdQg== + dependencies: + sentiment "2.1.0" + +node-red-node-tail@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/node-red-node-tail/-/node-red-node-tail-0.1.1.tgz#eb14c39119d05fb0304a0a2e485911432c745ba3" + integrity sha512-j1g/VtSCI2tBrBnCD+u8iSo9tH0nvn70k1O1SxkHk3+qx7tHUyOKQc7wNc4rUs9J1PkGngUC3qEDd5cL7Z/klg== + dependencies: + tail "^2.0.3" + +node-red-node-test-helper@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/node-red-node-test-helper/-/node-red-node-test-helper-0.2.3.tgz#2c8490af00730adf3532a87f283f6d4be286332a" + integrity sha512-N9/Fcrmbco3TSJNyLriM3L7tRd14nSjMQAseo2sgMaJi1rS+2+wXc8ka2RFYYH8EqI2MEeYbS2GPa+kfXEdrUg== + dependencies: + express "4.17.1" + read-pkg-up "3.0.0" + semver "6.2.0" + should "^13.2.3" + should-sinon "0.0.6" + sinon "5.0.3" + stoppable "1.1.0" + supertest "3.0.0" + +node-sass@^4.13.1: + version "4.13.1" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.13.1.tgz#9db5689696bb2eec2c32b98bfea4c7a2e992d0a3" + integrity sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw== + dependencies: + async-foreach "^0.1.3" + chalk "^1.1.1" + cross-spawn "^3.0.0" + gaze "^1.0.0" + get-stdin "^4.0.1" + glob "^7.0.3" + in-publish "^2.0.0" + lodash "^4.17.15" + meow "^3.7.0" + mkdirp "^0.5.1" + nan "^2.13.2" + node-gyp "^3.8.0" + npmlog "^4.0.0" + request "^2.88.0" + sass-graph "^2.2.4" + stdout-stream "^1.4.0" + "true-case-path" "^1.0.2" + +node-uuid@~1.4.3: + version "1.4.8" + resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" + integrity sha1-sEDrCSOWivq/jTL7HxfxFn/auQc= + +node-zookeeper-client@~0.2.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/node-zookeeper-client/-/node-zookeeper-client-0.2.3.tgz#48c79129c56b8e898df9bd3bdad9e27dcad63851" + integrity sha512-V4gVHxzQ42iwhkANpPryzfjmqi3Ql3xeO9E/px7W5Yi774WplU3YtqUpnvcL/eJit4UqcfuLOgZLkpf0BPhHmg== + dependencies: + async "~0.2.7" + underscore "~1.4.4" + +nodemon@^1.7.1: + version "1.19.4" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.19.4.tgz#56db5c607408e0fdf8920d2b444819af1aae0971" + integrity sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ== + dependencies: + chokidar "^2.1.8" + debug "^3.2.6" + ignore-by-default "^1.0.1" + minimatch "^3.0.4" + pstree.remy "^1.1.7" + semver "^5.7.1" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.2" + update-notifier "^2.5.0" + +noop-logger@^0.1.0, noop-logger@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" + integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI= + +"nopt@2 || 3", nopt@3.x, nopt@~3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + +nopt@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + dependencies: + abbrev "1" + osenv "^0.1.4" + +nopt@^4.0.1, nopt@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" + integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== + dependencies: + abbrev "1" + osenv "^0.1.4" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.0, normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-bundled@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" + integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== + dependencies: + npm-normalize-package-bin "^1.0.1" + +npm-normalize-package-bin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== + +npm-packlist@^1.1.6: + version "1.4.8" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" + integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + npm-normalize-package-bin "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +"npmlog@0 || 1 || 2", npmlog@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-2.0.4.tgz#98b52530f2514ca90d09ec5b22c8846722375692" + integrity sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI= + dependencies: + ansi "~0.3.1" + are-we-there-yet "~1.1.2" + gauge "~1.2.5" + +"npmlog@0 || 1 || 2 || 3": + version "3.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-3.1.2.tgz#2d46fa874337af9498a2f12bb43d8d0be4a36873" + integrity sha1-LUb6h0M3r5SYovErtD2NC+SjaHM= + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.6.0" + set-blocking "~2.0.0" + +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.1, npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +nth-check@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +oauth2orize@1.11.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/oauth2orize/-/oauth2orize-1.11.0.tgz#793cef251d45ebdeac32ae40a8b6814faab1d483" + integrity sha1-eTzvJR1F696sMq5AqLaBT6qx1IM= + dependencies: + debug "2.x.x" + uid2 "0.0.x" + utils-merge "1.x.x" + +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-get@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/object-get/-/object-get-2.1.1.tgz#1dad63baf6d94df184d1c58756cc9be55b174dac" + integrity sha512-7n4IpLMzGGcLEMiQKsNR7vCe+N5E9LORFrtNUVy4sO3dj9a3HedZCxEL2T7QuLhcHN1NBuBsMOKaOsAYI9IIvg== + +object-inspect@~1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.4.1.tgz#37ffb10e71adaf3748d05f713b4c9452f402cbc4" + integrity sha512-wqdhLpfCUbEsoEwl3FXwGyv8ief1k/1aUdIPCqVnupM6e8l63BEJdiF/0swtn04/8p05tG/T0FrpTlfwvljOdw== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.0.6: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-to-spawn-args@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-to-spawn-args/-/object-to-spawn-args-1.1.1.tgz#77da8827f073d011c9e1b173f895781470246785" + integrity sha1-d9qIJ/Bz0BHJ4bFz+JV4FHAkZ4U= + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.0.4: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.defaults@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" + integrity sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8= + dependencies: + array-each "^1.0.1" + array-slice "^1.0.0" + for-own "^1.0.0" + isobject "^3.0.0" + +object.map@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" + integrity sha1-z4Plncj8wK1fQlDh94s7gb2AHTc= + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + +object.pick@^1.2.0, object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +on-finished@^2.3.0, on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@1.0.2, on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@1.x, once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optional@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/optional/-/optional-0.1.4.tgz#cdb1a9bedc737d2025f690ceeb50e049444fd5b3" + integrity sha512-gtvrrCfkE08wKcgXaVwQVgwEQ8vel2dc5DDBn9RLQZ3YtmtkBss6A2HY6BnJH4N/4Ku97Ri/SF8sNWE2225WJw== + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +options@>=0.0.5: + version "0.0.6" + resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" + integrity sha1-7CLTEoBrtT5zF3Pnza788cZDEo8= + +ordered-read-streams@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" + integrity sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4= + dependencies: + readable-stream "^2.0.1" + +os-homedir@^1.0.0, os-homedir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= + dependencies: + lcid "^1.0.0" + +os-tmpdir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@0, osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +pad-stream@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pad-stream/-/pad-stream-1.2.0.tgz#631dcc9f79810b705965e89dedea6cff0fc1dfc9" + integrity sha1-Yx3Mn3mBC3BZZeid7eps/w/B38k= + dependencies: + meow "^3.0.0" + pumpify "^1.3.3" + repeating "^2.0.0" + split2 "^1.0.0" + through2 "^2.0.0" + +parse-filepath@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" + integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE= + dependencies: + is-absolute "^1.0.0" + map-cache "^0.2.0" + path-root "^0.1.1" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +passport-http-bearer@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/passport-http-bearer/-/passport-http-bearer-1.0.1.tgz#147469ea3669e2a84c6167ef99dbb77e1f0098a8" + integrity sha1-FHRp6jZp4qhMYWfvmdu3fh8AmKg= + dependencies: + passport-strategy "1.x.x" + +passport-oauth2-client-password@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/passport-oauth2-client-password/-/passport-oauth2-client-password-0.1.2.tgz#4f378b678b92d16dbbd233a6c706520093e561ba" + integrity sha1-TzeLZ4uS0W270jOmxwZSAJPlYbo= + dependencies: + passport-strategy "1.x.x" + +passport-strategy@1.x.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" + integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= + +passport@0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.1.tgz#941446a21cb92fc688d97a0861c38ce9f738f270" + integrity sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg== + dependencies: + passport-strategy "1.x.x" + pause "0.0.1" + +path-array@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-array/-/path-array-1.0.1.tgz#7e2f0f35f07a2015122b868b7eac0eb2c4fec271" + integrity sha1-fi8PNfB6IBUSK4aLfqwOssT+wnE= + dependencies: + array-index "^1.0.0" + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0, path-is-absolute@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-root-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0= + +path-root@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc= + dependencies: + path-root-regex "^0.1.0" + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-to-regexp@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +pause@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= + +pbkdf2-password@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pbkdf2-password/-/pbkdf2-password-1.2.1.tgz#9f74513a155fd38d4d6b5c8414d3955dd26ca6ee" + integrity sha1-n3RROhVf041Na1yEFNOVXdJspu4= + dependencies: + fastfall "^1.2.3" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pino@^2.4.2: + version "2.16.0" + resolved "https://registry.yarnpkg.com/pino/-/pino-2.16.0.tgz#51ab831b9b459330e7fff5edb75b20973ca94703" + integrity sha1-UauDG5tFkzDn//Xtt1sglzypRwM= + dependencies: + chalk "^1.1.1" + fast-json-parse "^1.0.0" + fast-safe-stringify "^1.1.3" + flatstr "^1.0.4" + object.assign "^4.0.4" + once "^1.3.3" + quick-format-unescaped "^1.0.0" + split2 "^2.0.1" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +prebuild-install@^2.3.0: + version "2.5.3" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-2.5.3.tgz#9f65f242782d370296353710e9bc843490c19f69" + integrity sha512-/rI36cN2g7vDQnKWN8Uzupi++KjyqS9iS+/fpwG4Ea8d0Pip0PQ5bshUNzVwt+/D2MRfhVAplYMMvWLqWrCF/g== + dependencies: + detect-libc "^1.0.3" + expand-template "^1.0.2" + github-from-package "0.0.0" + minimist "^1.2.0" + mkdirp "^0.5.1" + node-abi "^2.2.0" + noop-logger "^0.1.1" + npmlog "^4.0.1" + os-homedir "^1.0.1" + pump "^2.0.1" + rc "^1.1.6" + simple-get "^2.7.0" + tar-fs "^1.13.0" + tunnel-agent "^0.6.0" + which-pm-runs "^1.0.0" + +prebuild@^4.1.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/prebuild/-/prebuild-4.5.0.tgz#2aaa0df2063bff814a803bd4dc94ff9b64e5df00" + integrity sha1-KqoN8gY7/4FKgDvU3JT/m2Tl3wA= + dependencies: + async "^1.4.0" + execspawn "^1.0.1" + expand-template "^1.0.0" + ghreleases "^1.0.2" + github-from-package "0.0.0" + minimist "^1.1.2" + mkdirp "^0.5.1" + node-gyp "^3.0.3" + node-ninja "^1.0.1" + noop-logger "^0.1.0" + npmlog "^2.0.0" + os-homedir "^1.0.1" + pump "^1.0.0" + rc "^1.0.3" + simple-get "^1.4.2" + tar-fs "^1.7.0" + tar-stream "^1.2.1" + xtend "^4.0.1" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +pretty-bytes@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-3.0.1.tgz#27d0008d778063a0b4811bb35c79f1bd5d5fbccf" + integrity sha1-J9AAjXeAY6C0gRuzXHnxvV1fvM8= + dependencies: + number-is-nan "^1.0.0" + +pretty-bytes@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9" + integrity sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk= + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= + +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.1" + +prr@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" + integrity sha1-GoS4WQgyVQFBGFPQCB7j+obikmo= + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +pseudomap@^1.0.1, pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +psl@^1.1.24, psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +pstree.remy@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.7.tgz#c76963a28047ed61542dc361aa26ee55a7fa15f3" + integrity sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A== + +pull-cat@^1.1.9: + version "1.1.11" + resolved "https://registry.yarnpkg.com/pull-cat/-/pull-cat-1.1.11.tgz#b642dd1255da376a706b6db4fa962f5fdb74c31b" + integrity sha1-tkLdElXaN2pwa220+pYvX9t0wxs= + +pull-defer@^0.2.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/pull-defer/-/pull-defer-0.2.3.tgz#4ee09c6d9e227bede9938db80391c3dac489d113" + integrity sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA== + +pull-level@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pull-level/-/pull-level-2.0.4.tgz#4822e61757c10bdcc7cf4a03af04c92734c9afac" + integrity sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg== + dependencies: + level-post "^1.0.7" + pull-cat "^1.1.9" + pull-live "^1.0.1" + pull-pushable "^2.0.0" + pull-stream "^3.4.0" + pull-window "^2.1.4" + stream-to-pull-stream "^1.7.1" + +pull-live@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pull-live/-/pull-live-1.0.1.tgz#a4ecee01e330155e9124bbbcf4761f21b38f51f5" + integrity sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU= + dependencies: + pull-cat "^1.1.9" + pull-stream "^3.4.0" + +pull-pushable@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/pull-pushable/-/pull-pushable-2.2.0.tgz#5f2f3aed47ad86919f01b12a2e99d6f1bd776581" + integrity sha1-Xy867UethpGfAbEqLpnW8b13ZYE= + +pull-stream@^3.2.3, pull-stream@^3.4.0, pull-stream@^3.6.8: + version "3.6.14" + resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-3.6.14.tgz#529dbd5b86131f4a5ed636fdf7f6af00781357ee" + integrity sha512-KIqdvpqHHaTUA2mCYcLG1ibEbu/LCKoJZsBWyv9lSYtPkJPBq8m3Hxa103xHi6D2thj5YXa0TqK3L3GUkwgnew== + +pull-window@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/pull-window/-/pull-window-2.1.4.tgz#fc3b86feebd1920c7ae297691e23f705f88552f0" + integrity sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA= + dependencies: + looper "^2.0.0" + +pump@^1.0.0, pump@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" + integrity sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^2.0.0, pump@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3, pumpify@^1.3.5: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qlobber-fsq@~3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/qlobber-fsq/-/qlobber-fsq-3.2.4.tgz#fbe085da8f4626288ecc20c7107293e0eacf4db2" + integrity sha1-++CF2o9GJiiOzCDHEHKT4OrPTbI= + dependencies: + async "~1.5.2" + graceful-fs "~4.1.3" + qlobber "~0.7.0" + optionalDependencies: + fs-ext "~0.5.0" + +qlobber@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/qlobber/-/qlobber-0.7.0.tgz#0229b635cd7d20ad7b3acf298da6d2b94f0e34cf" + integrity sha1-Aim2Nc19IK17Os8pjabSuU8ONM8= + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +qs@^6.4.0, qs@^6.5.1: + version "6.9.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e" + integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +quick-format-unescaped@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-1.1.2.tgz#0ca581de3174becef25ac3c2e8956342381db698" + integrity sha1-DKWB3jF0vs7yWsPC6JVjQjgdtpg= + dependencies: + fast-safe-stringify "^1.0.8" + +quote-stream@^1.0.1, quote-stream@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/quote-stream/-/quote-stream-1.0.2.tgz#84963f8c9c26b942e153feeb53aae74652b7e0b2" + integrity sha1-hJY/jJwmuULhU/7rU6rnRlK34LI= + dependencies: + buffer-equal "0.0.1" + minimist "^1.1.3" + through2 "^2.0.0" + +random-bytes@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" + integrity sha1-T2ih3Arli9P7lYSMMDJNt11kNgs= + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +raw-body@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" + integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== + dependencies: + bytes "3.1.0" + http-errors "1.7.3" + iconv-lite "0.4.24" + unpipe "1.0.0" + +raw-body@~1.1.0: + version "1.1.7" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-1.1.7.tgz#1d027c2bfa116acc6623bca8f00016572a87d425" + integrity sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU= + dependencies: + bytes "1" + string_decoder "0.10" + +rc@^1.0.1, rc@^1.0.3, rc@^1.1.6, rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-pkg-up@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +readable-stream@1.0.31: + version "1.0.31" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.31.tgz#8f2502e0bc9e3b0da1b94520aabb4e2603ecafae" + integrity sha1-jyUC4LyeOw2huUUgqrtOJgPsr64= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@1.1: + version "1.1.13" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e" + integrity sha1-9u73ZPUUyJ4rniMUanW6EGdW0j4= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@1.1.x, "readable-stream@1.x >=1.1.9", readable-stream@^1.0.33, readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@2.2.7: + version "2.2.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.7.tgz#07057acbe2467b22042d36f98c5ad507054e95b1" + integrity sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE= + dependencies: + buffer-shims "~1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~1.0.0" + util-deprecate "~1.0.1" + +"readable-stream@> 1.0.0 < 3.0.0", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.3, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.2, readable-stream@~1.0.26, readable-stream@~1.0.26-2: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^3.0.1, readable-stream@^3.1.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +redis-commands@^1.2.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.5.0.tgz#80d2e20698fe688f227127ff9e5164a7dd17e785" + integrity sha512-6KxamqpZ468MeQC3bkWmCB1fp56XL64D4Kf0zJSwDZbVLLm7KFkoIcHrgRvQ+sk8dnhySs7+yBg94yIkAK7aJg== + +redis-parser@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-1.3.0.tgz#806ebe7bbfb7d34e4d7c1e9ef282efcfad04126a" + integrity sha1-gG6+e7+3005NfB6e8oLvz60EEmo= + +reduce-extract@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/reduce-extract/-/reduce-extract-1.0.0.tgz#67f2385beda65061b5f5f4312662e8b080ca1525" + integrity sha1-Z/I4W+2mUGG19fQxJmLosIDKFSU= + dependencies: + test-value "^1.0.1" + +reduce-flatten@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-1.0.1.tgz#258c78efd153ddf93cb561237f61184f3696e327" + integrity sha1-JYx479FT3fk8tWEjf2EYTzaW4yc= + +reduce-unique@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/reduce-unique/-/reduce-unique-1.0.0.tgz#7e586bcf87a4e32b6d7abd8277fad6cdec9f4803" + integrity sha1-flhrz4ek4ytter2Cd/rWzeyfSAM= + +reduce-without@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/reduce-without/-/reduce-without-1.0.1.tgz#68ad0ead11855c9a37d4e8256c15bbf87972fc8c" + integrity sha1-aK0OrRGFXJo31OglbBW7+Hly/Iw= + dependencies: + test-value "^2.0.0" + +reduplexer@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/reduplexer/-/reduplexer-1.1.0.tgz#7dfed18a679e749c1d7ad36de01acb515f08e140" + integrity sha1-ff7RimeedJwdetNt4BrLUV8I4UA= + dependencies: + inherits "^2.0.1" + readable-stream "~1.0.26-2" + +regenerator-runtime@^0.13.4: + version "0.13.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" + integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +registry-auth-token@^3.0.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" + integrity sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A== + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= + dependencies: + rc "^1.0.1" + +reinterval@^1.0.1, reinterval@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/reinterval/-/reinterval-1.1.0.tgz#3361ecfa3ca6c18283380dd0bb9546f390f5ece7" + integrity sha1-M2Hs+jymwYKDOA3Qu5VG85D17Oc= + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +request@2, request@^2.87.0, request@^2.88.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +request@2.88.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +require_optional@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require_optional/-/require_optional-1.0.1.tgz#4cf35a4247f64ca3df8c2ef208cc494b1ca8fc2e" + integrity sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g== + dependencies: + resolve-from "^2.0.0" + semver "^5.1.0" + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +requizzle@^0.2.3, requizzle@~0.2.1: + version "0.2.3" + resolved "https://registry.yarnpkg.com/requizzle/-/requizzle-0.2.3.tgz#4675c90aacafb2c036bd39ba2daa4a1cb777fded" + integrity sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ== + dependencies: + lodash "^4.17.14" + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" + integrity sha1-lICrIOlP+h2egKgEx+oUdhGWa1c= + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@1.1.x, resolve@~1.1.0: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + +resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0: + version "1.15.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" + integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== + dependencies: + path-parse "^1.0.6" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +retimer@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/retimer/-/retimer-1.1.0.tgz#8cb2cec5cc200c245622e943aa11549f25c5ed2c" + integrity sha512-+Tjoa47XqpO+cmNObvmK6UPFmUTzQPtr4MqMS7ZJKPKYAnryCxG2FXT8/SEgPsEghQQgXFPZEdILNxJkvXtjUw== + +retry@~0.6.0, retry@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.6.1.tgz#fdc90eed943fde11b893554b8cc63d0e899ba918" + integrity sha1-/ckO7ZQ/3hG4k1VLjMY9DombqRg= + +reusify@^1.0.0, reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@2, rimraf@^2.6.1, rimraf@^2.6.2: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.0, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + +safe-json-parse@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/safe-json-parse/-/safe-json-parse-1.0.1.tgz#3e76723e38dfdda13c9b1d29a1e07ffee4b30b57" + integrity sha1-PnZyPjjf3aE8mx0poeB//uSzC1c= + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +samsam@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567" + integrity sha1-vsEf3IOp/aBjQBIQ5AF2wwJNFWc= + +samsam@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50" + integrity sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg== + +samsam@~1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.3.tgz#9f5087419b4d091f232571e7fa52e90b0f552621" + integrity sha1-n1CHQZtNCR8jJXHn+lLpCw9VJiE= + +sass-graph@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" + integrity sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k= + dependencies: + glob "^7.0.0" + lodash "^4.0.0" + scss-tokenizer "^0.2.3" + yargs "^7.0.0" + +sax@>=0.6.0, sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +scss-tokenizer@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" + integrity sha1-jrBtualyMzOCTT9VMGQRSYR85dE= + dependencies: + js-base64 "^2.1.8" + source-map "^0.4.2" + +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= + dependencies: + semver "^5.0.3" + +"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.7.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db" + integrity sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A== + +semver@6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.1.1.tgz#a3292a373e6f3e0798da0b20641b9a9c5bc47e19" + integrity sha1-oykqNz5vPgeY2gsgZBuanFvEfhk= + +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= + +semver@~5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + 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.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +sentiment@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/sentiment/-/sentiment-2.1.0.tgz#33279100c35c38519ca5e435245186c512fe0fdc" + integrity sha1-MyeRAMNcOFGcpeQ1JFGGxRL+D9w= + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +shallow-copy@~0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170" + integrity sha1-QV9CcC1z2BAzApLMXuhurhoRoXA= + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shelljs@0.3.x: + version "0.3.0" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.3.0.tgz#3596e6307a781544f591f37da618360f31db57b1" + integrity sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E= + +shelljs@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.5.3.tgz#c54982b996c76ef0c1e6b59fbdc5825f5b713113" + integrity sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM= + +should-equal@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/should-equal/-/should-equal-0.8.0.tgz#a3f05732ff45bac1b7ba412f8408856819641299" + integrity sha1-o/BXMv9FusG3ukEvhAiFaBlkEpk= + dependencies: + should-type "0.2.0" + +should-equal@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/should-equal/-/should-equal-2.0.0.tgz#6072cf83047360867e68e98b09d71143d04ee0c3" + integrity sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA== + dependencies: + should-type "^1.4.0" + +should-format@0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/should-format/-/should-format-0.3.2.tgz#a59831e01a2ddee149911bc7148be5c80319e1ff" + integrity sha1-pZgx4Bot3uFJkRvHFIvlyAMZ4f8= + dependencies: + should-type "0.2.0" + +should-format@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/should-format/-/should-format-3.0.3.tgz#9bfc8f74fa39205c53d38c34d717303e277124f1" + integrity sha1-m/yPdPo5IFxT04w01xcwPidxJPE= + dependencies: + should-type "^1.3.0" + should-type-adaptors "^1.0.1" + +should-sinon@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/should-sinon/-/should-sinon-0.0.6.tgz#be041a7c928f44ac9ccf5dc042d032618ce29f84" + integrity sha512-ScBOH5uW5QVFaONmUnIXANSR6z5B8IKzEmBP3HE5sPOCDuZ88oTMdUdnKoCVQdLcCIrRrhRLPS5YT+7H40a04g== + +should-type-adaptors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz#401e7f33b5533033944d5cd8bf2b65027792e27a" + integrity sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA== + dependencies: + should-type "^1.3.0" + should-util "^1.0.0" + +should-type@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/should-type/-/should-type-0.2.0.tgz#6707ef95529d989dcc098fe0753ab1f9136bb7f6" + integrity sha1-ZwfvlVKdmJ3MCY/gdTqx+RNrt/Y= + +should-type@^1.3.0, should-type@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/should-type/-/should-type-1.4.0.tgz#0756d8ce846dfd09843a6947719dfa0d4cff5cf3" + integrity sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM= + +should-util@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/should-util/-/should-util-1.0.1.tgz#fb0d71338f532a3a149213639e2d32cbea8bcb28" + integrity sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g== + +should@^13.2.3: + version "13.2.3" + resolved "https://registry.yarnpkg.com/should/-/should-13.2.3.tgz#96d8e5acf3e97b49d89b51feaa5ae8d07ef58f10" + integrity sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ== + dependencies: + should-equal "^2.0.0" + should-format "^3.0.3" + should-type "^1.4.0" + should-type-adaptors "^1.0.1" + should-util "^1.0.0" + +should@^8.4.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/should/-/should-8.4.0.tgz#5e60889d3e644bbdd397a30cd34fad28fcf90bc0" + integrity sha1-XmCInT5kS73Tl6MM00+tKPz5C8A= + dependencies: + should-equal "0.8.0" + should-format "0.3.2" + should-type "0.2.0" + +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +simple-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" + integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= + +simple-get@^1.4.2: + version "1.4.3" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-1.4.3.tgz#e9755eda407e96da40c5e5158c9ea37b33becbeb" + integrity sha1-6XVe2kB+ltpAxeUVjJ6jezO+y+s= + dependencies: + once "^1.3.1" + unzip-response "^1.0.0" + xtend "^4.0.0" + +simple-get@^2.7.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" + integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw== + dependencies: + decompress-response "^3.3.0" + once "^1.3.1" + simple-concat "^1.0.0" + +simple-mime@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/simple-mime/-/simple-mime-0.1.0.tgz#95f517c4f466d7cff561a71fc9dab2596ea9ef2e" + integrity sha1-lfUXxPRm18/1YacfydqyWW6p7y4= + +sinon@1.17.7: + version "1.17.7" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-1.17.7.tgz#4542a4f49ba0c45c05eb2e9dd9d203e2b8efe0bf" + integrity sha1-RUKk9JugxFwF6y6d2dID4rjv4L8= + dependencies: + formatio "1.1.1" + lolex "1.3.2" + samsam "1.1.2" + util ">=0.10.3 <1" + +sinon@5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-5.0.3.tgz#9950f1616187ff0cd7d75a60d66bc27fed569945" + integrity sha512-kzBkET1Hf0r0J4uVnlicuAEiq9nnhPrEHZWS0mds+5EaB9rA0XoliIkLaqkBNU9lwPuJACo/velUQQOmTRJtUw== + dependencies: + "@sinonjs/formatio" "^2.0.0" + diff "^3.1.0" + lodash.get "^4.4.2" + lolex "^2.2.0" + nise "^1.2.0" + supports-color "^5.1.0" + type-detect "^4.0.5" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +snappy@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/snappy/-/snappy-5.0.5.tgz#ec189323469546aedde43592f7808808fd073b45" + integrity sha1-7BiTI0aVRq7d5DWS94CICP0HO0U= + dependencies: + bindings "1.2.1" + nan "2.3.5" + node-gyp "3.4.0" + +sort-array@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-array/-/sort-array-2.0.0.tgz#38a9c6da27fd7d147b42e60554f281187b4df472" + integrity sha1-OKnG2if9fRR7QuYFVPKBGHtN9HI= + dependencies: + array-back "^1.0.4" + object-get "^2.1.0" + typical "^2.6.0" + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + integrity sha1-66T12pwNyZneaAMti092FzZSA2s= + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.3, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= + dependencies: + amdefine ">=0.0.4" + +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" + integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +split2@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/split2/-/split2-1.1.1.tgz#162d9b18865f02ab2f2ad9585522db9b54c481f9" + integrity sha1-Fi2bGIZfAqsvKtlYVSLbm1TEgfk= + dependencies: + through2 "~2.0.0" + +split2@^2.0.1, split2@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" + integrity sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw== + dependencies: + through2 "^2.0.2" + +sprintf-js@^1.0.3: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" + integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +st@^1.1.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/st/-/st-1.2.2.tgz#b95554f41b457bf0ed1c48f2bad8fccff894b14f" + integrity sha512-goKkumvz0BMLs6KjjPf5Fub/3T34tRVQxInUI5lqtbaKD+s4HcRlJYP2GPJ8RgAmrsnYOPGmOFEP6ho0KJ+E8g== + dependencies: + async-cache "~1.1.0" + bl "~1.2.1" + fd "~0.0.2" + mime "~1.4.1" + negotiator "~0.6.1" + optionalDependencies: + graceful-fs "~4.1.11" + +static-eval@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-2.0.5.tgz#f0782e66999c4b3651cda99d9ce59c507d188f71" + integrity sha512-nNbV6LbGtMBgv7e9LFkt5JV8RVlRsyJrphfAt9tOtBBW/SfnzZDf2KnS72an8e434A+9e/BmJuTxeGPvrAK7KA== + dependencies: + escodegen "^1.11.1" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +static-module@^2.1.1: + version "2.2.5" + resolved "https://registry.yarnpkg.com/static-module/-/static-module-2.2.5.tgz#bd40abceae33da6b7afb84a0e4329ff8852bfbbf" + integrity sha512-D8vv82E/Kpmz3TXHKG8PPsCPg+RAX6cbCOyvjM6x04qZtQ47EtJFVwRsdov3n5d6/6ynrOY9XB4JkaZwB2xoRQ== + dependencies: + concat-stream "~1.6.0" + convert-source-map "^1.5.1" + duplexer2 "~0.1.4" + escodegen "~1.9.0" + falafel "^2.1.0" + has "^1.0.1" + magic-string "^0.22.4" + merge-source-map "1.0.4" + object-inspect "~1.4.0" + quote-stream "~1.0.2" + readable-stream "~2.3.3" + shallow-copy "~0.0.1" + static-eval "^2.0.0" + through2 "~2.0.3" + +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +stdout-stream@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de" + integrity sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA== + dependencies: + readable-stream "^2.0.1" + +steed@^1.0.0, steed@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/steed/-/steed-1.1.3.tgz#f1525dd5adb12eb21bf74749537668d625b9abc5" + integrity sha1-8VJd1a2xLrIb90dJU3Zo1iW5q8U= + dependencies: + fastfall "^1.5.0" + fastparallel "^2.2.0" + fastq "^1.3.0" + fastseries "^1.7.0" + reusify "^1.0.0" + +stoppable@1.1.0, stoppable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/stoppable/-/stoppable-1.1.0.tgz#32da568e83ea488b08e4d7ea2c3bcc9d75015d5b" + integrity sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw== + +stream-buffers@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" + integrity sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ= + +stream-connect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stream-connect/-/stream-connect-1.0.2.tgz#18bc81f2edb35b8b5d9a8009200a985314428a97" + integrity sha1-GLyB8u2zW4tdmoAJIAqYUxRCipc= + dependencies: + array-back "^1.0.2" + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +stream-to-pull-stream@^1.7.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/stream-to-pull-stream/-/stream-to-pull-stream-1.7.3.tgz#4161aa2d2eb9964de60bfa1af7feaf917e874ece" + integrity sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg== + dependencies: + looper "^3.0.0" + pull-stream "^3.2.3" + +stream-via@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/stream-via/-/stream-via-1.0.4.tgz#8dccbb0ac909328eb8bc8e2a4bd3934afdaf606c" + integrity sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ== + +streamsearch@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= + +string-template@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" + integrity sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0= + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@0.10, string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" + integrity sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ== + dependencies: + safe-buffer "~5.1.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" + integrity sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E= + +strip-json-comments@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" + integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +superagent@^3.0.0, superagent@^3.8.3: + version "3.8.3" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.3.tgz#460ea0dbdb7d5b11bc4f78deba565f86a178e128" + integrity sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA== + dependencies: + component-emitter "^1.2.0" + cookiejar "^2.1.0" + debug "^3.1.0" + extend "^3.0.0" + form-data "^2.3.1" + formidable "^1.2.0" + methods "^1.1.1" + mime "^1.4.1" + qs "^6.5.1" + readable-stream "^2.3.5" + +supertest@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/supertest/-/supertest-3.0.0.tgz#8d4bb68fd1830ee07033b1c5a5a9a4021c965296" + integrity sha1-jUu2j9GDDuBwM7HFpamkAhyWUpY= + dependencies: + methods "~1.1.2" + superagent "^3.0.0" + +supertest@3.4.2: + version "3.4.2" + resolved "https://registry.yarnpkg.com/supertest/-/supertest-3.4.2.tgz#bad7de2e43d60d27c8caeb8ab34a67c8a5f71aad" + integrity sha512-WZWbwceHUo2P36RoEIdXvmqfs47idNNZjCuJOqDz6rvtkk8ym56aU5oglORCpPeXGxT7l9rkJ41+O1lffQXYSA== + dependencies: + methods "^1.1.2" + superagent "^3.8.3" + +supervisor@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/supervisor/-/supervisor-0.12.0.tgz#de7e6337015b291851c10f3538c4a7f04917ecc1" + integrity sha1-3n5jNwFbKRhRwQ81OMSn8EkX7ME= + +supports-color@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-1.2.0.tgz#ff1ed1e61169d06b3cf2d588e188b18d8847e17e" + integrity sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4= + +supports-color@5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== + dependencies: + has-flag "^3.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^3.1.0: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + +supports-color@^5.1.0, supports-color@^5.3.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +table-layout@^0.4.2: + version "0.4.5" + resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-0.4.5.tgz#d906de6a25fa09c0c90d1d08ecd833ecedcb7378" + integrity sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw== + dependencies: + array-back "^2.0.0" + deep-extend "~0.6.0" + lodash.padend "^4.6.1" + typical "^2.6.1" + wordwrapjs "^3.0.0" + +taffydb@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.6.2.tgz#7cbcb64b5a141b6a2efc2c5d2c67b4e150b2a268" + integrity sha1-fLy2S1oUG2ou/CxdLGe04VCyomg= + +tail@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/tail/-/tail-2.0.3.tgz#37567adc4624a70b35f1d146c3376fa3d6ef7c04" + integrity sha512-s9NOGkLqqiDEtBttQZI7acLS8ycYK5sTlDwNjGnpXG9c8AWj0cfAtwEIzo/hVRMMiC5EYz+bXaJWC1u1u0GPpQ== + +tar-fs@^1.13.0, tar-fs@^1.7.0: + version "1.16.3" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.3.tgz#966a628841da2c4010406a82167cbd5e0c72d509" + integrity sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw== + dependencies: + chownr "^1.0.1" + mkdirp "^0.5.1" + pump "^1.0.0" + tar-stream "^1.1.2" + +tar-stream@^1.1.2, tar-stream@^1.2.1, tar-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + +tar@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" + integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== + dependencies: + block-stream "*" + fstream "^1.0.12" + inherits "2" + +tar@^4: + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.8.6" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" + +temp-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/temp-path/-/temp-path-1.0.0.tgz#24b1543973ab442896d9ad367dd9cbdbfafe918b" + integrity sha1-JLFUOXOrRCiW2a02fdnL2/r+kYs= + +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= + dependencies: + execa "^0.7.0" + +test-value@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/test-value/-/test-value-1.1.0.tgz#a09136f72ec043d27c893707c2b159bfad7de93f" + integrity sha1-oJE29y7AQ9J8iTcHwrFZv6196T8= + dependencies: + array-back "^1.0.2" + typical "^2.4.2" + +test-value@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/test-value/-/test-value-2.1.0.tgz#11da6ff670f3471a73b625ca4f3fdcf7bb748291" + integrity sha1-Edpv9nDzRxpztiXKTz/c97t0gpE= + dependencies: + array-back "^1.0.3" + typical "^2.6.0" + +test-value@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/test-value/-/test-value-3.0.0.tgz#9168c062fab11a86b8d444dd968bb4b73851ce92" + integrity sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ== + dependencies: + array-back "^2.0.0" + typical "^2.6.1" + +through2-filter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254" + integrity sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA== + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2@^0.6.3, through2@~0.6.3: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + integrity sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg= + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + +through2@^2.0.0, through2@^2.0.1, through2@^2.0.2, through2@~2.0.0, through2@~2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + +tiny-lr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-1.1.1.tgz#9fa547412f238fedb068ee295af8b682c98b2aab" + integrity sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA== + dependencies: + body "^5.1.0" + debug "^3.1.0" + faye-websocket "~0.10.0" + livereload-js "^2.3.0" + object-assign "^4.1.0" + qs "^6.4.0" + +to-absolute-glob@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" + integrity sha1-GGX0PZ50sIItufFFt4z/fQ98hJs= + dependencies: + is-absolute "^1.0.0" + is-negated-glob "^1.0.0" + +to-buffer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== + +to-iso-string@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/to-iso-string/-/to-iso-string-0.0.2.tgz#4dc19e664dfccbe25bd8db508b00c6da158255d1" + integrity sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== + dependencies: + nopt "~1.0.10" + +tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +"traverse@>=0.3.0 <0.4": + version "0.3.9" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" + integrity sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk= + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + +"true-case-path@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.3.tgz#f813b5a8c86b40da59606722b144e3225799f47d" + integrity sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew== + dependencies: + glob "^7.1.2" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-detect@4.0.8, type-detect@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-is@^1.6.4, type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" + integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +typewise-core@^1.2, typewise-core@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/typewise-core/-/typewise-core-1.2.0.tgz#97eb91805c7f55d2f941748fa50d315d991ef195" + integrity sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU= + +typewise@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/typewise/-/typewise-1.0.3.tgz#1067936540af97937cc5dcf9922486e9fa284651" + integrity sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE= + dependencies: + typewise-core "^1.2.0" + +typewiselite@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typewiselite/-/typewiselite-1.0.0.tgz#c8882fa1bb1092c06005a97f34ef5c8508e3664e" + integrity sha1-yIgvobsQksBgBal/NO9chQjjZk4= + +typical@^2.4.2, typical@^2.6.0, typical@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" + integrity sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0= + +typical@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" + integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== + +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + +uglify-js@3.8.0, uglify-js@^3.1.4, uglify-js@^3.5.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.8.0.tgz#f3541ae97b2f048d7e7e3aa4f39fd8a1f5d7a805" + integrity sha512-ugNSTT8ierCsDHso2jkBHXYrU8Y5/fY2ZUprfrJUiD7YpuFvV4jODLFmb3h4btQjqr5Nh4TX4XtgDfCU1WdioQ== + dependencies: + commander "~2.20.3" + source-map "~0.6.1" + +uid-safe@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a" + integrity sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA== + dependencies: + random-bytes "~1.0.0" + +uid2@0.0.x: + version "0.0.3" + resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" + integrity sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I= + +ultron@1.0.x: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" + integrity sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po= + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + +unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= + +undefsafe@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae" + integrity sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A== + dependencies: + debug "^2.2.0" + +underscore.string@~3.3.4: + version "3.3.5" + resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.3.5.tgz#fc2ad255b8bd309e239cbc5816fd23a9b7ea4023" + integrity sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg== + dependencies: + sprintf-js "^1.0.3" + util-deprecate "^1.0.2" + +underscore@~1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604" + integrity sha1-YaajIBBiKvoHljvzJSA88SI51gQ= + +underscore@~1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" + integrity sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI= + +underscore@~1.9.1: + version "1.9.2" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.2.tgz#0c8d6f536d6f378a5af264a72f7bec50feb7cf2f" + integrity sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ== + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +unique-stream@^2.0.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" + integrity sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== + dependencies: + json-stable-stringify-without-jsonify "^1.0.1" + through2-filter "^3.0.0" + +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= + dependencies: + crypto-random-string "^1.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +unzip-response@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe" + integrity sha1-uYTwh3/AqJwsdzzB73tbIytbBv4= + +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +update-notifier@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== + dependencies: + boxen "^1.2.1" + chalk "^2.0.1" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-ci "^1.0.10" + is-installed-globally "^0.1.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +uri-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/uri-path/-/uri-path-1.0.0.tgz#9747f018358933c31de0fccfd82d138e67262e32" + integrity sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI= + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + +url-template@~2.0.6: + version "2.0.8" + resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" + integrity sha1-/FZaPMy/93MMd19WQflVV5FDnyE= + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util-extend@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" + integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8= + +"util@>=0.10.3 <1": + version "0.12.2" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.2.tgz#54adb634c9e7c748707af2bf5a8c7ab640cbba2b" + integrity sha512-XE+MkWQvglYa+IOfBt5UFG93EmncEMP23UqpgDvVZVFBPxwmkK10QRp6pgU4xICPnWRf/t0zPv4noYSUq9gqUQ== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + safe-buffer "^5.1.2" + +utils-merge@1.0.1, utils-merge@1.x.x: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + integrity sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho= + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +v8flags@~3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.3.tgz#fc9dc23521ca20c5433f81cc4eb9b3033bb105d8" + integrity sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w== + dependencies: + homedir-polyfill "^1.0.1" + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vlq@^0.2.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26" + integrity sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow== + +walk-back@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/walk-back/-/walk-back-2.0.1.tgz#554e2a9d874fac47a8cb006bf44c2f0c4998a0a4" + integrity sha1-VU4qnYdPrEeoywBr9EwvDEmYoKQ= + +walk-back@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/walk-back/-/walk-back-3.0.1.tgz#0c0012694725604960d6c2f75aaf1a1e7d455d35" + integrity sha512-umiNB2qLO731Sxbp6cfZ9pwURJzTnftxE4Gc7hq8n/ehkuXC//s9F65IEIJA2ZytQZ1ZOsm/Fju4IWx0bivkUQ== + +walkdir@^0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.0.11.tgz#a16d025eb931bd03b52f308caed0f40fcebe9532" + integrity sha1-oW0CXrkxvQO1LzCMrtD0D86+lTI= + +websocket-driver@>=0.5.1: + version "0.7.3" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9" + integrity sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg== + dependencies: + http-parser-js ">=0.4.0 <0.4.11" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" + integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== + +websocket-stream@^3.0.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/websocket-stream/-/websocket-stream-3.3.3.tgz#361da5404a337e60cfbc29b4a46368762679df0b" + integrity sha1-Nh2lQEozfmDPvCm0pGNodiZ53ws= + dependencies: + duplexify "^3.2.0" + inherits "^2.0.1" + through2 "^2.0.0" + ws "^1.0.1" + xtend "^4.0.0" + +websocket-stream@^5.1.2: + version "5.5.2" + resolved "https://registry.yarnpkg.com/websocket-stream/-/websocket-stream-5.5.2.tgz#49d87083d96839f0648f5513bbddd581f496b8a2" + integrity sha512-8z49MKIHbGk3C4HtuHWDtYX8mYej1wWabjthC/RupM9ngeukU4IWoM46dgth1UOS/T4/IqgEdCDJuMe2039OQQ== + dependencies: + duplexify "^3.5.1" + inherits "^2.0.1" + readable-stream "^2.3.3" + safe-buffer "^5.1.2" + ws "^3.2.0" + xtend "^4.0.0" + +websocket-stream@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/websocket-stream/-/websocket-stream-3.1.0.tgz#c6d9d13230b77e474c4b6736c295bba77cdd7f87" + integrity sha1-xtnRMjC3fkdMS2c2wpW7p3zdf4c= + dependencies: + duplexify "^3.2.0" + inherits "^2.0.1" + through2 "^2.0.0" + ws "^1.0.1" + xtend "^4.0.0" + +when@3.7.8: + version "3.7.8" + resolved "https://registry.yarnpkg.com/when/-/when-3.7.8.tgz#c7130b6a7ea04693e842cdc9e7a1f2aa39a39f82" + integrity sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I= + +when@~3.6.2: + version "3.6.4" + resolved "https://registry.yarnpkg.com/when/-/when-3.6.4.tgz#473b517ec159e2b85005497a13983f095412e34e" + integrity sha1-RztRfsFZ4rhQBUl6E5g/CVQS404= + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= + +which-pm-runs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" + integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= + +which@1, which@^1.1.1, which@^1.2.14, which@^1.2.9, which@~1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== + dependencies: + string-width "^2.1.1" + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + +wordwrapjs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-3.0.0.tgz#c94c372894cadc6feb1a66bff64e1d9af92c5d1e" + integrity sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw== + dependencies: + reduce-flatten "^1.0.1" + typical "^2.6.1" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^2.0.0: + version "2.4.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" + integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +ws@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + +ws@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51" + integrity sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w== + dependencies: + options ">=0.0.5" + ultron "1.0.x" + +ws@^3.2.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= + +xml2js@0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" + integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + +xmlcreate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-1.0.2.tgz#fa6bf762a60a413fb3dd8f4b03c5b269238d308f" + integrity sha1-+mv3YqYKQT+z3Y9LA8WyaSONMI8= + +xmlcreate@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-2.0.3.tgz#df9ecd518fd3890ab3548e1b811d040614993497" + integrity sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ== + +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +xtend@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a" + integrity sha1-XM50B7r2Qsunvs2laBEcST9ZZlo= + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + +yallist@^2.0.0, yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yallist@^3.0.0, yallist@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yargs-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" + integrity sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo= + dependencies: + camelcase "^3.0.0" + +yargs@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" + integrity sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg= + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.0" + +zip-stream@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-1.2.0.tgz#a8bc45f4c1b49699c6b90198baacaacdbcd4ba04" + integrity sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ= + dependencies: + archiver-utils "^1.3.0" + compress-commons "^1.2.0" + lodash "^4.8.0" + readable-stream "^2.0.0" + +zmq@^2.14.0: + version "2.15.3" + resolved "https://registry.yarnpkg.com/zmq/-/zmq-2.15.3.tgz#66c6de82cc36b09734b820703776490a6fbbe624" + integrity sha1-Zsbegsw2sJc0uCBwN3ZJCm+75iQ= + dependencies: + bindings "~1.2.1" + nan "~2.3.0" diff --git a/packages/dapplib/.babelrc b/packages/dapplib/.babelrc new file mode 100644 index 0000000..e05d60a --- /dev/null +++ b/packages/dapplib/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + "@babel/env" + ,"@babel/react" + ], + "plugins": [ + ["@babel/plugin-proposal-decorators", { "legacy": true }], + "@babel/plugin-proposal-class-properties", + "@babel/plugin-transform-runtime" + ] +} + diff --git a/packages/dapplib/.gitignore b/packages/dapplib/.gitignore new file mode 100644 index 0000000..c79f259 --- /dev/null +++ b/packages/dapplib/.gitignore @@ -0,0 +1,2 @@ +dist/ +build/ \ No newline at end of file diff --git a/packages/dapplib/contracts/Dapp.sol b/packages/dapplib/contracts/Dapp.sol new file mode 100644 index 0000000..140ce3b --- /dev/null +++ b/packages/dapplib/contracts/Dapp.sol @@ -0,0 +1,88 @@ +pragma solidity >=0.5.0; +pragma experimental ABIEncoderV2; + +import "./interfaces/IDappState.sol"; +import "./DappLib.sol"; + + /* + + VERY IMPORTANT SECURITY NOTE: + + You will want to restrict some of your state contract functions so only authorized + contracts can call them. This can be achieved in four steps: + + 1) Include the "Access Control: Contract Access" feature block when creating your project. + This adds all the functionality to manage white-listing of external contracts in your + state contract. + + 2) Add the "requireContractAuthorized" function modifiers to those state contract functions + that should be restricted. + + 3) Deploy the contract that will be calling into the state contract (like this one, for example). + + 4) Call the "authorizeContract()" function in the state contract with the deployed address of the + calling contract. This adds the calling contract to a white-list. Thereafter, any calls to any + function in the state contract that use the "requireContractAuthorized" function modifier will + succeed only if the calling contract (or any caller for that matter) is white-listed. + + */ + + +contract Dapp { + // Allow DappLib(SafeMath) functions to be called for all uint256 types + // (similar to "prototype" in Javascript) + using DappLib for uint256; + + IDappState state; + + // During deployment, the address of the contract that contains data (or "state") + // is provided as a constructor argument. The "state" variable can then call any + // function in the state contract that it is aware of (by way of IDappState). + constructor + ( + address dappStateContract + ) + public + { + state = IDappState(dappStateContract); + } + + /** + * @dev Example function to demonstrate cross-contract READ call + * + */ + function getStateContractOwner() + external + view + returns(address) + { + return state.getContractOwner(); + } + + /** + * @dev Example function to demonstrate cross-contract WRITE call + * + */ + function incrementStateCounter + ( + uint256 increment + ) + external + { + return state.incrementCounter(increment); + } + + + /** + * @dev Another example function to demonstrate cross-contract WRITE call + * + */ + function getStateCounter() + external + view + returns(uint256) + { + return state.getCounter(); + } + +} diff --git a/packages/dapplib/contracts/DappLib.sol b/packages/dapplib/contracts/DappLib.sol new file mode 100644 index 0000000..86ad27c --- /dev/null +++ b/packages/dapplib/contracts/DappLib.sol @@ -0,0 +1,88 @@ +pragma solidity >=0.5.0; +pragma experimental ABIEncoderV2; + +// Shared library for all contracts +library DappLib { + +///+library + +function getItemsByPage + ( + uint256 page, + uint256 resultsPerPage, + bytes32[] memory itemList + + ) + internal + pure + returns(bytes32[] memory) +{ + /* + Source: https://medium.codylamson.com/how-to-paginate-smart-contract-array-returns-cd6227479aa3 + ex: _page 1, _resultsPerPage 20 | 1 * 20 - 20 = 0 + ex2: _page 2, _resultsPerPage 20 | 2 * 20 - 20 = 20 + starting point for listing items in array + */ + + uint256 index = sub(mul(resultsPerPage,page),resultsPerPage); + + // Return emptry array if already empty or index is out of bounds + if ((itemList.length == 0) || (index > sub(itemList.length, 1))) { + return new bytes32[](0); + } + + // Create fixed length array because we cannot push to array in memory + bytes32[] memory itemPage = new bytes32[](resultsPerPage); + + + uint256 returnCounter = 0; + + for(index; index < (mul(resultsPerPage, page)); index++) { + if (index < (itemList.length)) { + itemPage[returnCounter] = itemList[index]; + } else { + itemPage[returnCounter] = bytes32(0); + } + + returnCounter++; + } + + return itemPage; +} + + + +// *** BEGIN SafeMath -- Copyright (c) 2016 Smart Contract Solutions, Inc. *** + +// It's important to avoid vulnerabilities due to numeric overflow bugs +// OpenZeppelin's SafeMath library, when used correctly, protects agains such bugs + + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + if (a == 0) { + return 0; + } + uint256 c = a * b; + assert(c / a == b); + return c; + } + + function div(uint256 a, uint256 b) internal pure returns (uint256) { + // assert(b > 0); // Solidity automatically throws when dividing by 0 + uint256 c = a / b; + // assert(a == b * c + a % b); // There is no case in which this doesn't hold + return c; + } + + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + assert(b <= a); + return a - b; + } + + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + assert(c >= a); + return c; + } + +} + diff --git a/packages/dapplib/contracts/DappState.sol b/packages/dapplib/contracts/DappState.sol new file mode 100644 index 0000000..ce5f90d --- /dev/null +++ b/packages/dapplib/contracts/DappState.sol @@ -0,0 +1,122 @@ +pragma solidity >=0.5.0; +pragma experimental ABIEncoderV2; + +import "./interfaces/IDappState.sol"; +import "./DappLib.sol"; +///+import + +/********************************************************************************************/ +/* This contract is auto-generated based on your choices in DappStarter. You can make */ +/* changes, but be aware that generating a new DappStarter project will require you to */ +/* merge changes. One approach you can take is to make changes in Dapp.sol and have it */ +/* call into this one. You can maintain all your data in this contract and your app logic */ +/* in Dapp.sol. This lets you update and deploy Dapp.sol with revised code and still */ +/* continue using this one. */ +/********************************************************************************************/ + +contract DappState is IDappState { + // Allow DappLib(SafeMath) functions to be called for all uint256 types + // (similar to "prototype" in Javascript) + using DappLib for uint256; +///+using + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ S T A T E @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + + // Account used to deploy contract + address private contractOwner; +///+state + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ C O N S T R U C T O R @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + + constructor() public + { + contractOwner = msg.sender; +///+initialize + } + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ E V E N T S @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + +///+events + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ M O D I F I E R S @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + +///+modifiers + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ F U N C T I O N S @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + +///+functions + +// Example functions that demonstrate how to call into this contract that holds state from +// another contract. Look in ~/interfaces/IDappState.sol for the interface definitions and +// in Dapp.sol for the actual calls into this contract. + + /** + * @dev This is an EXAMPLE function that illustrates how functions in this contract can be + * called securely from another contract to READ state data. Using the Contract Access + * block will enable you to make your contract more secure by restricting which external + * contracts can call functions in this contract. + */ + function getContractOwner() + external + view + returns(address) + { + return contractOwner; + } + + uint256 counter; // This is an example variable used only to demonstrate calling + // a function that writes state from an external contract. It and + // "incrementCounter" and "getCounter" functions can (should?) be deleted. + /** + * @dev This is an EXAMPLE function that illustrates how functions in this contract can be + * called securely from another contract to WRITE state data. Using the Contract Access + * block will enable you to make your contract more secure by restricting which external + * contracts can call functions in this contract. + */ + function incrementCounter + ( + uint256 increment + ) + external + // Enable the modifier below if using the Contract Access feature + // requireContractAuthorized + { + // NOTE: If another contract is calling this function, then msg.sender will be the address + // of the calling contract and NOT the address of the user who initiated the + // transaction. It is possible to get the address of the user, but this is + // spoofable and therefore not recommended. + + require(increment > 0 && increment < 10, "Invalid increment value"); + counter = counter.add(increment); // Demonstration of using SafeMath to add to a number + // While verbose, using SafeMath everywhere that you + // add/sub/div/mul will ensure your contract does not + // have weird overflow bugs. + } + + /** + * @dev This is an another EXAMPLE function that illustrates how functions in this contract can be + * called securely from another contract to READ state data. Using the Contract Access + * block will enable you to make your contract more secure by restricting which external + * contracts can call functions in this contract. + */ + function getCounter() + external + view + returns(uint256) + { + return counter; + } + +} + + diff --git a/packages/dapplib/contracts/Migrations.sol b/packages/dapplib/contracts/Migrations.sol new file mode 100644 index 0000000..8c7da12 --- /dev/null +++ b/packages/dapplib/contracts/Migrations.sol @@ -0,0 +1,24 @@ +pragma solidity >=0.5.0; +pragma experimental ABIEncoderV2; + +contract Migrations { + address public owner; + uint public last_completed_migration; + + modifier restricted() { + if (msg.sender == owner) _; + } + + constructor() public { + owner = msg.sender; + } + + function setCompleted(uint completed) public restricted { + last_completed_migration = completed; + } + + function upgrade(address new_address) public restricted { + Migrations upgraded = Migrations(new_address); + upgraded.setCompleted(last_completed_migration); + } +} diff --git a/packages/dapplib/contracts/interfaces/IDappState.sol b/packages/dapplib/contracts/interfaces/IDappState.sol new file mode 100644 index 0000000..6ee7a55 --- /dev/null +++ b/packages/dapplib/contracts/interfaces/IDappState.sol @@ -0,0 +1,17 @@ +pragma solidity >=0.5.0; +pragma experimental ABIEncoderV2; + +/********************************************************************************************/ +/* This contract is the interface for DappState.sol functions used in Dapp.sol */ +/* to enable DappState functions to be called from Dapp. You can restrict the functions */ +/* in DappState directly known to Dapp by limiting the definitions you include here. */ +/* It's OK to not use IDappState and Dapp, but if you do use them, it's highly recommended */ +/* that you use the DappStarter "Contract Access" feature block so you can limit which */ +/* contracts can call in to the DappState contract. */ +/********************************************************************************************/ + +interface IDappState { + function getContractOwner() external view returns(address); // Example READ function + function incrementCounter(uint256 increment) external; // Example WRITE function + function getCounter() external view returns(uint256); // Another example READ function +} \ No newline at end of file diff --git a/packages/dapplib/manifest.json b/packages/dapplib/manifest.json new file mode 100644 index 0000000..b891d3e --- /dev/null +++ b/packages/dapplib/manifest.json @@ -0,0 +1,9 @@ +{ + "name": "myTestDapp", + "blocks": { + "/blockchain/ethereum": true, + "/blockchain/ethereum/solidity": true, + "/framework/react": true, + "/category/file_storage": false + } +} \ No newline at end of file diff --git a/packages/dapplib/migrations/1_initial_migration.js b/packages/dapplib/migrations/1_initial_migration.js new file mode 100644 index 0000000..8153c0e --- /dev/null +++ b/packages/dapplib/migrations/1_initial_migration.js @@ -0,0 +1,5 @@ +var Migrations = artifacts.require("Migrations"); + +module.exports = function(deployer) { + deployer.deploy(Migrations); +}; diff --git a/packages/dapplib/migrations/2_deploy_contracts.js b/packages/dapplib/migrations/2_deploy_contracts.js new file mode 100644 index 0000000..ff7dbe5 --- /dev/null +++ b/packages/dapplib/migrations/2_deploy_contracts.js @@ -0,0 +1,45 @@ +const DappStateContract = artifacts.require("DappState"); +const DappContract = artifacts.require("Dapp"); +const fs = require('fs'); + +module.exports = function(deployer, network) { + + let httpUri = deployer.networks[network].uri; + let wsUri = ''; + if (httpUri) { + wsUri = httpUri.replace('http', 'ws'); + } + + let accounts = []; + let wallets = []; + for(let address in deployer.networks[network].provider().wallets) { + let wallet = deployer.networks[network].provider().wallets[address]; + accounts.push(wallet.getAddressString()); + wallets.push({ + account: wallet.getAddressString(), + publicKey: wallet.getPublicKeyString(), + privateKey: wallet.getPrivateKeyString() + }) + }; + + deployer + .deploy(DappStateContract) + .then(() => { + return deployer.deploy(DappContract, DappStateContract.address); + }) + .then(() => { + let config = { + httpUri: httpUri, + wsUri: wsUri, + dappStateContractAddress: DappStateContract.address, + dappContractAddress: DappContract.address, + accounts: accounts, + wallets: wallets +///+config + } + + // On each deployment, a configuration file is created so dapp and API can access the latest contract code + fs.writeFileSync(__dirname + '/../src/dapp-config.json',JSON.stringify(config, null, '\t'), 'utf-8'); + }); + +} \ No newline at end of file diff --git a/packages/dapplib/package.json b/packages/dapplib/package.json new file mode 100644 index 0000000..8f5719f --- /dev/null +++ b/packages/dapplib/package.json @@ -0,0 +1,52 @@ +{ + "name": "@trycrypto/dappstarter-dapplib", + "version": "0.1.0", + "description": "> TODO: description", + "author": "Jonathan Sheely <jsheely@thirtytech.net>", + "homepage": "https://github.com/trycrypto/dappstarter-lerna#readme", + "license": "ISC", + "main": "src/lib/dapp-lib.js", + "repository": { + "type": "git", + "url": "git+https://github.com/trycrypto/dappstarter-lerna.git" + }, + "scripts": { + "clean": "rimraf -rf build && rimraf -rf dist", + "dev": "run-p ganache deploy", + "deploy": "wait-on tcp:7545 && truffle compile && truffle migrate --reset", + "ganache": "node scripts/ganache.js", + "test": "npx truffle test" + }, + "bugs": { + "url": "https://github.com/trycrypto/dappstarter-lerna/issues" + }, + "dependencies": { + "bs58": "^4.0.1", + "clipboard": "^2.0.6", + "ipfs-http-client": "^42.0.0", + "web3": "^1.2.6", + "web3-providers": "^1.0.0-beta.55" + }, + "devDependencies": { + "@babel/core": "^7.9.0", + "@babel/plugin-proposal-class-properties": "^7.8.3", + "@babel/plugin-proposal-decorators": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.9.0", + "@babel/polyfill": "^7.8.7", + "@babel/preset-env": "^7.9.0", + "@babel/preset-react": "^7.9.4", + "@babel/register": "^7.9.0", + "@truffle/hdwallet-provider": "1.0.32", + "@types/ethereum-protocol": "^1.0.0", + "@types/web3": "^1.2.2", + "babel-loader": "^8.1.0", + "ganache-cli": "^6.9.1", + "npm-run-all": "^4.1.5", + "rimraf": "^3.0.2", + "truffle": "^5.1.19", + "wait-on": "^4.0.1", + "webpack": "^4.42.1", + "webpack-cli": "^3.3.11", + "web3": "1.2.6" + } +} \ No newline at end of file diff --git a/packages/dapplib/scripts/ganache.js b/packages/dapplib/scripts/ganache.js new file mode 100644 index 0000000..bb88f92 --- /dev/null +++ b/packages/dapplib/scripts/ganache.js @@ -0,0 +1,17 @@ +const truffleConfig = require("../truffle-config"); +const spawn = require("cross-spawn"); +const ganache = spawn("npx", [ + "ganache-cli", + "--mnemonic", + `"${truffleConfig.mnemonic}"`, + "-p", + "7545" +]); + +ganache.stdout.on("data", data => { + console.log(data.toString()); +}); + +ganache.stderr.on("data", data => { + console.log(data.toString()); +}); diff --git a/packages/dapplib/src/lib/blockchain.js b/packages/dapplib/src/lib/blockchain.js new file mode 100644 index 0000000..de054f2 --- /dev/null +++ b/packages/dapplib/src/lib/blockchain.js @@ -0,0 +1,71 @@ +const DappStateContract = require("../../build/contracts/DappState.json"); +const DappContract = require("../../build/contracts/Dapp.json"); +const Web3 = require("web3"); + +// Ethereum +module.exports = class Blockchain { + + static async _init(config) { + let web3Obj = { + http: new Web3(new Web3.providers.HttpProvider(config.httpUri)), + ws: new Web3(new Web3.providers.WebsocketProvider(config.wsUri)) + } + + let accounts = config.accounts || await web3Obj.http.eth.getAccounts(); + + return { + dappStateContract: new web3Obj.http.eth.Contract(DappStateContract.abi, config.dappStateContractAddress), + dappContract: new web3Obj.http.eth.Contract(DappContract.abi, config.dappContractAddress), + dappStateContractWs: new web3Obj.ws.eth.Contract(DappStateContract.abi, config.dappStateContractAddress), + dappContractWs: new web3Obj.ws.eth.Contract(DappContract.abi, config.dappContractAddress), + accounts: accounts, + lastBlock: await web3Obj.http.eth.getBlockNumber() + } + } + + /** + * @dev Calls a read-only smart contract function + */ + static async get(env, action, ...data) { + let blockchain = await Blockchain._init(env.config); + env.params.from = typeof env.params.from === 'string' ? env.params.from : blockchain.accounts[0]; + return { + callAccount: env.params.from, + callData: await blockchain[env.contract] + .methods[action](...data) + .call(env.params) + } + } + + /** + * @dev Calls a writeable smart contract function + */ + static async post(env, action, ...data) { + let blockchain = await Blockchain._init(env.config); + env.params.from = typeof env.params.from === 'string' ? env.params.from : blockchain.accounts[0]; + return { + callAccount: env.params.from, + callData: await blockchain[env.contract] + .methods[action](...data) + .send(env.params) + } + } + + static async handleEvent(env, event, callback) { + let blockchain = await Blockchain._init(env.config); + env.params.fromBlock = typeof env.params.fromBlock === 'number' ? env.params.fromBlock : blockchain.lastBlock + 1; + if (blockchain[env.contract].events[event]) { + blockchain[env.contract].events[event](env.params, (error, result) => { + let eventInfo = Object.assign({ + id: result.id, + blockNumber: result.blockNumber + }, result.returnValues); + + callback(error, eventInfo); + }); + } else { + throw(`Contract "${env.contract}" does not contain event "${event}"`); + } + } + +} \ No newline at end of file diff --git a/packages/dapplib/src/lib/components/widgets/svg-icons.js b/packages/dapplib/src/lib/components/widgets/svg-icons.js new file mode 100644 index 0000000..6948e02 --- /dev/null +++ b/packages/dapplib/src/lib/components/widgets/svg-icons.js @@ -0,0 +1,54 @@ +module.exports = class SvgIcons { + + static get readOnly() { + return ` +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" width="20px" height="20px" xml:space="preserve"> +<style type="text/css"> + .st0{fill:none;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;} +</style> +<circle class="st0" cx="5.5" cy="18.5" r="5"/> +<path class="st0" d="M10.5,7V3c-0.9-0.8-2.1-0.8-3,0L6,7L4.5,8.5l-3,7"/> +<circle class="st0" cx="18.5" cy="18.5" r="5"/> +<path class="st0" d="M13.5,7V3.1c0.9-0.8,2.1-0.8,3,0L18,7l1.5,1.5l3,7"/> +<path class="st0" d="M8,11c0-1.1,1.8-2,4-2s4,0.9,4,2"/> +<line class="st0" x1="10.5" y1="18.5" x2="10.5" y2="9.1"/> +<line class="st0" x1="13.5" y1="18.5" x2="13.5" y2="9.1"/> +</svg> +` + } + + static get readWrite() { + return ` +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" width="20px" height="20px" xml:space="preserve"> +<style type="text/css"> + .st10{fill:none;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;} +</style> +<polygon class="st0" points="7,21.5 0.5,23.5 2.5,17 15.3,4.2 19.8,8.7 "/> +<path class="st10" d="M15.3,4.2l3.1-3.1c0.8-0.8,2-0.8,2.8,0l1.7,1.7c0.8,0.8,0.8,2,0,2.8l-3.1,3.1"/> +<line class="st10" x1="17.6" y1="6.4" x2="6" y2="18"/> +<polyline class="st10" points="2.5,17 3.5,18 6,18 6,20.5 7,21.5 "/> +<line class="st10" x1="1.5" y1="20.5" x2="3.5" y2="22.5"/> +<line class="st10" x1="16.8" y1="2.7" x2="21.3" y2="7.2"/> +</svg> +` + } + + static get clippy() { + return ` +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 22.1 23.5" style="enable-background:new 0 0 22.1 23.5;cursor:pointer;" class="copy-target" width="19px" height="20.357px" xml:space="preserve"> +<style type="text/css"> + .st99{fill:#777777;stroke:none;stroke-linecap:round;stroke-linejoin:round;} +</style> +<path class="st99" d="M3.9,17.4h5.4v1.4H3.9V17.4z M10.7,9.2H3.9v1.4h6.8V9.2z M13.4,13.3v-2.7l-4.1,4.1l4.1,4.1V16h6.8v-2.7H13.4z + M7.3,12H3.9v1.4h3.4V12z M3.9,16h3.4v-1.4H3.9V16z M16.1,17.4h1.4v2.7c0,0.4-0.1,0.7-0.4,1c-0.3,0.3-0.6,0.4-1,0.4H2.6 + c-0.7,0-1.4-0.6-1.4-1.4V5.2c0-0.7,0.6-1.4,1.4-1.4h4.1c0-1.5,1.2-2.7,2.7-2.7s2.7,1.2,2.7,2.7h4.1c0.7,0,1.4,0.6,1.4,1.4V12h-1.4 + V7.9H2.6v12.2h13.6V17.4z M3.9,6.5h10.9c0-0.7-0.6-1.4-1.4-1.4h-1.4c-0.7,0-1.4-0.6-1.4-1.4s-0.6-1.4-1.4-1.4S8,3.1,8,3.8 + S7.4,5.2,6.6,5.2H5.3C4.5,5.2,3.9,5.8,3.9,6.5z"/> +</svg> +` + } +} + \ No newline at end of file diff --git a/packages/dapplib/src/lib/dapp-lib.js b/packages/dapplib/src/lib/dapp-lib.js new file mode 100644 index 0000000..4f4c888 --- /dev/null +++ b/packages/dapplib/src/lib/dapp-lib.js @@ -0,0 +1,450 @@ +'use strict'; +const Blockchain = require( './blockchain'); +const dappConfig = require( '../dapp-config.json'); +const ClipboardJS = require( 'clipboard'); +const SvgIcons = require( './components/widgets/svg-icons'); +const BN = require('bn.js'); // Required for injected code + +///+import + +module.exports = class DappLib { + +///+functions +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> EXAMPLES <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ + + // These example functions demonstrate cross-contract calling + + static async getStateContractOwner() { + + let result = await Blockchain.get({ + config: DappLib.getConfig(), + contract: DappLib.DAPP_CONTRACT, + params: { + } + }, + 'getStateContractOwner', + ); + let owner = result.callData; + return { + type: DappLib.DAPP_RESULT_ACCOUNT, + label: 'Contract Owner', + result: owner, + unitResult: null, + hint: null + } + } + + static async getStateCounter() { + + let result = await Blockchain.get({ + config: DappLib.getConfig(), + contract: DappLib.DAPP_CONTRACT, + params: { + } + }, + 'getStateCounter', + ); + return result; + } + + static async incrementStateCounter(data) { + + let result = await Blockchain.post({ + config: DappLib.getConfig(), + contract: DappLib.DAPP_CONTRACT, + params: { + } + }, + 'incrementStateCounter', + data.increment + ); + return { + type: DappLib.DAPP_RESULT_TX_HASH, + label: 'Transaction Hash', + result: DappLib.getTransactionHash(result.callData), + hint: '' + } + } + + + +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DAPP LIBRARY <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ + + static get DAPP_STATE_CONTRACT() { + return 'dappStateContract' + } + static get DAPP_CONTRACT() { + return 'dappContract' + } + + static get DAPP_STATE_CONTRACT_WS() { + return 'dappStateContractWs' + } + static get DAPP_CONTRACT_WS() { + return 'dappContractWs' + } + + static get DAPP_RESULT_BIG_NUMBER() { + return 'big-number' + } + + static get DAPP_RESULT_ACCOUNT() { + return 'account' + } + + static get DAPP_RESULT_TX_HASH() { + return 'tx-hash' + } + + static get DAPP_RESULT_IPFS_HASH_ARRAY() { + return 'ipfs-hash-array' + } + + static get DAPP_RESULT_SIA_HASH_ARRAY() { + return 'sia-hash-array' + } + + static get DAPP_RESULT_ARRAY() { + return 'array' + } + + static get DAPP_RESULT_OBJECT() { + return 'object' + } + + static get DAPP_RESULT_ERROR() { + return 'error' + } + + static async addEventHandler(contract, event, params, callback) { + Blockchain.handleEvent({ + config: DappLib.getConfig(), + contract: contract, + params: params || {} + }, + event, + (error, result) => { + if (error) { + callback({ + event: event, + type: DappLib.DAPP_RESULT_ERROR, + label: 'Error Message', + result: error + }); + } else { + callback({ + event: event, + type: DappLib.DAPP_RESULT_OBJECT, + label: 'Event ' + event, + result: DappLib.getObjectNamedProperties(result) + }); + } + } + ); + } + + static getTransactionHash(t) { + if (!t) { return ''; } + let value = ''; + if (typeof t === 'string') { + value = t; + } else if (typeof t === 'object') { + if (t.hasOwnProperty('transactionHash')) { + value = t.transactionHash; // Ethereum + } else if (t.hasOwnProperty('transaction')) { + if (t.transaction.id) { + value = t.transaction.id; // Harmony + } + } else { + value = JSON.stringify(t); + } + } + return value; + } + + static formatHint(hint) { + if (hint) { + return `<p class="mt-3 grey-text"><strong>Hint:</strong> ${hint}</p>`; + } else { + return ''; + } + } + + static formatNumber(n) { + var parts = n.toString().split("."); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); + return `<strong class="p-1 blue-grey-text number copy-target" style="font-size:1.1rem;" title="${n}">${parts.join(".")}</strong>`; + } + + static formatAccount(a) { + return `<strong class="green accent-1 p-1 blue-grey-text number copy-target" title="${a}">${DappLib.toCondensed(a, 6, 4)}</strong>${ DappLib.addClippy(a)}`; + } + + static formatTxHash(a) { + let value = DappLib.getTransactionHash(a); + return `<strong class="teal lighten-5 p-1 blue-grey-text number copy-target" title="${value}">${DappLib.toCondensed(value, 6, 4)}</strong>${ DappLib.addClippy(value)}`; + } + + static formatBoolean(a) { + return (a ? 'YES' : 'NO'); + } + + static formatText(a, copyText) { + if (!a) { return; } + if (a.startsWith('<')) { + return a; + } + return `<span title="${copyText ? copyText : a}">${a}</span>${DappLib.addClippy(copyText ? copyText : a)}`; + } + + static formatStrong(a) { + return `<strong>${a}</strong>`; + } + + static formatPlain(a) { + return a; + } + + static formatObject(a) { + let data = []; + let labels = [ 'Item', 'Value' ]; + let keys = [ 'item', 'value' ]; + let formatters = [ 'Strong', 'Text-20-5' ]; + let reg = new RegExp('^\\d+$'); // only digits + for(let key in a) { + if (!reg.test(key)) { + data.push({ + item: key.substr(0,1).toUpperCase() + key.substr(1), + value: a[key] + }); + } + } + return DappLib.formatArray(data, formatters, labels, keys); + } + + static formatArray(h, dataFormatters, dataLabels, dataKeys) { + + let output = '<table class="table table-striped">'; + + if (dataLabels) { + output += '<thead><tr>'; + for(let d=0; d<dataLabels.length; d++) { + output += `<th scope="col">${dataLabels[d]}</th>`; + } + output += '</tr></thead>'; + } + output += '<tbody>'; + h.map((item) => { + output += '<tr>'; + for(let d=0; d<dataFormatters.length; d++) { + let text = String(dataKeys && dataKeys[d] ? item[dataKeys[d]] : item); + let copyText = dataKeys && dataKeys[d] ? item[dataKeys[d]] : item; + if (text.startsWith('<')) { + output += (d == 0 ? '<th scope="row">' : '<td>') + text + (d == 0 ? '</th>' : '</td>'); + } else { + let formatter = 'format' + dataFormatters[d]; + if (formatter.startsWith('formatText')) { + let formatterFrags = formatter.split('-'); + if (formatterFrags.length === 3) { + text = DappLib.toCondensed(text, Number(formatterFrags[1]), Number(formatterFrags[2])); + } else if (formatterFrags.length === 2) { + text = DappLib.toCondensed(text, Number(formatterFrags[1])); + } + formatter = formatterFrags[0]; + } + output += (d == 0 ? '<th scope="row">' : '<td>') + DappLib[formatter](text, copyText) + (d == 0 ? '</th>' : '</td>'); + } + } + output += '</tr>'; + }) + output += '</tbody></table>'; + return output; + } + + static getFormattedResultNode(retVal, key) { + + let returnKey = 'result'; + if (key && (key !== null) && (key !== 'null') && (typeof(key) === 'string')) { + returnKey = key; + } + let formatted = ''; + switch (retVal.type) { + case DappLib.DAPP_RESULT_BIG_NUMBER: + formatted = DappLib.formatNumber(retVal[returnKey].toString(10)); + break; + case DappLib.DAPP_RESULT_TX_HASH: + formatted = DappLib.formatTxHash(retVal[returnKey]); + break; + case DappLib.DAPP_RESULT_ACCOUNT: + formatted = DappLib.formatAccount(retVal[returnKey]); + break; + case DappLib.DAPP_RESULT_BOOLEAN: + formatted = DappLib.formatBoolean(retVal[returnKey]); + break; + case DappLib.DAPP_RESULT_IPFS_HASH_ARRAY: + formatted = DappLib.formatArray( + retVal[returnKey], + ['TxHash', 'IpfsHash', 'Text-10-5'], + ['Transaction', 'IPFS URL', 'Doc Id'], + ['transactionHash', 'ipfsHash', 'docId'] + ); + break; + case DappLib.DAPP_RESULT_SIA_HASH_ARRAY: + formatted = DappLib.formatArray( + retVal[returnKey], + ['TxHash', 'SiaHash', 'Text-10-5'], + ['Transaction', 'Sia URL', 'Doc Id'], + ['transactionHash', 'docId', 'docId'] + ); + break; + case DappLib.DAPP_RESULT_ARRAY: + formatted = DappLib.formatArray( + retVal[returnKey], + retVal.formatter ? retVal.formatter : ['Text'], + null, + null + ); + break; + case DappLib.DAPP_RESULT_OBJECT: + formatted = DappLib.formatObject(retVal[returnKey]); + break; + default: + formatted = retVal[returnKey]; + break; + } + + let resultNode = document.createElement('div'); + resultNode.className = `note ${retVal.type === DappLib.DAPP_RESULT_ERROR ? 'bg-red-400' : 'bg-green-400'} m-3 p-3`; + let closeMarkup = '<div class="float-right" onclick="this.parentNode.parentNode.removeChild(this.parentNode)" title="Dismiss" class="text-right mb-1 mr-2" style="cursor:pointer;">X</div>'; + resultNode.innerHTML = closeMarkup + `${retVal.type === DappLib.DAPP_RESULT_ERROR ? '☹️' : '👍️'} ` + (Array.isArray(retVal[returnKey]) ? 'Result' : retVal.label) + ': ' + formatted + DappLib.formatHint(retVal.hint); + // Wire-up clipboard copy + new ClipboardJS('.copy-target', { + text: function (trigger) { + return trigger.getAttribute('data-copy'); + } + }); + + return resultNode; + } + + static getObjectNamedProperties(a) { + let reg = new RegExp('^\\d+$'); // only digits + let newObj = {}; + for(let key in a) { + if (!reg.test(key)) { + newObj[key] = a[key]; + } + } + return newObj; + } + + static addClippy(data) { + let icon = SvgIcons.clippy; + return icon.replace('<svg ', `<svg data-copy="${data}" `) + } + + static fromAscii(str, padding) { + + if (str.startsWith('0x') || !padding) { + return str; + } + + if (str.length > padding) { + str = str.substr(0, padding); + } + + var hex = '0x'; + for (var i = 0; i < str.length; i++) { + var code = str.charCodeAt(i); + var n = code.toString(16); + hex += n.length < 2 ? '0' + n : n; + } + return hex + '0'.repeat(padding*2 - hex.length + 2); + }; + + static toAscii(hex) { + var str = '', + i = 0, + l = hex.length; + if (hex.substring(0, 2) === '0x') { + i = 2; + } + for (; i < l; i+=2) { + var code = parseInt(hex.substr(i, 2), 16); + if (code === 0) continue; // this is added + str += String.fromCharCode(code); + } + return str; + }; + + static toCondensed(s, begin, end) { + if (!s) { return; } + if (s.length && s.length <= begin + end) { + return s; + } else { + if (end) { + return `${s.substr(0, begin)}...${s.substr(s.length-end, end)}`; + } else { + return `${s.substr(0, begin)}...`; + } + } + } + + // https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript + static getUniqueId() { + return 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.replace(/[x]/g, function(c) { + var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + } + + static getConfig() { + return dappConfig; + } + + // Return value of this function is used to dynamically re-define getConfig() + // for use during testing. With this approach, even though getConfig() is static + // it returns the correct contract addresses as its definition is re-written + // before each test run. Look for the following line in test scripts to see it done: + // DappLib.getConfig = Function(`return ${ JSON.stringify(DappLib.getTestConfig(testDappStateContract, testDappContract, testAccounts))}`); + static getTestConfig(testDappStateContract, testDappContract, testAccounts) { + + return Object.assign( + {}, + dappConfig, + { + dappStateContractAddress: testDappStateContract.address, + dappContractAddress: testDappContract.address, + accounts: testAccounts, + owner: testAccounts[0], + admins: [ + testAccounts[1], + testAccounts[2], + testAccounts[3] + ], + users: [ + testAccounts[4], + testAccounts[5], + testAccounts[6], + testAccounts[7], + testAccounts[8] + ], + testAddresses: [ + // These test addresses are useful when you need to add random accounts in test scripts + "0xb1ac66b49fdc369879123332f2cdd98caad5f75a", + "0x0d27a7c9850f71d7ef71ffbe0155122e83d9455d", + "0x88477a8dc34d60c40b160e9e3b1721341b63c453", + "0x2880e2c501a70f7db1691a0e2722cf6a8a9c9009", + "0x0226df61d33e41b90be3b5fd830bae303fcb66f5", + "0x60a4dff3d25f4e5a5480fb91d550b0efc0e9dbb3", + "0xa2f52a2060841cc4eb4892c0234d2c6b6dcf1ea9", + "0x71b9b9bd7b6f72d7c0841f38fa7cdb840282267d", + "0x7f54a3318b2a728738cce36fc7bb1b927281c24e", + "0x81b7E08F65Bdf5648606c89998A9CC8164397647" + ] +///+test + } + ); + } + +} \ No newline at end of file diff --git a/packages/dapplib/test/[block-tests].js b/packages/dapplib/test/[block-tests].js new file mode 100644 index 0000000..e3f982a --- /dev/null +++ b/packages/dapplib/test/[block-tests].js @@ -0,0 +1,30 @@ +const BN = require('bn.js'); +const DappLib = require('../src/lib/dapp-lib.js').default; +const DappContract = artifacts.require('Dapp'); +const DappStateContract = artifacts.require('DappState'); + +contract('Dapp Contract Tests', async (testAccounts) => { + + let config = null; + + before('setup contract', async () => { + + let testDappStateContract = await DappStateContract.new(); + let testDappContract = await DappContract.new(testDappStateContract.address); + + // Swap the definition of the DappLib.getConfig() function so it returns + // dynamic contract addresses from the deployment above instead of the static + // addresses from the last migration script run. Also, inject test accounts + // for contracts and IPFS. The testAccounts variable is initialized by Truffle + // so we get whatever accounts are provided via the provider in truffle config. + DappLib.getConfig = Function(`return ${ JSON.stringify(DappLib.getTestConfig(testDappStateContract, testDappContract, testAccounts))}`); + + // Call the re-written function to get the test config values + config = DappLib.getConfig(); + config.testDappStateContract = testDappStateContract; + config.testDappContract = testDappContract; + }); + +///+test + +}); \ No newline at end of file diff --git a/packages/dapplib/test/dapp-tests.js b/packages/dapplib/test/dapp-tests.js new file mode 100644 index 0000000..e251e3f --- /dev/null +++ b/packages/dapplib/test/dapp-tests.js @@ -0,0 +1,30 @@ +const BN = require('bn.js'); +const DappLib = require('../src/lib/dapp-lib.js'); +const DappContract = artifacts.require('Dapp'); +const DappStateContract = artifacts.require('DappState'); + +contract('Dapp Cross-contract Tests', async (accounts) => { + + let testDappStateContract; + let testDappContract; + let testAccounts; + let config = null + + before('setup contract', async () => { + testDappStateContract = await DappStateContract.new(); + testDappContract = await DappContract.new(dappStateContract.address); + testAccounts = accounts; + DappLib.getConfig = Function(`return ${ JSON.stringify(DappLib.getTestConfig(testDappStateContract, testDappContract, testAccounts))}`); + + // Call the re-written function to get the test config values + config = DappLib.getConfig(); + config.testDappStateContract = testDappStateContract; + config.testDappContract = testDappContract; + }); + + it(`has correct result from sample cross-contract call`, async function () { + let stateContractOwner = await config.testDappContract.getStateContractOwner.call(); + assert.equal(stateContractOwner, config.owner, "Incorrect cross-contract result"); + }); + +}); \ No newline at end of file diff --git a/packages/dapplib/truffle-config.js b/packages/dapplib/truffle-config.js new file mode 100644 index 0000000..b3d8a66 --- /dev/null +++ b/packages/dapplib/truffle-config.js @@ -0,0 +1,46 @@ +require('@babel/register'); +({ + ignore: /node_modules/ +}); +require('@babel/polyfill'); + +const HDWalletProvider = require('@truffle/hdwallet-provider'); + +let mnemonic = 'grid arena fog sugar noodle ribbon remain evil install seek fresh smile'; +let testAccounts = [ +"0xc82cdb3a1ea0e2ad9a498c19aad83e00107afbf37e3db1c57ef41b053b9adeaf", +"0xdc6280fccffa0bc114a1264a6103b05ae53169502ce8df10b44ec050a5f216b5", +"0x2a459ee5353a62e442b979f09b4a5b08746bfe6d55185e6303bf1d9a32d3c62b", +"0x81a4e706c53111185fc426d02c9b33fb366a10dd7a1948333a6c5880d6e9084c", +"0xcd5dd8111a822984564c644ece1b2d4a4af65de686f91122a741e05cc6f9fd2b", +"0x2294e1aaf56a840f7389b47b4b4e2de6ffe8d570bcf224e76cb2867ada723d57", +"0x3634007e964a47c7ac9fba14d6820e36b2b96b63bb0f8feacc0b728bba747e6c", +"0x2efaf5b41bb2545de2f1d14f9475d8af7f8b6212c6957a31d3d42e6664e07cd7", +"0x092967230b49536431c1cf0b497b57a2dd387b2623a57c25779844c2ffeeb78a", +"0x7a4608522867e9af2db2fd6e9fa013ce5461f46e4456b82c39691afc8518f546" +]; +let devUri = 'http://127.0.0.1:7545/'; + +module.exports = { + testAccounts, + mnemonic, + networks: { + development: { + uri: devUri, + provider: () => new HDWalletProvider( + mnemonic, + devUri, // provider url + 0, // address index + 10, // number of addresses + true, // share nonce + `m/44'/60'/0'/0/` // wallet HD path + ), + network_id: '*' + } + }, + compilers: { + solc: { + version: '^0.5.11' + } + } +}; diff --git a/packages/frame/.eslintrc b/packages/frame/.eslintrc new file mode 100644 index 0000000..3de858e --- /dev/null +++ b/packages/frame/.eslintrc @@ -0,0 +1,20 @@ +{ + "extends": ["react-app"], + "plugins": ["react-hooks", "simple-import-sort"], + "rules": { + "react-hooks/rules-of-hooks": "error", + "no-multiple-empty-lines": "error", + "comma-dangle": ["error", "always-multiline"], + "eol-last": ["error", "always"], + "semi": ["error", "never"], + "quotes": ["error", "single"], + "no-tabs": "error", + "no-unused-vars": 0, + "jsx-a11y/anchor-is-valid": 0, + "@typescript-eslint/no-unused-vars": 0, + "padding-line-between-statements": [ + "error", + { "blankLine": "always", "prev": "*", "next": "return" } + ] + } +} diff --git a/packages/frame/.gitignore b/packages/frame/.gitignore new file mode 100644 index 0000000..361578c --- /dev/null +++ b/packages/frame/.gitignore @@ -0,0 +1,24 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.vscode/ \ No newline at end of file diff --git a/packages/frame/.prettierrc b/packages/frame/.prettierrc new file mode 100644 index 0000000..05c968c --- /dev/null +++ b/packages/frame/.prettierrc @@ -0,0 +1,5 @@ +{ + "semi": false, + "trailingComma": "all", + "singleQuote": true +} diff --git a/packages/frame/README.md b/packages/frame/README.md new file mode 100644 index 0000000..5b91765 --- /dev/null +++ b/packages/frame/README.md @@ -0,0 +1,52 @@ +![cra-template-unicorn_logo](./assets/logo.png) + +# cra-template-unicorn + +![GitHub Action Status](https://github.com/JaeYeopHan/cra-template-unicorn/workflows/Deploy/badge.svg) [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release) [![yarn version](https://badge.fury.io/js/cra-template-unicorn.svg)](https://badge.fury.io/js/cra-template-unicorn) + +The template for [Create React App](https://github.com/facebook/create-react-app). + +## Start Template + +### npx + +```sh +npx create-react-app my-app --template unicorn +``` + +### npm + +```sh +yarn init react-app my-app --template unicorn +``` + +### yarn + +```sh +yarn create react-app my-app --template unicorn +``` + +## In this template + +- [craco](https://github.com/gsoft-inc/craco) +- [redux-toolkit](https://github.com/reduxjs/redux-toolkit) +- [react-redux](https://github.com/reduxjs/react-redux) +- [react-router](https://github.com/ReactTraining/react-router) + +## Support + +- Support VSCode Integration +- Support reset.css +- Support absolute path +- Customize config with craco +- Customize eslint config > [link](https://create-react-app.dev/docs/advanced-configuration) + +## Show your support + +Give a ⭐️ if this project helped you! + +<div align="center"> + +<sub><sup>Written by <a href="https://github.com/JaeYeopHan">@Jbee</a></sup></sub><small>✌</small> + +</div> diff --git a/packages/frame/config/env.js b/packages/frame/config/env.js new file mode 100644 index 0000000..09ec03c --- /dev/null +++ b/packages/frame/config/env.js @@ -0,0 +1,101 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const paths = require('./paths'); + +// Make sure that including paths.js after env.js will read .env variables. +delete require.cache[require.resolve('./paths')]; + +const NODE_ENV = process.env.NODE_ENV; +if (!NODE_ENV) { + throw new Error( + 'The NODE_ENV environment variable is required but was not specified.' + ); +} + +// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use +const dotenvFiles = [ + `${paths.dotenv}.${NODE_ENV}.local`, + `${paths.dotenv}.${NODE_ENV}`, + // Don't include `.env.local` for `test` environment + // since normally you expect tests to produce the same + // results for everyone + NODE_ENV !== 'test' && `${paths.dotenv}.local`, + paths.dotenv, +].filter(Boolean); + +// Load environment variables from .env* files. Suppress warnings using silent +// if this file is missing. dotenv will never modify any environment variables +// that have already been set. Variable expansion is supported in .env files. +// https://github.com/motdotla/dotenv +// https://github.com/motdotla/dotenv-expand +dotenvFiles.forEach(dotenvFile => { + if (fs.existsSync(dotenvFile)) { + require('dotenv-expand')( + require('dotenv').config({ + path: dotenvFile, + }) + ); + } +}); + +// We support resolving modules according to `NODE_PATH`. +// This lets you use absolute paths in imports inside large monorepos: +// https://github.com/facebook/create-react-app/issues/253. +// It works similar to `NODE_PATH` in Node itself: +// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders +// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored. +// Otherwise, we risk importing Node.js core modules into an app instead of webpack shims. +// https://github.com/facebook/create-react-app/issues/1023#issuecomment-265344421 +// We also resolve them to make sure all tools using them work consistently. +const appDirectory = fs.realpathSync(process.cwd()); +process.env.NODE_PATH = (process.env.NODE_PATH || '') + .split(path.delimiter) + .filter(folder => folder && !path.isAbsolute(folder)) + .map(folder => path.resolve(appDirectory, folder)) + .join(path.delimiter); + +// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be +// injected into the application via DefinePlugin in webpack configuration. +const REACT_APP = /^REACT_APP_/i; + +function getClientEnvironment(publicUrl) { + const raw = Object.keys(process.env) + .filter(key => REACT_APP.test(key)) + .reduce( + (env, key) => { + env[key] = process.env[key]; + return env; + }, + { + // Useful for determining whether we’re running in production mode. + // Most importantly, it switches React into the correct mode. + NODE_ENV: process.env.NODE_ENV || 'development', + // Useful for resolving the correct path to static assets in `public`. + // For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />. + // This should only be used as an escape hatch. Normally you would put + // images into the `src` and `import` them in code to get their paths. + PUBLIC_URL: publicUrl, + // We support configuring the sockjs pathname during development. + // These settings let a developer run multiple simultaneous projects. + // They are used as the connection `hostname`, `pathname` and `port` + // in webpackHotDevClient. They are used as the `sockHost`, `sockPath` + // and `sockPort` options in webpack-dev-server. + WDS_SOCKET_HOST: process.env.WDS_SOCKET_HOST, + WDS_SOCKET_PATH: process.env.WDS_SOCKET_PATH, + WDS_SOCKET_PORT: process.env.WDS_SOCKET_PORT, + } + ); + // Stringify all values so we can feed into webpack DefinePlugin + const stringified = { + 'process.env': Object.keys(raw).reduce((env, key) => { + env[key] = JSON.stringify(raw[key]); + return env; + }, {}), + }; + + return { raw, stringified }; +} + +module.exports = getClientEnvironment; diff --git a/packages/frame/config/getHttpsConfig.js b/packages/frame/config/getHttpsConfig.js new file mode 100644 index 0000000..013d493 --- /dev/null +++ b/packages/frame/config/getHttpsConfig.js @@ -0,0 +1,66 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const crypto = require('crypto'); +const chalk = require('react-dev-utils/chalk'); +const paths = require('./paths'); + +// Ensure the certificate and key provided are valid and if not +// throw an easy to debug error +function validateKeyAndCerts({ cert, key, keyFile, crtFile }) { + let encrypted; + try { + // publicEncrypt will throw an error with an invalid cert + encrypted = crypto.publicEncrypt(cert, Buffer.from('test')); + } catch (err) { + throw new Error( + `The certificate "${chalk.yellow(crtFile)}" is invalid.\n${err.message}` + ); + } + + try { + // privateDecrypt will throw an error with an invalid key + crypto.privateDecrypt(key, encrypted); + } catch (err) { + throw new Error( + `The certificate key "${chalk.yellow(keyFile)}" is invalid.\n${ + err.message + }` + ); + } +} + +// Read file and throw an error if it doesn't exist +function readEnvFile(file, type) { + if (!fs.existsSync(file)) { + throw new Error( + `You specified ${chalk.cyan( + type + )} in your env, but the file "${chalk.yellow(file)}" can't be found.` + ); + } + return fs.readFileSync(file); +} + +// Get the https config +// Return cert files if provided in env, otherwise just true or false +function getHttpsConfig() { + const { SSL_CRT_FILE, SSL_KEY_FILE, HTTPS } = process.env; + const isHttps = HTTPS === 'true'; + + if (isHttps && SSL_CRT_FILE && SSL_KEY_FILE) { + const crtFile = path.resolve(paths.appPath, SSL_CRT_FILE); + const keyFile = path.resolve(paths.appPath, SSL_KEY_FILE); + const config = { + cert: readEnvFile(crtFile, 'SSL_CRT_FILE'), + key: readEnvFile(keyFile, 'SSL_KEY_FILE'), + }; + + validateKeyAndCerts({ ...config, keyFile, crtFile }); + return config; + } + return isHttps; +} + +module.exports = getHttpsConfig; diff --git a/packages/frame/config/jest/cssTransform.js b/packages/frame/config/jest/cssTransform.js new file mode 100644 index 0000000..8f65114 --- /dev/null +++ b/packages/frame/config/jest/cssTransform.js @@ -0,0 +1,14 @@ +'use strict'; + +// This is a custom Jest transformer turning style imports into empty objects. +// http://facebook.github.io/jest/docs/en/webpack.html + +module.exports = { + process() { + return 'module.exports = {};'; + }, + getCacheKey() { + // The output is always the same. + return 'cssTransform'; + }, +}; diff --git a/packages/frame/config/jest/fileTransform.js b/packages/frame/config/jest/fileTransform.js new file mode 100644 index 0000000..aab6761 --- /dev/null +++ b/packages/frame/config/jest/fileTransform.js @@ -0,0 +1,40 @@ +'use strict'; + +const path = require('path'); +const camelcase = require('camelcase'); + +// This is a custom Jest transformer turning file imports into filenames. +// http://facebook.github.io/jest/docs/en/webpack.html + +module.exports = { + process(src, filename) { + const assetFilename = JSON.stringify(path.basename(filename)); + + if (filename.match(/\.svg$/)) { + // Based on how SVGR generates a component name: + // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6 + const pascalCaseFilename = camelcase(path.parse(filename).name, { + pascalCase: true, + }); + const componentName = `Svg${pascalCaseFilename}`; + return `const React = require('react'); + module.exports = { + __esModule: true, + default: ${assetFilename}, + ReactComponent: React.forwardRef(function ${componentName}(props, ref) { + return { + $$typeof: Symbol.for('react.element'), + type: 'svg', + ref: ref, + key: null, + props: Object.assign({}, props, { + children: ${assetFilename} + }) + }; + }), + };`; + } + + return `module.exports = ${assetFilename};`; + }, +}; diff --git a/packages/frame/config/modules.js b/packages/frame/config/modules.js new file mode 100644 index 0000000..c8efd0d --- /dev/null +++ b/packages/frame/config/modules.js @@ -0,0 +1,141 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const paths = require('./paths'); +const chalk = require('react-dev-utils/chalk'); +const resolve = require('resolve'); + +/** + * Get additional module paths based on the baseUrl of a compilerOptions object. + * + * @param {Object} options + */ +function getAdditionalModulePaths(options = {}) { + const baseUrl = options.baseUrl; + + // We need to explicitly check for null and undefined (and not a falsy value) because + // TypeScript treats an empty string as `.`. + if (baseUrl == null) { + // If there's no baseUrl set we respect NODE_PATH + // Note that NODE_PATH is deprecated and will be removed + // in the next major release of create-react-app. + + const nodePath = process.env.NODE_PATH || ''; + return nodePath.split(path.delimiter).filter(Boolean); + } + + const baseUrlResolved = path.resolve(paths.appPath, baseUrl); + + // We don't need to do anything if `baseUrl` is set to `node_modules`. This is + // the default behavior. + if (path.relative(paths.appNodeModules, baseUrlResolved) === '') { + return null; + } + + // Allow the user set the `baseUrl` to `appSrc`. + if (path.relative(paths.appSrc, baseUrlResolved) === '') { + return [paths.appSrc]; + } + + // If the path is equal to the root directory we ignore it here. + // We don't want to allow importing from the root directly as source files are + // not transpiled outside of `src`. We do allow importing them with the + // absolute path (e.g. `src/Components/Button.js`) but we set that up with + // an alias. + if (path.relative(paths.appPath, baseUrlResolved) === '') { + return null; + } + + // Otherwise, throw an error. + throw new Error( + chalk.red.bold( + "Your project's `baseUrl` can only be set to `src` or `node_modules`." + + ' Create React App does not support other values at this time.' + ) + ); +} + +/** + * Get webpack aliases based on the baseUrl of a compilerOptions object. + * + * @param {*} options + */ +function getWebpackAliases(options = {}) { + const baseUrl = options.baseUrl; + + if (!baseUrl) { + return {}; + } + + const baseUrlResolved = path.resolve(paths.appPath, baseUrl); + + if (path.relative(paths.appPath, baseUrlResolved) === '') { + return { + src: paths.appSrc, + }; + } +} + +/** + * Get jest aliases based on the baseUrl of a compilerOptions object. + * + * @param {*} options + */ +function getJestAliases(options = {}) { + const baseUrl = options.baseUrl; + + if (!baseUrl) { + return {}; + } + + const baseUrlResolved = path.resolve(paths.appPath, baseUrl); + + if (path.relative(paths.appPath, baseUrlResolved) === '') { + return { + '^src/(.*)$': '<rootDir>/src/$1', + }; + } +} + +function getModules() { + // Check if TypeScript is setup + const hasTsConfig = fs.existsSync(paths.appTsConfig); + const hasJsConfig = fs.existsSync(paths.appJsConfig); + + if (hasTsConfig && hasJsConfig) { + throw new Error( + 'You have both a tsconfig.json and a jsconfig.json. If you are using TypeScript please remove your jsconfig.json file.' + ); + } + + let config; + + // If there's a tsconfig.json we assume it's a + // TypeScript project and set up the config + // based on tsconfig.json + if (hasTsConfig) { + const ts = require(resolve.sync('typescript', { + basedir: paths.appNodeModules, + })); + config = ts.readConfigFile(paths.appTsConfig, ts.sys.readFile).config; + // Otherwise we'll check if there is jsconfig.json + // for non TS projects. + } else if (hasJsConfig) { + config = require(paths.appJsConfig); + } + + config = config || {}; + const options = config.compilerOptions || {}; + + const additionalModulePaths = getAdditionalModulePaths(options); + + return { + additionalModulePaths: additionalModulePaths, + webpackAliases: getWebpackAliases(options), + jestAliases: getJestAliases(options), + hasTsConfig, + }; +} + +module.exports = getModules(); diff --git a/packages/frame/config/paths.js b/packages/frame/config/paths.js new file mode 100644 index 0000000..b3fd764 --- /dev/null +++ b/packages/frame/config/paths.js @@ -0,0 +1,72 @@ +'use strict'; + +const path = require('path'); +const fs = require('fs'); +const getPublicUrlOrPath = require('react-dev-utils/getPublicUrlOrPath'); + +// Make sure any symlinks in the project folder are resolved: +// https://github.com/facebook/create-react-app/issues/637 +const appDirectory = fs.realpathSync(process.cwd()); +const resolveApp = relativePath => path.resolve(appDirectory, relativePath); + +// We use `PUBLIC_URL` environment variable or "homepage" field to infer +// "public path" at which the app is served. +// webpack needs to know it to put the right <script> hrefs into HTML even in +// single-page apps that may serve index.html for nested URLs like /todos/42. +// We can't use a relative path in HTML because we don't want to load something +// like /todos/42/static/js/bundle.7289d.js. We have to know the root. +const publicUrlOrPath = getPublicUrlOrPath( + process.env.NODE_ENV === 'development', + require(resolveApp('package.json')).homepage, + process.env.PUBLIC_URL +); + +const moduleFileExtensions = [ + 'web.mjs', + 'mjs', + 'web.js', + 'js', + 'web.ts', + 'ts', + 'web.tsx', + 'tsx', + 'json', + 'web.jsx', + 'jsx', +]; + +// Resolve file paths in the same order as webpack +const resolveModule = (resolveFn, filePath) => { + const extension = moduleFileExtensions.find(extension => + fs.existsSync(resolveFn(`${filePath}.${extension}`)) + ); + + if (extension) { + return resolveFn(`${filePath}.${extension}`); + } + + return resolveFn(`${filePath}.js`); +}; + +// config after eject: we're in ./config/ +module.exports = { + dotenv: resolveApp('.env'), + appPath: resolveApp('.'), + appBuild: resolveApp('build'), + appPublic: resolveApp('public'), + appHtml: resolveApp('public/index.html'), + appIndexJs: resolveModule(resolveApp, 'src/index'), + appPackageJson: resolveApp('package.json'), + appSrc: resolveApp('src'), + appTsConfig: resolveApp('tsconfig.json'), + appJsConfig: resolveApp('jsconfig.json'), + yarnLockFile: resolveApp('yarn.lock'), + testsSetup: resolveModule(resolveApp, 'src/setupTests'), + proxySetup: resolveApp('src/setupProxy.js'), + appNodeModules: resolveApp('node_modules'), + publicUrlOrPath, +}; + + + +module.exports.moduleFileExtensions = moduleFileExtensions; diff --git a/packages/frame/config/pnpTs.js b/packages/frame/config/pnpTs.js new file mode 100644 index 0000000..d1b0539 --- /dev/null +++ b/packages/frame/config/pnpTs.js @@ -0,0 +1,35 @@ +'use strict'; + +const { resolveModuleName } = require('ts-pnp'); + +exports.resolveModuleName = ( + typescript, + moduleName, + containingFile, + compilerOptions, + resolutionHost +) => { + return resolveModuleName( + moduleName, + containingFile, + compilerOptions, + resolutionHost, + typescript.resolveModuleName + ); +}; + +exports.resolveTypeReferenceDirective = ( + typescript, + moduleName, + containingFile, + compilerOptions, + resolutionHost +) => { + return resolveModuleName( + moduleName, + containingFile, + compilerOptions, + resolutionHost, + typescript.resolveTypeReferenceDirective + ); +}; diff --git a/packages/frame/config/webpack.config.js b/packages/frame/config/webpack.config.js new file mode 100644 index 0000000..d45325f --- /dev/null +++ b/packages/frame/config/webpack.config.js @@ -0,0 +1,669 @@ +'use strict' + +const fs = require('fs') +const path = require('path') +const webpack = require('webpack') +const resolve = require('resolve') +const PnpWebpackPlugin = require('pnp-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin') +const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin') +const TerserPlugin = require('terser-webpack-plugin') +const MiniCssExtractPlugin = require('mini-css-extract-plugin') +const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin') +const safePostCssParser = require('postcss-safe-parser') +const ManifestPlugin = require('webpack-manifest-plugin') +const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin') +const WorkboxWebpackPlugin = require('workbox-webpack-plugin') +const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin') +const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin') +const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent') +const paths = require('./paths') +const modules = require('./modules') +const getClientEnvironment = require('./env') +const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin') +const ForkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin') +const typescriptFormatter = require('react-dev-utils/typescriptFormatter') + +const postcssNormalize = require('postcss-normalize') + +const appPackageJson = require(paths.appPackageJson) + +// Source maps are resource heavy and can cause out of memory issue for large source files. +const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false' +// Some apps do not need the benefits of saving a web request, so not inlining the chunk +// makes for a smoother build process. +const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false' + +const imageInlineSizeLimit = parseInt( + process.env.IMAGE_INLINE_SIZE_LIMIT || '10000', +) + +// Check if TypeScript is setup +const useTypeScript = fs.existsSync(paths.appTsConfig) + +// style files regexes +const cssRegex = /\.css$/ +const cssModuleRegex = /\.module\.css$/ +const sassRegex = /\.(scss|sass)$/ +const sassModuleRegex = /\.module\.(scss|sass)$/ + +// This is the production and development configuration. +// It is focused on developer experience, fast rebuilds, and a minimal bundle. +module.exports = function(webpackEnv) { + const isEnvDevelopment = webpackEnv === 'development' + const isEnvProduction = webpackEnv === 'production' + + // Variable used for enabling profiling in Production + // passed into alias object. Uses a flag if passed into the build command + const isEnvProductionProfile = + isEnvProduction && process.argv.includes('--profile') + + // We will provide `paths.publicUrlOrPath` to our app + // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript. + // Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz. + // Get environment variables to inject into our app. + const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1)) + + // common function to get style loaders + const getStyleLoaders = (cssOptions, preProcessor) => { + const loaders = [ + isEnvDevelopment && require.resolve('style-loader'), + isEnvProduction && { + loader: MiniCssExtractPlugin.loader, + // css is located in `static/css`, use '../../' to locate index.html folder + // in production `paths.publicUrlOrPath` can be a relative path + options: paths.publicUrlOrPath.startsWith('.') + ? { publicPath: '../../' } + : {}, + }, + { + loader: require.resolve('css-loader'), + options: cssOptions, + }, + { + // Options for PostCSS as we reference these options twice + // Adds vendor prefixing based on your specified browser support in + // package.json + loader: require.resolve('postcss-loader'), + options: { + // Necessary for external CSS imports to work + // https://github.com/facebook/create-react-app/issues/2677 + ident: 'postcss', + plugins: () => [ + require('postcss-flexbugs-fixes'), + require('postcss-preset-env')({ + autoprefixer: { + flexbox: 'no-2009', + }, + stage: 3, + }), + // Adds PostCSS Normalize as the reset css with default options, + // so that it honors browserslist config in package.json + // which in turn let's users customize the target behavior as per their needs. + postcssNormalize(), + ], + sourceMap: isEnvProduction && shouldUseSourceMap, + }, + }, + ].filter(Boolean) + if (preProcessor) { + loaders.push( + { + loader: require.resolve('resolve-url-loader'), + options: { + sourceMap: isEnvProduction && shouldUseSourceMap, + }, + }, + { + loader: require.resolve(preProcessor), + options: { + sourceMap: true, + }, + }, + ) + } + return loaders + } + + return { + mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development', + // Stop compilation early in production + bail: isEnvProduction, + devtool: isEnvProduction + ? shouldUseSourceMap + ? 'source-map' + : false + : isEnvDevelopment && 'cheap-module-source-map', + // These are the "entry points" to our application. + // This means they will be the "root" imports that are included in JS bundle. + entry: [ + // Include an alternative client for WebpackDevServer. A client's job is to + // connect to WebpackDevServer by a socket and get notified about changes. + // When you save a file, the client will either apply hot updates (in case + // of CSS changes), or refresh the page (in case of JS changes). When you + // make a syntax error, this client will display a syntax error overlay. + // Note: instead of the default WebpackDevServer client, we use a custom one + // to bring better experience for Create React App users. You can replace + // the line below with these two lines if you prefer the stock client: + // require.resolve('webpack-dev-server/client') + '?/', + // require.resolve('webpack/hot/dev-server'), + isEnvDevelopment && + require.resolve('react-dev-utils/webpackHotDevClient'), + // Finally, this is your app's code: + paths.appIndexJs, + // We include the app code last so that if there is a runtime error during + // initialization, it doesn't blow up the WebpackDevServer client, and + // changing JS code would still trigger a refresh. + ].filter(Boolean), + output: { + // The build folder. + path: isEnvProduction ? paths.appBuild : undefined, + // Add /* filename */ comments to generated require()s in the output. + pathinfo: isEnvDevelopment, + // There will be one main bundle, and one file per asynchronous chunk. + // In development, it does not produce real files. + filename: isEnvProduction + ? 'static/js/[name].[contenthash:8].js' + : isEnvDevelopment && 'static/js/bundle.js', + // TODO: remove this when upgrading to webpack 5 + futureEmitAssets: true, + // There are also additional JS chunk files if you use code splitting. + chunkFilename: isEnvProduction + ? 'static/js/[name].[contenthash:8].chunk.js' + : isEnvDevelopment && 'static/js/[name].chunk.js', + // webpack uses `publicPath` to determine where the app is being served from. + // It requires a trailing slash, or the file assets will get an incorrect path. + // We inferred the "public path" (such as / or /my-project) from homepage. + publicPath: paths.publicUrlOrPath, + // Point sourcemap entries to original disk location (format as URL on Windows) + devtoolModuleFilenameTemplate: isEnvProduction + ? info => + path + .relative(paths.appSrc, info.absoluteResourcePath) + .replace(/\\/g, '/') + : isEnvDevelopment && + (info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')), + // Prevents conflicts when multiple webpack runtimes (from different apps) + // are used on the same page. + jsonpFunction: `webpackJsonp${appPackageJson.name}`, + // this defaults to 'window', but by setting it to 'this' then + // module chunks which are built will work in web workers as well. + globalObject: 'this', + }, + optimization: { + minimize: isEnvProduction, + minimizer: [ + // This is only used in production mode + new TerserPlugin({ + terserOptions: { + parse: { + // We want terser to parse ecma 8 code. However, we don't want it + // to apply any minification steps that turns valid ecma 5 code + // into invalid ecma 5 code. This is why the 'compress' and 'output' + // sections only apply transformations that are ecma 5 safe + // https://github.com/facebook/create-react-app/pull/4234 + ecma: 8, + }, + compress: { + ecma: 5, + warnings: false, + // Disabled because of an issue with Uglify breaking seemingly valid code: + // https://github.com/facebook/create-react-app/issues/2376 + // Pending further investigation: + // https://github.com/mishoo/UglifyJS2/issues/2011 + comparisons: false, + // Disabled because of an issue with Terser breaking valid code: + // https://github.com/facebook/create-react-app/issues/5250 + // Pending further investigation: + // https://github.com/terser-js/terser/issues/120 + inline: 2, + }, + mangle: { + safari10: true, + }, + // Added for profiling in devtools + keep_classnames: isEnvProductionProfile, + keep_fnames: isEnvProductionProfile, + output: { + ecma: 5, + comments: false, + // Turned on because emoji and regex is not minified properly using default + // https://github.com/facebook/create-react-app/issues/2488 + ascii_only: true, + }, + }, + sourceMap: shouldUseSourceMap, + }), + // This is only used in production mode + new OptimizeCSSAssetsPlugin({ + cssProcessorOptions: { + parser: safePostCssParser, + map: shouldUseSourceMap + ? { + // `inline: false` forces the sourcemap to be output into a + // separate file + inline: false, + // `annotation: true` appends the sourceMappingURL to the end of + // the css file, helping the browser find the sourcemap + annotation: true, + } + : false, + }, + cssProcessorPluginOptions: { + preset: ['default', { minifyFontValues: { removeQuotes: false } }], + }, + }), + ], + // Automatically split vendor and commons + // https://twitter.com/wSokra/status/969633336732905474 + // https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366 + splitChunks: { + chunks: 'all', + name: false, + }, + // Keep the runtime chunk separated to enable long term caching + // https://twitter.com/wSokra/status/969679223278505985 + // https://github.com/facebook/create-react-app/issues/5358 + runtimeChunk: { + name: entrypoint => `runtime-${entrypoint.name}`, + }, + }, + resolve: { + // This allows you to set a fallback for where webpack should look for modules. + // We placed these paths second because we want `node_modules` to "win" + // if there are any conflicts. This matches Node resolution mechanism. + // https://github.com/facebook/create-react-app/issues/253 + modules: ['node_modules', paths.appNodeModules].concat( + modules.additionalModulePaths || [], + ), + // These are the reasonable defaults supported by the Node ecosystem. + // We also include JSX as a common component filename extension to support + // some tools, although we do not recommend using it, see: + // https://github.com/facebook/create-react-app/issues/290 + // `web` extension prefixes have been added for better support + // for React Native Web. + extensions: paths.moduleFileExtensions + .map(ext => `.${ext}`) + .filter(ext => useTypeScript || !ext.includes('ts')), + alias: { + // Support React Native Web + // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ + 'react-native': 'react-native-web', + // Allows for better profiling with ReactDevTools + ...(isEnvProductionProfile && { + 'react-dom$': 'react-dom/profiling', + 'scheduler/tracing': 'scheduler/tracing-profiling', + }), + ...(modules.webpackAliases || {}), + }, + plugins: [ + // Adds support for installing with Plug'n'Play, leading to faster installs and adding + // guards against forgotten dependencies and such. + PnpWebpackPlugin, + // Prevents users from importing files from outside of src/ (or node_modules/). + // This often causes confusion because we only process files within src/ with babel. + // To fix this, we prevent you from importing files out of src/ -- if you'd like to, + // please link the files into your node_modules/ and let module-resolution kick in. + // Make sure your source files are compiled, as they will not be processed in any way. + new ModuleScopePlugin(paths.appSrc, [ + paths.appPackageJson, + '../client', + ]), + ], + }, + resolveLoader: { + plugins: [ + // Also related to Plug'n'Play, but this time it tells webpack to load its loaders + // from the current package. + PnpWebpackPlugin.moduleLoader(module), + ], + }, + module: { + strictExportPresence: true, + rules: [ + // Disable require.ensure as it's not a standard language feature. + { parser: { requireEnsure: false } }, + + // First, run the linter. + // It's important to do this before Babel processes the JS. + { + test: /\.(js|mjs|jsx|ts|tsx)$/, + enforce: 'pre', + use: [ + { + options: { + cache: true, + formatter: require.resolve('react-dev-utils/eslintFormatter'), + eslintPath: require.resolve('eslint'), + resolvePluginsRelativeTo: __dirname, + }, + loader: require.resolve('eslint-loader'), + }, + ], + include: paths.appSrc, + }, + { + // "oneOf" will traverse all following loaders until one will + // match the requirements. When no loader matches it will fall + // back to the "file" loader at the end of the loader list. + oneOf: [ + // "url" loader works like "file" loader except that it embeds assets + // smaller than specified limit in bytes as data URLs to avoid requests. + // A missing `test` is equivalent to a match. + { + test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/], + loader: require.resolve('url-loader'), + options: { + limit: imageInlineSizeLimit, + name: 'static/media/[name].[hash:8].[ext]', + }, + }, + // Process application JS with Babel. + // The preset includes JSX, Flow, TypeScript, and some ESnext features. + { + test: /\.(js|mjs|jsx|ts|tsx)$/, + include: paths.appSrc, + loader: require.resolve('babel-loader'), + options: { + customize: require.resolve( + 'babel-preset-react-app/webpack-overrides', + ), + + plugins: [ + [ + require.resolve('babel-plugin-named-asset-import'), + { + loaderMap: { + svg: { + ReactComponent: + '@svgr/webpack?-svgo,+titleProp,+ref![path]', + }, + }, + }, + ], + ], + // This is a feature of `babel-loader` for webpack (not Babel itself). + // It enables caching results in ./node_modules/.cache/babel-loader/ + // directory for faster rebuilds. + cacheDirectory: true, + // See #6846 for context on why cacheCompression is disabled + cacheCompression: false, + compact: isEnvProduction, + }, + }, + // Process any JS outside of the app with Babel. + // Unlike the application JS, we only compile the standard ES features. + { + test: /\.(js|mjs)$/, + exclude: /@babel(?:\/|\\{1,2})runtime/, + loader: require.resolve('babel-loader'), + options: { + babelrc: false, + configFile: false, + compact: false, + presets: [ + [ + require.resolve('babel-preset-react-app/dependencies'), + { helpers: true }, + ], + ], + cacheDirectory: true, + // See #6846 for context on why cacheCompression is disabled + cacheCompression: false, + + // Babel sourcemaps are needed for debugging into node_modules + // code. Without the options below, debuggers like VSCode + // show incorrect code and set breakpoints on the wrong lines. + sourceMaps: shouldUseSourceMap, + inputSourceMap: shouldUseSourceMap, + }, + }, + // "postcss" loader applies autoprefixer to our CSS. + // "css" loader resolves paths in CSS and adds assets as dependencies. + // "style" loader turns CSS into JS modules that inject <style> tags. + // In production, we use MiniCSSExtractPlugin to extract that CSS + // to a file, but in development "style" loader enables hot editing + // of CSS. + // By default we support CSS Modules with the extension .module.css + { + test: cssRegex, + exclude: cssModuleRegex, + use: getStyleLoaders({ + importLoaders: 1, + sourceMap: isEnvProduction && shouldUseSourceMap, + }), + // Don't consider CSS imports dead code even if the + // containing package claims to have no side effects. + // Remove this when webpack adds a warning or an error for this. + // See https://github.com/webpack/webpack/issues/6571 + sideEffects: true, + }, + // Adds support for CSS Modules (https://github.com/css-modules/css-modules) + // using the extension .module.css + { + test: cssModuleRegex, + use: getStyleLoaders({ + importLoaders: 1, + sourceMap: isEnvProduction && shouldUseSourceMap, + modules: { + getLocalIdent: getCSSModuleLocalIdent, + }, + }), + }, + // Opt-in support for SASS (using .scss or .sass extensions). + // By default we support SASS Modules with the + // extensions .module.scss or .module.sass + { + test: sassRegex, + exclude: sassModuleRegex, + use: getStyleLoaders( + { + importLoaders: 3, + sourceMap: isEnvProduction && shouldUseSourceMap, + }, + 'sass-loader', + ), + // Don't consider CSS imports dead code even if the + // containing package claims to have no side effects. + // Remove this when webpack adds a warning or an error for this. + // See https://github.com/webpack/webpack/issues/6571 + sideEffects: true, + }, + // Adds support for CSS Modules, but using SASS + // using the extension .module.scss or .module.sass + { + test: sassModuleRegex, + use: getStyleLoaders( + { + importLoaders: 3, + sourceMap: isEnvProduction && shouldUseSourceMap, + modules: { + getLocalIdent: getCSSModuleLocalIdent, + }, + }, + 'sass-loader', + ), + }, + // "file" loader makes sure those assets get served by WebpackDevServer. + // When you `import` an asset, you get its (virtual) filename. + // In production, they would get copied to the `build` folder. + // This loader doesn't use a "test" so it will catch all modules + // that fall through the other loaders. + { + loader: require.resolve('file-loader'), + // Exclude `js` files to keep "css" loader working as it injects + // its runtime that would otherwise be processed through "file" loader. + // Also exclude `html` and `json` extensions so they get processed + // by webpacks internal loaders. + exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/], + options: { + name: 'static/media/[name].[hash:8].[ext]', + }, + }, + // ** STOP ** Are you adding a new loader? + // Make sure to add the new loader(s) before the "file" loader. + ], + }, + ], + }, + plugins: [ + // Generates an `index.html` file with the <script> injected. + new HtmlWebpackPlugin( + Object.assign( + {}, + { + inject: true, + template: paths.appHtml, + }, + isEnvProduction + ? { + minify: { + removeComments: true, + collapseWhitespace: true, + removeRedundantAttributes: true, + useShortDoctype: true, + removeEmptyAttributes: true, + removeStyleLinkTypeAttributes: true, + keepClosingSlash: true, + minifyJS: true, + minifyCSS: true, + minifyURLs: true, + }, + } + : undefined, + ), + ), + // Inlines the webpack runtime script. This script is too small to warrant + // a network request. + // https://github.com/facebook/create-react-app/issues/5358 + isEnvProduction && + shouldInlineRuntimeChunk && + new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]), + // Makes some environment variables available in index.html. + // The public URL is available as %PUBLIC_URL% in index.html, e.g.: + // <link rel="icon" href="%PUBLIC_URL%/favicon.ico"> + // It will be an empty string unless you specify "homepage" + // in `package.json`, in which case it will be the pathname of that URL. + new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw), + // This gives some necessary context to module not found errors, such as + // the requesting resource. + new ModuleNotFoundPlugin(paths.appPath), + // Makes some environment variables available to the JS code, for example: + // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`. + // It is absolutely essential that NODE_ENV is set to production + // during a production build. + // Otherwise React will be compiled in the very slow development mode. + new webpack.DefinePlugin(env.stringified), + // This is necessary to emit hot updates (currently CSS only): + isEnvDevelopment && new webpack.HotModuleReplacementPlugin(), + // Watcher doesn't work well if you mistype casing in a path so we use + // a plugin that prints an error when you attempt to do this. + // See https://github.com/facebook/create-react-app/issues/240 + isEnvDevelopment && new CaseSensitivePathsPlugin(), + // If you require a missing module and then `npm install` it, you still have + // to restart the development server for webpack to discover it. This plugin + // makes the discovery automatic so you don't have to restart. + // See https://github.com/facebook/create-react-app/issues/186 + isEnvDevelopment && + new WatchMissingNodeModulesPlugin(paths.appNodeModules), + isEnvProduction && + new MiniCssExtractPlugin({ + // Options similar to the same options in webpackOptions.output + // both options are optional + filename: 'static/css/[name].[contenthash:8].css', + chunkFilename: 'static/css/[name].[contenthash:8].chunk.css', + }), + // Generate an asset manifest file with the following content: + // - "files" key: Mapping of all asset filenames to their corresponding + // output file so that tools can pick it up without having to parse + // `index.html` + // - "entrypoints" key: Array of files which are included in `index.html`, + // can be used to reconstruct the HTML if necessary + new ManifestPlugin({ + fileName: 'asset-manifest.json', + publicPath: paths.publicUrlOrPath, + generate: (seed, files, entrypoints) => { + const manifestFiles = files.reduce((manifest, file) => { + manifest[file.name] = file.path + return manifest + }, seed) + const entrypointFiles = entrypoints.main.filter( + fileName => !fileName.endsWith('.map'), + ) + + return { + files: manifestFiles, + entrypoints: entrypointFiles, + } + }, + }), + // Moment.js is an extremely popular library that bundles large locale files + // by default due to how webpack interprets its code. This is a practical + // solution that requires the user to opt into importing specific locales. + // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack + // You can remove this if you don't use Moment.js: + new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), + // Generate a service worker script that will precache, and keep up to date, + // the HTML & assets that are part of the webpack build. + isEnvProduction && + new WorkboxWebpackPlugin.GenerateSW({ + clientsClaim: true, + exclude: [/\.map$/, /asset-manifest\.json$/], + importWorkboxFrom: 'cdn', + navigateFallback: paths.publicUrlOrPath + 'index.html', + navigateFallbackBlacklist: [ + // Exclude URLs starting with /_, as they're likely an API call + new RegExp('^/_'), + // Exclude any URLs whose last part seems to be a file extension + // as they're likely a resource and not a SPA route. + // URLs containing a "?" character won't be blacklisted as they're likely + // a route with query params (e.g. auth callbacks). + new RegExp('/[^/?]+\\.[^/]+$'), + ], + }), + // TypeScript type checking + useTypeScript && + new ForkTsCheckerWebpackPlugin({ + typescript: resolve.sync('typescript', { + basedir: paths.appNodeModules, + }), + async: isEnvDevelopment, + useTypescriptIncrementalApi: true, + checkSyntacticErrors: true, + resolveModuleNameModule: process.versions.pnp + ? `${__dirname}/pnpTs.js` + : undefined, + resolveTypeReferenceDirectiveModule: process.versions.pnp + ? `${__dirname}/pnpTs.js` + : undefined, + tsconfig: paths.appTsConfig, + reportFiles: [ + '**', + '!**/__tests__/**', + '!**/?(*.)(spec|test).*', + '!**/src/setupProxy.*', + '!**/src/setupTests.*', + ], + silent: true, + // The formatter is invoked directly in WebpackDevServerUtils during development + formatter: isEnvProduction ? typescriptFormatter : undefined, + }), + ].filter(Boolean), + // Some libraries import Node modules but don't use them in the browser. + // Tell webpack to provide empty mocks for them so importing them works. + node: { + module: 'empty', + dgram: 'empty', + dns: 'mock', + fs: 'empty', + http2: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty', + }, + // Turn off performance processing because we utilize + // our own hints via the FileSizeReporter + performance: false, + } +} diff --git a/packages/frame/config/webpackDevServer.config.js b/packages/frame/config/webpackDevServer.config.js new file mode 100644 index 0000000..9892bec --- /dev/null +++ b/packages/frame/config/webpackDevServer.config.js @@ -0,0 +1,130 @@ +'use strict'; + +const fs = require('fs'); +const errorOverlayMiddleware = require('react-dev-utils/errorOverlayMiddleware'); +const evalSourceMapMiddleware = require('react-dev-utils/evalSourceMapMiddleware'); +const noopServiceWorkerMiddleware = require('react-dev-utils/noopServiceWorkerMiddleware'); +const ignoredFiles = require('react-dev-utils/ignoredFiles'); +const redirectServedPath = require('react-dev-utils/redirectServedPathMiddleware'); +const paths = require('./paths'); +const getHttpsConfig = require('./getHttpsConfig'); + +const host = process.env.HOST || '0.0.0.0'; +const sockHost = process.env.WDS_SOCKET_HOST; +const sockPath = process.env.WDS_SOCKET_PATH; // default: '/sockjs-node' +const sockPort = process.env.WDS_SOCKET_PORT; + +module.exports = function(proxy, allowedHost) { + return { + // WebpackDevServer 2.4.3 introduced a security fix that prevents remote + // websites from potentially accessing local content through DNS rebinding: + // https://github.com/webpack/webpack-dev-server/issues/887 + // https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a + // However, it made several existing use cases such as development in cloud + // environment or subdomains in development significantly more complicated: + // https://github.com/facebook/create-react-app/issues/2271 + // https://github.com/facebook/create-react-app/issues/2233 + // While we're investigating better solutions, for now we will take a + // compromise. Since our WDS configuration only serves files in the `public` + // folder we won't consider accessing them a vulnerability. However, if you + // use the `proxy` feature, it gets more dangerous because it can expose + // remote code execution vulnerabilities in backends like Django and Rails. + // So we will disable the host check normally, but enable it if you have + // specified the `proxy` setting. Finally, we let you override it if you + // really know what you're doing with a special environment variable. + disableHostCheck: + !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true', + // Enable gzip compression of generated files. + compress: true, + // Silence WebpackDevServer's own logs since they're generally not useful. + // It will still show compile warnings and errors with this setting. + clientLogLevel: 'none', + // By default WebpackDevServer serves physical files from current directory + // in addition to all the virtual build products that it serves from memory. + // This is confusing because those files won’t automatically be available in + // production build folder unless we copy them. However, copying the whole + // project directory is dangerous because we may expose sensitive files. + // Instead, we establish a convention that only files in `public` directory + // get served. Our build script will copy `public` into the `build` folder. + // In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%: + // <link rel="icon" href="%PUBLIC_URL%/favicon.ico"> + // In JavaScript code, you can access it with `process.env.PUBLIC_URL`. + // Note that we only recommend to use `public` folder as an escape hatch + // for files like `favicon.ico`, `manifest.json`, and libraries that are + // for some reason broken when imported through webpack. If you just want to + // use an image, put it in `src` and `import` it from JavaScript instead. + contentBase: paths.appPublic, + contentBasePublicPath: paths.publicUrlOrPath, + // By default files from `contentBase` will not trigger a page reload. + watchContentBase: true, + // Enable hot reloading server. It will provide WDS_SOCKET_PATH endpoint + // for the WebpackDevServer client so it can learn when the files were + // updated. The WebpackDevServer client is included as an entry point + // in the webpack development configuration. Note that only changes + // to CSS are currently hot reloaded. JS changes will refresh the browser. + hot: true, + // Use 'ws' instead of 'sockjs-node' on server since we're using native + // websockets in `webpackHotDevClient`. + transportMode: 'ws', + // Prevent a WS client from getting injected as we're already including + // `webpackHotDevClient`. + injectClient: false, + // Enable custom sockjs pathname for websocket connection to hot reloading server. + // Enable custom sockjs hostname, pathname and port for websocket connection + // to hot reloading server. + sockHost, + sockPath, + sockPort, + // It is important to tell WebpackDevServer to use the same "publicPath" path as + // we specified in the webpack config. When homepage is '.', default to serving + // from the root. + // remove last slash so user can land on `/test` instead of `/test/` + publicPath: paths.publicUrlOrPath.slice(0, -1), + // WebpackDevServer is noisy by default so we emit custom message instead + // by listening to the compiler events with `compiler.hooks[...].tap` calls above. + quiet: true, + // Reportedly, this avoids CPU overload on some systems. + // https://github.com/facebook/create-react-app/issues/293 + // src/node_modules is not ignored to support absolute imports + // https://github.com/facebook/create-react-app/issues/1065 + watchOptions: { + ignored: ignoredFiles(paths.appSrc), + }, + https: getHttpsConfig(), + host, + overlay: false, + historyApiFallback: { + // Paths with dots should still use the history fallback. + // See https://github.com/facebook/create-react-app/issues/387. + disableDotRule: true, + index: paths.publicUrlOrPath, + }, + public: allowedHost, + // `proxy` is run between `before` and `after` `webpack-dev-server` hooks + proxy, + before(app, server) { + // Keep `evalSourceMapMiddleware` and `errorOverlayMiddleware` + // middlewares before `redirectServedPath` otherwise will not have any effect + // This lets us fetch source contents from webpack for the error overlay + app.use(evalSourceMapMiddleware(server)); + // This lets us open files from the runtime error overlay. + app.use(errorOverlayMiddleware()); + + if (fs.existsSync(paths.proxySetup)) { + // This registers user provided middleware for proxy reasons + require(paths.proxySetup)(app); + } + }, + after(app) { + // Redirect to `PUBLIC_URL` or `homepage` from `package.json` if url not match + app.use(redirectServedPath(paths.publicUrlOrPath)); + + // This service worker file is effectively a 'no-op' that will reset any + // previous service worker registered for the same host:port combination. + // We do this in development to avoid hitting the production cache if + // it used the same host and port. + // https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432 + app.use(noopServiceWorkerMiddleware(paths.publicUrlOrPath)); + }, + }; +}; diff --git a/packages/frame/craco.config.js b/packages/frame/craco.config.js new file mode 100644 index 0000000..4f84c80 --- /dev/null +++ b/packages/frame/craco.config.js @@ -0,0 +1,30 @@ +const path = require('path') +const resolve = arg => path.resolve(__dirname, arg) + +module.exports = function() { + return { + babel: { + plugins: [ + [ + 'emotion', + { + labelFormat: '[filename]--[local]', + }, + ], + ], + }, + webpack: { + alias: { + '@': resolve('src'), + '@client': resolve('../client'), + }, + }, + jest: { + configure: { + moduleNameMapper: { + '^@/(.*)$': '<rootDir>/src/$1', + }, + }, + }, + } +} diff --git a/packages/frame/package.json b/packages/frame/package.json new file mode 100644 index 0000000..6bdfcc6 --- /dev/null +++ b/packages/frame/package.json @@ -0,0 +1,68 @@ +{ + "name": "@trycrypto/dappstarter-frame", + "version": "0.1.0", + "private": true, + "dependencies": { + "@craco/craco": "^5.6.3", + "@trycrypto/dappstarter-client": "^0.1.0", + "@trycrypto/dappstarter-dapplib": "^0.1.0", + "@emotion/core": "^10.0.27", + "@emotion/styled": "^10.0.27", + "@fortawesome/fontawesome-free": "^5.13.0", + "@reduxjs/toolkit": "^1.2.5", + "@testing-library/jest-dom": "^4.2.4", + "@testing-library/react": "^9.4.1", + "@testing-library/user-event": "^10.0.0", + "@types/jest": "^24.0.0", + "@types/node": "^12.0.0", + "@types/react": "^16.9.0", + "@types/react-dom": "^16.9.0", + "@types/react-redux": "^7.1.5", + "@types/react-router": "^5.1.3", + "@types/react-router-dom": "^5.1.3", + "babel-plugin-emotion": "^10.0.27", + "clsx": "^1.1.0", + "eslint-plugin-simple-import-sort": "^5.0.0", + "lodash": "^4.17.15", + "react": "^16.12.0", + "react-dom": "^16.12.0", + "react-redux": "^7.2.0", + "react-router": "^5.1.2", + "react-router-dom": "^5.1.2", + "react-scripts": "3.4.0", + "typescript": "~3.8.2" + }, + "scripts": { + "start": "craco start", + "dev": "wait-on ../dapplib/src/dapp-config.json && craco start", + "build": "craco build", + "build:styles": "postcss ./src/tailwind.css -o src/styles.css", + "prebuild": "yarn build:styles", + "prestart": "yarn build:styles", + "test": "craco test", + "eject": "react-scripts eject", + "lint": "eslint ." + }, + "eslintConfig": { + "extends": "react-app" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "devDependencies": { + "@types/lodash": "^4.14.149", + "autoprefixer": "^9.7.4", + "postcss-cli": "^7.1.0", + "tailwindcss": "^1.2.0", + "wait-on": "^4.0.2" + } +} diff --git a/packages/frame/postcss.config.js b/packages/frame/postcss.config.js new file mode 100644 index 0000000..4193e8a --- /dev/null +++ b/packages/frame/postcss.config.js @@ -0,0 +1,3 @@ +module.exports = { + plugins: [require('tailwindcss'), require('autoprefixer')], +} diff --git a/packages/frame/public/android-chrome-192x192.png b/packages/frame/public/android-chrome-192x192.png new file mode 100644 index 0000000..a370abd Binary files /dev/null and b/packages/frame/public/android-chrome-192x192.png differ diff --git a/packages/frame/public/android-chrome-512x512.png b/packages/frame/public/android-chrome-512x512.png new file mode 100644 index 0000000..182ea16 Binary files /dev/null and b/packages/frame/public/android-chrome-512x512.png differ diff --git a/packages/frame/public/apple-touch-icon.png b/packages/frame/public/apple-touch-icon.png new file mode 100644 index 0000000..6380ddb Binary files /dev/null and b/packages/frame/public/apple-touch-icon.png differ diff --git a/packages/frame/public/favicon-16x16.png b/packages/frame/public/favicon-16x16.png new file mode 100644 index 0000000..8e9cc80 Binary files /dev/null and b/packages/frame/public/favicon-16x16.png differ diff --git a/packages/frame/public/favicon-32x32.png b/packages/frame/public/favicon-32x32.png new file mode 100644 index 0000000..cfbf7af Binary files /dev/null and b/packages/frame/public/favicon-32x32.png differ diff --git a/packages/frame/public/favicon.ico b/packages/frame/public/favicon.ico new file mode 100644 index 0000000..8a333ab Binary files /dev/null and b/packages/frame/public/favicon.ico differ diff --git a/packages/frame/public/index.html b/packages/frame/public/index.html new file mode 100644 index 0000000..1398aba --- /dev/null +++ b/packages/frame/public/index.html @@ -0,0 +1,246 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#000000" /> + <meta + name="description" + content="Web application created using create-react-app unicorn template" + /> + <link rel="apple-touch-icon" sizes="180x180" href="%PUBLIC_URL%/apple-touch-icon.png"> + <link rel="icon" type="image/png" sizes="32x32" href="%PUBLIC_URL%/favicon-32x32.png"> + <link rel="icon" type="image/png" sizes="16x16" href="%PUBLIC_URL%/favicon-16x16.png"> + <link rel="manifest" href="/site.webmanifest"> + <link rel="stylesheet" href="%PUBLIC_URL%/reset.css" /> + <link + href="https://fonts.googleapis.com/css?family=Cabin:400,700&display=swap" + rel="stylesheet" + /> + <title>DappStarter - TryCrypto</title> + <style> + body { + color: #212121; + font-family: 'Cabin', -apple-system, BlinkMacSystemFont, 'Segoe UI', + Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', + sans-serif; + margin: 0; + padding: 0; + background: #10264c; + } + + body a { + color: #707070; + } + + header, + main { + margin: 0 24px; + width: calc(100vw - 48px); + } + + header { + color: white; + display: flex; + font-size: 0.875rem; + justify-content: space-between; + align-items: center; + height: 72px; + } + + header a { + color: #e6e6e6; + } + + header h1 { + font-size: 0.875rem; + letter-spacing: 0.05em; + width: 245px; + } + + header h1 span { + color: rgba(255, 255, 255, 0.75); + font-weight: normal; + margin-left: 8px; + letter-spacing: normal; + } + + header nav ul { + display: flex; + list-style: none; + margin: 0; + padding: 0; + } + + header nav ul li { + border-radius: 3px; + margin: 0 12px; + } + + header nav ul li:hover { + background: rgba(0, 0, 0, 0.35); + } + + header nav ul li.active { + background: white; + } + + header nav ul li.active button { + color: #10264c; + text-decoration: none; + } + + .svg-icon { + color: currentColor; + display: block; + } + + header nav ul li button { + display: block; + padding: 8px; + } + + header .account { + display: flex; + align-items: center; + width: 245px; + } + + .avatar { + border-radius: 100px; + height: 32px; + width: 32px; + overflow: hidden; + } + + .avatar > img { + display: block; + } + + header .account > div { + display: flex; + width: 210px; + } + + header .account > div > div { + display: flex; + flex-direction: column; + padding: 0 18px; + } + + main { + background: white; + border-radius: 3px; + box-shadow: 0 3px 12px rgba(0, 0, 0, 0.16); + height: calc(100vh - 72px - 24px); + width: calc(100vw - 48px); + } + + main .main-header { + display: flex; + font-size: 0.875rem; + justify-content: space-between; + align-items: center; + align-content: center; + justify-items: center; + height: 32px; + position: relative; + text-align: center; + width: 100%; + text-transform: uppercase; + letter-spacing: 0.05em; + } + + main .main-header a.full { + position: absolute; + top: 0; + right: 20px; + height: 32px; + display: flex; + align-items: center; + } + + main .main-header h2 { + font-size: 14px; + font-weight: bold; + text-align: center; + width: 100%; + } + + main .main-header h2 span { + font-weight: normal; + } + + main .main-iframe { + border: 3px solid #10264c; + border: 12px solid #e4e4e4; + border: 1px solid #ddd; + position: relative; + width: calc(100vw - 62px); + /* 104px + 32px */ + height: calc(100vh - 168px); + /* 72px + 24px + 54px + 40px + 24px */ + margin: 0 auto; + /* padding: 16px; */ + background: #e9e9e9; + } + + main .main-iframe iframe { + position: absolute; + height: calc(100vh - 170px); + /* 86px + 32px + 54px + 48px + 32px */ + /* width: calc(100vw - 82px); */ + /* left: 16px; + right: 16px; + top: 16px; + bottom: 16px; */ + border: none; + } + + main .main-footer { + color: #707070; + font-size: 0.75rem; + text-transform: uppercase; + height: 40px; + position: relative; + margin: 0 20px; + width: calc(100% - 40px); + display: flex; + align-items: center; + justify-content: center; + text-transform: uppercase; + letter-spacing: 0.05em; + } + + main .main-footer .footer-left { + position: absolute; + left: 0; + top: 0; + height: 40px; + display: flex; + align-items: center; + opacity: 0.75; + } + + main .main-footer .footer-right { + position: absolute; + right: 0; + top: 0; + height: 40px; + display: flex; + align-items: center; + opacity: 0.75; + } + + main .main-footer .footer-right a { + text-decoration: none; + } + </style> + </head> + + <body> + <noscript>You need to enable JavaScript to run this app.</noscript> + <div id="root"></div> + </body> +</html> diff --git a/packages/frame/public/reset.css b/packages/frame/public/reset.css new file mode 100644 index 0000000..80e45b8 --- /dev/null +++ b/packages/frame/public/reset.css @@ -0,0 +1,446 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0-modified | 20110126 + License: none (public domain) +*/ + +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +ul, +li, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} + +/* make sure to set some focus styles for accessibility */ +:focus { + outline: 0; +} + +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} + +body { + line-height: 1; +} + +ol, +ul { + list-style: none; +} + +blockquote, +q { + quotes: none; +} + +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ""; + content: none; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-results-button, +input[type="search"]::-webkit-search-results-decoration { + -webkit-appearance: none; + -moz-appearance: none; +} + +input[type="search"] { + -webkit-appearance: none; + -moz-appearance: none; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +textarea { + overflow: auto; + vertical-align: top; + resize: vertical; +} + +/** + * Correct `inline-block` display not defined in IE 6/7/8/9 and Firefox 3. + */ + +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; + max-width: 100%; +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address styling not present in IE 7/8/9, Firefox 3, and Safari 4. + * Known issue: no IE 6 support. + */ + +[hidden] { + display: none; +} + +/** + * 1. Correct text resizing oddly in IE 6/7 when body `font-size` is set using + * `em` units. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-size: 100%; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ + -ms-text-size-adjust: 100%; /* 2 */ +} + +/** + * Address `outline` inconsistency between Chrome and other browsers. + */ + +a:focus { + outline: thin dotted; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/** + * 1. Remove border when inside `a` element in IE 6/7/8/9 and Firefox 3. + * 2. Improve image quality when scaled in IE 7. + */ + +img { + border: 0; /* 1 */ + -ms-interpolation-mode: bicubic; /* 2 */ +} + +/** + * Address margin not present in IE 6/7/8/9, Safari 5, and Opera 11. + */ + +figure { + margin: 0; +} + +/** + * Correct margin displayed oddly in IE 6/7. + */ + +form { + margin: 0; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct color not being inherited in IE 6/7/8/9. + * 2. Correct text not wrapping in Firefox 3. + * 3. Correct alignment displayed oddly in IE 6/7. + */ + +legend { + border: 0; /* 1 */ + padding: 0; + white-space: normal; /* 2 */ + *margin-left: -7px; /* 3 */ +} + +/** + * 1. Correct font size not being inherited in all browsers. + * 2. Address margins set differently in IE 6/7, Firefox 3+, Safari 5, + * and Chrome. + * 3. Improve appearance and consistency in all browsers. + */ + +button, +input, +select, +textarea { + font-size: 100%; /* 1 */ + margin: 0; /* 2 */ + vertical-align: baseline; /* 3 */ + *vertical-align: middle; /* 3 */ +} + +/** + * Address Firefox 3+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +button, +input { + line-height: normal; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Chrome, Safari 5+, and IE 6+. + * Correct `select` style inheritance in Firefox 4+ and Opera. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + * 4. Remove inner spacing in IE 7 without affecting normal text inputs. + * Known issue: inner spacing remains in IE 6. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ + *overflow: visible; /* 4 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * 1. Address box sizing set to content-box in IE 8/9. + * 2. Remove excess padding in IE 8/9. + * 3. Remove excess padding in IE 7. + * Known issue: excess padding remains in IE 6. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ + *height: 13px; /* 3 */ + *width: 13px; /* 3 */ +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/** + * Remove inner padding and search cancel button in Safari 5 and Chrome + * on OS X. + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Remove inner padding and border in Firefox 3+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * 1. Remove default vertical scrollbar in IE 6/7/8/9. + * 2. Improve readability and alignment in all browsers. + */ + +textarea { + overflow: auto; /* 1 */ + vertical-align: top; /* 2 */ +} + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} + +html, +button, +input, +select, +textarea { + color: #222; +} + +::-moz-selection { + background: #b3d4fc; + text-shadow: none; +} + +::selection { + background: #b3d4fc; + text-shadow: none; +} + +img { + vertical-align: middle; +} + +fieldset { + border: 0; + margin: 0; + padding: 0; +} + +textarea { + resize: vertical; +} + +.chromeframe { + margin: 0.2em 0; + background: #ccc; + color: #000; + padding: 0.2em 0; +} diff --git a/packages/frame/public/robots.txt b/packages/frame/public/robots.txt new file mode 100644 index 0000000..01b0f9a --- /dev/null +++ b/packages/frame/public/robots.txt @@ -0,0 +1,2 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * diff --git a/packages/frame/public/site.webmanifest b/packages/frame/public/site.webmanifest new file mode 100644 index 0000000..45dc8a2 --- /dev/null +++ b/packages/frame/public/site.webmanifest @@ -0,0 +1 @@ +{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/packages/frame/public/trycrypto-logo.svg b/packages/frame/public/trycrypto-logo.svg new file mode 100644 index 0000000..a59aa66 --- /dev/null +++ b/packages/frame/public/trycrypto-logo.svg @@ -0,0 +1 @@ +<svg id="MouseOff" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1618.24 485.7"><defs><style>.cls-1{fill:#00c6f6;}.cls-2,.cls-6{fill:#ffd200;}.cls-3{fill:#fff;}.cls-3,.cls-4,.cls-5,.cls-6{fill-rule:evenodd;}.cls-4{fill:#3f3f3f;}.cls-5{fill:url(#linear-gradient);}.cls-7{fill:#333;}</style><linearGradient id="linear-gradient" x1="90.2" y1="525" x2="90.2" y2="282" gradientTransform="translate(0 -282)" gradientUnits="userSpaceOnUse"><stop offset="0.48" stop-color="#00c6f6"/><stop offset="0.88" stop-color="#7fe862"/></linearGradient></defs><path class="cls-1" d="M216.8,279.3a7.49,7.49,0,0,1-2.2-5.3V258.7a7.71,7.71,0,0,1,2.2-5.5,6.82,6.82,0,0,1,5.2-2.3h21.8a7.79,7.79,0,0,1,7.8,7.7V274a7.19,7.19,0,0,1-2.3,5.3,7.47,7.47,0,0,1-5.5,2.3H222A7.55,7.55,0,0,1,216.8,279.3Zm50,127.7a7.19,7.19,0,0,1-2.3-5.3v-143a7.79,7.79,0,0,1,7.7-7.8h66.3a6.82,6.82,0,0,1,5.2,2.3,8.15,8.15,0,0,1,2.2,5.5V274a7.49,7.49,0,0,1-2.2,5.3,6.82,6.82,0,0,1-5.2,2.3H296V401.7a7.69,7.69,0,0,1-7.5,7.5H272.3A7,7,0,0,1,266.8,407Z" transform="translate(0)"/><path class="cls-1" d="M368.4,407.1a6.82,6.82,0,0,1-2.3-5.2V331.4a7.69,7.69,0,0,1,7.5-7.5h66c18.1,0,27.2-6.8,27.2-20.5,0-7-2.4-12.5-7.2-16.4s-11.2-5.8-19.1-5.8H373.7a7.4,7.4,0,0,1-5.3-2.1,6.82,6.82,0,0,1-2.3-5.2V258.3a6.82,6.82,0,0,1,2.3-5.2,7,7,0,0,1,5.3-2.1h68.8c10.9,0,20.6,2.2,29,6.5a47.41,47.41,0,0,1,19.6,18.3c4.7,7.9,7,17.1,7,27.6,0,10.9-2.6,20.3-7.9,28.1s-12.8,13.4-22.5,16.7l32.4,49.6a7.39,7.39,0,0,1,1.3,4.1,6.77,6.77,0,0,1-2.3,5.1,7.19,7.19,0,0,1-5.3,2.3H474.4a6.86,6.86,0,0,1-6.3-3.5l-32.6-51.5H397.3V402a7,7,0,0,1-2.3,5.2,7.49,7.49,0,0,1-5.3,2.2H373.5A8.52,8.52,0,0,1,368.4,407.1Z" transform="translate(0)"/><path class="cls-1" d="M537.8,302.2l-27.4-39.5a7.49,7.49,0,0,1-1.3-4.3,7.28,7.28,0,0,1,7.1-7.5h20a7.54,7.54,0,0,1,6.3,3l27.6,39.7a7.54,7.54,0,0,1,.4,7.8,6.57,6.57,0,0,1-2.7,3,8,8,0,0,1-4,1.1H544.2A7.87,7.87,0,0,1,537.8,302.2Zm33.8,104.9a6.82,6.82,0,0,1-2.3-5.2V339.8a7.6,7.6,0,0,1,1.5-4.1l56.7-81.8q1.95-3,6.3-3h19.4a6.82,6.82,0,0,1,6.7,3.9,9.36,9.36,0,0,1,1.1,3.7,8.57,8.57,0,0,1-1.5,4.3l-58.7,84.8v54.3a6.82,6.82,0,0,1-2.3,5.2,7.49,7.49,0,0,1-5.3,2.2H577A7.73,7.73,0,0,1,571.6,407.1Z" transform="translate(0)"/><path class="cls-2" d="M689.1,394.6a76.25,76.25,0,0,1-20.8-28.2,95.55,95.55,0,0,1,0-73.5,76.6,76.6,0,0,1,20.8-28.3,68.14,68.14,0,0,1,31.4-14.8,5,5,0,0,1,1.7-.2,8.66,8.66,0,0,1,4.7,1.7,7,7,0,0,1,2.8,5.8V274a7.49,7.49,0,0,1-1.6,4.5,7,7,0,0,1-4,2.8,38.34,38.34,0,0,0-23.5,17.2c-5.5,8.8-8.2,19.1-8.2,31.1,0,12.2,2.7,22.6,8.2,31.1A40.68,40.68,0,0,0,724.1,378a9.4,9.4,0,0,1,4,2.8,6.72,6.72,0,0,1,1.6,4.3v17c0,2.7-.9,4.7-2.7,5.8a11.86,11.86,0,0,1-6.6,1.7A68.6,68.6,0,0,1,689.1,394.6Zm93.6-87.7a6.44,6.44,0,0,1-2.8-3.3,44.67,44.67,0,0,0-12.2-16,37.68,37.68,0,0,0-18-8,7.71,7.71,0,0,1-6.5-7.5V256.4a6.55,6.55,0,0,1,2.5-5.5,9.08,9.08,0,0,1,6.2-2,76.41,76.41,0,0,1,36.8,16.4,73,73,0,0,1,22.7,32.8,10.87,10.87,0,0,1,.4,2.6,6.79,6.79,0,0,1-2.3,5.5,7.31,7.31,0,0,1-5.3,2H786.9A9,9,0,0,1,782.7,306.9Zm-37,101.7a6.73,6.73,0,0,1-2.5-5.6V387.3a8.16,8.16,0,0,1,1.7-5,7.16,7.16,0,0,1,4.5-2.6,39.53,39.53,0,0,0,18.2-8.1,44.32,44.32,0,0,0,12.2-15.9,6.66,6.66,0,0,1,2.8-3.4,8.21,8.21,0,0,1,4.3-1.2h17.2a7.76,7.76,0,0,1,5.3,2,7.11,7.11,0,0,1,2.3,5.5,11.71,11.71,0,0,1-.4,2.6,71.54,71.54,0,0,1-22.7,33,74.23,74.23,0,0,1-36.9,16.2,8.72,8.72,0,0,1-6-1.8Z" transform="translate(0)"/><path class="cls-2" d="M833.8,407.1a6.82,6.82,0,0,1-2.3-5.2V331.4a7.69,7.69,0,0,1,7.5-7.5h66c18.1,0,27.2-6.8,27.2-20.5,0-7-2.4-12.5-7.2-16.4s-11.2-5.8-19.1-5.8H839a7.49,7.49,0,0,1-5.3-2.2,6.82,6.82,0,0,1-2.3-5.2V258.3a6.82,6.82,0,0,1,2.3-5.2A7,7,0,0,1,839,251h68.8c10.9,0,20.6,2.2,29,6.5a47.41,47.41,0,0,1,19.6,18.3c4.7,7.9,7,17.1,7,27.6,0,10.9-2.6,20.3-7.9,28.1s-12.8,13.4-22.5,16.7l32.3,49.6a7.39,7.39,0,0,1,1.3,4.1,6.77,6.77,0,0,1-2.3,5.1,7.19,7.19,0,0,1-5.3,2.3H939.6a6.86,6.86,0,0,1-6.3-3.5L901,354.2H862.8v47.7a7,7,0,0,1-2.3,5.2,7.49,7.49,0,0,1-5.3,2.2H839A8.33,8.33,0,0,1,833.8,407.1Z" transform="translate(0)"/><path class="cls-2" d="M1003.3,302.2l-27.4-39.5a7.49,7.49,0,0,1-1.3-4.3,7.3,7.3,0,0,1,7.2-7.5h20a7.54,7.54,0,0,1,6.3,3l27.6,39.7a7.54,7.54,0,0,1,.4,7.8,6.57,6.57,0,0,1-2.7,3,8,8,0,0,1-4,1.1h-19.6A7.92,7.92,0,0,1,1003.3,302.2ZM1037,407.1a6.82,6.82,0,0,1-2.3-5.2V339.8a7.6,7.6,0,0,1,1.5-4.1l56.7-81.8q1.95-3,6.3-3h19.4a6.82,6.82,0,0,1,6.7,3.9,9.36,9.36,0,0,1,1.1,3.7,8.25,8.25,0,0,1-1.5,4.3l-58.7,84.8v54.3a6.82,6.82,0,0,1-2.3,5.2,7.49,7.49,0,0,1-5.3,2.2h-16.2A8.1,8.1,0,0,1,1037,407.1Z" transform="translate(0)"/><path class="cls-2" d="M1141.5,407a7.49,7.49,0,0,1-2.2-5.3V335.4a7.49,7.49,0,0,1,2.2-5.3,6.82,6.82,0,0,1,5.2-2.3h63.4c17.8,0,26.7-7.8,26.7-23.3s-8.9-23.3-26.7-23.3h-63.4a6.82,6.82,0,0,1-5.2-2.3,7.49,7.49,0,0,1-2.2-5.3V258.3a7.49,7.49,0,0,1,2.2-5.3,6.82,6.82,0,0,1,5.2-2.3h64.7c11.2,0,21.1,2.2,29.7,6.7a47.47,47.47,0,0,1,19.8,18.9c4.7,8.1,7,17.5,7,28.1s-2.3,20-7,28.1a47.23,47.23,0,0,1-19.8,18.8c-8.6,4.4-18.4,6.6-29.7,6.6h-41v43.6a7.49,7.49,0,0,1-2.2,5.3,6.82,6.82,0,0,1-5.2,2.3h-16.4A6.38,6.38,0,0,1,1141.5,407Z" transform="translate(0)"/><path class="cls-2" d="M1273.1,279.3a7.49,7.49,0,0,1-2.2-5.3V258.7a7.71,7.71,0,0,1,2.2-5.5,6.82,6.82,0,0,1,5.2-2.3h21.8a7.79,7.79,0,0,1,7.8,7.7V274a7.19,7.19,0,0,1-2.3,5.3,7.47,7.47,0,0,1-5.5,2.3h-21.8A7.19,7.19,0,0,1,1273.1,279.3Zm50,127.7a7.19,7.19,0,0,1-2.3-5.3v-143a7.79,7.79,0,0,1,7.7-7.8h66.3a7,7,0,0,1,5.2,2.3,8.15,8.15,0,0,1,2.2,5.5V274a7.49,7.49,0,0,1-2.2,5.3,6.82,6.82,0,0,1-5.2,2.3h-42.5V401.7a7.71,7.71,0,0,1-7.6,7.5h-16.2A7,7,0,0,1,1323.1,407Z" transform="translate(0)"/><path class="cls-2" d="M1436.9,395.5a79.88,79.88,0,0,1-23.4-28.8,83.9,83.9,0,0,1-8.4-37.1,85.2,85.2,0,0,1,8.3-37.1,78.81,78.81,0,0,1,57.9-43.8q4,0,6,1.5a8.6,8.6,0,0,1,2.6,6.3v16.2a7.55,7.55,0,0,1-1.6,4.6,7.84,7.84,0,0,1-4.4,2.7,46.69,46.69,0,0,0-27.1,17.2c-6.7,8.7-10,19.6-10,32.4,0,12.5,3.3,23.2,9.9,32s15.7,14.6,27.2,17.4a7.84,7.84,0,0,1,4.4,2.7,7.16,7.16,0,0,1,1.6,4.6v16.2a7.32,7.32,0,0,1-2.5,5.9,9.08,9.08,0,0,1-6.2,2A77,77,0,0,1,1436.9,395.5Zm58.9,13a7.45,7.45,0,0,1-2.5-5.9V386.4a7.55,7.55,0,0,1,1.6-4.6,7.84,7.84,0,0,1,4.4-2.7c11.5-2.7,20.6-8.5,27.2-17.4s9.9-19.5,9.9-32c0-12.7-3.3-23.5-10-32.4a45.06,45.06,0,0,0-27.1-17.3,6.62,6.62,0,0,1-4.4-2.5,7.24,7.24,0,0,1-1.6-4.9V256.5a7.24,7.24,0,0,1,2.3-5.8,9.18,9.18,0,0,1,6.4-1.9,76.2,76.2,0,0,1,43.3,22.9,80.54,80.54,0,0,1,17.2,26.2,88.53,88.53,0,0,1-2.7,68.9,79.88,79.88,0,0,1-23.4,28.8,78.2,78.2,0,0,1-34.4,15A9.89,9.89,0,0,1,1495.8,408.5Z" transform="translate(0)"/><path class="cls-3" d="M179.9,160.5V0H100.7V81c0,43.8,35.4,79.8,79.2,80.9Z" transform="translate(0)"/><path class="cls-4" d="M136.7,65.1a16.18,16.18,0,1,1-12.3,19.3A16.22,16.22,0,0,1,136.7,65.1Z" transform="translate(0)"/><path class="cls-4" d="M261.1,30.1A102.07,102.07,0,0,0,184,.5c-1.5-.1-3-.1-4.5-.1V160.7a80.84,80.84,0,0,0,50.6-17.8l31,30.8a101.22,101.22,0,0,0,.5-143.1C261.5,30.4,261.3,30.3,261.1,30.1Z" transform="translate(0)"/><path class="cls-5" d="M100.7,81V0H81.9C37.1,0,.5,36.5.5,81V243c0-44.6,36.6-81,81.4-81h98C136.1,160.8,100.7,124.9,100.7,81Z" transform="translate(0)"/><path class="cls-6" d="M98,329.4c0-44.7,36.4-81,81.4-81V161.7h-98c-44.8,0-81.4,36.4-81.4,81v162c0,44.5,36.6,81,81.4,81h98V410.4C134.4,410.4,98,374.1,98,329.4Z" transform="translate(0)"/><path class="cls-7" d="M1581.42,251.78h-7.14v-3h17.6v3h-7.14v21.49h-3.32Z" transform="translate(0)"/><path class="cls-7" d="M1614.74,273.27l-2.31-18.52-6.65,12.71L1599,254.72l-2.31,18.55h-3.5l3.29-24.5h2.83l6.44,12.14,6.37-12.14H1615l3.26,24.5Z" transform="translate(0)"/></svg> \ No newline at end of file diff --git a/packages/frame/scripts/build.js b/packages/frame/scripts/build.js new file mode 100644 index 0000000..2d82669 --- /dev/null +++ b/packages/frame/scripts/build.js @@ -0,0 +1,211 @@ +'use strict'; + +// Do this as the first thing so that any code reading it knows the right env. +process.env.BABEL_ENV = 'production'; +process.env.NODE_ENV = 'production'; + +// Makes the script crash on unhandled rejections instead of silently +// ignoring them. In the future, promise rejections that are not handled will +// terminate the Node.js process with a non-zero exit code. +process.on('unhandledRejection', err => { + throw err; +}); + +// Ensure environment variables are read. +require('../config/env'); + + +const path = require('path'); +const chalk = require('react-dev-utils/chalk'); +const fs = require('fs-extra'); +const webpack = require('webpack'); +const configFactory = require('../config/webpack.config'); +const paths = require('../config/paths'); +const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); +const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages'); +const printHostingInstructions = require('react-dev-utils/printHostingInstructions'); +const FileSizeReporter = require('react-dev-utils/FileSizeReporter'); +const printBuildError = require('react-dev-utils/printBuildError'); + +const measureFileSizesBeforeBuild = + FileSizeReporter.measureFileSizesBeforeBuild; +const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild; +const useYarn = fs.existsSync(paths.yarnLockFile); + +// These sizes are pretty large. We'll warn for bundles exceeding them. +const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024; +const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024; + +const isInteractive = process.stdout.isTTY; + +// Warn and crash if required files are missing +if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { + process.exit(1); +} + +// Generate configuration +const config = configFactory('production'); + +// We require that you explicitly set browsers and do not fall back to +// browserslist defaults. +const { checkBrowsers } = require('react-dev-utils/browsersHelper'); +checkBrowsers(paths.appPath, isInteractive) + .then(() => { + // First, read the current file sizes in build directory. + // This lets us display how much they changed later. + return measureFileSizesBeforeBuild(paths.appBuild); + }) + .then(previousFileSizes => { + // Remove all content but keep the directory so that + // if you're in it, you don't end up in Trash + fs.emptyDirSync(paths.appBuild); + // Merge with the public folder + copyPublicFolder(); + // Start the webpack build + return build(previousFileSizes); + }) + .then( + ({ stats, previousFileSizes, warnings }) => { + if (warnings.length) { + console.log(chalk.yellow('Compiled with warnings.\n')); + console.log(warnings.join('\n\n')); + console.log( + '\nSearch for the ' + + chalk.underline(chalk.yellow('keywords')) + + ' to learn more about each warning.' + ); + console.log( + 'To ignore, add ' + + chalk.cyan('// eslint-disable-next-line') + + ' to the line before.\n' + ); + } else { + console.log(chalk.green('Compiled successfully.\n')); + } + + console.log('File sizes after gzip:\n'); + printFileSizesAfterBuild( + stats, + previousFileSizes, + paths.appBuild, + WARN_AFTER_BUNDLE_GZIP_SIZE, + WARN_AFTER_CHUNK_GZIP_SIZE + ); + console.log(); + + const appPackage = require(paths.appPackageJson); + const publicUrl = paths.publicUrlOrPath; + const publicPath = config.output.publicPath; + const buildFolder = path.relative(process.cwd(), paths.appBuild); + printHostingInstructions( + appPackage, + publicUrl, + publicPath, + buildFolder, + useYarn + ); + }, + err => { + const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true'; + if (tscCompileOnError) { + console.log( + chalk.yellow( + 'Compiled with the following type errors (you may want to check these before deploying your app):\n' + ) + ); + printBuildError(err); + } else { + console.log(chalk.red('Failed to compile.\n')); + printBuildError(err); + process.exit(1); + } + } + ) + .catch(err => { + if (err && err.message) { + console.log(err.message); + } + process.exit(1); + }); + +// Create the production build and print the deployment instructions. +function build(previousFileSizes) { + // We used to support resolving modules according to `NODE_PATH`. + // This now has been deprecated in favor of jsconfig/tsconfig.json + // This lets you use absolute paths in imports inside large monorepos: + if (process.env.NODE_PATH) { + console.log( + chalk.yellow( + 'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.' + ) + ); + console.log(); + } + + console.log('Creating an optimized production build...'); + + const compiler = webpack(config); + return new Promise((resolve, reject) => { + compiler.run((err, stats) => { + let messages; + if (err) { + if (!err.message) { + return reject(err); + } + + let errMessage = err.message; + + // Add additional information for postcss errors + if (Object.prototype.hasOwnProperty.call(err, 'postcssNode')) { + errMessage += + '\nCompileError: Begins at CSS selector ' + + err['postcssNode'].selector; + } + + messages = formatWebpackMessages({ + errors: [errMessage], + warnings: [], + }); + } else { + messages = formatWebpackMessages( + stats.toJson({ all: false, warnings: true, errors: true }) + ); + } + if (messages.errors.length) { + // Only keep the first error. Others are often indicative + // of the same problem, but confuse the reader with noise. + if (messages.errors.length > 1) { + messages.errors.length = 1; + } + return reject(new Error(messages.errors.join('\n\n'))); + } + if ( + process.env.CI && + (typeof process.env.CI !== 'string' || + process.env.CI.toLowerCase() !== 'false') && + messages.warnings.length + ) { + console.log( + chalk.yellow( + '\nTreating warnings as errors because process.env.CI = true.\n' + + 'Most CI servers set it automatically.\n' + ) + ); + return reject(new Error(messages.warnings.join('\n\n'))); + } + + return resolve({ + stats, + previousFileSizes, + warnings: messages.warnings, + }); + }); + }); +} + +function copyPublicFolder() { + fs.copySync(paths.appPublic, paths.appBuild, { + dereference: true, + filter: file => file !== paths.appHtml, + }); +} diff --git a/packages/frame/scripts/start.js b/packages/frame/scripts/start.js new file mode 100644 index 0000000..f0f9ec0 --- /dev/null +++ b/packages/frame/scripts/start.js @@ -0,0 +1,157 @@ +'use strict'; + +// Do this as the first thing so that any code reading it knows the right env. +process.env.BABEL_ENV = 'development'; +process.env.NODE_ENV = 'development'; + +// Makes the script crash on unhandled rejections instead of silently +// ignoring them. In the future, promise rejections that are not handled will +// terminate the Node.js process with a non-zero exit code. +process.on('unhandledRejection', err => { + throw err; +}); + +// Ensure environment variables are read. +require('../config/env'); + + +const fs = require('fs'); +const chalk = require('react-dev-utils/chalk'); +const webpack = require('webpack'); +const WebpackDevServer = require('webpack-dev-server'); +const clearConsole = require('react-dev-utils/clearConsole'); +const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); +const { + choosePort, + createCompiler, + prepareProxy, + prepareUrls, +} = require('react-dev-utils/WebpackDevServerUtils'); +const openBrowser = require('react-dev-utils/openBrowser'); +const paths = require('../config/paths'); +const configFactory = require('../config/webpack.config'); +const createDevServerConfig = require('../config/webpackDevServer.config'); + +const useYarn = fs.existsSync(paths.yarnLockFile); +const isInteractive = process.stdout.isTTY; + +// Warn and crash if required files are missing +if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { + process.exit(1); +} + +// Tools like Cloud9 rely on this. +const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000; +const HOST = process.env.HOST || '0.0.0.0'; + +if (process.env.HOST) { + console.log( + chalk.cyan( + `Attempting to bind to HOST environment variable: ${chalk.yellow( + chalk.bold(process.env.HOST) + )}` + ) + ); + console.log( + `If this was unintentional, check that you haven't mistakenly set it in your shell.` + ); + console.log( + `Learn more here: ${chalk.yellow('https://bit.ly/CRA-advanced-config')}` + ); + console.log(); +} + +// We require that you explicitly set browsers and do not fall back to +// browserslist defaults. +const { checkBrowsers } = require('react-dev-utils/browsersHelper'); +checkBrowsers(paths.appPath, isInteractive) + .then(() => { + // We attempt to use the default port but if it is busy, we offer the user to + // run on a different port. `choosePort()` Promise resolves to the next free port. + return choosePort(HOST, DEFAULT_PORT); + }) + .then(port => { + if (port == null) { + // We have not found a port. + return; + } + + const config = configFactory('development'); + const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; + const appName = require(paths.appPackageJson).name; + const useTypeScript = fs.existsSync(paths.appTsConfig); + const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true'; + const urls = prepareUrls( + protocol, + HOST, + port, + paths.publicUrlOrPath.slice(0, -1) + ); + const devSocket = { + warnings: warnings => + devServer.sockWrite(devServer.sockets, 'warnings', warnings), + errors: errors => + devServer.sockWrite(devServer.sockets, 'errors', errors), + }; + // Create a webpack compiler that is configured with custom messages. + const compiler = createCompiler({ + appName, + config, + devSocket, + urls, + useYarn, + useTypeScript, + tscCompileOnError, + webpack, + }); + // Load proxy config + const proxySetting = require(paths.appPackageJson).proxy; + const proxyConfig = prepareProxy( + proxySetting, + paths.appPublic, + paths.publicUrlOrPath + ); + // Serve webpack assets generated by the compiler over a web server. + const serverConfig = createDevServerConfig( + proxyConfig, + urls.lanUrlForConfig + ); + const devServer = new WebpackDevServer(compiler, serverConfig); + // Launch WebpackDevServer. + devServer.listen(port, HOST, err => { + if (err) { + return console.log(err); + } + if (isInteractive) { + clearConsole(); + } + + // We used to support resolving modules according to `NODE_PATH`. + // This now has been deprecated in favor of jsconfig/tsconfig.json + // This lets you use absolute paths in imports inside large monorepos: + if (process.env.NODE_PATH) { + console.log( + chalk.yellow( + 'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.' + ) + ); + console.log(); + } + + console.log(chalk.cyan('Starting the development server...\n')); + openBrowser(urls.localUrlForBrowser); + }); + + ['SIGINT', 'SIGTERM'].forEach(function(sig) { + process.on(sig, function() { + devServer.close(); + process.exit(); + }); + }); + }) + .catch(err => { + if (err && err.message) { + console.log(err.message); + } + process.exit(1); + }); diff --git a/packages/frame/scripts/test.js b/packages/frame/scripts/test.js new file mode 100644 index 0000000..b57cb38 --- /dev/null +++ b/packages/frame/scripts/test.js @@ -0,0 +1,53 @@ +'use strict'; + +// Do this as the first thing so that any code reading it knows the right env. +process.env.BABEL_ENV = 'test'; +process.env.NODE_ENV = 'test'; +process.env.PUBLIC_URL = ''; + +// Makes the script crash on unhandled rejections instead of silently +// ignoring them. In the future, promise rejections that are not handled will +// terminate the Node.js process with a non-zero exit code. +process.on('unhandledRejection', err => { + throw err; +}); + +// Ensure environment variables are read. +require('../config/env'); + + +const jest = require('jest'); +const execSync = require('child_process').execSync; +let argv = process.argv.slice(2); + +function isInGitRepository() { + try { + execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' }); + return true; + } catch (e) { + return false; + } +} + +function isInMercurialRepository() { + try { + execSync('hg --cwd . root', { stdio: 'ignore' }); + return true; + } catch (e) { + return false; + } +} + +// Watch unless on CI or explicitly running all tests +if ( + !process.env.CI && + argv.indexOf('--watchAll') === -1 && + argv.indexOf('--watchAll=false') === -1 +) { + // https://github.com/facebook/create-react-app/issues/5210 + const hasSourceControl = isInGitRepository() || isInMercurialRepository(); + argv.push(hasSourceControl ? '--watch' : '--watchAll'); +} + + +jest.run(argv); diff --git a/packages/frame/src/components/App.tsx b/packages/frame/src/components/App.tsx new file mode 100644 index 0000000..126038e --- /dev/null +++ b/packages/frame/src/components/App.tsx @@ -0,0 +1,302 @@ +import React, { useState, useEffect, useCallback } from 'react' +import clsx from 'clsx' +import { find, keys } from 'lodash' +const manifest = require('@trycrypto/dappstarter-dapplib/manifest.json') + +enum View { + Client, + Server, + Connector, + Contract, + Logs, +} + +const viewLinks = { + [View.Client]: 'http://localhost:5001', + [View.Server]: 'http://localhost:5002', + [View.Connector]: 'http://localhost:5003', + [View.Contract]: '', + [View.Logs]: '', +} +interface ISiteReady { + [index: number]: boolean +} + +export default () => { + const [selected, setSelected] = useState<View>(View.Client) + const [dappReady, setDappReady] = useState<ISiteReady>({}) + const blockchain = find(keys(manifest.blocks), /\/blockchains\//) + ?.toString() + .split('/')[2] + + const checkAppReady = useCallback( + async (view: View) => { + try { + const response = await fetch(viewLinks[view]) + if (response.ok) { + setDappReady((dappReady) => { + return { ...dappReady, [view]: true } + }) + } else { + setTimeout(() => checkAppReady(view), 1000) + } + } catch (error) { + setTimeout(() => checkAppReady(view), 1000) + } + }, + [] + ) + + useEffect(() => { + checkAppReady(View.Client) + checkAppReady(View.Connector) + checkAppReady(View.Server) + }, [checkAppReady]) + + return ( + <div> + <header> + <div className="logo"> + <img src="./trycrypto-logo.svg" width="133" alt="logo" /> + </div> + <nav> + <ul> + <li className={clsx({ active: selected === View.Client })}> + <button title="Client" onClick={() => setSelected(View.Client)}> + <svg + xmlns="http://www.w3.org/2000/svg" + width="20" + height="20" + viewBox="0 0 24 24" + fill="none" + stroke="#51C3F2" + strokeWidth="2" + strokeLinecap="round" + strokeLinejoin="round" + className="svg-icon feather feather-layout" + > + <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect> + <line x1="3" y1="9" x2="21" y2="9"></line> + <line x1="9" y1="21" x2="9" y2="9"></line> + </svg> + </button> + </li> + <li className={clsx({ active: selected === View.Connector })}> + <button + title="Connector" + onClick={() => setSelected(View.Connector)} + > + <svg + xmlns="http://www.w3.org/2000/svg" + width="20" + height="20" + viewBox="0 0 24 24" + fill="none" + stroke="#61CCCD" + strokeWidth="2" + strokeLinecap="round" + strokeLinejoin="round" + className="svg-icon feather feather-server" + > + <rect x="2" y="2" width="20" height="8" rx="2" ry="2"></rect> + <rect x="2" y="14" width="20" height="8" rx="2" ry="2"></rect> + <line x1="6" y1="6" x2="6.01" y2="6"></line> + <line x1="6" y1="18" x2="6.01" y2="18"></line> + </svg> + </button> + </li> + <li className={clsx({ active: selected === View.Server })}> + <button title="Server" onClick={() => setSelected(View.Server)}> + <svg + xmlns="http://www.w3.org/2000/svg" + width="20" + height="20" + viewBox="0 0 24 24" + fill="none" + stroke="#70D2B8" + strokeWidth="2" + strokeLinecap="round" + strokeLinejoin="round" + className="svg-icon feather feather-code" + > + <polyline points="16 18 22 12 16 6"></polyline> + <polyline points="8 6 2 12 8 18"></polyline> + </svg> + </button> + </li> + {/* <li className={clsx({ active: selected === View.Contract })}> + <button + title="Smart Contract" + onClick={() => setSelected(View.Contract)} + > + <svg + xmlns="http://www.w3.org/2000/svg" + width="20" + height="20" + viewBox="0 0 24 24" + fill="none" + stroke="#86D79E" + strokeWidth="2" + strokeLinecap="round" + strokeLinejoin="round" + className="svg-icon feather feather-codesandbox" + > + <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path> + <polyline points="7.5 4.21 12 6.81 16.5 4.21"></polyline> + <polyline points="7.5 19.79 7.5 14.6 3 12"></polyline> + <polyline points="21 12 16.5 14.6 16.5 19.79"></polyline> + <polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline> + <line x1="12" y1="22.08" x2="12" y2="12"></line> + </svg> + </button> + </li> */} + <li className={clsx({ active: selected === View.Logs })}> + <button title="Logs" onClick={() => setSelected(View.Logs)}> + <svg + xmlns="http://www.w3.org/2000/svg" + width="20" + height="20" + viewBox="0 0 24 24" + fill="none" + stroke="#A7DF81" + strokeWidth="2" + strokeLinecap="round" + strokeLinejoin="round" + className="svg-icon feather feather-list" + > + <line x1="8" y1="6" x2="21" y2="6"></line> + <line x1="8" y1="12" x2="21" y2="12"></line> + <line x1="8" y1="18" x2="21" y2="18"></line> + <line x1="3" y1="6" x2="3.01" y2="6"></line> + <line x1="3" y1="12" x2="3.01" y2="12"></line> + <line x1="3" y1="18" x2="3.01" y2="18"></line> + </svg> + </button> + </li> + </ul> + </nav> + <div className="account"> + <div> + <span className="avatar"> + <img + src="https://uploads-ssl.webflow.com/5dea4f8b31edea3328b9a0f6/5e26f87654abf8eaf9235d7d_ethereum.png" + alt="" + /> + </span> + <div className="capitalize"> + <strong>{manifest.name}</strong> + <span>{blockchain}</span> + </div> + </div> + <a href="http://dappstarter.trycrypto.com" target="_blank" rel="noopener noreferrer"> + <i className="fa fa-cog text-xl"></i> + </a> + </div> + </header> + <main> + <div className="main-header"> + <h2> + {View[selected]} <span>Preview</span> + </h2> + <a className="full" target="_blank" href={viewLinks[selected]} rel="noopener noreferrer"> + <svg + xmlns="http://www.w3.org/2000/svg" + width="24" + height="24" + viewBox="0 0 24 24" + fill="none" + stroke="currentColor" + strokeWidth="2" + strokeLinecap="round" + strokeLinejoin="round" + className="svg-icon feather feather-arrow-up-right" + > + <line x1="7" y1="17" x2="17" y2="7"></line> + <polyline points="7 7 17 7 17 17"></polyline> + </svg> + </a> + </div> + <div + className={clsx('main-iframe', { hidden: selected !== View.Client })} + > + {dappReady[View.Client] ? ( + <iframe + src={viewLinks[View.Client]} + title="client" + height="100%" + width="100%" + ></iframe> + ) : ( + <div className="flex justify-center h-full items-center "> + <i className="fas fa-spinner fa-spin text-yellow-400 text-5xl"></i> + </div> + )} + </div> + <div + className={clsx('main-iframe', { + hidden: selected !== View.Connector, + })} + > + {dappReady[View.Connector] ? ( + <iframe + src={viewLinks[View.Connector]} + title="connector" + height="100%" + width="100%" + ></iframe> + ) : ( + <div className="flex justify-center h-full items-center "> + <i className="fas fa-spinner fa-spin text-yellow-400 text-5xl"></i> + </div> + )} + </div> + <div + className={clsx('main-iframe', { hidden: selected !== View.Server })} + > + {dappReady[View.Server] ? ( + <iframe + src={viewLinks[View.Server]} + title="server" + height="100%" + width="100%" + ></iframe> + ) : ( + <div className="flex justify-center h-full items-center "> + <i className="fas fa-spinner fa-spin text-yellow-400 text-5xl"></i> + </div> + )} + </div> + <div + className={clsx('main-iframe', { + hidden: selected !== View.Contract, + })} + > + <div className="flex justify-center h-full items-center "> + <i className="fas fa-hourglass-half text-yellow-400 text-5xl"> + Coming Soon + </i> + </div> + </div> + <div + className={clsx('main-iframe', { hidden: selected !== View.Logs })} + > + <div className="flex justify-center h-full items-center "> + <i className="fas fa-hourglass-half text-yellow-400 text-5xl"> + Coming Soon + </i> + </div> + </div> + + <div className="main-footer"> + <div className="docs"> + <a href="https://support.trycrypto.com/">Support Documentation</a> + </div> + <span className="footer-left">Powered by TryCrypto</span> + <span className="footer-right"> + <a href="https://www.trycrypto.com">www.trycrypto.com</a> + </span> + </div> + </main> + </div> + ) +} diff --git a/packages/frame/src/components/shared/.gitkeep b/packages/frame/src/components/shared/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/packages/frame/src/features/index.ts b/packages/frame/src/features/index.ts new file mode 100644 index 0000000..03498b9 --- /dev/null +++ b/packages/frame/src/features/index.ts @@ -0,0 +1,9 @@ +import { combineReducers } from '@reduxjs/toolkit' +import { configureStore } from '@reduxjs/toolkit' + +const rootReducer = combineReducers({}) + +const store = configureStore({ reducer: rootReducer }) + +export type RootState = ReturnType<typeof rootReducer> +export default store diff --git a/packages/frame/src/index.tsx b/packages/frame/src/index.tsx new file mode 100644 index 0000000..d17d732 --- /dev/null +++ b/packages/frame/src/index.tsx @@ -0,0 +1,17 @@ +import React from 'react' +import ReactDOM from 'react-dom' +import { Provider } from 'react-redux' +import { Router } from 'react-router-dom' +import App from '@/components/App' +import store from '@/features' +import history from '@/utils/history' +import './styles.css' + +ReactDOM.render( + <Provider store={store}> + <Router history={history}> + <App /> + </Router> + </Provider>, + document.getElementById('root'), +) diff --git a/packages/frame/src/react-app-env.d.ts b/packages/frame/src/react-app-env.d.ts new file mode 100644 index 0000000..6431bc5 --- /dev/null +++ b/packages/frame/src/react-app-env.d.ts @@ -0,0 +1 @@ +/// <reference types="react-scripts" /> diff --git a/packages/frame/src/setupTests.ts b/packages/frame/src/setupTests.ts new file mode 100644 index 0000000..2eb59b0 --- /dev/null +++ b/packages/frame/src/setupTests.ts @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom/extend-expect' diff --git a/packages/frame/src/styles.css b/packages/frame/src/styles.css new file mode 100644 index 0000000..1d49e8a --- /dev/null +++ b/packages/frame/src/styles.css @@ -0,0 +1,52147 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers. + */ + +body { + margin: 0; +} + +/** + * Render the `main` element consistently in IE. + */ + +main { + display: block; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Remove the gray background on active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove the border on images inside links in IE 10. + */ + +img { + border-style: none; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { /* 1 */ + text-transform: none; +} + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + vertical-align: baseline; +} + +/** + * Remove the default vertical scrollbar in IE 10+. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + +details { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Misc + ========================================================================== */ + +/** + * Add the correct display in IE 10+. + */ + +template { + display: none; +} + +/** + * Add the correct display in IE 10. + */ + +[hidden] { + display: none; +} + +/** + * Manually forked from SUIT CSS Base: https://github.com/suitcss/base + * A thin layer on top of normalize.css that provides a starting point more + * suitable for web applications. + */ + +/** + * Removes the default spacing and border for appropriate elements. + */ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +button { + background-color: transparent; + background-image: none; + padding: 0; +} + +/** + * Work around a Firefox/IE bug where the transparent `button` background + * results in a loss of the default `button` focus styles. + */ + +button:focus { + outline: 1px dotted; + outline: 5px auto -webkit-focus-ring-color; +} + +fieldset { + margin: 0; + padding: 0; +} + +ol, +ul { + list-style: none; + margin: 0; + padding: 0; +} + +/** + * Tailwind custom reset styles + */ + +/** + * 1. Use the user's configured `sans` font-family (with Tailwind's default + * sans-serif font stack as a fallback) as a sane default. + * 2. Use Tailwind's default "normal" line-height so the user isn't forced + * to override it to ensure consistency even when using the default theme. + */ + +html { + font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 1 */ + line-height: 1.5; /* 2 */ +} + +/** + * 1. Prevent padding and border from affecting element width. + * + * We used to set this in the html element and inherit from + * the parent element for everything else. This caused issues + * in shadow-dom-enhanced elements like <details> where the content + * is wrapped by a div with box-sizing set to `content-box`. + * + * https://github.com/mozdevs/cssremedy/issues/4 + * + * + * 2. Allow adding a border to an element by just adding a border-width. + * + * By default, the way the browser specifies that an element should have no + * border is by setting it's border-style to `none` in the user-agent + * stylesheet. + * + * In order to easily add borders to elements by just setting the `border-width` + * property, we change the default border-style for all elements to `solid`, and + * use border-width to hide them instead. This way our `border` utilities only + * need to set the `border-width` property instead of the entire `border` + * shorthand, making our border utilities much more straightforward to compose. + * + * https://github.com/tailwindcss/tailwindcss/pull/116 + */ + +*, +::before, +::after { + box-sizing: border-box; /* 1 */ + border-width: 0; /* 2 */ + border-style: solid; /* 2 */ + border-color: #e2e8f0; /* 2 */ +} + +/* + * Ensure horizontal rules are visible by default + */ + +hr { + border-top-width: 1px; +} + +/** + * Undo the `border-style: none` reset that Normalize applies to images so that + * our `border-{width}` utilities have the expected effect. + * + * The Normalize reset is unnecessary for us since we default the border-width + * to 0 on all elements. + * + * https://github.com/tailwindcss/tailwindcss/issues/362 + */ + +img { + border-style: solid; +} + +textarea { + resize: vertical; +} + +input::placeholder, +textarea::placeholder { + color: #a0aec0; +} + +button, +[role="button"] { + cursor: pointer; +} + +table { + border-collapse: collapse; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/** + * Reset links to optimize for opt-in styling instead of + * opt-out. + */ + +a { + color: inherit; + text-decoration: inherit; +} + +/** + * Reset form element properties that are easy to forget to + * style explicitly so you don't inadvertently introduce + * styles that deviate from your design system. These styles + * supplement a partial reset that is already applied by + * normalize.css. + */ + +button, +input, +optgroup, +select, +textarea { + padding: 0; + line-height: inherit; + color: inherit; +} + +/** + * Use the configured 'mono' font family for elements that + * are expected to be rendered with a monospace font, falling + * back to the system monospace stack if there is no configured + * 'mono' font family. + */ + +pre, +code, +kbd, +samp { + font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +/** + * Make replaced elements `display: block` by default as that's + * the behavior you want almost all of the time. Inspired by + * CSS Remedy, with `svg` added as well. + * + * https://github.com/mozdevs/cssremedy/issues/14 + */ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; + vertical-align: middle; +} + +/** + * Constrain images and videos to the parent width and preserve + * their instrinsic aspect ratio. + * + * https://github.com/mozdevs/cssremedy/issues/14 + */ + +img, +video { + max-width: 100%; + height: auto; +} + +.container { + width: 100%; +} + +@media (min-width: 640px) { + .container { + max-width: 640px; + } +} + +@media (min-width: 768px) { + .container { + max-width: 768px; + } +} + +@media (min-width: 1024px) { + .container { + max-width: 1024px; + } +} + +@media (min-width: 1280px) { + .container { + max-width: 1280px; + } +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; +} + +.not-sr-only { + position: static; + width: auto; + height: auto; + padding: 0; + margin: 0; + overflow: visible; + clip: auto; + white-space: normal; +} + +.focus\:sr-only:focus { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; +} + +.focus\:not-sr-only:focus { + position: static; + width: auto; + height: auto; + padding: 0; + margin: 0; + overflow: visible; + clip: auto; + white-space: normal; +} + +.appearance-none { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + +.bg-fixed { + background-attachment: fixed; +} + +.bg-local { + background-attachment: local; +} + +.bg-scroll { + background-attachment: scroll; +} + +.bg-transparent { + background-color: transparent; +} + +.bg-black { + background-color: #000; +} + +.bg-white { + background-color: #fff; +} + +.bg-gray-100 { + background-color: #f7fafc; +} + +.bg-gray-200 { + background-color: #edf2f7; +} + +.bg-gray-300 { + background-color: #e2e8f0; +} + +.bg-gray-400 { + background-color: #cbd5e0; +} + +.bg-gray-500 { + background-color: #a0aec0; +} + +.bg-gray-600 { + background-color: #718096; +} + +.bg-gray-700 { + background-color: #4a5568; +} + +.bg-gray-800 { + background-color: #2d3748; +} + +.bg-gray-900 { + background-color: #1a202c; +} + +.bg-red-100 { + background-color: #fff5f5; +} + +.bg-red-200 { + background-color: #fed7d7; +} + +.bg-red-300 { + background-color: #feb2b2; +} + +.bg-red-400 { + background-color: #fc8181; +} + +.bg-red-500 { + background-color: #f56565; +} + +.bg-red-600 { + background-color: #e53e3e; +} + +.bg-red-700 { + background-color: #c53030; +} + +.bg-red-800 { + background-color: #9b2c2c; +} + +.bg-red-900 { + background-color: #742a2a; +} + +.bg-orange-100 { + background-color: #fffaf0; +} + +.bg-orange-200 { + background-color: #feebc8; +} + +.bg-orange-300 { + background-color: #fbd38d; +} + +.bg-orange-400 { + background-color: #f6ad55; +} + +.bg-orange-500 { + background-color: #ed8936; +} + +.bg-orange-600 { + background-color: #dd6b20; +} + +.bg-orange-700 { + background-color: #c05621; +} + +.bg-orange-800 { + background-color: #9c4221; +} + +.bg-orange-900 { + background-color: #7b341e; +} + +.bg-yellow-100 { + background-color: #fffff0; +} + +.bg-yellow-200 { + background-color: #fefcbf; +} + +.bg-yellow-300 { + background-color: #faf089; +} + +.bg-yellow-400 { + background-color: #f6e05e; +} + +.bg-yellow-500 { + background-color: #ecc94b; +} + +.bg-yellow-600 { + background-color: #d69e2e; +} + +.bg-yellow-700 { + background-color: #b7791f; +} + +.bg-yellow-800 { + background-color: #975a16; +} + +.bg-yellow-900 { + background-color: #744210; +} + +.bg-green-100 { + background-color: #f0fff4; +} + +.bg-green-200 { + background-color: #c6f6d5; +} + +.bg-green-300 { + background-color: #9ae6b4; +} + +.bg-green-400 { + background-color: #68d391; +} + +.bg-green-500 { + background-color: #48bb78; +} + +.bg-green-600 { + background-color: #38a169; +} + +.bg-green-700 { + background-color: #2f855a; +} + +.bg-green-800 { + background-color: #276749; +} + +.bg-green-900 { + background-color: #22543d; +} + +.bg-teal-100 { + background-color: #e6fffa; +} + +.bg-teal-200 { + background-color: #b2f5ea; +} + +.bg-teal-300 { + background-color: #81e6d9; +} + +.bg-teal-400 { + background-color: #4fd1c5; +} + +.bg-teal-500 { + background-color: #38b2ac; +} + +.bg-teal-600 { + background-color: #319795; +} + +.bg-teal-700 { + background-color: #2c7a7b; +} + +.bg-teal-800 { + background-color: #285e61; +} + +.bg-teal-900 { + background-color: #234e52; +} + +.bg-blue-100 { + background-color: #ebf8ff; +} + +.bg-blue-200 { + background-color: #bee3f8; +} + +.bg-blue-300 { + background-color: #90cdf4; +} + +.bg-blue-400 { + background-color: #63b3ed; +} + +.bg-blue-500 { + background-color: #4299e1; +} + +.bg-blue-600 { + background-color: #3182ce; +} + +.bg-blue-700 { + background-color: #2b6cb0; +} + +.bg-blue-800 { + background-color: #2c5282; +} + +.bg-blue-900 { + background-color: #2a4365; +} + +.bg-indigo-100 { + background-color: #ebf4ff; +} + +.bg-indigo-200 { + background-color: #c3dafe; +} + +.bg-indigo-300 { + background-color: #a3bffa; +} + +.bg-indigo-400 { + background-color: #7f9cf5; +} + +.bg-indigo-500 { + background-color: #667eea; +} + +.bg-indigo-600 { + background-color: #5a67d8; +} + +.bg-indigo-700 { + background-color: #4c51bf; +} + +.bg-indigo-800 { + background-color: #434190; +} + +.bg-indigo-900 { + background-color: #3c366b; +} + +.bg-purple-100 { + background-color: #faf5ff; +} + +.bg-purple-200 { + background-color: #e9d8fd; +} + +.bg-purple-300 { + background-color: #d6bcfa; +} + +.bg-purple-400 { + background-color: #b794f4; +} + +.bg-purple-500 { + background-color: #9f7aea; +} + +.bg-purple-600 { + background-color: #805ad5; +} + +.bg-purple-700 { + background-color: #6b46c1; +} + +.bg-purple-800 { + background-color: #553c9a; +} + +.bg-purple-900 { + background-color: #44337a; +} + +.bg-pink-100 { + background-color: #fff5f7; +} + +.bg-pink-200 { + background-color: #fed7e2; +} + +.bg-pink-300 { + background-color: #fbb6ce; +} + +.bg-pink-400 { + background-color: #f687b3; +} + +.bg-pink-500 { + background-color: #ed64a6; +} + +.bg-pink-600 { + background-color: #d53f8c; +} + +.bg-pink-700 { + background-color: #b83280; +} + +.bg-pink-800 { + background-color: #97266d; +} + +.bg-pink-900 { + background-color: #702459; +} + +.hover\:bg-transparent:hover { + background-color: transparent; +} + +.hover\:bg-black:hover { + background-color: #000; +} + +.hover\:bg-white:hover { + background-color: #fff; +} + +.hover\:bg-gray-100:hover { + background-color: #f7fafc; +} + +.hover\:bg-gray-200:hover { + background-color: #edf2f7; +} + +.hover\:bg-gray-300:hover { + background-color: #e2e8f0; +} + +.hover\:bg-gray-400:hover { + background-color: #cbd5e0; +} + +.hover\:bg-gray-500:hover { + background-color: #a0aec0; +} + +.hover\:bg-gray-600:hover { + background-color: #718096; +} + +.hover\:bg-gray-700:hover { + background-color: #4a5568; +} + +.hover\:bg-gray-800:hover { + background-color: #2d3748; +} + +.hover\:bg-gray-900:hover { + background-color: #1a202c; +} + +.hover\:bg-red-100:hover { + background-color: #fff5f5; +} + +.hover\:bg-red-200:hover { + background-color: #fed7d7; +} + +.hover\:bg-red-300:hover { + background-color: #feb2b2; +} + +.hover\:bg-red-400:hover { + background-color: #fc8181; +} + +.hover\:bg-red-500:hover { + background-color: #f56565; +} + +.hover\:bg-red-600:hover { + background-color: #e53e3e; +} + +.hover\:bg-red-700:hover { + background-color: #c53030; +} + +.hover\:bg-red-800:hover { + background-color: #9b2c2c; +} + +.hover\:bg-red-900:hover { + background-color: #742a2a; +} + +.hover\:bg-orange-100:hover { + background-color: #fffaf0; +} + +.hover\:bg-orange-200:hover { + background-color: #feebc8; +} + +.hover\:bg-orange-300:hover { + background-color: #fbd38d; +} + +.hover\:bg-orange-400:hover { + background-color: #f6ad55; +} + +.hover\:bg-orange-500:hover { + background-color: #ed8936; +} + +.hover\:bg-orange-600:hover { + background-color: #dd6b20; +} + +.hover\:bg-orange-700:hover { + background-color: #c05621; +} + +.hover\:bg-orange-800:hover { + background-color: #9c4221; +} + +.hover\:bg-orange-900:hover { + background-color: #7b341e; +} + +.hover\:bg-yellow-100:hover { + background-color: #fffff0; +} + +.hover\:bg-yellow-200:hover { + background-color: #fefcbf; +} + +.hover\:bg-yellow-300:hover { + background-color: #faf089; +} + +.hover\:bg-yellow-400:hover { + background-color: #f6e05e; +} + +.hover\:bg-yellow-500:hover { + background-color: #ecc94b; +} + +.hover\:bg-yellow-600:hover { + background-color: #d69e2e; +} + +.hover\:bg-yellow-700:hover { + background-color: #b7791f; +} + +.hover\:bg-yellow-800:hover { + background-color: #975a16; +} + +.hover\:bg-yellow-900:hover { + background-color: #744210; +} + +.hover\:bg-green-100:hover { + background-color: #f0fff4; +} + +.hover\:bg-green-200:hover { + background-color: #c6f6d5; +} + +.hover\:bg-green-300:hover { + background-color: #9ae6b4; +} + +.hover\:bg-green-400:hover { + background-color: #68d391; +} + +.hover\:bg-green-500:hover { + background-color: #48bb78; +} + +.hover\:bg-green-600:hover { + background-color: #38a169; +} + +.hover\:bg-green-700:hover { + background-color: #2f855a; +} + +.hover\:bg-green-800:hover { + background-color: #276749; +} + +.hover\:bg-green-900:hover { + background-color: #22543d; +} + +.hover\:bg-teal-100:hover { + background-color: #e6fffa; +} + +.hover\:bg-teal-200:hover { + background-color: #b2f5ea; +} + +.hover\:bg-teal-300:hover { + background-color: #81e6d9; +} + +.hover\:bg-teal-400:hover { + background-color: #4fd1c5; +} + +.hover\:bg-teal-500:hover { + background-color: #38b2ac; +} + +.hover\:bg-teal-600:hover { + background-color: #319795; +} + +.hover\:bg-teal-700:hover { + background-color: #2c7a7b; +} + +.hover\:bg-teal-800:hover { + background-color: #285e61; +} + +.hover\:bg-teal-900:hover { + background-color: #234e52; +} + +.hover\:bg-blue-100:hover { + background-color: #ebf8ff; +} + +.hover\:bg-blue-200:hover { + background-color: #bee3f8; +} + +.hover\:bg-blue-300:hover { + background-color: #90cdf4; +} + +.hover\:bg-blue-400:hover { + background-color: #63b3ed; +} + +.hover\:bg-blue-500:hover { + background-color: #4299e1; +} + +.hover\:bg-blue-600:hover { + background-color: #3182ce; +} + +.hover\:bg-blue-700:hover { + background-color: #2b6cb0; +} + +.hover\:bg-blue-800:hover { + background-color: #2c5282; +} + +.hover\:bg-blue-900:hover { + background-color: #2a4365; +} + +.hover\:bg-indigo-100:hover { + background-color: #ebf4ff; +} + +.hover\:bg-indigo-200:hover { + background-color: #c3dafe; +} + +.hover\:bg-indigo-300:hover { + background-color: #a3bffa; +} + +.hover\:bg-indigo-400:hover { + background-color: #7f9cf5; +} + +.hover\:bg-indigo-500:hover { + background-color: #667eea; +} + +.hover\:bg-indigo-600:hover { + background-color: #5a67d8; +} + +.hover\:bg-indigo-700:hover { + background-color: #4c51bf; +} + +.hover\:bg-indigo-800:hover { + background-color: #434190; +} + +.hover\:bg-indigo-900:hover { + background-color: #3c366b; +} + +.hover\:bg-purple-100:hover { + background-color: #faf5ff; +} + +.hover\:bg-purple-200:hover { + background-color: #e9d8fd; +} + +.hover\:bg-purple-300:hover { + background-color: #d6bcfa; +} + +.hover\:bg-purple-400:hover { + background-color: #b794f4; +} + +.hover\:bg-purple-500:hover { + background-color: #9f7aea; +} + +.hover\:bg-purple-600:hover { + background-color: #805ad5; +} + +.hover\:bg-purple-700:hover { + background-color: #6b46c1; +} + +.hover\:bg-purple-800:hover { + background-color: #553c9a; +} + +.hover\:bg-purple-900:hover { + background-color: #44337a; +} + +.hover\:bg-pink-100:hover { + background-color: #fff5f7; +} + +.hover\:bg-pink-200:hover { + background-color: #fed7e2; +} + +.hover\:bg-pink-300:hover { + background-color: #fbb6ce; +} + +.hover\:bg-pink-400:hover { + background-color: #f687b3; +} + +.hover\:bg-pink-500:hover { + background-color: #ed64a6; +} + +.hover\:bg-pink-600:hover { + background-color: #d53f8c; +} + +.hover\:bg-pink-700:hover { + background-color: #b83280; +} + +.hover\:bg-pink-800:hover { + background-color: #97266d; +} + +.hover\:bg-pink-900:hover { + background-color: #702459; +} + +.focus\:bg-transparent:focus { + background-color: transparent; +} + +.focus\:bg-black:focus { + background-color: #000; +} + +.focus\:bg-white:focus { + background-color: #fff; +} + +.focus\:bg-gray-100:focus { + background-color: #f7fafc; +} + +.focus\:bg-gray-200:focus { + background-color: #edf2f7; +} + +.focus\:bg-gray-300:focus { + background-color: #e2e8f0; +} + +.focus\:bg-gray-400:focus { + background-color: #cbd5e0; +} + +.focus\:bg-gray-500:focus { + background-color: #a0aec0; +} + +.focus\:bg-gray-600:focus { + background-color: #718096; +} + +.focus\:bg-gray-700:focus { + background-color: #4a5568; +} + +.focus\:bg-gray-800:focus { + background-color: #2d3748; +} + +.focus\:bg-gray-900:focus { + background-color: #1a202c; +} + +.focus\:bg-red-100:focus { + background-color: #fff5f5; +} + +.focus\:bg-red-200:focus { + background-color: #fed7d7; +} + +.focus\:bg-red-300:focus { + background-color: #feb2b2; +} + +.focus\:bg-red-400:focus { + background-color: #fc8181; +} + +.focus\:bg-red-500:focus { + background-color: #f56565; +} + +.focus\:bg-red-600:focus { + background-color: #e53e3e; +} + +.focus\:bg-red-700:focus { + background-color: #c53030; +} + +.focus\:bg-red-800:focus { + background-color: #9b2c2c; +} + +.focus\:bg-red-900:focus { + background-color: #742a2a; +} + +.focus\:bg-orange-100:focus { + background-color: #fffaf0; +} + +.focus\:bg-orange-200:focus { + background-color: #feebc8; +} + +.focus\:bg-orange-300:focus { + background-color: #fbd38d; +} + +.focus\:bg-orange-400:focus { + background-color: #f6ad55; +} + +.focus\:bg-orange-500:focus { + background-color: #ed8936; +} + +.focus\:bg-orange-600:focus { + background-color: #dd6b20; +} + +.focus\:bg-orange-700:focus { + background-color: #c05621; +} + +.focus\:bg-orange-800:focus { + background-color: #9c4221; +} + +.focus\:bg-orange-900:focus { + background-color: #7b341e; +} + +.focus\:bg-yellow-100:focus { + background-color: #fffff0; +} + +.focus\:bg-yellow-200:focus { + background-color: #fefcbf; +} + +.focus\:bg-yellow-300:focus { + background-color: #faf089; +} + +.focus\:bg-yellow-400:focus { + background-color: #f6e05e; +} + +.focus\:bg-yellow-500:focus { + background-color: #ecc94b; +} + +.focus\:bg-yellow-600:focus { + background-color: #d69e2e; +} + +.focus\:bg-yellow-700:focus { + background-color: #b7791f; +} + +.focus\:bg-yellow-800:focus { + background-color: #975a16; +} + +.focus\:bg-yellow-900:focus { + background-color: #744210; +} + +.focus\:bg-green-100:focus { + background-color: #f0fff4; +} + +.focus\:bg-green-200:focus { + background-color: #c6f6d5; +} + +.focus\:bg-green-300:focus { + background-color: #9ae6b4; +} + +.focus\:bg-green-400:focus { + background-color: #68d391; +} + +.focus\:bg-green-500:focus { + background-color: #48bb78; +} + +.focus\:bg-green-600:focus { + background-color: #38a169; +} + +.focus\:bg-green-700:focus { + background-color: #2f855a; +} + +.focus\:bg-green-800:focus { + background-color: #276749; +} + +.focus\:bg-green-900:focus { + background-color: #22543d; +} + +.focus\:bg-teal-100:focus { + background-color: #e6fffa; +} + +.focus\:bg-teal-200:focus { + background-color: #b2f5ea; +} + +.focus\:bg-teal-300:focus { + background-color: #81e6d9; +} + +.focus\:bg-teal-400:focus { + background-color: #4fd1c5; +} + +.focus\:bg-teal-500:focus { + background-color: #38b2ac; +} + +.focus\:bg-teal-600:focus { + background-color: #319795; +} + +.focus\:bg-teal-700:focus { + background-color: #2c7a7b; +} + +.focus\:bg-teal-800:focus { + background-color: #285e61; +} + +.focus\:bg-teal-900:focus { + background-color: #234e52; +} + +.focus\:bg-blue-100:focus { + background-color: #ebf8ff; +} + +.focus\:bg-blue-200:focus { + background-color: #bee3f8; +} + +.focus\:bg-blue-300:focus { + background-color: #90cdf4; +} + +.focus\:bg-blue-400:focus { + background-color: #63b3ed; +} + +.focus\:bg-blue-500:focus { + background-color: #4299e1; +} + +.focus\:bg-blue-600:focus { + background-color: #3182ce; +} + +.focus\:bg-blue-700:focus { + background-color: #2b6cb0; +} + +.focus\:bg-blue-800:focus { + background-color: #2c5282; +} + +.focus\:bg-blue-900:focus { + background-color: #2a4365; +} + +.focus\:bg-indigo-100:focus { + background-color: #ebf4ff; +} + +.focus\:bg-indigo-200:focus { + background-color: #c3dafe; +} + +.focus\:bg-indigo-300:focus { + background-color: #a3bffa; +} + +.focus\:bg-indigo-400:focus { + background-color: #7f9cf5; +} + +.focus\:bg-indigo-500:focus { + background-color: #667eea; +} + +.focus\:bg-indigo-600:focus { + background-color: #5a67d8; +} + +.focus\:bg-indigo-700:focus { + background-color: #4c51bf; +} + +.focus\:bg-indigo-800:focus { + background-color: #434190; +} + +.focus\:bg-indigo-900:focus { + background-color: #3c366b; +} + +.focus\:bg-purple-100:focus { + background-color: #faf5ff; +} + +.focus\:bg-purple-200:focus { + background-color: #e9d8fd; +} + +.focus\:bg-purple-300:focus { + background-color: #d6bcfa; +} + +.focus\:bg-purple-400:focus { + background-color: #b794f4; +} + +.focus\:bg-purple-500:focus { + background-color: #9f7aea; +} + +.focus\:bg-purple-600:focus { + background-color: #805ad5; +} + +.focus\:bg-purple-700:focus { + background-color: #6b46c1; +} + +.focus\:bg-purple-800:focus { + background-color: #553c9a; +} + +.focus\:bg-purple-900:focus { + background-color: #44337a; +} + +.focus\:bg-pink-100:focus { + background-color: #fff5f7; +} + +.focus\:bg-pink-200:focus { + background-color: #fed7e2; +} + +.focus\:bg-pink-300:focus { + background-color: #fbb6ce; +} + +.focus\:bg-pink-400:focus { + background-color: #f687b3; +} + +.focus\:bg-pink-500:focus { + background-color: #ed64a6; +} + +.focus\:bg-pink-600:focus { + background-color: #d53f8c; +} + +.focus\:bg-pink-700:focus { + background-color: #b83280; +} + +.focus\:bg-pink-800:focus { + background-color: #97266d; +} + +.focus\:bg-pink-900:focus { + background-color: #702459; +} + +.bg-bottom { + background-position: bottom; +} + +.bg-center { + background-position: center; +} + +.bg-left { + background-position: left; +} + +.bg-left-bottom { + background-position: left bottom; +} + +.bg-left-top { + background-position: left top; +} + +.bg-right { + background-position: right; +} + +.bg-right-bottom { + background-position: right bottom; +} + +.bg-right-top { + background-position: right top; +} + +.bg-top { + background-position: top; +} + +.bg-repeat { + background-repeat: repeat; +} + +.bg-no-repeat { + background-repeat: no-repeat; +} + +.bg-repeat-x { + background-repeat: repeat-x; +} + +.bg-repeat-y { + background-repeat: repeat-y; +} + +.bg-repeat-round { + background-repeat: round; +} + +.bg-repeat-space { + background-repeat: space; +} + +.bg-auto { + background-size: auto; +} + +.bg-cover { + background-size: cover; +} + +.bg-contain { + background-size: contain; +} + +.border-collapse { + border-collapse: collapse; +} + +.border-separate { + border-collapse: separate; +} + +.border-transparent { + border-color: transparent; +} + +.border-black { + border-color: #000; +} + +.border-white { + border-color: #fff; +} + +.border-gray-100 { + border-color: #f7fafc; +} + +.border-gray-200 { + border-color: #edf2f7; +} + +.border-gray-300 { + border-color: #e2e8f0; +} + +.border-gray-400 { + border-color: #cbd5e0; +} + +.border-gray-500 { + border-color: #a0aec0; +} + +.border-gray-600 { + border-color: #718096; +} + +.border-gray-700 { + border-color: #4a5568; +} + +.border-gray-800 { + border-color: #2d3748; +} + +.border-gray-900 { + border-color: #1a202c; +} + +.border-red-100 { + border-color: #fff5f5; +} + +.border-red-200 { + border-color: #fed7d7; +} + +.border-red-300 { + border-color: #feb2b2; +} + +.border-red-400 { + border-color: #fc8181; +} + +.border-red-500 { + border-color: #f56565; +} + +.border-red-600 { + border-color: #e53e3e; +} + +.border-red-700 { + border-color: #c53030; +} + +.border-red-800 { + border-color: #9b2c2c; +} + +.border-red-900 { + border-color: #742a2a; +} + +.border-orange-100 { + border-color: #fffaf0; +} + +.border-orange-200 { + border-color: #feebc8; +} + +.border-orange-300 { + border-color: #fbd38d; +} + +.border-orange-400 { + border-color: #f6ad55; +} + +.border-orange-500 { + border-color: #ed8936; +} + +.border-orange-600 { + border-color: #dd6b20; +} + +.border-orange-700 { + border-color: #c05621; +} + +.border-orange-800 { + border-color: #9c4221; +} + +.border-orange-900 { + border-color: #7b341e; +} + +.border-yellow-100 { + border-color: #fffff0; +} + +.border-yellow-200 { + border-color: #fefcbf; +} + +.border-yellow-300 { + border-color: #faf089; +} + +.border-yellow-400 { + border-color: #f6e05e; +} + +.border-yellow-500 { + border-color: #ecc94b; +} + +.border-yellow-600 { + border-color: #d69e2e; +} + +.border-yellow-700 { + border-color: #b7791f; +} + +.border-yellow-800 { + border-color: #975a16; +} + +.border-yellow-900 { + border-color: #744210; +} + +.border-green-100 { + border-color: #f0fff4; +} + +.border-green-200 { + border-color: #c6f6d5; +} + +.border-green-300 { + border-color: #9ae6b4; +} + +.border-green-400 { + border-color: #68d391; +} + +.border-green-500 { + border-color: #48bb78; +} + +.border-green-600 { + border-color: #38a169; +} + +.border-green-700 { + border-color: #2f855a; +} + +.border-green-800 { + border-color: #276749; +} + +.border-green-900 { + border-color: #22543d; +} + +.border-teal-100 { + border-color: #e6fffa; +} + +.border-teal-200 { + border-color: #b2f5ea; +} + +.border-teal-300 { + border-color: #81e6d9; +} + +.border-teal-400 { + border-color: #4fd1c5; +} + +.border-teal-500 { + border-color: #38b2ac; +} + +.border-teal-600 { + border-color: #319795; +} + +.border-teal-700 { + border-color: #2c7a7b; +} + +.border-teal-800 { + border-color: #285e61; +} + +.border-teal-900 { + border-color: #234e52; +} + +.border-blue-100 { + border-color: #ebf8ff; +} + +.border-blue-200 { + border-color: #bee3f8; +} + +.border-blue-300 { + border-color: #90cdf4; +} + +.border-blue-400 { + border-color: #63b3ed; +} + +.border-blue-500 { + border-color: #4299e1; +} + +.border-blue-600 { + border-color: #3182ce; +} + +.border-blue-700 { + border-color: #2b6cb0; +} + +.border-blue-800 { + border-color: #2c5282; +} + +.border-blue-900 { + border-color: #2a4365; +} + +.border-indigo-100 { + border-color: #ebf4ff; +} + +.border-indigo-200 { + border-color: #c3dafe; +} + +.border-indigo-300 { + border-color: #a3bffa; +} + +.border-indigo-400 { + border-color: #7f9cf5; +} + +.border-indigo-500 { + border-color: #667eea; +} + +.border-indigo-600 { + border-color: #5a67d8; +} + +.border-indigo-700 { + border-color: #4c51bf; +} + +.border-indigo-800 { + border-color: #434190; +} + +.border-indigo-900 { + border-color: #3c366b; +} + +.border-purple-100 { + border-color: #faf5ff; +} + +.border-purple-200 { + border-color: #e9d8fd; +} + +.border-purple-300 { + border-color: #d6bcfa; +} + +.border-purple-400 { + border-color: #b794f4; +} + +.border-purple-500 { + border-color: #9f7aea; +} + +.border-purple-600 { + border-color: #805ad5; +} + +.border-purple-700 { + border-color: #6b46c1; +} + +.border-purple-800 { + border-color: #553c9a; +} + +.border-purple-900 { + border-color: #44337a; +} + +.border-pink-100 { + border-color: #fff5f7; +} + +.border-pink-200 { + border-color: #fed7e2; +} + +.border-pink-300 { + border-color: #fbb6ce; +} + +.border-pink-400 { + border-color: #f687b3; +} + +.border-pink-500 { + border-color: #ed64a6; +} + +.border-pink-600 { + border-color: #d53f8c; +} + +.border-pink-700 { + border-color: #b83280; +} + +.border-pink-800 { + border-color: #97266d; +} + +.border-pink-900 { + border-color: #702459; +} + +.hover\:border-transparent:hover { + border-color: transparent; +} + +.hover\:border-black:hover { + border-color: #000; +} + +.hover\:border-white:hover { + border-color: #fff; +} + +.hover\:border-gray-100:hover { + border-color: #f7fafc; +} + +.hover\:border-gray-200:hover { + border-color: #edf2f7; +} + +.hover\:border-gray-300:hover { + border-color: #e2e8f0; +} + +.hover\:border-gray-400:hover { + border-color: #cbd5e0; +} + +.hover\:border-gray-500:hover { + border-color: #a0aec0; +} + +.hover\:border-gray-600:hover { + border-color: #718096; +} + +.hover\:border-gray-700:hover { + border-color: #4a5568; +} + +.hover\:border-gray-800:hover { + border-color: #2d3748; +} + +.hover\:border-gray-900:hover { + border-color: #1a202c; +} + +.hover\:border-red-100:hover { + border-color: #fff5f5; +} + +.hover\:border-red-200:hover { + border-color: #fed7d7; +} + +.hover\:border-red-300:hover { + border-color: #feb2b2; +} + +.hover\:border-red-400:hover { + border-color: #fc8181; +} + +.hover\:border-red-500:hover { + border-color: #f56565; +} + +.hover\:border-red-600:hover { + border-color: #e53e3e; +} + +.hover\:border-red-700:hover { + border-color: #c53030; +} + +.hover\:border-red-800:hover { + border-color: #9b2c2c; +} + +.hover\:border-red-900:hover { + border-color: #742a2a; +} + +.hover\:border-orange-100:hover { + border-color: #fffaf0; +} + +.hover\:border-orange-200:hover { + border-color: #feebc8; +} + +.hover\:border-orange-300:hover { + border-color: #fbd38d; +} + +.hover\:border-orange-400:hover { + border-color: #f6ad55; +} + +.hover\:border-orange-500:hover { + border-color: #ed8936; +} + +.hover\:border-orange-600:hover { + border-color: #dd6b20; +} + +.hover\:border-orange-700:hover { + border-color: #c05621; +} + +.hover\:border-orange-800:hover { + border-color: #9c4221; +} + +.hover\:border-orange-900:hover { + border-color: #7b341e; +} + +.hover\:border-yellow-100:hover { + border-color: #fffff0; +} + +.hover\:border-yellow-200:hover { + border-color: #fefcbf; +} + +.hover\:border-yellow-300:hover { + border-color: #faf089; +} + +.hover\:border-yellow-400:hover { + border-color: #f6e05e; +} + +.hover\:border-yellow-500:hover { + border-color: #ecc94b; +} + +.hover\:border-yellow-600:hover { + border-color: #d69e2e; +} + +.hover\:border-yellow-700:hover { + border-color: #b7791f; +} + +.hover\:border-yellow-800:hover { + border-color: #975a16; +} + +.hover\:border-yellow-900:hover { + border-color: #744210; +} + +.hover\:border-green-100:hover { + border-color: #f0fff4; +} + +.hover\:border-green-200:hover { + border-color: #c6f6d5; +} + +.hover\:border-green-300:hover { + border-color: #9ae6b4; +} + +.hover\:border-green-400:hover { + border-color: #68d391; +} + +.hover\:border-green-500:hover { + border-color: #48bb78; +} + +.hover\:border-green-600:hover { + border-color: #38a169; +} + +.hover\:border-green-700:hover { + border-color: #2f855a; +} + +.hover\:border-green-800:hover { + border-color: #276749; +} + +.hover\:border-green-900:hover { + border-color: #22543d; +} + +.hover\:border-teal-100:hover { + border-color: #e6fffa; +} + +.hover\:border-teal-200:hover { + border-color: #b2f5ea; +} + +.hover\:border-teal-300:hover { + border-color: #81e6d9; +} + +.hover\:border-teal-400:hover { + border-color: #4fd1c5; +} + +.hover\:border-teal-500:hover { + border-color: #38b2ac; +} + +.hover\:border-teal-600:hover { + border-color: #319795; +} + +.hover\:border-teal-700:hover { + border-color: #2c7a7b; +} + +.hover\:border-teal-800:hover { + border-color: #285e61; +} + +.hover\:border-teal-900:hover { + border-color: #234e52; +} + +.hover\:border-blue-100:hover { + border-color: #ebf8ff; +} + +.hover\:border-blue-200:hover { + border-color: #bee3f8; +} + +.hover\:border-blue-300:hover { + border-color: #90cdf4; +} + +.hover\:border-blue-400:hover { + border-color: #63b3ed; +} + +.hover\:border-blue-500:hover { + border-color: #4299e1; +} + +.hover\:border-blue-600:hover { + border-color: #3182ce; +} + +.hover\:border-blue-700:hover { + border-color: #2b6cb0; +} + +.hover\:border-blue-800:hover { + border-color: #2c5282; +} + +.hover\:border-blue-900:hover { + border-color: #2a4365; +} + +.hover\:border-indigo-100:hover { + border-color: #ebf4ff; +} + +.hover\:border-indigo-200:hover { + border-color: #c3dafe; +} + +.hover\:border-indigo-300:hover { + border-color: #a3bffa; +} + +.hover\:border-indigo-400:hover { + border-color: #7f9cf5; +} + +.hover\:border-indigo-500:hover { + border-color: #667eea; +} + +.hover\:border-indigo-600:hover { + border-color: #5a67d8; +} + +.hover\:border-indigo-700:hover { + border-color: #4c51bf; +} + +.hover\:border-indigo-800:hover { + border-color: #434190; +} + +.hover\:border-indigo-900:hover { + border-color: #3c366b; +} + +.hover\:border-purple-100:hover { + border-color: #faf5ff; +} + +.hover\:border-purple-200:hover { + border-color: #e9d8fd; +} + +.hover\:border-purple-300:hover { + border-color: #d6bcfa; +} + +.hover\:border-purple-400:hover { + border-color: #b794f4; +} + +.hover\:border-purple-500:hover { + border-color: #9f7aea; +} + +.hover\:border-purple-600:hover { + border-color: #805ad5; +} + +.hover\:border-purple-700:hover { + border-color: #6b46c1; +} + +.hover\:border-purple-800:hover { + border-color: #553c9a; +} + +.hover\:border-purple-900:hover { + border-color: #44337a; +} + +.hover\:border-pink-100:hover { + border-color: #fff5f7; +} + +.hover\:border-pink-200:hover { + border-color: #fed7e2; +} + +.hover\:border-pink-300:hover { + border-color: #fbb6ce; +} + +.hover\:border-pink-400:hover { + border-color: #f687b3; +} + +.hover\:border-pink-500:hover { + border-color: #ed64a6; +} + +.hover\:border-pink-600:hover { + border-color: #d53f8c; +} + +.hover\:border-pink-700:hover { + border-color: #b83280; +} + +.hover\:border-pink-800:hover { + border-color: #97266d; +} + +.hover\:border-pink-900:hover { + border-color: #702459; +} + +.focus\:border-transparent:focus { + border-color: transparent; +} + +.focus\:border-black:focus { + border-color: #000; +} + +.focus\:border-white:focus { + border-color: #fff; +} + +.focus\:border-gray-100:focus { + border-color: #f7fafc; +} + +.focus\:border-gray-200:focus { + border-color: #edf2f7; +} + +.focus\:border-gray-300:focus { + border-color: #e2e8f0; +} + +.focus\:border-gray-400:focus { + border-color: #cbd5e0; +} + +.focus\:border-gray-500:focus { + border-color: #a0aec0; +} + +.focus\:border-gray-600:focus { + border-color: #718096; +} + +.focus\:border-gray-700:focus { + border-color: #4a5568; +} + +.focus\:border-gray-800:focus { + border-color: #2d3748; +} + +.focus\:border-gray-900:focus { + border-color: #1a202c; +} + +.focus\:border-red-100:focus { + border-color: #fff5f5; +} + +.focus\:border-red-200:focus { + border-color: #fed7d7; +} + +.focus\:border-red-300:focus { + border-color: #feb2b2; +} + +.focus\:border-red-400:focus { + border-color: #fc8181; +} + +.focus\:border-red-500:focus { + border-color: #f56565; +} + +.focus\:border-red-600:focus { + border-color: #e53e3e; +} + +.focus\:border-red-700:focus { + border-color: #c53030; +} + +.focus\:border-red-800:focus { + border-color: #9b2c2c; +} + +.focus\:border-red-900:focus { + border-color: #742a2a; +} + +.focus\:border-orange-100:focus { + border-color: #fffaf0; +} + +.focus\:border-orange-200:focus { + border-color: #feebc8; +} + +.focus\:border-orange-300:focus { + border-color: #fbd38d; +} + +.focus\:border-orange-400:focus { + border-color: #f6ad55; +} + +.focus\:border-orange-500:focus { + border-color: #ed8936; +} + +.focus\:border-orange-600:focus { + border-color: #dd6b20; +} + +.focus\:border-orange-700:focus { + border-color: #c05621; +} + +.focus\:border-orange-800:focus { + border-color: #9c4221; +} + +.focus\:border-orange-900:focus { + border-color: #7b341e; +} + +.focus\:border-yellow-100:focus { + border-color: #fffff0; +} + +.focus\:border-yellow-200:focus { + border-color: #fefcbf; +} + +.focus\:border-yellow-300:focus { + border-color: #faf089; +} + +.focus\:border-yellow-400:focus { + border-color: #f6e05e; +} + +.focus\:border-yellow-500:focus { + border-color: #ecc94b; +} + +.focus\:border-yellow-600:focus { + border-color: #d69e2e; +} + +.focus\:border-yellow-700:focus { + border-color: #b7791f; +} + +.focus\:border-yellow-800:focus { + border-color: #975a16; +} + +.focus\:border-yellow-900:focus { + border-color: #744210; +} + +.focus\:border-green-100:focus { + border-color: #f0fff4; +} + +.focus\:border-green-200:focus { + border-color: #c6f6d5; +} + +.focus\:border-green-300:focus { + border-color: #9ae6b4; +} + +.focus\:border-green-400:focus { + border-color: #68d391; +} + +.focus\:border-green-500:focus { + border-color: #48bb78; +} + +.focus\:border-green-600:focus { + border-color: #38a169; +} + +.focus\:border-green-700:focus { + border-color: #2f855a; +} + +.focus\:border-green-800:focus { + border-color: #276749; +} + +.focus\:border-green-900:focus { + border-color: #22543d; +} + +.focus\:border-teal-100:focus { + border-color: #e6fffa; +} + +.focus\:border-teal-200:focus { + border-color: #b2f5ea; +} + +.focus\:border-teal-300:focus { + border-color: #81e6d9; +} + +.focus\:border-teal-400:focus { + border-color: #4fd1c5; +} + +.focus\:border-teal-500:focus { + border-color: #38b2ac; +} + +.focus\:border-teal-600:focus { + border-color: #319795; +} + +.focus\:border-teal-700:focus { + border-color: #2c7a7b; +} + +.focus\:border-teal-800:focus { + border-color: #285e61; +} + +.focus\:border-teal-900:focus { + border-color: #234e52; +} + +.focus\:border-blue-100:focus { + border-color: #ebf8ff; +} + +.focus\:border-blue-200:focus { + border-color: #bee3f8; +} + +.focus\:border-blue-300:focus { + border-color: #90cdf4; +} + +.focus\:border-blue-400:focus { + border-color: #63b3ed; +} + +.focus\:border-blue-500:focus { + border-color: #4299e1; +} + +.focus\:border-blue-600:focus { + border-color: #3182ce; +} + +.focus\:border-blue-700:focus { + border-color: #2b6cb0; +} + +.focus\:border-blue-800:focus { + border-color: #2c5282; +} + +.focus\:border-blue-900:focus { + border-color: #2a4365; +} + +.focus\:border-indigo-100:focus { + border-color: #ebf4ff; +} + +.focus\:border-indigo-200:focus { + border-color: #c3dafe; +} + +.focus\:border-indigo-300:focus { + border-color: #a3bffa; +} + +.focus\:border-indigo-400:focus { + border-color: #7f9cf5; +} + +.focus\:border-indigo-500:focus { + border-color: #667eea; +} + +.focus\:border-indigo-600:focus { + border-color: #5a67d8; +} + +.focus\:border-indigo-700:focus { + border-color: #4c51bf; +} + +.focus\:border-indigo-800:focus { + border-color: #434190; +} + +.focus\:border-indigo-900:focus { + border-color: #3c366b; +} + +.focus\:border-purple-100:focus { + border-color: #faf5ff; +} + +.focus\:border-purple-200:focus { + border-color: #e9d8fd; +} + +.focus\:border-purple-300:focus { + border-color: #d6bcfa; +} + +.focus\:border-purple-400:focus { + border-color: #b794f4; +} + +.focus\:border-purple-500:focus { + border-color: #9f7aea; +} + +.focus\:border-purple-600:focus { + border-color: #805ad5; +} + +.focus\:border-purple-700:focus { + border-color: #6b46c1; +} + +.focus\:border-purple-800:focus { + border-color: #553c9a; +} + +.focus\:border-purple-900:focus { + border-color: #44337a; +} + +.focus\:border-pink-100:focus { + border-color: #fff5f7; +} + +.focus\:border-pink-200:focus { + border-color: #fed7e2; +} + +.focus\:border-pink-300:focus { + border-color: #fbb6ce; +} + +.focus\:border-pink-400:focus { + border-color: #f687b3; +} + +.focus\:border-pink-500:focus { + border-color: #ed64a6; +} + +.focus\:border-pink-600:focus { + border-color: #d53f8c; +} + +.focus\:border-pink-700:focus { + border-color: #b83280; +} + +.focus\:border-pink-800:focus { + border-color: #97266d; +} + +.focus\:border-pink-900:focus { + border-color: #702459; +} + +.rounded-none { + border-radius: 0; +} + +.rounded-sm { + border-radius: 0.125rem; +} + +.rounded { + border-radius: 0.25rem; +} + +.rounded-md { + border-radius: 0.375rem; +} + +.rounded-lg { + border-radius: 0.5rem; +} + +.rounded-full { + border-radius: 9999px; +} + +.rounded-t-none { + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.rounded-r-none { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.rounded-b-none { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +.rounded-l-none { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.rounded-t-sm { + border-top-left-radius: 0.125rem; + border-top-right-radius: 0.125rem; +} + +.rounded-r-sm { + border-top-right-radius: 0.125rem; + border-bottom-right-radius: 0.125rem; +} + +.rounded-b-sm { + border-bottom-right-radius: 0.125rem; + border-bottom-left-radius: 0.125rem; +} + +.rounded-l-sm { + border-top-left-radius: 0.125rem; + border-bottom-left-radius: 0.125rem; +} + +.rounded-t { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} + +.rounded-r { + border-top-right-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; +} + +.rounded-b { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} + +.rounded-l { + border-top-left-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} + +.rounded-t-md { + border-top-left-radius: 0.375rem; + border-top-right-radius: 0.375rem; +} + +.rounded-r-md { + border-top-right-radius: 0.375rem; + border-bottom-right-radius: 0.375rem; +} + +.rounded-b-md { + border-bottom-right-radius: 0.375rem; + border-bottom-left-radius: 0.375rem; +} + +.rounded-l-md { + border-top-left-radius: 0.375rem; + border-bottom-left-radius: 0.375rem; +} + +.rounded-t-lg { + border-top-left-radius: 0.5rem; + border-top-right-radius: 0.5rem; +} + +.rounded-r-lg { + border-top-right-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; +} + +.rounded-b-lg { + border-bottom-right-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; +} + +.rounded-l-lg { + border-top-left-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; +} + +.rounded-t-full { + border-top-left-radius: 9999px; + border-top-right-radius: 9999px; +} + +.rounded-r-full { + border-top-right-radius: 9999px; + border-bottom-right-radius: 9999px; +} + +.rounded-b-full { + border-bottom-right-radius: 9999px; + border-bottom-left-radius: 9999px; +} + +.rounded-l-full { + border-top-left-radius: 9999px; + border-bottom-left-radius: 9999px; +} + +.rounded-tl-none { + border-top-left-radius: 0; +} + +.rounded-tr-none { + border-top-right-radius: 0; +} + +.rounded-br-none { + border-bottom-right-radius: 0; +} + +.rounded-bl-none { + border-bottom-left-radius: 0; +} + +.rounded-tl-sm { + border-top-left-radius: 0.125rem; +} + +.rounded-tr-sm { + border-top-right-radius: 0.125rem; +} + +.rounded-br-sm { + border-bottom-right-radius: 0.125rem; +} + +.rounded-bl-sm { + border-bottom-left-radius: 0.125rem; +} + +.rounded-tl { + border-top-left-radius: 0.25rem; +} + +.rounded-tr { + border-top-right-radius: 0.25rem; +} + +.rounded-br { + border-bottom-right-radius: 0.25rem; +} + +.rounded-bl { + border-bottom-left-radius: 0.25rem; +} + +.rounded-tl-md { + border-top-left-radius: 0.375rem; +} + +.rounded-tr-md { + border-top-right-radius: 0.375rem; +} + +.rounded-br-md { + border-bottom-right-radius: 0.375rem; +} + +.rounded-bl-md { + border-bottom-left-radius: 0.375rem; +} + +.rounded-tl-lg { + border-top-left-radius: 0.5rem; +} + +.rounded-tr-lg { + border-top-right-radius: 0.5rem; +} + +.rounded-br-lg { + border-bottom-right-radius: 0.5rem; +} + +.rounded-bl-lg { + border-bottom-left-radius: 0.5rem; +} + +.rounded-tl-full { + border-top-left-radius: 9999px; +} + +.rounded-tr-full { + border-top-right-radius: 9999px; +} + +.rounded-br-full { + border-bottom-right-radius: 9999px; +} + +.rounded-bl-full { + border-bottom-left-radius: 9999px; +} + +.border-solid { + border-style: solid; +} + +.border-dashed { + border-style: dashed; +} + +.border-dotted { + border-style: dotted; +} + +.border-double { + border-style: double; +} + +.border-none { + border-style: none; +} + +.border-0 { + border-width: 0; +} + +.border-2 { + border-width: 2px; +} + +.border-4 { + border-width: 4px; +} + +.border-8 { + border-width: 8px; +} + +.border { + border-width: 1px; +} + +.border-t-0 { + border-top-width: 0; +} + +.border-r-0 { + border-right-width: 0; +} + +.border-b-0 { + border-bottom-width: 0; +} + +.border-l-0 { + border-left-width: 0; +} + +.border-t-2 { + border-top-width: 2px; +} + +.border-r-2 { + border-right-width: 2px; +} + +.border-b-2 { + border-bottom-width: 2px; +} + +.border-l-2 { + border-left-width: 2px; +} + +.border-t-4 { + border-top-width: 4px; +} + +.border-r-4 { + border-right-width: 4px; +} + +.border-b-4 { + border-bottom-width: 4px; +} + +.border-l-4 { + border-left-width: 4px; +} + +.border-t-8 { + border-top-width: 8px; +} + +.border-r-8 { + border-right-width: 8px; +} + +.border-b-8 { + border-bottom-width: 8px; +} + +.border-l-8 { + border-left-width: 8px; +} + +.border-t { + border-top-width: 1px; +} + +.border-r { + border-right-width: 1px; +} + +.border-b { + border-bottom-width: 1px; +} + +.border-l { + border-left-width: 1px; +} + +.box-border { + box-sizing: border-box; +} + +.box-content { + box-sizing: content-box; +} + +.cursor-auto { + cursor: auto; +} + +.cursor-default { + cursor: default; +} + +.cursor-pointer { + cursor: pointer; +} + +.cursor-wait { + cursor: wait; +} + +.cursor-text { + cursor: text; +} + +.cursor-move { + cursor: move; +} + +.cursor-not-allowed { + cursor: not-allowed; +} + +.block { + display: block; +} + +.inline-block { + display: inline-block; +} + +.inline { + display: inline; +} + +.flex { + display: flex; +} + +.inline-flex { + display: inline-flex; +} + +.grid { + display: grid; +} + +.table { + display: table; +} + +.table-caption { + display: table-caption; +} + +.table-cell { + display: table-cell; +} + +.table-column { + display: table-column; +} + +.table-column-group { + display: table-column-group; +} + +.table-footer-group { + display: table-footer-group; +} + +.table-header-group { + display: table-header-group; +} + +.table-row-group { + display: table-row-group; +} + +.table-row { + display: table-row; +} + +.hidden { + display: none; +} + +.flex-row { + flex-direction: row; +} + +.flex-row-reverse { + flex-direction: row-reverse; +} + +.flex-col { + flex-direction: column; +} + +.flex-col-reverse { + flex-direction: column-reverse; +} + +.flex-wrap { + flex-wrap: wrap; +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse; +} + +.flex-no-wrap { + flex-wrap: nowrap; +} + +.items-start { + align-items: flex-start; +} + +.items-end { + align-items: flex-end; +} + +.items-center { + align-items: center; +} + +.items-baseline { + align-items: baseline; +} + +.items-stretch { + align-items: stretch; +} + +.self-auto { + align-self: auto; +} + +.self-start { + align-self: flex-start; +} + +.self-end { + align-self: flex-end; +} + +.self-center { + align-self: center; +} + +.self-stretch { + align-self: stretch; +} + +.justify-start { + justify-content: flex-start; +} + +.justify-end { + justify-content: flex-end; +} + +.justify-center { + justify-content: center; +} + +.justify-between { + justify-content: space-between; +} + +.justify-around { + justify-content: space-around; +} + +.justify-evenly { + justify-content: space-evenly; +} + +.content-center { + align-content: center; +} + +.content-start { + align-content: flex-start; +} + +.content-end { + align-content: flex-end; +} + +.content-between { + align-content: space-between; +} + +.content-around { + align-content: space-around; +} + +.flex-1 { + flex: 1 1 0%; +} + +.flex-auto { + flex: 1 1 auto; +} + +.flex-initial { + flex: 0 1 auto; +} + +.flex-none { + flex: none; +} + +.flex-grow-0 { + flex-grow: 0; +} + +.flex-grow { + flex-grow: 1; +} + +.flex-shrink-0 { + flex-shrink: 0; +} + +.flex-shrink { + flex-shrink: 1; +} + +.order-1 { + order: 1; +} + +.order-2 { + order: 2; +} + +.order-3 { + order: 3; +} + +.order-4 { + order: 4; +} + +.order-5 { + order: 5; +} + +.order-6 { + order: 6; +} + +.order-7 { + order: 7; +} + +.order-8 { + order: 8; +} + +.order-9 { + order: 9; +} + +.order-10 { + order: 10; +} + +.order-11 { + order: 11; +} + +.order-12 { + order: 12; +} + +.order-first { + order: -9999; +} + +.order-last { + order: 9999; +} + +.order-none { + order: 0; +} + +.float-right { + float: right; +} + +.float-left { + float: left; +} + +.float-none { + float: none; +} + +.clearfix:after { + content: ""; + display: table; + clear: both; +} + +.clear-left { + clear: left; +} + +.clear-right { + clear: right; +} + +.clear-both { + clear: both; +} + +.font-sans { + font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; +} + +.font-serif { + font-family: Georgia, Cambria, "Times New Roman", Times, serif; +} + +.font-mono { + font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +.font-hairline { + font-weight: 100; +} + +.font-thin { + font-weight: 200; +} + +.font-light { + font-weight: 300; +} + +.font-normal { + font-weight: 400; +} + +.font-medium { + font-weight: 500; +} + +.font-semibold { + font-weight: 600; +} + +.font-bold { + font-weight: 700; +} + +.font-extrabold { + font-weight: 800; +} + +.font-black { + font-weight: 900; +} + +.hover\:font-hairline:hover { + font-weight: 100; +} + +.hover\:font-thin:hover { + font-weight: 200; +} + +.hover\:font-light:hover { + font-weight: 300; +} + +.hover\:font-normal:hover { + font-weight: 400; +} + +.hover\:font-medium:hover { + font-weight: 500; +} + +.hover\:font-semibold:hover { + font-weight: 600; +} + +.hover\:font-bold:hover { + font-weight: 700; +} + +.hover\:font-extrabold:hover { + font-weight: 800; +} + +.hover\:font-black:hover { + font-weight: 900; +} + +.focus\:font-hairline:focus { + font-weight: 100; +} + +.focus\:font-thin:focus { + font-weight: 200; +} + +.focus\:font-light:focus { + font-weight: 300; +} + +.focus\:font-normal:focus { + font-weight: 400; +} + +.focus\:font-medium:focus { + font-weight: 500; +} + +.focus\:font-semibold:focus { + font-weight: 600; +} + +.focus\:font-bold:focus { + font-weight: 700; +} + +.focus\:font-extrabold:focus { + font-weight: 800; +} + +.focus\:font-black:focus { + font-weight: 900; +} + +.h-0 { + height: 0; +} + +.h-1 { + height: 0.25rem; +} + +.h-2 { + height: 0.5rem; +} + +.h-3 { + height: 0.75rem; +} + +.h-4 { + height: 1rem; +} + +.h-5 { + height: 1.25rem; +} + +.h-6 { + height: 1.5rem; +} + +.h-8 { + height: 2rem; +} + +.h-10 { + height: 2.5rem; +} + +.h-12 { + height: 3rem; +} + +.h-16 { + height: 4rem; +} + +.h-20 { + height: 5rem; +} + +.h-24 { + height: 6rem; +} + +.h-32 { + height: 8rem; +} + +.h-40 { + height: 10rem; +} + +.h-48 { + height: 12rem; +} + +.h-56 { + height: 14rem; +} + +.h-64 { + height: 16rem; +} + +.h-auto { + height: auto; +} + +.h-px { + height: 1px; +} + +.h-full { + height: 100%; +} + +.h-screen { + height: 100vh; +} + +.leading-3 { + line-height: .75rem; +} + +.leading-4 { + line-height: 1rem; +} + +.leading-5 { + line-height: 1.25rem; +} + +.leading-6 { + line-height: 1.5rem; +} + +.leading-7 { + line-height: 1.75rem; +} + +.leading-8 { + line-height: 2rem; +} + +.leading-9 { + line-height: 2.25rem; +} + +.leading-10 { + line-height: 2.5rem; +} + +.leading-none { + line-height: 1; +} + +.leading-tight { + line-height: 1.25; +} + +.leading-snug { + line-height: 1.375; +} + +.leading-normal { + line-height: 1.5; +} + +.leading-relaxed { + line-height: 1.625; +} + +.leading-loose { + line-height: 2; +} + +.list-inside { + list-style-position: inside; +} + +.list-outside { + list-style-position: outside; +} + +.list-none { + list-style-type: none; +} + +.list-disc { + list-style-type: disc; +} + +.list-decimal { + list-style-type: decimal; +} + +.m-0 { + margin: 0; +} + +.m-1 { + margin: 0.25rem; +} + +.m-2 { + margin: 0.5rem; +} + +.m-3 { + margin: 0.75rem; +} + +.m-4 { + margin: 1rem; +} + +.m-5 { + margin: 1.25rem; +} + +.m-6 { + margin: 1.5rem; +} + +.m-8 { + margin: 2rem; +} + +.m-10 { + margin: 2.5rem; +} + +.m-12 { + margin: 3rem; +} + +.m-16 { + margin: 4rem; +} + +.m-20 { + margin: 5rem; +} + +.m-24 { + margin: 6rem; +} + +.m-32 { + margin: 8rem; +} + +.m-40 { + margin: 10rem; +} + +.m-48 { + margin: 12rem; +} + +.m-56 { + margin: 14rem; +} + +.m-64 { + margin: 16rem; +} + +.m-auto { + margin: auto; +} + +.m-px { + margin: 1px; +} + +.-m-1 { + margin: -0.25rem; +} + +.-m-2 { + margin: -0.5rem; +} + +.-m-3 { + margin: -0.75rem; +} + +.-m-4 { + margin: -1rem; +} + +.-m-5 { + margin: -1.25rem; +} + +.-m-6 { + margin: -1.5rem; +} + +.-m-8 { + margin: -2rem; +} + +.-m-10 { + margin: -2.5rem; +} + +.-m-12 { + margin: -3rem; +} + +.-m-16 { + margin: -4rem; +} + +.-m-20 { + margin: -5rem; +} + +.-m-24 { + margin: -6rem; +} + +.-m-32 { + margin: -8rem; +} + +.-m-40 { + margin: -10rem; +} + +.-m-48 { + margin: -12rem; +} + +.-m-56 { + margin: -14rem; +} + +.-m-64 { + margin: -16rem; +} + +.-m-px { + margin: -1px; +} + +.my-0 { + margin-top: 0; + margin-bottom: 0; +} + +.mx-0 { + margin-left: 0; + margin-right: 0; +} + +.my-1 { + margin-top: 0.25rem; + margin-bottom: 0.25rem; +} + +.mx-1 { + margin-left: 0.25rem; + margin-right: 0.25rem; +} + +.my-2 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; +} + +.mx-2 { + margin-left: 0.5rem; + margin-right: 0.5rem; +} + +.my-3 { + margin-top: 0.75rem; + margin-bottom: 0.75rem; +} + +.mx-3 { + margin-left: 0.75rem; + margin-right: 0.75rem; +} + +.my-4 { + margin-top: 1rem; + margin-bottom: 1rem; +} + +.mx-4 { + margin-left: 1rem; + margin-right: 1rem; +} + +.my-5 { + margin-top: 1.25rem; + margin-bottom: 1.25rem; +} + +.mx-5 { + margin-left: 1.25rem; + margin-right: 1.25rem; +} + +.my-6 { + margin-top: 1.5rem; + margin-bottom: 1.5rem; +} + +.mx-6 { + margin-left: 1.5rem; + margin-right: 1.5rem; +} + +.my-8 { + margin-top: 2rem; + margin-bottom: 2rem; +} + +.mx-8 { + margin-left: 2rem; + margin-right: 2rem; +} + +.my-10 { + margin-top: 2.5rem; + margin-bottom: 2.5rem; +} + +.mx-10 { + margin-left: 2.5rem; + margin-right: 2.5rem; +} + +.my-12 { + margin-top: 3rem; + margin-bottom: 3rem; +} + +.mx-12 { + margin-left: 3rem; + margin-right: 3rem; +} + +.my-16 { + margin-top: 4rem; + margin-bottom: 4rem; +} + +.mx-16 { + margin-left: 4rem; + margin-right: 4rem; +} + +.my-20 { + margin-top: 5rem; + margin-bottom: 5rem; +} + +.mx-20 { + margin-left: 5rem; + margin-right: 5rem; +} + +.my-24 { + margin-top: 6rem; + margin-bottom: 6rem; +} + +.mx-24 { + margin-left: 6rem; + margin-right: 6rem; +} + +.my-32 { + margin-top: 8rem; + margin-bottom: 8rem; +} + +.mx-32 { + margin-left: 8rem; + margin-right: 8rem; +} + +.my-40 { + margin-top: 10rem; + margin-bottom: 10rem; +} + +.mx-40 { + margin-left: 10rem; + margin-right: 10rem; +} + +.my-48 { + margin-top: 12rem; + margin-bottom: 12rem; +} + +.mx-48 { + margin-left: 12rem; + margin-right: 12rem; +} + +.my-56 { + margin-top: 14rem; + margin-bottom: 14rem; +} + +.mx-56 { + margin-left: 14rem; + margin-right: 14rem; +} + +.my-64 { + margin-top: 16rem; + margin-bottom: 16rem; +} + +.mx-64 { + margin-left: 16rem; + margin-right: 16rem; +} + +.my-auto { + margin-top: auto; + margin-bottom: auto; +} + +.mx-auto { + margin-left: auto; + margin-right: auto; +} + +.my-px { + margin-top: 1px; + margin-bottom: 1px; +} + +.mx-px { + margin-left: 1px; + margin-right: 1px; +} + +.-my-1 { + margin-top: -0.25rem; + margin-bottom: -0.25rem; +} + +.-mx-1 { + margin-left: -0.25rem; + margin-right: -0.25rem; +} + +.-my-2 { + margin-top: -0.5rem; + margin-bottom: -0.5rem; +} + +.-mx-2 { + margin-left: -0.5rem; + margin-right: -0.5rem; +} + +.-my-3 { + margin-top: -0.75rem; + margin-bottom: -0.75rem; +} + +.-mx-3 { + margin-left: -0.75rem; + margin-right: -0.75rem; +} + +.-my-4 { + margin-top: -1rem; + margin-bottom: -1rem; +} + +.-mx-4 { + margin-left: -1rem; + margin-right: -1rem; +} + +.-my-5 { + margin-top: -1.25rem; + margin-bottom: -1.25rem; +} + +.-mx-5 { + margin-left: -1.25rem; + margin-right: -1.25rem; +} + +.-my-6 { + margin-top: -1.5rem; + margin-bottom: -1.5rem; +} + +.-mx-6 { + margin-left: -1.5rem; + margin-right: -1.5rem; +} + +.-my-8 { + margin-top: -2rem; + margin-bottom: -2rem; +} + +.-mx-8 { + margin-left: -2rem; + margin-right: -2rem; +} + +.-my-10 { + margin-top: -2.5rem; + margin-bottom: -2.5rem; +} + +.-mx-10 { + margin-left: -2.5rem; + margin-right: -2.5rem; +} + +.-my-12 { + margin-top: -3rem; + margin-bottom: -3rem; +} + +.-mx-12 { + margin-left: -3rem; + margin-right: -3rem; +} + +.-my-16 { + margin-top: -4rem; + margin-bottom: -4rem; +} + +.-mx-16 { + margin-left: -4rem; + margin-right: -4rem; +} + +.-my-20 { + margin-top: -5rem; + margin-bottom: -5rem; +} + +.-mx-20 { + margin-left: -5rem; + margin-right: -5rem; +} + +.-my-24 { + margin-top: -6rem; + margin-bottom: -6rem; +} + +.-mx-24 { + margin-left: -6rem; + margin-right: -6rem; +} + +.-my-32 { + margin-top: -8rem; + margin-bottom: -8rem; +} + +.-mx-32 { + margin-left: -8rem; + margin-right: -8rem; +} + +.-my-40 { + margin-top: -10rem; + margin-bottom: -10rem; +} + +.-mx-40 { + margin-left: -10rem; + margin-right: -10rem; +} + +.-my-48 { + margin-top: -12rem; + margin-bottom: -12rem; +} + +.-mx-48 { + margin-left: -12rem; + margin-right: -12rem; +} + +.-my-56 { + margin-top: -14rem; + margin-bottom: -14rem; +} + +.-mx-56 { + margin-left: -14rem; + margin-right: -14rem; +} + +.-my-64 { + margin-top: -16rem; + margin-bottom: -16rem; +} + +.-mx-64 { + margin-left: -16rem; + margin-right: -16rem; +} + +.-my-px { + margin-top: -1px; + margin-bottom: -1px; +} + +.-mx-px { + margin-left: -1px; + margin-right: -1px; +} + +.mt-0 { + margin-top: 0; +} + +.mr-0 { + margin-right: 0; +} + +.mb-0 { + margin-bottom: 0; +} + +.ml-0 { + margin-left: 0; +} + +.mt-1 { + margin-top: 0.25rem; +} + +.mr-1 { + margin-right: 0.25rem; +} + +.mb-1 { + margin-bottom: 0.25rem; +} + +.ml-1 { + margin-left: 0.25rem; +} + +.mt-2 { + margin-top: 0.5rem; +} + +.mr-2 { + margin-right: 0.5rem; +} + +.mb-2 { + margin-bottom: 0.5rem; +} + +.ml-2 { + margin-left: 0.5rem; +} + +.mt-3 { + margin-top: 0.75rem; +} + +.mr-3 { + margin-right: 0.75rem; +} + +.mb-3 { + margin-bottom: 0.75rem; +} + +.ml-3 { + margin-left: 0.75rem; +} + +.mt-4 { + margin-top: 1rem; +} + +.mr-4 { + margin-right: 1rem; +} + +.mb-4 { + margin-bottom: 1rem; +} + +.ml-4 { + margin-left: 1rem; +} + +.mt-5 { + margin-top: 1.25rem; +} + +.mr-5 { + margin-right: 1.25rem; +} + +.mb-5 { + margin-bottom: 1.25rem; +} + +.ml-5 { + margin-left: 1.25rem; +} + +.mt-6 { + margin-top: 1.5rem; +} + +.mr-6 { + margin-right: 1.5rem; +} + +.mb-6 { + margin-bottom: 1.5rem; +} + +.ml-6 { + margin-left: 1.5rem; +} + +.mt-8 { + margin-top: 2rem; +} + +.mr-8 { + margin-right: 2rem; +} + +.mb-8 { + margin-bottom: 2rem; +} + +.ml-8 { + margin-left: 2rem; +} + +.mt-10 { + margin-top: 2.5rem; +} + +.mr-10 { + margin-right: 2.5rem; +} + +.mb-10 { + margin-bottom: 2.5rem; +} + +.ml-10 { + margin-left: 2.5rem; +} + +.mt-12 { + margin-top: 3rem; +} + +.mr-12 { + margin-right: 3rem; +} + +.mb-12 { + margin-bottom: 3rem; +} + +.ml-12 { + margin-left: 3rem; +} + +.mt-16 { + margin-top: 4rem; +} + +.mr-16 { + margin-right: 4rem; +} + +.mb-16 { + margin-bottom: 4rem; +} + +.ml-16 { + margin-left: 4rem; +} + +.mt-20 { + margin-top: 5rem; +} + +.mr-20 { + margin-right: 5rem; +} + +.mb-20 { + margin-bottom: 5rem; +} + +.ml-20 { + margin-left: 5rem; +} + +.mt-24 { + margin-top: 6rem; +} + +.mr-24 { + margin-right: 6rem; +} + +.mb-24 { + margin-bottom: 6rem; +} + +.ml-24 { + margin-left: 6rem; +} + +.mt-32 { + margin-top: 8rem; +} + +.mr-32 { + margin-right: 8rem; +} + +.mb-32 { + margin-bottom: 8rem; +} + +.ml-32 { + margin-left: 8rem; +} + +.mt-40 { + margin-top: 10rem; +} + +.mr-40 { + margin-right: 10rem; +} + +.mb-40 { + margin-bottom: 10rem; +} + +.ml-40 { + margin-left: 10rem; +} + +.mt-48 { + margin-top: 12rem; +} + +.mr-48 { + margin-right: 12rem; +} + +.mb-48 { + margin-bottom: 12rem; +} + +.ml-48 { + margin-left: 12rem; +} + +.mt-56 { + margin-top: 14rem; +} + +.mr-56 { + margin-right: 14rem; +} + +.mb-56 { + margin-bottom: 14rem; +} + +.ml-56 { + margin-left: 14rem; +} + +.mt-64 { + margin-top: 16rem; +} + +.mr-64 { + margin-right: 16rem; +} + +.mb-64 { + margin-bottom: 16rem; +} + +.ml-64 { + margin-left: 16rem; +} + +.mt-auto { + margin-top: auto; +} + +.mr-auto { + margin-right: auto; +} + +.mb-auto { + margin-bottom: auto; +} + +.ml-auto { + margin-left: auto; +} + +.mt-px { + margin-top: 1px; +} + +.mr-px { + margin-right: 1px; +} + +.mb-px { + margin-bottom: 1px; +} + +.ml-px { + margin-left: 1px; +} + +.-mt-1 { + margin-top: -0.25rem; +} + +.-mr-1 { + margin-right: -0.25rem; +} + +.-mb-1 { + margin-bottom: -0.25rem; +} + +.-ml-1 { + margin-left: -0.25rem; +} + +.-mt-2 { + margin-top: -0.5rem; +} + +.-mr-2 { + margin-right: -0.5rem; +} + +.-mb-2 { + margin-bottom: -0.5rem; +} + +.-ml-2 { + margin-left: -0.5rem; +} + +.-mt-3 { + margin-top: -0.75rem; +} + +.-mr-3 { + margin-right: -0.75rem; +} + +.-mb-3 { + margin-bottom: -0.75rem; +} + +.-ml-3 { + margin-left: -0.75rem; +} + +.-mt-4 { + margin-top: -1rem; +} + +.-mr-4 { + margin-right: -1rem; +} + +.-mb-4 { + margin-bottom: -1rem; +} + +.-ml-4 { + margin-left: -1rem; +} + +.-mt-5 { + margin-top: -1.25rem; +} + +.-mr-5 { + margin-right: -1.25rem; +} + +.-mb-5 { + margin-bottom: -1.25rem; +} + +.-ml-5 { + margin-left: -1.25rem; +} + +.-mt-6 { + margin-top: -1.5rem; +} + +.-mr-6 { + margin-right: -1.5rem; +} + +.-mb-6 { + margin-bottom: -1.5rem; +} + +.-ml-6 { + margin-left: -1.5rem; +} + +.-mt-8 { + margin-top: -2rem; +} + +.-mr-8 { + margin-right: -2rem; +} + +.-mb-8 { + margin-bottom: -2rem; +} + +.-ml-8 { + margin-left: -2rem; +} + +.-mt-10 { + margin-top: -2.5rem; +} + +.-mr-10 { + margin-right: -2.5rem; +} + +.-mb-10 { + margin-bottom: -2.5rem; +} + +.-ml-10 { + margin-left: -2.5rem; +} + +.-mt-12 { + margin-top: -3rem; +} + +.-mr-12 { + margin-right: -3rem; +} + +.-mb-12 { + margin-bottom: -3rem; +} + +.-ml-12 { + margin-left: -3rem; +} + +.-mt-16 { + margin-top: -4rem; +} + +.-mr-16 { + margin-right: -4rem; +} + +.-mb-16 { + margin-bottom: -4rem; +} + +.-ml-16 { + margin-left: -4rem; +} + +.-mt-20 { + margin-top: -5rem; +} + +.-mr-20 { + margin-right: -5rem; +} + +.-mb-20 { + margin-bottom: -5rem; +} + +.-ml-20 { + margin-left: -5rem; +} + +.-mt-24 { + margin-top: -6rem; +} + +.-mr-24 { + margin-right: -6rem; +} + +.-mb-24 { + margin-bottom: -6rem; +} + +.-ml-24 { + margin-left: -6rem; +} + +.-mt-32 { + margin-top: -8rem; +} + +.-mr-32 { + margin-right: -8rem; +} + +.-mb-32 { + margin-bottom: -8rem; +} + +.-ml-32 { + margin-left: -8rem; +} + +.-mt-40 { + margin-top: -10rem; +} + +.-mr-40 { + margin-right: -10rem; +} + +.-mb-40 { + margin-bottom: -10rem; +} + +.-ml-40 { + margin-left: -10rem; +} + +.-mt-48 { + margin-top: -12rem; +} + +.-mr-48 { + margin-right: -12rem; +} + +.-mb-48 { + margin-bottom: -12rem; +} + +.-ml-48 { + margin-left: -12rem; +} + +.-mt-56 { + margin-top: -14rem; +} + +.-mr-56 { + margin-right: -14rem; +} + +.-mb-56 { + margin-bottom: -14rem; +} + +.-ml-56 { + margin-left: -14rem; +} + +.-mt-64 { + margin-top: -16rem; +} + +.-mr-64 { + margin-right: -16rem; +} + +.-mb-64 { + margin-bottom: -16rem; +} + +.-ml-64 { + margin-left: -16rem; +} + +.-mt-px { + margin-top: -1px; +} + +.-mr-px { + margin-right: -1px; +} + +.-mb-px { + margin-bottom: -1px; +} + +.-ml-px { + margin-left: -1px; +} + +.max-h-full { + max-height: 100%; +} + +.max-h-screen { + max-height: 100vh; +} + +.max-w-none { + max-width: none; +} + +.max-w-xs { + max-width: 20rem; +} + +.max-w-sm { + max-width: 24rem; +} + +.max-w-md { + max-width: 28rem; +} + +.max-w-lg { + max-width: 32rem; +} + +.max-w-xl { + max-width: 36rem; +} + +.max-w-2xl { + max-width: 42rem; +} + +.max-w-3xl { + max-width: 48rem; +} + +.max-w-4xl { + max-width: 56rem; +} + +.max-w-5xl { + max-width: 64rem; +} + +.max-w-6xl { + max-width: 72rem; +} + +.max-w-full { + max-width: 100%; +} + +.max-w-screen-sm { + max-width: 640px; +} + +.max-w-screen-md { + max-width: 768px; +} + +.max-w-screen-lg { + max-width: 1024px; +} + +.max-w-screen-xl { + max-width: 1280px; +} + +.min-h-0 { + min-height: 0; +} + +.min-h-full { + min-height: 100%; +} + +.min-h-screen { + min-height: 100vh; +} + +.min-w-0 { + min-width: 0; +} + +.min-w-full { + min-width: 100%; +} + +.object-contain { + object-fit: contain; +} + +.object-cover { + object-fit: cover; +} + +.object-fill { + object-fit: fill; +} + +.object-none { + object-fit: none; +} + +.object-scale-down { + object-fit: scale-down; +} + +.object-bottom { + object-position: bottom; +} + +.object-center { + object-position: center; +} + +.object-left { + object-position: left; +} + +.object-left-bottom { + object-position: left bottom; +} + +.object-left-top { + object-position: left top; +} + +.object-right { + object-position: right; +} + +.object-right-bottom { + object-position: right bottom; +} + +.object-right-top { + object-position: right top; +} + +.object-top { + object-position: top; +} + +.opacity-0 { + opacity: 0; +} + +.opacity-25 { + opacity: 0.25; +} + +.opacity-50 { + opacity: 0.5; +} + +.opacity-75 { + opacity: 0.75; +} + +.opacity-100 { + opacity: 1; +} + +.hover\:opacity-0:hover { + opacity: 0; +} + +.hover\:opacity-25:hover { + opacity: 0.25; +} + +.hover\:opacity-50:hover { + opacity: 0.5; +} + +.hover\:opacity-75:hover { + opacity: 0.75; +} + +.hover\:opacity-100:hover { + opacity: 1; +} + +.focus\:opacity-0:focus { + opacity: 0; +} + +.focus\:opacity-25:focus { + opacity: 0.25; +} + +.focus\:opacity-50:focus { + opacity: 0.5; +} + +.focus\:opacity-75:focus { + opacity: 0.75; +} + +.focus\:opacity-100:focus { + opacity: 1; +} + +.outline-none { + outline: 0; +} + +.focus\:outline-none:focus { + outline: 0; +} + +.overflow-auto { + overflow: auto; +} + +.overflow-hidden { + overflow: hidden; +} + +.overflow-visible { + overflow: visible; +} + +.overflow-scroll { + overflow: scroll; +} + +.overflow-x-auto { + overflow-x: auto; +} + +.overflow-y-auto { + overflow-y: auto; +} + +.overflow-x-hidden { + overflow-x: hidden; +} + +.overflow-y-hidden { + overflow-y: hidden; +} + +.overflow-x-visible { + overflow-x: visible; +} + +.overflow-y-visible { + overflow-y: visible; +} + +.overflow-x-scroll { + overflow-x: scroll; +} + +.overflow-y-scroll { + overflow-y: scroll; +} + +.scrolling-touch { + -webkit-overflow-scrolling: touch; +} + +.scrolling-auto { + -webkit-overflow-scrolling: auto; +} + +.p-0 { + padding: 0; +} + +.p-1 { + padding: 0.25rem; +} + +.p-2 { + padding: 0.5rem; +} + +.p-3 { + padding: 0.75rem; +} + +.p-4 { + padding: 1rem; +} + +.p-5 { + padding: 1.25rem; +} + +.p-6 { + padding: 1.5rem; +} + +.p-8 { + padding: 2rem; +} + +.p-10 { + padding: 2.5rem; +} + +.p-12 { + padding: 3rem; +} + +.p-16 { + padding: 4rem; +} + +.p-20 { + padding: 5rem; +} + +.p-24 { + padding: 6rem; +} + +.p-32 { + padding: 8rem; +} + +.p-40 { + padding: 10rem; +} + +.p-48 { + padding: 12rem; +} + +.p-56 { + padding: 14rem; +} + +.p-64 { + padding: 16rem; +} + +.p-px { + padding: 1px; +} + +.py-0 { + padding-top: 0; + padding-bottom: 0; +} + +.px-0 { + padding-left: 0; + padding-right: 0; +} + +.py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +.px-1 { + padding-left: 0.25rem; + padding-right: 0.25rem; +} + +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.py-3 { + padding-top: 0.75rem; + padding-bottom: 0.75rem; +} + +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} + +.py-4 { + padding-top: 1rem; + padding-bottom: 1rem; +} + +.px-4 { + padding-left: 1rem; + padding-right: 1rem; +} + +.py-5 { + padding-top: 1.25rem; + padding-bottom: 1.25rem; +} + +.px-5 { + padding-left: 1.25rem; + padding-right: 1.25rem; +} + +.py-6 { + padding-top: 1.5rem; + padding-bottom: 1.5rem; +} + +.px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; +} + +.py-8 { + padding-top: 2rem; + padding-bottom: 2rem; +} + +.px-8 { + padding-left: 2rem; + padding-right: 2rem; +} + +.py-10 { + padding-top: 2.5rem; + padding-bottom: 2.5rem; +} + +.px-10 { + padding-left: 2.5rem; + padding-right: 2.5rem; +} + +.py-12 { + padding-top: 3rem; + padding-bottom: 3rem; +} + +.px-12 { + padding-left: 3rem; + padding-right: 3rem; +} + +.py-16 { + padding-top: 4rem; + padding-bottom: 4rem; +} + +.px-16 { + padding-left: 4rem; + padding-right: 4rem; +} + +.py-20 { + padding-top: 5rem; + padding-bottom: 5rem; +} + +.px-20 { + padding-left: 5rem; + padding-right: 5rem; +} + +.py-24 { + padding-top: 6rem; + padding-bottom: 6rem; +} + +.px-24 { + padding-left: 6rem; + padding-right: 6rem; +} + +.py-32 { + padding-top: 8rem; + padding-bottom: 8rem; +} + +.px-32 { + padding-left: 8rem; + padding-right: 8rem; +} + +.py-40 { + padding-top: 10rem; + padding-bottom: 10rem; +} + +.px-40 { + padding-left: 10rem; + padding-right: 10rem; +} + +.py-48 { + padding-top: 12rem; + padding-bottom: 12rem; +} + +.px-48 { + padding-left: 12rem; + padding-right: 12rem; +} + +.py-56 { + padding-top: 14rem; + padding-bottom: 14rem; +} + +.px-56 { + padding-left: 14rem; + padding-right: 14rem; +} + +.py-64 { + padding-top: 16rem; + padding-bottom: 16rem; +} + +.px-64 { + padding-left: 16rem; + padding-right: 16rem; +} + +.py-px { + padding-top: 1px; + padding-bottom: 1px; +} + +.px-px { + padding-left: 1px; + padding-right: 1px; +} + +.pt-0 { + padding-top: 0; +} + +.pr-0 { + padding-right: 0; +} + +.pb-0 { + padding-bottom: 0; +} + +.pl-0 { + padding-left: 0; +} + +.pt-1 { + padding-top: 0.25rem; +} + +.pr-1 { + padding-right: 0.25rem; +} + +.pb-1 { + padding-bottom: 0.25rem; +} + +.pl-1 { + padding-left: 0.25rem; +} + +.pt-2 { + padding-top: 0.5rem; +} + +.pr-2 { + padding-right: 0.5rem; +} + +.pb-2 { + padding-bottom: 0.5rem; +} + +.pl-2 { + padding-left: 0.5rem; +} + +.pt-3 { + padding-top: 0.75rem; +} + +.pr-3 { + padding-right: 0.75rem; +} + +.pb-3 { + padding-bottom: 0.75rem; +} + +.pl-3 { + padding-left: 0.75rem; +} + +.pt-4 { + padding-top: 1rem; +} + +.pr-4 { + padding-right: 1rem; +} + +.pb-4 { + padding-bottom: 1rem; +} + +.pl-4 { + padding-left: 1rem; +} + +.pt-5 { + padding-top: 1.25rem; +} + +.pr-5 { + padding-right: 1.25rem; +} + +.pb-5 { + padding-bottom: 1.25rem; +} + +.pl-5 { + padding-left: 1.25rem; +} + +.pt-6 { + padding-top: 1.5rem; +} + +.pr-6 { + padding-right: 1.5rem; +} + +.pb-6 { + padding-bottom: 1.5rem; +} + +.pl-6 { + padding-left: 1.5rem; +} + +.pt-8 { + padding-top: 2rem; +} + +.pr-8 { + padding-right: 2rem; +} + +.pb-8 { + padding-bottom: 2rem; +} + +.pl-8 { + padding-left: 2rem; +} + +.pt-10 { + padding-top: 2.5rem; +} + +.pr-10 { + padding-right: 2.5rem; +} + +.pb-10 { + padding-bottom: 2.5rem; +} + +.pl-10 { + padding-left: 2.5rem; +} + +.pt-12 { + padding-top: 3rem; +} + +.pr-12 { + padding-right: 3rem; +} + +.pb-12 { + padding-bottom: 3rem; +} + +.pl-12 { + padding-left: 3rem; +} + +.pt-16 { + padding-top: 4rem; +} + +.pr-16 { + padding-right: 4rem; +} + +.pb-16 { + padding-bottom: 4rem; +} + +.pl-16 { + padding-left: 4rem; +} + +.pt-20 { + padding-top: 5rem; +} + +.pr-20 { + padding-right: 5rem; +} + +.pb-20 { + padding-bottom: 5rem; +} + +.pl-20 { + padding-left: 5rem; +} + +.pt-24 { + padding-top: 6rem; +} + +.pr-24 { + padding-right: 6rem; +} + +.pb-24 { + padding-bottom: 6rem; +} + +.pl-24 { + padding-left: 6rem; +} + +.pt-32 { + padding-top: 8rem; +} + +.pr-32 { + padding-right: 8rem; +} + +.pb-32 { + padding-bottom: 8rem; +} + +.pl-32 { + padding-left: 8rem; +} + +.pt-40 { + padding-top: 10rem; +} + +.pr-40 { + padding-right: 10rem; +} + +.pb-40 { + padding-bottom: 10rem; +} + +.pl-40 { + padding-left: 10rem; +} + +.pt-48 { + padding-top: 12rem; +} + +.pr-48 { + padding-right: 12rem; +} + +.pb-48 { + padding-bottom: 12rem; +} + +.pl-48 { + padding-left: 12rem; +} + +.pt-56 { + padding-top: 14rem; +} + +.pr-56 { + padding-right: 14rem; +} + +.pb-56 { + padding-bottom: 14rem; +} + +.pl-56 { + padding-left: 14rem; +} + +.pt-64 { + padding-top: 16rem; +} + +.pr-64 { + padding-right: 16rem; +} + +.pb-64 { + padding-bottom: 16rem; +} + +.pl-64 { + padding-left: 16rem; +} + +.pt-px { + padding-top: 1px; +} + +.pr-px { + padding-right: 1px; +} + +.pb-px { + padding-bottom: 1px; +} + +.pl-px { + padding-left: 1px; +} + +.placeholder-transparent::placeholder { + color: transparent; +} + +.placeholder-black::placeholder { + color: #000; +} + +.placeholder-white::placeholder { + color: #fff; +} + +.placeholder-gray-100::placeholder { + color: #f7fafc; +} + +.placeholder-gray-200::placeholder { + color: #edf2f7; +} + +.placeholder-gray-300::placeholder { + color: #e2e8f0; +} + +.placeholder-gray-400::placeholder { + color: #cbd5e0; +} + +.placeholder-gray-500::placeholder { + color: #a0aec0; +} + +.placeholder-gray-600::placeholder { + color: #718096; +} + +.placeholder-gray-700::placeholder { + color: #4a5568; +} + +.placeholder-gray-800::placeholder { + color: #2d3748; +} + +.placeholder-gray-900::placeholder { + color: #1a202c; +} + +.placeholder-red-100::placeholder { + color: #fff5f5; +} + +.placeholder-red-200::placeholder { + color: #fed7d7; +} + +.placeholder-red-300::placeholder { + color: #feb2b2; +} + +.placeholder-red-400::placeholder { + color: #fc8181; +} + +.placeholder-red-500::placeholder { + color: #f56565; +} + +.placeholder-red-600::placeholder { + color: #e53e3e; +} + +.placeholder-red-700::placeholder { + color: #c53030; +} + +.placeholder-red-800::placeholder { + color: #9b2c2c; +} + +.placeholder-red-900::placeholder { + color: #742a2a; +} + +.placeholder-orange-100::placeholder { + color: #fffaf0; +} + +.placeholder-orange-200::placeholder { + color: #feebc8; +} + +.placeholder-orange-300::placeholder { + color: #fbd38d; +} + +.placeholder-orange-400::placeholder { + color: #f6ad55; +} + +.placeholder-orange-500::placeholder { + color: #ed8936; +} + +.placeholder-orange-600::placeholder { + color: #dd6b20; +} + +.placeholder-orange-700::placeholder { + color: #c05621; +} + +.placeholder-orange-800::placeholder { + color: #9c4221; +} + +.placeholder-orange-900::placeholder { + color: #7b341e; +} + +.placeholder-yellow-100::placeholder { + color: #fffff0; +} + +.placeholder-yellow-200::placeholder { + color: #fefcbf; +} + +.placeholder-yellow-300::placeholder { + color: #faf089; +} + +.placeholder-yellow-400::placeholder { + color: #f6e05e; +} + +.placeholder-yellow-500::placeholder { + color: #ecc94b; +} + +.placeholder-yellow-600::placeholder { + color: #d69e2e; +} + +.placeholder-yellow-700::placeholder { + color: #b7791f; +} + +.placeholder-yellow-800::placeholder { + color: #975a16; +} + +.placeholder-yellow-900::placeholder { + color: #744210; +} + +.placeholder-green-100::placeholder { + color: #f0fff4; +} + +.placeholder-green-200::placeholder { + color: #c6f6d5; +} + +.placeholder-green-300::placeholder { + color: #9ae6b4; +} + +.placeholder-green-400::placeholder { + color: #68d391; +} + +.placeholder-green-500::placeholder { + color: #48bb78; +} + +.placeholder-green-600::placeholder { + color: #38a169; +} + +.placeholder-green-700::placeholder { + color: #2f855a; +} + +.placeholder-green-800::placeholder { + color: #276749; +} + +.placeholder-green-900::placeholder { + color: #22543d; +} + +.placeholder-teal-100::placeholder { + color: #e6fffa; +} + +.placeholder-teal-200::placeholder { + color: #b2f5ea; +} + +.placeholder-teal-300::placeholder { + color: #81e6d9; +} + +.placeholder-teal-400::placeholder { + color: #4fd1c5; +} + +.placeholder-teal-500::placeholder { + color: #38b2ac; +} + +.placeholder-teal-600::placeholder { + color: #319795; +} + +.placeholder-teal-700::placeholder { + color: #2c7a7b; +} + +.placeholder-teal-800::placeholder { + color: #285e61; +} + +.placeholder-teal-900::placeholder { + color: #234e52; +} + +.placeholder-blue-100::placeholder { + color: #ebf8ff; +} + +.placeholder-blue-200::placeholder { + color: #bee3f8; +} + +.placeholder-blue-300::placeholder { + color: #90cdf4; +} + +.placeholder-blue-400::placeholder { + color: #63b3ed; +} + +.placeholder-blue-500::placeholder { + color: #4299e1; +} + +.placeholder-blue-600::placeholder { + color: #3182ce; +} + +.placeholder-blue-700::placeholder { + color: #2b6cb0; +} + +.placeholder-blue-800::placeholder { + color: #2c5282; +} + +.placeholder-blue-900::placeholder { + color: #2a4365; +} + +.placeholder-indigo-100::placeholder { + color: #ebf4ff; +} + +.placeholder-indigo-200::placeholder { + color: #c3dafe; +} + +.placeholder-indigo-300::placeholder { + color: #a3bffa; +} + +.placeholder-indigo-400::placeholder { + color: #7f9cf5; +} + +.placeholder-indigo-500::placeholder { + color: #667eea; +} + +.placeholder-indigo-600::placeholder { + color: #5a67d8; +} + +.placeholder-indigo-700::placeholder { + color: #4c51bf; +} + +.placeholder-indigo-800::placeholder { + color: #434190; +} + +.placeholder-indigo-900::placeholder { + color: #3c366b; +} + +.placeholder-purple-100::placeholder { + color: #faf5ff; +} + +.placeholder-purple-200::placeholder { + color: #e9d8fd; +} + +.placeholder-purple-300::placeholder { + color: #d6bcfa; +} + +.placeholder-purple-400::placeholder { + color: #b794f4; +} + +.placeholder-purple-500::placeholder { + color: #9f7aea; +} + +.placeholder-purple-600::placeholder { + color: #805ad5; +} + +.placeholder-purple-700::placeholder { + color: #6b46c1; +} + +.placeholder-purple-800::placeholder { + color: #553c9a; +} + +.placeholder-purple-900::placeholder { + color: #44337a; +} + +.placeholder-pink-100::placeholder { + color: #fff5f7; +} + +.placeholder-pink-200::placeholder { + color: #fed7e2; +} + +.placeholder-pink-300::placeholder { + color: #fbb6ce; +} + +.placeholder-pink-400::placeholder { + color: #f687b3; +} + +.placeholder-pink-500::placeholder { + color: #ed64a6; +} + +.placeholder-pink-600::placeholder { + color: #d53f8c; +} + +.placeholder-pink-700::placeholder { + color: #b83280; +} + +.placeholder-pink-800::placeholder { + color: #97266d; +} + +.placeholder-pink-900::placeholder { + color: #702459; +} + +.focus\:placeholder-transparent:focus::placeholder { + color: transparent; +} + +.focus\:placeholder-black:focus::placeholder { + color: #000; +} + +.focus\:placeholder-white:focus::placeholder { + color: #fff; +} + +.focus\:placeholder-gray-100:focus::placeholder { + color: #f7fafc; +} + +.focus\:placeholder-gray-200:focus::placeholder { + color: #edf2f7; +} + +.focus\:placeholder-gray-300:focus::placeholder { + color: #e2e8f0; +} + +.focus\:placeholder-gray-400:focus::placeholder { + color: #cbd5e0; +} + +.focus\:placeholder-gray-500:focus::placeholder { + color: #a0aec0; +} + +.focus\:placeholder-gray-600:focus::placeholder { + color: #718096; +} + +.focus\:placeholder-gray-700:focus::placeholder { + color: #4a5568; +} + +.focus\:placeholder-gray-800:focus::placeholder { + color: #2d3748; +} + +.focus\:placeholder-gray-900:focus::placeholder { + color: #1a202c; +} + +.focus\:placeholder-red-100:focus::placeholder { + color: #fff5f5; +} + +.focus\:placeholder-red-200:focus::placeholder { + color: #fed7d7; +} + +.focus\:placeholder-red-300:focus::placeholder { + color: #feb2b2; +} + +.focus\:placeholder-red-400:focus::placeholder { + color: #fc8181; +} + +.focus\:placeholder-red-500:focus::placeholder { + color: #f56565; +} + +.focus\:placeholder-red-600:focus::placeholder { + color: #e53e3e; +} + +.focus\:placeholder-red-700:focus::placeholder { + color: #c53030; +} + +.focus\:placeholder-red-800:focus::placeholder { + color: #9b2c2c; +} + +.focus\:placeholder-red-900:focus::placeholder { + color: #742a2a; +} + +.focus\:placeholder-orange-100:focus::placeholder { + color: #fffaf0; +} + +.focus\:placeholder-orange-200:focus::placeholder { + color: #feebc8; +} + +.focus\:placeholder-orange-300:focus::placeholder { + color: #fbd38d; +} + +.focus\:placeholder-orange-400:focus::placeholder { + color: #f6ad55; +} + +.focus\:placeholder-orange-500:focus::placeholder { + color: #ed8936; +} + +.focus\:placeholder-orange-600:focus::placeholder { + color: #dd6b20; +} + +.focus\:placeholder-orange-700:focus::placeholder { + color: #c05621; +} + +.focus\:placeholder-orange-800:focus::placeholder { + color: #9c4221; +} + +.focus\:placeholder-orange-900:focus::placeholder { + color: #7b341e; +} + +.focus\:placeholder-yellow-100:focus::placeholder { + color: #fffff0; +} + +.focus\:placeholder-yellow-200:focus::placeholder { + color: #fefcbf; +} + +.focus\:placeholder-yellow-300:focus::placeholder { + color: #faf089; +} + +.focus\:placeholder-yellow-400:focus::placeholder { + color: #f6e05e; +} + +.focus\:placeholder-yellow-500:focus::placeholder { + color: #ecc94b; +} + +.focus\:placeholder-yellow-600:focus::placeholder { + color: #d69e2e; +} + +.focus\:placeholder-yellow-700:focus::placeholder { + color: #b7791f; +} + +.focus\:placeholder-yellow-800:focus::placeholder { + color: #975a16; +} + +.focus\:placeholder-yellow-900:focus::placeholder { + color: #744210; +} + +.focus\:placeholder-green-100:focus::placeholder { + color: #f0fff4; +} + +.focus\:placeholder-green-200:focus::placeholder { + color: #c6f6d5; +} + +.focus\:placeholder-green-300:focus::placeholder { + color: #9ae6b4; +} + +.focus\:placeholder-green-400:focus::placeholder { + color: #68d391; +} + +.focus\:placeholder-green-500:focus::placeholder { + color: #48bb78; +} + +.focus\:placeholder-green-600:focus::placeholder { + color: #38a169; +} + +.focus\:placeholder-green-700:focus::placeholder { + color: #2f855a; +} + +.focus\:placeholder-green-800:focus::placeholder { + color: #276749; +} + +.focus\:placeholder-green-900:focus::placeholder { + color: #22543d; +} + +.focus\:placeholder-teal-100:focus::placeholder { + color: #e6fffa; +} + +.focus\:placeholder-teal-200:focus::placeholder { + color: #b2f5ea; +} + +.focus\:placeholder-teal-300:focus::placeholder { + color: #81e6d9; +} + +.focus\:placeholder-teal-400:focus::placeholder { + color: #4fd1c5; +} + +.focus\:placeholder-teal-500:focus::placeholder { + color: #38b2ac; +} + +.focus\:placeholder-teal-600:focus::placeholder { + color: #319795; +} + +.focus\:placeholder-teal-700:focus::placeholder { + color: #2c7a7b; +} + +.focus\:placeholder-teal-800:focus::placeholder { + color: #285e61; +} + +.focus\:placeholder-teal-900:focus::placeholder { + color: #234e52; +} + +.focus\:placeholder-blue-100:focus::placeholder { + color: #ebf8ff; +} + +.focus\:placeholder-blue-200:focus::placeholder { + color: #bee3f8; +} + +.focus\:placeholder-blue-300:focus::placeholder { + color: #90cdf4; +} + +.focus\:placeholder-blue-400:focus::placeholder { + color: #63b3ed; +} + +.focus\:placeholder-blue-500:focus::placeholder { + color: #4299e1; +} + +.focus\:placeholder-blue-600:focus::placeholder { + color: #3182ce; +} + +.focus\:placeholder-blue-700:focus::placeholder { + color: #2b6cb0; +} + +.focus\:placeholder-blue-800:focus::placeholder { + color: #2c5282; +} + +.focus\:placeholder-blue-900:focus::placeholder { + color: #2a4365; +} + +.focus\:placeholder-indigo-100:focus::placeholder { + color: #ebf4ff; +} + +.focus\:placeholder-indigo-200:focus::placeholder { + color: #c3dafe; +} + +.focus\:placeholder-indigo-300:focus::placeholder { + color: #a3bffa; +} + +.focus\:placeholder-indigo-400:focus::placeholder { + color: #7f9cf5; +} + +.focus\:placeholder-indigo-500:focus::placeholder { + color: #667eea; +} + +.focus\:placeholder-indigo-600:focus::placeholder { + color: #5a67d8; +} + +.focus\:placeholder-indigo-700:focus::placeholder { + color: #4c51bf; +} + +.focus\:placeholder-indigo-800:focus::placeholder { + color: #434190; +} + +.focus\:placeholder-indigo-900:focus::placeholder { + color: #3c366b; +} + +.focus\:placeholder-purple-100:focus::placeholder { + color: #faf5ff; +} + +.focus\:placeholder-purple-200:focus::placeholder { + color: #e9d8fd; +} + +.focus\:placeholder-purple-300:focus::placeholder { + color: #d6bcfa; +} + +.focus\:placeholder-purple-400:focus::placeholder { + color: #b794f4; +} + +.focus\:placeholder-purple-500:focus::placeholder { + color: #9f7aea; +} + +.focus\:placeholder-purple-600:focus::placeholder { + color: #805ad5; +} + +.focus\:placeholder-purple-700:focus::placeholder { + color: #6b46c1; +} + +.focus\:placeholder-purple-800:focus::placeholder { + color: #553c9a; +} + +.focus\:placeholder-purple-900:focus::placeholder { + color: #44337a; +} + +.focus\:placeholder-pink-100:focus::placeholder { + color: #fff5f7; +} + +.focus\:placeholder-pink-200:focus::placeholder { + color: #fed7e2; +} + +.focus\:placeholder-pink-300:focus::placeholder { + color: #fbb6ce; +} + +.focus\:placeholder-pink-400:focus::placeholder { + color: #f687b3; +} + +.focus\:placeholder-pink-500:focus::placeholder { + color: #ed64a6; +} + +.focus\:placeholder-pink-600:focus::placeholder { + color: #d53f8c; +} + +.focus\:placeholder-pink-700:focus::placeholder { + color: #b83280; +} + +.focus\:placeholder-pink-800:focus::placeholder { + color: #97266d; +} + +.focus\:placeholder-pink-900:focus::placeholder { + color: #702459; +} + +.pointer-events-none { + pointer-events: none; +} + +.pointer-events-auto { + pointer-events: auto; +} + +.static { + position: static; +} + +.fixed { + position: fixed; +} + +.absolute { + position: absolute; +} + +.relative { + position: relative; +} + +.sticky { + position: -webkit-sticky; + position: sticky; +} + +.inset-0 { + top: 0; + right: 0; + bottom: 0; + left: 0; +} + +.inset-auto { + top: auto; + right: auto; + bottom: auto; + left: auto; +} + +.inset-y-0 { + top: 0; + bottom: 0; +} + +.inset-x-0 { + right: 0; + left: 0; +} + +.inset-y-auto { + top: auto; + bottom: auto; +} + +.inset-x-auto { + right: auto; + left: auto; +} + +.top-0 { + top: 0; +} + +.right-0 { + right: 0; +} + +.bottom-0 { + bottom: 0; +} + +.left-0 { + left: 0; +} + +.top-auto { + top: auto; +} + +.right-auto { + right: auto; +} + +.bottom-auto { + bottom: auto; +} + +.left-auto { + left: auto; +} + +.resize-none { + resize: none; +} + +.resize-y { + resize: vertical; +} + +.resize-x { + resize: horizontal; +} + +.resize { + resize: both; +} + +.shadow-xs { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); +} + +.shadow-sm { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); +} + +.shadow { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); +} + +.shadow-md { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); +} + +.shadow-lg { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); +} + +.shadow-xl { + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); +} + +.shadow-2xl { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); +} + +.shadow-inner { + box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); +} + +.shadow-outline { + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); +} + +.shadow-none { + box-shadow: none; +} + +.hover\:shadow-xs:hover { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); +} + +.hover\:shadow-sm:hover { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); +} + +.hover\:shadow:hover { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); +} + +.hover\:shadow-md:hover { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); +} + +.hover\:shadow-lg:hover { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); +} + +.hover\:shadow-xl:hover { + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); +} + +.hover\:shadow-2xl:hover { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); +} + +.hover\:shadow-inner:hover { + box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); +} + +.hover\:shadow-outline:hover { + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); +} + +.hover\:shadow-none:hover { + box-shadow: none; +} + +.focus\:shadow-xs:focus { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); +} + +.focus\:shadow-sm:focus { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); +} + +.focus\:shadow:focus { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); +} + +.focus\:shadow-md:focus { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); +} + +.focus\:shadow-lg:focus { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); +} + +.focus\:shadow-xl:focus { + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); +} + +.focus\:shadow-2xl:focus { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); +} + +.focus\:shadow-inner:focus { + box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); +} + +.focus\:shadow-outline:focus { + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); +} + +.focus\:shadow-none:focus { + box-shadow: none; +} + +.fill-current { + fill: currentColor; +} + +.stroke-current { + stroke: currentColor; +} + +.stroke-0 { + stroke-width: 0; +} + +.stroke-1 { + stroke-width: 1; +} + +.stroke-2 { + stroke-width: 2; +} + +.table-auto { + table-layout: auto; +} + +.table-fixed { + table-layout: fixed; +} + +.text-left { + text-align: left; +} + +.text-center { + text-align: center; +} + +.text-right { + text-align: right; +} + +.text-justify { + text-align: justify; +} + +.text-transparent { + color: transparent; +} + +.text-black { + color: #000; +} + +.text-white { + color: #fff; +} + +.text-gray-100 { + color: #f7fafc; +} + +.text-gray-200 { + color: #edf2f7; +} + +.text-gray-300 { + color: #e2e8f0; +} + +.text-gray-400 { + color: #cbd5e0; +} + +.text-gray-500 { + color: #a0aec0; +} + +.text-gray-600 { + color: #718096; +} + +.text-gray-700 { + color: #4a5568; +} + +.text-gray-800 { + color: #2d3748; +} + +.text-gray-900 { + color: #1a202c; +} + +.text-red-100 { + color: #fff5f5; +} + +.text-red-200 { + color: #fed7d7; +} + +.text-red-300 { + color: #feb2b2; +} + +.text-red-400 { + color: #fc8181; +} + +.text-red-500 { + color: #f56565; +} + +.text-red-600 { + color: #e53e3e; +} + +.text-red-700 { + color: #c53030; +} + +.text-red-800 { + color: #9b2c2c; +} + +.text-red-900 { + color: #742a2a; +} + +.text-orange-100 { + color: #fffaf0; +} + +.text-orange-200 { + color: #feebc8; +} + +.text-orange-300 { + color: #fbd38d; +} + +.text-orange-400 { + color: #f6ad55; +} + +.text-orange-500 { + color: #ed8936; +} + +.text-orange-600 { + color: #dd6b20; +} + +.text-orange-700 { + color: #c05621; +} + +.text-orange-800 { + color: #9c4221; +} + +.text-orange-900 { + color: #7b341e; +} + +.text-yellow-100 { + color: #fffff0; +} + +.text-yellow-200 { + color: #fefcbf; +} + +.text-yellow-300 { + color: #faf089; +} + +.text-yellow-400 { + color: #f6e05e; +} + +.text-yellow-500 { + color: #ecc94b; +} + +.text-yellow-600 { + color: #d69e2e; +} + +.text-yellow-700 { + color: #b7791f; +} + +.text-yellow-800 { + color: #975a16; +} + +.text-yellow-900 { + color: #744210; +} + +.text-green-100 { + color: #f0fff4; +} + +.text-green-200 { + color: #c6f6d5; +} + +.text-green-300 { + color: #9ae6b4; +} + +.text-green-400 { + color: #68d391; +} + +.text-green-500 { + color: #48bb78; +} + +.text-green-600 { + color: #38a169; +} + +.text-green-700 { + color: #2f855a; +} + +.text-green-800 { + color: #276749; +} + +.text-green-900 { + color: #22543d; +} + +.text-teal-100 { + color: #e6fffa; +} + +.text-teal-200 { + color: #b2f5ea; +} + +.text-teal-300 { + color: #81e6d9; +} + +.text-teal-400 { + color: #4fd1c5; +} + +.text-teal-500 { + color: #38b2ac; +} + +.text-teal-600 { + color: #319795; +} + +.text-teal-700 { + color: #2c7a7b; +} + +.text-teal-800 { + color: #285e61; +} + +.text-teal-900 { + color: #234e52; +} + +.text-blue-100 { + color: #ebf8ff; +} + +.text-blue-200 { + color: #bee3f8; +} + +.text-blue-300 { + color: #90cdf4; +} + +.text-blue-400 { + color: #63b3ed; +} + +.text-blue-500 { + color: #4299e1; +} + +.text-blue-600 { + color: #3182ce; +} + +.text-blue-700 { + color: #2b6cb0; +} + +.text-blue-800 { + color: #2c5282; +} + +.text-blue-900 { + color: #2a4365; +} + +.text-indigo-100 { + color: #ebf4ff; +} + +.text-indigo-200 { + color: #c3dafe; +} + +.text-indigo-300 { + color: #a3bffa; +} + +.text-indigo-400 { + color: #7f9cf5; +} + +.text-indigo-500 { + color: #667eea; +} + +.text-indigo-600 { + color: #5a67d8; +} + +.text-indigo-700 { + color: #4c51bf; +} + +.text-indigo-800 { + color: #434190; +} + +.text-indigo-900 { + color: #3c366b; +} + +.text-purple-100 { + color: #faf5ff; +} + +.text-purple-200 { + color: #e9d8fd; +} + +.text-purple-300 { + color: #d6bcfa; +} + +.text-purple-400 { + color: #b794f4; +} + +.text-purple-500 { + color: #9f7aea; +} + +.text-purple-600 { + color: #805ad5; +} + +.text-purple-700 { + color: #6b46c1; +} + +.text-purple-800 { + color: #553c9a; +} + +.text-purple-900 { + color: #44337a; +} + +.text-pink-100 { + color: #fff5f7; +} + +.text-pink-200 { + color: #fed7e2; +} + +.text-pink-300 { + color: #fbb6ce; +} + +.text-pink-400 { + color: #f687b3; +} + +.text-pink-500 { + color: #ed64a6; +} + +.text-pink-600 { + color: #d53f8c; +} + +.text-pink-700 { + color: #b83280; +} + +.text-pink-800 { + color: #97266d; +} + +.text-pink-900 { + color: #702459; +} + +.hover\:text-transparent:hover { + color: transparent; +} + +.hover\:text-black:hover { + color: #000; +} + +.hover\:text-white:hover { + color: #fff; +} + +.hover\:text-gray-100:hover { + color: #f7fafc; +} + +.hover\:text-gray-200:hover { + color: #edf2f7; +} + +.hover\:text-gray-300:hover { + color: #e2e8f0; +} + +.hover\:text-gray-400:hover { + color: #cbd5e0; +} + +.hover\:text-gray-500:hover { + color: #a0aec0; +} + +.hover\:text-gray-600:hover { + color: #718096; +} + +.hover\:text-gray-700:hover { + color: #4a5568; +} + +.hover\:text-gray-800:hover { + color: #2d3748; +} + +.hover\:text-gray-900:hover { + color: #1a202c; +} + +.hover\:text-red-100:hover { + color: #fff5f5; +} + +.hover\:text-red-200:hover { + color: #fed7d7; +} + +.hover\:text-red-300:hover { + color: #feb2b2; +} + +.hover\:text-red-400:hover { + color: #fc8181; +} + +.hover\:text-red-500:hover { + color: #f56565; +} + +.hover\:text-red-600:hover { + color: #e53e3e; +} + +.hover\:text-red-700:hover { + color: #c53030; +} + +.hover\:text-red-800:hover { + color: #9b2c2c; +} + +.hover\:text-red-900:hover { + color: #742a2a; +} + +.hover\:text-orange-100:hover { + color: #fffaf0; +} + +.hover\:text-orange-200:hover { + color: #feebc8; +} + +.hover\:text-orange-300:hover { + color: #fbd38d; +} + +.hover\:text-orange-400:hover { + color: #f6ad55; +} + +.hover\:text-orange-500:hover { + color: #ed8936; +} + +.hover\:text-orange-600:hover { + color: #dd6b20; +} + +.hover\:text-orange-700:hover { + color: #c05621; +} + +.hover\:text-orange-800:hover { + color: #9c4221; +} + +.hover\:text-orange-900:hover { + color: #7b341e; +} + +.hover\:text-yellow-100:hover { + color: #fffff0; +} + +.hover\:text-yellow-200:hover { + color: #fefcbf; +} + +.hover\:text-yellow-300:hover { + color: #faf089; +} + +.hover\:text-yellow-400:hover { + color: #f6e05e; +} + +.hover\:text-yellow-500:hover { + color: #ecc94b; +} + +.hover\:text-yellow-600:hover { + color: #d69e2e; +} + +.hover\:text-yellow-700:hover { + color: #b7791f; +} + +.hover\:text-yellow-800:hover { + color: #975a16; +} + +.hover\:text-yellow-900:hover { + color: #744210; +} + +.hover\:text-green-100:hover { + color: #f0fff4; +} + +.hover\:text-green-200:hover { + color: #c6f6d5; +} + +.hover\:text-green-300:hover { + color: #9ae6b4; +} + +.hover\:text-green-400:hover { + color: #68d391; +} + +.hover\:text-green-500:hover { + color: #48bb78; +} + +.hover\:text-green-600:hover { + color: #38a169; +} + +.hover\:text-green-700:hover { + color: #2f855a; +} + +.hover\:text-green-800:hover { + color: #276749; +} + +.hover\:text-green-900:hover { + color: #22543d; +} + +.hover\:text-teal-100:hover { + color: #e6fffa; +} + +.hover\:text-teal-200:hover { + color: #b2f5ea; +} + +.hover\:text-teal-300:hover { + color: #81e6d9; +} + +.hover\:text-teal-400:hover { + color: #4fd1c5; +} + +.hover\:text-teal-500:hover { + color: #38b2ac; +} + +.hover\:text-teal-600:hover { + color: #319795; +} + +.hover\:text-teal-700:hover { + color: #2c7a7b; +} + +.hover\:text-teal-800:hover { + color: #285e61; +} + +.hover\:text-teal-900:hover { + color: #234e52; +} + +.hover\:text-blue-100:hover { + color: #ebf8ff; +} + +.hover\:text-blue-200:hover { + color: #bee3f8; +} + +.hover\:text-blue-300:hover { + color: #90cdf4; +} + +.hover\:text-blue-400:hover { + color: #63b3ed; +} + +.hover\:text-blue-500:hover { + color: #4299e1; +} + +.hover\:text-blue-600:hover { + color: #3182ce; +} + +.hover\:text-blue-700:hover { + color: #2b6cb0; +} + +.hover\:text-blue-800:hover { + color: #2c5282; +} + +.hover\:text-blue-900:hover { + color: #2a4365; +} + +.hover\:text-indigo-100:hover { + color: #ebf4ff; +} + +.hover\:text-indigo-200:hover { + color: #c3dafe; +} + +.hover\:text-indigo-300:hover { + color: #a3bffa; +} + +.hover\:text-indigo-400:hover { + color: #7f9cf5; +} + +.hover\:text-indigo-500:hover { + color: #667eea; +} + +.hover\:text-indigo-600:hover { + color: #5a67d8; +} + +.hover\:text-indigo-700:hover { + color: #4c51bf; +} + +.hover\:text-indigo-800:hover { + color: #434190; +} + +.hover\:text-indigo-900:hover { + color: #3c366b; +} + +.hover\:text-purple-100:hover { + color: #faf5ff; +} + +.hover\:text-purple-200:hover { + color: #e9d8fd; +} + +.hover\:text-purple-300:hover { + color: #d6bcfa; +} + +.hover\:text-purple-400:hover { + color: #b794f4; +} + +.hover\:text-purple-500:hover { + color: #9f7aea; +} + +.hover\:text-purple-600:hover { + color: #805ad5; +} + +.hover\:text-purple-700:hover { + color: #6b46c1; +} + +.hover\:text-purple-800:hover { + color: #553c9a; +} + +.hover\:text-purple-900:hover { + color: #44337a; +} + +.hover\:text-pink-100:hover { + color: #fff5f7; +} + +.hover\:text-pink-200:hover { + color: #fed7e2; +} + +.hover\:text-pink-300:hover { + color: #fbb6ce; +} + +.hover\:text-pink-400:hover { + color: #f687b3; +} + +.hover\:text-pink-500:hover { + color: #ed64a6; +} + +.hover\:text-pink-600:hover { + color: #d53f8c; +} + +.hover\:text-pink-700:hover { + color: #b83280; +} + +.hover\:text-pink-800:hover { + color: #97266d; +} + +.hover\:text-pink-900:hover { + color: #702459; +} + +.focus\:text-transparent:focus { + color: transparent; +} + +.focus\:text-black:focus { + color: #000; +} + +.focus\:text-white:focus { + color: #fff; +} + +.focus\:text-gray-100:focus { + color: #f7fafc; +} + +.focus\:text-gray-200:focus { + color: #edf2f7; +} + +.focus\:text-gray-300:focus { + color: #e2e8f0; +} + +.focus\:text-gray-400:focus { + color: #cbd5e0; +} + +.focus\:text-gray-500:focus { + color: #a0aec0; +} + +.focus\:text-gray-600:focus { + color: #718096; +} + +.focus\:text-gray-700:focus { + color: #4a5568; +} + +.focus\:text-gray-800:focus { + color: #2d3748; +} + +.focus\:text-gray-900:focus { + color: #1a202c; +} + +.focus\:text-red-100:focus { + color: #fff5f5; +} + +.focus\:text-red-200:focus { + color: #fed7d7; +} + +.focus\:text-red-300:focus { + color: #feb2b2; +} + +.focus\:text-red-400:focus { + color: #fc8181; +} + +.focus\:text-red-500:focus { + color: #f56565; +} + +.focus\:text-red-600:focus { + color: #e53e3e; +} + +.focus\:text-red-700:focus { + color: #c53030; +} + +.focus\:text-red-800:focus { + color: #9b2c2c; +} + +.focus\:text-red-900:focus { + color: #742a2a; +} + +.focus\:text-orange-100:focus { + color: #fffaf0; +} + +.focus\:text-orange-200:focus { + color: #feebc8; +} + +.focus\:text-orange-300:focus { + color: #fbd38d; +} + +.focus\:text-orange-400:focus { + color: #f6ad55; +} + +.focus\:text-orange-500:focus { + color: #ed8936; +} + +.focus\:text-orange-600:focus { + color: #dd6b20; +} + +.focus\:text-orange-700:focus { + color: #c05621; +} + +.focus\:text-orange-800:focus { + color: #9c4221; +} + +.focus\:text-orange-900:focus { + color: #7b341e; +} + +.focus\:text-yellow-100:focus { + color: #fffff0; +} + +.focus\:text-yellow-200:focus { + color: #fefcbf; +} + +.focus\:text-yellow-300:focus { + color: #faf089; +} + +.focus\:text-yellow-400:focus { + color: #f6e05e; +} + +.focus\:text-yellow-500:focus { + color: #ecc94b; +} + +.focus\:text-yellow-600:focus { + color: #d69e2e; +} + +.focus\:text-yellow-700:focus { + color: #b7791f; +} + +.focus\:text-yellow-800:focus { + color: #975a16; +} + +.focus\:text-yellow-900:focus { + color: #744210; +} + +.focus\:text-green-100:focus { + color: #f0fff4; +} + +.focus\:text-green-200:focus { + color: #c6f6d5; +} + +.focus\:text-green-300:focus { + color: #9ae6b4; +} + +.focus\:text-green-400:focus { + color: #68d391; +} + +.focus\:text-green-500:focus { + color: #48bb78; +} + +.focus\:text-green-600:focus { + color: #38a169; +} + +.focus\:text-green-700:focus { + color: #2f855a; +} + +.focus\:text-green-800:focus { + color: #276749; +} + +.focus\:text-green-900:focus { + color: #22543d; +} + +.focus\:text-teal-100:focus { + color: #e6fffa; +} + +.focus\:text-teal-200:focus { + color: #b2f5ea; +} + +.focus\:text-teal-300:focus { + color: #81e6d9; +} + +.focus\:text-teal-400:focus { + color: #4fd1c5; +} + +.focus\:text-teal-500:focus { + color: #38b2ac; +} + +.focus\:text-teal-600:focus { + color: #319795; +} + +.focus\:text-teal-700:focus { + color: #2c7a7b; +} + +.focus\:text-teal-800:focus { + color: #285e61; +} + +.focus\:text-teal-900:focus { + color: #234e52; +} + +.focus\:text-blue-100:focus { + color: #ebf8ff; +} + +.focus\:text-blue-200:focus { + color: #bee3f8; +} + +.focus\:text-blue-300:focus { + color: #90cdf4; +} + +.focus\:text-blue-400:focus { + color: #63b3ed; +} + +.focus\:text-blue-500:focus { + color: #4299e1; +} + +.focus\:text-blue-600:focus { + color: #3182ce; +} + +.focus\:text-blue-700:focus { + color: #2b6cb0; +} + +.focus\:text-blue-800:focus { + color: #2c5282; +} + +.focus\:text-blue-900:focus { + color: #2a4365; +} + +.focus\:text-indigo-100:focus { + color: #ebf4ff; +} + +.focus\:text-indigo-200:focus { + color: #c3dafe; +} + +.focus\:text-indigo-300:focus { + color: #a3bffa; +} + +.focus\:text-indigo-400:focus { + color: #7f9cf5; +} + +.focus\:text-indigo-500:focus { + color: #667eea; +} + +.focus\:text-indigo-600:focus { + color: #5a67d8; +} + +.focus\:text-indigo-700:focus { + color: #4c51bf; +} + +.focus\:text-indigo-800:focus { + color: #434190; +} + +.focus\:text-indigo-900:focus { + color: #3c366b; +} + +.focus\:text-purple-100:focus { + color: #faf5ff; +} + +.focus\:text-purple-200:focus { + color: #e9d8fd; +} + +.focus\:text-purple-300:focus { + color: #d6bcfa; +} + +.focus\:text-purple-400:focus { + color: #b794f4; +} + +.focus\:text-purple-500:focus { + color: #9f7aea; +} + +.focus\:text-purple-600:focus { + color: #805ad5; +} + +.focus\:text-purple-700:focus { + color: #6b46c1; +} + +.focus\:text-purple-800:focus { + color: #553c9a; +} + +.focus\:text-purple-900:focus { + color: #44337a; +} + +.focus\:text-pink-100:focus { + color: #fff5f7; +} + +.focus\:text-pink-200:focus { + color: #fed7e2; +} + +.focus\:text-pink-300:focus { + color: #fbb6ce; +} + +.focus\:text-pink-400:focus { + color: #f687b3; +} + +.focus\:text-pink-500:focus { + color: #ed64a6; +} + +.focus\:text-pink-600:focus { + color: #d53f8c; +} + +.focus\:text-pink-700:focus { + color: #b83280; +} + +.focus\:text-pink-800:focus { + color: #97266d; +} + +.focus\:text-pink-900:focus { + color: #702459; +} + +.text-xs { + font-size: 0.75rem; +} + +.text-sm { + font-size: 0.875rem; +} + +.text-base { + font-size: 1rem; +} + +.text-lg { + font-size: 1.125rem; +} + +.text-xl { + font-size: 1.25rem; +} + +.text-2xl { + font-size: 1.5rem; +} + +.text-3xl { + font-size: 1.875rem; +} + +.text-4xl { + font-size: 2.25rem; +} + +.text-5xl { + font-size: 3rem; +} + +.text-6xl { + font-size: 4rem; +} + +.italic { + font-style: italic; +} + +.not-italic { + font-style: normal; +} + +.uppercase { + text-transform: uppercase; +} + +.lowercase { + text-transform: lowercase; +} + +.capitalize { + text-transform: capitalize; +} + +.normal-case { + text-transform: none; +} + +.underline { + text-decoration: underline; +} + +.line-through { + text-decoration: line-through; +} + +.no-underline { + text-decoration: none; +} + +.hover\:underline:hover { + text-decoration: underline; +} + +.hover\:line-through:hover { + text-decoration: line-through; +} + +.hover\:no-underline:hover { + text-decoration: none; +} + +.focus\:underline:focus { + text-decoration: underline; +} + +.focus\:line-through:focus { + text-decoration: line-through; +} + +.focus\:no-underline:focus { + text-decoration: none; +} + +.antialiased { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.subpixel-antialiased { + -webkit-font-smoothing: auto; + -moz-osx-font-smoothing: auto; +} + +.tracking-tighter { + letter-spacing: -0.05em; +} + +.tracking-tight { + letter-spacing: -0.025em; +} + +.tracking-normal { + letter-spacing: 0; +} + +.tracking-wide { + letter-spacing: 0.025em; +} + +.tracking-wider { + letter-spacing: 0.05em; +} + +.tracking-widest { + letter-spacing: 0.1em; +} + +.select-none { + -webkit-user-select: none; + user-select: none; +} + +.select-text { + -webkit-user-select: text; + user-select: text; +} + +.select-all { + -webkit-user-select: all; + user-select: all; +} + +.select-auto { + -webkit-user-select: auto; + user-select: auto; +} + +.align-baseline { + vertical-align: baseline; +} + +.align-top { + vertical-align: top; +} + +.align-middle { + vertical-align: middle; +} + +.align-bottom { + vertical-align: bottom; +} + +.align-text-top { + vertical-align: text-top; +} + +.align-text-bottom { + vertical-align: text-bottom; +} + +.visible { + visibility: visible; +} + +.invisible { + visibility: hidden; +} + +.whitespace-normal { + white-space: normal; +} + +.whitespace-no-wrap { + white-space: nowrap; +} + +.whitespace-pre { + white-space: pre; +} + +.whitespace-pre-line { + white-space: pre-line; +} + +.whitespace-pre-wrap { + white-space: pre-wrap; +} + +.break-normal { + overflow-wrap: normal; + word-break: normal; +} + +.break-words { + overflow-wrap: break-word; +} + +.break-all { + word-break: break-all; +} + +.truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.w-0 { + width: 0; +} + +.w-1 { + width: 0.25rem; +} + +.w-2 { + width: 0.5rem; +} + +.w-3 { + width: 0.75rem; +} + +.w-4 { + width: 1rem; +} + +.w-5 { + width: 1.25rem; +} + +.w-6 { + width: 1.5rem; +} + +.w-8 { + width: 2rem; +} + +.w-10 { + width: 2.5rem; +} + +.w-12 { + width: 3rem; +} + +.w-16 { + width: 4rem; +} + +.w-20 { + width: 5rem; +} + +.w-24 { + width: 6rem; +} + +.w-32 { + width: 8rem; +} + +.w-40 { + width: 10rem; +} + +.w-48 { + width: 12rem; +} + +.w-56 { + width: 14rem; +} + +.w-64 { + width: 16rem; +} + +.w-auto { + width: auto; +} + +.w-px { + width: 1px; +} + +.w-1\/2 { + width: 50%; +} + +.w-1\/3 { + width: 33.333333%; +} + +.w-2\/3 { + width: 66.666667%; +} + +.w-1\/4 { + width: 25%; +} + +.w-2\/4 { + width: 50%; +} + +.w-3\/4 { + width: 75%; +} + +.w-1\/5 { + width: 20%; +} + +.w-2\/5 { + width: 40%; +} + +.w-3\/5 { + width: 60%; +} + +.w-4\/5 { + width: 80%; +} + +.w-1\/6 { + width: 16.666667%; +} + +.w-2\/6 { + width: 33.333333%; +} + +.w-3\/6 { + width: 50%; +} + +.w-4\/6 { + width: 66.666667%; +} + +.w-5\/6 { + width: 83.333333%; +} + +.w-1\/12 { + width: 8.333333%; +} + +.w-2\/12 { + width: 16.666667%; +} + +.w-3\/12 { + width: 25%; +} + +.w-4\/12 { + width: 33.333333%; +} + +.w-5\/12 { + width: 41.666667%; +} + +.w-6\/12 { + width: 50%; +} + +.w-7\/12 { + width: 58.333333%; +} + +.w-8\/12 { + width: 66.666667%; +} + +.w-9\/12 { + width: 75%; +} + +.w-10\/12 { + width: 83.333333%; +} + +.w-11\/12 { + width: 91.666667%; +} + +.w-full { + width: 100%; +} + +.w-screen { + width: 100vw; +} + +.z-0 { + z-index: 0; +} + +.z-10 { + z-index: 10; +} + +.z-20 { + z-index: 20; +} + +.z-30 { + z-index: 30; +} + +.z-40 { + z-index: 40; +} + +.z-50 { + z-index: 50; +} + +.z-auto { + z-index: auto; +} + +.gap-0 { + grid-gap: 0; + gap: 0; +} + +.gap-1 { + grid-gap: 0.25rem; + gap: 0.25rem; +} + +.gap-2 { + grid-gap: 0.5rem; + gap: 0.5rem; +} + +.gap-3 { + grid-gap: 0.75rem; + gap: 0.75rem; +} + +.gap-4 { + grid-gap: 1rem; + gap: 1rem; +} + +.gap-5 { + grid-gap: 1.25rem; + gap: 1.25rem; +} + +.gap-6 { + grid-gap: 1.5rem; + gap: 1.5rem; +} + +.gap-8 { + grid-gap: 2rem; + gap: 2rem; +} + +.gap-10 { + grid-gap: 2.5rem; + gap: 2.5rem; +} + +.gap-12 { + grid-gap: 3rem; + gap: 3rem; +} + +.gap-16 { + grid-gap: 4rem; + gap: 4rem; +} + +.gap-20 { + grid-gap: 5rem; + gap: 5rem; +} + +.gap-24 { + grid-gap: 6rem; + gap: 6rem; +} + +.gap-32 { + grid-gap: 8rem; + gap: 8rem; +} + +.gap-40 { + grid-gap: 10rem; + gap: 10rem; +} + +.gap-48 { + grid-gap: 12rem; + gap: 12rem; +} + +.gap-56 { + grid-gap: 14rem; + gap: 14rem; +} + +.gap-64 { + grid-gap: 16rem; + gap: 16rem; +} + +.gap-px { + grid-gap: 1px; + gap: 1px; +} + +.col-gap-0 { + grid-column-gap: 0; + column-gap: 0; +} + +.col-gap-1 { + grid-column-gap: 0.25rem; + column-gap: 0.25rem; +} + +.col-gap-2 { + grid-column-gap: 0.5rem; + column-gap: 0.5rem; +} + +.col-gap-3 { + grid-column-gap: 0.75rem; + column-gap: 0.75rem; +} + +.col-gap-4 { + grid-column-gap: 1rem; + column-gap: 1rem; +} + +.col-gap-5 { + grid-column-gap: 1.25rem; + column-gap: 1.25rem; +} + +.col-gap-6 { + grid-column-gap: 1.5rem; + column-gap: 1.5rem; +} + +.col-gap-8 { + grid-column-gap: 2rem; + column-gap: 2rem; +} + +.col-gap-10 { + grid-column-gap: 2.5rem; + column-gap: 2.5rem; +} + +.col-gap-12 { + grid-column-gap: 3rem; + column-gap: 3rem; +} + +.col-gap-16 { + grid-column-gap: 4rem; + column-gap: 4rem; +} + +.col-gap-20 { + grid-column-gap: 5rem; + column-gap: 5rem; +} + +.col-gap-24 { + grid-column-gap: 6rem; + column-gap: 6rem; +} + +.col-gap-32 { + grid-column-gap: 8rem; + column-gap: 8rem; +} + +.col-gap-40 { + grid-column-gap: 10rem; + column-gap: 10rem; +} + +.col-gap-48 { + grid-column-gap: 12rem; + column-gap: 12rem; +} + +.col-gap-56 { + grid-column-gap: 14rem; + column-gap: 14rem; +} + +.col-gap-64 { + grid-column-gap: 16rem; + column-gap: 16rem; +} + +.col-gap-px { + grid-column-gap: 1px; + column-gap: 1px; +} + +.row-gap-0 { + grid-row-gap: 0; + row-gap: 0; +} + +.row-gap-1 { + grid-row-gap: 0.25rem; + row-gap: 0.25rem; +} + +.row-gap-2 { + grid-row-gap: 0.5rem; + row-gap: 0.5rem; +} + +.row-gap-3 { + grid-row-gap: 0.75rem; + row-gap: 0.75rem; +} + +.row-gap-4 { + grid-row-gap: 1rem; + row-gap: 1rem; +} + +.row-gap-5 { + grid-row-gap: 1.25rem; + row-gap: 1.25rem; +} + +.row-gap-6 { + grid-row-gap: 1.5rem; + row-gap: 1.5rem; +} + +.row-gap-8 { + grid-row-gap: 2rem; + row-gap: 2rem; +} + +.row-gap-10 { + grid-row-gap: 2.5rem; + row-gap: 2.5rem; +} + +.row-gap-12 { + grid-row-gap: 3rem; + row-gap: 3rem; +} + +.row-gap-16 { + grid-row-gap: 4rem; + row-gap: 4rem; +} + +.row-gap-20 { + grid-row-gap: 5rem; + row-gap: 5rem; +} + +.row-gap-24 { + grid-row-gap: 6rem; + row-gap: 6rem; +} + +.row-gap-32 { + grid-row-gap: 8rem; + row-gap: 8rem; +} + +.row-gap-40 { + grid-row-gap: 10rem; + row-gap: 10rem; +} + +.row-gap-48 { + grid-row-gap: 12rem; + row-gap: 12rem; +} + +.row-gap-56 { + grid-row-gap: 14rem; + row-gap: 14rem; +} + +.row-gap-64 { + grid-row-gap: 16rem; + row-gap: 16rem; +} + +.row-gap-px { + grid-row-gap: 1px; + row-gap: 1px; +} + +.grid-flow-row { + grid-auto-flow: row; +} + +.grid-flow-col { + grid-auto-flow: column; +} + +.grid-flow-row-dense { + grid-auto-flow: row dense; +} + +.grid-flow-col-dense { + grid-auto-flow: column dense; +} + +.grid-cols-1 { + grid-template-columns: repeat(1, minmax(0, 1fr)); +} + +.grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.grid-cols-4 { + grid-template-columns: repeat(4, minmax(0, 1fr)); +} + +.grid-cols-5 { + grid-template-columns: repeat(5, minmax(0, 1fr)); +} + +.grid-cols-6 { + grid-template-columns: repeat(6, minmax(0, 1fr)); +} + +.grid-cols-7 { + grid-template-columns: repeat(7, minmax(0, 1fr)); +} + +.grid-cols-8 { + grid-template-columns: repeat(8, minmax(0, 1fr)); +} + +.grid-cols-9 { + grid-template-columns: repeat(9, minmax(0, 1fr)); +} + +.grid-cols-10 { + grid-template-columns: repeat(10, minmax(0, 1fr)); +} + +.grid-cols-11 { + grid-template-columns: repeat(11, minmax(0, 1fr)); +} + +.grid-cols-12 { + grid-template-columns: repeat(12, minmax(0, 1fr)); +} + +.grid-cols-none { + grid-template-columns: none; +} + +.col-auto { + grid-column: auto; +} + +.col-span-1 { + grid-column: span 1 / span 1; +} + +.col-span-2 { + grid-column: span 2 / span 2; +} + +.col-span-3 { + grid-column: span 3 / span 3; +} + +.col-span-4 { + grid-column: span 4 / span 4; +} + +.col-span-5 { + grid-column: span 5 / span 5; +} + +.col-span-6 { + grid-column: span 6 / span 6; +} + +.col-span-7 { + grid-column: span 7 / span 7; +} + +.col-span-8 { + grid-column: span 8 / span 8; +} + +.col-span-9 { + grid-column: span 9 / span 9; +} + +.col-span-10 { + grid-column: span 10 / span 10; +} + +.col-span-11 { + grid-column: span 11 / span 11; +} + +.col-span-12 { + grid-column: span 12 / span 12; +} + +.col-start-1 { + grid-column-start: 1; +} + +.col-start-2 { + grid-column-start: 2; +} + +.col-start-3 { + grid-column-start: 3; +} + +.col-start-4 { + grid-column-start: 4; +} + +.col-start-5 { + grid-column-start: 5; +} + +.col-start-6 { + grid-column-start: 6; +} + +.col-start-7 { + grid-column-start: 7; +} + +.col-start-8 { + grid-column-start: 8; +} + +.col-start-9 { + grid-column-start: 9; +} + +.col-start-10 { + grid-column-start: 10; +} + +.col-start-11 { + grid-column-start: 11; +} + +.col-start-12 { + grid-column-start: 12; +} + +.col-start-13 { + grid-column-start: 13; +} + +.col-start-auto { + grid-column-start: auto; +} + +.col-end-1 { + grid-column-end: 1; +} + +.col-end-2 { + grid-column-end: 2; +} + +.col-end-3 { + grid-column-end: 3; +} + +.col-end-4 { + grid-column-end: 4; +} + +.col-end-5 { + grid-column-end: 5; +} + +.col-end-6 { + grid-column-end: 6; +} + +.col-end-7 { + grid-column-end: 7; +} + +.col-end-8 { + grid-column-end: 8; +} + +.col-end-9 { + grid-column-end: 9; +} + +.col-end-10 { + grid-column-end: 10; +} + +.col-end-11 { + grid-column-end: 11; +} + +.col-end-12 { + grid-column-end: 12; +} + +.col-end-13 { + grid-column-end: 13; +} + +.col-end-auto { + grid-column-end: auto; +} + +.grid-rows-1 { + grid-template-rows: repeat(1, minmax(0, 1fr)); +} + +.grid-rows-2 { + grid-template-rows: repeat(2, minmax(0, 1fr)); +} + +.grid-rows-3 { + grid-template-rows: repeat(3, minmax(0, 1fr)); +} + +.grid-rows-4 { + grid-template-rows: repeat(4, minmax(0, 1fr)); +} + +.grid-rows-5 { + grid-template-rows: repeat(5, minmax(0, 1fr)); +} + +.grid-rows-6 { + grid-template-rows: repeat(6, minmax(0, 1fr)); +} + +.grid-rows-none { + grid-template-rows: none; +} + +.row-auto { + grid-row: auto; +} + +.row-span-1 { + grid-row: span 1 / span 1; +} + +.row-span-2 { + grid-row: span 2 / span 2; +} + +.row-span-3 { + grid-row: span 3 / span 3; +} + +.row-span-4 { + grid-row: span 4 / span 4; +} + +.row-span-5 { + grid-row: span 5 / span 5; +} + +.row-span-6 { + grid-row: span 6 / span 6; +} + +.row-start-1 { + grid-row-start: 1; +} + +.row-start-2 { + grid-row-start: 2; +} + +.row-start-3 { + grid-row-start: 3; +} + +.row-start-4 { + grid-row-start: 4; +} + +.row-start-5 { + grid-row-start: 5; +} + +.row-start-6 { + grid-row-start: 6; +} + +.row-start-7 { + grid-row-start: 7; +} + +.row-start-auto { + grid-row-start: auto; +} + +.row-end-1 { + grid-row-end: 1; +} + +.row-end-2 { + grid-row-end: 2; +} + +.row-end-3 { + grid-row-end: 3; +} + +.row-end-4 { + grid-row-end: 4; +} + +.row-end-5 { + grid-row-end: 5; +} + +.row-end-6 { + grid-row-end: 6; +} + +.row-end-7 { + grid-row-end: 7; +} + +.row-end-auto { + grid-row-end: auto; +} + +.transform { + --transform-translate-x: 0; + --transform-translate-y: 0; + --transform-rotate: 0; + --transform-skew-x: 0; + --transform-skew-y: 0; + --transform-scale-x: 1; + --transform-scale-y: 1; + transform: translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y)); +} + +.transform-none { + transform: none; +} + +.origin-center { + transform-origin: center; +} + +.origin-top { + transform-origin: top; +} + +.origin-top-right { + transform-origin: top right; +} + +.origin-right { + transform-origin: right; +} + +.origin-bottom-right { + transform-origin: bottom right; +} + +.origin-bottom { + transform-origin: bottom; +} + +.origin-bottom-left { + transform-origin: bottom left; +} + +.origin-left { + transform-origin: left; +} + +.origin-top-left { + transform-origin: top left; +} + +.scale-0 { + --transform-scale-x: 0; + --transform-scale-y: 0; +} + +.scale-50 { + --transform-scale-x: .5; + --transform-scale-y: .5; +} + +.scale-75 { + --transform-scale-x: .75; + --transform-scale-y: .75; +} + +.scale-90 { + --transform-scale-x: .9; + --transform-scale-y: .9; +} + +.scale-95 { + --transform-scale-x: .95; + --transform-scale-y: .95; +} + +.scale-100 { + --transform-scale-x: 1; + --transform-scale-y: 1; +} + +.scale-105 { + --transform-scale-x: 1.05; + --transform-scale-y: 1.05; +} + +.scale-110 { + --transform-scale-x: 1.1; + --transform-scale-y: 1.1; +} + +.scale-125 { + --transform-scale-x: 1.25; + --transform-scale-y: 1.25; +} + +.scale-150 { + --transform-scale-x: 1.5; + --transform-scale-y: 1.5; +} + +.scale-x-0 { + --transform-scale-x: 0; +} + +.scale-x-50 { + --transform-scale-x: .5; +} + +.scale-x-75 { + --transform-scale-x: .75; +} + +.scale-x-90 { + --transform-scale-x: .9; +} + +.scale-x-95 { + --transform-scale-x: .95; +} + +.scale-x-100 { + --transform-scale-x: 1; +} + +.scale-x-105 { + --transform-scale-x: 1.05; +} + +.scale-x-110 { + --transform-scale-x: 1.1; +} + +.scale-x-125 { + --transform-scale-x: 1.25; +} + +.scale-x-150 { + --transform-scale-x: 1.5; +} + +.scale-y-0 { + --transform-scale-y: 0; +} + +.scale-y-50 { + --transform-scale-y: .5; +} + +.scale-y-75 { + --transform-scale-y: .75; +} + +.scale-y-90 { + --transform-scale-y: .9; +} + +.scale-y-95 { + --transform-scale-y: .95; +} + +.scale-y-100 { + --transform-scale-y: 1; +} + +.scale-y-105 { + --transform-scale-y: 1.05; +} + +.scale-y-110 { + --transform-scale-y: 1.1; +} + +.scale-y-125 { + --transform-scale-y: 1.25; +} + +.scale-y-150 { + --transform-scale-y: 1.5; +} + +.hover\:scale-0:hover { + --transform-scale-x: 0; + --transform-scale-y: 0; +} + +.hover\:scale-50:hover { + --transform-scale-x: .5; + --transform-scale-y: .5; +} + +.hover\:scale-75:hover { + --transform-scale-x: .75; + --transform-scale-y: .75; +} + +.hover\:scale-90:hover { + --transform-scale-x: .9; + --transform-scale-y: .9; +} + +.hover\:scale-95:hover { + --transform-scale-x: .95; + --transform-scale-y: .95; +} + +.hover\:scale-100:hover { + --transform-scale-x: 1; + --transform-scale-y: 1; +} + +.hover\:scale-105:hover { + --transform-scale-x: 1.05; + --transform-scale-y: 1.05; +} + +.hover\:scale-110:hover { + --transform-scale-x: 1.1; + --transform-scale-y: 1.1; +} + +.hover\:scale-125:hover { + --transform-scale-x: 1.25; + --transform-scale-y: 1.25; +} + +.hover\:scale-150:hover { + --transform-scale-x: 1.5; + --transform-scale-y: 1.5; +} + +.hover\:scale-x-0:hover { + --transform-scale-x: 0; +} + +.hover\:scale-x-50:hover { + --transform-scale-x: .5; +} + +.hover\:scale-x-75:hover { + --transform-scale-x: .75; +} + +.hover\:scale-x-90:hover { + --transform-scale-x: .9; +} + +.hover\:scale-x-95:hover { + --transform-scale-x: .95; +} + +.hover\:scale-x-100:hover { + --transform-scale-x: 1; +} + +.hover\:scale-x-105:hover { + --transform-scale-x: 1.05; +} + +.hover\:scale-x-110:hover { + --transform-scale-x: 1.1; +} + +.hover\:scale-x-125:hover { + --transform-scale-x: 1.25; +} + +.hover\:scale-x-150:hover { + --transform-scale-x: 1.5; +} + +.hover\:scale-y-0:hover { + --transform-scale-y: 0; +} + +.hover\:scale-y-50:hover { + --transform-scale-y: .5; +} + +.hover\:scale-y-75:hover { + --transform-scale-y: .75; +} + +.hover\:scale-y-90:hover { + --transform-scale-y: .9; +} + +.hover\:scale-y-95:hover { + --transform-scale-y: .95; +} + +.hover\:scale-y-100:hover { + --transform-scale-y: 1; +} + +.hover\:scale-y-105:hover { + --transform-scale-y: 1.05; +} + +.hover\:scale-y-110:hover { + --transform-scale-y: 1.1; +} + +.hover\:scale-y-125:hover { + --transform-scale-y: 1.25; +} + +.hover\:scale-y-150:hover { + --transform-scale-y: 1.5; +} + +.focus\:scale-0:focus { + --transform-scale-x: 0; + --transform-scale-y: 0; +} + +.focus\:scale-50:focus { + --transform-scale-x: .5; + --transform-scale-y: .5; +} + +.focus\:scale-75:focus { + --transform-scale-x: .75; + --transform-scale-y: .75; +} + +.focus\:scale-90:focus { + --transform-scale-x: .9; + --transform-scale-y: .9; +} + +.focus\:scale-95:focus { + --transform-scale-x: .95; + --transform-scale-y: .95; +} + +.focus\:scale-100:focus { + --transform-scale-x: 1; + --transform-scale-y: 1; +} + +.focus\:scale-105:focus { + --transform-scale-x: 1.05; + --transform-scale-y: 1.05; +} + +.focus\:scale-110:focus { + --transform-scale-x: 1.1; + --transform-scale-y: 1.1; +} + +.focus\:scale-125:focus { + --transform-scale-x: 1.25; + --transform-scale-y: 1.25; +} + +.focus\:scale-150:focus { + --transform-scale-x: 1.5; + --transform-scale-y: 1.5; +} + +.focus\:scale-x-0:focus { + --transform-scale-x: 0; +} + +.focus\:scale-x-50:focus { + --transform-scale-x: .5; +} + +.focus\:scale-x-75:focus { + --transform-scale-x: .75; +} + +.focus\:scale-x-90:focus { + --transform-scale-x: .9; +} + +.focus\:scale-x-95:focus { + --transform-scale-x: .95; +} + +.focus\:scale-x-100:focus { + --transform-scale-x: 1; +} + +.focus\:scale-x-105:focus { + --transform-scale-x: 1.05; +} + +.focus\:scale-x-110:focus { + --transform-scale-x: 1.1; +} + +.focus\:scale-x-125:focus { + --transform-scale-x: 1.25; +} + +.focus\:scale-x-150:focus { + --transform-scale-x: 1.5; +} + +.focus\:scale-y-0:focus { + --transform-scale-y: 0; +} + +.focus\:scale-y-50:focus { + --transform-scale-y: .5; +} + +.focus\:scale-y-75:focus { + --transform-scale-y: .75; +} + +.focus\:scale-y-90:focus { + --transform-scale-y: .9; +} + +.focus\:scale-y-95:focus { + --transform-scale-y: .95; +} + +.focus\:scale-y-100:focus { + --transform-scale-y: 1; +} + +.focus\:scale-y-105:focus { + --transform-scale-y: 1.05; +} + +.focus\:scale-y-110:focus { + --transform-scale-y: 1.1; +} + +.focus\:scale-y-125:focus { + --transform-scale-y: 1.25; +} + +.focus\:scale-y-150:focus { + --transform-scale-y: 1.5; +} + +.rotate-0 { + --transform-rotate: 0; +} + +.rotate-45 { + --transform-rotate: 45deg; +} + +.rotate-90 { + --transform-rotate: 90deg; +} + +.rotate-180 { + --transform-rotate: 180deg; +} + +.-rotate-180 { + --transform-rotate: -180deg; +} + +.-rotate-90 { + --transform-rotate: -90deg; +} + +.-rotate-45 { + --transform-rotate: -45deg; +} + +.hover\:rotate-0:hover { + --transform-rotate: 0; +} + +.hover\:rotate-45:hover { + --transform-rotate: 45deg; +} + +.hover\:rotate-90:hover { + --transform-rotate: 90deg; +} + +.hover\:rotate-180:hover { + --transform-rotate: 180deg; +} + +.hover\:-rotate-180:hover { + --transform-rotate: -180deg; +} + +.hover\:-rotate-90:hover { + --transform-rotate: -90deg; +} + +.hover\:-rotate-45:hover { + --transform-rotate: -45deg; +} + +.focus\:rotate-0:focus { + --transform-rotate: 0; +} + +.focus\:rotate-45:focus { + --transform-rotate: 45deg; +} + +.focus\:rotate-90:focus { + --transform-rotate: 90deg; +} + +.focus\:rotate-180:focus { + --transform-rotate: 180deg; +} + +.focus\:-rotate-180:focus { + --transform-rotate: -180deg; +} + +.focus\:-rotate-90:focus { + --transform-rotate: -90deg; +} + +.focus\:-rotate-45:focus { + --transform-rotate: -45deg; +} + +.translate-x-0 { + --transform-translate-x: 0; +} + +.translate-x-1 { + --transform-translate-x: 0.25rem; +} + +.translate-x-2 { + --transform-translate-x: 0.5rem; +} + +.translate-x-3 { + --transform-translate-x: 0.75rem; +} + +.translate-x-4 { + --transform-translate-x: 1rem; +} + +.translate-x-5 { + --transform-translate-x: 1.25rem; +} + +.translate-x-6 { + --transform-translate-x: 1.5rem; +} + +.translate-x-8 { + --transform-translate-x: 2rem; +} + +.translate-x-10 { + --transform-translate-x: 2.5rem; +} + +.translate-x-12 { + --transform-translate-x: 3rem; +} + +.translate-x-16 { + --transform-translate-x: 4rem; +} + +.translate-x-20 { + --transform-translate-x: 5rem; +} + +.translate-x-24 { + --transform-translate-x: 6rem; +} + +.translate-x-32 { + --transform-translate-x: 8rem; +} + +.translate-x-40 { + --transform-translate-x: 10rem; +} + +.translate-x-48 { + --transform-translate-x: 12rem; +} + +.translate-x-56 { + --transform-translate-x: 14rem; +} + +.translate-x-64 { + --transform-translate-x: 16rem; +} + +.translate-x-px { + --transform-translate-x: 1px; +} + +.-translate-x-1 { + --transform-translate-x: -0.25rem; +} + +.-translate-x-2 { + --transform-translate-x: -0.5rem; +} + +.-translate-x-3 { + --transform-translate-x: -0.75rem; +} + +.-translate-x-4 { + --transform-translate-x: -1rem; +} + +.-translate-x-5 { + --transform-translate-x: -1.25rem; +} + +.-translate-x-6 { + --transform-translate-x: -1.5rem; +} + +.-translate-x-8 { + --transform-translate-x: -2rem; +} + +.-translate-x-10 { + --transform-translate-x: -2.5rem; +} + +.-translate-x-12 { + --transform-translate-x: -3rem; +} + +.-translate-x-16 { + --transform-translate-x: -4rem; +} + +.-translate-x-20 { + --transform-translate-x: -5rem; +} + +.-translate-x-24 { + --transform-translate-x: -6rem; +} + +.-translate-x-32 { + --transform-translate-x: -8rem; +} + +.-translate-x-40 { + --transform-translate-x: -10rem; +} + +.-translate-x-48 { + --transform-translate-x: -12rem; +} + +.-translate-x-56 { + --transform-translate-x: -14rem; +} + +.-translate-x-64 { + --transform-translate-x: -16rem; +} + +.-translate-x-px { + --transform-translate-x: -1px; +} + +.-translate-x-full { + --transform-translate-x: -100%; +} + +.-translate-x-1\/2 { + --transform-translate-x: -50%; +} + +.translate-x-1\/2 { + --transform-translate-x: 50%; +} + +.translate-x-full { + --transform-translate-x: 100%; +} + +.translate-y-0 { + --transform-translate-y: 0; +} + +.translate-y-1 { + --transform-translate-y: 0.25rem; +} + +.translate-y-2 { + --transform-translate-y: 0.5rem; +} + +.translate-y-3 { + --transform-translate-y: 0.75rem; +} + +.translate-y-4 { + --transform-translate-y: 1rem; +} + +.translate-y-5 { + --transform-translate-y: 1.25rem; +} + +.translate-y-6 { + --transform-translate-y: 1.5rem; +} + +.translate-y-8 { + --transform-translate-y: 2rem; +} + +.translate-y-10 { + --transform-translate-y: 2.5rem; +} + +.translate-y-12 { + --transform-translate-y: 3rem; +} + +.translate-y-16 { + --transform-translate-y: 4rem; +} + +.translate-y-20 { + --transform-translate-y: 5rem; +} + +.translate-y-24 { + --transform-translate-y: 6rem; +} + +.translate-y-32 { + --transform-translate-y: 8rem; +} + +.translate-y-40 { + --transform-translate-y: 10rem; +} + +.translate-y-48 { + --transform-translate-y: 12rem; +} + +.translate-y-56 { + --transform-translate-y: 14rem; +} + +.translate-y-64 { + --transform-translate-y: 16rem; +} + +.translate-y-px { + --transform-translate-y: 1px; +} + +.-translate-y-1 { + --transform-translate-y: -0.25rem; +} + +.-translate-y-2 { + --transform-translate-y: -0.5rem; +} + +.-translate-y-3 { + --transform-translate-y: -0.75rem; +} + +.-translate-y-4 { + --transform-translate-y: -1rem; +} + +.-translate-y-5 { + --transform-translate-y: -1.25rem; +} + +.-translate-y-6 { + --transform-translate-y: -1.5rem; +} + +.-translate-y-8 { + --transform-translate-y: -2rem; +} + +.-translate-y-10 { + --transform-translate-y: -2.5rem; +} + +.-translate-y-12 { + --transform-translate-y: -3rem; +} + +.-translate-y-16 { + --transform-translate-y: -4rem; +} + +.-translate-y-20 { + --transform-translate-y: -5rem; +} + +.-translate-y-24 { + --transform-translate-y: -6rem; +} + +.-translate-y-32 { + --transform-translate-y: -8rem; +} + +.-translate-y-40 { + --transform-translate-y: -10rem; +} + +.-translate-y-48 { + --transform-translate-y: -12rem; +} + +.-translate-y-56 { + --transform-translate-y: -14rem; +} + +.-translate-y-64 { + --transform-translate-y: -16rem; +} + +.-translate-y-px { + --transform-translate-y: -1px; +} + +.-translate-y-full { + --transform-translate-y: -100%; +} + +.-translate-y-1\/2 { + --transform-translate-y: -50%; +} + +.translate-y-1\/2 { + --transform-translate-y: 50%; +} + +.translate-y-full { + --transform-translate-y: 100%; +} + +.hover\:translate-x-0:hover { + --transform-translate-x: 0; +} + +.hover\:translate-x-1:hover { + --transform-translate-x: 0.25rem; +} + +.hover\:translate-x-2:hover { + --transform-translate-x: 0.5rem; +} + +.hover\:translate-x-3:hover { + --transform-translate-x: 0.75rem; +} + +.hover\:translate-x-4:hover { + --transform-translate-x: 1rem; +} + +.hover\:translate-x-5:hover { + --transform-translate-x: 1.25rem; +} + +.hover\:translate-x-6:hover { + --transform-translate-x: 1.5rem; +} + +.hover\:translate-x-8:hover { + --transform-translate-x: 2rem; +} + +.hover\:translate-x-10:hover { + --transform-translate-x: 2.5rem; +} + +.hover\:translate-x-12:hover { + --transform-translate-x: 3rem; +} + +.hover\:translate-x-16:hover { + --transform-translate-x: 4rem; +} + +.hover\:translate-x-20:hover { + --transform-translate-x: 5rem; +} + +.hover\:translate-x-24:hover { + --transform-translate-x: 6rem; +} + +.hover\:translate-x-32:hover { + --transform-translate-x: 8rem; +} + +.hover\:translate-x-40:hover { + --transform-translate-x: 10rem; +} + +.hover\:translate-x-48:hover { + --transform-translate-x: 12rem; +} + +.hover\:translate-x-56:hover { + --transform-translate-x: 14rem; +} + +.hover\:translate-x-64:hover { + --transform-translate-x: 16rem; +} + +.hover\:translate-x-px:hover { + --transform-translate-x: 1px; +} + +.hover\:-translate-x-1:hover { + --transform-translate-x: -0.25rem; +} + +.hover\:-translate-x-2:hover { + --transform-translate-x: -0.5rem; +} + +.hover\:-translate-x-3:hover { + --transform-translate-x: -0.75rem; +} + +.hover\:-translate-x-4:hover { + --transform-translate-x: -1rem; +} + +.hover\:-translate-x-5:hover { + --transform-translate-x: -1.25rem; +} + +.hover\:-translate-x-6:hover { + --transform-translate-x: -1.5rem; +} + +.hover\:-translate-x-8:hover { + --transform-translate-x: -2rem; +} + +.hover\:-translate-x-10:hover { + --transform-translate-x: -2.5rem; +} + +.hover\:-translate-x-12:hover { + --transform-translate-x: -3rem; +} + +.hover\:-translate-x-16:hover { + --transform-translate-x: -4rem; +} + +.hover\:-translate-x-20:hover { + --transform-translate-x: -5rem; +} + +.hover\:-translate-x-24:hover { + --transform-translate-x: -6rem; +} + +.hover\:-translate-x-32:hover { + --transform-translate-x: -8rem; +} + +.hover\:-translate-x-40:hover { + --transform-translate-x: -10rem; +} + +.hover\:-translate-x-48:hover { + --transform-translate-x: -12rem; +} + +.hover\:-translate-x-56:hover { + --transform-translate-x: -14rem; +} + +.hover\:-translate-x-64:hover { + --transform-translate-x: -16rem; +} + +.hover\:-translate-x-px:hover { + --transform-translate-x: -1px; +} + +.hover\:-translate-x-full:hover { + --transform-translate-x: -100%; +} + +.hover\:-translate-x-1\/2:hover { + --transform-translate-x: -50%; +} + +.hover\:translate-x-1\/2:hover { + --transform-translate-x: 50%; +} + +.hover\:translate-x-full:hover { + --transform-translate-x: 100%; +} + +.hover\:translate-y-0:hover { + --transform-translate-y: 0; +} + +.hover\:translate-y-1:hover { + --transform-translate-y: 0.25rem; +} + +.hover\:translate-y-2:hover { + --transform-translate-y: 0.5rem; +} + +.hover\:translate-y-3:hover { + --transform-translate-y: 0.75rem; +} + +.hover\:translate-y-4:hover { + --transform-translate-y: 1rem; +} + +.hover\:translate-y-5:hover { + --transform-translate-y: 1.25rem; +} + +.hover\:translate-y-6:hover { + --transform-translate-y: 1.5rem; +} + +.hover\:translate-y-8:hover { + --transform-translate-y: 2rem; +} + +.hover\:translate-y-10:hover { + --transform-translate-y: 2.5rem; +} + +.hover\:translate-y-12:hover { + --transform-translate-y: 3rem; +} + +.hover\:translate-y-16:hover { + --transform-translate-y: 4rem; +} + +.hover\:translate-y-20:hover { + --transform-translate-y: 5rem; +} + +.hover\:translate-y-24:hover { + --transform-translate-y: 6rem; +} + +.hover\:translate-y-32:hover { + --transform-translate-y: 8rem; +} + +.hover\:translate-y-40:hover { + --transform-translate-y: 10rem; +} + +.hover\:translate-y-48:hover { + --transform-translate-y: 12rem; +} + +.hover\:translate-y-56:hover { + --transform-translate-y: 14rem; +} + +.hover\:translate-y-64:hover { + --transform-translate-y: 16rem; +} + +.hover\:translate-y-px:hover { + --transform-translate-y: 1px; +} + +.hover\:-translate-y-1:hover { + --transform-translate-y: -0.25rem; +} + +.hover\:-translate-y-2:hover { + --transform-translate-y: -0.5rem; +} + +.hover\:-translate-y-3:hover { + --transform-translate-y: -0.75rem; +} + +.hover\:-translate-y-4:hover { + --transform-translate-y: -1rem; +} + +.hover\:-translate-y-5:hover { + --transform-translate-y: -1.25rem; +} + +.hover\:-translate-y-6:hover { + --transform-translate-y: -1.5rem; +} + +.hover\:-translate-y-8:hover { + --transform-translate-y: -2rem; +} + +.hover\:-translate-y-10:hover { + --transform-translate-y: -2.5rem; +} + +.hover\:-translate-y-12:hover { + --transform-translate-y: -3rem; +} + +.hover\:-translate-y-16:hover { + --transform-translate-y: -4rem; +} + +.hover\:-translate-y-20:hover { + --transform-translate-y: -5rem; +} + +.hover\:-translate-y-24:hover { + --transform-translate-y: -6rem; +} + +.hover\:-translate-y-32:hover { + --transform-translate-y: -8rem; +} + +.hover\:-translate-y-40:hover { + --transform-translate-y: -10rem; +} + +.hover\:-translate-y-48:hover { + --transform-translate-y: -12rem; +} + +.hover\:-translate-y-56:hover { + --transform-translate-y: -14rem; +} + +.hover\:-translate-y-64:hover { + --transform-translate-y: -16rem; +} + +.hover\:-translate-y-px:hover { + --transform-translate-y: -1px; +} + +.hover\:-translate-y-full:hover { + --transform-translate-y: -100%; +} + +.hover\:-translate-y-1\/2:hover { + --transform-translate-y: -50%; +} + +.hover\:translate-y-1\/2:hover { + --transform-translate-y: 50%; +} + +.hover\:translate-y-full:hover { + --transform-translate-y: 100%; +} + +.focus\:translate-x-0:focus { + --transform-translate-x: 0; +} + +.focus\:translate-x-1:focus { + --transform-translate-x: 0.25rem; +} + +.focus\:translate-x-2:focus { + --transform-translate-x: 0.5rem; +} + +.focus\:translate-x-3:focus { + --transform-translate-x: 0.75rem; +} + +.focus\:translate-x-4:focus { + --transform-translate-x: 1rem; +} + +.focus\:translate-x-5:focus { + --transform-translate-x: 1.25rem; +} + +.focus\:translate-x-6:focus { + --transform-translate-x: 1.5rem; +} + +.focus\:translate-x-8:focus { + --transform-translate-x: 2rem; +} + +.focus\:translate-x-10:focus { + --transform-translate-x: 2.5rem; +} + +.focus\:translate-x-12:focus { + --transform-translate-x: 3rem; +} + +.focus\:translate-x-16:focus { + --transform-translate-x: 4rem; +} + +.focus\:translate-x-20:focus { + --transform-translate-x: 5rem; +} + +.focus\:translate-x-24:focus { + --transform-translate-x: 6rem; +} + +.focus\:translate-x-32:focus { + --transform-translate-x: 8rem; +} + +.focus\:translate-x-40:focus { + --transform-translate-x: 10rem; +} + +.focus\:translate-x-48:focus { + --transform-translate-x: 12rem; +} + +.focus\:translate-x-56:focus { + --transform-translate-x: 14rem; +} + +.focus\:translate-x-64:focus { + --transform-translate-x: 16rem; +} + +.focus\:translate-x-px:focus { + --transform-translate-x: 1px; +} + +.focus\:-translate-x-1:focus { + --transform-translate-x: -0.25rem; +} + +.focus\:-translate-x-2:focus { + --transform-translate-x: -0.5rem; +} + +.focus\:-translate-x-3:focus { + --transform-translate-x: -0.75rem; +} + +.focus\:-translate-x-4:focus { + --transform-translate-x: -1rem; +} + +.focus\:-translate-x-5:focus { + --transform-translate-x: -1.25rem; +} + +.focus\:-translate-x-6:focus { + --transform-translate-x: -1.5rem; +} + +.focus\:-translate-x-8:focus { + --transform-translate-x: -2rem; +} + +.focus\:-translate-x-10:focus { + --transform-translate-x: -2.5rem; +} + +.focus\:-translate-x-12:focus { + --transform-translate-x: -3rem; +} + +.focus\:-translate-x-16:focus { + --transform-translate-x: -4rem; +} + +.focus\:-translate-x-20:focus { + --transform-translate-x: -5rem; +} + +.focus\:-translate-x-24:focus { + --transform-translate-x: -6rem; +} + +.focus\:-translate-x-32:focus { + --transform-translate-x: -8rem; +} + +.focus\:-translate-x-40:focus { + --transform-translate-x: -10rem; +} + +.focus\:-translate-x-48:focus { + --transform-translate-x: -12rem; +} + +.focus\:-translate-x-56:focus { + --transform-translate-x: -14rem; +} + +.focus\:-translate-x-64:focus { + --transform-translate-x: -16rem; +} + +.focus\:-translate-x-px:focus { + --transform-translate-x: -1px; +} + +.focus\:-translate-x-full:focus { + --transform-translate-x: -100%; +} + +.focus\:-translate-x-1\/2:focus { + --transform-translate-x: -50%; +} + +.focus\:translate-x-1\/2:focus { + --transform-translate-x: 50%; +} + +.focus\:translate-x-full:focus { + --transform-translate-x: 100%; +} + +.focus\:translate-y-0:focus { + --transform-translate-y: 0; +} + +.focus\:translate-y-1:focus { + --transform-translate-y: 0.25rem; +} + +.focus\:translate-y-2:focus { + --transform-translate-y: 0.5rem; +} + +.focus\:translate-y-3:focus { + --transform-translate-y: 0.75rem; +} + +.focus\:translate-y-4:focus { + --transform-translate-y: 1rem; +} + +.focus\:translate-y-5:focus { + --transform-translate-y: 1.25rem; +} + +.focus\:translate-y-6:focus { + --transform-translate-y: 1.5rem; +} + +.focus\:translate-y-8:focus { + --transform-translate-y: 2rem; +} + +.focus\:translate-y-10:focus { + --transform-translate-y: 2.5rem; +} + +.focus\:translate-y-12:focus { + --transform-translate-y: 3rem; +} + +.focus\:translate-y-16:focus { + --transform-translate-y: 4rem; +} + +.focus\:translate-y-20:focus { + --transform-translate-y: 5rem; +} + +.focus\:translate-y-24:focus { + --transform-translate-y: 6rem; +} + +.focus\:translate-y-32:focus { + --transform-translate-y: 8rem; +} + +.focus\:translate-y-40:focus { + --transform-translate-y: 10rem; +} + +.focus\:translate-y-48:focus { + --transform-translate-y: 12rem; +} + +.focus\:translate-y-56:focus { + --transform-translate-y: 14rem; +} + +.focus\:translate-y-64:focus { + --transform-translate-y: 16rem; +} + +.focus\:translate-y-px:focus { + --transform-translate-y: 1px; +} + +.focus\:-translate-y-1:focus { + --transform-translate-y: -0.25rem; +} + +.focus\:-translate-y-2:focus { + --transform-translate-y: -0.5rem; +} + +.focus\:-translate-y-3:focus { + --transform-translate-y: -0.75rem; +} + +.focus\:-translate-y-4:focus { + --transform-translate-y: -1rem; +} + +.focus\:-translate-y-5:focus { + --transform-translate-y: -1.25rem; +} + +.focus\:-translate-y-6:focus { + --transform-translate-y: -1.5rem; +} + +.focus\:-translate-y-8:focus { + --transform-translate-y: -2rem; +} + +.focus\:-translate-y-10:focus { + --transform-translate-y: -2.5rem; +} + +.focus\:-translate-y-12:focus { + --transform-translate-y: -3rem; +} + +.focus\:-translate-y-16:focus { + --transform-translate-y: -4rem; +} + +.focus\:-translate-y-20:focus { + --transform-translate-y: -5rem; +} + +.focus\:-translate-y-24:focus { + --transform-translate-y: -6rem; +} + +.focus\:-translate-y-32:focus { + --transform-translate-y: -8rem; +} + +.focus\:-translate-y-40:focus { + --transform-translate-y: -10rem; +} + +.focus\:-translate-y-48:focus { + --transform-translate-y: -12rem; +} + +.focus\:-translate-y-56:focus { + --transform-translate-y: -14rem; +} + +.focus\:-translate-y-64:focus { + --transform-translate-y: -16rem; +} + +.focus\:-translate-y-px:focus { + --transform-translate-y: -1px; +} + +.focus\:-translate-y-full:focus { + --transform-translate-y: -100%; +} + +.focus\:-translate-y-1\/2:focus { + --transform-translate-y: -50%; +} + +.focus\:translate-y-1\/2:focus { + --transform-translate-y: 50%; +} + +.focus\:translate-y-full:focus { + --transform-translate-y: 100%; +} + +.skew-x-0 { + --transform-skew-x: 0; +} + +.skew-x-3 { + --transform-skew-x: 3deg; +} + +.skew-x-6 { + --transform-skew-x: 6deg; +} + +.skew-x-12 { + --transform-skew-x: 12deg; +} + +.-skew-x-12 { + --transform-skew-x: -12deg; +} + +.-skew-x-6 { + --transform-skew-x: -6deg; +} + +.-skew-x-3 { + --transform-skew-x: -3deg; +} + +.skew-y-0 { + --transform-skew-y: 0; +} + +.skew-y-3 { + --transform-skew-y: 3deg; +} + +.skew-y-6 { + --transform-skew-y: 6deg; +} + +.skew-y-12 { + --transform-skew-y: 12deg; +} + +.-skew-y-12 { + --transform-skew-y: -12deg; +} + +.-skew-y-6 { + --transform-skew-y: -6deg; +} + +.-skew-y-3 { + --transform-skew-y: -3deg; +} + +.hover\:skew-x-0:hover { + --transform-skew-x: 0; +} + +.hover\:skew-x-3:hover { + --transform-skew-x: 3deg; +} + +.hover\:skew-x-6:hover { + --transform-skew-x: 6deg; +} + +.hover\:skew-x-12:hover { + --transform-skew-x: 12deg; +} + +.hover\:-skew-x-12:hover { + --transform-skew-x: -12deg; +} + +.hover\:-skew-x-6:hover { + --transform-skew-x: -6deg; +} + +.hover\:-skew-x-3:hover { + --transform-skew-x: -3deg; +} + +.hover\:skew-y-0:hover { + --transform-skew-y: 0; +} + +.hover\:skew-y-3:hover { + --transform-skew-y: 3deg; +} + +.hover\:skew-y-6:hover { + --transform-skew-y: 6deg; +} + +.hover\:skew-y-12:hover { + --transform-skew-y: 12deg; +} + +.hover\:-skew-y-12:hover { + --transform-skew-y: -12deg; +} + +.hover\:-skew-y-6:hover { + --transform-skew-y: -6deg; +} + +.hover\:-skew-y-3:hover { + --transform-skew-y: -3deg; +} + +.focus\:skew-x-0:focus { + --transform-skew-x: 0; +} + +.focus\:skew-x-3:focus { + --transform-skew-x: 3deg; +} + +.focus\:skew-x-6:focus { + --transform-skew-x: 6deg; +} + +.focus\:skew-x-12:focus { + --transform-skew-x: 12deg; +} + +.focus\:-skew-x-12:focus { + --transform-skew-x: -12deg; +} + +.focus\:-skew-x-6:focus { + --transform-skew-x: -6deg; +} + +.focus\:-skew-x-3:focus { + --transform-skew-x: -3deg; +} + +.focus\:skew-y-0:focus { + --transform-skew-y: 0; +} + +.focus\:skew-y-3:focus { + --transform-skew-y: 3deg; +} + +.focus\:skew-y-6:focus { + --transform-skew-y: 6deg; +} + +.focus\:skew-y-12:focus { + --transform-skew-y: 12deg; +} + +.focus\:-skew-y-12:focus { + --transform-skew-y: -12deg; +} + +.focus\:-skew-y-6:focus { + --transform-skew-y: -6deg; +} + +.focus\:-skew-y-3:focus { + --transform-skew-y: -3deg; +} + +.transition-none { + transition-property: none; +} + +.transition-all { + transition-property: all; +} + +.transition { + transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform; +} + +.transition-colors { + transition-property: background-color, border-color, color, fill, stroke; +} + +.transition-opacity { + transition-property: opacity; +} + +.transition-shadow { + transition-property: box-shadow; +} + +.transition-transform { + transition-property: transform; +} + +.ease-linear { + transition-timing-function: linear; +} + +.ease-in { + transition-timing-function: cubic-bezier(0.4, 0, 1, 1); +} + +.ease-out { + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} + +.ease-in-out { + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +.duration-75 { + transition-duration: 75ms; +} + +.duration-100 { + transition-duration: 100ms; +} + +.duration-150 { + transition-duration: 150ms; +} + +.duration-200 { + transition-duration: 200ms; +} + +.duration-300 { + transition-duration: 300ms; +} + +.duration-500 { + transition-duration: 500ms; +} + +.duration-700 { + transition-duration: 700ms; +} + +.duration-1000 { + transition-duration: 1000ms; +} + +@import '~@fortawesome/fontawesome-free/css/all.css'; + +@media (min-width: 640px) { + .sm\:sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; + } + + .sm\:not-sr-only { + position: static; + width: auto; + height: auto; + padding: 0; + margin: 0; + overflow: visible; + clip: auto; + white-space: normal; + } + + .sm\:focus\:sr-only:focus { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; + } + + .sm\:focus\:not-sr-only:focus { + position: static; + width: auto; + height: auto; + padding: 0; + margin: 0; + overflow: visible; + clip: auto; + white-space: normal; + } + + .sm\:appearance-none { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + } + + .sm\:bg-fixed { + background-attachment: fixed; + } + + .sm\:bg-local { + background-attachment: local; + } + + .sm\:bg-scroll { + background-attachment: scroll; + } + + .sm\:bg-transparent { + background-color: transparent; + } + + .sm\:bg-black { + background-color: #000; + } + + .sm\:bg-white { + background-color: #fff; + } + + .sm\:bg-gray-100 { + background-color: #f7fafc; + } + + .sm\:bg-gray-200 { + background-color: #edf2f7; + } + + .sm\:bg-gray-300 { + background-color: #e2e8f0; + } + + .sm\:bg-gray-400 { + background-color: #cbd5e0; + } + + .sm\:bg-gray-500 { + background-color: #a0aec0; + } + + .sm\:bg-gray-600 { + background-color: #718096; + } + + .sm\:bg-gray-700 { + background-color: #4a5568; + } + + .sm\:bg-gray-800 { + background-color: #2d3748; + } + + .sm\:bg-gray-900 { + background-color: #1a202c; + } + + .sm\:bg-red-100 { + background-color: #fff5f5; + } + + .sm\:bg-red-200 { + background-color: #fed7d7; + } + + .sm\:bg-red-300 { + background-color: #feb2b2; + } + + .sm\:bg-red-400 { + background-color: #fc8181; + } + + .sm\:bg-red-500 { + background-color: #f56565; + } + + .sm\:bg-red-600 { + background-color: #e53e3e; + } + + .sm\:bg-red-700 { + background-color: #c53030; + } + + .sm\:bg-red-800 { + background-color: #9b2c2c; + } + + .sm\:bg-red-900 { + background-color: #742a2a; + } + + .sm\:bg-orange-100 { + background-color: #fffaf0; + } + + .sm\:bg-orange-200 { + background-color: #feebc8; + } + + .sm\:bg-orange-300 { + background-color: #fbd38d; + } + + .sm\:bg-orange-400 { + background-color: #f6ad55; + } + + .sm\:bg-orange-500 { + background-color: #ed8936; + } + + .sm\:bg-orange-600 { + background-color: #dd6b20; + } + + .sm\:bg-orange-700 { + background-color: #c05621; + } + + .sm\:bg-orange-800 { + background-color: #9c4221; + } + + .sm\:bg-orange-900 { + background-color: #7b341e; + } + + .sm\:bg-yellow-100 { + background-color: #fffff0; + } + + .sm\:bg-yellow-200 { + background-color: #fefcbf; + } + + .sm\:bg-yellow-300 { + background-color: #faf089; + } + + .sm\:bg-yellow-400 { + background-color: #f6e05e; + } + + .sm\:bg-yellow-500 { + background-color: #ecc94b; + } + + .sm\:bg-yellow-600 { + background-color: #d69e2e; + } + + .sm\:bg-yellow-700 { + background-color: #b7791f; + } + + .sm\:bg-yellow-800 { + background-color: #975a16; + } + + .sm\:bg-yellow-900 { + background-color: #744210; + } + + .sm\:bg-green-100 { + background-color: #f0fff4; + } + + .sm\:bg-green-200 { + background-color: #c6f6d5; + } + + .sm\:bg-green-300 { + background-color: #9ae6b4; + } + + .sm\:bg-green-400 { + background-color: #68d391; + } + + .sm\:bg-green-500 { + background-color: #48bb78; + } + + .sm\:bg-green-600 { + background-color: #38a169; + } + + .sm\:bg-green-700 { + background-color: #2f855a; + } + + .sm\:bg-green-800 { + background-color: #276749; + } + + .sm\:bg-green-900 { + background-color: #22543d; + } + + .sm\:bg-teal-100 { + background-color: #e6fffa; + } + + .sm\:bg-teal-200 { + background-color: #b2f5ea; + } + + .sm\:bg-teal-300 { + background-color: #81e6d9; + } + + .sm\:bg-teal-400 { + background-color: #4fd1c5; + } + + .sm\:bg-teal-500 { + background-color: #38b2ac; + } + + .sm\:bg-teal-600 { + background-color: #319795; + } + + .sm\:bg-teal-700 { + background-color: #2c7a7b; + } + + .sm\:bg-teal-800 { + background-color: #285e61; + } + + .sm\:bg-teal-900 { + background-color: #234e52; + } + + .sm\:bg-blue-100 { + background-color: #ebf8ff; + } + + .sm\:bg-blue-200 { + background-color: #bee3f8; + } + + .sm\:bg-blue-300 { + background-color: #90cdf4; + } + + .sm\:bg-blue-400 { + background-color: #63b3ed; + } + + .sm\:bg-blue-500 { + background-color: #4299e1; + } + + .sm\:bg-blue-600 { + background-color: #3182ce; + } + + .sm\:bg-blue-700 { + background-color: #2b6cb0; + } + + .sm\:bg-blue-800 { + background-color: #2c5282; + } + + .sm\:bg-blue-900 { + background-color: #2a4365; + } + + .sm\:bg-indigo-100 { + background-color: #ebf4ff; + } + + .sm\:bg-indigo-200 { + background-color: #c3dafe; + } + + .sm\:bg-indigo-300 { + background-color: #a3bffa; + } + + .sm\:bg-indigo-400 { + background-color: #7f9cf5; + } + + .sm\:bg-indigo-500 { + background-color: #667eea; + } + + .sm\:bg-indigo-600 { + background-color: #5a67d8; + } + + .sm\:bg-indigo-700 { + background-color: #4c51bf; + } + + .sm\:bg-indigo-800 { + background-color: #434190; + } + + .sm\:bg-indigo-900 { + background-color: #3c366b; + } + + .sm\:bg-purple-100 { + background-color: #faf5ff; + } + + .sm\:bg-purple-200 { + background-color: #e9d8fd; + } + + .sm\:bg-purple-300 { + background-color: #d6bcfa; + } + + .sm\:bg-purple-400 { + background-color: #b794f4; + } + + .sm\:bg-purple-500 { + background-color: #9f7aea; + } + + .sm\:bg-purple-600 { + background-color: #805ad5; + } + + .sm\:bg-purple-700 { + background-color: #6b46c1; + } + + .sm\:bg-purple-800 { + background-color: #553c9a; + } + + .sm\:bg-purple-900 { + background-color: #44337a; + } + + .sm\:bg-pink-100 { + background-color: #fff5f7; + } + + .sm\:bg-pink-200 { + background-color: #fed7e2; + } + + .sm\:bg-pink-300 { + background-color: #fbb6ce; + } + + .sm\:bg-pink-400 { + background-color: #f687b3; + } + + .sm\:bg-pink-500 { + background-color: #ed64a6; + } + + .sm\:bg-pink-600 { + background-color: #d53f8c; + } + + .sm\:bg-pink-700 { + background-color: #b83280; + } + + .sm\:bg-pink-800 { + background-color: #97266d; + } + + .sm\:bg-pink-900 { + background-color: #702459; + } + + .sm\:hover\:bg-transparent:hover { + background-color: transparent; + } + + .sm\:hover\:bg-black:hover { + background-color: #000; + } + + .sm\:hover\:bg-white:hover { + background-color: #fff; + } + + .sm\:hover\:bg-gray-100:hover { + background-color: #f7fafc; + } + + .sm\:hover\:bg-gray-200:hover { + background-color: #edf2f7; + } + + .sm\:hover\:bg-gray-300:hover { + background-color: #e2e8f0; + } + + .sm\:hover\:bg-gray-400:hover { + background-color: #cbd5e0; + } + + .sm\:hover\:bg-gray-500:hover { + background-color: #a0aec0; + } + + .sm\:hover\:bg-gray-600:hover { + background-color: #718096; + } + + .sm\:hover\:bg-gray-700:hover { + background-color: #4a5568; + } + + .sm\:hover\:bg-gray-800:hover { + background-color: #2d3748; + } + + .sm\:hover\:bg-gray-900:hover { + background-color: #1a202c; + } + + .sm\:hover\:bg-red-100:hover { + background-color: #fff5f5; + } + + .sm\:hover\:bg-red-200:hover { + background-color: #fed7d7; + } + + .sm\:hover\:bg-red-300:hover { + background-color: #feb2b2; + } + + .sm\:hover\:bg-red-400:hover { + background-color: #fc8181; + } + + .sm\:hover\:bg-red-500:hover { + background-color: #f56565; + } + + .sm\:hover\:bg-red-600:hover { + background-color: #e53e3e; + } + + .sm\:hover\:bg-red-700:hover { + background-color: #c53030; + } + + .sm\:hover\:bg-red-800:hover { + background-color: #9b2c2c; + } + + .sm\:hover\:bg-red-900:hover { + background-color: #742a2a; + } + + .sm\:hover\:bg-orange-100:hover { + background-color: #fffaf0; + } + + .sm\:hover\:bg-orange-200:hover { + background-color: #feebc8; + } + + .sm\:hover\:bg-orange-300:hover { + background-color: #fbd38d; + } + + .sm\:hover\:bg-orange-400:hover { + background-color: #f6ad55; + } + + .sm\:hover\:bg-orange-500:hover { + background-color: #ed8936; + } + + .sm\:hover\:bg-orange-600:hover { + background-color: #dd6b20; + } + + .sm\:hover\:bg-orange-700:hover { + background-color: #c05621; + } + + .sm\:hover\:bg-orange-800:hover { + background-color: #9c4221; + } + + .sm\:hover\:bg-orange-900:hover { + background-color: #7b341e; + } + + .sm\:hover\:bg-yellow-100:hover { + background-color: #fffff0; + } + + .sm\:hover\:bg-yellow-200:hover { + background-color: #fefcbf; + } + + .sm\:hover\:bg-yellow-300:hover { + background-color: #faf089; + } + + .sm\:hover\:bg-yellow-400:hover { + background-color: #f6e05e; + } + + .sm\:hover\:bg-yellow-500:hover { + background-color: #ecc94b; + } + + .sm\:hover\:bg-yellow-600:hover { + background-color: #d69e2e; + } + + .sm\:hover\:bg-yellow-700:hover { + background-color: #b7791f; + } + + .sm\:hover\:bg-yellow-800:hover { + background-color: #975a16; + } + + .sm\:hover\:bg-yellow-900:hover { + background-color: #744210; + } + + .sm\:hover\:bg-green-100:hover { + background-color: #f0fff4; + } + + .sm\:hover\:bg-green-200:hover { + background-color: #c6f6d5; + } + + .sm\:hover\:bg-green-300:hover { + background-color: #9ae6b4; + } + + .sm\:hover\:bg-green-400:hover { + background-color: #68d391; + } + + .sm\:hover\:bg-green-500:hover { + background-color: #48bb78; + } + + .sm\:hover\:bg-green-600:hover { + background-color: #38a169; + } + + .sm\:hover\:bg-green-700:hover { + background-color: #2f855a; + } + + .sm\:hover\:bg-green-800:hover { + background-color: #276749; + } + + .sm\:hover\:bg-green-900:hover { + background-color: #22543d; + } + + .sm\:hover\:bg-teal-100:hover { + background-color: #e6fffa; + } + + .sm\:hover\:bg-teal-200:hover { + background-color: #b2f5ea; + } + + .sm\:hover\:bg-teal-300:hover { + background-color: #81e6d9; + } + + .sm\:hover\:bg-teal-400:hover { + background-color: #4fd1c5; + } + + .sm\:hover\:bg-teal-500:hover { + background-color: #38b2ac; + } + + .sm\:hover\:bg-teal-600:hover { + background-color: #319795; + } + + .sm\:hover\:bg-teal-700:hover { + background-color: #2c7a7b; + } + + .sm\:hover\:bg-teal-800:hover { + background-color: #285e61; + } + + .sm\:hover\:bg-teal-900:hover { + background-color: #234e52; + } + + .sm\:hover\:bg-blue-100:hover { + background-color: #ebf8ff; + } + + .sm\:hover\:bg-blue-200:hover { + background-color: #bee3f8; + } + + .sm\:hover\:bg-blue-300:hover { + background-color: #90cdf4; + } + + .sm\:hover\:bg-blue-400:hover { + background-color: #63b3ed; + } + + .sm\:hover\:bg-blue-500:hover { + background-color: #4299e1; + } + + .sm\:hover\:bg-blue-600:hover { + background-color: #3182ce; + } + + .sm\:hover\:bg-blue-700:hover { + background-color: #2b6cb0; + } + + .sm\:hover\:bg-blue-800:hover { + background-color: #2c5282; + } + + .sm\:hover\:bg-blue-900:hover { + background-color: #2a4365; + } + + .sm\:hover\:bg-indigo-100:hover { + background-color: #ebf4ff; + } + + .sm\:hover\:bg-indigo-200:hover { + background-color: #c3dafe; + } + + .sm\:hover\:bg-indigo-300:hover { + background-color: #a3bffa; + } + + .sm\:hover\:bg-indigo-400:hover { + background-color: #7f9cf5; + } + + .sm\:hover\:bg-indigo-500:hover { + background-color: #667eea; + } + + .sm\:hover\:bg-indigo-600:hover { + background-color: #5a67d8; + } + + .sm\:hover\:bg-indigo-700:hover { + background-color: #4c51bf; + } + + .sm\:hover\:bg-indigo-800:hover { + background-color: #434190; + } + + .sm\:hover\:bg-indigo-900:hover { + background-color: #3c366b; + } + + .sm\:hover\:bg-purple-100:hover { + background-color: #faf5ff; + } + + .sm\:hover\:bg-purple-200:hover { + background-color: #e9d8fd; + } + + .sm\:hover\:bg-purple-300:hover { + background-color: #d6bcfa; + } + + .sm\:hover\:bg-purple-400:hover { + background-color: #b794f4; + } + + .sm\:hover\:bg-purple-500:hover { + background-color: #9f7aea; + } + + .sm\:hover\:bg-purple-600:hover { + background-color: #805ad5; + } + + .sm\:hover\:bg-purple-700:hover { + background-color: #6b46c1; + } + + .sm\:hover\:bg-purple-800:hover { + background-color: #553c9a; + } + + .sm\:hover\:bg-purple-900:hover { + background-color: #44337a; + } + + .sm\:hover\:bg-pink-100:hover { + background-color: #fff5f7; + } + + .sm\:hover\:bg-pink-200:hover { + background-color: #fed7e2; + } + + .sm\:hover\:bg-pink-300:hover { + background-color: #fbb6ce; + } + + .sm\:hover\:bg-pink-400:hover { + background-color: #f687b3; + } + + .sm\:hover\:bg-pink-500:hover { + background-color: #ed64a6; + } + + .sm\:hover\:bg-pink-600:hover { + background-color: #d53f8c; + } + + .sm\:hover\:bg-pink-700:hover { + background-color: #b83280; + } + + .sm\:hover\:bg-pink-800:hover { + background-color: #97266d; + } + + .sm\:hover\:bg-pink-900:hover { + background-color: #702459; + } + + .sm\:focus\:bg-transparent:focus { + background-color: transparent; + } + + .sm\:focus\:bg-black:focus { + background-color: #000; + } + + .sm\:focus\:bg-white:focus { + background-color: #fff; + } + + .sm\:focus\:bg-gray-100:focus { + background-color: #f7fafc; + } + + .sm\:focus\:bg-gray-200:focus { + background-color: #edf2f7; + } + + .sm\:focus\:bg-gray-300:focus { + background-color: #e2e8f0; + } + + .sm\:focus\:bg-gray-400:focus { + background-color: #cbd5e0; + } + + .sm\:focus\:bg-gray-500:focus { + background-color: #a0aec0; + } + + .sm\:focus\:bg-gray-600:focus { + background-color: #718096; + } + + .sm\:focus\:bg-gray-700:focus { + background-color: #4a5568; + } + + .sm\:focus\:bg-gray-800:focus { + background-color: #2d3748; + } + + .sm\:focus\:bg-gray-900:focus { + background-color: #1a202c; + } + + .sm\:focus\:bg-red-100:focus { + background-color: #fff5f5; + } + + .sm\:focus\:bg-red-200:focus { + background-color: #fed7d7; + } + + .sm\:focus\:bg-red-300:focus { + background-color: #feb2b2; + } + + .sm\:focus\:bg-red-400:focus { + background-color: #fc8181; + } + + .sm\:focus\:bg-red-500:focus { + background-color: #f56565; + } + + .sm\:focus\:bg-red-600:focus { + background-color: #e53e3e; + } + + .sm\:focus\:bg-red-700:focus { + background-color: #c53030; + } + + .sm\:focus\:bg-red-800:focus { + background-color: #9b2c2c; + } + + .sm\:focus\:bg-red-900:focus { + background-color: #742a2a; + } + + .sm\:focus\:bg-orange-100:focus { + background-color: #fffaf0; + } + + .sm\:focus\:bg-orange-200:focus { + background-color: #feebc8; + } + + .sm\:focus\:bg-orange-300:focus { + background-color: #fbd38d; + } + + .sm\:focus\:bg-orange-400:focus { + background-color: #f6ad55; + } + + .sm\:focus\:bg-orange-500:focus { + background-color: #ed8936; + } + + .sm\:focus\:bg-orange-600:focus { + background-color: #dd6b20; + } + + .sm\:focus\:bg-orange-700:focus { + background-color: #c05621; + } + + .sm\:focus\:bg-orange-800:focus { + background-color: #9c4221; + } + + .sm\:focus\:bg-orange-900:focus { + background-color: #7b341e; + } + + .sm\:focus\:bg-yellow-100:focus { + background-color: #fffff0; + } + + .sm\:focus\:bg-yellow-200:focus { + background-color: #fefcbf; + } + + .sm\:focus\:bg-yellow-300:focus { + background-color: #faf089; + } + + .sm\:focus\:bg-yellow-400:focus { + background-color: #f6e05e; + } + + .sm\:focus\:bg-yellow-500:focus { + background-color: #ecc94b; + } + + .sm\:focus\:bg-yellow-600:focus { + background-color: #d69e2e; + } + + .sm\:focus\:bg-yellow-700:focus { + background-color: #b7791f; + } + + .sm\:focus\:bg-yellow-800:focus { + background-color: #975a16; + } + + .sm\:focus\:bg-yellow-900:focus { + background-color: #744210; + } + + .sm\:focus\:bg-green-100:focus { + background-color: #f0fff4; + } + + .sm\:focus\:bg-green-200:focus { + background-color: #c6f6d5; + } + + .sm\:focus\:bg-green-300:focus { + background-color: #9ae6b4; + } + + .sm\:focus\:bg-green-400:focus { + background-color: #68d391; + } + + .sm\:focus\:bg-green-500:focus { + background-color: #48bb78; + } + + .sm\:focus\:bg-green-600:focus { + background-color: #38a169; + } + + .sm\:focus\:bg-green-700:focus { + background-color: #2f855a; + } + + .sm\:focus\:bg-green-800:focus { + background-color: #276749; + } + + .sm\:focus\:bg-green-900:focus { + background-color: #22543d; + } + + .sm\:focus\:bg-teal-100:focus { + background-color: #e6fffa; + } + + .sm\:focus\:bg-teal-200:focus { + background-color: #b2f5ea; + } + + .sm\:focus\:bg-teal-300:focus { + background-color: #81e6d9; + } + + .sm\:focus\:bg-teal-400:focus { + background-color: #4fd1c5; + } + + .sm\:focus\:bg-teal-500:focus { + background-color: #38b2ac; + } + + .sm\:focus\:bg-teal-600:focus { + background-color: #319795; + } + + .sm\:focus\:bg-teal-700:focus { + background-color: #2c7a7b; + } + + .sm\:focus\:bg-teal-800:focus { + background-color: #285e61; + } + + .sm\:focus\:bg-teal-900:focus { + background-color: #234e52; + } + + .sm\:focus\:bg-blue-100:focus { + background-color: #ebf8ff; + } + + .sm\:focus\:bg-blue-200:focus { + background-color: #bee3f8; + } + + .sm\:focus\:bg-blue-300:focus { + background-color: #90cdf4; + } + + .sm\:focus\:bg-blue-400:focus { + background-color: #63b3ed; + } + + .sm\:focus\:bg-blue-500:focus { + background-color: #4299e1; + } + + .sm\:focus\:bg-blue-600:focus { + background-color: #3182ce; + } + + .sm\:focus\:bg-blue-700:focus { + background-color: #2b6cb0; + } + + .sm\:focus\:bg-blue-800:focus { + background-color: #2c5282; + } + + .sm\:focus\:bg-blue-900:focus { + background-color: #2a4365; + } + + .sm\:focus\:bg-indigo-100:focus { + background-color: #ebf4ff; + } + + .sm\:focus\:bg-indigo-200:focus { + background-color: #c3dafe; + } + + .sm\:focus\:bg-indigo-300:focus { + background-color: #a3bffa; + } + + .sm\:focus\:bg-indigo-400:focus { + background-color: #7f9cf5; + } + + .sm\:focus\:bg-indigo-500:focus { + background-color: #667eea; + } + + .sm\:focus\:bg-indigo-600:focus { + background-color: #5a67d8; + } + + .sm\:focus\:bg-indigo-700:focus { + background-color: #4c51bf; + } + + .sm\:focus\:bg-indigo-800:focus { + background-color: #434190; + } + + .sm\:focus\:bg-indigo-900:focus { + background-color: #3c366b; + } + + .sm\:focus\:bg-purple-100:focus { + background-color: #faf5ff; + } + + .sm\:focus\:bg-purple-200:focus { + background-color: #e9d8fd; + } + + .sm\:focus\:bg-purple-300:focus { + background-color: #d6bcfa; + } + + .sm\:focus\:bg-purple-400:focus { + background-color: #b794f4; + } + + .sm\:focus\:bg-purple-500:focus { + background-color: #9f7aea; + } + + .sm\:focus\:bg-purple-600:focus { + background-color: #805ad5; + } + + .sm\:focus\:bg-purple-700:focus { + background-color: #6b46c1; + } + + .sm\:focus\:bg-purple-800:focus { + background-color: #553c9a; + } + + .sm\:focus\:bg-purple-900:focus { + background-color: #44337a; + } + + .sm\:focus\:bg-pink-100:focus { + background-color: #fff5f7; + } + + .sm\:focus\:bg-pink-200:focus { + background-color: #fed7e2; + } + + .sm\:focus\:bg-pink-300:focus { + background-color: #fbb6ce; + } + + .sm\:focus\:bg-pink-400:focus { + background-color: #f687b3; + } + + .sm\:focus\:bg-pink-500:focus { + background-color: #ed64a6; + } + + .sm\:focus\:bg-pink-600:focus { + background-color: #d53f8c; + } + + .sm\:focus\:bg-pink-700:focus { + background-color: #b83280; + } + + .sm\:focus\:bg-pink-800:focus { + background-color: #97266d; + } + + .sm\:focus\:bg-pink-900:focus { + background-color: #702459; + } + + .sm\:bg-bottom { + background-position: bottom; + } + + .sm\:bg-center { + background-position: center; + } + + .sm\:bg-left { + background-position: left; + } + + .sm\:bg-left-bottom { + background-position: left bottom; + } + + .sm\:bg-left-top { + background-position: left top; + } + + .sm\:bg-right { + background-position: right; + } + + .sm\:bg-right-bottom { + background-position: right bottom; + } + + .sm\:bg-right-top { + background-position: right top; + } + + .sm\:bg-top { + background-position: top; + } + + .sm\:bg-repeat { + background-repeat: repeat; + } + + .sm\:bg-no-repeat { + background-repeat: no-repeat; + } + + .sm\:bg-repeat-x { + background-repeat: repeat-x; + } + + .sm\:bg-repeat-y { + background-repeat: repeat-y; + } + + .sm\:bg-repeat-round { + background-repeat: round; + } + + .sm\:bg-repeat-space { + background-repeat: space; + } + + .sm\:bg-auto { + background-size: auto; + } + + .sm\:bg-cover { + background-size: cover; + } + + .sm\:bg-contain { + background-size: contain; + } + + .sm\:border-collapse { + border-collapse: collapse; + } + + .sm\:border-separate { + border-collapse: separate; + } + + .sm\:border-transparent { + border-color: transparent; + } + + .sm\:border-black { + border-color: #000; + } + + .sm\:border-white { + border-color: #fff; + } + + .sm\:border-gray-100 { + border-color: #f7fafc; + } + + .sm\:border-gray-200 { + border-color: #edf2f7; + } + + .sm\:border-gray-300 { + border-color: #e2e8f0; + } + + .sm\:border-gray-400 { + border-color: #cbd5e0; + } + + .sm\:border-gray-500 { + border-color: #a0aec0; + } + + .sm\:border-gray-600 { + border-color: #718096; + } + + .sm\:border-gray-700 { + border-color: #4a5568; + } + + .sm\:border-gray-800 { + border-color: #2d3748; + } + + .sm\:border-gray-900 { + border-color: #1a202c; + } + + .sm\:border-red-100 { + border-color: #fff5f5; + } + + .sm\:border-red-200 { + border-color: #fed7d7; + } + + .sm\:border-red-300 { + border-color: #feb2b2; + } + + .sm\:border-red-400 { + border-color: #fc8181; + } + + .sm\:border-red-500 { + border-color: #f56565; + } + + .sm\:border-red-600 { + border-color: #e53e3e; + } + + .sm\:border-red-700 { + border-color: #c53030; + } + + .sm\:border-red-800 { + border-color: #9b2c2c; + } + + .sm\:border-red-900 { + border-color: #742a2a; + } + + .sm\:border-orange-100 { + border-color: #fffaf0; + } + + .sm\:border-orange-200 { + border-color: #feebc8; + } + + .sm\:border-orange-300 { + border-color: #fbd38d; + } + + .sm\:border-orange-400 { + border-color: #f6ad55; + } + + .sm\:border-orange-500 { + border-color: #ed8936; + } + + .sm\:border-orange-600 { + border-color: #dd6b20; + } + + .sm\:border-orange-700 { + border-color: #c05621; + } + + .sm\:border-orange-800 { + border-color: #9c4221; + } + + .sm\:border-orange-900 { + border-color: #7b341e; + } + + .sm\:border-yellow-100 { + border-color: #fffff0; + } + + .sm\:border-yellow-200 { + border-color: #fefcbf; + } + + .sm\:border-yellow-300 { + border-color: #faf089; + } + + .sm\:border-yellow-400 { + border-color: #f6e05e; + } + + .sm\:border-yellow-500 { + border-color: #ecc94b; + } + + .sm\:border-yellow-600 { + border-color: #d69e2e; + } + + .sm\:border-yellow-700 { + border-color: #b7791f; + } + + .sm\:border-yellow-800 { + border-color: #975a16; + } + + .sm\:border-yellow-900 { + border-color: #744210; + } + + .sm\:border-green-100 { + border-color: #f0fff4; + } + + .sm\:border-green-200 { + border-color: #c6f6d5; + } + + .sm\:border-green-300 { + border-color: #9ae6b4; + } + + .sm\:border-green-400 { + border-color: #68d391; + } + + .sm\:border-green-500 { + border-color: #48bb78; + } + + .sm\:border-green-600 { + border-color: #38a169; + } + + .sm\:border-green-700 { + border-color: #2f855a; + } + + .sm\:border-green-800 { + border-color: #276749; + } + + .sm\:border-green-900 { + border-color: #22543d; + } + + .sm\:border-teal-100 { + border-color: #e6fffa; + } + + .sm\:border-teal-200 { + border-color: #b2f5ea; + } + + .sm\:border-teal-300 { + border-color: #81e6d9; + } + + .sm\:border-teal-400 { + border-color: #4fd1c5; + } + + .sm\:border-teal-500 { + border-color: #38b2ac; + } + + .sm\:border-teal-600 { + border-color: #319795; + } + + .sm\:border-teal-700 { + border-color: #2c7a7b; + } + + .sm\:border-teal-800 { + border-color: #285e61; + } + + .sm\:border-teal-900 { + border-color: #234e52; + } + + .sm\:border-blue-100 { + border-color: #ebf8ff; + } + + .sm\:border-blue-200 { + border-color: #bee3f8; + } + + .sm\:border-blue-300 { + border-color: #90cdf4; + } + + .sm\:border-blue-400 { + border-color: #63b3ed; + } + + .sm\:border-blue-500 { + border-color: #4299e1; + } + + .sm\:border-blue-600 { + border-color: #3182ce; + } + + .sm\:border-blue-700 { + border-color: #2b6cb0; + } + + .sm\:border-blue-800 { + border-color: #2c5282; + } + + .sm\:border-blue-900 { + border-color: #2a4365; + } + + .sm\:border-indigo-100 { + border-color: #ebf4ff; + } + + .sm\:border-indigo-200 { + border-color: #c3dafe; + } + + .sm\:border-indigo-300 { + border-color: #a3bffa; + } + + .sm\:border-indigo-400 { + border-color: #7f9cf5; + } + + .sm\:border-indigo-500 { + border-color: #667eea; + } + + .sm\:border-indigo-600 { + border-color: #5a67d8; + } + + .sm\:border-indigo-700 { + border-color: #4c51bf; + } + + .sm\:border-indigo-800 { + border-color: #434190; + } + + .sm\:border-indigo-900 { + border-color: #3c366b; + } + + .sm\:border-purple-100 { + border-color: #faf5ff; + } + + .sm\:border-purple-200 { + border-color: #e9d8fd; + } + + .sm\:border-purple-300 { + border-color: #d6bcfa; + } + + .sm\:border-purple-400 { + border-color: #b794f4; + } + + .sm\:border-purple-500 { + border-color: #9f7aea; + } + + .sm\:border-purple-600 { + border-color: #805ad5; + } + + .sm\:border-purple-700 { + border-color: #6b46c1; + } + + .sm\:border-purple-800 { + border-color: #553c9a; + } + + .sm\:border-purple-900 { + border-color: #44337a; + } + + .sm\:border-pink-100 { + border-color: #fff5f7; + } + + .sm\:border-pink-200 { + border-color: #fed7e2; + } + + .sm\:border-pink-300 { + border-color: #fbb6ce; + } + + .sm\:border-pink-400 { + border-color: #f687b3; + } + + .sm\:border-pink-500 { + border-color: #ed64a6; + } + + .sm\:border-pink-600 { + border-color: #d53f8c; + } + + .sm\:border-pink-700 { + border-color: #b83280; + } + + .sm\:border-pink-800 { + border-color: #97266d; + } + + .sm\:border-pink-900 { + border-color: #702459; + } + + .sm\:hover\:border-transparent:hover { + border-color: transparent; + } + + .sm\:hover\:border-black:hover { + border-color: #000; + } + + .sm\:hover\:border-white:hover { + border-color: #fff; + } + + .sm\:hover\:border-gray-100:hover { + border-color: #f7fafc; + } + + .sm\:hover\:border-gray-200:hover { + border-color: #edf2f7; + } + + .sm\:hover\:border-gray-300:hover { + border-color: #e2e8f0; + } + + .sm\:hover\:border-gray-400:hover { + border-color: #cbd5e0; + } + + .sm\:hover\:border-gray-500:hover { + border-color: #a0aec0; + } + + .sm\:hover\:border-gray-600:hover { + border-color: #718096; + } + + .sm\:hover\:border-gray-700:hover { + border-color: #4a5568; + } + + .sm\:hover\:border-gray-800:hover { + border-color: #2d3748; + } + + .sm\:hover\:border-gray-900:hover { + border-color: #1a202c; + } + + .sm\:hover\:border-red-100:hover { + border-color: #fff5f5; + } + + .sm\:hover\:border-red-200:hover { + border-color: #fed7d7; + } + + .sm\:hover\:border-red-300:hover { + border-color: #feb2b2; + } + + .sm\:hover\:border-red-400:hover { + border-color: #fc8181; + } + + .sm\:hover\:border-red-500:hover { + border-color: #f56565; + } + + .sm\:hover\:border-red-600:hover { + border-color: #e53e3e; + } + + .sm\:hover\:border-red-700:hover { + border-color: #c53030; + } + + .sm\:hover\:border-red-800:hover { + border-color: #9b2c2c; + } + + .sm\:hover\:border-red-900:hover { + border-color: #742a2a; + } + + .sm\:hover\:border-orange-100:hover { + border-color: #fffaf0; + } + + .sm\:hover\:border-orange-200:hover { + border-color: #feebc8; + } + + .sm\:hover\:border-orange-300:hover { + border-color: #fbd38d; + } + + .sm\:hover\:border-orange-400:hover { + border-color: #f6ad55; + } + + .sm\:hover\:border-orange-500:hover { + border-color: #ed8936; + } + + .sm\:hover\:border-orange-600:hover { + border-color: #dd6b20; + } + + .sm\:hover\:border-orange-700:hover { + border-color: #c05621; + } + + .sm\:hover\:border-orange-800:hover { + border-color: #9c4221; + } + + .sm\:hover\:border-orange-900:hover { + border-color: #7b341e; + } + + .sm\:hover\:border-yellow-100:hover { + border-color: #fffff0; + } + + .sm\:hover\:border-yellow-200:hover { + border-color: #fefcbf; + } + + .sm\:hover\:border-yellow-300:hover { + border-color: #faf089; + } + + .sm\:hover\:border-yellow-400:hover { + border-color: #f6e05e; + } + + .sm\:hover\:border-yellow-500:hover { + border-color: #ecc94b; + } + + .sm\:hover\:border-yellow-600:hover { + border-color: #d69e2e; + } + + .sm\:hover\:border-yellow-700:hover { + border-color: #b7791f; + } + + .sm\:hover\:border-yellow-800:hover { + border-color: #975a16; + } + + .sm\:hover\:border-yellow-900:hover { + border-color: #744210; + } + + .sm\:hover\:border-green-100:hover { + border-color: #f0fff4; + } + + .sm\:hover\:border-green-200:hover { + border-color: #c6f6d5; + } + + .sm\:hover\:border-green-300:hover { + border-color: #9ae6b4; + } + + .sm\:hover\:border-green-400:hover { + border-color: #68d391; + } + + .sm\:hover\:border-green-500:hover { + border-color: #48bb78; + } + + .sm\:hover\:border-green-600:hover { + border-color: #38a169; + } + + .sm\:hover\:border-green-700:hover { + border-color: #2f855a; + } + + .sm\:hover\:border-green-800:hover { + border-color: #276749; + } + + .sm\:hover\:border-green-900:hover { + border-color: #22543d; + } + + .sm\:hover\:border-teal-100:hover { + border-color: #e6fffa; + } + + .sm\:hover\:border-teal-200:hover { + border-color: #b2f5ea; + } + + .sm\:hover\:border-teal-300:hover { + border-color: #81e6d9; + } + + .sm\:hover\:border-teal-400:hover { + border-color: #4fd1c5; + } + + .sm\:hover\:border-teal-500:hover { + border-color: #38b2ac; + } + + .sm\:hover\:border-teal-600:hover { + border-color: #319795; + } + + .sm\:hover\:border-teal-700:hover { + border-color: #2c7a7b; + } + + .sm\:hover\:border-teal-800:hover { + border-color: #285e61; + } + + .sm\:hover\:border-teal-900:hover { + border-color: #234e52; + } + + .sm\:hover\:border-blue-100:hover { + border-color: #ebf8ff; + } + + .sm\:hover\:border-blue-200:hover { + border-color: #bee3f8; + } + + .sm\:hover\:border-blue-300:hover { + border-color: #90cdf4; + } + + .sm\:hover\:border-blue-400:hover { + border-color: #63b3ed; + } + + .sm\:hover\:border-blue-500:hover { + border-color: #4299e1; + } + + .sm\:hover\:border-blue-600:hover { + border-color: #3182ce; + } + + .sm\:hover\:border-blue-700:hover { + border-color: #2b6cb0; + } + + .sm\:hover\:border-blue-800:hover { + border-color: #2c5282; + } + + .sm\:hover\:border-blue-900:hover { + border-color: #2a4365; + } + + .sm\:hover\:border-indigo-100:hover { + border-color: #ebf4ff; + } + + .sm\:hover\:border-indigo-200:hover { + border-color: #c3dafe; + } + + .sm\:hover\:border-indigo-300:hover { + border-color: #a3bffa; + } + + .sm\:hover\:border-indigo-400:hover { + border-color: #7f9cf5; + } + + .sm\:hover\:border-indigo-500:hover { + border-color: #667eea; + } + + .sm\:hover\:border-indigo-600:hover { + border-color: #5a67d8; + } + + .sm\:hover\:border-indigo-700:hover { + border-color: #4c51bf; + } + + .sm\:hover\:border-indigo-800:hover { + border-color: #434190; + } + + .sm\:hover\:border-indigo-900:hover { + border-color: #3c366b; + } + + .sm\:hover\:border-purple-100:hover { + border-color: #faf5ff; + } + + .sm\:hover\:border-purple-200:hover { + border-color: #e9d8fd; + } + + .sm\:hover\:border-purple-300:hover { + border-color: #d6bcfa; + } + + .sm\:hover\:border-purple-400:hover { + border-color: #b794f4; + } + + .sm\:hover\:border-purple-500:hover { + border-color: #9f7aea; + } + + .sm\:hover\:border-purple-600:hover { + border-color: #805ad5; + } + + .sm\:hover\:border-purple-700:hover { + border-color: #6b46c1; + } + + .sm\:hover\:border-purple-800:hover { + border-color: #553c9a; + } + + .sm\:hover\:border-purple-900:hover { + border-color: #44337a; + } + + .sm\:hover\:border-pink-100:hover { + border-color: #fff5f7; + } + + .sm\:hover\:border-pink-200:hover { + border-color: #fed7e2; + } + + .sm\:hover\:border-pink-300:hover { + border-color: #fbb6ce; + } + + .sm\:hover\:border-pink-400:hover { + border-color: #f687b3; + } + + .sm\:hover\:border-pink-500:hover { + border-color: #ed64a6; + } + + .sm\:hover\:border-pink-600:hover { + border-color: #d53f8c; + } + + .sm\:hover\:border-pink-700:hover { + border-color: #b83280; + } + + .sm\:hover\:border-pink-800:hover { + border-color: #97266d; + } + + .sm\:hover\:border-pink-900:hover { + border-color: #702459; + } + + .sm\:focus\:border-transparent:focus { + border-color: transparent; + } + + .sm\:focus\:border-black:focus { + border-color: #000; + } + + .sm\:focus\:border-white:focus { + border-color: #fff; + } + + .sm\:focus\:border-gray-100:focus { + border-color: #f7fafc; + } + + .sm\:focus\:border-gray-200:focus { + border-color: #edf2f7; + } + + .sm\:focus\:border-gray-300:focus { + border-color: #e2e8f0; + } + + .sm\:focus\:border-gray-400:focus { + border-color: #cbd5e0; + } + + .sm\:focus\:border-gray-500:focus { + border-color: #a0aec0; + } + + .sm\:focus\:border-gray-600:focus { + border-color: #718096; + } + + .sm\:focus\:border-gray-700:focus { + border-color: #4a5568; + } + + .sm\:focus\:border-gray-800:focus { + border-color: #2d3748; + } + + .sm\:focus\:border-gray-900:focus { + border-color: #1a202c; + } + + .sm\:focus\:border-red-100:focus { + border-color: #fff5f5; + } + + .sm\:focus\:border-red-200:focus { + border-color: #fed7d7; + } + + .sm\:focus\:border-red-300:focus { + border-color: #feb2b2; + } + + .sm\:focus\:border-red-400:focus { + border-color: #fc8181; + } + + .sm\:focus\:border-red-500:focus { + border-color: #f56565; + } + + .sm\:focus\:border-red-600:focus { + border-color: #e53e3e; + } + + .sm\:focus\:border-red-700:focus { + border-color: #c53030; + } + + .sm\:focus\:border-red-800:focus { + border-color: #9b2c2c; + } + + .sm\:focus\:border-red-900:focus { + border-color: #742a2a; + } + + .sm\:focus\:border-orange-100:focus { + border-color: #fffaf0; + } + + .sm\:focus\:border-orange-200:focus { + border-color: #feebc8; + } + + .sm\:focus\:border-orange-300:focus { + border-color: #fbd38d; + } + + .sm\:focus\:border-orange-400:focus { + border-color: #f6ad55; + } + + .sm\:focus\:border-orange-500:focus { + border-color: #ed8936; + } + + .sm\:focus\:border-orange-600:focus { + border-color: #dd6b20; + } + + .sm\:focus\:border-orange-700:focus { + border-color: #c05621; + } + + .sm\:focus\:border-orange-800:focus { + border-color: #9c4221; + } + + .sm\:focus\:border-orange-900:focus { + border-color: #7b341e; + } + + .sm\:focus\:border-yellow-100:focus { + border-color: #fffff0; + } + + .sm\:focus\:border-yellow-200:focus { + border-color: #fefcbf; + } + + .sm\:focus\:border-yellow-300:focus { + border-color: #faf089; + } + + .sm\:focus\:border-yellow-400:focus { + border-color: #f6e05e; + } + + .sm\:focus\:border-yellow-500:focus { + border-color: #ecc94b; + } + + .sm\:focus\:border-yellow-600:focus { + border-color: #d69e2e; + } + + .sm\:focus\:border-yellow-700:focus { + border-color: #b7791f; + } + + .sm\:focus\:border-yellow-800:focus { + border-color: #975a16; + } + + .sm\:focus\:border-yellow-900:focus { + border-color: #744210; + } + + .sm\:focus\:border-green-100:focus { + border-color: #f0fff4; + } + + .sm\:focus\:border-green-200:focus { + border-color: #c6f6d5; + } + + .sm\:focus\:border-green-300:focus { + border-color: #9ae6b4; + } + + .sm\:focus\:border-green-400:focus { + border-color: #68d391; + } + + .sm\:focus\:border-green-500:focus { + border-color: #48bb78; + } + + .sm\:focus\:border-green-600:focus { + border-color: #38a169; + } + + .sm\:focus\:border-green-700:focus { + border-color: #2f855a; + } + + .sm\:focus\:border-green-800:focus { + border-color: #276749; + } + + .sm\:focus\:border-green-900:focus { + border-color: #22543d; + } + + .sm\:focus\:border-teal-100:focus { + border-color: #e6fffa; + } + + .sm\:focus\:border-teal-200:focus { + border-color: #b2f5ea; + } + + .sm\:focus\:border-teal-300:focus { + border-color: #81e6d9; + } + + .sm\:focus\:border-teal-400:focus { + border-color: #4fd1c5; + } + + .sm\:focus\:border-teal-500:focus { + border-color: #38b2ac; + } + + .sm\:focus\:border-teal-600:focus { + border-color: #319795; + } + + .sm\:focus\:border-teal-700:focus { + border-color: #2c7a7b; + } + + .sm\:focus\:border-teal-800:focus { + border-color: #285e61; + } + + .sm\:focus\:border-teal-900:focus { + border-color: #234e52; + } + + .sm\:focus\:border-blue-100:focus { + border-color: #ebf8ff; + } + + .sm\:focus\:border-blue-200:focus { + border-color: #bee3f8; + } + + .sm\:focus\:border-blue-300:focus { + border-color: #90cdf4; + } + + .sm\:focus\:border-blue-400:focus { + border-color: #63b3ed; + } + + .sm\:focus\:border-blue-500:focus { + border-color: #4299e1; + } + + .sm\:focus\:border-blue-600:focus { + border-color: #3182ce; + } + + .sm\:focus\:border-blue-700:focus { + border-color: #2b6cb0; + } + + .sm\:focus\:border-blue-800:focus { + border-color: #2c5282; + } + + .sm\:focus\:border-blue-900:focus { + border-color: #2a4365; + } + + .sm\:focus\:border-indigo-100:focus { + border-color: #ebf4ff; + } + + .sm\:focus\:border-indigo-200:focus { + border-color: #c3dafe; + } + + .sm\:focus\:border-indigo-300:focus { + border-color: #a3bffa; + } + + .sm\:focus\:border-indigo-400:focus { + border-color: #7f9cf5; + } + + .sm\:focus\:border-indigo-500:focus { + border-color: #667eea; + } + + .sm\:focus\:border-indigo-600:focus { + border-color: #5a67d8; + } + + .sm\:focus\:border-indigo-700:focus { + border-color: #4c51bf; + } + + .sm\:focus\:border-indigo-800:focus { + border-color: #434190; + } + + .sm\:focus\:border-indigo-900:focus { + border-color: #3c366b; + } + + .sm\:focus\:border-purple-100:focus { + border-color: #faf5ff; + } + + .sm\:focus\:border-purple-200:focus { + border-color: #e9d8fd; + } + + .sm\:focus\:border-purple-300:focus { + border-color: #d6bcfa; + } + + .sm\:focus\:border-purple-400:focus { + border-color: #b794f4; + } + + .sm\:focus\:border-purple-500:focus { + border-color: #9f7aea; + } + + .sm\:focus\:border-purple-600:focus { + border-color: #805ad5; + } + + .sm\:focus\:border-purple-700:focus { + border-color: #6b46c1; + } + + .sm\:focus\:border-purple-800:focus { + border-color: #553c9a; + } + + .sm\:focus\:border-purple-900:focus { + border-color: #44337a; + } + + .sm\:focus\:border-pink-100:focus { + border-color: #fff5f7; + } + + .sm\:focus\:border-pink-200:focus { + border-color: #fed7e2; + } + + .sm\:focus\:border-pink-300:focus { + border-color: #fbb6ce; + } + + .sm\:focus\:border-pink-400:focus { + border-color: #f687b3; + } + + .sm\:focus\:border-pink-500:focus { + border-color: #ed64a6; + } + + .sm\:focus\:border-pink-600:focus { + border-color: #d53f8c; + } + + .sm\:focus\:border-pink-700:focus { + border-color: #b83280; + } + + .sm\:focus\:border-pink-800:focus { + border-color: #97266d; + } + + .sm\:focus\:border-pink-900:focus { + border-color: #702459; + } + + .sm\:rounded-none { + border-radius: 0; + } + + .sm\:rounded-sm { + border-radius: 0.125rem; + } + + .sm\:rounded { + border-radius: 0.25rem; + } + + .sm\:rounded-md { + border-radius: 0.375rem; + } + + .sm\:rounded-lg { + border-radius: 0.5rem; + } + + .sm\:rounded-full { + border-radius: 9999px; + } + + .sm\:rounded-t-none { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + + .sm\:rounded-r-none { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .sm\:rounded-b-none { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } + + .sm\:rounded-l-none { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + + .sm\:rounded-t-sm { + border-top-left-radius: 0.125rem; + border-top-right-radius: 0.125rem; + } + + .sm\:rounded-r-sm { + border-top-right-radius: 0.125rem; + border-bottom-right-radius: 0.125rem; + } + + .sm\:rounded-b-sm { + border-bottom-right-radius: 0.125rem; + border-bottom-left-radius: 0.125rem; + } + + .sm\:rounded-l-sm { + border-top-left-radius: 0.125rem; + border-bottom-left-radius: 0.125rem; + } + + .sm\:rounded-t { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; + } + + .sm\:rounded-r { + border-top-right-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; + } + + .sm\:rounded-b { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + } + + .sm\:rounded-l { + border-top-left-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + } + + .sm\:rounded-t-md { + border-top-left-radius: 0.375rem; + border-top-right-radius: 0.375rem; + } + + .sm\:rounded-r-md { + border-top-right-radius: 0.375rem; + border-bottom-right-radius: 0.375rem; + } + + .sm\:rounded-b-md { + border-bottom-right-radius: 0.375rem; + border-bottom-left-radius: 0.375rem; + } + + .sm\:rounded-l-md { + border-top-left-radius: 0.375rem; + border-bottom-left-radius: 0.375rem; + } + + .sm\:rounded-t-lg { + border-top-left-radius: 0.5rem; + border-top-right-radius: 0.5rem; + } + + .sm\:rounded-r-lg { + border-top-right-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; + } + + .sm\:rounded-b-lg { + border-bottom-right-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; + } + + .sm\:rounded-l-lg { + border-top-left-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; + } + + .sm\:rounded-t-full { + border-top-left-radius: 9999px; + border-top-right-radius: 9999px; + } + + .sm\:rounded-r-full { + border-top-right-radius: 9999px; + border-bottom-right-radius: 9999px; + } + + .sm\:rounded-b-full { + border-bottom-right-radius: 9999px; + border-bottom-left-radius: 9999px; + } + + .sm\:rounded-l-full { + border-top-left-radius: 9999px; + border-bottom-left-radius: 9999px; + } + + .sm\:rounded-tl-none { + border-top-left-radius: 0; + } + + .sm\:rounded-tr-none { + border-top-right-radius: 0; + } + + .sm\:rounded-br-none { + border-bottom-right-radius: 0; + } + + .sm\:rounded-bl-none { + border-bottom-left-radius: 0; + } + + .sm\:rounded-tl-sm { + border-top-left-radius: 0.125rem; + } + + .sm\:rounded-tr-sm { + border-top-right-radius: 0.125rem; + } + + .sm\:rounded-br-sm { + border-bottom-right-radius: 0.125rem; + } + + .sm\:rounded-bl-sm { + border-bottom-left-radius: 0.125rem; + } + + .sm\:rounded-tl { + border-top-left-radius: 0.25rem; + } + + .sm\:rounded-tr { + border-top-right-radius: 0.25rem; + } + + .sm\:rounded-br { + border-bottom-right-radius: 0.25rem; + } + + .sm\:rounded-bl { + border-bottom-left-radius: 0.25rem; + } + + .sm\:rounded-tl-md { + border-top-left-radius: 0.375rem; + } + + .sm\:rounded-tr-md { + border-top-right-radius: 0.375rem; + } + + .sm\:rounded-br-md { + border-bottom-right-radius: 0.375rem; + } + + .sm\:rounded-bl-md { + border-bottom-left-radius: 0.375rem; + } + + .sm\:rounded-tl-lg { + border-top-left-radius: 0.5rem; + } + + .sm\:rounded-tr-lg { + border-top-right-radius: 0.5rem; + } + + .sm\:rounded-br-lg { + border-bottom-right-radius: 0.5rem; + } + + .sm\:rounded-bl-lg { + border-bottom-left-radius: 0.5rem; + } + + .sm\:rounded-tl-full { + border-top-left-radius: 9999px; + } + + .sm\:rounded-tr-full { + border-top-right-radius: 9999px; + } + + .sm\:rounded-br-full { + border-bottom-right-radius: 9999px; + } + + .sm\:rounded-bl-full { + border-bottom-left-radius: 9999px; + } + + .sm\:border-solid { + border-style: solid; + } + + .sm\:border-dashed { + border-style: dashed; + } + + .sm\:border-dotted { + border-style: dotted; + } + + .sm\:border-double { + border-style: double; + } + + .sm\:border-none { + border-style: none; + } + + .sm\:border-0 { + border-width: 0; + } + + .sm\:border-2 { + border-width: 2px; + } + + .sm\:border-4 { + border-width: 4px; + } + + .sm\:border-8 { + border-width: 8px; + } + + .sm\:border { + border-width: 1px; + } + + .sm\:border-t-0 { + border-top-width: 0; + } + + .sm\:border-r-0 { + border-right-width: 0; + } + + .sm\:border-b-0 { + border-bottom-width: 0; + } + + .sm\:border-l-0 { + border-left-width: 0; + } + + .sm\:border-t-2 { + border-top-width: 2px; + } + + .sm\:border-r-2 { + border-right-width: 2px; + } + + .sm\:border-b-2 { + border-bottom-width: 2px; + } + + .sm\:border-l-2 { + border-left-width: 2px; + } + + .sm\:border-t-4 { + border-top-width: 4px; + } + + .sm\:border-r-4 { + border-right-width: 4px; + } + + .sm\:border-b-4 { + border-bottom-width: 4px; + } + + .sm\:border-l-4 { + border-left-width: 4px; + } + + .sm\:border-t-8 { + border-top-width: 8px; + } + + .sm\:border-r-8 { + border-right-width: 8px; + } + + .sm\:border-b-8 { + border-bottom-width: 8px; + } + + .sm\:border-l-8 { + border-left-width: 8px; + } + + .sm\:border-t { + border-top-width: 1px; + } + + .sm\:border-r { + border-right-width: 1px; + } + + .sm\:border-b { + border-bottom-width: 1px; + } + + .sm\:border-l { + border-left-width: 1px; + } + + .sm\:box-border { + box-sizing: border-box; + } + + .sm\:box-content { + box-sizing: content-box; + } + + .sm\:cursor-auto { + cursor: auto; + } + + .sm\:cursor-default { + cursor: default; + } + + .sm\:cursor-pointer { + cursor: pointer; + } + + .sm\:cursor-wait { + cursor: wait; + } + + .sm\:cursor-text { + cursor: text; + } + + .sm\:cursor-move { + cursor: move; + } + + .sm\:cursor-not-allowed { + cursor: not-allowed; + } + + .sm\:block { + display: block; + } + + .sm\:inline-block { + display: inline-block; + } + + .sm\:inline { + display: inline; + } + + .sm\:flex { + display: flex; + } + + .sm\:inline-flex { + display: inline-flex; + } + + .sm\:grid { + display: grid; + } + + .sm\:table { + display: table; + } + + .sm\:table-caption { + display: table-caption; + } + + .sm\:table-cell { + display: table-cell; + } + + .sm\:table-column { + display: table-column; + } + + .sm\:table-column-group { + display: table-column-group; + } + + .sm\:table-footer-group { + display: table-footer-group; + } + + .sm\:table-header-group { + display: table-header-group; + } + + .sm\:table-row-group { + display: table-row-group; + } + + .sm\:table-row { + display: table-row; + } + + .sm\:hidden { + display: none; + } + + .sm\:flex-row { + flex-direction: row; + } + + .sm\:flex-row-reverse { + flex-direction: row-reverse; + } + + .sm\:flex-col { + flex-direction: column; + } + + .sm\:flex-col-reverse { + flex-direction: column-reverse; + } + + .sm\:flex-wrap { + flex-wrap: wrap; + } + + .sm\:flex-wrap-reverse { + flex-wrap: wrap-reverse; + } + + .sm\:flex-no-wrap { + flex-wrap: nowrap; + } + + .sm\:items-start { + align-items: flex-start; + } + + .sm\:items-end { + align-items: flex-end; + } + + .sm\:items-center { + align-items: center; + } + + .sm\:items-baseline { + align-items: baseline; + } + + .sm\:items-stretch { + align-items: stretch; + } + + .sm\:self-auto { + align-self: auto; + } + + .sm\:self-start { + align-self: flex-start; + } + + .sm\:self-end { + align-self: flex-end; + } + + .sm\:self-center { + align-self: center; + } + + .sm\:self-stretch { + align-self: stretch; + } + + .sm\:justify-start { + justify-content: flex-start; + } + + .sm\:justify-end { + justify-content: flex-end; + } + + .sm\:justify-center { + justify-content: center; + } + + .sm\:justify-between { + justify-content: space-between; + } + + .sm\:justify-around { + justify-content: space-around; + } + + .sm\:justify-evenly { + justify-content: space-evenly; + } + + .sm\:content-center { + align-content: center; + } + + .sm\:content-start { + align-content: flex-start; + } + + .sm\:content-end { + align-content: flex-end; + } + + .sm\:content-between { + align-content: space-between; + } + + .sm\:content-around { + align-content: space-around; + } + + .sm\:flex-1 { + flex: 1 1 0%; + } + + .sm\:flex-auto { + flex: 1 1 auto; + } + + .sm\:flex-initial { + flex: 0 1 auto; + } + + .sm\:flex-none { + flex: none; + } + + .sm\:flex-grow-0 { + flex-grow: 0; + } + + .sm\:flex-grow { + flex-grow: 1; + } + + .sm\:flex-shrink-0 { + flex-shrink: 0; + } + + .sm\:flex-shrink { + flex-shrink: 1; + } + + .sm\:order-1 { + order: 1; + } + + .sm\:order-2 { + order: 2; + } + + .sm\:order-3 { + order: 3; + } + + .sm\:order-4 { + order: 4; + } + + .sm\:order-5 { + order: 5; + } + + .sm\:order-6 { + order: 6; + } + + .sm\:order-7 { + order: 7; + } + + .sm\:order-8 { + order: 8; + } + + .sm\:order-9 { + order: 9; + } + + .sm\:order-10 { + order: 10; + } + + .sm\:order-11 { + order: 11; + } + + .sm\:order-12 { + order: 12; + } + + .sm\:order-first { + order: -9999; + } + + .sm\:order-last { + order: 9999; + } + + .sm\:order-none { + order: 0; + } + + .sm\:float-right { + float: right; + } + + .sm\:float-left { + float: left; + } + + .sm\:float-none { + float: none; + } + + .sm\:clearfix:after { + content: ""; + display: table; + clear: both; + } + + .sm\:clear-left { + clear: left; + } + + .sm\:clear-right { + clear: right; + } + + .sm\:clear-both { + clear: both; + } + + .sm\:font-sans { + font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + } + + .sm\:font-serif { + font-family: Georgia, Cambria, "Times New Roman", Times, serif; + } + + .sm\:font-mono { + font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + } + + .sm\:font-hairline { + font-weight: 100; + } + + .sm\:font-thin { + font-weight: 200; + } + + .sm\:font-light { + font-weight: 300; + } + + .sm\:font-normal { + font-weight: 400; + } + + .sm\:font-medium { + font-weight: 500; + } + + .sm\:font-semibold { + font-weight: 600; + } + + .sm\:font-bold { + font-weight: 700; + } + + .sm\:font-extrabold { + font-weight: 800; + } + + .sm\:font-black { + font-weight: 900; + } + + .sm\:hover\:font-hairline:hover { + font-weight: 100; + } + + .sm\:hover\:font-thin:hover { + font-weight: 200; + } + + .sm\:hover\:font-light:hover { + font-weight: 300; + } + + .sm\:hover\:font-normal:hover { + font-weight: 400; + } + + .sm\:hover\:font-medium:hover { + font-weight: 500; + } + + .sm\:hover\:font-semibold:hover { + font-weight: 600; + } + + .sm\:hover\:font-bold:hover { + font-weight: 700; + } + + .sm\:hover\:font-extrabold:hover { + font-weight: 800; + } + + .sm\:hover\:font-black:hover { + font-weight: 900; + } + + .sm\:focus\:font-hairline:focus { + font-weight: 100; + } + + .sm\:focus\:font-thin:focus { + font-weight: 200; + } + + .sm\:focus\:font-light:focus { + font-weight: 300; + } + + .sm\:focus\:font-normal:focus { + font-weight: 400; + } + + .sm\:focus\:font-medium:focus { + font-weight: 500; + } + + .sm\:focus\:font-semibold:focus { + font-weight: 600; + } + + .sm\:focus\:font-bold:focus { + font-weight: 700; + } + + .sm\:focus\:font-extrabold:focus { + font-weight: 800; + } + + .sm\:focus\:font-black:focus { + font-weight: 900; + } + + .sm\:h-0 { + height: 0; + } + + .sm\:h-1 { + height: 0.25rem; + } + + .sm\:h-2 { + height: 0.5rem; + } + + .sm\:h-3 { + height: 0.75rem; + } + + .sm\:h-4 { + height: 1rem; + } + + .sm\:h-5 { + height: 1.25rem; + } + + .sm\:h-6 { + height: 1.5rem; + } + + .sm\:h-8 { + height: 2rem; + } + + .sm\:h-10 { + height: 2.5rem; + } + + .sm\:h-12 { + height: 3rem; + } + + .sm\:h-16 { + height: 4rem; + } + + .sm\:h-20 { + height: 5rem; + } + + .sm\:h-24 { + height: 6rem; + } + + .sm\:h-32 { + height: 8rem; + } + + .sm\:h-40 { + height: 10rem; + } + + .sm\:h-48 { + height: 12rem; + } + + .sm\:h-56 { + height: 14rem; + } + + .sm\:h-64 { + height: 16rem; + } + + .sm\:h-auto { + height: auto; + } + + .sm\:h-px { + height: 1px; + } + + .sm\:h-full { + height: 100%; + } + + .sm\:h-screen { + height: 100vh; + } + + .sm\:leading-3 { + line-height: .75rem; + } + + .sm\:leading-4 { + line-height: 1rem; + } + + .sm\:leading-5 { + line-height: 1.25rem; + } + + .sm\:leading-6 { + line-height: 1.5rem; + } + + .sm\:leading-7 { + line-height: 1.75rem; + } + + .sm\:leading-8 { + line-height: 2rem; + } + + .sm\:leading-9 { + line-height: 2.25rem; + } + + .sm\:leading-10 { + line-height: 2.5rem; + } + + .sm\:leading-none { + line-height: 1; + } + + .sm\:leading-tight { + line-height: 1.25; + } + + .sm\:leading-snug { + line-height: 1.375; + } + + .sm\:leading-normal { + line-height: 1.5; + } + + .sm\:leading-relaxed { + line-height: 1.625; + } + + .sm\:leading-loose { + line-height: 2; + } + + .sm\:list-inside { + list-style-position: inside; + } + + .sm\:list-outside { + list-style-position: outside; + } + + .sm\:list-none { + list-style-type: none; + } + + .sm\:list-disc { + list-style-type: disc; + } + + .sm\:list-decimal { + list-style-type: decimal; + } + + .sm\:m-0 { + margin: 0; + } + + .sm\:m-1 { + margin: 0.25rem; + } + + .sm\:m-2 { + margin: 0.5rem; + } + + .sm\:m-3 { + margin: 0.75rem; + } + + .sm\:m-4 { + margin: 1rem; + } + + .sm\:m-5 { + margin: 1.25rem; + } + + .sm\:m-6 { + margin: 1.5rem; + } + + .sm\:m-8 { + margin: 2rem; + } + + .sm\:m-10 { + margin: 2.5rem; + } + + .sm\:m-12 { + margin: 3rem; + } + + .sm\:m-16 { + margin: 4rem; + } + + .sm\:m-20 { + margin: 5rem; + } + + .sm\:m-24 { + margin: 6rem; + } + + .sm\:m-32 { + margin: 8rem; + } + + .sm\:m-40 { + margin: 10rem; + } + + .sm\:m-48 { + margin: 12rem; + } + + .sm\:m-56 { + margin: 14rem; + } + + .sm\:m-64 { + margin: 16rem; + } + + .sm\:m-auto { + margin: auto; + } + + .sm\:m-px { + margin: 1px; + } + + .sm\:-m-1 { + margin: -0.25rem; + } + + .sm\:-m-2 { + margin: -0.5rem; + } + + .sm\:-m-3 { + margin: -0.75rem; + } + + .sm\:-m-4 { + margin: -1rem; + } + + .sm\:-m-5 { + margin: -1.25rem; + } + + .sm\:-m-6 { + margin: -1.5rem; + } + + .sm\:-m-8 { + margin: -2rem; + } + + .sm\:-m-10 { + margin: -2.5rem; + } + + .sm\:-m-12 { + margin: -3rem; + } + + .sm\:-m-16 { + margin: -4rem; + } + + .sm\:-m-20 { + margin: -5rem; + } + + .sm\:-m-24 { + margin: -6rem; + } + + .sm\:-m-32 { + margin: -8rem; + } + + .sm\:-m-40 { + margin: -10rem; + } + + .sm\:-m-48 { + margin: -12rem; + } + + .sm\:-m-56 { + margin: -14rem; + } + + .sm\:-m-64 { + margin: -16rem; + } + + .sm\:-m-px { + margin: -1px; + } + + .sm\:my-0 { + margin-top: 0; + margin-bottom: 0; + } + + .sm\:mx-0 { + margin-left: 0; + margin-right: 0; + } + + .sm\:my-1 { + margin-top: 0.25rem; + margin-bottom: 0.25rem; + } + + .sm\:mx-1 { + margin-left: 0.25rem; + margin-right: 0.25rem; + } + + .sm\:my-2 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; + } + + .sm\:mx-2 { + margin-left: 0.5rem; + margin-right: 0.5rem; + } + + .sm\:my-3 { + margin-top: 0.75rem; + margin-bottom: 0.75rem; + } + + .sm\:mx-3 { + margin-left: 0.75rem; + margin-right: 0.75rem; + } + + .sm\:my-4 { + margin-top: 1rem; + margin-bottom: 1rem; + } + + .sm\:mx-4 { + margin-left: 1rem; + margin-right: 1rem; + } + + .sm\:my-5 { + margin-top: 1.25rem; + margin-bottom: 1.25rem; + } + + .sm\:mx-5 { + margin-left: 1.25rem; + margin-right: 1.25rem; + } + + .sm\:my-6 { + margin-top: 1.5rem; + margin-bottom: 1.5rem; + } + + .sm\:mx-6 { + margin-left: 1.5rem; + margin-right: 1.5rem; + } + + .sm\:my-8 { + margin-top: 2rem; + margin-bottom: 2rem; + } + + .sm\:mx-8 { + margin-left: 2rem; + margin-right: 2rem; + } + + .sm\:my-10 { + margin-top: 2.5rem; + margin-bottom: 2.5rem; + } + + .sm\:mx-10 { + margin-left: 2.5rem; + margin-right: 2.5rem; + } + + .sm\:my-12 { + margin-top: 3rem; + margin-bottom: 3rem; + } + + .sm\:mx-12 { + margin-left: 3rem; + margin-right: 3rem; + } + + .sm\:my-16 { + margin-top: 4rem; + margin-bottom: 4rem; + } + + .sm\:mx-16 { + margin-left: 4rem; + margin-right: 4rem; + } + + .sm\:my-20 { + margin-top: 5rem; + margin-bottom: 5rem; + } + + .sm\:mx-20 { + margin-left: 5rem; + margin-right: 5rem; + } + + .sm\:my-24 { + margin-top: 6rem; + margin-bottom: 6rem; + } + + .sm\:mx-24 { + margin-left: 6rem; + margin-right: 6rem; + } + + .sm\:my-32 { + margin-top: 8rem; + margin-bottom: 8rem; + } + + .sm\:mx-32 { + margin-left: 8rem; + margin-right: 8rem; + } + + .sm\:my-40 { + margin-top: 10rem; + margin-bottom: 10rem; + } + + .sm\:mx-40 { + margin-left: 10rem; + margin-right: 10rem; + } + + .sm\:my-48 { + margin-top: 12rem; + margin-bottom: 12rem; + } + + .sm\:mx-48 { + margin-left: 12rem; + margin-right: 12rem; + } + + .sm\:my-56 { + margin-top: 14rem; + margin-bottom: 14rem; + } + + .sm\:mx-56 { + margin-left: 14rem; + margin-right: 14rem; + } + + .sm\:my-64 { + margin-top: 16rem; + margin-bottom: 16rem; + } + + .sm\:mx-64 { + margin-left: 16rem; + margin-right: 16rem; + } + + .sm\:my-auto { + margin-top: auto; + margin-bottom: auto; + } + + .sm\:mx-auto { + margin-left: auto; + margin-right: auto; + } + + .sm\:my-px { + margin-top: 1px; + margin-bottom: 1px; + } + + .sm\:mx-px { + margin-left: 1px; + margin-right: 1px; + } + + .sm\:-my-1 { + margin-top: -0.25rem; + margin-bottom: -0.25rem; + } + + .sm\:-mx-1 { + margin-left: -0.25rem; + margin-right: -0.25rem; + } + + .sm\:-my-2 { + margin-top: -0.5rem; + margin-bottom: -0.5rem; + } + + .sm\:-mx-2 { + margin-left: -0.5rem; + margin-right: -0.5rem; + } + + .sm\:-my-3 { + margin-top: -0.75rem; + margin-bottom: -0.75rem; + } + + .sm\:-mx-3 { + margin-left: -0.75rem; + margin-right: -0.75rem; + } + + .sm\:-my-4 { + margin-top: -1rem; + margin-bottom: -1rem; + } + + .sm\:-mx-4 { + margin-left: -1rem; + margin-right: -1rem; + } + + .sm\:-my-5 { + margin-top: -1.25rem; + margin-bottom: -1.25rem; + } + + .sm\:-mx-5 { + margin-left: -1.25rem; + margin-right: -1.25rem; + } + + .sm\:-my-6 { + margin-top: -1.5rem; + margin-bottom: -1.5rem; + } + + .sm\:-mx-6 { + margin-left: -1.5rem; + margin-right: -1.5rem; + } + + .sm\:-my-8 { + margin-top: -2rem; + margin-bottom: -2rem; + } + + .sm\:-mx-8 { + margin-left: -2rem; + margin-right: -2rem; + } + + .sm\:-my-10 { + margin-top: -2.5rem; + margin-bottom: -2.5rem; + } + + .sm\:-mx-10 { + margin-left: -2.5rem; + margin-right: -2.5rem; + } + + .sm\:-my-12 { + margin-top: -3rem; + margin-bottom: -3rem; + } + + .sm\:-mx-12 { + margin-left: -3rem; + margin-right: -3rem; + } + + .sm\:-my-16 { + margin-top: -4rem; + margin-bottom: -4rem; + } + + .sm\:-mx-16 { + margin-left: -4rem; + margin-right: -4rem; + } + + .sm\:-my-20 { + margin-top: -5rem; + margin-bottom: -5rem; + } + + .sm\:-mx-20 { + margin-left: -5rem; + margin-right: -5rem; + } + + .sm\:-my-24 { + margin-top: -6rem; + margin-bottom: -6rem; + } + + .sm\:-mx-24 { + margin-left: -6rem; + margin-right: -6rem; + } + + .sm\:-my-32 { + margin-top: -8rem; + margin-bottom: -8rem; + } + + .sm\:-mx-32 { + margin-left: -8rem; + margin-right: -8rem; + } + + .sm\:-my-40 { + margin-top: -10rem; + margin-bottom: -10rem; + } + + .sm\:-mx-40 { + margin-left: -10rem; + margin-right: -10rem; + } + + .sm\:-my-48 { + margin-top: -12rem; + margin-bottom: -12rem; + } + + .sm\:-mx-48 { + margin-left: -12rem; + margin-right: -12rem; + } + + .sm\:-my-56 { + margin-top: -14rem; + margin-bottom: -14rem; + } + + .sm\:-mx-56 { + margin-left: -14rem; + margin-right: -14rem; + } + + .sm\:-my-64 { + margin-top: -16rem; + margin-bottom: -16rem; + } + + .sm\:-mx-64 { + margin-left: -16rem; + margin-right: -16rem; + } + + .sm\:-my-px { + margin-top: -1px; + margin-bottom: -1px; + } + + .sm\:-mx-px { + margin-left: -1px; + margin-right: -1px; + } + + .sm\:mt-0 { + margin-top: 0; + } + + .sm\:mr-0 { + margin-right: 0; + } + + .sm\:mb-0 { + margin-bottom: 0; + } + + .sm\:ml-0 { + margin-left: 0; + } + + .sm\:mt-1 { + margin-top: 0.25rem; + } + + .sm\:mr-1 { + margin-right: 0.25rem; + } + + .sm\:mb-1 { + margin-bottom: 0.25rem; + } + + .sm\:ml-1 { + margin-left: 0.25rem; + } + + .sm\:mt-2 { + margin-top: 0.5rem; + } + + .sm\:mr-2 { + margin-right: 0.5rem; + } + + .sm\:mb-2 { + margin-bottom: 0.5rem; + } + + .sm\:ml-2 { + margin-left: 0.5rem; + } + + .sm\:mt-3 { + margin-top: 0.75rem; + } + + .sm\:mr-3 { + margin-right: 0.75rem; + } + + .sm\:mb-3 { + margin-bottom: 0.75rem; + } + + .sm\:ml-3 { + margin-left: 0.75rem; + } + + .sm\:mt-4 { + margin-top: 1rem; + } + + .sm\:mr-4 { + margin-right: 1rem; + } + + .sm\:mb-4 { + margin-bottom: 1rem; + } + + .sm\:ml-4 { + margin-left: 1rem; + } + + .sm\:mt-5 { + margin-top: 1.25rem; + } + + .sm\:mr-5 { + margin-right: 1.25rem; + } + + .sm\:mb-5 { + margin-bottom: 1.25rem; + } + + .sm\:ml-5 { + margin-left: 1.25rem; + } + + .sm\:mt-6 { + margin-top: 1.5rem; + } + + .sm\:mr-6 { + margin-right: 1.5rem; + } + + .sm\:mb-6 { + margin-bottom: 1.5rem; + } + + .sm\:ml-6 { + margin-left: 1.5rem; + } + + .sm\:mt-8 { + margin-top: 2rem; + } + + .sm\:mr-8 { + margin-right: 2rem; + } + + .sm\:mb-8 { + margin-bottom: 2rem; + } + + .sm\:ml-8 { + margin-left: 2rem; + } + + .sm\:mt-10 { + margin-top: 2.5rem; + } + + .sm\:mr-10 { + margin-right: 2.5rem; + } + + .sm\:mb-10 { + margin-bottom: 2.5rem; + } + + .sm\:ml-10 { + margin-left: 2.5rem; + } + + .sm\:mt-12 { + margin-top: 3rem; + } + + .sm\:mr-12 { + margin-right: 3rem; + } + + .sm\:mb-12 { + margin-bottom: 3rem; + } + + .sm\:ml-12 { + margin-left: 3rem; + } + + .sm\:mt-16 { + margin-top: 4rem; + } + + .sm\:mr-16 { + margin-right: 4rem; + } + + .sm\:mb-16 { + margin-bottom: 4rem; + } + + .sm\:ml-16 { + margin-left: 4rem; + } + + .sm\:mt-20 { + margin-top: 5rem; + } + + .sm\:mr-20 { + margin-right: 5rem; + } + + .sm\:mb-20 { + margin-bottom: 5rem; + } + + .sm\:ml-20 { + margin-left: 5rem; + } + + .sm\:mt-24 { + margin-top: 6rem; + } + + .sm\:mr-24 { + margin-right: 6rem; + } + + .sm\:mb-24 { + margin-bottom: 6rem; + } + + .sm\:ml-24 { + margin-left: 6rem; + } + + .sm\:mt-32 { + margin-top: 8rem; + } + + .sm\:mr-32 { + margin-right: 8rem; + } + + .sm\:mb-32 { + margin-bottom: 8rem; + } + + .sm\:ml-32 { + margin-left: 8rem; + } + + .sm\:mt-40 { + margin-top: 10rem; + } + + .sm\:mr-40 { + margin-right: 10rem; + } + + .sm\:mb-40 { + margin-bottom: 10rem; + } + + .sm\:ml-40 { + margin-left: 10rem; + } + + .sm\:mt-48 { + margin-top: 12rem; + } + + .sm\:mr-48 { + margin-right: 12rem; + } + + .sm\:mb-48 { + margin-bottom: 12rem; + } + + .sm\:ml-48 { + margin-left: 12rem; + } + + .sm\:mt-56 { + margin-top: 14rem; + } + + .sm\:mr-56 { + margin-right: 14rem; + } + + .sm\:mb-56 { + margin-bottom: 14rem; + } + + .sm\:ml-56 { + margin-left: 14rem; + } + + .sm\:mt-64 { + margin-top: 16rem; + } + + .sm\:mr-64 { + margin-right: 16rem; + } + + .sm\:mb-64 { + margin-bottom: 16rem; + } + + .sm\:ml-64 { + margin-left: 16rem; + } + + .sm\:mt-auto { + margin-top: auto; + } + + .sm\:mr-auto { + margin-right: auto; + } + + .sm\:mb-auto { + margin-bottom: auto; + } + + .sm\:ml-auto { + margin-left: auto; + } + + .sm\:mt-px { + margin-top: 1px; + } + + .sm\:mr-px { + margin-right: 1px; + } + + .sm\:mb-px { + margin-bottom: 1px; + } + + .sm\:ml-px { + margin-left: 1px; + } + + .sm\:-mt-1 { + margin-top: -0.25rem; + } + + .sm\:-mr-1 { + margin-right: -0.25rem; + } + + .sm\:-mb-1 { + margin-bottom: -0.25rem; + } + + .sm\:-ml-1 { + margin-left: -0.25rem; + } + + .sm\:-mt-2 { + margin-top: -0.5rem; + } + + .sm\:-mr-2 { + margin-right: -0.5rem; + } + + .sm\:-mb-2 { + margin-bottom: -0.5rem; + } + + .sm\:-ml-2 { + margin-left: -0.5rem; + } + + .sm\:-mt-3 { + margin-top: -0.75rem; + } + + .sm\:-mr-3 { + margin-right: -0.75rem; + } + + .sm\:-mb-3 { + margin-bottom: -0.75rem; + } + + .sm\:-ml-3 { + margin-left: -0.75rem; + } + + .sm\:-mt-4 { + margin-top: -1rem; + } + + .sm\:-mr-4 { + margin-right: -1rem; + } + + .sm\:-mb-4 { + margin-bottom: -1rem; + } + + .sm\:-ml-4 { + margin-left: -1rem; + } + + .sm\:-mt-5 { + margin-top: -1.25rem; + } + + .sm\:-mr-5 { + margin-right: -1.25rem; + } + + .sm\:-mb-5 { + margin-bottom: -1.25rem; + } + + .sm\:-ml-5 { + margin-left: -1.25rem; + } + + .sm\:-mt-6 { + margin-top: -1.5rem; + } + + .sm\:-mr-6 { + margin-right: -1.5rem; + } + + .sm\:-mb-6 { + margin-bottom: -1.5rem; + } + + .sm\:-ml-6 { + margin-left: -1.5rem; + } + + .sm\:-mt-8 { + margin-top: -2rem; + } + + .sm\:-mr-8 { + margin-right: -2rem; + } + + .sm\:-mb-8 { + margin-bottom: -2rem; + } + + .sm\:-ml-8 { + margin-left: -2rem; + } + + .sm\:-mt-10 { + margin-top: -2.5rem; + } + + .sm\:-mr-10 { + margin-right: -2.5rem; + } + + .sm\:-mb-10 { + margin-bottom: -2.5rem; + } + + .sm\:-ml-10 { + margin-left: -2.5rem; + } + + .sm\:-mt-12 { + margin-top: -3rem; + } + + .sm\:-mr-12 { + margin-right: -3rem; + } + + .sm\:-mb-12 { + margin-bottom: -3rem; + } + + .sm\:-ml-12 { + margin-left: -3rem; + } + + .sm\:-mt-16 { + margin-top: -4rem; + } + + .sm\:-mr-16 { + margin-right: -4rem; + } + + .sm\:-mb-16 { + margin-bottom: -4rem; + } + + .sm\:-ml-16 { + margin-left: -4rem; + } + + .sm\:-mt-20 { + margin-top: -5rem; + } + + .sm\:-mr-20 { + margin-right: -5rem; + } + + .sm\:-mb-20 { + margin-bottom: -5rem; + } + + .sm\:-ml-20 { + margin-left: -5rem; + } + + .sm\:-mt-24 { + margin-top: -6rem; + } + + .sm\:-mr-24 { + margin-right: -6rem; + } + + .sm\:-mb-24 { + margin-bottom: -6rem; + } + + .sm\:-ml-24 { + margin-left: -6rem; + } + + .sm\:-mt-32 { + margin-top: -8rem; + } + + .sm\:-mr-32 { + margin-right: -8rem; + } + + .sm\:-mb-32 { + margin-bottom: -8rem; + } + + .sm\:-ml-32 { + margin-left: -8rem; + } + + .sm\:-mt-40 { + margin-top: -10rem; + } + + .sm\:-mr-40 { + margin-right: -10rem; + } + + .sm\:-mb-40 { + margin-bottom: -10rem; + } + + .sm\:-ml-40 { + margin-left: -10rem; + } + + .sm\:-mt-48 { + margin-top: -12rem; + } + + .sm\:-mr-48 { + margin-right: -12rem; + } + + .sm\:-mb-48 { + margin-bottom: -12rem; + } + + .sm\:-ml-48 { + margin-left: -12rem; + } + + .sm\:-mt-56 { + margin-top: -14rem; + } + + .sm\:-mr-56 { + margin-right: -14rem; + } + + .sm\:-mb-56 { + margin-bottom: -14rem; + } + + .sm\:-ml-56 { + margin-left: -14rem; + } + + .sm\:-mt-64 { + margin-top: -16rem; + } + + .sm\:-mr-64 { + margin-right: -16rem; + } + + .sm\:-mb-64 { + margin-bottom: -16rem; + } + + .sm\:-ml-64 { + margin-left: -16rem; + } + + .sm\:-mt-px { + margin-top: -1px; + } + + .sm\:-mr-px { + margin-right: -1px; + } + + .sm\:-mb-px { + margin-bottom: -1px; + } + + .sm\:-ml-px { + margin-left: -1px; + } + + .sm\:max-h-full { + max-height: 100%; + } + + .sm\:max-h-screen { + max-height: 100vh; + } + + .sm\:max-w-none { + max-width: none; + } + + .sm\:max-w-xs { + max-width: 20rem; + } + + .sm\:max-w-sm { + max-width: 24rem; + } + + .sm\:max-w-md { + max-width: 28rem; + } + + .sm\:max-w-lg { + max-width: 32rem; + } + + .sm\:max-w-xl { + max-width: 36rem; + } + + .sm\:max-w-2xl { + max-width: 42rem; + } + + .sm\:max-w-3xl { + max-width: 48rem; + } + + .sm\:max-w-4xl { + max-width: 56rem; + } + + .sm\:max-w-5xl { + max-width: 64rem; + } + + .sm\:max-w-6xl { + max-width: 72rem; + } + + .sm\:max-w-full { + max-width: 100%; + } + + .sm\:max-w-screen-sm { + max-width: 640px; + } + + .sm\:max-w-screen-md { + max-width: 768px; + } + + .sm\:max-w-screen-lg { + max-width: 1024px; + } + + .sm\:max-w-screen-xl { + max-width: 1280px; + } + + .sm\:min-h-0 { + min-height: 0; + } + + .sm\:min-h-full { + min-height: 100%; + } + + .sm\:min-h-screen { + min-height: 100vh; + } + + .sm\:min-w-0 { + min-width: 0; + } + + .sm\:min-w-full { + min-width: 100%; + } + + .sm\:object-contain { + object-fit: contain; + } + + .sm\:object-cover { + object-fit: cover; + } + + .sm\:object-fill { + object-fit: fill; + } + + .sm\:object-none { + object-fit: none; + } + + .sm\:object-scale-down { + object-fit: scale-down; + } + + .sm\:object-bottom { + object-position: bottom; + } + + .sm\:object-center { + object-position: center; + } + + .sm\:object-left { + object-position: left; + } + + .sm\:object-left-bottom { + object-position: left bottom; + } + + .sm\:object-left-top { + object-position: left top; + } + + .sm\:object-right { + object-position: right; + } + + .sm\:object-right-bottom { + object-position: right bottom; + } + + .sm\:object-right-top { + object-position: right top; + } + + .sm\:object-top { + object-position: top; + } + + .sm\:opacity-0 { + opacity: 0; + } + + .sm\:opacity-25 { + opacity: 0.25; + } + + .sm\:opacity-50 { + opacity: 0.5; + } + + .sm\:opacity-75 { + opacity: 0.75; + } + + .sm\:opacity-100 { + opacity: 1; + } + + .sm\:hover\:opacity-0:hover { + opacity: 0; + } + + .sm\:hover\:opacity-25:hover { + opacity: 0.25; + } + + .sm\:hover\:opacity-50:hover { + opacity: 0.5; + } + + .sm\:hover\:opacity-75:hover { + opacity: 0.75; + } + + .sm\:hover\:opacity-100:hover { + opacity: 1; + } + + .sm\:focus\:opacity-0:focus { + opacity: 0; + } + + .sm\:focus\:opacity-25:focus { + opacity: 0.25; + } + + .sm\:focus\:opacity-50:focus { + opacity: 0.5; + } + + .sm\:focus\:opacity-75:focus { + opacity: 0.75; + } + + .sm\:focus\:opacity-100:focus { + opacity: 1; + } + + .sm\:outline-none { + outline: 0; + } + + .sm\:focus\:outline-none:focus { + outline: 0; + } + + .sm\:overflow-auto { + overflow: auto; + } + + .sm\:overflow-hidden { + overflow: hidden; + } + + .sm\:overflow-visible { + overflow: visible; + } + + .sm\:overflow-scroll { + overflow: scroll; + } + + .sm\:overflow-x-auto { + overflow-x: auto; + } + + .sm\:overflow-y-auto { + overflow-y: auto; + } + + .sm\:overflow-x-hidden { + overflow-x: hidden; + } + + .sm\:overflow-y-hidden { + overflow-y: hidden; + } + + .sm\:overflow-x-visible { + overflow-x: visible; + } + + .sm\:overflow-y-visible { + overflow-y: visible; + } + + .sm\:overflow-x-scroll { + overflow-x: scroll; + } + + .sm\:overflow-y-scroll { + overflow-y: scroll; + } + + .sm\:scrolling-touch { + -webkit-overflow-scrolling: touch; + } + + .sm\:scrolling-auto { + -webkit-overflow-scrolling: auto; + } + + .sm\:p-0 { + padding: 0; + } + + .sm\:p-1 { + padding: 0.25rem; + } + + .sm\:p-2 { + padding: 0.5rem; + } + + .sm\:p-3 { + padding: 0.75rem; + } + + .sm\:p-4 { + padding: 1rem; + } + + .sm\:p-5 { + padding: 1.25rem; + } + + .sm\:p-6 { + padding: 1.5rem; + } + + .sm\:p-8 { + padding: 2rem; + } + + .sm\:p-10 { + padding: 2.5rem; + } + + .sm\:p-12 { + padding: 3rem; + } + + .sm\:p-16 { + padding: 4rem; + } + + .sm\:p-20 { + padding: 5rem; + } + + .sm\:p-24 { + padding: 6rem; + } + + .sm\:p-32 { + padding: 8rem; + } + + .sm\:p-40 { + padding: 10rem; + } + + .sm\:p-48 { + padding: 12rem; + } + + .sm\:p-56 { + padding: 14rem; + } + + .sm\:p-64 { + padding: 16rem; + } + + .sm\:p-px { + padding: 1px; + } + + .sm\:py-0 { + padding-top: 0; + padding-bottom: 0; + } + + .sm\:px-0 { + padding-left: 0; + padding-right: 0; + } + + .sm\:py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + + .sm\:px-1 { + padding-left: 0.25rem; + padding-right: 0.25rem; + } + + .sm\:py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + } + + .sm\:px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; + } + + .sm\:py-3 { + padding-top: 0.75rem; + padding-bottom: 0.75rem; + } + + .sm\:px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; + } + + .sm\:py-4 { + padding-top: 1rem; + padding-bottom: 1rem; + } + + .sm\:px-4 { + padding-left: 1rem; + padding-right: 1rem; + } + + .sm\:py-5 { + padding-top: 1.25rem; + padding-bottom: 1.25rem; + } + + .sm\:px-5 { + padding-left: 1.25rem; + padding-right: 1.25rem; + } + + .sm\:py-6 { + padding-top: 1.5rem; + padding-bottom: 1.5rem; + } + + .sm\:px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; + } + + .sm\:py-8 { + padding-top: 2rem; + padding-bottom: 2rem; + } + + .sm\:px-8 { + padding-left: 2rem; + padding-right: 2rem; + } + + .sm\:py-10 { + padding-top: 2.5rem; + padding-bottom: 2.5rem; + } + + .sm\:px-10 { + padding-left: 2.5rem; + padding-right: 2.5rem; + } + + .sm\:py-12 { + padding-top: 3rem; + padding-bottom: 3rem; + } + + .sm\:px-12 { + padding-left: 3rem; + padding-right: 3rem; + } + + .sm\:py-16 { + padding-top: 4rem; + padding-bottom: 4rem; + } + + .sm\:px-16 { + padding-left: 4rem; + padding-right: 4rem; + } + + .sm\:py-20 { + padding-top: 5rem; + padding-bottom: 5rem; + } + + .sm\:px-20 { + padding-left: 5rem; + padding-right: 5rem; + } + + .sm\:py-24 { + padding-top: 6rem; + padding-bottom: 6rem; + } + + .sm\:px-24 { + padding-left: 6rem; + padding-right: 6rem; + } + + .sm\:py-32 { + padding-top: 8rem; + padding-bottom: 8rem; + } + + .sm\:px-32 { + padding-left: 8rem; + padding-right: 8rem; + } + + .sm\:py-40 { + padding-top: 10rem; + padding-bottom: 10rem; + } + + .sm\:px-40 { + padding-left: 10rem; + padding-right: 10rem; + } + + .sm\:py-48 { + padding-top: 12rem; + padding-bottom: 12rem; + } + + .sm\:px-48 { + padding-left: 12rem; + padding-right: 12rem; + } + + .sm\:py-56 { + padding-top: 14rem; + padding-bottom: 14rem; + } + + .sm\:px-56 { + padding-left: 14rem; + padding-right: 14rem; + } + + .sm\:py-64 { + padding-top: 16rem; + padding-bottom: 16rem; + } + + .sm\:px-64 { + padding-left: 16rem; + padding-right: 16rem; + } + + .sm\:py-px { + padding-top: 1px; + padding-bottom: 1px; + } + + .sm\:px-px { + padding-left: 1px; + padding-right: 1px; + } + + .sm\:pt-0 { + padding-top: 0; + } + + .sm\:pr-0 { + padding-right: 0; + } + + .sm\:pb-0 { + padding-bottom: 0; + } + + .sm\:pl-0 { + padding-left: 0; + } + + .sm\:pt-1 { + padding-top: 0.25rem; + } + + .sm\:pr-1 { + padding-right: 0.25rem; + } + + .sm\:pb-1 { + padding-bottom: 0.25rem; + } + + .sm\:pl-1 { + padding-left: 0.25rem; + } + + .sm\:pt-2 { + padding-top: 0.5rem; + } + + .sm\:pr-2 { + padding-right: 0.5rem; + } + + .sm\:pb-2 { + padding-bottom: 0.5rem; + } + + .sm\:pl-2 { + padding-left: 0.5rem; + } + + .sm\:pt-3 { + padding-top: 0.75rem; + } + + .sm\:pr-3 { + padding-right: 0.75rem; + } + + .sm\:pb-3 { + padding-bottom: 0.75rem; + } + + .sm\:pl-3 { + padding-left: 0.75rem; + } + + .sm\:pt-4 { + padding-top: 1rem; + } + + .sm\:pr-4 { + padding-right: 1rem; + } + + .sm\:pb-4 { + padding-bottom: 1rem; + } + + .sm\:pl-4 { + padding-left: 1rem; + } + + .sm\:pt-5 { + padding-top: 1.25rem; + } + + .sm\:pr-5 { + padding-right: 1.25rem; + } + + .sm\:pb-5 { + padding-bottom: 1.25rem; + } + + .sm\:pl-5 { + padding-left: 1.25rem; + } + + .sm\:pt-6 { + padding-top: 1.5rem; + } + + .sm\:pr-6 { + padding-right: 1.5rem; + } + + .sm\:pb-6 { + padding-bottom: 1.5rem; + } + + .sm\:pl-6 { + padding-left: 1.5rem; + } + + .sm\:pt-8 { + padding-top: 2rem; + } + + .sm\:pr-8 { + padding-right: 2rem; + } + + .sm\:pb-8 { + padding-bottom: 2rem; + } + + .sm\:pl-8 { + padding-left: 2rem; + } + + .sm\:pt-10 { + padding-top: 2.5rem; + } + + .sm\:pr-10 { + padding-right: 2.5rem; + } + + .sm\:pb-10 { + padding-bottom: 2.5rem; + } + + .sm\:pl-10 { + padding-left: 2.5rem; + } + + .sm\:pt-12 { + padding-top: 3rem; + } + + .sm\:pr-12 { + padding-right: 3rem; + } + + .sm\:pb-12 { + padding-bottom: 3rem; + } + + .sm\:pl-12 { + padding-left: 3rem; + } + + .sm\:pt-16 { + padding-top: 4rem; + } + + .sm\:pr-16 { + padding-right: 4rem; + } + + .sm\:pb-16 { + padding-bottom: 4rem; + } + + .sm\:pl-16 { + padding-left: 4rem; + } + + .sm\:pt-20 { + padding-top: 5rem; + } + + .sm\:pr-20 { + padding-right: 5rem; + } + + .sm\:pb-20 { + padding-bottom: 5rem; + } + + .sm\:pl-20 { + padding-left: 5rem; + } + + .sm\:pt-24 { + padding-top: 6rem; + } + + .sm\:pr-24 { + padding-right: 6rem; + } + + .sm\:pb-24 { + padding-bottom: 6rem; + } + + .sm\:pl-24 { + padding-left: 6rem; + } + + .sm\:pt-32 { + padding-top: 8rem; + } + + .sm\:pr-32 { + padding-right: 8rem; + } + + .sm\:pb-32 { + padding-bottom: 8rem; + } + + .sm\:pl-32 { + padding-left: 8rem; + } + + .sm\:pt-40 { + padding-top: 10rem; + } + + .sm\:pr-40 { + padding-right: 10rem; + } + + .sm\:pb-40 { + padding-bottom: 10rem; + } + + .sm\:pl-40 { + padding-left: 10rem; + } + + .sm\:pt-48 { + padding-top: 12rem; + } + + .sm\:pr-48 { + padding-right: 12rem; + } + + .sm\:pb-48 { + padding-bottom: 12rem; + } + + .sm\:pl-48 { + padding-left: 12rem; + } + + .sm\:pt-56 { + padding-top: 14rem; + } + + .sm\:pr-56 { + padding-right: 14rem; + } + + .sm\:pb-56 { + padding-bottom: 14rem; + } + + .sm\:pl-56 { + padding-left: 14rem; + } + + .sm\:pt-64 { + padding-top: 16rem; + } + + .sm\:pr-64 { + padding-right: 16rem; + } + + .sm\:pb-64 { + padding-bottom: 16rem; + } + + .sm\:pl-64 { + padding-left: 16rem; + } + + .sm\:pt-px { + padding-top: 1px; + } + + .sm\:pr-px { + padding-right: 1px; + } + + .sm\:pb-px { + padding-bottom: 1px; + } + + .sm\:pl-px { + padding-left: 1px; + } + + .sm\:placeholder-transparent::placeholder { + color: transparent; + } + + .sm\:placeholder-black::placeholder { + color: #000; + } + + .sm\:placeholder-white::placeholder { + color: #fff; + } + + .sm\:placeholder-gray-100::placeholder { + color: #f7fafc; + } + + .sm\:placeholder-gray-200::placeholder { + color: #edf2f7; + } + + .sm\:placeholder-gray-300::placeholder { + color: #e2e8f0; + } + + .sm\:placeholder-gray-400::placeholder { + color: #cbd5e0; + } + + .sm\:placeholder-gray-500::placeholder { + color: #a0aec0; + } + + .sm\:placeholder-gray-600::placeholder { + color: #718096; + } + + .sm\:placeholder-gray-700::placeholder { + color: #4a5568; + } + + .sm\:placeholder-gray-800::placeholder { + color: #2d3748; + } + + .sm\:placeholder-gray-900::placeholder { + color: #1a202c; + } + + .sm\:placeholder-red-100::placeholder { + color: #fff5f5; + } + + .sm\:placeholder-red-200::placeholder { + color: #fed7d7; + } + + .sm\:placeholder-red-300::placeholder { + color: #feb2b2; + } + + .sm\:placeholder-red-400::placeholder { + color: #fc8181; + } + + .sm\:placeholder-red-500::placeholder { + color: #f56565; + } + + .sm\:placeholder-red-600::placeholder { + color: #e53e3e; + } + + .sm\:placeholder-red-700::placeholder { + color: #c53030; + } + + .sm\:placeholder-red-800::placeholder { + color: #9b2c2c; + } + + .sm\:placeholder-red-900::placeholder { + color: #742a2a; + } + + .sm\:placeholder-orange-100::placeholder { + color: #fffaf0; + } + + .sm\:placeholder-orange-200::placeholder { + color: #feebc8; + } + + .sm\:placeholder-orange-300::placeholder { + color: #fbd38d; + } + + .sm\:placeholder-orange-400::placeholder { + color: #f6ad55; + } + + .sm\:placeholder-orange-500::placeholder { + color: #ed8936; + } + + .sm\:placeholder-orange-600::placeholder { + color: #dd6b20; + } + + .sm\:placeholder-orange-700::placeholder { + color: #c05621; + } + + .sm\:placeholder-orange-800::placeholder { + color: #9c4221; + } + + .sm\:placeholder-orange-900::placeholder { + color: #7b341e; + } + + .sm\:placeholder-yellow-100::placeholder { + color: #fffff0; + } + + .sm\:placeholder-yellow-200::placeholder { + color: #fefcbf; + } + + .sm\:placeholder-yellow-300::placeholder { + color: #faf089; + } + + .sm\:placeholder-yellow-400::placeholder { + color: #f6e05e; + } + + .sm\:placeholder-yellow-500::placeholder { + color: #ecc94b; + } + + .sm\:placeholder-yellow-600::placeholder { + color: #d69e2e; + } + + .sm\:placeholder-yellow-700::placeholder { + color: #b7791f; + } + + .sm\:placeholder-yellow-800::placeholder { + color: #975a16; + } + + .sm\:placeholder-yellow-900::placeholder { + color: #744210; + } + + .sm\:placeholder-green-100::placeholder { + color: #f0fff4; + } + + .sm\:placeholder-green-200::placeholder { + color: #c6f6d5; + } + + .sm\:placeholder-green-300::placeholder { + color: #9ae6b4; + } + + .sm\:placeholder-green-400::placeholder { + color: #68d391; + } + + .sm\:placeholder-green-500::placeholder { + color: #48bb78; + } + + .sm\:placeholder-green-600::placeholder { + color: #38a169; + } + + .sm\:placeholder-green-700::placeholder { + color: #2f855a; + } + + .sm\:placeholder-green-800::placeholder { + color: #276749; + } + + .sm\:placeholder-green-900::placeholder { + color: #22543d; + } + + .sm\:placeholder-teal-100::placeholder { + color: #e6fffa; + } + + .sm\:placeholder-teal-200::placeholder { + color: #b2f5ea; + } + + .sm\:placeholder-teal-300::placeholder { + color: #81e6d9; + } + + .sm\:placeholder-teal-400::placeholder { + color: #4fd1c5; + } + + .sm\:placeholder-teal-500::placeholder { + color: #38b2ac; + } + + .sm\:placeholder-teal-600::placeholder { + color: #319795; + } + + .sm\:placeholder-teal-700::placeholder { + color: #2c7a7b; + } + + .sm\:placeholder-teal-800::placeholder { + color: #285e61; + } + + .sm\:placeholder-teal-900::placeholder { + color: #234e52; + } + + .sm\:placeholder-blue-100::placeholder { + color: #ebf8ff; + } + + .sm\:placeholder-blue-200::placeholder { + color: #bee3f8; + } + + .sm\:placeholder-blue-300::placeholder { + color: #90cdf4; + } + + .sm\:placeholder-blue-400::placeholder { + color: #63b3ed; + } + + .sm\:placeholder-blue-500::placeholder { + color: #4299e1; + } + + .sm\:placeholder-blue-600::placeholder { + color: #3182ce; + } + + .sm\:placeholder-blue-700::placeholder { + color: #2b6cb0; + } + + .sm\:placeholder-blue-800::placeholder { + color: #2c5282; + } + + .sm\:placeholder-blue-900::placeholder { + color: #2a4365; + } + + .sm\:placeholder-indigo-100::placeholder { + color: #ebf4ff; + } + + .sm\:placeholder-indigo-200::placeholder { + color: #c3dafe; + } + + .sm\:placeholder-indigo-300::placeholder { + color: #a3bffa; + } + + .sm\:placeholder-indigo-400::placeholder { + color: #7f9cf5; + } + + .sm\:placeholder-indigo-500::placeholder { + color: #667eea; + } + + .sm\:placeholder-indigo-600::placeholder { + color: #5a67d8; + } + + .sm\:placeholder-indigo-700::placeholder { + color: #4c51bf; + } + + .sm\:placeholder-indigo-800::placeholder { + color: #434190; + } + + .sm\:placeholder-indigo-900::placeholder { + color: #3c366b; + } + + .sm\:placeholder-purple-100::placeholder { + color: #faf5ff; + } + + .sm\:placeholder-purple-200::placeholder { + color: #e9d8fd; + } + + .sm\:placeholder-purple-300::placeholder { + color: #d6bcfa; + } + + .sm\:placeholder-purple-400::placeholder { + color: #b794f4; + } + + .sm\:placeholder-purple-500::placeholder { + color: #9f7aea; + } + + .sm\:placeholder-purple-600::placeholder { + color: #805ad5; + } + + .sm\:placeholder-purple-700::placeholder { + color: #6b46c1; + } + + .sm\:placeholder-purple-800::placeholder { + color: #553c9a; + } + + .sm\:placeholder-purple-900::placeholder { + color: #44337a; + } + + .sm\:placeholder-pink-100::placeholder { + color: #fff5f7; + } + + .sm\:placeholder-pink-200::placeholder { + color: #fed7e2; + } + + .sm\:placeholder-pink-300::placeholder { + color: #fbb6ce; + } + + .sm\:placeholder-pink-400::placeholder { + color: #f687b3; + } + + .sm\:placeholder-pink-500::placeholder { + color: #ed64a6; + } + + .sm\:placeholder-pink-600::placeholder { + color: #d53f8c; + } + + .sm\:placeholder-pink-700::placeholder { + color: #b83280; + } + + .sm\:placeholder-pink-800::placeholder { + color: #97266d; + } + + .sm\:placeholder-pink-900::placeholder { + color: #702459; + } + + .sm\:focus\:placeholder-transparent:focus::placeholder { + color: transparent; + } + + .sm\:focus\:placeholder-black:focus::placeholder { + color: #000; + } + + .sm\:focus\:placeholder-white:focus::placeholder { + color: #fff; + } + + .sm\:focus\:placeholder-gray-100:focus::placeholder { + color: #f7fafc; + } + + .sm\:focus\:placeholder-gray-200:focus::placeholder { + color: #edf2f7; + } + + .sm\:focus\:placeholder-gray-300:focus::placeholder { + color: #e2e8f0; + } + + .sm\:focus\:placeholder-gray-400:focus::placeholder { + color: #cbd5e0; + } + + .sm\:focus\:placeholder-gray-500:focus::placeholder { + color: #a0aec0; + } + + .sm\:focus\:placeholder-gray-600:focus::placeholder { + color: #718096; + } + + .sm\:focus\:placeholder-gray-700:focus::placeholder { + color: #4a5568; + } + + .sm\:focus\:placeholder-gray-800:focus::placeholder { + color: #2d3748; + } + + .sm\:focus\:placeholder-gray-900:focus::placeholder { + color: #1a202c; + } + + .sm\:focus\:placeholder-red-100:focus::placeholder { + color: #fff5f5; + } + + .sm\:focus\:placeholder-red-200:focus::placeholder { + color: #fed7d7; + } + + .sm\:focus\:placeholder-red-300:focus::placeholder { + color: #feb2b2; + } + + .sm\:focus\:placeholder-red-400:focus::placeholder { + color: #fc8181; + } + + .sm\:focus\:placeholder-red-500:focus::placeholder { + color: #f56565; + } + + .sm\:focus\:placeholder-red-600:focus::placeholder { + color: #e53e3e; + } + + .sm\:focus\:placeholder-red-700:focus::placeholder { + color: #c53030; + } + + .sm\:focus\:placeholder-red-800:focus::placeholder { + color: #9b2c2c; + } + + .sm\:focus\:placeholder-red-900:focus::placeholder { + color: #742a2a; + } + + .sm\:focus\:placeholder-orange-100:focus::placeholder { + color: #fffaf0; + } + + .sm\:focus\:placeholder-orange-200:focus::placeholder { + color: #feebc8; + } + + .sm\:focus\:placeholder-orange-300:focus::placeholder { + color: #fbd38d; + } + + .sm\:focus\:placeholder-orange-400:focus::placeholder { + color: #f6ad55; + } + + .sm\:focus\:placeholder-orange-500:focus::placeholder { + color: #ed8936; + } + + .sm\:focus\:placeholder-orange-600:focus::placeholder { + color: #dd6b20; + } + + .sm\:focus\:placeholder-orange-700:focus::placeholder { + color: #c05621; + } + + .sm\:focus\:placeholder-orange-800:focus::placeholder { + color: #9c4221; + } + + .sm\:focus\:placeholder-orange-900:focus::placeholder { + color: #7b341e; + } + + .sm\:focus\:placeholder-yellow-100:focus::placeholder { + color: #fffff0; + } + + .sm\:focus\:placeholder-yellow-200:focus::placeholder { + color: #fefcbf; + } + + .sm\:focus\:placeholder-yellow-300:focus::placeholder { + color: #faf089; + } + + .sm\:focus\:placeholder-yellow-400:focus::placeholder { + color: #f6e05e; + } + + .sm\:focus\:placeholder-yellow-500:focus::placeholder { + color: #ecc94b; + } + + .sm\:focus\:placeholder-yellow-600:focus::placeholder { + color: #d69e2e; + } + + .sm\:focus\:placeholder-yellow-700:focus::placeholder { + color: #b7791f; + } + + .sm\:focus\:placeholder-yellow-800:focus::placeholder { + color: #975a16; + } + + .sm\:focus\:placeholder-yellow-900:focus::placeholder { + color: #744210; + } + + .sm\:focus\:placeholder-green-100:focus::placeholder { + color: #f0fff4; + } + + .sm\:focus\:placeholder-green-200:focus::placeholder { + color: #c6f6d5; + } + + .sm\:focus\:placeholder-green-300:focus::placeholder { + color: #9ae6b4; + } + + .sm\:focus\:placeholder-green-400:focus::placeholder { + color: #68d391; + } + + .sm\:focus\:placeholder-green-500:focus::placeholder { + color: #48bb78; + } + + .sm\:focus\:placeholder-green-600:focus::placeholder { + color: #38a169; + } + + .sm\:focus\:placeholder-green-700:focus::placeholder { + color: #2f855a; + } + + .sm\:focus\:placeholder-green-800:focus::placeholder { + color: #276749; + } + + .sm\:focus\:placeholder-green-900:focus::placeholder { + color: #22543d; + } + + .sm\:focus\:placeholder-teal-100:focus::placeholder { + color: #e6fffa; + } + + .sm\:focus\:placeholder-teal-200:focus::placeholder { + color: #b2f5ea; + } + + .sm\:focus\:placeholder-teal-300:focus::placeholder { + color: #81e6d9; + } + + .sm\:focus\:placeholder-teal-400:focus::placeholder { + color: #4fd1c5; + } + + .sm\:focus\:placeholder-teal-500:focus::placeholder { + color: #38b2ac; + } + + .sm\:focus\:placeholder-teal-600:focus::placeholder { + color: #319795; + } + + .sm\:focus\:placeholder-teal-700:focus::placeholder { + color: #2c7a7b; + } + + .sm\:focus\:placeholder-teal-800:focus::placeholder { + color: #285e61; + } + + .sm\:focus\:placeholder-teal-900:focus::placeholder { + color: #234e52; + } + + .sm\:focus\:placeholder-blue-100:focus::placeholder { + color: #ebf8ff; + } + + .sm\:focus\:placeholder-blue-200:focus::placeholder { + color: #bee3f8; + } + + .sm\:focus\:placeholder-blue-300:focus::placeholder { + color: #90cdf4; + } + + .sm\:focus\:placeholder-blue-400:focus::placeholder { + color: #63b3ed; + } + + .sm\:focus\:placeholder-blue-500:focus::placeholder { + color: #4299e1; + } + + .sm\:focus\:placeholder-blue-600:focus::placeholder { + color: #3182ce; + } + + .sm\:focus\:placeholder-blue-700:focus::placeholder { + color: #2b6cb0; + } + + .sm\:focus\:placeholder-blue-800:focus::placeholder { + color: #2c5282; + } + + .sm\:focus\:placeholder-blue-900:focus::placeholder { + color: #2a4365; + } + + .sm\:focus\:placeholder-indigo-100:focus::placeholder { + color: #ebf4ff; + } + + .sm\:focus\:placeholder-indigo-200:focus::placeholder { + color: #c3dafe; + } + + .sm\:focus\:placeholder-indigo-300:focus::placeholder { + color: #a3bffa; + } + + .sm\:focus\:placeholder-indigo-400:focus::placeholder { + color: #7f9cf5; + } + + .sm\:focus\:placeholder-indigo-500:focus::placeholder { + color: #667eea; + } + + .sm\:focus\:placeholder-indigo-600:focus::placeholder { + color: #5a67d8; + } + + .sm\:focus\:placeholder-indigo-700:focus::placeholder { + color: #4c51bf; + } + + .sm\:focus\:placeholder-indigo-800:focus::placeholder { + color: #434190; + } + + .sm\:focus\:placeholder-indigo-900:focus::placeholder { + color: #3c366b; + } + + .sm\:focus\:placeholder-purple-100:focus::placeholder { + color: #faf5ff; + } + + .sm\:focus\:placeholder-purple-200:focus::placeholder { + color: #e9d8fd; + } + + .sm\:focus\:placeholder-purple-300:focus::placeholder { + color: #d6bcfa; + } + + .sm\:focus\:placeholder-purple-400:focus::placeholder { + color: #b794f4; + } + + .sm\:focus\:placeholder-purple-500:focus::placeholder { + color: #9f7aea; + } + + .sm\:focus\:placeholder-purple-600:focus::placeholder { + color: #805ad5; + } + + .sm\:focus\:placeholder-purple-700:focus::placeholder { + color: #6b46c1; + } + + .sm\:focus\:placeholder-purple-800:focus::placeholder { + color: #553c9a; + } + + .sm\:focus\:placeholder-purple-900:focus::placeholder { + color: #44337a; + } + + .sm\:focus\:placeholder-pink-100:focus::placeholder { + color: #fff5f7; + } + + .sm\:focus\:placeholder-pink-200:focus::placeholder { + color: #fed7e2; + } + + .sm\:focus\:placeholder-pink-300:focus::placeholder { + color: #fbb6ce; + } + + .sm\:focus\:placeholder-pink-400:focus::placeholder { + color: #f687b3; + } + + .sm\:focus\:placeholder-pink-500:focus::placeholder { + color: #ed64a6; + } + + .sm\:focus\:placeholder-pink-600:focus::placeholder { + color: #d53f8c; + } + + .sm\:focus\:placeholder-pink-700:focus::placeholder { + color: #b83280; + } + + .sm\:focus\:placeholder-pink-800:focus::placeholder { + color: #97266d; + } + + .sm\:focus\:placeholder-pink-900:focus::placeholder { + color: #702459; + } + + .sm\:pointer-events-none { + pointer-events: none; + } + + .sm\:pointer-events-auto { + pointer-events: auto; + } + + .sm\:static { + position: static; + } + + .sm\:fixed { + position: fixed; + } + + .sm\:absolute { + position: absolute; + } + + .sm\:relative { + position: relative; + } + + .sm\:sticky { + position: -webkit-sticky; + position: sticky; + } + + .sm\:inset-0 { + top: 0; + right: 0; + bottom: 0; + left: 0; + } + + .sm\:inset-auto { + top: auto; + right: auto; + bottom: auto; + left: auto; + } + + .sm\:inset-y-0 { + top: 0; + bottom: 0; + } + + .sm\:inset-x-0 { + right: 0; + left: 0; + } + + .sm\:inset-y-auto { + top: auto; + bottom: auto; + } + + .sm\:inset-x-auto { + right: auto; + left: auto; + } + + .sm\:top-0 { + top: 0; + } + + .sm\:right-0 { + right: 0; + } + + .sm\:bottom-0 { + bottom: 0; + } + + .sm\:left-0 { + left: 0; + } + + .sm\:top-auto { + top: auto; + } + + .sm\:right-auto { + right: auto; + } + + .sm\:bottom-auto { + bottom: auto; + } + + .sm\:left-auto { + left: auto; + } + + .sm\:resize-none { + resize: none; + } + + .sm\:resize-y { + resize: vertical; + } + + .sm\:resize-x { + resize: horizontal; + } + + .sm\:resize { + resize: both; + } + + .sm\:shadow-xs { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); + } + + .sm\:shadow-sm { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + } + + .sm\:shadow { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + } + + .sm\:shadow-md { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + } + + .sm\:shadow-lg { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + } + + .sm\:shadow-xl { + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + } + + .sm\:shadow-2xl { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + } + + .sm\:shadow-inner { + box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); + } + + .sm\:shadow-outline { + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); + } + + .sm\:shadow-none { + box-shadow: none; + } + + .sm\:hover\:shadow-xs:hover { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); + } + + .sm\:hover\:shadow-sm:hover { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + } + + .sm\:hover\:shadow:hover { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + } + + .sm\:hover\:shadow-md:hover { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + } + + .sm\:hover\:shadow-lg:hover { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + } + + .sm\:hover\:shadow-xl:hover { + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + } + + .sm\:hover\:shadow-2xl:hover { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + } + + .sm\:hover\:shadow-inner:hover { + box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); + } + + .sm\:hover\:shadow-outline:hover { + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); + } + + .sm\:hover\:shadow-none:hover { + box-shadow: none; + } + + .sm\:focus\:shadow-xs:focus { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); + } + + .sm\:focus\:shadow-sm:focus { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + } + + .sm\:focus\:shadow:focus { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + } + + .sm\:focus\:shadow-md:focus { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + } + + .sm\:focus\:shadow-lg:focus { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + } + + .sm\:focus\:shadow-xl:focus { + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + } + + .sm\:focus\:shadow-2xl:focus { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + } + + .sm\:focus\:shadow-inner:focus { + box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); + } + + .sm\:focus\:shadow-outline:focus { + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); + } + + .sm\:focus\:shadow-none:focus { + box-shadow: none; + } + + .sm\:fill-current { + fill: currentColor; + } + + .sm\:stroke-current { + stroke: currentColor; + } + + .sm\:stroke-0 { + stroke-width: 0; + } + + .sm\:stroke-1 { + stroke-width: 1; + } + + .sm\:stroke-2 { + stroke-width: 2; + } + + .sm\:table-auto { + table-layout: auto; + } + + .sm\:table-fixed { + table-layout: fixed; + } + + .sm\:text-left { + text-align: left; + } + + .sm\:text-center { + text-align: center; + } + + .sm\:text-right { + text-align: right; + } + + .sm\:text-justify { + text-align: justify; + } + + .sm\:text-transparent { + color: transparent; + } + + .sm\:text-black { + color: #000; + } + + .sm\:text-white { + color: #fff; + } + + .sm\:text-gray-100 { + color: #f7fafc; + } + + .sm\:text-gray-200 { + color: #edf2f7; + } + + .sm\:text-gray-300 { + color: #e2e8f0; + } + + .sm\:text-gray-400 { + color: #cbd5e0; + } + + .sm\:text-gray-500 { + color: #a0aec0; + } + + .sm\:text-gray-600 { + color: #718096; + } + + .sm\:text-gray-700 { + color: #4a5568; + } + + .sm\:text-gray-800 { + color: #2d3748; + } + + .sm\:text-gray-900 { + color: #1a202c; + } + + .sm\:text-red-100 { + color: #fff5f5; + } + + .sm\:text-red-200 { + color: #fed7d7; + } + + .sm\:text-red-300 { + color: #feb2b2; + } + + .sm\:text-red-400 { + color: #fc8181; + } + + .sm\:text-red-500 { + color: #f56565; + } + + .sm\:text-red-600 { + color: #e53e3e; + } + + .sm\:text-red-700 { + color: #c53030; + } + + .sm\:text-red-800 { + color: #9b2c2c; + } + + .sm\:text-red-900 { + color: #742a2a; + } + + .sm\:text-orange-100 { + color: #fffaf0; + } + + .sm\:text-orange-200 { + color: #feebc8; + } + + .sm\:text-orange-300 { + color: #fbd38d; + } + + .sm\:text-orange-400 { + color: #f6ad55; + } + + .sm\:text-orange-500 { + color: #ed8936; + } + + .sm\:text-orange-600 { + color: #dd6b20; + } + + .sm\:text-orange-700 { + color: #c05621; + } + + .sm\:text-orange-800 { + color: #9c4221; + } + + .sm\:text-orange-900 { + color: #7b341e; + } + + .sm\:text-yellow-100 { + color: #fffff0; + } + + .sm\:text-yellow-200 { + color: #fefcbf; + } + + .sm\:text-yellow-300 { + color: #faf089; + } + + .sm\:text-yellow-400 { + color: #f6e05e; + } + + .sm\:text-yellow-500 { + color: #ecc94b; + } + + .sm\:text-yellow-600 { + color: #d69e2e; + } + + .sm\:text-yellow-700 { + color: #b7791f; + } + + .sm\:text-yellow-800 { + color: #975a16; + } + + .sm\:text-yellow-900 { + color: #744210; + } + + .sm\:text-green-100 { + color: #f0fff4; + } + + .sm\:text-green-200 { + color: #c6f6d5; + } + + .sm\:text-green-300 { + color: #9ae6b4; + } + + .sm\:text-green-400 { + color: #68d391; + } + + .sm\:text-green-500 { + color: #48bb78; + } + + .sm\:text-green-600 { + color: #38a169; + } + + .sm\:text-green-700 { + color: #2f855a; + } + + .sm\:text-green-800 { + color: #276749; + } + + .sm\:text-green-900 { + color: #22543d; + } + + .sm\:text-teal-100 { + color: #e6fffa; + } + + .sm\:text-teal-200 { + color: #b2f5ea; + } + + .sm\:text-teal-300 { + color: #81e6d9; + } + + .sm\:text-teal-400 { + color: #4fd1c5; + } + + .sm\:text-teal-500 { + color: #38b2ac; + } + + .sm\:text-teal-600 { + color: #319795; + } + + .sm\:text-teal-700 { + color: #2c7a7b; + } + + .sm\:text-teal-800 { + color: #285e61; + } + + .sm\:text-teal-900 { + color: #234e52; + } + + .sm\:text-blue-100 { + color: #ebf8ff; + } + + .sm\:text-blue-200 { + color: #bee3f8; + } + + .sm\:text-blue-300 { + color: #90cdf4; + } + + .sm\:text-blue-400 { + color: #63b3ed; + } + + .sm\:text-blue-500 { + color: #4299e1; + } + + .sm\:text-blue-600 { + color: #3182ce; + } + + .sm\:text-blue-700 { + color: #2b6cb0; + } + + .sm\:text-blue-800 { + color: #2c5282; + } + + .sm\:text-blue-900 { + color: #2a4365; + } + + .sm\:text-indigo-100 { + color: #ebf4ff; + } + + .sm\:text-indigo-200 { + color: #c3dafe; + } + + .sm\:text-indigo-300 { + color: #a3bffa; + } + + .sm\:text-indigo-400 { + color: #7f9cf5; + } + + .sm\:text-indigo-500 { + color: #667eea; + } + + .sm\:text-indigo-600 { + color: #5a67d8; + } + + .sm\:text-indigo-700 { + color: #4c51bf; + } + + .sm\:text-indigo-800 { + color: #434190; + } + + .sm\:text-indigo-900 { + color: #3c366b; + } + + .sm\:text-purple-100 { + color: #faf5ff; + } + + .sm\:text-purple-200 { + color: #e9d8fd; + } + + .sm\:text-purple-300 { + color: #d6bcfa; + } + + .sm\:text-purple-400 { + color: #b794f4; + } + + .sm\:text-purple-500 { + color: #9f7aea; + } + + .sm\:text-purple-600 { + color: #805ad5; + } + + .sm\:text-purple-700 { + color: #6b46c1; + } + + .sm\:text-purple-800 { + color: #553c9a; + } + + .sm\:text-purple-900 { + color: #44337a; + } + + .sm\:text-pink-100 { + color: #fff5f7; + } + + .sm\:text-pink-200 { + color: #fed7e2; + } + + .sm\:text-pink-300 { + color: #fbb6ce; + } + + .sm\:text-pink-400 { + color: #f687b3; + } + + .sm\:text-pink-500 { + color: #ed64a6; + } + + .sm\:text-pink-600 { + color: #d53f8c; + } + + .sm\:text-pink-700 { + color: #b83280; + } + + .sm\:text-pink-800 { + color: #97266d; + } + + .sm\:text-pink-900 { + color: #702459; + } + + .sm\:hover\:text-transparent:hover { + color: transparent; + } + + .sm\:hover\:text-black:hover { + color: #000; + } + + .sm\:hover\:text-white:hover { + color: #fff; + } + + .sm\:hover\:text-gray-100:hover { + color: #f7fafc; + } + + .sm\:hover\:text-gray-200:hover { + color: #edf2f7; + } + + .sm\:hover\:text-gray-300:hover { + color: #e2e8f0; + } + + .sm\:hover\:text-gray-400:hover { + color: #cbd5e0; + } + + .sm\:hover\:text-gray-500:hover { + color: #a0aec0; + } + + .sm\:hover\:text-gray-600:hover { + color: #718096; + } + + .sm\:hover\:text-gray-700:hover { + color: #4a5568; + } + + .sm\:hover\:text-gray-800:hover { + color: #2d3748; + } + + .sm\:hover\:text-gray-900:hover { + color: #1a202c; + } + + .sm\:hover\:text-red-100:hover { + color: #fff5f5; + } + + .sm\:hover\:text-red-200:hover { + color: #fed7d7; + } + + .sm\:hover\:text-red-300:hover { + color: #feb2b2; + } + + .sm\:hover\:text-red-400:hover { + color: #fc8181; + } + + .sm\:hover\:text-red-500:hover { + color: #f56565; + } + + .sm\:hover\:text-red-600:hover { + color: #e53e3e; + } + + .sm\:hover\:text-red-700:hover { + color: #c53030; + } + + .sm\:hover\:text-red-800:hover { + color: #9b2c2c; + } + + .sm\:hover\:text-red-900:hover { + color: #742a2a; + } + + .sm\:hover\:text-orange-100:hover { + color: #fffaf0; + } + + .sm\:hover\:text-orange-200:hover { + color: #feebc8; + } + + .sm\:hover\:text-orange-300:hover { + color: #fbd38d; + } + + .sm\:hover\:text-orange-400:hover { + color: #f6ad55; + } + + .sm\:hover\:text-orange-500:hover { + color: #ed8936; + } + + .sm\:hover\:text-orange-600:hover { + color: #dd6b20; + } + + .sm\:hover\:text-orange-700:hover { + color: #c05621; + } + + .sm\:hover\:text-orange-800:hover { + color: #9c4221; + } + + .sm\:hover\:text-orange-900:hover { + color: #7b341e; + } + + .sm\:hover\:text-yellow-100:hover { + color: #fffff0; + } + + .sm\:hover\:text-yellow-200:hover { + color: #fefcbf; + } + + .sm\:hover\:text-yellow-300:hover { + color: #faf089; + } + + .sm\:hover\:text-yellow-400:hover { + color: #f6e05e; + } + + .sm\:hover\:text-yellow-500:hover { + color: #ecc94b; + } + + .sm\:hover\:text-yellow-600:hover { + color: #d69e2e; + } + + .sm\:hover\:text-yellow-700:hover { + color: #b7791f; + } + + .sm\:hover\:text-yellow-800:hover { + color: #975a16; + } + + .sm\:hover\:text-yellow-900:hover { + color: #744210; + } + + .sm\:hover\:text-green-100:hover { + color: #f0fff4; + } + + .sm\:hover\:text-green-200:hover { + color: #c6f6d5; + } + + .sm\:hover\:text-green-300:hover { + color: #9ae6b4; + } + + .sm\:hover\:text-green-400:hover { + color: #68d391; + } + + .sm\:hover\:text-green-500:hover { + color: #48bb78; + } + + .sm\:hover\:text-green-600:hover { + color: #38a169; + } + + .sm\:hover\:text-green-700:hover { + color: #2f855a; + } + + .sm\:hover\:text-green-800:hover { + color: #276749; + } + + .sm\:hover\:text-green-900:hover { + color: #22543d; + } + + .sm\:hover\:text-teal-100:hover { + color: #e6fffa; + } + + .sm\:hover\:text-teal-200:hover { + color: #b2f5ea; + } + + .sm\:hover\:text-teal-300:hover { + color: #81e6d9; + } + + .sm\:hover\:text-teal-400:hover { + color: #4fd1c5; + } + + .sm\:hover\:text-teal-500:hover { + color: #38b2ac; + } + + .sm\:hover\:text-teal-600:hover { + color: #319795; + } + + .sm\:hover\:text-teal-700:hover { + color: #2c7a7b; + } + + .sm\:hover\:text-teal-800:hover { + color: #285e61; + } + + .sm\:hover\:text-teal-900:hover { + color: #234e52; + } + + .sm\:hover\:text-blue-100:hover { + color: #ebf8ff; + } + + .sm\:hover\:text-blue-200:hover { + color: #bee3f8; + } + + .sm\:hover\:text-blue-300:hover { + color: #90cdf4; + } + + .sm\:hover\:text-blue-400:hover { + color: #63b3ed; + } + + .sm\:hover\:text-blue-500:hover { + color: #4299e1; + } + + .sm\:hover\:text-blue-600:hover { + color: #3182ce; + } + + .sm\:hover\:text-blue-700:hover { + color: #2b6cb0; + } + + .sm\:hover\:text-blue-800:hover { + color: #2c5282; + } + + .sm\:hover\:text-blue-900:hover { + color: #2a4365; + } + + .sm\:hover\:text-indigo-100:hover { + color: #ebf4ff; + } + + .sm\:hover\:text-indigo-200:hover { + color: #c3dafe; + } + + .sm\:hover\:text-indigo-300:hover { + color: #a3bffa; + } + + .sm\:hover\:text-indigo-400:hover { + color: #7f9cf5; + } + + .sm\:hover\:text-indigo-500:hover { + color: #667eea; + } + + .sm\:hover\:text-indigo-600:hover { + color: #5a67d8; + } + + .sm\:hover\:text-indigo-700:hover { + color: #4c51bf; + } + + .sm\:hover\:text-indigo-800:hover { + color: #434190; + } + + .sm\:hover\:text-indigo-900:hover { + color: #3c366b; + } + + .sm\:hover\:text-purple-100:hover { + color: #faf5ff; + } + + .sm\:hover\:text-purple-200:hover { + color: #e9d8fd; + } + + .sm\:hover\:text-purple-300:hover { + color: #d6bcfa; + } + + .sm\:hover\:text-purple-400:hover { + color: #b794f4; + } + + .sm\:hover\:text-purple-500:hover { + color: #9f7aea; + } + + .sm\:hover\:text-purple-600:hover { + color: #805ad5; + } + + .sm\:hover\:text-purple-700:hover { + color: #6b46c1; + } + + .sm\:hover\:text-purple-800:hover { + color: #553c9a; + } + + .sm\:hover\:text-purple-900:hover { + color: #44337a; + } + + .sm\:hover\:text-pink-100:hover { + color: #fff5f7; + } + + .sm\:hover\:text-pink-200:hover { + color: #fed7e2; + } + + .sm\:hover\:text-pink-300:hover { + color: #fbb6ce; + } + + .sm\:hover\:text-pink-400:hover { + color: #f687b3; + } + + .sm\:hover\:text-pink-500:hover { + color: #ed64a6; + } + + .sm\:hover\:text-pink-600:hover { + color: #d53f8c; + } + + .sm\:hover\:text-pink-700:hover { + color: #b83280; + } + + .sm\:hover\:text-pink-800:hover { + color: #97266d; + } + + .sm\:hover\:text-pink-900:hover { + color: #702459; + } + + .sm\:focus\:text-transparent:focus { + color: transparent; + } + + .sm\:focus\:text-black:focus { + color: #000; + } + + .sm\:focus\:text-white:focus { + color: #fff; + } + + .sm\:focus\:text-gray-100:focus { + color: #f7fafc; + } + + .sm\:focus\:text-gray-200:focus { + color: #edf2f7; + } + + .sm\:focus\:text-gray-300:focus { + color: #e2e8f0; + } + + .sm\:focus\:text-gray-400:focus { + color: #cbd5e0; + } + + .sm\:focus\:text-gray-500:focus { + color: #a0aec0; + } + + .sm\:focus\:text-gray-600:focus { + color: #718096; + } + + .sm\:focus\:text-gray-700:focus { + color: #4a5568; + } + + .sm\:focus\:text-gray-800:focus { + color: #2d3748; + } + + .sm\:focus\:text-gray-900:focus { + color: #1a202c; + } + + .sm\:focus\:text-red-100:focus { + color: #fff5f5; + } + + .sm\:focus\:text-red-200:focus { + color: #fed7d7; + } + + .sm\:focus\:text-red-300:focus { + color: #feb2b2; + } + + .sm\:focus\:text-red-400:focus { + color: #fc8181; + } + + .sm\:focus\:text-red-500:focus { + color: #f56565; + } + + .sm\:focus\:text-red-600:focus { + color: #e53e3e; + } + + .sm\:focus\:text-red-700:focus { + color: #c53030; + } + + .sm\:focus\:text-red-800:focus { + color: #9b2c2c; + } + + .sm\:focus\:text-red-900:focus { + color: #742a2a; + } + + .sm\:focus\:text-orange-100:focus { + color: #fffaf0; + } + + .sm\:focus\:text-orange-200:focus { + color: #feebc8; + } + + .sm\:focus\:text-orange-300:focus { + color: #fbd38d; + } + + .sm\:focus\:text-orange-400:focus { + color: #f6ad55; + } + + .sm\:focus\:text-orange-500:focus { + color: #ed8936; + } + + .sm\:focus\:text-orange-600:focus { + color: #dd6b20; + } + + .sm\:focus\:text-orange-700:focus { + color: #c05621; + } + + .sm\:focus\:text-orange-800:focus { + color: #9c4221; + } + + .sm\:focus\:text-orange-900:focus { + color: #7b341e; + } + + .sm\:focus\:text-yellow-100:focus { + color: #fffff0; + } + + .sm\:focus\:text-yellow-200:focus { + color: #fefcbf; + } + + .sm\:focus\:text-yellow-300:focus { + color: #faf089; + } + + .sm\:focus\:text-yellow-400:focus { + color: #f6e05e; + } + + .sm\:focus\:text-yellow-500:focus { + color: #ecc94b; + } + + .sm\:focus\:text-yellow-600:focus { + color: #d69e2e; + } + + .sm\:focus\:text-yellow-700:focus { + color: #b7791f; + } + + .sm\:focus\:text-yellow-800:focus { + color: #975a16; + } + + .sm\:focus\:text-yellow-900:focus { + color: #744210; + } + + .sm\:focus\:text-green-100:focus { + color: #f0fff4; + } + + .sm\:focus\:text-green-200:focus { + color: #c6f6d5; + } + + .sm\:focus\:text-green-300:focus { + color: #9ae6b4; + } + + .sm\:focus\:text-green-400:focus { + color: #68d391; + } + + .sm\:focus\:text-green-500:focus { + color: #48bb78; + } + + .sm\:focus\:text-green-600:focus { + color: #38a169; + } + + .sm\:focus\:text-green-700:focus { + color: #2f855a; + } + + .sm\:focus\:text-green-800:focus { + color: #276749; + } + + .sm\:focus\:text-green-900:focus { + color: #22543d; + } + + .sm\:focus\:text-teal-100:focus { + color: #e6fffa; + } + + .sm\:focus\:text-teal-200:focus { + color: #b2f5ea; + } + + .sm\:focus\:text-teal-300:focus { + color: #81e6d9; + } + + .sm\:focus\:text-teal-400:focus { + color: #4fd1c5; + } + + .sm\:focus\:text-teal-500:focus { + color: #38b2ac; + } + + .sm\:focus\:text-teal-600:focus { + color: #319795; + } + + .sm\:focus\:text-teal-700:focus { + color: #2c7a7b; + } + + .sm\:focus\:text-teal-800:focus { + color: #285e61; + } + + .sm\:focus\:text-teal-900:focus { + color: #234e52; + } + + .sm\:focus\:text-blue-100:focus { + color: #ebf8ff; + } + + .sm\:focus\:text-blue-200:focus { + color: #bee3f8; + } + + .sm\:focus\:text-blue-300:focus { + color: #90cdf4; + } + + .sm\:focus\:text-blue-400:focus { + color: #63b3ed; + } + + .sm\:focus\:text-blue-500:focus { + color: #4299e1; + } + + .sm\:focus\:text-blue-600:focus { + color: #3182ce; + } + + .sm\:focus\:text-blue-700:focus { + color: #2b6cb0; + } + + .sm\:focus\:text-blue-800:focus { + color: #2c5282; + } + + .sm\:focus\:text-blue-900:focus { + color: #2a4365; + } + + .sm\:focus\:text-indigo-100:focus { + color: #ebf4ff; + } + + .sm\:focus\:text-indigo-200:focus { + color: #c3dafe; + } + + .sm\:focus\:text-indigo-300:focus { + color: #a3bffa; + } + + .sm\:focus\:text-indigo-400:focus { + color: #7f9cf5; + } + + .sm\:focus\:text-indigo-500:focus { + color: #667eea; + } + + .sm\:focus\:text-indigo-600:focus { + color: #5a67d8; + } + + .sm\:focus\:text-indigo-700:focus { + color: #4c51bf; + } + + .sm\:focus\:text-indigo-800:focus { + color: #434190; + } + + .sm\:focus\:text-indigo-900:focus { + color: #3c366b; + } + + .sm\:focus\:text-purple-100:focus { + color: #faf5ff; + } + + .sm\:focus\:text-purple-200:focus { + color: #e9d8fd; + } + + .sm\:focus\:text-purple-300:focus { + color: #d6bcfa; + } + + .sm\:focus\:text-purple-400:focus { + color: #b794f4; + } + + .sm\:focus\:text-purple-500:focus { + color: #9f7aea; + } + + .sm\:focus\:text-purple-600:focus { + color: #805ad5; + } + + .sm\:focus\:text-purple-700:focus { + color: #6b46c1; + } + + .sm\:focus\:text-purple-800:focus { + color: #553c9a; + } + + .sm\:focus\:text-purple-900:focus { + color: #44337a; + } + + .sm\:focus\:text-pink-100:focus { + color: #fff5f7; + } + + .sm\:focus\:text-pink-200:focus { + color: #fed7e2; + } + + .sm\:focus\:text-pink-300:focus { + color: #fbb6ce; + } + + .sm\:focus\:text-pink-400:focus { + color: #f687b3; + } + + .sm\:focus\:text-pink-500:focus { + color: #ed64a6; + } + + .sm\:focus\:text-pink-600:focus { + color: #d53f8c; + } + + .sm\:focus\:text-pink-700:focus { + color: #b83280; + } + + .sm\:focus\:text-pink-800:focus { + color: #97266d; + } + + .sm\:focus\:text-pink-900:focus { + color: #702459; + } + + .sm\:text-xs { + font-size: 0.75rem; + } + + .sm\:text-sm { + font-size: 0.875rem; + } + + .sm\:text-base { + font-size: 1rem; + } + + .sm\:text-lg { + font-size: 1.125rem; + } + + .sm\:text-xl { + font-size: 1.25rem; + } + + .sm\:text-2xl { + font-size: 1.5rem; + } + + .sm\:text-3xl { + font-size: 1.875rem; + } + + .sm\:text-4xl { + font-size: 2.25rem; + } + + .sm\:text-5xl { + font-size: 3rem; + } + + .sm\:text-6xl { + font-size: 4rem; + } + + .sm\:italic { + font-style: italic; + } + + .sm\:not-italic { + font-style: normal; + } + + .sm\:uppercase { + text-transform: uppercase; + } + + .sm\:lowercase { + text-transform: lowercase; + } + + .sm\:capitalize { + text-transform: capitalize; + } + + .sm\:normal-case { + text-transform: none; + } + + .sm\:underline { + text-decoration: underline; + } + + .sm\:line-through { + text-decoration: line-through; + } + + .sm\:no-underline { + text-decoration: none; + } + + .sm\:hover\:underline:hover { + text-decoration: underline; + } + + .sm\:hover\:line-through:hover { + text-decoration: line-through; + } + + .sm\:hover\:no-underline:hover { + text-decoration: none; + } + + .sm\:focus\:underline:focus { + text-decoration: underline; + } + + .sm\:focus\:line-through:focus { + text-decoration: line-through; + } + + .sm\:focus\:no-underline:focus { + text-decoration: none; + } + + .sm\:antialiased { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + + .sm\:subpixel-antialiased { + -webkit-font-smoothing: auto; + -moz-osx-font-smoothing: auto; + } + + .sm\:tracking-tighter { + letter-spacing: -0.05em; + } + + .sm\:tracking-tight { + letter-spacing: -0.025em; + } + + .sm\:tracking-normal { + letter-spacing: 0; + } + + .sm\:tracking-wide { + letter-spacing: 0.025em; + } + + .sm\:tracking-wider { + letter-spacing: 0.05em; + } + + .sm\:tracking-widest { + letter-spacing: 0.1em; + } + + .sm\:select-none { + -webkit-user-select: none; + user-select: none; + } + + .sm\:select-text { + -webkit-user-select: text; + user-select: text; + } + + .sm\:select-all { + -webkit-user-select: all; + user-select: all; + } + + .sm\:select-auto { + -webkit-user-select: auto; + user-select: auto; + } + + .sm\:align-baseline { + vertical-align: baseline; + } + + .sm\:align-top { + vertical-align: top; + } + + .sm\:align-middle { + vertical-align: middle; + } + + .sm\:align-bottom { + vertical-align: bottom; + } + + .sm\:align-text-top { + vertical-align: text-top; + } + + .sm\:align-text-bottom { + vertical-align: text-bottom; + } + + .sm\:visible { + visibility: visible; + } + + .sm\:invisible { + visibility: hidden; + } + + .sm\:whitespace-normal { + white-space: normal; + } + + .sm\:whitespace-no-wrap { + white-space: nowrap; + } + + .sm\:whitespace-pre { + white-space: pre; + } + + .sm\:whitespace-pre-line { + white-space: pre-line; + } + + .sm\:whitespace-pre-wrap { + white-space: pre-wrap; + } + + .sm\:break-normal { + overflow-wrap: normal; + word-break: normal; + } + + .sm\:break-words { + overflow-wrap: break-word; + } + + .sm\:break-all { + word-break: break-all; + } + + .sm\:truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .sm\:w-0 { + width: 0; + } + + .sm\:w-1 { + width: 0.25rem; + } + + .sm\:w-2 { + width: 0.5rem; + } + + .sm\:w-3 { + width: 0.75rem; + } + + .sm\:w-4 { + width: 1rem; + } + + .sm\:w-5 { + width: 1.25rem; + } + + .sm\:w-6 { + width: 1.5rem; + } + + .sm\:w-8 { + width: 2rem; + } + + .sm\:w-10 { + width: 2.5rem; + } + + .sm\:w-12 { + width: 3rem; + } + + .sm\:w-16 { + width: 4rem; + } + + .sm\:w-20 { + width: 5rem; + } + + .sm\:w-24 { + width: 6rem; + } + + .sm\:w-32 { + width: 8rem; + } + + .sm\:w-40 { + width: 10rem; + } + + .sm\:w-48 { + width: 12rem; + } + + .sm\:w-56 { + width: 14rem; + } + + .sm\:w-64 { + width: 16rem; + } + + .sm\:w-auto { + width: auto; + } + + .sm\:w-px { + width: 1px; + } + + .sm\:w-1\/2 { + width: 50%; + } + + .sm\:w-1\/3 { + width: 33.333333%; + } + + .sm\:w-2\/3 { + width: 66.666667%; + } + + .sm\:w-1\/4 { + width: 25%; + } + + .sm\:w-2\/4 { + width: 50%; + } + + .sm\:w-3\/4 { + width: 75%; + } + + .sm\:w-1\/5 { + width: 20%; + } + + .sm\:w-2\/5 { + width: 40%; + } + + .sm\:w-3\/5 { + width: 60%; + } + + .sm\:w-4\/5 { + width: 80%; + } + + .sm\:w-1\/6 { + width: 16.666667%; + } + + .sm\:w-2\/6 { + width: 33.333333%; + } + + .sm\:w-3\/6 { + width: 50%; + } + + .sm\:w-4\/6 { + width: 66.666667%; + } + + .sm\:w-5\/6 { + width: 83.333333%; + } + + .sm\:w-1\/12 { + width: 8.333333%; + } + + .sm\:w-2\/12 { + width: 16.666667%; + } + + .sm\:w-3\/12 { + width: 25%; + } + + .sm\:w-4\/12 { + width: 33.333333%; + } + + .sm\:w-5\/12 { + width: 41.666667%; + } + + .sm\:w-6\/12 { + width: 50%; + } + + .sm\:w-7\/12 { + width: 58.333333%; + } + + .sm\:w-8\/12 { + width: 66.666667%; + } + + .sm\:w-9\/12 { + width: 75%; + } + + .sm\:w-10\/12 { + width: 83.333333%; + } + + .sm\:w-11\/12 { + width: 91.666667%; + } + + .sm\:w-full { + width: 100%; + } + + .sm\:w-screen { + width: 100vw; + } + + .sm\:z-0 { + z-index: 0; + } + + .sm\:z-10 { + z-index: 10; + } + + .sm\:z-20 { + z-index: 20; + } + + .sm\:z-30 { + z-index: 30; + } + + .sm\:z-40 { + z-index: 40; + } + + .sm\:z-50 { + z-index: 50; + } + + .sm\:z-auto { + z-index: auto; + } + + .sm\:gap-0 { + grid-gap: 0; + gap: 0; + } + + .sm\:gap-1 { + grid-gap: 0.25rem; + gap: 0.25rem; + } + + .sm\:gap-2 { + grid-gap: 0.5rem; + gap: 0.5rem; + } + + .sm\:gap-3 { + grid-gap: 0.75rem; + gap: 0.75rem; + } + + .sm\:gap-4 { + grid-gap: 1rem; + gap: 1rem; + } + + .sm\:gap-5 { + grid-gap: 1.25rem; + gap: 1.25rem; + } + + .sm\:gap-6 { + grid-gap: 1.5rem; + gap: 1.5rem; + } + + .sm\:gap-8 { + grid-gap: 2rem; + gap: 2rem; + } + + .sm\:gap-10 { + grid-gap: 2.5rem; + gap: 2.5rem; + } + + .sm\:gap-12 { + grid-gap: 3rem; + gap: 3rem; + } + + .sm\:gap-16 { + grid-gap: 4rem; + gap: 4rem; + } + + .sm\:gap-20 { + grid-gap: 5rem; + gap: 5rem; + } + + .sm\:gap-24 { + grid-gap: 6rem; + gap: 6rem; + } + + .sm\:gap-32 { + grid-gap: 8rem; + gap: 8rem; + } + + .sm\:gap-40 { + grid-gap: 10rem; + gap: 10rem; + } + + .sm\:gap-48 { + grid-gap: 12rem; + gap: 12rem; + } + + .sm\:gap-56 { + grid-gap: 14rem; + gap: 14rem; + } + + .sm\:gap-64 { + grid-gap: 16rem; + gap: 16rem; + } + + .sm\:gap-px { + grid-gap: 1px; + gap: 1px; + } + + .sm\:col-gap-0 { + grid-column-gap: 0; + column-gap: 0; + } + + .sm\:col-gap-1 { + grid-column-gap: 0.25rem; + column-gap: 0.25rem; + } + + .sm\:col-gap-2 { + grid-column-gap: 0.5rem; + column-gap: 0.5rem; + } + + .sm\:col-gap-3 { + grid-column-gap: 0.75rem; + column-gap: 0.75rem; + } + + .sm\:col-gap-4 { + grid-column-gap: 1rem; + column-gap: 1rem; + } + + .sm\:col-gap-5 { + grid-column-gap: 1.25rem; + column-gap: 1.25rem; + } + + .sm\:col-gap-6 { + grid-column-gap: 1.5rem; + column-gap: 1.5rem; + } + + .sm\:col-gap-8 { + grid-column-gap: 2rem; + column-gap: 2rem; + } + + .sm\:col-gap-10 { + grid-column-gap: 2.5rem; + column-gap: 2.5rem; + } + + .sm\:col-gap-12 { + grid-column-gap: 3rem; + column-gap: 3rem; + } + + .sm\:col-gap-16 { + grid-column-gap: 4rem; + column-gap: 4rem; + } + + .sm\:col-gap-20 { + grid-column-gap: 5rem; + column-gap: 5rem; + } + + .sm\:col-gap-24 { + grid-column-gap: 6rem; + column-gap: 6rem; + } + + .sm\:col-gap-32 { + grid-column-gap: 8rem; + column-gap: 8rem; + } + + .sm\:col-gap-40 { + grid-column-gap: 10rem; + column-gap: 10rem; + } + + .sm\:col-gap-48 { + grid-column-gap: 12rem; + column-gap: 12rem; + } + + .sm\:col-gap-56 { + grid-column-gap: 14rem; + column-gap: 14rem; + } + + .sm\:col-gap-64 { + grid-column-gap: 16rem; + column-gap: 16rem; + } + + .sm\:col-gap-px { + grid-column-gap: 1px; + column-gap: 1px; + } + + .sm\:row-gap-0 { + grid-row-gap: 0; + row-gap: 0; + } + + .sm\:row-gap-1 { + grid-row-gap: 0.25rem; + row-gap: 0.25rem; + } + + .sm\:row-gap-2 { + grid-row-gap: 0.5rem; + row-gap: 0.5rem; + } + + .sm\:row-gap-3 { + grid-row-gap: 0.75rem; + row-gap: 0.75rem; + } + + .sm\:row-gap-4 { + grid-row-gap: 1rem; + row-gap: 1rem; + } + + .sm\:row-gap-5 { + grid-row-gap: 1.25rem; + row-gap: 1.25rem; + } + + .sm\:row-gap-6 { + grid-row-gap: 1.5rem; + row-gap: 1.5rem; + } + + .sm\:row-gap-8 { + grid-row-gap: 2rem; + row-gap: 2rem; + } + + .sm\:row-gap-10 { + grid-row-gap: 2.5rem; + row-gap: 2.5rem; + } + + .sm\:row-gap-12 { + grid-row-gap: 3rem; + row-gap: 3rem; + } + + .sm\:row-gap-16 { + grid-row-gap: 4rem; + row-gap: 4rem; + } + + .sm\:row-gap-20 { + grid-row-gap: 5rem; + row-gap: 5rem; + } + + .sm\:row-gap-24 { + grid-row-gap: 6rem; + row-gap: 6rem; + } + + .sm\:row-gap-32 { + grid-row-gap: 8rem; + row-gap: 8rem; + } + + .sm\:row-gap-40 { + grid-row-gap: 10rem; + row-gap: 10rem; + } + + .sm\:row-gap-48 { + grid-row-gap: 12rem; + row-gap: 12rem; + } + + .sm\:row-gap-56 { + grid-row-gap: 14rem; + row-gap: 14rem; + } + + .sm\:row-gap-64 { + grid-row-gap: 16rem; + row-gap: 16rem; + } + + .sm\:row-gap-px { + grid-row-gap: 1px; + row-gap: 1px; + } + + .sm\:grid-flow-row { + grid-auto-flow: row; + } + + .sm\:grid-flow-col { + grid-auto-flow: column; + } + + .sm\:grid-flow-row-dense { + grid-auto-flow: row dense; + } + + .sm\:grid-flow-col-dense { + grid-auto-flow: column dense; + } + + .sm\:grid-cols-1 { + grid-template-columns: repeat(1, minmax(0, 1fr)); + } + + .sm\:grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .sm\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .sm\:grid-cols-4 { + grid-template-columns: repeat(4, minmax(0, 1fr)); + } + + .sm\:grid-cols-5 { + grid-template-columns: repeat(5, minmax(0, 1fr)); + } + + .sm\:grid-cols-6 { + grid-template-columns: repeat(6, minmax(0, 1fr)); + } + + .sm\:grid-cols-7 { + grid-template-columns: repeat(7, minmax(0, 1fr)); + } + + .sm\:grid-cols-8 { + grid-template-columns: repeat(8, minmax(0, 1fr)); + } + + .sm\:grid-cols-9 { + grid-template-columns: repeat(9, minmax(0, 1fr)); + } + + .sm\:grid-cols-10 { + grid-template-columns: repeat(10, minmax(0, 1fr)); + } + + .sm\:grid-cols-11 { + grid-template-columns: repeat(11, minmax(0, 1fr)); + } + + .sm\:grid-cols-12 { + grid-template-columns: repeat(12, minmax(0, 1fr)); + } + + .sm\:grid-cols-none { + grid-template-columns: none; + } + + .sm\:col-auto { + grid-column: auto; + } + + .sm\:col-span-1 { + grid-column: span 1 / span 1; + } + + .sm\:col-span-2 { + grid-column: span 2 / span 2; + } + + .sm\:col-span-3 { + grid-column: span 3 / span 3; + } + + .sm\:col-span-4 { + grid-column: span 4 / span 4; + } + + .sm\:col-span-5 { + grid-column: span 5 / span 5; + } + + .sm\:col-span-6 { + grid-column: span 6 / span 6; + } + + .sm\:col-span-7 { + grid-column: span 7 / span 7; + } + + .sm\:col-span-8 { + grid-column: span 8 / span 8; + } + + .sm\:col-span-9 { + grid-column: span 9 / span 9; + } + + .sm\:col-span-10 { + grid-column: span 10 / span 10; + } + + .sm\:col-span-11 { + grid-column: span 11 / span 11; + } + + .sm\:col-span-12 { + grid-column: span 12 / span 12; + } + + .sm\:col-start-1 { + grid-column-start: 1; + } + + .sm\:col-start-2 { + grid-column-start: 2; + } + + .sm\:col-start-3 { + grid-column-start: 3; + } + + .sm\:col-start-4 { + grid-column-start: 4; + } + + .sm\:col-start-5 { + grid-column-start: 5; + } + + .sm\:col-start-6 { + grid-column-start: 6; + } + + .sm\:col-start-7 { + grid-column-start: 7; + } + + .sm\:col-start-8 { + grid-column-start: 8; + } + + .sm\:col-start-9 { + grid-column-start: 9; + } + + .sm\:col-start-10 { + grid-column-start: 10; + } + + .sm\:col-start-11 { + grid-column-start: 11; + } + + .sm\:col-start-12 { + grid-column-start: 12; + } + + .sm\:col-start-13 { + grid-column-start: 13; + } + + .sm\:col-start-auto { + grid-column-start: auto; + } + + .sm\:col-end-1 { + grid-column-end: 1; + } + + .sm\:col-end-2 { + grid-column-end: 2; + } + + .sm\:col-end-3 { + grid-column-end: 3; + } + + .sm\:col-end-4 { + grid-column-end: 4; + } + + .sm\:col-end-5 { + grid-column-end: 5; + } + + .sm\:col-end-6 { + grid-column-end: 6; + } + + .sm\:col-end-7 { + grid-column-end: 7; + } + + .sm\:col-end-8 { + grid-column-end: 8; + } + + .sm\:col-end-9 { + grid-column-end: 9; + } + + .sm\:col-end-10 { + grid-column-end: 10; + } + + .sm\:col-end-11 { + grid-column-end: 11; + } + + .sm\:col-end-12 { + grid-column-end: 12; + } + + .sm\:col-end-13 { + grid-column-end: 13; + } + + .sm\:col-end-auto { + grid-column-end: auto; + } + + .sm\:grid-rows-1 { + grid-template-rows: repeat(1, minmax(0, 1fr)); + } + + .sm\:grid-rows-2 { + grid-template-rows: repeat(2, minmax(0, 1fr)); + } + + .sm\:grid-rows-3 { + grid-template-rows: repeat(3, minmax(0, 1fr)); + } + + .sm\:grid-rows-4 { + grid-template-rows: repeat(4, minmax(0, 1fr)); + } + + .sm\:grid-rows-5 { + grid-template-rows: repeat(5, minmax(0, 1fr)); + } + + .sm\:grid-rows-6 { + grid-template-rows: repeat(6, minmax(0, 1fr)); + } + + .sm\:grid-rows-none { + grid-template-rows: none; + } + + .sm\:row-auto { + grid-row: auto; + } + + .sm\:row-span-1 { + grid-row: span 1 / span 1; + } + + .sm\:row-span-2 { + grid-row: span 2 / span 2; + } + + .sm\:row-span-3 { + grid-row: span 3 / span 3; + } + + .sm\:row-span-4 { + grid-row: span 4 / span 4; + } + + .sm\:row-span-5 { + grid-row: span 5 / span 5; + } + + .sm\:row-span-6 { + grid-row: span 6 / span 6; + } + + .sm\:row-start-1 { + grid-row-start: 1; + } + + .sm\:row-start-2 { + grid-row-start: 2; + } + + .sm\:row-start-3 { + grid-row-start: 3; + } + + .sm\:row-start-4 { + grid-row-start: 4; + } + + .sm\:row-start-5 { + grid-row-start: 5; + } + + .sm\:row-start-6 { + grid-row-start: 6; + } + + .sm\:row-start-7 { + grid-row-start: 7; + } + + .sm\:row-start-auto { + grid-row-start: auto; + } + + .sm\:row-end-1 { + grid-row-end: 1; + } + + .sm\:row-end-2 { + grid-row-end: 2; + } + + .sm\:row-end-3 { + grid-row-end: 3; + } + + .sm\:row-end-4 { + grid-row-end: 4; + } + + .sm\:row-end-5 { + grid-row-end: 5; + } + + .sm\:row-end-6 { + grid-row-end: 6; + } + + .sm\:row-end-7 { + grid-row-end: 7; + } + + .sm\:row-end-auto { + grid-row-end: auto; + } + + .sm\:transform { + --transform-translate-x: 0; + --transform-translate-y: 0; + --transform-rotate: 0; + --transform-skew-x: 0; + --transform-skew-y: 0; + --transform-scale-x: 1; + --transform-scale-y: 1; + transform: translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y)); + } + + .sm\:transform-none { + transform: none; + } + + .sm\:origin-center { + transform-origin: center; + } + + .sm\:origin-top { + transform-origin: top; + } + + .sm\:origin-top-right { + transform-origin: top right; + } + + .sm\:origin-right { + transform-origin: right; + } + + .sm\:origin-bottom-right { + transform-origin: bottom right; + } + + .sm\:origin-bottom { + transform-origin: bottom; + } + + .sm\:origin-bottom-left { + transform-origin: bottom left; + } + + .sm\:origin-left { + transform-origin: left; + } + + .sm\:origin-top-left { + transform-origin: top left; + } + + .sm\:scale-0 { + --transform-scale-x: 0; + --transform-scale-y: 0; + } + + .sm\:scale-50 { + --transform-scale-x: .5; + --transform-scale-y: .5; + } + + .sm\:scale-75 { + --transform-scale-x: .75; + --transform-scale-y: .75; + } + + .sm\:scale-90 { + --transform-scale-x: .9; + --transform-scale-y: .9; + } + + .sm\:scale-95 { + --transform-scale-x: .95; + --transform-scale-y: .95; + } + + .sm\:scale-100 { + --transform-scale-x: 1; + --transform-scale-y: 1; + } + + .sm\:scale-105 { + --transform-scale-x: 1.05; + --transform-scale-y: 1.05; + } + + .sm\:scale-110 { + --transform-scale-x: 1.1; + --transform-scale-y: 1.1; + } + + .sm\:scale-125 { + --transform-scale-x: 1.25; + --transform-scale-y: 1.25; + } + + .sm\:scale-150 { + --transform-scale-x: 1.5; + --transform-scale-y: 1.5; + } + + .sm\:scale-x-0 { + --transform-scale-x: 0; + } + + .sm\:scale-x-50 { + --transform-scale-x: .5; + } + + .sm\:scale-x-75 { + --transform-scale-x: .75; + } + + .sm\:scale-x-90 { + --transform-scale-x: .9; + } + + .sm\:scale-x-95 { + --transform-scale-x: .95; + } + + .sm\:scale-x-100 { + --transform-scale-x: 1; + } + + .sm\:scale-x-105 { + --transform-scale-x: 1.05; + } + + .sm\:scale-x-110 { + --transform-scale-x: 1.1; + } + + .sm\:scale-x-125 { + --transform-scale-x: 1.25; + } + + .sm\:scale-x-150 { + --transform-scale-x: 1.5; + } + + .sm\:scale-y-0 { + --transform-scale-y: 0; + } + + .sm\:scale-y-50 { + --transform-scale-y: .5; + } + + .sm\:scale-y-75 { + --transform-scale-y: .75; + } + + .sm\:scale-y-90 { + --transform-scale-y: .9; + } + + .sm\:scale-y-95 { + --transform-scale-y: .95; + } + + .sm\:scale-y-100 { + --transform-scale-y: 1; + } + + .sm\:scale-y-105 { + --transform-scale-y: 1.05; + } + + .sm\:scale-y-110 { + --transform-scale-y: 1.1; + } + + .sm\:scale-y-125 { + --transform-scale-y: 1.25; + } + + .sm\:scale-y-150 { + --transform-scale-y: 1.5; + } + + .sm\:hover\:scale-0:hover { + --transform-scale-x: 0; + --transform-scale-y: 0; + } + + .sm\:hover\:scale-50:hover { + --transform-scale-x: .5; + --transform-scale-y: .5; + } + + .sm\:hover\:scale-75:hover { + --transform-scale-x: .75; + --transform-scale-y: .75; + } + + .sm\:hover\:scale-90:hover { + --transform-scale-x: .9; + --transform-scale-y: .9; + } + + .sm\:hover\:scale-95:hover { + --transform-scale-x: .95; + --transform-scale-y: .95; + } + + .sm\:hover\:scale-100:hover { + --transform-scale-x: 1; + --transform-scale-y: 1; + } + + .sm\:hover\:scale-105:hover { + --transform-scale-x: 1.05; + --transform-scale-y: 1.05; + } + + .sm\:hover\:scale-110:hover { + --transform-scale-x: 1.1; + --transform-scale-y: 1.1; + } + + .sm\:hover\:scale-125:hover { + --transform-scale-x: 1.25; + --transform-scale-y: 1.25; + } + + .sm\:hover\:scale-150:hover { + --transform-scale-x: 1.5; + --transform-scale-y: 1.5; + } + + .sm\:hover\:scale-x-0:hover { + --transform-scale-x: 0; + } + + .sm\:hover\:scale-x-50:hover { + --transform-scale-x: .5; + } + + .sm\:hover\:scale-x-75:hover { + --transform-scale-x: .75; + } + + .sm\:hover\:scale-x-90:hover { + --transform-scale-x: .9; + } + + .sm\:hover\:scale-x-95:hover { + --transform-scale-x: .95; + } + + .sm\:hover\:scale-x-100:hover { + --transform-scale-x: 1; + } + + .sm\:hover\:scale-x-105:hover { + --transform-scale-x: 1.05; + } + + .sm\:hover\:scale-x-110:hover { + --transform-scale-x: 1.1; + } + + .sm\:hover\:scale-x-125:hover { + --transform-scale-x: 1.25; + } + + .sm\:hover\:scale-x-150:hover { + --transform-scale-x: 1.5; + } + + .sm\:hover\:scale-y-0:hover { + --transform-scale-y: 0; + } + + .sm\:hover\:scale-y-50:hover { + --transform-scale-y: .5; + } + + .sm\:hover\:scale-y-75:hover { + --transform-scale-y: .75; + } + + .sm\:hover\:scale-y-90:hover { + --transform-scale-y: .9; + } + + .sm\:hover\:scale-y-95:hover { + --transform-scale-y: .95; + } + + .sm\:hover\:scale-y-100:hover { + --transform-scale-y: 1; + } + + .sm\:hover\:scale-y-105:hover { + --transform-scale-y: 1.05; + } + + .sm\:hover\:scale-y-110:hover { + --transform-scale-y: 1.1; + } + + .sm\:hover\:scale-y-125:hover { + --transform-scale-y: 1.25; + } + + .sm\:hover\:scale-y-150:hover { + --transform-scale-y: 1.5; + } + + .sm\:focus\:scale-0:focus { + --transform-scale-x: 0; + --transform-scale-y: 0; + } + + .sm\:focus\:scale-50:focus { + --transform-scale-x: .5; + --transform-scale-y: .5; + } + + .sm\:focus\:scale-75:focus { + --transform-scale-x: .75; + --transform-scale-y: .75; + } + + .sm\:focus\:scale-90:focus { + --transform-scale-x: .9; + --transform-scale-y: .9; + } + + .sm\:focus\:scale-95:focus { + --transform-scale-x: .95; + --transform-scale-y: .95; + } + + .sm\:focus\:scale-100:focus { + --transform-scale-x: 1; + --transform-scale-y: 1; + } + + .sm\:focus\:scale-105:focus { + --transform-scale-x: 1.05; + --transform-scale-y: 1.05; + } + + .sm\:focus\:scale-110:focus { + --transform-scale-x: 1.1; + --transform-scale-y: 1.1; + } + + .sm\:focus\:scale-125:focus { + --transform-scale-x: 1.25; + --transform-scale-y: 1.25; + } + + .sm\:focus\:scale-150:focus { + --transform-scale-x: 1.5; + --transform-scale-y: 1.5; + } + + .sm\:focus\:scale-x-0:focus { + --transform-scale-x: 0; + } + + .sm\:focus\:scale-x-50:focus { + --transform-scale-x: .5; + } + + .sm\:focus\:scale-x-75:focus { + --transform-scale-x: .75; + } + + .sm\:focus\:scale-x-90:focus { + --transform-scale-x: .9; + } + + .sm\:focus\:scale-x-95:focus { + --transform-scale-x: .95; + } + + .sm\:focus\:scale-x-100:focus { + --transform-scale-x: 1; + } + + .sm\:focus\:scale-x-105:focus { + --transform-scale-x: 1.05; + } + + .sm\:focus\:scale-x-110:focus { + --transform-scale-x: 1.1; + } + + .sm\:focus\:scale-x-125:focus { + --transform-scale-x: 1.25; + } + + .sm\:focus\:scale-x-150:focus { + --transform-scale-x: 1.5; + } + + .sm\:focus\:scale-y-0:focus { + --transform-scale-y: 0; + } + + .sm\:focus\:scale-y-50:focus { + --transform-scale-y: .5; + } + + .sm\:focus\:scale-y-75:focus { + --transform-scale-y: .75; + } + + .sm\:focus\:scale-y-90:focus { + --transform-scale-y: .9; + } + + .sm\:focus\:scale-y-95:focus { + --transform-scale-y: .95; + } + + .sm\:focus\:scale-y-100:focus { + --transform-scale-y: 1; + } + + .sm\:focus\:scale-y-105:focus { + --transform-scale-y: 1.05; + } + + .sm\:focus\:scale-y-110:focus { + --transform-scale-y: 1.1; + } + + .sm\:focus\:scale-y-125:focus { + --transform-scale-y: 1.25; + } + + .sm\:focus\:scale-y-150:focus { + --transform-scale-y: 1.5; + } + + .sm\:rotate-0 { + --transform-rotate: 0; + } + + .sm\:rotate-45 { + --transform-rotate: 45deg; + } + + .sm\:rotate-90 { + --transform-rotate: 90deg; + } + + .sm\:rotate-180 { + --transform-rotate: 180deg; + } + + .sm\:-rotate-180 { + --transform-rotate: -180deg; + } + + .sm\:-rotate-90 { + --transform-rotate: -90deg; + } + + .sm\:-rotate-45 { + --transform-rotate: -45deg; + } + + .sm\:hover\:rotate-0:hover { + --transform-rotate: 0; + } + + .sm\:hover\:rotate-45:hover { + --transform-rotate: 45deg; + } + + .sm\:hover\:rotate-90:hover { + --transform-rotate: 90deg; + } + + .sm\:hover\:rotate-180:hover { + --transform-rotate: 180deg; + } + + .sm\:hover\:-rotate-180:hover { + --transform-rotate: -180deg; + } + + .sm\:hover\:-rotate-90:hover { + --transform-rotate: -90deg; + } + + .sm\:hover\:-rotate-45:hover { + --transform-rotate: -45deg; + } + + .sm\:focus\:rotate-0:focus { + --transform-rotate: 0; + } + + .sm\:focus\:rotate-45:focus { + --transform-rotate: 45deg; + } + + .sm\:focus\:rotate-90:focus { + --transform-rotate: 90deg; + } + + .sm\:focus\:rotate-180:focus { + --transform-rotate: 180deg; + } + + .sm\:focus\:-rotate-180:focus { + --transform-rotate: -180deg; + } + + .sm\:focus\:-rotate-90:focus { + --transform-rotate: -90deg; + } + + .sm\:focus\:-rotate-45:focus { + --transform-rotate: -45deg; + } + + .sm\:translate-x-0 { + --transform-translate-x: 0; + } + + .sm\:translate-x-1 { + --transform-translate-x: 0.25rem; + } + + .sm\:translate-x-2 { + --transform-translate-x: 0.5rem; + } + + .sm\:translate-x-3 { + --transform-translate-x: 0.75rem; + } + + .sm\:translate-x-4 { + --transform-translate-x: 1rem; + } + + .sm\:translate-x-5 { + --transform-translate-x: 1.25rem; + } + + .sm\:translate-x-6 { + --transform-translate-x: 1.5rem; + } + + .sm\:translate-x-8 { + --transform-translate-x: 2rem; + } + + .sm\:translate-x-10 { + --transform-translate-x: 2.5rem; + } + + .sm\:translate-x-12 { + --transform-translate-x: 3rem; + } + + .sm\:translate-x-16 { + --transform-translate-x: 4rem; + } + + .sm\:translate-x-20 { + --transform-translate-x: 5rem; + } + + .sm\:translate-x-24 { + --transform-translate-x: 6rem; + } + + .sm\:translate-x-32 { + --transform-translate-x: 8rem; + } + + .sm\:translate-x-40 { + --transform-translate-x: 10rem; + } + + .sm\:translate-x-48 { + --transform-translate-x: 12rem; + } + + .sm\:translate-x-56 { + --transform-translate-x: 14rem; + } + + .sm\:translate-x-64 { + --transform-translate-x: 16rem; + } + + .sm\:translate-x-px { + --transform-translate-x: 1px; + } + + .sm\:-translate-x-1 { + --transform-translate-x: -0.25rem; + } + + .sm\:-translate-x-2 { + --transform-translate-x: -0.5rem; + } + + .sm\:-translate-x-3 { + --transform-translate-x: -0.75rem; + } + + .sm\:-translate-x-4 { + --transform-translate-x: -1rem; + } + + .sm\:-translate-x-5 { + --transform-translate-x: -1.25rem; + } + + .sm\:-translate-x-6 { + --transform-translate-x: -1.5rem; + } + + .sm\:-translate-x-8 { + --transform-translate-x: -2rem; + } + + .sm\:-translate-x-10 { + --transform-translate-x: -2.5rem; + } + + .sm\:-translate-x-12 { + --transform-translate-x: -3rem; + } + + .sm\:-translate-x-16 { + --transform-translate-x: -4rem; + } + + .sm\:-translate-x-20 { + --transform-translate-x: -5rem; + } + + .sm\:-translate-x-24 { + --transform-translate-x: -6rem; + } + + .sm\:-translate-x-32 { + --transform-translate-x: -8rem; + } + + .sm\:-translate-x-40 { + --transform-translate-x: -10rem; + } + + .sm\:-translate-x-48 { + --transform-translate-x: -12rem; + } + + .sm\:-translate-x-56 { + --transform-translate-x: -14rem; + } + + .sm\:-translate-x-64 { + --transform-translate-x: -16rem; + } + + .sm\:-translate-x-px { + --transform-translate-x: -1px; + } + + .sm\:-translate-x-full { + --transform-translate-x: -100%; + } + + .sm\:-translate-x-1\/2 { + --transform-translate-x: -50%; + } + + .sm\:translate-x-1\/2 { + --transform-translate-x: 50%; + } + + .sm\:translate-x-full { + --transform-translate-x: 100%; + } + + .sm\:translate-y-0 { + --transform-translate-y: 0; + } + + .sm\:translate-y-1 { + --transform-translate-y: 0.25rem; + } + + .sm\:translate-y-2 { + --transform-translate-y: 0.5rem; + } + + .sm\:translate-y-3 { + --transform-translate-y: 0.75rem; + } + + .sm\:translate-y-4 { + --transform-translate-y: 1rem; + } + + .sm\:translate-y-5 { + --transform-translate-y: 1.25rem; + } + + .sm\:translate-y-6 { + --transform-translate-y: 1.5rem; + } + + .sm\:translate-y-8 { + --transform-translate-y: 2rem; + } + + .sm\:translate-y-10 { + --transform-translate-y: 2.5rem; + } + + .sm\:translate-y-12 { + --transform-translate-y: 3rem; + } + + .sm\:translate-y-16 { + --transform-translate-y: 4rem; + } + + .sm\:translate-y-20 { + --transform-translate-y: 5rem; + } + + .sm\:translate-y-24 { + --transform-translate-y: 6rem; + } + + .sm\:translate-y-32 { + --transform-translate-y: 8rem; + } + + .sm\:translate-y-40 { + --transform-translate-y: 10rem; + } + + .sm\:translate-y-48 { + --transform-translate-y: 12rem; + } + + .sm\:translate-y-56 { + --transform-translate-y: 14rem; + } + + .sm\:translate-y-64 { + --transform-translate-y: 16rem; + } + + .sm\:translate-y-px { + --transform-translate-y: 1px; + } + + .sm\:-translate-y-1 { + --transform-translate-y: -0.25rem; + } + + .sm\:-translate-y-2 { + --transform-translate-y: -0.5rem; + } + + .sm\:-translate-y-3 { + --transform-translate-y: -0.75rem; + } + + .sm\:-translate-y-4 { + --transform-translate-y: -1rem; + } + + .sm\:-translate-y-5 { + --transform-translate-y: -1.25rem; + } + + .sm\:-translate-y-6 { + --transform-translate-y: -1.5rem; + } + + .sm\:-translate-y-8 { + --transform-translate-y: -2rem; + } + + .sm\:-translate-y-10 { + --transform-translate-y: -2.5rem; + } + + .sm\:-translate-y-12 { + --transform-translate-y: -3rem; + } + + .sm\:-translate-y-16 { + --transform-translate-y: -4rem; + } + + .sm\:-translate-y-20 { + --transform-translate-y: -5rem; + } + + .sm\:-translate-y-24 { + --transform-translate-y: -6rem; + } + + .sm\:-translate-y-32 { + --transform-translate-y: -8rem; + } + + .sm\:-translate-y-40 { + --transform-translate-y: -10rem; + } + + .sm\:-translate-y-48 { + --transform-translate-y: -12rem; + } + + .sm\:-translate-y-56 { + --transform-translate-y: -14rem; + } + + .sm\:-translate-y-64 { + --transform-translate-y: -16rem; + } + + .sm\:-translate-y-px { + --transform-translate-y: -1px; + } + + .sm\:-translate-y-full { + --transform-translate-y: -100%; + } + + .sm\:-translate-y-1\/2 { + --transform-translate-y: -50%; + } + + .sm\:translate-y-1\/2 { + --transform-translate-y: 50%; + } + + .sm\:translate-y-full { + --transform-translate-y: 100%; + } + + .sm\:hover\:translate-x-0:hover { + --transform-translate-x: 0; + } + + .sm\:hover\:translate-x-1:hover { + --transform-translate-x: 0.25rem; + } + + .sm\:hover\:translate-x-2:hover { + --transform-translate-x: 0.5rem; + } + + .sm\:hover\:translate-x-3:hover { + --transform-translate-x: 0.75rem; + } + + .sm\:hover\:translate-x-4:hover { + --transform-translate-x: 1rem; + } + + .sm\:hover\:translate-x-5:hover { + --transform-translate-x: 1.25rem; + } + + .sm\:hover\:translate-x-6:hover { + --transform-translate-x: 1.5rem; + } + + .sm\:hover\:translate-x-8:hover { + --transform-translate-x: 2rem; + } + + .sm\:hover\:translate-x-10:hover { + --transform-translate-x: 2.5rem; + } + + .sm\:hover\:translate-x-12:hover { + --transform-translate-x: 3rem; + } + + .sm\:hover\:translate-x-16:hover { + --transform-translate-x: 4rem; + } + + .sm\:hover\:translate-x-20:hover { + --transform-translate-x: 5rem; + } + + .sm\:hover\:translate-x-24:hover { + --transform-translate-x: 6rem; + } + + .sm\:hover\:translate-x-32:hover { + --transform-translate-x: 8rem; + } + + .sm\:hover\:translate-x-40:hover { + --transform-translate-x: 10rem; + } + + .sm\:hover\:translate-x-48:hover { + --transform-translate-x: 12rem; + } + + .sm\:hover\:translate-x-56:hover { + --transform-translate-x: 14rem; + } + + .sm\:hover\:translate-x-64:hover { + --transform-translate-x: 16rem; + } + + .sm\:hover\:translate-x-px:hover { + --transform-translate-x: 1px; + } + + .sm\:hover\:-translate-x-1:hover { + --transform-translate-x: -0.25rem; + } + + .sm\:hover\:-translate-x-2:hover { + --transform-translate-x: -0.5rem; + } + + .sm\:hover\:-translate-x-3:hover { + --transform-translate-x: -0.75rem; + } + + .sm\:hover\:-translate-x-4:hover { + --transform-translate-x: -1rem; + } + + .sm\:hover\:-translate-x-5:hover { + --transform-translate-x: -1.25rem; + } + + .sm\:hover\:-translate-x-6:hover { + --transform-translate-x: -1.5rem; + } + + .sm\:hover\:-translate-x-8:hover { + --transform-translate-x: -2rem; + } + + .sm\:hover\:-translate-x-10:hover { + --transform-translate-x: -2.5rem; + } + + .sm\:hover\:-translate-x-12:hover { + --transform-translate-x: -3rem; + } + + .sm\:hover\:-translate-x-16:hover { + --transform-translate-x: -4rem; + } + + .sm\:hover\:-translate-x-20:hover { + --transform-translate-x: -5rem; + } + + .sm\:hover\:-translate-x-24:hover { + --transform-translate-x: -6rem; + } + + .sm\:hover\:-translate-x-32:hover { + --transform-translate-x: -8rem; + } + + .sm\:hover\:-translate-x-40:hover { + --transform-translate-x: -10rem; + } + + .sm\:hover\:-translate-x-48:hover { + --transform-translate-x: -12rem; + } + + .sm\:hover\:-translate-x-56:hover { + --transform-translate-x: -14rem; + } + + .sm\:hover\:-translate-x-64:hover { + --transform-translate-x: -16rem; + } + + .sm\:hover\:-translate-x-px:hover { + --transform-translate-x: -1px; + } + + .sm\:hover\:-translate-x-full:hover { + --transform-translate-x: -100%; + } + + .sm\:hover\:-translate-x-1\/2:hover { + --transform-translate-x: -50%; + } + + .sm\:hover\:translate-x-1\/2:hover { + --transform-translate-x: 50%; + } + + .sm\:hover\:translate-x-full:hover { + --transform-translate-x: 100%; + } + + .sm\:hover\:translate-y-0:hover { + --transform-translate-y: 0; + } + + .sm\:hover\:translate-y-1:hover { + --transform-translate-y: 0.25rem; + } + + .sm\:hover\:translate-y-2:hover { + --transform-translate-y: 0.5rem; + } + + .sm\:hover\:translate-y-3:hover { + --transform-translate-y: 0.75rem; + } + + .sm\:hover\:translate-y-4:hover { + --transform-translate-y: 1rem; + } + + .sm\:hover\:translate-y-5:hover { + --transform-translate-y: 1.25rem; + } + + .sm\:hover\:translate-y-6:hover { + --transform-translate-y: 1.5rem; + } + + .sm\:hover\:translate-y-8:hover { + --transform-translate-y: 2rem; + } + + .sm\:hover\:translate-y-10:hover { + --transform-translate-y: 2.5rem; + } + + .sm\:hover\:translate-y-12:hover { + --transform-translate-y: 3rem; + } + + .sm\:hover\:translate-y-16:hover { + --transform-translate-y: 4rem; + } + + .sm\:hover\:translate-y-20:hover { + --transform-translate-y: 5rem; + } + + .sm\:hover\:translate-y-24:hover { + --transform-translate-y: 6rem; + } + + .sm\:hover\:translate-y-32:hover { + --transform-translate-y: 8rem; + } + + .sm\:hover\:translate-y-40:hover { + --transform-translate-y: 10rem; + } + + .sm\:hover\:translate-y-48:hover { + --transform-translate-y: 12rem; + } + + .sm\:hover\:translate-y-56:hover { + --transform-translate-y: 14rem; + } + + .sm\:hover\:translate-y-64:hover { + --transform-translate-y: 16rem; + } + + .sm\:hover\:translate-y-px:hover { + --transform-translate-y: 1px; + } + + .sm\:hover\:-translate-y-1:hover { + --transform-translate-y: -0.25rem; + } + + .sm\:hover\:-translate-y-2:hover { + --transform-translate-y: -0.5rem; + } + + .sm\:hover\:-translate-y-3:hover { + --transform-translate-y: -0.75rem; + } + + .sm\:hover\:-translate-y-4:hover { + --transform-translate-y: -1rem; + } + + .sm\:hover\:-translate-y-5:hover { + --transform-translate-y: -1.25rem; + } + + .sm\:hover\:-translate-y-6:hover { + --transform-translate-y: -1.5rem; + } + + .sm\:hover\:-translate-y-8:hover { + --transform-translate-y: -2rem; + } + + .sm\:hover\:-translate-y-10:hover { + --transform-translate-y: -2.5rem; + } + + .sm\:hover\:-translate-y-12:hover { + --transform-translate-y: -3rem; + } + + .sm\:hover\:-translate-y-16:hover { + --transform-translate-y: -4rem; + } + + .sm\:hover\:-translate-y-20:hover { + --transform-translate-y: -5rem; + } + + .sm\:hover\:-translate-y-24:hover { + --transform-translate-y: -6rem; + } + + .sm\:hover\:-translate-y-32:hover { + --transform-translate-y: -8rem; + } + + .sm\:hover\:-translate-y-40:hover { + --transform-translate-y: -10rem; + } + + .sm\:hover\:-translate-y-48:hover { + --transform-translate-y: -12rem; + } + + .sm\:hover\:-translate-y-56:hover { + --transform-translate-y: -14rem; + } + + .sm\:hover\:-translate-y-64:hover { + --transform-translate-y: -16rem; + } + + .sm\:hover\:-translate-y-px:hover { + --transform-translate-y: -1px; + } + + .sm\:hover\:-translate-y-full:hover { + --transform-translate-y: -100%; + } + + .sm\:hover\:-translate-y-1\/2:hover { + --transform-translate-y: -50%; + } + + .sm\:hover\:translate-y-1\/2:hover { + --transform-translate-y: 50%; + } + + .sm\:hover\:translate-y-full:hover { + --transform-translate-y: 100%; + } + + .sm\:focus\:translate-x-0:focus { + --transform-translate-x: 0; + } + + .sm\:focus\:translate-x-1:focus { + --transform-translate-x: 0.25rem; + } + + .sm\:focus\:translate-x-2:focus { + --transform-translate-x: 0.5rem; + } + + .sm\:focus\:translate-x-3:focus { + --transform-translate-x: 0.75rem; + } + + .sm\:focus\:translate-x-4:focus { + --transform-translate-x: 1rem; + } + + .sm\:focus\:translate-x-5:focus { + --transform-translate-x: 1.25rem; + } + + .sm\:focus\:translate-x-6:focus { + --transform-translate-x: 1.5rem; + } + + .sm\:focus\:translate-x-8:focus { + --transform-translate-x: 2rem; + } + + .sm\:focus\:translate-x-10:focus { + --transform-translate-x: 2.5rem; + } + + .sm\:focus\:translate-x-12:focus { + --transform-translate-x: 3rem; + } + + .sm\:focus\:translate-x-16:focus { + --transform-translate-x: 4rem; + } + + .sm\:focus\:translate-x-20:focus { + --transform-translate-x: 5rem; + } + + .sm\:focus\:translate-x-24:focus { + --transform-translate-x: 6rem; + } + + .sm\:focus\:translate-x-32:focus { + --transform-translate-x: 8rem; + } + + .sm\:focus\:translate-x-40:focus { + --transform-translate-x: 10rem; + } + + .sm\:focus\:translate-x-48:focus { + --transform-translate-x: 12rem; + } + + .sm\:focus\:translate-x-56:focus { + --transform-translate-x: 14rem; + } + + .sm\:focus\:translate-x-64:focus { + --transform-translate-x: 16rem; + } + + .sm\:focus\:translate-x-px:focus { + --transform-translate-x: 1px; + } + + .sm\:focus\:-translate-x-1:focus { + --transform-translate-x: -0.25rem; + } + + .sm\:focus\:-translate-x-2:focus { + --transform-translate-x: -0.5rem; + } + + .sm\:focus\:-translate-x-3:focus { + --transform-translate-x: -0.75rem; + } + + .sm\:focus\:-translate-x-4:focus { + --transform-translate-x: -1rem; + } + + .sm\:focus\:-translate-x-5:focus { + --transform-translate-x: -1.25rem; + } + + .sm\:focus\:-translate-x-6:focus { + --transform-translate-x: -1.5rem; + } + + .sm\:focus\:-translate-x-8:focus { + --transform-translate-x: -2rem; + } + + .sm\:focus\:-translate-x-10:focus { + --transform-translate-x: -2.5rem; + } + + .sm\:focus\:-translate-x-12:focus { + --transform-translate-x: -3rem; + } + + .sm\:focus\:-translate-x-16:focus { + --transform-translate-x: -4rem; + } + + .sm\:focus\:-translate-x-20:focus { + --transform-translate-x: -5rem; + } + + .sm\:focus\:-translate-x-24:focus { + --transform-translate-x: -6rem; + } + + .sm\:focus\:-translate-x-32:focus { + --transform-translate-x: -8rem; + } + + .sm\:focus\:-translate-x-40:focus { + --transform-translate-x: -10rem; + } + + .sm\:focus\:-translate-x-48:focus { + --transform-translate-x: -12rem; + } + + .sm\:focus\:-translate-x-56:focus { + --transform-translate-x: -14rem; + } + + .sm\:focus\:-translate-x-64:focus { + --transform-translate-x: -16rem; + } + + .sm\:focus\:-translate-x-px:focus { + --transform-translate-x: -1px; + } + + .sm\:focus\:-translate-x-full:focus { + --transform-translate-x: -100%; + } + + .sm\:focus\:-translate-x-1\/2:focus { + --transform-translate-x: -50%; + } + + .sm\:focus\:translate-x-1\/2:focus { + --transform-translate-x: 50%; + } + + .sm\:focus\:translate-x-full:focus { + --transform-translate-x: 100%; + } + + .sm\:focus\:translate-y-0:focus { + --transform-translate-y: 0; + } + + .sm\:focus\:translate-y-1:focus { + --transform-translate-y: 0.25rem; + } + + .sm\:focus\:translate-y-2:focus { + --transform-translate-y: 0.5rem; + } + + .sm\:focus\:translate-y-3:focus { + --transform-translate-y: 0.75rem; + } + + .sm\:focus\:translate-y-4:focus { + --transform-translate-y: 1rem; + } + + .sm\:focus\:translate-y-5:focus { + --transform-translate-y: 1.25rem; + } + + .sm\:focus\:translate-y-6:focus { + --transform-translate-y: 1.5rem; + } + + .sm\:focus\:translate-y-8:focus { + --transform-translate-y: 2rem; + } + + .sm\:focus\:translate-y-10:focus { + --transform-translate-y: 2.5rem; + } + + .sm\:focus\:translate-y-12:focus { + --transform-translate-y: 3rem; + } + + .sm\:focus\:translate-y-16:focus { + --transform-translate-y: 4rem; + } + + .sm\:focus\:translate-y-20:focus { + --transform-translate-y: 5rem; + } + + .sm\:focus\:translate-y-24:focus { + --transform-translate-y: 6rem; + } + + .sm\:focus\:translate-y-32:focus { + --transform-translate-y: 8rem; + } + + .sm\:focus\:translate-y-40:focus { + --transform-translate-y: 10rem; + } + + .sm\:focus\:translate-y-48:focus { + --transform-translate-y: 12rem; + } + + .sm\:focus\:translate-y-56:focus { + --transform-translate-y: 14rem; + } + + .sm\:focus\:translate-y-64:focus { + --transform-translate-y: 16rem; + } + + .sm\:focus\:translate-y-px:focus { + --transform-translate-y: 1px; + } + + .sm\:focus\:-translate-y-1:focus { + --transform-translate-y: -0.25rem; + } + + .sm\:focus\:-translate-y-2:focus { + --transform-translate-y: -0.5rem; + } + + .sm\:focus\:-translate-y-3:focus { + --transform-translate-y: -0.75rem; + } + + .sm\:focus\:-translate-y-4:focus { + --transform-translate-y: -1rem; + } + + .sm\:focus\:-translate-y-5:focus { + --transform-translate-y: -1.25rem; + } + + .sm\:focus\:-translate-y-6:focus { + --transform-translate-y: -1.5rem; + } + + .sm\:focus\:-translate-y-8:focus { + --transform-translate-y: -2rem; + } + + .sm\:focus\:-translate-y-10:focus { + --transform-translate-y: -2.5rem; + } + + .sm\:focus\:-translate-y-12:focus { + --transform-translate-y: -3rem; + } + + .sm\:focus\:-translate-y-16:focus { + --transform-translate-y: -4rem; + } + + .sm\:focus\:-translate-y-20:focus { + --transform-translate-y: -5rem; + } + + .sm\:focus\:-translate-y-24:focus { + --transform-translate-y: -6rem; + } + + .sm\:focus\:-translate-y-32:focus { + --transform-translate-y: -8rem; + } + + .sm\:focus\:-translate-y-40:focus { + --transform-translate-y: -10rem; + } + + .sm\:focus\:-translate-y-48:focus { + --transform-translate-y: -12rem; + } + + .sm\:focus\:-translate-y-56:focus { + --transform-translate-y: -14rem; + } + + .sm\:focus\:-translate-y-64:focus { + --transform-translate-y: -16rem; + } + + .sm\:focus\:-translate-y-px:focus { + --transform-translate-y: -1px; + } + + .sm\:focus\:-translate-y-full:focus { + --transform-translate-y: -100%; + } + + .sm\:focus\:-translate-y-1\/2:focus { + --transform-translate-y: -50%; + } + + .sm\:focus\:translate-y-1\/2:focus { + --transform-translate-y: 50%; + } + + .sm\:focus\:translate-y-full:focus { + --transform-translate-y: 100%; + } + + .sm\:skew-x-0 { + --transform-skew-x: 0; + } + + .sm\:skew-x-3 { + --transform-skew-x: 3deg; + } + + .sm\:skew-x-6 { + --transform-skew-x: 6deg; + } + + .sm\:skew-x-12 { + --transform-skew-x: 12deg; + } + + .sm\:-skew-x-12 { + --transform-skew-x: -12deg; + } + + .sm\:-skew-x-6 { + --transform-skew-x: -6deg; + } + + .sm\:-skew-x-3 { + --transform-skew-x: -3deg; + } + + .sm\:skew-y-0 { + --transform-skew-y: 0; + } + + .sm\:skew-y-3 { + --transform-skew-y: 3deg; + } + + .sm\:skew-y-6 { + --transform-skew-y: 6deg; + } + + .sm\:skew-y-12 { + --transform-skew-y: 12deg; + } + + .sm\:-skew-y-12 { + --transform-skew-y: -12deg; + } + + .sm\:-skew-y-6 { + --transform-skew-y: -6deg; + } + + .sm\:-skew-y-3 { + --transform-skew-y: -3deg; + } + + .sm\:hover\:skew-x-0:hover { + --transform-skew-x: 0; + } + + .sm\:hover\:skew-x-3:hover { + --transform-skew-x: 3deg; + } + + .sm\:hover\:skew-x-6:hover { + --transform-skew-x: 6deg; + } + + .sm\:hover\:skew-x-12:hover { + --transform-skew-x: 12deg; + } + + .sm\:hover\:-skew-x-12:hover { + --transform-skew-x: -12deg; + } + + .sm\:hover\:-skew-x-6:hover { + --transform-skew-x: -6deg; + } + + .sm\:hover\:-skew-x-3:hover { + --transform-skew-x: -3deg; + } + + .sm\:hover\:skew-y-0:hover { + --transform-skew-y: 0; + } + + .sm\:hover\:skew-y-3:hover { + --transform-skew-y: 3deg; + } + + .sm\:hover\:skew-y-6:hover { + --transform-skew-y: 6deg; + } + + .sm\:hover\:skew-y-12:hover { + --transform-skew-y: 12deg; + } + + .sm\:hover\:-skew-y-12:hover { + --transform-skew-y: -12deg; + } + + .sm\:hover\:-skew-y-6:hover { + --transform-skew-y: -6deg; + } + + .sm\:hover\:-skew-y-3:hover { + --transform-skew-y: -3deg; + } + + .sm\:focus\:skew-x-0:focus { + --transform-skew-x: 0; + } + + .sm\:focus\:skew-x-3:focus { + --transform-skew-x: 3deg; + } + + .sm\:focus\:skew-x-6:focus { + --transform-skew-x: 6deg; + } + + .sm\:focus\:skew-x-12:focus { + --transform-skew-x: 12deg; + } + + .sm\:focus\:-skew-x-12:focus { + --transform-skew-x: -12deg; + } + + .sm\:focus\:-skew-x-6:focus { + --transform-skew-x: -6deg; + } + + .sm\:focus\:-skew-x-3:focus { + --transform-skew-x: -3deg; + } + + .sm\:focus\:skew-y-0:focus { + --transform-skew-y: 0; + } + + .sm\:focus\:skew-y-3:focus { + --transform-skew-y: 3deg; + } + + .sm\:focus\:skew-y-6:focus { + --transform-skew-y: 6deg; + } + + .sm\:focus\:skew-y-12:focus { + --transform-skew-y: 12deg; + } + + .sm\:focus\:-skew-y-12:focus { + --transform-skew-y: -12deg; + } + + .sm\:focus\:-skew-y-6:focus { + --transform-skew-y: -6deg; + } + + .sm\:focus\:-skew-y-3:focus { + --transform-skew-y: -3deg; + } + + .sm\:transition-none { + transition-property: none; + } + + .sm\:transition-all { + transition-property: all; + } + + .sm\:transition { + transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform; + } + + .sm\:transition-colors { + transition-property: background-color, border-color, color, fill, stroke; + } + + .sm\:transition-opacity { + transition-property: opacity; + } + + .sm\:transition-shadow { + transition-property: box-shadow; + } + + .sm\:transition-transform { + transition-property: transform; + } + + .sm\:ease-linear { + transition-timing-function: linear; + } + + .sm\:ease-in { + transition-timing-function: cubic-bezier(0.4, 0, 1, 1); + } + + .sm\:ease-out { + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + } + + .sm\:ease-in-out { + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + } + + .sm\:duration-75 { + transition-duration: 75ms; + } + + .sm\:duration-100 { + transition-duration: 100ms; + } + + .sm\:duration-150 { + transition-duration: 150ms; + } + + .sm\:duration-200 { + transition-duration: 200ms; + } + + .sm\:duration-300 { + transition-duration: 300ms; + } + + .sm\:duration-500 { + transition-duration: 500ms; + } + + .sm\:duration-700 { + transition-duration: 700ms; + } + + .sm\:duration-1000 { + transition-duration: 1000ms; + } +} + +@media (min-width: 768px) { + .md\:sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; + } + + .md\:not-sr-only { + position: static; + width: auto; + height: auto; + padding: 0; + margin: 0; + overflow: visible; + clip: auto; + white-space: normal; + } + + .md\:focus\:sr-only:focus { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; + } + + .md\:focus\:not-sr-only:focus { + position: static; + width: auto; + height: auto; + padding: 0; + margin: 0; + overflow: visible; + clip: auto; + white-space: normal; + } + + .md\:appearance-none { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + } + + .md\:bg-fixed { + background-attachment: fixed; + } + + .md\:bg-local { + background-attachment: local; + } + + .md\:bg-scroll { + background-attachment: scroll; + } + + .md\:bg-transparent { + background-color: transparent; + } + + .md\:bg-black { + background-color: #000; + } + + .md\:bg-white { + background-color: #fff; + } + + .md\:bg-gray-100 { + background-color: #f7fafc; + } + + .md\:bg-gray-200 { + background-color: #edf2f7; + } + + .md\:bg-gray-300 { + background-color: #e2e8f0; + } + + .md\:bg-gray-400 { + background-color: #cbd5e0; + } + + .md\:bg-gray-500 { + background-color: #a0aec0; + } + + .md\:bg-gray-600 { + background-color: #718096; + } + + .md\:bg-gray-700 { + background-color: #4a5568; + } + + .md\:bg-gray-800 { + background-color: #2d3748; + } + + .md\:bg-gray-900 { + background-color: #1a202c; + } + + .md\:bg-red-100 { + background-color: #fff5f5; + } + + .md\:bg-red-200 { + background-color: #fed7d7; + } + + .md\:bg-red-300 { + background-color: #feb2b2; + } + + .md\:bg-red-400 { + background-color: #fc8181; + } + + .md\:bg-red-500 { + background-color: #f56565; + } + + .md\:bg-red-600 { + background-color: #e53e3e; + } + + .md\:bg-red-700 { + background-color: #c53030; + } + + .md\:bg-red-800 { + background-color: #9b2c2c; + } + + .md\:bg-red-900 { + background-color: #742a2a; + } + + .md\:bg-orange-100 { + background-color: #fffaf0; + } + + .md\:bg-orange-200 { + background-color: #feebc8; + } + + .md\:bg-orange-300 { + background-color: #fbd38d; + } + + .md\:bg-orange-400 { + background-color: #f6ad55; + } + + .md\:bg-orange-500 { + background-color: #ed8936; + } + + .md\:bg-orange-600 { + background-color: #dd6b20; + } + + .md\:bg-orange-700 { + background-color: #c05621; + } + + .md\:bg-orange-800 { + background-color: #9c4221; + } + + .md\:bg-orange-900 { + background-color: #7b341e; + } + + .md\:bg-yellow-100 { + background-color: #fffff0; + } + + .md\:bg-yellow-200 { + background-color: #fefcbf; + } + + .md\:bg-yellow-300 { + background-color: #faf089; + } + + .md\:bg-yellow-400 { + background-color: #f6e05e; + } + + .md\:bg-yellow-500 { + background-color: #ecc94b; + } + + .md\:bg-yellow-600 { + background-color: #d69e2e; + } + + .md\:bg-yellow-700 { + background-color: #b7791f; + } + + .md\:bg-yellow-800 { + background-color: #975a16; + } + + .md\:bg-yellow-900 { + background-color: #744210; + } + + .md\:bg-green-100 { + background-color: #f0fff4; + } + + .md\:bg-green-200 { + background-color: #c6f6d5; + } + + .md\:bg-green-300 { + background-color: #9ae6b4; + } + + .md\:bg-green-400 { + background-color: #68d391; + } + + .md\:bg-green-500 { + background-color: #48bb78; + } + + .md\:bg-green-600 { + background-color: #38a169; + } + + .md\:bg-green-700 { + background-color: #2f855a; + } + + .md\:bg-green-800 { + background-color: #276749; + } + + .md\:bg-green-900 { + background-color: #22543d; + } + + .md\:bg-teal-100 { + background-color: #e6fffa; + } + + .md\:bg-teal-200 { + background-color: #b2f5ea; + } + + .md\:bg-teal-300 { + background-color: #81e6d9; + } + + .md\:bg-teal-400 { + background-color: #4fd1c5; + } + + .md\:bg-teal-500 { + background-color: #38b2ac; + } + + .md\:bg-teal-600 { + background-color: #319795; + } + + .md\:bg-teal-700 { + background-color: #2c7a7b; + } + + .md\:bg-teal-800 { + background-color: #285e61; + } + + .md\:bg-teal-900 { + background-color: #234e52; + } + + .md\:bg-blue-100 { + background-color: #ebf8ff; + } + + .md\:bg-blue-200 { + background-color: #bee3f8; + } + + .md\:bg-blue-300 { + background-color: #90cdf4; + } + + .md\:bg-blue-400 { + background-color: #63b3ed; + } + + .md\:bg-blue-500 { + background-color: #4299e1; + } + + .md\:bg-blue-600 { + background-color: #3182ce; + } + + .md\:bg-blue-700 { + background-color: #2b6cb0; + } + + .md\:bg-blue-800 { + background-color: #2c5282; + } + + .md\:bg-blue-900 { + background-color: #2a4365; + } + + .md\:bg-indigo-100 { + background-color: #ebf4ff; + } + + .md\:bg-indigo-200 { + background-color: #c3dafe; + } + + .md\:bg-indigo-300 { + background-color: #a3bffa; + } + + .md\:bg-indigo-400 { + background-color: #7f9cf5; + } + + .md\:bg-indigo-500 { + background-color: #667eea; + } + + .md\:bg-indigo-600 { + background-color: #5a67d8; + } + + .md\:bg-indigo-700 { + background-color: #4c51bf; + } + + .md\:bg-indigo-800 { + background-color: #434190; + } + + .md\:bg-indigo-900 { + background-color: #3c366b; + } + + .md\:bg-purple-100 { + background-color: #faf5ff; + } + + .md\:bg-purple-200 { + background-color: #e9d8fd; + } + + .md\:bg-purple-300 { + background-color: #d6bcfa; + } + + .md\:bg-purple-400 { + background-color: #b794f4; + } + + .md\:bg-purple-500 { + background-color: #9f7aea; + } + + .md\:bg-purple-600 { + background-color: #805ad5; + } + + .md\:bg-purple-700 { + background-color: #6b46c1; + } + + .md\:bg-purple-800 { + background-color: #553c9a; + } + + .md\:bg-purple-900 { + background-color: #44337a; + } + + .md\:bg-pink-100 { + background-color: #fff5f7; + } + + .md\:bg-pink-200 { + background-color: #fed7e2; + } + + .md\:bg-pink-300 { + background-color: #fbb6ce; + } + + .md\:bg-pink-400 { + background-color: #f687b3; + } + + .md\:bg-pink-500 { + background-color: #ed64a6; + } + + .md\:bg-pink-600 { + background-color: #d53f8c; + } + + .md\:bg-pink-700 { + background-color: #b83280; + } + + .md\:bg-pink-800 { + background-color: #97266d; + } + + .md\:bg-pink-900 { + background-color: #702459; + } + + .md\:hover\:bg-transparent:hover { + background-color: transparent; + } + + .md\:hover\:bg-black:hover { + background-color: #000; + } + + .md\:hover\:bg-white:hover { + background-color: #fff; + } + + .md\:hover\:bg-gray-100:hover { + background-color: #f7fafc; + } + + .md\:hover\:bg-gray-200:hover { + background-color: #edf2f7; + } + + .md\:hover\:bg-gray-300:hover { + background-color: #e2e8f0; + } + + .md\:hover\:bg-gray-400:hover { + background-color: #cbd5e0; + } + + .md\:hover\:bg-gray-500:hover { + background-color: #a0aec0; + } + + .md\:hover\:bg-gray-600:hover { + background-color: #718096; + } + + .md\:hover\:bg-gray-700:hover { + background-color: #4a5568; + } + + .md\:hover\:bg-gray-800:hover { + background-color: #2d3748; + } + + .md\:hover\:bg-gray-900:hover { + background-color: #1a202c; + } + + .md\:hover\:bg-red-100:hover { + background-color: #fff5f5; + } + + .md\:hover\:bg-red-200:hover { + background-color: #fed7d7; + } + + .md\:hover\:bg-red-300:hover { + background-color: #feb2b2; + } + + .md\:hover\:bg-red-400:hover { + background-color: #fc8181; + } + + .md\:hover\:bg-red-500:hover { + background-color: #f56565; + } + + .md\:hover\:bg-red-600:hover { + background-color: #e53e3e; + } + + .md\:hover\:bg-red-700:hover { + background-color: #c53030; + } + + .md\:hover\:bg-red-800:hover { + background-color: #9b2c2c; + } + + .md\:hover\:bg-red-900:hover { + background-color: #742a2a; + } + + .md\:hover\:bg-orange-100:hover { + background-color: #fffaf0; + } + + .md\:hover\:bg-orange-200:hover { + background-color: #feebc8; + } + + .md\:hover\:bg-orange-300:hover { + background-color: #fbd38d; + } + + .md\:hover\:bg-orange-400:hover { + background-color: #f6ad55; + } + + .md\:hover\:bg-orange-500:hover { + background-color: #ed8936; + } + + .md\:hover\:bg-orange-600:hover { + background-color: #dd6b20; + } + + .md\:hover\:bg-orange-700:hover { + background-color: #c05621; + } + + .md\:hover\:bg-orange-800:hover { + background-color: #9c4221; + } + + .md\:hover\:bg-orange-900:hover { + background-color: #7b341e; + } + + .md\:hover\:bg-yellow-100:hover { + background-color: #fffff0; + } + + .md\:hover\:bg-yellow-200:hover { + background-color: #fefcbf; + } + + .md\:hover\:bg-yellow-300:hover { + background-color: #faf089; + } + + .md\:hover\:bg-yellow-400:hover { + background-color: #f6e05e; + } + + .md\:hover\:bg-yellow-500:hover { + background-color: #ecc94b; + } + + .md\:hover\:bg-yellow-600:hover { + background-color: #d69e2e; + } + + .md\:hover\:bg-yellow-700:hover { + background-color: #b7791f; + } + + .md\:hover\:bg-yellow-800:hover { + background-color: #975a16; + } + + .md\:hover\:bg-yellow-900:hover { + background-color: #744210; + } + + .md\:hover\:bg-green-100:hover { + background-color: #f0fff4; + } + + .md\:hover\:bg-green-200:hover { + background-color: #c6f6d5; + } + + .md\:hover\:bg-green-300:hover { + background-color: #9ae6b4; + } + + .md\:hover\:bg-green-400:hover { + background-color: #68d391; + } + + .md\:hover\:bg-green-500:hover { + background-color: #48bb78; + } + + .md\:hover\:bg-green-600:hover { + background-color: #38a169; + } + + .md\:hover\:bg-green-700:hover { + background-color: #2f855a; + } + + .md\:hover\:bg-green-800:hover { + background-color: #276749; + } + + .md\:hover\:bg-green-900:hover { + background-color: #22543d; + } + + .md\:hover\:bg-teal-100:hover { + background-color: #e6fffa; + } + + .md\:hover\:bg-teal-200:hover { + background-color: #b2f5ea; + } + + .md\:hover\:bg-teal-300:hover { + background-color: #81e6d9; + } + + .md\:hover\:bg-teal-400:hover { + background-color: #4fd1c5; + } + + .md\:hover\:bg-teal-500:hover { + background-color: #38b2ac; + } + + .md\:hover\:bg-teal-600:hover { + background-color: #319795; + } + + .md\:hover\:bg-teal-700:hover { + background-color: #2c7a7b; + } + + .md\:hover\:bg-teal-800:hover { + background-color: #285e61; + } + + .md\:hover\:bg-teal-900:hover { + background-color: #234e52; + } + + .md\:hover\:bg-blue-100:hover { + background-color: #ebf8ff; + } + + .md\:hover\:bg-blue-200:hover { + background-color: #bee3f8; + } + + .md\:hover\:bg-blue-300:hover { + background-color: #90cdf4; + } + + .md\:hover\:bg-blue-400:hover { + background-color: #63b3ed; + } + + .md\:hover\:bg-blue-500:hover { + background-color: #4299e1; + } + + .md\:hover\:bg-blue-600:hover { + background-color: #3182ce; + } + + .md\:hover\:bg-blue-700:hover { + background-color: #2b6cb0; + } + + .md\:hover\:bg-blue-800:hover { + background-color: #2c5282; + } + + .md\:hover\:bg-blue-900:hover { + background-color: #2a4365; + } + + .md\:hover\:bg-indigo-100:hover { + background-color: #ebf4ff; + } + + .md\:hover\:bg-indigo-200:hover { + background-color: #c3dafe; + } + + .md\:hover\:bg-indigo-300:hover { + background-color: #a3bffa; + } + + .md\:hover\:bg-indigo-400:hover { + background-color: #7f9cf5; + } + + .md\:hover\:bg-indigo-500:hover { + background-color: #667eea; + } + + .md\:hover\:bg-indigo-600:hover { + background-color: #5a67d8; + } + + .md\:hover\:bg-indigo-700:hover { + background-color: #4c51bf; + } + + .md\:hover\:bg-indigo-800:hover { + background-color: #434190; + } + + .md\:hover\:bg-indigo-900:hover { + background-color: #3c366b; + } + + .md\:hover\:bg-purple-100:hover { + background-color: #faf5ff; + } + + .md\:hover\:bg-purple-200:hover { + background-color: #e9d8fd; + } + + .md\:hover\:bg-purple-300:hover { + background-color: #d6bcfa; + } + + .md\:hover\:bg-purple-400:hover { + background-color: #b794f4; + } + + .md\:hover\:bg-purple-500:hover { + background-color: #9f7aea; + } + + .md\:hover\:bg-purple-600:hover { + background-color: #805ad5; + } + + .md\:hover\:bg-purple-700:hover { + background-color: #6b46c1; + } + + .md\:hover\:bg-purple-800:hover { + background-color: #553c9a; + } + + .md\:hover\:bg-purple-900:hover { + background-color: #44337a; + } + + .md\:hover\:bg-pink-100:hover { + background-color: #fff5f7; + } + + .md\:hover\:bg-pink-200:hover { + background-color: #fed7e2; + } + + .md\:hover\:bg-pink-300:hover { + background-color: #fbb6ce; + } + + .md\:hover\:bg-pink-400:hover { + background-color: #f687b3; + } + + .md\:hover\:bg-pink-500:hover { + background-color: #ed64a6; + } + + .md\:hover\:bg-pink-600:hover { + background-color: #d53f8c; + } + + .md\:hover\:bg-pink-700:hover { + background-color: #b83280; + } + + .md\:hover\:bg-pink-800:hover { + background-color: #97266d; + } + + .md\:hover\:bg-pink-900:hover { + background-color: #702459; + } + + .md\:focus\:bg-transparent:focus { + background-color: transparent; + } + + .md\:focus\:bg-black:focus { + background-color: #000; + } + + .md\:focus\:bg-white:focus { + background-color: #fff; + } + + .md\:focus\:bg-gray-100:focus { + background-color: #f7fafc; + } + + .md\:focus\:bg-gray-200:focus { + background-color: #edf2f7; + } + + .md\:focus\:bg-gray-300:focus { + background-color: #e2e8f0; + } + + .md\:focus\:bg-gray-400:focus { + background-color: #cbd5e0; + } + + .md\:focus\:bg-gray-500:focus { + background-color: #a0aec0; + } + + .md\:focus\:bg-gray-600:focus { + background-color: #718096; + } + + .md\:focus\:bg-gray-700:focus { + background-color: #4a5568; + } + + .md\:focus\:bg-gray-800:focus { + background-color: #2d3748; + } + + .md\:focus\:bg-gray-900:focus { + background-color: #1a202c; + } + + .md\:focus\:bg-red-100:focus { + background-color: #fff5f5; + } + + .md\:focus\:bg-red-200:focus { + background-color: #fed7d7; + } + + .md\:focus\:bg-red-300:focus { + background-color: #feb2b2; + } + + .md\:focus\:bg-red-400:focus { + background-color: #fc8181; + } + + .md\:focus\:bg-red-500:focus { + background-color: #f56565; + } + + .md\:focus\:bg-red-600:focus { + background-color: #e53e3e; + } + + .md\:focus\:bg-red-700:focus { + background-color: #c53030; + } + + .md\:focus\:bg-red-800:focus { + background-color: #9b2c2c; + } + + .md\:focus\:bg-red-900:focus { + background-color: #742a2a; + } + + .md\:focus\:bg-orange-100:focus { + background-color: #fffaf0; + } + + .md\:focus\:bg-orange-200:focus { + background-color: #feebc8; + } + + .md\:focus\:bg-orange-300:focus { + background-color: #fbd38d; + } + + .md\:focus\:bg-orange-400:focus { + background-color: #f6ad55; + } + + .md\:focus\:bg-orange-500:focus { + background-color: #ed8936; + } + + .md\:focus\:bg-orange-600:focus { + background-color: #dd6b20; + } + + .md\:focus\:bg-orange-700:focus { + background-color: #c05621; + } + + .md\:focus\:bg-orange-800:focus { + background-color: #9c4221; + } + + .md\:focus\:bg-orange-900:focus { + background-color: #7b341e; + } + + .md\:focus\:bg-yellow-100:focus { + background-color: #fffff0; + } + + .md\:focus\:bg-yellow-200:focus { + background-color: #fefcbf; + } + + .md\:focus\:bg-yellow-300:focus { + background-color: #faf089; + } + + .md\:focus\:bg-yellow-400:focus { + background-color: #f6e05e; + } + + .md\:focus\:bg-yellow-500:focus { + background-color: #ecc94b; + } + + .md\:focus\:bg-yellow-600:focus { + background-color: #d69e2e; + } + + .md\:focus\:bg-yellow-700:focus { + background-color: #b7791f; + } + + .md\:focus\:bg-yellow-800:focus { + background-color: #975a16; + } + + .md\:focus\:bg-yellow-900:focus { + background-color: #744210; + } + + .md\:focus\:bg-green-100:focus { + background-color: #f0fff4; + } + + .md\:focus\:bg-green-200:focus { + background-color: #c6f6d5; + } + + .md\:focus\:bg-green-300:focus { + background-color: #9ae6b4; + } + + .md\:focus\:bg-green-400:focus { + background-color: #68d391; + } + + .md\:focus\:bg-green-500:focus { + background-color: #48bb78; + } + + .md\:focus\:bg-green-600:focus { + background-color: #38a169; + } + + .md\:focus\:bg-green-700:focus { + background-color: #2f855a; + } + + .md\:focus\:bg-green-800:focus { + background-color: #276749; + } + + .md\:focus\:bg-green-900:focus { + background-color: #22543d; + } + + .md\:focus\:bg-teal-100:focus { + background-color: #e6fffa; + } + + .md\:focus\:bg-teal-200:focus { + background-color: #b2f5ea; + } + + .md\:focus\:bg-teal-300:focus { + background-color: #81e6d9; + } + + .md\:focus\:bg-teal-400:focus { + background-color: #4fd1c5; + } + + .md\:focus\:bg-teal-500:focus { + background-color: #38b2ac; + } + + .md\:focus\:bg-teal-600:focus { + background-color: #319795; + } + + .md\:focus\:bg-teal-700:focus { + background-color: #2c7a7b; + } + + .md\:focus\:bg-teal-800:focus { + background-color: #285e61; + } + + .md\:focus\:bg-teal-900:focus { + background-color: #234e52; + } + + .md\:focus\:bg-blue-100:focus { + background-color: #ebf8ff; + } + + .md\:focus\:bg-blue-200:focus { + background-color: #bee3f8; + } + + .md\:focus\:bg-blue-300:focus { + background-color: #90cdf4; + } + + .md\:focus\:bg-blue-400:focus { + background-color: #63b3ed; + } + + .md\:focus\:bg-blue-500:focus { + background-color: #4299e1; + } + + .md\:focus\:bg-blue-600:focus { + background-color: #3182ce; + } + + .md\:focus\:bg-blue-700:focus { + background-color: #2b6cb0; + } + + .md\:focus\:bg-blue-800:focus { + background-color: #2c5282; + } + + .md\:focus\:bg-blue-900:focus { + background-color: #2a4365; + } + + .md\:focus\:bg-indigo-100:focus { + background-color: #ebf4ff; + } + + .md\:focus\:bg-indigo-200:focus { + background-color: #c3dafe; + } + + .md\:focus\:bg-indigo-300:focus { + background-color: #a3bffa; + } + + .md\:focus\:bg-indigo-400:focus { + background-color: #7f9cf5; + } + + .md\:focus\:bg-indigo-500:focus { + background-color: #667eea; + } + + .md\:focus\:bg-indigo-600:focus { + background-color: #5a67d8; + } + + .md\:focus\:bg-indigo-700:focus { + background-color: #4c51bf; + } + + .md\:focus\:bg-indigo-800:focus { + background-color: #434190; + } + + .md\:focus\:bg-indigo-900:focus { + background-color: #3c366b; + } + + .md\:focus\:bg-purple-100:focus { + background-color: #faf5ff; + } + + .md\:focus\:bg-purple-200:focus { + background-color: #e9d8fd; + } + + .md\:focus\:bg-purple-300:focus { + background-color: #d6bcfa; + } + + .md\:focus\:bg-purple-400:focus { + background-color: #b794f4; + } + + .md\:focus\:bg-purple-500:focus { + background-color: #9f7aea; + } + + .md\:focus\:bg-purple-600:focus { + background-color: #805ad5; + } + + .md\:focus\:bg-purple-700:focus { + background-color: #6b46c1; + } + + .md\:focus\:bg-purple-800:focus { + background-color: #553c9a; + } + + .md\:focus\:bg-purple-900:focus { + background-color: #44337a; + } + + .md\:focus\:bg-pink-100:focus { + background-color: #fff5f7; + } + + .md\:focus\:bg-pink-200:focus { + background-color: #fed7e2; + } + + .md\:focus\:bg-pink-300:focus { + background-color: #fbb6ce; + } + + .md\:focus\:bg-pink-400:focus { + background-color: #f687b3; + } + + .md\:focus\:bg-pink-500:focus { + background-color: #ed64a6; + } + + .md\:focus\:bg-pink-600:focus { + background-color: #d53f8c; + } + + .md\:focus\:bg-pink-700:focus { + background-color: #b83280; + } + + .md\:focus\:bg-pink-800:focus { + background-color: #97266d; + } + + .md\:focus\:bg-pink-900:focus { + background-color: #702459; + } + + .md\:bg-bottom { + background-position: bottom; + } + + .md\:bg-center { + background-position: center; + } + + .md\:bg-left { + background-position: left; + } + + .md\:bg-left-bottom { + background-position: left bottom; + } + + .md\:bg-left-top { + background-position: left top; + } + + .md\:bg-right { + background-position: right; + } + + .md\:bg-right-bottom { + background-position: right bottom; + } + + .md\:bg-right-top { + background-position: right top; + } + + .md\:bg-top { + background-position: top; + } + + .md\:bg-repeat { + background-repeat: repeat; + } + + .md\:bg-no-repeat { + background-repeat: no-repeat; + } + + .md\:bg-repeat-x { + background-repeat: repeat-x; + } + + .md\:bg-repeat-y { + background-repeat: repeat-y; + } + + .md\:bg-repeat-round { + background-repeat: round; + } + + .md\:bg-repeat-space { + background-repeat: space; + } + + .md\:bg-auto { + background-size: auto; + } + + .md\:bg-cover { + background-size: cover; + } + + .md\:bg-contain { + background-size: contain; + } + + .md\:border-collapse { + border-collapse: collapse; + } + + .md\:border-separate { + border-collapse: separate; + } + + .md\:border-transparent { + border-color: transparent; + } + + .md\:border-black { + border-color: #000; + } + + .md\:border-white { + border-color: #fff; + } + + .md\:border-gray-100 { + border-color: #f7fafc; + } + + .md\:border-gray-200 { + border-color: #edf2f7; + } + + .md\:border-gray-300 { + border-color: #e2e8f0; + } + + .md\:border-gray-400 { + border-color: #cbd5e0; + } + + .md\:border-gray-500 { + border-color: #a0aec0; + } + + .md\:border-gray-600 { + border-color: #718096; + } + + .md\:border-gray-700 { + border-color: #4a5568; + } + + .md\:border-gray-800 { + border-color: #2d3748; + } + + .md\:border-gray-900 { + border-color: #1a202c; + } + + .md\:border-red-100 { + border-color: #fff5f5; + } + + .md\:border-red-200 { + border-color: #fed7d7; + } + + .md\:border-red-300 { + border-color: #feb2b2; + } + + .md\:border-red-400 { + border-color: #fc8181; + } + + .md\:border-red-500 { + border-color: #f56565; + } + + .md\:border-red-600 { + border-color: #e53e3e; + } + + .md\:border-red-700 { + border-color: #c53030; + } + + .md\:border-red-800 { + border-color: #9b2c2c; + } + + .md\:border-red-900 { + border-color: #742a2a; + } + + .md\:border-orange-100 { + border-color: #fffaf0; + } + + .md\:border-orange-200 { + border-color: #feebc8; + } + + .md\:border-orange-300 { + border-color: #fbd38d; + } + + .md\:border-orange-400 { + border-color: #f6ad55; + } + + .md\:border-orange-500 { + border-color: #ed8936; + } + + .md\:border-orange-600 { + border-color: #dd6b20; + } + + .md\:border-orange-700 { + border-color: #c05621; + } + + .md\:border-orange-800 { + border-color: #9c4221; + } + + .md\:border-orange-900 { + border-color: #7b341e; + } + + .md\:border-yellow-100 { + border-color: #fffff0; + } + + .md\:border-yellow-200 { + border-color: #fefcbf; + } + + .md\:border-yellow-300 { + border-color: #faf089; + } + + .md\:border-yellow-400 { + border-color: #f6e05e; + } + + .md\:border-yellow-500 { + border-color: #ecc94b; + } + + .md\:border-yellow-600 { + border-color: #d69e2e; + } + + .md\:border-yellow-700 { + border-color: #b7791f; + } + + .md\:border-yellow-800 { + border-color: #975a16; + } + + .md\:border-yellow-900 { + border-color: #744210; + } + + .md\:border-green-100 { + border-color: #f0fff4; + } + + .md\:border-green-200 { + border-color: #c6f6d5; + } + + .md\:border-green-300 { + border-color: #9ae6b4; + } + + .md\:border-green-400 { + border-color: #68d391; + } + + .md\:border-green-500 { + border-color: #48bb78; + } + + .md\:border-green-600 { + border-color: #38a169; + } + + .md\:border-green-700 { + border-color: #2f855a; + } + + .md\:border-green-800 { + border-color: #276749; + } + + .md\:border-green-900 { + border-color: #22543d; + } + + .md\:border-teal-100 { + border-color: #e6fffa; + } + + .md\:border-teal-200 { + border-color: #b2f5ea; + } + + .md\:border-teal-300 { + border-color: #81e6d9; + } + + .md\:border-teal-400 { + border-color: #4fd1c5; + } + + .md\:border-teal-500 { + border-color: #38b2ac; + } + + .md\:border-teal-600 { + border-color: #319795; + } + + .md\:border-teal-700 { + border-color: #2c7a7b; + } + + .md\:border-teal-800 { + border-color: #285e61; + } + + .md\:border-teal-900 { + border-color: #234e52; + } + + .md\:border-blue-100 { + border-color: #ebf8ff; + } + + .md\:border-blue-200 { + border-color: #bee3f8; + } + + .md\:border-blue-300 { + border-color: #90cdf4; + } + + .md\:border-blue-400 { + border-color: #63b3ed; + } + + .md\:border-blue-500 { + border-color: #4299e1; + } + + .md\:border-blue-600 { + border-color: #3182ce; + } + + .md\:border-blue-700 { + border-color: #2b6cb0; + } + + .md\:border-blue-800 { + border-color: #2c5282; + } + + .md\:border-blue-900 { + border-color: #2a4365; + } + + .md\:border-indigo-100 { + border-color: #ebf4ff; + } + + .md\:border-indigo-200 { + border-color: #c3dafe; + } + + .md\:border-indigo-300 { + border-color: #a3bffa; + } + + .md\:border-indigo-400 { + border-color: #7f9cf5; + } + + .md\:border-indigo-500 { + border-color: #667eea; + } + + .md\:border-indigo-600 { + border-color: #5a67d8; + } + + .md\:border-indigo-700 { + border-color: #4c51bf; + } + + .md\:border-indigo-800 { + border-color: #434190; + } + + .md\:border-indigo-900 { + border-color: #3c366b; + } + + .md\:border-purple-100 { + border-color: #faf5ff; + } + + .md\:border-purple-200 { + border-color: #e9d8fd; + } + + .md\:border-purple-300 { + border-color: #d6bcfa; + } + + .md\:border-purple-400 { + border-color: #b794f4; + } + + .md\:border-purple-500 { + border-color: #9f7aea; + } + + .md\:border-purple-600 { + border-color: #805ad5; + } + + .md\:border-purple-700 { + border-color: #6b46c1; + } + + .md\:border-purple-800 { + border-color: #553c9a; + } + + .md\:border-purple-900 { + border-color: #44337a; + } + + .md\:border-pink-100 { + border-color: #fff5f7; + } + + .md\:border-pink-200 { + border-color: #fed7e2; + } + + .md\:border-pink-300 { + border-color: #fbb6ce; + } + + .md\:border-pink-400 { + border-color: #f687b3; + } + + .md\:border-pink-500 { + border-color: #ed64a6; + } + + .md\:border-pink-600 { + border-color: #d53f8c; + } + + .md\:border-pink-700 { + border-color: #b83280; + } + + .md\:border-pink-800 { + border-color: #97266d; + } + + .md\:border-pink-900 { + border-color: #702459; + } + + .md\:hover\:border-transparent:hover { + border-color: transparent; + } + + .md\:hover\:border-black:hover { + border-color: #000; + } + + .md\:hover\:border-white:hover { + border-color: #fff; + } + + .md\:hover\:border-gray-100:hover { + border-color: #f7fafc; + } + + .md\:hover\:border-gray-200:hover { + border-color: #edf2f7; + } + + .md\:hover\:border-gray-300:hover { + border-color: #e2e8f0; + } + + .md\:hover\:border-gray-400:hover { + border-color: #cbd5e0; + } + + .md\:hover\:border-gray-500:hover { + border-color: #a0aec0; + } + + .md\:hover\:border-gray-600:hover { + border-color: #718096; + } + + .md\:hover\:border-gray-700:hover { + border-color: #4a5568; + } + + .md\:hover\:border-gray-800:hover { + border-color: #2d3748; + } + + .md\:hover\:border-gray-900:hover { + border-color: #1a202c; + } + + .md\:hover\:border-red-100:hover { + border-color: #fff5f5; + } + + .md\:hover\:border-red-200:hover { + border-color: #fed7d7; + } + + .md\:hover\:border-red-300:hover { + border-color: #feb2b2; + } + + .md\:hover\:border-red-400:hover { + border-color: #fc8181; + } + + .md\:hover\:border-red-500:hover { + border-color: #f56565; + } + + .md\:hover\:border-red-600:hover { + border-color: #e53e3e; + } + + .md\:hover\:border-red-700:hover { + border-color: #c53030; + } + + .md\:hover\:border-red-800:hover { + border-color: #9b2c2c; + } + + .md\:hover\:border-red-900:hover { + border-color: #742a2a; + } + + .md\:hover\:border-orange-100:hover { + border-color: #fffaf0; + } + + .md\:hover\:border-orange-200:hover { + border-color: #feebc8; + } + + .md\:hover\:border-orange-300:hover { + border-color: #fbd38d; + } + + .md\:hover\:border-orange-400:hover { + border-color: #f6ad55; + } + + .md\:hover\:border-orange-500:hover { + border-color: #ed8936; + } + + .md\:hover\:border-orange-600:hover { + border-color: #dd6b20; + } + + .md\:hover\:border-orange-700:hover { + border-color: #c05621; + } + + .md\:hover\:border-orange-800:hover { + border-color: #9c4221; + } + + .md\:hover\:border-orange-900:hover { + border-color: #7b341e; + } + + .md\:hover\:border-yellow-100:hover { + border-color: #fffff0; + } + + .md\:hover\:border-yellow-200:hover { + border-color: #fefcbf; + } + + .md\:hover\:border-yellow-300:hover { + border-color: #faf089; + } + + .md\:hover\:border-yellow-400:hover { + border-color: #f6e05e; + } + + .md\:hover\:border-yellow-500:hover { + border-color: #ecc94b; + } + + .md\:hover\:border-yellow-600:hover { + border-color: #d69e2e; + } + + .md\:hover\:border-yellow-700:hover { + border-color: #b7791f; + } + + .md\:hover\:border-yellow-800:hover { + border-color: #975a16; + } + + .md\:hover\:border-yellow-900:hover { + border-color: #744210; + } + + .md\:hover\:border-green-100:hover { + border-color: #f0fff4; + } + + .md\:hover\:border-green-200:hover { + border-color: #c6f6d5; + } + + .md\:hover\:border-green-300:hover { + border-color: #9ae6b4; + } + + .md\:hover\:border-green-400:hover { + border-color: #68d391; + } + + .md\:hover\:border-green-500:hover { + border-color: #48bb78; + } + + .md\:hover\:border-green-600:hover { + border-color: #38a169; + } + + .md\:hover\:border-green-700:hover { + border-color: #2f855a; + } + + .md\:hover\:border-green-800:hover { + border-color: #276749; + } + + .md\:hover\:border-green-900:hover { + border-color: #22543d; + } + + .md\:hover\:border-teal-100:hover { + border-color: #e6fffa; + } + + .md\:hover\:border-teal-200:hover { + border-color: #b2f5ea; + } + + .md\:hover\:border-teal-300:hover { + border-color: #81e6d9; + } + + .md\:hover\:border-teal-400:hover { + border-color: #4fd1c5; + } + + .md\:hover\:border-teal-500:hover { + border-color: #38b2ac; + } + + .md\:hover\:border-teal-600:hover { + border-color: #319795; + } + + .md\:hover\:border-teal-700:hover { + border-color: #2c7a7b; + } + + .md\:hover\:border-teal-800:hover { + border-color: #285e61; + } + + .md\:hover\:border-teal-900:hover { + border-color: #234e52; + } + + .md\:hover\:border-blue-100:hover { + border-color: #ebf8ff; + } + + .md\:hover\:border-blue-200:hover { + border-color: #bee3f8; + } + + .md\:hover\:border-blue-300:hover { + border-color: #90cdf4; + } + + .md\:hover\:border-blue-400:hover { + border-color: #63b3ed; + } + + .md\:hover\:border-blue-500:hover { + border-color: #4299e1; + } + + .md\:hover\:border-blue-600:hover { + border-color: #3182ce; + } + + .md\:hover\:border-blue-700:hover { + border-color: #2b6cb0; + } + + .md\:hover\:border-blue-800:hover { + border-color: #2c5282; + } + + .md\:hover\:border-blue-900:hover { + border-color: #2a4365; + } + + .md\:hover\:border-indigo-100:hover { + border-color: #ebf4ff; + } + + .md\:hover\:border-indigo-200:hover { + border-color: #c3dafe; + } + + .md\:hover\:border-indigo-300:hover { + border-color: #a3bffa; + } + + .md\:hover\:border-indigo-400:hover { + border-color: #7f9cf5; + } + + .md\:hover\:border-indigo-500:hover { + border-color: #667eea; + } + + .md\:hover\:border-indigo-600:hover { + border-color: #5a67d8; + } + + .md\:hover\:border-indigo-700:hover { + border-color: #4c51bf; + } + + .md\:hover\:border-indigo-800:hover { + border-color: #434190; + } + + .md\:hover\:border-indigo-900:hover { + border-color: #3c366b; + } + + .md\:hover\:border-purple-100:hover { + border-color: #faf5ff; + } + + .md\:hover\:border-purple-200:hover { + border-color: #e9d8fd; + } + + .md\:hover\:border-purple-300:hover { + border-color: #d6bcfa; + } + + .md\:hover\:border-purple-400:hover { + border-color: #b794f4; + } + + .md\:hover\:border-purple-500:hover { + border-color: #9f7aea; + } + + .md\:hover\:border-purple-600:hover { + border-color: #805ad5; + } + + .md\:hover\:border-purple-700:hover { + border-color: #6b46c1; + } + + .md\:hover\:border-purple-800:hover { + border-color: #553c9a; + } + + .md\:hover\:border-purple-900:hover { + border-color: #44337a; + } + + .md\:hover\:border-pink-100:hover { + border-color: #fff5f7; + } + + .md\:hover\:border-pink-200:hover { + border-color: #fed7e2; + } + + .md\:hover\:border-pink-300:hover { + border-color: #fbb6ce; + } + + .md\:hover\:border-pink-400:hover { + border-color: #f687b3; + } + + .md\:hover\:border-pink-500:hover { + border-color: #ed64a6; + } + + .md\:hover\:border-pink-600:hover { + border-color: #d53f8c; + } + + .md\:hover\:border-pink-700:hover { + border-color: #b83280; + } + + .md\:hover\:border-pink-800:hover { + border-color: #97266d; + } + + .md\:hover\:border-pink-900:hover { + border-color: #702459; + } + + .md\:focus\:border-transparent:focus { + border-color: transparent; + } + + .md\:focus\:border-black:focus { + border-color: #000; + } + + .md\:focus\:border-white:focus { + border-color: #fff; + } + + .md\:focus\:border-gray-100:focus { + border-color: #f7fafc; + } + + .md\:focus\:border-gray-200:focus { + border-color: #edf2f7; + } + + .md\:focus\:border-gray-300:focus { + border-color: #e2e8f0; + } + + .md\:focus\:border-gray-400:focus { + border-color: #cbd5e0; + } + + .md\:focus\:border-gray-500:focus { + border-color: #a0aec0; + } + + .md\:focus\:border-gray-600:focus { + border-color: #718096; + } + + .md\:focus\:border-gray-700:focus { + border-color: #4a5568; + } + + .md\:focus\:border-gray-800:focus { + border-color: #2d3748; + } + + .md\:focus\:border-gray-900:focus { + border-color: #1a202c; + } + + .md\:focus\:border-red-100:focus { + border-color: #fff5f5; + } + + .md\:focus\:border-red-200:focus { + border-color: #fed7d7; + } + + .md\:focus\:border-red-300:focus { + border-color: #feb2b2; + } + + .md\:focus\:border-red-400:focus { + border-color: #fc8181; + } + + .md\:focus\:border-red-500:focus { + border-color: #f56565; + } + + .md\:focus\:border-red-600:focus { + border-color: #e53e3e; + } + + .md\:focus\:border-red-700:focus { + border-color: #c53030; + } + + .md\:focus\:border-red-800:focus { + border-color: #9b2c2c; + } + + .md\:focus\:border-red-900:focus { + border-color: #742a2a; + } + + .md\:focus\:border-orange-100:focus { + border-color: #fffaf0; + } + + .md\:focus\:border-orange-200:focus { + border-color: #feebc8; + } + + .md\:focus\:border-orange-300:focus { + border-color: #fbd38d; + } + + .md\:focus\:border-orange-400:focus { + border-color: #f6ad55; + } + + .md\:focus\:border-orange-500:focus { + border-color: #ed8936; + } + + .md\:focus\:border-orange-600:focus { + border-color: #dd6b20; + } + + .md\:focus\:border-orange-700:focus { + border-color: #c05621; + } + + .md\:focus\:border-orange-800:focus { + border-color: #9c4221; + } + + .md\:focus\:border-orange-900:focus { + border-color: #7b341e; + } + + .md\:focus\:border-yellow-100:focus { + border-color: #fffff0; + } + + .md\:focus\:border-yellow-200:focus { + border-color: #fefcbf; + } + + .md\:focus\:border-yellow-300:focus { + border-color: #faf089; + } + + .md\:focus\:border-yellow-400:focus { + border-color: #f6e05e; + } + + .md\:focus\:border-yellow-500:focus { + border-color: #ecc94b; + } + + .md\:focus\:border-yellow-600:focus { + border-color: #d69e2e; + } + + .md\:focus\:border-yellow-700:focus { + border-color: #b7791f; + } + + .md\:focus\:border-yellow-800:focus { + border-color: #975a16; + } + + .md\:focus\:border-yellow-900:focus { + border-color: #744210; + } + + .md\:focus\:border-green-100:focus { + border-color: #f0fff4; + } + + .md\:focus\:border-green-200:focus { + border-color: #c6f6d5; + } + + .md\:focus\:border-green-300:focus { + border-color: #9ae6b4; + } + + .md\:focus\:border-green-400:focus { + border-color: #68d391; + } + + .md\:focus\:border-green-500:focus { + border-color: #48bb78; + } + + .md\:focus\:border-green-600:focus { + border-color: #38a169; + } + + .md\:focus\:border-green-700:focus { + border-color: #2f855a; + } + + .md\:focus\:border-green-800:focus { + border-color: #276749; + } + + .md\:focus\:border-green-900:focus { + border-color: #22543d; + } + + .md\:focus\:border-teal-100:focus { + border-color: #e6fffa; + } + + .md\:focus\:border-teal-200:focus { + border-color: #b2f5ea; + } + + .md\:focus\:border-teal-300:focus { + border-color: #81e6d9; + } + + .md\:focus\:border-teal-400:focus { + border-color: #4fd1c5; + } + + .md\:focus\:border-teal-500:focus { + border-color: #38b2ac; + } + + .md\:focus\:border-teal-600:focus { + border-color: #319795; + } + + .md\:focus\:border-teal-700:focus { + border-color: #2c7a7b; + } + + .md\:focus\:border-teal-800:focus { + border-color: #285e61; + } + + .md\:focus\:border-teal-900:focus { + border-color: #234e52; + } + + .md\:focus\:border-blue-100:focus { + border-color: #ebf8ff; + } + + .md\:focus\:border-blue-200:focus { + border-color: #bee3f8; + } + + .md\:focus\:border-blue-300:focus { + border-color: #90cdf4; + } + + .md\:focus\:border-blue-400:focus { + border-color: #63b3ed; + } + + .md\:focus\:border-blue-500:focus { + border-color: #4299e1; + } + + .md\:focus\:border-blue-600:focus { + border-color: #3182ce; + } + + .md\:focus\:border-blue-700:focus { + border-color: #2b6cb0; + } + + .md\:focus\:border-blue-800:focus { + border-color: #2c5282; + } + + .md\:focus\:border-blue-900:focus { + border-color: #2a4365; + } + + .md\:focus\:border-indigo-100:focus { + border-color: #ebf4ff; + } + + .md\:focus\:border-indigo-200:focus { + border-color: #c3dafe; + } + + .md\:focus\:border-indigo-300:focus { + border-color: #a3bffa; + } + + .md\:focus\:border-indigo-400:focus { + border-color: #7f9cf5; + } + + .md\:focus\:border-indigo-500:focus { + border-color: #667eea; + } + + .md\:focus\:border-indigo-600:focus { + border-color: #5a67d8; + } + + .md\:focus\:border-indigo-700:focus { + border-color: #4c51bf; + } + + .md\:focus\:border-indigo-800:focus { + border-color: #434190; + } + + .md\:focus\:border-indigo-900:focus { + border-color: #3c366b; + } + + .md\:focus\:border-purple-100:focus { + border-color: #faf5ff; + } + + .md\:focus\:border-purple-200:focus { + border-color: #e9d8fd; + } + + .md\:focus\:border-purple-300:focus { + border-color: #d6bcfa; + } + + .md\:focus\:border-purple-400:focus { + border-color: #b794f4; + } + + .md\:focus\:border-purple-500:focus { + border-color: #9f7aea; + } + + .md\:focus\:border-purple-600:focus { + border-color: #805ad5; + } + + .md\:focus\:border-purple-700:focus { + border-color: #6b46c1; + } + + .md\:focus\:border-purple-800:focus { + border-color: #553c9a; + } + + .md\:focus\:border-purple-900:focus { + border-color: #44337a; + } + + .md\:focus\:border-pink-100:focus { + border-color: #fff5f7; + } + + .md\:focus\:border-pink-200:focus { + border-color: #fed7e2; + } + + .md\:focus\:border-pink-300:focus { + border-color: #fbb6ce; + } + + .md\:focus\:border-pink-400:focus { + border-color: #f687b3; + } + + .md\:focus\:border-pink-500:focus { + border-color: #ed64a6; + } + + .md\:focus\:border-pink-600:focus { + border-color: #d53f8c; + } + + .md\:focus\:border-pink-700:focus { + border-color: #b83280; + } + + .md\:focus\:border-pink-800:focus { + border-color: #97266d; + } + + .md\:focus\:border-pink-900:focus { + border-color: #702459; + } + + .md\:rounded-none { + border-radius: 0; + } + + .md\:rounded-sm { + border-radius: 0.125rem; + } + + .md\:rounded { + border-radius: 0.25rem; + } + + .md\:rounded-md { + border-radius: 0.375rem; + } + + .md\:rounded-lg { + border-radius: 0.5rem; + } + + .md\:rounded-full { + border-radius: 9999px; + } + + .md\:rounded-t-none { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + + .md\:rounded-r-none { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .md\:rounded-b-none { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } + + .md\:rounded-l-none { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + + .md\:rounded-t-sm { + border-top-left-radius: 0.125rem; + border-top-right-radius: 0.125rem; + } + + .md\:rounded-r-sm { + border-top-right-radius: 0.125rem; + border-bottom-right-radius: 0.125rem; + } + + .md\:rounded-b-sm { + border-bottom-right-radius: 0.125rem; + border-bottom-left-radius: 0.125rem; + } + + .md\:rounded-l-sm { + border-top-left-radius: 0.125rem; + border-bottom-left-radius: 0.125rem; + } + + .md\:rounded-t { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; + } + + .md\:rounded-r { + border-top-right-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; + } + + .md\:rounded-b { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + } + + .md\:rounded-l { + border-top-left-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + } + + .md\:rounded-t-md { + border-top-left-radius: 0.375rem; + border-top-right-radius: 0.375rem; + } + + .md\:rounded-r-md { + border-top-right-radius: 0.375rem; + border-bottom-right-radius: 0.375rem; + } + + .md\:rounded-b-md { + border-bottom-right-radius: 0.375rem; + border-bottom-left-radius: 0.375rem; + } + + .md\:rounded-l-md { + border-top-left-radius: 0.375rem; + border-bottom-left-radius: 0.375rem; + } + + .md\:rounded-t-lg { + border-top-left-radius: 0.5rem; + border-top-right-radius: 0.5rem; + } + + .md\:rounded-r-lg { + border-top-right-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; + } + + .md\:rounded-b-lg { + border-bottom-right-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; + } + + .md\:rounded-l-lg { + border-top-left-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; + } + + .md\:rounded-t-full { + border-top-left-radius: 9999px; + border-top-right-radius: 9999px; + } + + .md\:rounded-r-full { + border-top-right-radius: 9999px; + border-bottom-right-radius: 9999px; + } + + .md\:rounded-b-full { + border-bottom-right-radius: 9999px; + border-bottom-left-radius: 9999px; + } + + .md\:rounded-l-full { + border-top-left-radius: 9999px; + border-bottom-left-radius: 9999px; + } + + .md\:rounded-tl-none { + border-top-left-radius: 0; + } + + .md\:rounded-tr-none { + border-top-right-radius: 0; + } + + .md\:rounded-br-none { + border-bottom-right-radius: 0; + } + + .md\:rounded-bl-none { + border-bottom-left-radius: 0; + } + + .md\:rounded-tl-sm { + border-top-left-radius: 0.125rem; + } + + .md\:rounded-tr-sm { + border-top-right-radius: 0.125rem; + } + + .md\:rounded-br-sm { + border-bottom-right-radius: 0.125rem; + } + + .md\:rounded-bl-sm { + border-bottom-left-radius: 0.125rem; + } + + .md\:rounded-tl { + border-top-left-radius: 0.25rem; + } + + .md\:rounded-tr { + border-top-right-radius: 0.25rem; + } + + .md\:rounded-br { + border-bottom-right-radius: 0.25rem; + } + + .md\:rounded-bl { + border-bottom-left-radius: 0.25rem; + } + + .md\:rounded-tl-md { + border-top-left-radius: 0.375rem; + } + + .md\:rounded-tr-md { + border-top-right-radius: 0.375rem; + } + + .md\:rounded-br-md { + border-bottom-right-radius: 0.375rem; + } + + .md\:rounded-bl-md { + border-bottom-left-radius: 0.375rem; + } + + .md\:rounded-tl-lg { + border-top-left-radius: 0.5rem; + } + + .md\:rounded-tr-lg { + border-top-right-radius: 0.5rem; + } + + .md\:rounded-br-lg { + border-bottom-right-radius: 0.5rem; + } + + .md\:rounded-bl-lg { + border-bottom-left-radius: 0.5rem; + } + + .md\:rounded-tl-full { + border-top-left-radius: 9999px; + } + + .md\:rounded-tr-full { + border-top-right-radius: 9999px; + } + + .md\:rounded-br-full { + border-bottom-right-radius: 9999px; + } + + .md\:rounded-bl-full { + border-bottom-left-radius: 9999px; + } + + .md\:border-solid { + border-style: solid; + } + + .md\:border-dashed { + border-style: dashed; + } + + .md\:border-dotted { + border-style: dotted; + } + + .md\:border-double { + border-style: double; + } + + .md\:border-none { + border-style: none; + } + + .md\:border-0 { + border-width: 0; + } + + .md\:border-2 { + border-width: 2px; + } + + .md\:border-4 { + border-width: 4px; + } + + .md\:border-8 { + border-width: 8px; + } + + .md\:border { + border-width: 1px; + } + + .md\:border-t-0 { + border-top-width: 0; + } + + .md\:border-r-0 { + border-right-width: 0; + } + + .md\:border-b-0 { + border-bottom-width: 0; + } + + .md\:border-l-0 { + border-left-width: 0; + } + + .md\:border-t-2 { + border-top-width: 2px; + } + + .md\:border-r-2 { + border-right-width: 2px; + } + + .md\:border-b-2 { + border-bottom-width: 2px; + } + + .md\:border-l-2 { + border-left-width: 2px; + } + + .md\:border-t-4 { + border-top-width: 4px; + } + + .md\:border-r-4 { + border-right-width: 4px; + } + + .md\:border-b-4 { + border-bottom-width: 4px; + } + + .md\:border-l-4 { + border-left-width: 4px; + } + + .md\:border-t-8 { + border-top-width: 8px; + } + + .md\:border-r-8 { + border-right-width: 8px; + } + + .md\:border-b-8 { + border-bottom-width: 8px; + } + + .md\:border-l-8 { + border-left-width: 8px; + } + + .md\:border-t { + border-top-width: 1px; + } + + .md\:border-r { + border-right-width: 1px; + } + + .md\:border-b { + border-bottom-width: 1px; + } + + .md\:border-l { + border-left-width: 1px; + } + + .md\:box-border { + box-sizing: border-box; + } + + .md\:box-content { + box-sizing: content-box; + } + + .md\:cursor-auto { + cursor: auto; + } + + .md\:cursor-default { + cursor: default; + } + + .md\:cursor-pointer { + cursor: pointer; + } + + .md\:cursor-wait { + cursor: wait; + } + + .md\:cursor-text { + cursor: text; + } + + .md\:cursor-move { + cursor: move; + } + + .md\:cursor-not-allowed { + cursor: not-allowed; + } + + .md\:block { + display: block; + } + + .md\:inline-block { + display: inline-block; + } + + .md\:inline { + display: inline; + } + + .md\:flex { + display: flex; + } + + .md\:inline-flex { + display: inline-flex; + } + + .md\:grid { + display: grid; + } + + .md\:table { + display: table; + } + + .md\:table-caption { + display: table-caption; + } + + .md\:table-cell { + display: table-cell; + } + + .md\:table-column { + display: table-column; + } + + .md\:table-column-group { + display: table-column-group; + } + + .md\:table-footer-group { + display: table-footer-group; + } + + .md\:table-header-group { + display: table-header-group; + } + + .md\:table-row-group { + display: table-row-group; + } + + .md\:table-row { + display: table-row; + } + + .md\:hidden { + display: none; + } + + .md\:flex-row { + flex-direction: row; + } + + .md\:flex-row-reverse { + flex-direction: row-reverse; + } + + .md\:flex-col { + flex-direction: column; + } + + .md\:flex-col-reverse { + flex-direction: column-reverse; + } + + .md\:flex-wrap { + flex-wrap: wrap; + } + + .md\:flex-wrap-reverse { + flex-wrap: wrap-reverse; + } + + .md\:flex-no-wrap { + flex-wrap: nowrap; + } + + .md\:items-start { + align-items: flex-start; + } + + .md\:items-end { + align-items: flex-end; + } + + .md\:items-center { + align-items: center; + } + + .md\:items-baseline { + align-items: baseline; + } + + .md\:items-stretch { + align-items: stretch; + } + + .md\:self-auto { + align-self: auto; + } + + .md\:self-start { + align-self: flex-start; + } + + .md\:self-end { + align-self: flex-end; + } + + .md\:self-center { + align-self: center; + } + + .md\:self-stretch { + align-self: stretch; + } + + .md\:justify-start { + justify-content: flex-start; + } + + .md\:justify-end { + justify-content: flex-end; + } + + .md\:justify-center { + justify-content: center; + } + + .md\:justify-between { + justify-content: space-between; + } + + .md\:justify-around { + justify-content: space-around; + } + + .md\:justify-evenly { + justify-content: space-evenly; + } + + .md\:content-center { + align-content: center; + } + + .md\:content-start { + align-content: flex-start; + } + + .md\:content-end { + align-content: flex-end; + } + + .md\:content-between { + align-content: space-between; + } + + .md\:content-around { + align-content: space-around; + } + + .md\:flex-1 { + flex: 1 1 0%; + } + + .md\:flex-auto { + flex: 1 1 auto; + } + + .md\:flex-initial { + flex: 0 1 auto; + } + + .md\:flex-none { + flex: none; + } + + .md\:flex-grow-0 { + flex-grow: 0; + } + + .md\:flex-grow { + flex-grow: 1; + } + + .md\:flex-shrink-0 { + flex-shrink: 0; + } + + .md\:flex-shrink { + flex-shrink: 1; + } + + .md\:order-1 { + order: 1; + } + + .md\:order-2 { + order: 2; + } + + .md\:order-3 { + order: 3; + } + + .md\:order-4 { + order: 4; + } + + .md\:order-5 { + order: 5; + } + + .md\:order-6 { + order: 6; + } + + .md\:order-7 { + order: 7; + } + + .md\:order-8 { + order: 8; + } + + .md\:order-9 { + order: 9; + } + + .md\:order-10 { + order: 10; + } + + .md\:order-11 { + order: 11; + } + + .md\:order-12 { + order: 12; + } + + .md\:order-first { + order: -9999; + } + + .md\:order-last { + order: 9999; + } + + .md\:order-none { + order: 0; + } + + .md\:float-right { + float: right; + } + + .md\:float-left { + float: left; + } + + .md\:float-none { + float: none; + } + + .md\:clearfix:after { + content: ""; + display: table; + clear: both; + } + + .md\:clear-left { + clear: left; + } + + .md\:clear-right { + clear: right; + } + + .md\:clear-both { + clear: both; + } + + .md\:font-sans { + font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + } + + .md\:font-serif { + font-family: Georgia, Cambria, "Times New Roman", Times, serif; + } + + .md\:font-mono { + font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + } + + .md\:font-hairline { + font-weight: 100; + } + + .md\:font-thin { + font-weight: 200; + } + + .md\:font-light { + font-weight: 300; + } + + .md\:font-normal { + font-weight: 400; + } + + .md\:font-medium { + font-weight: 500; + } + + .md\:font-semibold { + font-weight: 600; + } + + .md\:font-bold { + font-weight: 700; + } + + .md\:font-extrabold { + font-weight: 800; + } + + .md\:font-black { + font-weight: 900; + } + + .md\:hover\:font-hairline:hover { + font-weight: 100; + } + + .md\:hover\:font-thin:hover { + font-weight: 200; + } + + .md\:hover\:font-light:hover { + font-weight: 300; + } + + .md\:hover\:font-normal:hover { + font-weight: 400; + } + + .md\:hover\:font-medium:hover { + font-weight: 500; + } + + .md\:hover\:font-semibold:hover { + font-weight: 600; + } + + .md\:hover\:font-bold:hover { + font-weight: 700; + } + + .md\:hover\:font-extrabold:hover { + font-weight: 800; + } + + .md\:hover\:font-black:hover { + font-weight: 900; + } + + .md\:focus\:font-hairline:focus { + font-weight: 100; + } + + .md\:focus\:font-thin:focus { + font-weight: 200; + } + + .md\:focus\:font-light:focus { + font-weight: 300; + } + + .md\:focus\:font-normal:focus { + font-weight: 400; + } + + .md\:focus\:font-medium:focus { + font-weight: 500; + } + + .md\:focus\:font-semibold:focus { + font-weight: 600; + } + + .md\:focus\:font-bold:focus { + font-weight: 700; + } + + .md\:focus\:font-extrabold:focus { + font-weight: 800; + } + + .md\:focus\:font-black:focus { + font-weight: 900; + } + + .md\:h-0 { + height: 0; + } + + .md\:h-1 { + height: 0.25rem; + } + + .md\:h-2 { + height: 0.5rem; + } + + .md\:h-3 { + height: 0.75rem; + } + + .md\:h-4 { + height: 1rem; + } + + .md\:h-5 { + height: 1.25rem; + } + + .md\:h-6 { + height: 1.5rem; + } + + .md\:h-8 { + height: 2rem; + } + + .md\:h-10 { + height: 2.5rem; + } + + .md\:h-12 { + height: 3rem; + } + + .md\:h-16 { + height: 4rem; + } + + .md\:h-20 { + height: 5rem; + } + + .md\:h-24 { + height: 6rem; + } + + .md\:h-32 { + height: 8rem; + } + + .md\:h-40 { + height: 10rem; + } + + .md\:h-48 { + height: 12rem; + } + + .md\:h-56 { + height: 14rem; + } + + .md\:h-64 { + height: 16rem; + } + + .md\:h-auto { + height: auto; + } + + .md\:h-px { + height: 1px; + } + + .md\:h-full { + height: 100%; + } + + .md\:h-screen { + height: 100vh; + } + + .md\:leading-3 { + line-height: .75rem; + } + + .md\:leading-4 { + line-height: 1rem; + } + + .md\:leading-5 { + line-height: 1.25rem; + } + + .md\:leading-6 { + line-height: 1.5rem; + } + + .md\:leading-7 { + line-height: 1.75rem; + } + + .md\:leading-8 { + line-height: 2rem; + } + + .md\:leading-9 { + line-height: 2.25rem; + } + + .md\:leading-10 { + line-height: 2.5rem; + } + + .md\:leading-none { + line-height: 1; + } + + .md\:leading-tight { + line-height: 1.25; + } + + .md\:leading-snug { + line-height: 1.375; + } + + .md\:leading-normal { + line-height: 1.5; + } + + .md\:leading-relaxed { + line-height: 1.625; + } + + .md\:leading-loose { + line-height: 2; + } + + .md\:list-inside { + list-style-position: inside; + } + + .md\:list-outside { + list-style-position: outside; + } + + .md\:list-none { + list-style-type: none; + } + + .md\:list-disc { + list-style-type: disc; + } + + .md\:list-decimal { + list-style-type: decimal; + } + + .md\:m-0 { + margin: 0; + } + + .md\:m-1 { + margin: 0.25rem; + } + + .md\:m-2 { + margin: 0.5rem; + } + + .md\:m-3 { + margin: 0.75rem; + } + + .md\:m-4 { + margin: 1rem; + } + + .md\:m-5 { + margin: 1.25rem; + } + + .md\:m-6 { + margin: 1.5rem; + } + + .md\:m-8 { + margin: 2rem; + } + + .md\:m-10 { + margin: 2.5rem; + } + + .md\:m-12 { + margin: 3rem; + } + + .md\:m-16 { + margin: 4rem; + } + + .md\:m-20 { + margin: 5rem; + } + + .md\:m-24 { + margin: 6rem; + } + + .md\:m-32 { + margin: 8rem; + } + + .md\:m-40 { + margin: 10rem; + } + + .md\:m-48 { + margin: 12rem; + } + + .md\:m-56 { + margin: 14rem; + } + + .md\:m-64 { + margin: 16rem; + } + + .md\:m-auto { + margin: auto; + } + + .md\:m-px { + margin: 1px; + } + + .md\:-m-1 { + margin: -0.25rem; + } + + .md\:-m-2 { + margin: -0.5rem; + } + + .md\:-m-3 { + margin: -0.75rem; + } + + .md\:-m-4 { + margin: -1rem; + } + + .md\:-m-5 { + margin: -1.25rem; + } + + .md\:-m-6 { + margin: -1.5rem; + } + + .md\:-m-8 { + margin: -2rem; + } + + .md\:-m-10 { + margin: -2.5rem; + } + + .md\:-m-12 { + margin: -3rem; + } + + .md\:-m-16 { + margin: -4rem; + } + + .md\:-m-20 { + margin: -5rem; + } + + .md\:-m-24 { + margin: -6rem; + } + + .md\:-m-32 { + margin: -8rem; + } + + .md\:-m-40 { + margin: -10rem; + } + + .md\:-m-48 { + margin: -12rem; + } + + .md\:-m-56 { + margin: -14rem; + } + + .md\:-m-64 { + margin: -16rem; + } + + .md\:-m-px { + margin: -1px; + } + + .md\:my-0 { + margin-top: 0; + margin-bottom: 0; + } + + .md\:mx-0 { + margin-left: 0; + margin-right: 0; + } + + .md\:my-1 { + margin-top: 0.25rem; + margin-bottom: 0.25rem; + } + + .md\:mx-1 { + margin-left: 0.25rem; + margin-right: 0.25rem; + } + + .md\:my-2 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; + } + + .md\:mx-2 { + margin-left: 0.5rem; + margin-right: 0.5rem; + } + + .md\:my-3 { + margin-top: 0.75rem; + margin-bottom: 0.75rem; + } + + .md\:mx-3 { + margin-left: 0.75rem; + margin-right: 0.75rem; + } + + .md\:my-4 { + margin-top: 1rem; + margin-bottom: 1rem; + } + + .md\:mx-4 { + margin-left: 1rem; + margin-right: 1rem; + } + + .md\:my-5 { + margin-top: 1.25rem; + margin-bottom: 1.25rem; + } + + .md\:mx-5 { + margin-left: 1.25rem; + margin-right: 1.25rem; + } + + .md\:my-6 { + margin-top: 1.5rem; + margin-bottom: 1.5rem; + } + + .md\:mx-6 { + margin-left: 1.5rem; + margin-right: 1.5rem; + } + + .md\:my-8 { + margin-top: 2rem; + margin-bottom: 2rem; + } + + .md\:mx-8 { + margin-left: 2rem; + margin-right: 2rem; + } + + .md\:my-10 { + margin-top: 2.5rem; + margin-bottom: 2.5rem; + } + + .md\:mx-10 { + margin-left: 2.5rem; + margin-right: 2.5rem; + } + + .md\:my-12 { + margin-top: 3rem; + margin-bottom: 3rem; + } + + .md\:mx-12 { + margin-left: 3rem; + margin-right: 3rem; + } + + .md\:my-16 { + margin-top: 4rem; + margin-bottom: 4rem; + } + + .md\:mx-16 { + margin-left: 4rem; + margin-right: 4rem; + } + + .md\:my-20 { + margin-top: 5rem; + margin-bottom: 5rem; + } + + .md\:mx-20 { + margin-left: 5rem; + margin-right: 5rem; + } + + .md\:my-24 { + margin-top: 6rem; + margin-bottom: 6rem; + } + + .md\:mx-24 { + margin-left: 6rem; + margin-right: 6rem; + } + + .md\:my-32 { + margin-top: 8rem; + margin-bottom: 8rem; + } + + .md\:mx-32 { + margin-left: 8rem; + margin-right: 8rem; + } + + .md\:my-40 { + margin-top: 10rem; + margin-bottom: 10rem; + } + + .md\:mx-40 { + margin-left: 10rem; + margin-right: 10rem; + } + + .md\:my-48 { + margin-top: 12rem; + margin-bottom: 12rem; + } + + .md\:mx-48 { + margin-left: 12rem; + margin-right: 12rem; + } + + .md\:my-56 { + margin-top: 14rem; + margin-bottom: 14rem; + } + + .md\:mx-56 { + margin-left: 14rem; + margin-right: 14rem; + } + + .md\:my-64 { + margin-top: 16rem; + margin-bottom: 16rem; + } + + .md\:mx-64 { + margin-left: 16rem; + margin-right: 16rem; + } + + .md\:my-auto { + margin-top: auto; + margin-bottom: auto; + } + + .md\:mx-auto { + margin-left: auto; + margin-right: auto; + } + + .md\:my-px { + margin-top: 1px; + margin-bottom: 1px; + } + + .md\:mx-px { + margin-left: 1px; + margin-right: 1px; + } + + .md\:-my-1 { + margin-top: -0.25rem; + margin-bottom: -0.25rem; + } + + .md\:-mx-1 { + margin-left: -0.25rem; + margin-right: -0.25rem; + } + + .md\:-my-2 { + margin-top: -0.5rem; + margin-bottom: -0.5rem; + } + + .md\:-mx-2 { + margin-left: -0.5rem; + margin-right: -0.5rem; + } + + .md\:-my-3 { + margin-top: -0.75rem; + margin-bottom: -0.75rem; + } + + .md\:-mx-3 { + margin-left: -0.75rem; + margin-right: -0.75rem; + } + + .md\:-my-4 { + margin-top: -1rem; + margin-bottom: -1rem; + } + + .md\:-mx-4 { + margin-left: -1rem; + margin-right: -1rem; + } + + .md\:-my-5 { + margin-top: -1.25rem; + margin-bottom: -1.25rem; + } + + .md\:-mx-5 { + margin-left: -1.25rem; + margin-right: -1.25rem; + } + + .md\:-my-6 { + margin-top: -1.5rem; + margin-bottom: -1.5rem; + } + + .md\:-mx-6 { + margin-left: -1.5rem; + margin-right: -1.5rem; + } + + .md\:-my-8 { + margin-top: -2rem; + margin-bottom: -2rem; + } + + .md\:-mx-8 { + margin-left: -2rem; + margin-right: -2rem; + } + + .md\:-my-10 { + margin-top: -2.5rem; + margin-bottom: -2.5rem; + } + + .md\:-mx-10 { + margin-left: -2.5rem; + margin-right: -2.5rem; + } + + .md\:-my-12 { + margin-top: -3rem; + margin-bottom: -3rem; + } + + .md\:-mx-12 { + margin-left: -3rem; + margin-right: -3rem; + } + + .md\:-my-16 { + margin-top: -4rem; + margin-bottom: -4rem; + } + + .md\:-mx-16 { + margin-left: -4rem; + margin-right: -4rem; + } + + .md\:-my-20 { + margin-top: -5rem; + margin-bottom: -5rem; + } + + .md\:-mx-20 { + margin-left: -5rem; + margin-right: -5rem; + } + + .md\:-my-24 { + margin-top: -6rem; + margin-bottom: -6rem; + } + + .md\:-mx-24 { + margin-left: -6rem; + margin-right: -6rem; + } + + .md\:-my-32 { + margin-top: -8rem; + margin-bottom: -8rem; + } + + .md\:-mx-32 { + margin-left: -8rem; + margin-right: -8rem; + } + + .md\:-my-40 { + margin-top: -10rem; + margin-bottom: -10rem; + } + + .md\:-mx-40 { + margin-left: -10rem; + margin-right: -10rem; + } + + .md\:-my-48 { + margin-top: -12rem; + margin-bottom: -12rem; + } + + .md\:-mx-48 { + margin-left: -12rem; + margin-right: -12rem; + } + + .md\:-my-56 { + margin-top: -14rem; + margin-bottom: -14rem; + } + + .md\:-mx-56 { + margin-left: -14rem; + margin-right: -14rem; + } + + .md\:-my-64 { + margin-top: -16rem; + margin-bottom: -16rem; + } + + .md\:-mx-64 { + margin-left: -16rem; + margin-right: -16rem; + } + + .md\:-my-px { + margin-top: -1px; + margin-bottom: -1px; + } + + .md\:-mx-px { + margin-left: -1px; + margin-right: -1px; + } + + .md\:mt-0 { + margin-top: 0; + } + + .md\:mr-0 { + margin-right: 0; + } + + .md\:mb-0 { + margin-bottom: 0; + } + + .md\:ml-0 { + margin-left: 0; + } + + .md\:mt-1 { + margin-top: 0.25rem; + } + + .md\:mr-1 { + margin-right: 0.25rem; + } + + .md\:mb-1 { + margin-bottom: 0.25rem; + } + + .md\:ml-1 { + margin-left: 0.25rem; + } + + .md\:mt-2 { + margin-top: 0.5rem; + } + + .md\:mr-2 { + margin-right: 0.5rem; + } + + .md\:mb-2 { + margin-bottom: 0.5rem; + } + + .md\:ml-2 { + margin-left: 0.5rem; + } + + .md\:mt-3 { + margin-top: 0.75rem; + } + + .md\:mr-3 { + margin-right: 0.75rem; + } + + .md\:mb-3 { + margin-bottom: 0.75rem; + } + + .md\:ml-3 { + margin-left: 0.75rem; + } + + .md\:mt-4 { + margin-top: 1rem; + } + + .md\:mr-4 { + margin-right: 1rem; + } + + .md\:mb-4 { + margin-bottom: 1rem; + } + + .md\:ml-4 { + margin-left: 1rem; + } + + .md\:mt-5 { + margin-top: 1.25rem; + } + + .md\:mr-5 { + margin-right: 1.25rem; + } + + .md\:mb-5 { + margin-bottom: 1.25rem; + } + + .md\:ml-5 { + margin-left: 1.25rem; + } + + .md\:mt-6 { + margin-top: 1.5rem; + } + + .md\:mr-6 { + margin-right: 1.5rem; + } + + .md\:mb-6 { + margin-bottom: 1.5rem; + } + + .md\:ml-6 { + margin-left: 1.5rem; + } + + .md\:mt-8 { + margin-top: 2rem; + } + + .md\:mr-8 { + margin-right: 2rem; + } + + .md\:mb-8 { + margin-bottom: 2rem; + } + + .md\:ml-8 { + margin-left: 2rem; + } + + .md\:mt-10 { + margin-top: 2.5rem; + } + + .md\:mr-10 { + margin-right: 2.5rem; + } + + .md\:mb-10 { + margin-bottom: 2.5rem; + } + + .md\:ml-10 { + margin-left: 2.5rem; + } + + .md\:mt-12 { + margin-top: 3rem; + } + + .md\:mr-12 { + margin-right: 3rem; + } + + .md\:mb-12 { + margin-bottom: 3rem; + } + + .md\:ml-12 { + margin-left: 3rem; + } + + .md\:mt-16 { + margin-top: 4rem; + } + + .md\:mr-16 { + margin-right: 4rem; + } + + .md\:mb-16 { + margin-bottom: 4rem; + } + + .md\:ml-16 { + margin-left: 4rem; + } + + .md\:mt-20 { + margin-top: 5rem; + } + + .md\:mr-20 { + margin-right: 5rem; + } + + .md\:mb-20 { + margin-bottom: 5rem; + } + + .md\:ml-20 { + margin-left: 5rem; + } + + .md\:mt-24 { + margin-top: 6rem; + } + + .md\:mr-24 { + margin-right: 6rem; + } + + .md\:mb-24 { + margin-bottom: 6rem; + } + + .md\:ml-24 { + margin-left: 6rem; + } + + .md\:mt-32 { + margin-top: 8rem; + } + + .md\:mr-32 { + margin-right: 8rem; + } + + .md\:mb-32 { + margin-bottom: 8rem; + } + + .md\:ml-32 { + margin-left: 8rem; + } + + .md\:mt-40 { + margin-top: 10rem; + } + + .md\:mr-40 { + margin-right: 10rem; + } + + .md\:mb-40 { + margin-bottom: 10rem; + } + + .md\:ml-40 { + margin-left: 10rem; + } + + .md\:mt-48 { + margin-top: 12rem; + } + + .md\:mr-48 { + margin-right: 12rem; + } + + .md\:mb-48 { + margin-bottom: 12rem; + } + + .md\:ml-48 { + margin-left: 12rem; + } + + .md\:mt-56 { + margin-top: 14rem; + } + + .md\:mr-56 { + margin-right: 14rem; + } + + .md\:mb-56 { + margin-bottom: 14rem; + } + + .md\:ml-56 { + margin-left: 14rem; + } + + .md\:mt-64 { + margin-top: 16rem; + } + + .md\:mr-64 { + margin-right: 16rem; + } + + .md\:mb-64 { + margin-bottom: 16rem; + } + + .md\:ml-64 { + margin-left: 16rem; + } + + .md\:mt-auto { + margin-top: auto; + } + + .md\:mr-auto { + margin-right: auto; + } + + .md\:mb-auto { + margin-bottom: auto; + } + + .md\:ml-auto { + margin-left: auto; + } + + .md\:mt-px { + margin-top: 1px; + } + + .md\:mr-px { + margin-right: 1px; + } + + .md\:mb-px { + margin-bottom: 1px; + } + + .md\:ml-px { + margin-left: 1px; + } + + .md\:-mt-1 { + margin-top: -0.25rem; + } + + .md\:-mr-1 { + margin-right: -0.25rem; + } + + .md\:-mb-1 { + margin-bottom: -0.25rem; + } + + .md\:-ml-1 { + margin-left: -0.25rem; + } + + .md\:-mt-2 { + margin-top: -0.5rem; + } + + .md\:-mr-2 { + margin-right: -0.5rem; + } + + .md\:-mb-2 { + margin-bottom: -0.5rem; + } + + .md\:-ml-2 { + margin-left: -0.5rem; + } + + .md\:-mt-3 { + margin-top: -0.75rem; + } + + .md\:-mr-3 { + margin-right: -0.75rem; + } + + .md\:-mb-3 { + margin-bottom: -0.75rem; + } + + .md\:-ml-3 { + margin-left: -0.75rem; + } + + .md\:-mt-4 { + margin-top: -1rem; + } + + .md\:-mr-4 { + margin-right: -1rem; + } + + .md\:-mb-4 { + margin-bottom: -1rem; + } + + .md\:-ml-4 { + margin-left: -1rem; + } + + .md\:-mt-5 { + margin-top: -1.25rem; + } + + .md\:-mr-5 { + margin-right: -1.25rem; + } + + .md\:-mb-5 { + margin-bottom: -1.25rem; + } + + .md\:-ml-5 { + margin-left: -1.25rem; + } + + .md\:-mt-6 { + margin-top: -1.5rem; + } + + .md\:-mr-6 { + margin-right: -1.5rem; + } + + .md\:-mb-6 { + margin-bottom: -1.5rem; + } + + .md\:-ml-6 { + margin-left: -1.5rem; + } + + .md\:-mt-8 { + margin-top: -2rem; + } + + .md\:-mr-8 { + margin-right: -2rem; + } + + .md\:-mb-8 { + margin-bottom: -2rem; + } + + .md\:-ml-8 { + margin-left: -2rem; + } + + .md\:-mt-10 { + margin-top: -2.5rem; + } + + .md\:-mr-10 { + margin-right: -2.5rem; + } + + .md\:-mb-10 { + margin-bottom: -2.5rem; + } + + .md\:-ml-10 { + margin-left: -2.5rem; + } + + .md\:-mt-12 { + margin-top: -3rem; + } + + .md\:-mr-12 { + margin-right: -3rem; + } + + .md\:-mb-12 { + margin-bottom: -3rem; + } + + .md\:-ml-12 { + margin-left: -3rem; + } + + .md\:-mt-16 { + margin-top: -4rem; + } + + .md\:-mr-16 { + margin-right: -4rem; + } + + .md\:-mb-16 { + margin-bottom: -4rem; + } + + .md\:-ml-16 { + margin-left: -4rem; + } + + .md\:-mt-20 { + margin-top: -5rem; + } + + .md\:-mr-20 { + margin-right: -5rem; + } + + .md\:-mb-20 { + margin-bottom: -5rem; + } + + .md\:-ml-20 { + margin-left: -5rem; + } + + .md\:-mt-24 { + margin-top: -6rem; + } + + .md\:-mr-24 { + margin-right: -6rem; + } + + .md\:-mb-24 { + margin-bottom: -6rem; + } + + .md\:-ml-24 { + margin-left: -6rem; + } + + .md\:-mt-32 { + margin-top: -8rem; + } + + .md\:-mr-32 { + margin-right: -8rem; + } + + .md\:-mb-32 { + margin-bottom: -8rem; + } + + .md\:-ml-32 { + margin-left: -8rem; + } + + .md\:-mt-40 { + margin-top: -10rem; + } + + .md\:-mr-40 { + margin-right: -10rem; + } + + .md\:-mb-40 { + margin-bottom: -10rem; + } + + .md\:-ml-40 { + margin-left: -10rem; + } + + .md\:-mt-48 { + margin-top: -12rem; + } + + .md\:-mr-48 { + margin-right: -12rem; + } + + .md\:-mb-48 { + margin-bottom: -12rem; + } + + .md\:-ml-48 { + margin-left: -12rem; + } + + .md\:-mt-56 { + margin-top: -14rem; + } + + .md\:-mr-56 { + margin-right: -14rem; + } + + .md\:-mb-56 { + margin-bottom: -14rem; + } + + .md\:-ml-56 { + margin-left: -14rem; + } + + .md\:-mt-64 { + margin-top: -16rem; + } + + .md\:-mr-64 { + margin-right: -16rem; + } + + .md\:-mb-64 { + margin-bottom: -16rem; + } + + .md\:-ml-64 { + margin-left: -16rem; + } + + .md\:-mt-px { + margin-top: -1px; + } + + .md\:-mr-px { + margin-right: -1px; + } + + .md\:-mb-px { + margin-bottom: -1px; + } + + .md\:-ml-px { + margin-left: -1px; + } + + .md\:max-h-full { + max-height: 100%; + } + + .md\:max-h-screen { + max-height: 100vh; + } + + .md\:max-w-none { + max-width: none; + } + + .md\:max-w-xs { + max-width: 20rem; + } + + .md\:max-w-sm { + max-width: 24rem; + } + + .md\:max-w-md { + max-width: 28rem; + } + + .md\:max-w-lg { + max-width: 32rem; + } + + .md\:max-w-xl { + max-width: 36rem; + } + + .md\:max-w-2xl { + max-width: 42rem; + } + + .md\:max-w-3xl { + max-width: 48rem; + } + + .md\:max-w-4xl { + max-width: 56rem; + } + + .md\:max-w-5xl { + max-width: 64rem; + } + + .md\:max-w-6xl { + max-width: 72rem; + } + + .md\:max-w-full { + max-width: 100%; + } + + .md\:max-w-screen-sm { + max-width: 640px; + } + + .md\:max-w-screen-md { + max-width: 768px; + } + + .md\:max-w-screen-lg { + max-width: 1024px; + } + + .md\:max-w-screen-xl { + max-width: 1280px; + } + + .md\:min-h-0 { + min-height: 0; + } + + .md\:min-h-full { + min-height: 100%; + } + + .md\:min-h-screen { + min-height: 100vh; + } + + .md\:min-w-0 { + min-width: 0; + } + + .md\:min-w-full { + min-width: 100%; + } + + .md\:object-contain { + object-fit: contain; + } + + .md\:object-cover { + object-fit: cover; + } + + .md\:object-fill { + object-fit: fill; + } + + .md\:object-none { + object-fit: none; + } + + .md\:object-scale-down { + object-fit: scale-down; + } + + .md\:object-bottom { + object-position: bottom; + } + + .md\:object-center { + object-position: center; + } + + .md\:object-left { + object-position: left; + } + + .md\:object-left-bottom { + object-position: left bottom; + } + + .md\:object-left-top { + object-position: left top; + } + + .md\:object-right { + object-position: right; + } + + .md\:object-right-bottom { + object-position: right bottom; + } + + .md\:object-right-top { + object-position: right top; + } + + .md\:object-top { + object-position: top; + } + + .md\:opacity-0 { + opacity: 0; + } + + .md\:opacity-25 { + opacity: 0.25; + } + + .md\:opacity-50 { + opacity: 0.5; + } + + .md\:opacity-75 { + opacity: 0.75; + } + + .md\:opacity-100 { + opacity: 1; + } + + .md\:hover\:opacity-0:hover { + opacity: 0; + } + + .md\:hover\:opacity-25:hover { + opacity: 0.25; + } + + .md\:hover\:opacity-50:hover { + opacity: 0.5; + } + + .md\:hover\:opacity-75:hover { + opacity: 0.75; + } + + .md\:hover\:opacity-100:hover { + opacity: 1; + } + + .md\:focus\:opacity-0:focus { + opacity: 0; + } + + .md\:focus\:opacity-25:focus { + opacity: 0.25; + } + + .md\:focus\:opacity-50:focus { + opacity: 0.5; + } + + .md\:focus\:opacity-75:focus { + opacity: 0.75; + } + + .md\:focus\:opacity-100:focus { + opacity: 1; + } + + .md\:outline-none { + outline: 0; + } + + .md\:focus\:outline-none:focus { + outline: 0; + } + + .md\:overflow-auto { + overflow: auto; + } + + .md\:overflow-hidden { + overflow: hidden; + } + + .md\:overflow-visible { + overflow: visible; + } + + .md\:overflow-scroll { + overflow: scroll; + } + + .md\:overflow-x-auto { + overflow-x: auto; + } + + .md\:overflow-y-auto { + overflow-y: auto; + } + + .md\:overflow-x-hidden { + overflow-x: hidden; + } + + .md\:overflow-y-hidden { + overflow-y: hidden; + } + + .md\:overflow-x-visible { + overflow-x: visible; + } + + .md\:overflow-y-visible { + overflow-y: visible; + } + + .md\:overflow-x-scroll { + overflow-x: scroll; + } + + .md\:overflow-y-scroll { + overflow-y: scroll; + } + + .md\:scrolling-touch { + -webkit-overflow-scrolling: touch; + } + + .md\:scrolling-auto { + -webkit-overflow-scrolling: auto; + } + + .md\:p-0 { + padding: 0; + } + + .md\:p-1 { + padding: 0.25rem; + } + + .md\:p-2 { + padding: 0.5rem; + } + + .md\:p-3 { + padding: 0.75rem; + } + + .md\:p-4 { + padding: 1rem; + } + + .md\:p-5 { + padding: 1.25rem; + } + + .md\:p-6 { + padding: 1.5rem; + } + + .md\:p-8 { + padding: 2rem; + } + + .md\:p-10 { + padding: 2.5rem; + } + + .md\:p-12 { + padding: 3rem; + } + + .md\:p-16 { + padding: 4rem; + } + + .md\:p-20 { + padding: 5rem; + } + + .md\:p-24 { + padding: 6rem; + } + + .md\:p-32 { + padding: 8rem; + } + + .md\:p-40 { + padding: 10rem; + } + + .md\:p-48 { + padding: 12rem; + } + + .md\:p-56 { + padding: 14rem; + } + + .md\:p-64 { + padding: 16rem; + } + + .md\:p-px { + padding: 1px; + } + + .md\:py-0 { + padding-top: 0; + padding-bottom: 0; + } + + .md\:px-0 { + padding-left: 0; + padding-right: 0; + } + + .md\:py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + + .md\:px-1 { + padding-left: 0.25rem; + padding-right: 0.25rem; + } + + .md\:py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + } + + .md\:px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; + } + + .md\:py-3 { + padding-top: 0.75rem; + padding-bottom: 0.75rem; + } + + .md\:px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; + } + + .md\:py-4 { + padding-top: 1rem; + padding-bottom: 1rem; + } + + .md\:px-4 { + padding-left: 1rem; + padding-right: 1rem; + } + + .md\:py-5 { + padding-top: 1.25rem; + padding-bottom: 1.25rem; + } + + .md\:px-5 { + padding-left: 1.25rem; + padding-right: 1.25rem; + } + + .md\:py-6 { + padding-top: 1.5rem; + padding-bottom: 1.5rem; + } + + .md\:px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; + } + + .md\:py-8 { + padding-top: 2rem; + padding-bottom: 2rem; + } + + .md\:px-8 { + padding-left: 2rem; + padding-right: 2rem; + } + + .md\:py-10 { + padding-top: 2.5rem; + padding-bottom: 2.5rem; + } + + .md\:px-10 { + padding-left: 2.5rem; + padding-right: 2.5rem; + } + + .md\:py-12 { + padding-top: 3rem; + padding-bottom: 3rem; + } + + .md\:px-12 { + padding-left: 3rem; + padding-right: 3rem; + } + + .md\:py-16 { + padding-top: 4rem; + padding-bottom: 4rem; + } + + .md\:px-16 { + padding-left: 4rem; + padding-right: 4rem; + } + + .md\:py-20 { + padding-top: 5rem; + padding-bottom: 5rem; + } + + .md\:px-20 { + padding-left: 5rem; + padding-right: 5rem; + } + + .md\:py-24 { + padding-top: 6rem; + padding-bottom: 6rem; + } + + .md\:px-24 { + padding-left: 6rem; + padding-right: 6rem; + } + + .md\:py-32 { + padding-top: 8rem; + padding-bottom: 8rem; + } + + .md\:px-32 { + padding-left: 8rem; + padding-right: 8rem; + } + + .md\:py-40 { + padding-top: 10rem; + padding-bottom: 10rem; + } + + .md\:px-40 { + padding-left: 10rem; + padding-right: 10rem; + } + + .md\:py-48 { + padding-top: 12rem; + padding-bottom: 12rem; + } + + .md\:px-48 { + padding-left: 12rem; + padding-right: 12rem; + } + + .md\:py-56 { + padding-top: 14rem; + padding-bottom: 14rem; + } + + .md\:px-56 { + padding-left: 14rem; + padding-right: 14rem; + } + + .md\:py-64 { + padding-top: 16rem; + padding-bottom: 16rem; + } + + .md\:px-64 { + padding-left: 16rem; + padding-right: 16rem; + } + + .md\:py-px { + padding-top: 1px; + padding-bottom: 1px; + } + + .md\:px-px { + padding-left: 1px; + padding-right: 1px; + } + + .md\:pt-0 { + padding-top: 0; + } + + .md\:pr-0 { + padding-right: 0; + } + + .md\:pb-0 { + padding-bottom: 0; + } + + .md\:pl-0 { + padding-left: 0; + } + + .md\:pt-1 { + padding-top: 0.25rem; + } + + .md\:pr-1 { + padding-right: 0.25rem; + } + + .md\:pb-1 { + padding-bottom: 0.25rem; + } + + .md\:pl-1 { + padding-left: 0.25rem; + } + + .md\:pt-2 { + padding-top: 0.5rem; + } + + .md\:pr-2 { + padding-right: 0.5rem; + } + + .md\:pb-2 { + padding-bottom: 0.5rem; + } + + .md\:pl-2 { + padding-left: 0.5rem; + } + + .md\:pt-3 { + padding-top: 0.75rem; + } + + .md\:pr-3 { + padding-right: 0.75rem; + } + + .md\:pb-3 { + padding-bottom: 0.75rem; + } + + .md\:pl-3 { + padding-left: 0.75rem; + } + + .md\:pt-4 { + padding-top: 1rem; + } + + .md\:pr-4 { + padding-right: 1rem; + } + + .md\:pb-4 { + padding-bottom: 1rem; + } + + .md\:pl-4 { + padding-left: 1rem; + } + + .md\:pt-5 { + padding-top: 1.25rem; + } + + .md\:pr-5 { + padding-right: 1.25rem; + } + + .md\:pb-5 { + padding-bottom: 1.25rem; + } + + .md\:pl-5 { + padding-left: 1.25rem; + } + + .md\:pt-6 { + padding-top: 1.5rem; + } + + .md\:pr-6 { + padding-right: 1.5rem; + } + + .md\:pb-6 { + padding-bottom: 1.5rem; + } + + .md\:pl-6 { + padding-left: 1.5rem; + } + + .md\:pt-8 { + padding-top: 2rem; + } + + .md\:pr-8 { + padding-right: 2rem; + } + + .md\:pb-8 { + padding-bottom: 2rem; + } + + .md\:pl-8 { + padding-left: 2rem; + } + + .md\:pt-10 { + padding-top: 2.5rem; + } + + .md\:pr-10 { + padding-right: 2.5rem; + } + + .md\:pb-10 { + padding-bottom: 2.5rem; + } + + .md\:pl-10 { + padding-left: 2.5rem; + } + + .md\:pt-12 { + padding-top: 3rem; + } + + .md\:pr-12 { + padding-right: 3rem; + } + + .md\:pb-12 { + padding-bottom: 3rem; + } + + .md\:pl-12 { + padding-left: 3rem; + } + + .md\:pt-16 { + padding-top: 4rem; + } + + .md\:pr-16 { + padding-right: 4rem; + } + + .md\:pb-16 { + padding-bottom: 4rem; + } + + .md\:pl-16 { + padding-left: 4rem; + } + + .md\:pt-20 { + padding-top: 5rem; + } + + .md\:pr-20 { + padding-right: 5rem; + } + + .md\:pb-20 { + padding-bottom: 5rem; + } + + .md\:pl-20 { + padding-left: 5rem; + } + + .md\:pt-24 { + padding-top: 6rem; + } + + .md\:pr-24 { + padding-right: 6rem; + } + + .md\:pb-24 { + padding-bottom: 6rem; + } + + .md\:pl-24 { + padding-left: 6rem; + } + + .md\:pt-32 { + padding-top: 8rem; + } + + .md\:pr-32 { + padding-right: 8rem; + } + + .md\:pb-32 { + padding-bottom: 8rem; + } + + .md\:pl-32 { + padding-left: 8rem; + } + + .md\:pt-40 { + padding-top: 10rem; + } + + .md\:pr-40 { + padding-right: 10rem; + } + + .md\:pb-40 { + padding-bottom: 10rem; + } + + .md\:pl-40 { + padding-left: 10rem; + } + + .md\:pt-48 { + padding-top: 12rem; + } + + .md\:pr-48 { + padding-right: 12rem; + } + + .md\:pb-48 { + padding-bottom: 12rem; + } + + .md\:pl-48 { + padding-left: 12rem; + } + + .md\:pt-56 { + padding-top: 14rem; + } + + .md\:pr-56 { + padding-right: 14rem; + } + + .md\:pb-56 { + padding-bottom: 14rem; + } + + .md\:pl-56 { + padding-left: 14rem; + } + + .md\:pt-64 { + padding-top: 16rem; + } + + .md\:pr-64 { + padding-right: 16rem; + } + + .md\:pb-64 { + padding-bottom: 16rem; + } + + .md\:pl-64 { + padding-left: 16rem; + } + + .md\:pt-px { + padding-top: 1px; + } + + .md\:pr-px { + padding-right: 1px; + } + + .md\:pb-px { + padding-bottom: 1px; + } + + .md\:pl-px { + padding-left: 1px; + } + + .md\:placeholder-transparent::placeholder { + color: transparent; + } + + .md\:placeholder-black::placeholder { + color: #000; + } + + .md\:placeholder-white::placeholder { + color: #fff; + } + + .md\:placeholder-gray-100::placeholder { + color: #f7fafc; + } + + .md\:placeholder-gray-200::placeholder { + color: #edf2f7; + } + + .md\:placeholder-gray-300::placeholder { + color: #e2e8f0; + } + + .md\:placeholder-gray-400::placeholder { + color: #cbd5e0; + } + + .md\:placeholder-gray-500::placeholder { + color: #a0aec0; + } + + .md\:placeholder-gray-600::placeholder { + color: #718096; + } + + .md\:placeholder-gray-700::placeholder { + color: #4a5568; + } + + .md\:placeholder-gray-800::placeholder { + color: #2d3748; + } + + .md\:placeholder-gray-900::placeholder { + color: #1a202c; + } + + .md\:placeholder-red-100::placeholder { + color: #fff5f5; + } + + .md\:placeholder-red-200::placeholder { + color: #fed7d7; + } + + .md\:placeholder-red-300::placeholder { + color: #feb2b2; + } + + .md\:placeholder-red-400::placeholder { + color: #fc8181; + } + + .md\:placeholder-red-500::placeholder { + color: #f56565; + } + + .md\:placeholder-red-600::placeholder { + color: #e53e3e; + } + + .md\:placeholder-red-700::placeholder { + color: #c53030; + } + + .md\:placeholder-red-800::placeholder { + color: #9b2c2c; + } + + .md\:placeholder-red-900::placeholder { + color: #742a2a; + } + + .md\:placeholder-orange-100::placeholder { + color: #fffaf0; + } + + .md\:placeholder-orange-200::placeholder { + color: #feebc8; + } + + .md\:placeholder-orange-300::placeholder { + color: #fbd38d; + } + + .md\:placeholder-orange-400::placeholder { + color: #f6ad55; + } + + .md\:placeholder-orange-500::placeholder { + color: #ed8936; + } + + .md\:placeholder-orange-600::placeholder { + color: #dd6b20; + } + + .md\:placeholder-orange-700::placeholder { + color: #c05621; + } + + .md\:placeholder-orange-800::placeholder { + color: #9c4221; + } + + .md\:placeholder-orange-900::placeholder { + color: #7b341e; + } + + .md\:placeholder-yellow-100::placeholder { + color: #fffff0; + } + + .md\:placeholder-yellow-200::placeholder { + color: #fefcbf; + } + + .md\:placeholder-yellow-300::placeholder { + color: #faf089; + } + + .md\:placeholder-yellow-400::placeholder { + color: #f6e05e; + } + + .md\:placeholder-yellow-500::placeholder { + color: #ecc94b; + } + + .md\:placeholder-yellow-600::placeholder { + color: #d69e2e; + } + + .md\:placeholder-yellow-700::placeholder { + color: #b7791f; + } + + .md\:placeholder-yellow-800::placeholder { + color: #975a16; + } + + .md\:placeholder-yellow-900::placeholder { + color: #744210; + } + + .md\:placeholder-green-100::placeholder { + color: #f0fff4; + } + + .md\:placeholder-green-200::placeholder { + color: #c6f6d5; + } + + .md\:placeholder-green-300::placeholder { + color: #9ae6b4; + } + + .md\:placeholder-green-400::placeholder { + color: #68d391; + } + + .md\:placeholder-green-500::placeholder { + color: #48bb78; + } + + .md\:placeholder-green-600::placeholder { + color: #38a169; + } + + .md\:placeholder-green-700::placeholder { + color: #2f855a; + } + + .md\:placeholder-green-800::placeholder { + color: #276749; + } + + .md\:placeholder-green-900::placeholder { + color: #22543d; + } + + .md\:placeholder-teal-100::placeholder { + color: #e6fffa; + } + + .md\:placeholder-teal-200::placeholder { + color: #b2f5ea; + } + + .md\:placeholder-teal-300::placeholder { + color: #81e6d9; + } + + .md\:placeholder-teal-400::placeholder { + color: #4fd1c5; + } + + .md\:placeholder-teal-500::placeholder { + color: #38b2ac; + } + + .md\:placeholder-teal-600::placeholder { + color: #319795; + } + + .md\:placeholder-teal-700::placeholder { + color: #2c7a7b; + } + + .md\:placeholder-teal-800::placeholder { + color: #285e61; + } + + .md\:placeholder-teal-900::placeholder { + color: #234e52; + } + + .md\:placeholder-blue-100::placeholder { + color: #ebf8ff; + } + + .md\:placeholder-blue-200::placeholder { + color: #bee3f8; + } + + .md\:placeholder-blue-300::placeholder { + color: #90cdf4; + } + + .md\:placeholder-blue-400::placeholder { + color: #63b3ed; + } + + .md\:placeholder-blue-500::placeholder { + color: #4299e1; + } + + .md\:placeholder-blue-600::placeholder { + color: #3182ce; + } + + .md\:placeholder-blue-700::placeholder { + color: #2b6cb0; + } + + .md\:placeholder-blue-800::placeholder { + color: #2c5282; + } + + .md\:placeholder-blue-900::placeholder { + color: #2a4365; + } + + .md\:placeholder-indigo-100::placeholder { + color: #ebf4ff; + } + + .md\:placeholder-indigo-200::placeholder { + color: #c3dafe; + } + + .md\:placeholder-indigo-300::placeholder { + color: #a3bffa; + } + + .md\:placeholder-indigo-400::placeholder { + color: #7f9cf5; + } + + .md\:placeholder-indigo-500::placeholder { + color: #667eea; + } + + .md\:placeholder-indigo-600::placeholder { + color: #5a67d8; + } + + .md\:placeholder-indigo-700::placeholder { + color: #4c51bf; + } + + .md\:placeholder-indigo-800::placeholder { + color: #434190; + } + + .md\:placeholder-indigo-900::placeholder { + color: #3c366b; + } + + .md\:placeholder-purple-100::placeholder { + color: #faf5ff; + } + + .md\:placeholder-purple-200::placeholder { + color: #e9d8fd; + } + + .md\:placeholder-purple-300::placeholder { + color: #d6bcfa; + } + + .md\:placeholder-purple-400::placeholder { + color: #b794f4; + } + + .md\:placeholder-purple-500::placeholder { + color: #9f7aea; + } + + .md\:placeholder-purple-600::placeholder { + color: #805ad5; + } + + .md\:placeholder-purple-700::placeholder { + color: #6b46c1; + } + + .md\:placeholder-purple-800::placeholder { + color: #553c9a; + } + + .md\:placeholder-purple-900::placeholder { + color: #44337a; + } + + .md\:placeholder-pink-100::placeholder { + color: #fff5f7; + } + + .md\:placeholder-pink-200::placeholder { + color: #fed7e2; + } + + .md\:placeholder-pink-300::placeholder { + color: #fbb6ce; + } + + .md\:placeholder-pink-400::placeholder { + color: #f687b3; + } + + .md\:placeholder-pink-500::placeholder { + color: #ed64a6; + } + + .md\:placeholder-pink-600::placeholder { + color: #d53f8c; + } + + .md\:placeholder-pink-700::placeholder { + color: #b83280; + } + + .md\:placeholder-pink-800::placeholder { + color: #97266d; + } + + .md\:placeholder-pink-900::placeholder { + color: #702459; + } + + .md\:focus\:placeholder-transparent:focus::placeholder { + color: transparent; + } + + .md\:focus\:placeholder-black:focus::placeholder { + color: #000; + } + + .md\:focus\:placeholder-white:focus::placeholder { + color: #fff; + } + + .md\:focus\:placeholder-gray-100:focus::placeholder { + color: #f7fafc; + } + + .md\:focus\:placeholder-gray-200:focus::placeholder { + color: #edf2f7; + } + + .md\:focus\:placeholder-gray-300:focus::placeholder { + color: #e2e8f0; + } + + .md\:focus\:placeholder-gray-400:focus::placeholder { + color: #cbd5e0; + } + + .md\:focus\:placeholder-gray-500:focus::placeholder { + color: #a0aec0; + } + + .md\:focus\:placeholder-gray-600:focus::placeholder { + color: #718096; + } + + .md\:focus\:placeholder-gray-700:focus::placeholder { + color: #4a5568; + } + + .md\:focus\:placeholder-gray-800:focus::placeholder { + color: #2d3748; + } + + .md\:focus\:placeholder-gray-900:focus::placeholder { + color: #1a202c; + } + + .md\:focus\:placeholder-red-100:focus::placeholder { + color: #fff5f5; + } + + .md\:focus\:placeholder-red-200:focus::placeholder { + color: #fed7d7; + } + + .md\:focus\:placeholder-red-300:focus::placeholder { + color: #feb2b2; + } + + .md\:focus\:placeholder-red-400:focus::placeholder { + color: #fc8181; + } + + .md\:focus\:placeholder-red-500:focus::placeholder { + color: #f56565; + } + + .md\:focus\:placeholder-red-600:focus::placeholder { + color: #e53e3e; + } + + .md\:focus\:placeholder-red-700:focus::placeholder { + color: #c53030; + } + + .md\:focus\:placeholder-red-800:focus::placeholder { + color: #9b2c2c; + } + + .md\:focus\:placeholder-red-900:focus::placeholder { + color: #742a2a; + } + + .md\:focus\:placeholder-orange-100:focus::placeholder { + color: #fffaf0; + } + + .md\:focus\:placeholder-orange-200:focus::placeholder { + color: #feebc8; + } + + .md\:focus\:placeholder-orange-300:focus::placeholder { + color: #fbd38d; + } + + .md\:focus\:placeholder-orange-400:focus::placeholder { + color: #f6ad55; + } + + .md\:focus\:placeholder-orange-500:focus::placeholder { + color: #ed8936; + } + + .md\:focus\:placeholder-orange-600:focus::placeholder { + color: #dd6b20; + } + + .md\:focus\:placeholder-orange-700:focus::placeholder { + color: #c05621; + } + + .md\:focus\:placeholder-orange-800:focus::placeholder { + color: #9c4221; + } + + .md\:focus\:placeholder-orange-900:focus::placeholder { + color: #7b341e; + } + + .md\:focus\:placeholder-yellow-100:focus::placeholder { + color: #fffff0; + } + + .md\:focus\:placeholder-yellow-200:focus::placeholder { + color: #fefcbf; + } + + .md\:focus\:placeholder-yellow-300:focus::placeholder { + color: #faf089; + } + + .md\:focus\:placeholder-yellow-400:focus::placeholder { + color: #f6e05e; + } + + .md\:focus\:placeholder-yellow-500:focus::placeholder { + color: #ecc94b; + } + + .md\:focus\:placeholder-yellow-600:focus::placeholder { + color: #d69e2e; + } + + .md\:focus\:placeholder-yellow-700:focus::placeholder { + color: #b7791f; + } + + .md\:focus\:placeholder-yellow-800:focus::placeholder { + color: #975a16; + } + + .md\:focus\:placeholder-yellow-900:focus::placeholder { + color: #744210; + } + + .md\:focus\:placeholder-green-100:focus::placeholder { + color: #f0fff4; + } + + .md\:focus\:placeholder-green-200:focus::placeholder { + color: #c6f6d5; + } + + .md\:focus\:placeholder-green-300:focus::placeholder { + color: #9ae6b4; + } + + .md\:focus\:placeholder-green-400:focus::placeholder { + color: #68d391; + } + + .md\:focus\:placeholder-green-500:focus::placeholder { + color: #48bb78; + } + + .md\:focus\:placeholder-green-600:focus::placeholder { + color: #38a169; + } + + .md\:focus\:placeholder-green-700:focus::placeholder { + color: #2f855a; + } + + .md\:focus\:placeholder-green-800:focus::placeholder { + color: #276749; + } + + .md\:focus\:placeholder-green-900:focus::placeholder { + color: #22543d; + } + + .md\:focus\:placeholder-teal-100:focus::placeholder { + color: #e6fffa; + } + + .md\:focus\:placeholder-teal-200:focus::placeholder { + color: #b2f5ea; + } + + .md\:focus\:placeholder-teal-300:focus::placeholder { + color: #81e6d9; + } + + .md\:focus\:placeholder-teal-400:focus::placeholder { + color: #4fd1c5; + } + + .md\:focus\:placeholder-teal-500:focus::placeholder { + color: #38b2ac; + } + + .md\:focus\:placeholder-teal-600:focus::placeholder { + color: #319795; + } + + .md\:focus\:placeholder-teal-700:focus::placeholder { + color: #2c7a7b; + } + + .md\:focus\:placeholder-teal-800:focus::placeholder { + color: #285e61; + } + + .md\:focus\:placeholder-teal-900:focus::placeholder { + color: #234e52; + } + + .md\:focus\:placeholder-blue-100:focus::placeholder { + color: #ebf8ff; + } + + .md\:focus\:placeholder-blue-200:focus::placeholder { + color: #bee3f8; + } + + .md\:focus\:placeholder-blue-300:focus::placeholder { + color: #90cdf4; + } + + .md\:focus\:placeholder-blue-400:focus::placeholder { + color: #63b3ed; + } + + .md\:focus\:placeholder-blue-500:focus::placeholder { + color: #4299e1; + } + + .md\:focus\:placeholder-blue-600:focus::placeholder { + color: #3182ce; + } + + .md\:focus\:placeholder-blue-700:focus::placeholder { + color: #2b6cb0; + } + + .md\:focus\:placeholder-blue-800:focus::placeholder { + color: #2c5282; + } + + .md\:focus\:placeholder-blue-900:focus::placeholder { + color: #2a4365; + } + + .md\:focus\:placeholder-indigo-100:focus::placeholder { + color: #ebf4ff; + } + + .md\:focus\:placeholder-indigo-200:focus::placeholder { + color: #c3dafe; + } + + .md\:focus\:placeholder-indigo-300:focus::placeholder { + color: #a3bffa; + } + + .md\:focus\:placeholder-indigo-400:focus::placeholder { + color: #7f9cf5; + } + + .md\:focus\:placeholder-indigo-500:focus::placeholder { + color: #667eea; + } + + .md\:focus\:placeholder-indigo-600:focus::placeholder { + color: #5a67d8; + } + + .md\:focus\:placeholder-indigo-700:focus::placeholder { + color: #4c51bf; + } + + .md\:focus\:placeholder-indigo-800:focus::placeholder { + color: #434190; + } + + .md\:focus\:placeholder-indigo-900:focus::placeholder { + color: #3c366b; + } + + .md\:focus\:placeholder-purple-100:focus::placeholder { + color: #faf5ff; + } + + .md\:focus\:placeholder-purple-200:focus::placeholder { + color: #e9d8fd; + } + + .md\:focus\:placeholder-purple-300:focus::placeholder { + color: #d6bcfa; + } + + .md\:focus\:placeholder-purple-400:focus::placeholder { + color: #b794f4; + } + + .md\:focus\:placeholder-purple-500:focus::placeholder { + color: #9f7aea; + } + + .md\:focus\:placeholder-purple-600:focus::placeholder { + color: #805ad5; + } + + .md\:focus\:placeholder-purple-700:focus::placeholder { + color: #6b46c1; + } + + .md\:focus\:placeholder-purple-800:focus::placeholder { + color: #553c9a; + } + + .md\:focus\:placeholder-purple-900:focus::placeholder { + color: #44337a; + } + + .md\:focus\:placeholder-pink-100:focus::placeholder { + color: #fff5f7; + } + + .md\:focus\:placeholder-pink-200:focus::placeholder { + color: #fed7e2; + } + + .md\:focus\:placeholder-pink-300:focus::placeholder { + color: #fbb6ce; + } + + .md\:focus\:placeholder-pink-400:focus::placeholder { + color: #f687b3; + } + + .md\:focus\:placeholder-pink-500:focus::placeholder { + color: #ed64a6; + } + + .md\:focus\:placeholder-pink-600:focus::placeholder { + color: #d53f8c; + } + + .md\:focus\:placeholder-pink-700:focus::placeholder { + color: #b83280; + } + + .md\:focus\:placeholder-pink-800:focus::placeholder { + color: #97266d; + } + + .md\:focus\:placeholder-pink-900:focus::placeholder { + color: #702459; + } + + .md\:pointer-events-none { + pointer-events: none; + } + + .md\:pointer-events-auto { + pointer-events: auto; + } + + .md\:static { + position: static; + } + + .md\:fixed { + position: fixed; + } + + .md\:absolute { + position: absolute; + } + + .md\:relative { + position: relative; + } + + .md\:sticky { + position: -webkit-sticky; + position: sticky; + } + + .md\:inset-0 { + top: 0; + right: 0; + bottom: 0; + left: 0; + } + + .md\:inset-auto { + top: auto; + right: auto; + bottom: auto; + left: auto; + } + + .md\:inset-y-0 { + top: 0; + bottom: 0; + } + + .md\:inset-x-0 { + right: 0; + left: 0; + } + + .md\:inset-y-auto { + top: auto; + bottom: auto; + } + + .md\:inset-x-auto { + right: auto; + left: auto; + } + + .md\:top-0 { + top: 0; + } + + .md\:right-0 { + right: 0; + } + + .md\:bottom-0 { + bottom: 0; + } + + .md\:left-0 { + left: 0; + } + + .md\:top-auto { + top: auto; + } + + .md\:right-auto { + right: auto; + } + + .md\:bottom-auto { + bottom: auto; + } + + .md\:left-auto { + left: auto; + } + + .md\:resize-none { + resize: none; + } + + .md\:resize-y { + resize: vertical; + } + + .md\:resize-x { + resize: horizontal; + } + + .md\:resize { + resize: both; + } + + .md\:shadow-xs { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); + } + + .md\:shadow-sm { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + } + + .md\:shadow { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + } + + .md\:shadow-md { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + } + + .md\:shadow-lg { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + } + + .md\:shadow-xl { + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + } + + .md\:shadow-2xl { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + } + + .md\:shadow-inner { + box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); + } + + .md\:shadow-outline { + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); + } + + .md\:shadow-none { + box-shadow: none; + } + + .md\:hover\:shadow-xs:hover { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); + } + + .md\:hover\:shadow-sm:hover { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + } + + .md\:hover\:shadow:hover { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + } + + .md\:hover\:shadow-md:hover { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + } + + .md\:hover\:shadow-lg:hover { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + } + + .md\:hover\:shadow-xl:hover { + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + } + + .md\:hover\:shadow-2xl:hover { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + } + + .md\:hover\:shadow-inner:hover { + box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); + } + + .md\:hover\:shadow-outline:hover { + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); + } + + .md\:hover\:shadow-none:hover { + box-shadow: none; + } + + .md\:focus\:shadow-xs:focus { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); + } + + .md\:focus\:shadow-sm:focus { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + } + + .md\:focus\:shadow:focus { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + } + + .md\:focus\:shadow-md:focus { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + } + + .md\:focus\:shadow-lg:focus { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + } + + .md\:focus\:shadow-xl:focus { + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + } + + .md\:focus\:shadow-2xl:focus { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + } + + .md\:focus\:shadow-inner:focus { + box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); + } + + .md\:focus\:shadow-outline:focus { + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); + } + + .md\:focus\:shadow-none:focus { + box-shadow: none; + } + + .md\:fill-current { + fill: currentColor; + } + + .md\:stroke-current { + stroke: currentColor; + } + + .md\:stroke-0 { + stroke-width: 0; + } + + .md\:stroke-1 { + stroke-width: 1; + } + + .md\:stroke-2 { + stroke-width: 2; + } + + .md\:table-auto { + table-layout: auto; + } + + .md\:table-fixed { + table-layout: fixed; + } + + .md\:text-left { + text-align: left; + } + + .md\:text-center { + text-align: center; + } + + .md\:text-right { + text-align: right; + } + + .md\:text-justify { + text-align: justify; + } + + .md\:text-transparent { + color: transparent; + } + + .md\:text-black { + color: #000; + } + + .md\:text-white { + color: #fff; + } + + .md\:text-gray-100 { + color: #f7fafc; + } + + .md\:text-gray-200 { + color: #edf2f7; + } + + .md\:text-gray-300 { + color: #e2e8f0; + } + + .md\:text-gray-400 { + color: #cbd5e0; + } + + .md\:text-gray-500 { + color: #a0aec0; + } + + .md\:text-gray-600 { + color: #718096; + } + + .md\:text-gray-700 { + color: #4a5568; + } + + .md\:text-gray-800 { + color: #2d3748; + } + + .md\:text-gray-900 { + color: #1a202c; + } + + .md\:text-red-100 { + color: #fff5f5; + } + + .md\:text-red-200 { + color: #fed7d7; + } + + .md\:text-red-300 { + color: #feb2b2; + } + + .md\:text-red-400 { + color: #fc8181; + } + + .md\:text-red-500 { + color: #f56565; + } + + .md\:text-red-600 { + color: #e53e3e; + } + + .md\:text-red-700 { + color: #c53030; + } + + .md\:text-red-800 { + color: #9b2c2c; + } + + .md\:text-red-900 { + color: #742a2a; + } + + .md\:text-orange-100 { + color: #fffaf0; + } + + .md\:text-orange-200 { + color: #feebc8; + } + + .md\:text-orange-300 { + color: #fbd38d; + } + + .md\:text-orange-400 { + color: #f6ad55; + } + + .md\:text-orange-500 { + color: #ed8936; + } + + .md\:text-orange-600 { + color: #dd6b20; + } + + .md\:text-orange-700 { + color: #c05621; + } + + .md\:text-orange-800 { + color: #9c4221; + } + + .md\:text-orange-900 { + color: #7b341e; + } + + .md\:text-yellow-100 { + color: #fffff0; + } + + .md\:text-yellow-200 { + color: #fefcbf; + } + + .md\:text-yellow-300 { + color: #faf089; + } + + .md\:text-yellow-400 { + color: #f6e05e; + } + + .md\:text-yellow-500 { + color: #ecc94b; + } + + .md\:text-yellow-600 { + color: #d69e2e; + } + + .md\:text-yellow-700 { + color: #b7791f; + } + + .md\:text-yellow-800 { + color: #975a16; + } + + .md\:text-yellow-900 { + color: #744210; + } + + .md\:text-green-100 { + color: #f0fff4; + } + + .md\:text-green-200 { + color: #c6f6d5; + } + + .md\:text-green-300 { + color: #9ae6b4; + } + + .md\:text-green-400 { + color: #68d391; + } + + .md\:text-green-500 { + color: #48bb78; + } + + .md\:text-green-600 { + color: #38a169; + } + + .md\:text-green-700 { + color: #2f855a; + } + + .md\:text-green-800 { + color: #276749; + } + + .md\:text-green-900 { + color: #22543d; + } + + .md\:text-teal-100 { + color: #e6fffa; + } + + .md\:text-teal-200 { + color: #b2f5ea; + } + + .md\:text-teal-300 { + color: #81e6d9; + } + + .md\:text-teal-400 { + color: #4fd1c5; + } + + .md\:text-teal-500 { + color: #38b2ac; + } + + .md\:text-teal-600 { + color: #319795; + } + + .md\:text-teal-700 { + color: #2c7a7b; + } + + .md\:text-teal-800 { + color: #285e61; + } + + .md\:text-teal-900 { + color: #234e52; + } + + .md\:text-blue-100 { + color: #ebf8ff; + } + + .md\:text-blue-200 { + color: #bee3f8; + } + + .md\:text-blue-300 { + color: #90cdf4; + } + + .md\:text-blue-400 { + color: #63b3ed; + } + + .md\:text-blue-500 { + color: #4299e1; + } + + .md\:text-blue-600 { + color: #3182ce; + } + + .md\:text-blue-700 { + color: #2b6cb0; + } + + .md\:text-blue-800 { + color: #2c5282; + } + + .md\:text-blue-900 { + color: #2a4365; + } + + .md\:text-indigo-100 { + color: #ebf4ff; + } + + .md\:text-indigo-200 { + color: #c3dafe; + } + + .md\:text-indigo-300 { + color: #a3bffa; + } + + .md\:text-indigo-400 { + color: #7f9cf5; + } + + .md\:text-indigo-500 { + color: #667eea; + } + + .md\:text-indigo-600 { + color: #5a67d8; + } + + .md\:text-indigo-700 { + color: #4c51bf; + } + + .md\:text-indigo-800 { + color: #434190; + } + + .md\:text-indigo-900 { + color: #3c366b; + } + + .md\:text-purple-100 { + color: #faf5ff; + } + + .md\:text-purple-200 { + color: #e9d8fd; + } + + .md\:text-purple-300 { + color: #d6bcfa; + } + + .md\:text-purple-400 { + color: #b794f4; + } + + .md\:text-purple-500 { + color: #9f7aea; + } + + .md\:text-purple-600 { + color: #805ad5; + } + + .md\:text-purple-700 { + color: #6b46c1; + } + + .md\:text-purple-800 { + color: #553c9a; + } + + .md\:text-purple-900 { + color: #44337a; + } + + .md\:text-pink-100 { + color: #fff5f7; + } + + .md\:text-pink-200 { + color: #fed7e2; + } + + .md\:text-pink-300 { + color: #fbb6ce; + } + + .md\:text-pink-400 { + color: #f687b3; + } + + .md\:text-pink-500 { + color: #ed64a6; + } + + .md\:text-pink-600 { + color: #d53f8c; + } + + .md\:text-pink-700 { + color: #b83280; + } + + .md\:text-pink-800 { + color: #97266d; + } + + .md\:text-pink-900 { + color: #702459; + } + + .md\:hover\:text-transparent:hover { + color: transparent; + } + + .md\:hover\:text-black:hover { + color: #000; + } + + .md\:hover\:text-white:hover { + color: #fff; + } + + .md\:hover\:text-gray-100:hover { + color: #f7fafc; + } + + .md\:hover\:text-gray-200:hover { + color: #edf2f7; + } + + .md\:hover\:text-gray-300:hover { + color: #e2e8f0; + } + + .md\:hover\:text-gray-400:hover { + color: #cbd5e0; + } + + .md\:hover\:text-gray-500:hover { + color: #a0aec0; + } + + .md\:hover\:text-gray-600:hover { + color: #718096; + } + + .md\:hover\:text-gray-700:hover { + color: #4a5568; + } + + .md\:hover\:text-gray-800:hover { + color: #2d3748; + } + + .md\:hover\:text-gray-900:hover { + color: #1a202c; + } + + .md\:hover\:text-red-100:hover { + color: #fff5f5; + } + + .md\:hover\:text-red-200:hover { + color: #fed7d7; + } + + .md\:hover\:text-red-300:hover { + color: #feb2b2; + } + + .md\:hover\:text-red-400:hover { + color: #fc8181; + } + + .md\:hover\:text-red-500:hover { + color: #f56565; + } + + .md\:hover\:text-red-600:hover { + color: #e53e3e; + } + + .md\:hover\:text-red-700:hover { + color: #c53030; + } + + .md\:hover\:text-red-800:hover { + color: #9b2c2c; + } + + .md\:hover\:text-red-900:hover { + color: #742a2a; + } + + .md\:hover\:text-orange-100:hover { + color: #fffaf0; + } + + .md\:hover\:text-orange-200:hover { + color: #feebc8; + } + + .md\:hover\:text-orange-300:hover { + color: #fbd38d; + } + + .md\:hover\:text-orange-400:hover { + color: #f6ad55; + } + + .md\:hover\:text-orange-500:hover { + color: #ed8936; + } + + .md\:hover\:text-orange-600:hover { + color: #dd6b20; + } + + .md\:hover\:text-orange-700:hover { + color: #c05621; + } + + .md\:hover\:text-orange-800:hover { + color: #9c4221; + } + + .md\:hover\:text-orange-900:hover { + color: #7b341e; + } + + .md\:hover\:text-yellow-100:hover { + color: #fffff0; + } + + .md\:hover\:text-yellow-200:hover { + color: #fefcbf; + } + + .md\:hover\:text-yellow-300:hover { + color: #faf089; + } + + .md\:hover\:text-yellow-400:hover { + color: #f6e05e; + } + + .md\:hover\:text-yellow-500:hover { + color: #ecc94b; + } + + .md\:hover\:text-yellow-600:hover { + color: #d69e2e; + } + + .md\:hover\:text-yellow-700:hover { + color: #b7791f; + } + + .md\:hover\:text-yellow-800:hover { + color: #975a16; + } + + .md\:hover\:text-yellow-900:hover { + color: #744210; + } + + .md\:hover\:text-green-100:hover { + color: #f0fff4; + } + + .md\:hover\:text-green-200:hover { + color: #c6f6d5; + } + + .md\:hover\:text-green-300:hover { + color: #9ae6b4; + } + + .md\:hover\:text-green-400:hover { + color: #68d391; + } + + .md\:hover\:text-green-500:hover { + color: #48bb78; + } + + .md\:hover\:text-green-600:hover { + color: #38a169; + } + + .md\:hover\:text-green-700:hover { + color: #2f855a; + } + + .md\:hover\:text-green-800:hover { + color: #276749; + } + + .md\:hover\:text-green-900:hover { + color: #22543d; + } + + .md\:hover\:text-teal-100:hover { + color: #e6fffa; + } + + .md\:hover\:text-teal-200:hover { + color: #b2f5ea; + } + + .md\:hover\:text-teal-300:hover { + color: #81e6d9; + } + + .md\:hover\:text-teal-400:hover { + color: #4fd1c5; + } + + .md\:hover\:text-teal-500:hover { + color: #38b2ac; + } + + .md\:hover\:text-teal-600:hover { + color: #319795; + } + + .md\:hover\:text-teal-700:hover { + color: #2c7a7b; + } + + .md\:hover\:text-teal-800:hover { + color: #285e61; + } + + .md\:hover\:text-teal-900:hover { + color: #234e52; + } + + .md\:hover\:text-blue-100:hover { + color: #ebf8ff; + } + + .md\:hover\:text-blue-200:hover { + color: #bee3f8; + } + + .md\:hover\:text-blue-300:hover { + color: #90cdf4; + } + + .md\:hover\:text-blue-400:hover { + color: #63b3ed; + } + + .md\:hover\:text-blue-500:hover { + color: #4299e1; + } + + .md\:hover\:text-blue-600:hover { + color: #3182ce; + } + + .md\:hover\:text-blue-700:hover { + color: #2b6cb0; + } + + .md\:hover\:text-blue-800:hover { + color: #2c5282; + } + + .md\:hover\:text-blue-900:hover { + color: #2a4365; + } + + .md\:hover\:text-indigo-100:hover { + color: #ebf4ff; + } + + .md\:hover\:text-indigo-200:hover { + color: #c3dafe; + } + + .md\:hover\:text-indigo-300:hover { + color: #a3bffa; + } + + .md\:hover\:text-indigo-400:hover { + color: #7f9cf5; + } + + .md\:hover\:text-indigo-500:hover { + color: #667eea; + } + + .md\:hover\:text-indigo-600:hover { + color: #5a67d8; + } + + .md\:hover\:text-indigo-700:hover { + color: #4c51bf; + } + + .md\:hover\:text-indigo-800:hover { + color: #434190; + } + + .md\:hover\:text-indigo-900:hover { + color: #3c366b; + } + + .md\:hover\:text-purple-100:hover { + color: #faf5ff; + } + + .md\:hover\:text-purple-200:hover { + color: #e9d8fd; + } + + .md\:hover\:text-purple-300:hover { + color: #d6bcfa; + } + + .md\:hover\:text-purple-400:hover { + color: #b794f4; + } + + .md\:hover\:text-purple-500:hover { + color: #9f7aea; + } + + .md\:hover\:text-purple-600:hover { + color: #805ad5; + } + + .md\:hover\:text-purple-700:hover { + color: #6b46c1; + } + + .md\:hover\:text-purple-800:hover { + color: #553c9a; + } + + .md\:hover\:text-purple-900:hover { + color: #44337a; + } + + .md\:hover\:text-pink-100:hover { + color: #fff5f7; + } + + .md\:hover\:text-pink-200:hover { + color: #fed7e2; + } + + .md\:hover\:text-pink-300:hover { + color: #fbb6ce; + } + + .md\:hover\:text-pink-400:hover { + color: #f687b3; + } + + .md\:hover\:text-pink-500:hover { + color: #ed64a6; + } + + .md\:hover\:text-pink-600:hover { + color: #d53f8c; + } + + .md\:hover\:text-pink-700:hover { + color: #b83280; + } + + .md\:hover\:text-pink-800:hover { + color: #97266d; + } + + .md\:hover\:text-pink-900:hover { + color: #702459; + } + + .md\:focus\:text-transparent:focus { + color: transparent; + } + + .md\:focus\:text-black:focus { + color: #000; + } + + .md\:focus\:text-white:focus { + color: #fff; + } + + .md\:focus\:text-gray-100:focus { + color: #f7fafc; + } + + .md\:focus\:text-gray-200:focus { + color: #edf2f7; + } + + .md\:focus\:text-gray-300:focus { + color: #e2e8f0; + } + + .md\:focus\:text-gray-400:focus { + color: #cbd5e0; + } + + .md\:focus\:text-gray-500:focus { + color: #a0aec0; + } + + .md\:focus\:text-gray-600:focus { + color: #718096; + } + + .md\:focus\:text-gray-700:focus { + color: #4a5568; + } + + .md\:focus\:text-gray-800:focus { + color: #2d3748; + } + + .md\:focus\:text-gray-900:focus { + color: #1a202c; + } + + .md\:focus\:text-red-100:focus { + color: #fff5f5; + } + + .md\:focus\:text-red-200:focus { + color: #fed7d7; + } + + .md\:focus\:text-red-300:focus { + color: #feb2b2; + } + + .md\:focus\:text-red-400:focus { + color: #fc8181; + } + + .md\:focus\:text-red-500:focus { + color: #f56565; + } + + .md\:focus\:text-red-600:focus { + color: #e53e3e; + } + + .md\:focus\:text-red-700:focus { + color: #c53030; + } + + .md\:focus\:text-red-800:focus { + color: #9b2c2c; + } + + .md\:focus\:text-red-900:focus { + color: #742a2a; + } + + .md\:focus\:text-orange-100:focus { + color: #fffaf0; + } + + .md\:focus\:text-orange-200:focus { + color: #feebc8; + } + + .md\:focus\:text-orange-300:focus { + color: #fbd38d; + } + + .md\:focus\:text-orange-400:focus { + color: #f6ad55; + } + + .md\:focus\:text-orange-500:focus { + color: #ed8936; + } + + .md\:focus\:text-orange-600:focus { + color: #dd6b20; + } + + .md\:focus\:text-orange-700:focus { + color: #c05621; + } + + .md\:focus\:text-orange-800:focus { + color: #9c4221; + } + + .md\:focus\:text-orange-900:focus { + color: #7b341e; + } + + .md\:focus\:text-yellow-100:focus { + color: #fffff0; + } + + .md\:focus\:text-yellow-200:focus { + color: #fefcbf; + } + + .md\:focus\:text-yellow-300:focus { + color: #faf089; + } + + .md\:focus\:text-yellow-400:focus { + color: #f6e05e; + } + + .md\:focus\:text-yellow-500:focus { + color: #ecc94b; + } + + .md\:focus\:text-yellow-600:focus { + color: #d69e2e; + } + + .md\:focus\:text-yellow-700:focus { + color: #b7791f; + } + + .md\:focus\:text-yellow-800:focus { + color: #975a16; + } + + .md\:focus\:text-yellow-900:focus { + color: #744210; + } + + .md\:focus\:text-green-100:focus { + color: #f0fff4; + } + + .md\:focus\:text-green-200:focus { + color: #c6f6d5; + } + + .md\:focus\:text-green-300:focus { + color: #9ae6b4; + } + + .md\:focus\:text-green-400:focus { + color: #68d391; + } + + .md\:focus\:text-green-500:focus { + color: #48bb78; + } + + .md\:focus\:text-green-600:focus { + color: #38a169; + } + + .md\:focus\:text-green-700:focus { + color: #2f855a; + } + + .md\:focus\:text-green-800:focus { + color: #276749; + } + + .md\:focus\:text-green-900:focus { + color: #22543d; + } + + .md\:focus\:text-teal-100:focus { + color: #e6fffa; + } + + .md\:focus\:text-teal-200:focus { + color: #b2f5ea; + } + + .md\:focus\:text-teal-300:focus { + color: #81e6d9; + } + + .md\:focus\:text-teal-400:focus { + color: #4fd1c5; + } + + .md\:focus\:text-teal-500:focus { + color: #38b2ac; + } + + .md\:focus\:text-teal-600:focus { + color: #319795; + } + + .md\:focus\:text-teal-700:focus { + color: #2c7a7b; + } + + .md\:focus\:text-teal-800:focus { + color: #285e61; + } + + .md\:focus\:text-teal-900:focus { + color: #234e52; + } + + .md\:focus\:text-blue-100:focus { + color: #ebf8ff; + } + + .md\:focus\:text-blue-200:focus { + color: #bee3f8; + } + + .md\:focus\:text-blue-300:focus { + color: #90cdf4; + } + + .md\:focus\:text-blue-400:focus { + color: #63b3ed; + } + + .md\:focus\:text-blue-500:focus { + color: #4299e1; + } + + .md\:focus\:text-blue-600:focus { + color: #3182ce; + } + + .md\:focus\:text-blue-700:focus { + color: #2b6cb0; + } + + .md\:focus\:text-blue-800:focus { + color: #2c5282; + } + + .md\:focus\:text-blue-900:focus { + color: #2a4365; + } + + .md\:focus\:text-indigo-100:focus { + color: #ebf4ff; + } + + .md\:focus\:text-indigo-200:focus { + color: #c3dafe; + } + + .md\:focus\:text-indigo-300:focus { + color: #a3bffa; + } + + .md\:focus\:text-indigo-400:focus { + color: #7f9cf5; + } + + .md\:focus\:text-indigo-500:focus { + color: #667eea; + } + + .md\:focus\:text-indigo-600:focus { + color: #5a67d8; + } + + .md\:focus\:text-indigo-700:focus { + color: #4c51bf; + } + + .md\:focus\:text-indigo-800:focus { + color: #434190; + } + + .md\:focus\:text-indigo-900:focus { + color: #3c366b; + } + + .md\:focus\:text-purple-100:focus { + color: #faf5ff; + } + + .md\:focus\:text-purple-200:focus { + color: #e9d8fd; + } + + .md\:focus\:text-purple-300:focus { + color: #d6bcfa; + } + + .md\:focus\:text-purple-400:focus { + color: #b794f4; + } + + .md\:focus\:text-purple-500:focus { + color: #9f7aea; + } + + .md\:focus\:text-purple-600:focus { + color: #805ad5; + } + + .md\:focus\:text-purple-700:focus { + color: #6b46c1; + } + + .md\:focus\:text-purple-800:focus { + color: #553c9a; + } + + .md\:focus\:text-purple-900:focus { + color: #44337a; + } + + .md\:focus\:text-pink-100:focus { + color: #fff5f7; + } + + .md\:focus\:text-pink-200:focus { + color: #fed7e2; + } + + .md\:focus\:text-pink-300:focus { + color: #fbb6ce; + } + + .md\:focus\:text-pink-400:focus { + color: #f687b3; + } + + .md\:focus\:text-pink-500:focus { + color: #ed64a6; + } + + .md\:focus\:text-pink-600:focus { + color: #d53f8c; + } + + .md\:focus\:text-pink-700:focus { + color: #b83280; + } + + .md\:focus\:text-pink-800:focus { + color: #97266d; + } + + .md\:focus\:text-pink-900:focus { + color: #702459; + } + + .md\:text-xs { + font-size: 0.75rem; + } + + .md\:text-sm { + font-size: 0.875rem; + } + + .md\:text-base { + font-size: 1rem; + } + + .md\:text-lg { + font-size: 1.125rem; + } + + .md\:text-xl { + font-size: 1.25rem; + } + + .md\:text-2xl { + font-size: 1.5rem; + } + + .md\:text-3xl { + font-size: 1.875rem; + } + + .md\:text-4xl { + font-size: 2.25rem; + } + + .md\:text-5xl { + font-size: 3rem; + } + + .md\:text-6xl { + font-size: 4rem; + } + + .md\:italic { + font-style: italic; + } + + .md\:not-italic { + font-style: normal; + } + + .md\:uppercase { + text-transform: uppercase; + } + + .md\:lowercase { + text-transform: lowercase; + } + + .md\:capitalize { + text-transform: capitalize; + } + + .md\:normal-case { + text-transform: none; + } + + .md\:underline { + text-decoration: underline; + } + + .md\:line-through { + text-decoration: line-through; + } + + .md\:no-underline { + text-decoration: none; + } + + .md\:hover\:underline:hover { + text-decoration: underline; + } + + .md\:hover\:line-through:hover { + text-decoration: line-through; + } + + .md\:hover\:no-underline:hover { + text-decoration: none; + } + + .md\:focus\:underline:focus { + text-decoration: underline; + } + + .md\:focus\:line-through:focus { + text-decoration: line-through; + } + + .md\:focus\:no-underline:focus { + text-decoration: none; + } + + .md\:antialiased { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + + .md\:subpixel-antialiased { + -webkit-font-smoothing: auto; + -moz-osx-font-smoothing: auto; + } + + .md\:tracking-tighter { + letter-spacing: -0.05em; + } + + .md\:tracking-tight { + letter-spacing: -0.025em; + } + + .md\:tracking-normal { + letter-spacing: 0; + } + + .md\:tracking-wide { + letter-spacing: 0.025em; + } + + .md\:tracking-wider { + letter-spacing: 0.05em; + } + + .md\:tracking-widest { + letter-spacing: 0.1em; + } + + .md\:select-none { + -webkit-user-select: none; + user-select: none; + } + + .md\:select-text { + -webkit-user-select: text; + user-select: text; + } + + .md\:select-all { + -webkit-user-select: all; + user-select: all; + } + + .md\:select-auto { + -webkit-user-select: auto; + user-select: auto; + } + + .md\:align-baseline { + vertical-align: baseline; + } + + .md\:align-top { + vertical-align: top; + } + + .md\:align-middle { + vertical-align: middle; + } + + .md\:align-bottom { + vertical-align: bottom; + } + + .md\:align-text-top { + vertical-align: text-top; + } + + .md\:align-text-bottom { + vertical-align: text-bottom; + } + + .md\:visible { + visibility: visible; + } + + .md\:invisible { + visibility: hidden; + } + + .md\:whitespace-normal { + white-space: normal; + } + + .md\:whitespace-no-wrap { + white-space: nowrap; + } + + .md\:whitespace-pre { + white-space: pre; + } + + .md\:whitespace-pre-line { + white-space: pre-line; + } + + .md\:whitespace-pre-wrap { + white-space: pre-wrap; + } + + .md\:break-normal { + overflow-wrap: normal; + word-break: normal; + } + + .md\:break-words { + overflow-wrap: break-word; + } + + .md\:break-all { + word-break: break-all; + } + + .md\:truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .md\:w-0 { + width: 0; + } + + .md\:w-1 { + width: 0.25rem; + } + + .md\:w-2 { + width: 0.5rem; + } + + .md\:w-3 { + width: 0.75rem; + } + + .md\:w-4 { + width: 1rem; + } + + .md\:w-5 { + width: 1.25rem; + } + + .md\:w-6 { + width: 1.5rem; + } + + .md\:w-8 { + width: 2rem; + } + + .md\:w-10 { + width: 2.5rem; + } + + .md\:w-12 { + width: 3rem; + } + + .md\:w-16 { + width: 4rem; + } + + .md\:w-20 { + width: 5rem; + } + + .md\:w-24 { + width: 6rem; + } + + .md\:w-32 { + width: 8rem; + } + + .md\:w-40 { + width: 10rem; + } + + .md\:w-48 { + width: 12rem; + } + + .md\:w-56 { + width: 14rem; + } + + .md\:w-64 { + width: 16rem; + } + + .md\:w-auto { + width: auto; + } + + .md\:w-px { + width: 1px; + } + + .md\:w-1\/2 { + width: 50%; + } + + .md\:w-1\/3 { + width: 33.333333%; + } + + .md\:w-2\/3 { + width: 66.666667%; + } + + .md\:w-1\/4 { + width: 25%; + } + + .md\:w-2\/4 { + width: 50%; + } + + .md\:w-3\/4 { + width: 75%; + } + + .md\:w-1\/5 { + width: 20%; + } + + .md\:w-2\/5 { + width: 40%; + } + + .md\:w-3\/5 { + width: 60%; + } + + .md\:w-4\/5 { + width: 80%; + } + + .md\:w-1\/6 { + width: 16.666667%; + } + + .md\:w-2\/6 { + width: 33.333333%; + } + + .md\:w-3\/6 { + width: 50%; + } + + .md\:w-4\/6 { + width: 66.666667%; + } + + .md\:w-5\/6 { + width: 83.333333%; + } + + .md\:w-1\/12 { + width: 8.333333%; + } + + .md\:w-2\/12 { + width: 16.666667%; + } + + .md\:w-3\/12 { + width: 25%; + } + + .md\:w-4\/12 { + width: 33.333333%; + } + + .md\:w-5\/12 { + width: 41.666667%; + } + + .md\:w-6\/12 { + width: 50%; + } + + .md\:w-7\/12 { + width: 58.333333%; + } + + .md\:w-8\/12 { + width: 66.666667%; + } + + .md\:w-9\/12 { + width: 75%; + } + + .md\:w-10\/12 { + width: 83.333333%; + } + + .md\:w-11\/12 { + width: 91.666667%; + } + + .md\:w-full { + width: 100%; + } + + .md\:w-screen { + width: 100vw; + } + + .md\:z-0 { + z-index: 0; + } + + .md\:z-10 { + z-index: 10; + } + + .md\:z-20 { + z-index: 20; + } + + .md\:z-30 { + z-index: 30; + } + + .md\:z-40 { + z-index: 40; + } + + .md\:z-50 { + z-index: 50; + } + + .md\:z-auto { + z-index: auto; + } + + .md\:gap-0 { + grid-gap: 0; + gap: 0; + } + + .md\:gap-1 { + grid-gap: 0.25rem; + gap: 0.25rem; + } + + .md\:gap-2 { + grid-gap: 0.5rem; + gap: 0.5rem; + } + + .md\:gap-3 { + grid-gap: 0.75rem; + gap: 0.75rem; + } + + .md\:gap-4 { + grid-gap: 1rem; + gap: 1rem; + } + + .md\:gap-5 { + grid-gap: 1.25rem; + gap: 1.25rem; + } + + .md\:gap-6 { + grid-gap: 1.5rem; + gap: 1.5rem; + } + + .md\:gap-8 { + grid-gap: 2rem; + gap: 2rem; + } + + .md\:gap-10 { + grid-gap: 2.5rem; + gap: 2.5rem; + } + + .md\:gap-12 { + grid-gap: 3rem; + gap: 3rem; + } + + .md\:gap-16 { + grid-gap: 4rem; + gap: 4rem; + } + + .md\:gap-20 { + grid-gap: 5rem; + gap: 5rem; + } + + .md\:gap-24 { + grid-gap: 6rem; + gap: 6rem; + } + + .md\:gap-32 { + grid-gap: 8rem; + gap: 8rem; + } + + .md\:gap-40 { + grid-gap: 10rem; + gap: 10rem; + } + + .md\:gap-48 { + grid-gap: 12rem; + gap: 12rem; + } + + .md\:gap-56 { + grid-gap: 14rem; + gap: 14rem; + } + + .md\:gap-64 { + grid-gap: 16rem; + gap: 16rem; + } + + .md\:gap-px { + grid-gap: 1px; + gap: 1px; + } + + .md\:col-gap-0 { + grid-column-gap: 0; + column-gap: 0; + } + + .md\:col-gap-1 { + grid-column-gap: 0.25rem; + column-gap: 0.25rem; + } + + .md\:col-gap-2 { + grid-column-gap: 0.5rem; + column-gap: 0.5rem; + } + + .md\:col-gap-3 { + grid-column-gap: 0.75rem; + column-gap: 0.75rem; + } + + .md\:col-gap-4 { + grid-column-gap: 1rem; + column-gap: 1rem; + } + + .md\:col-gap-5 { + grid-column-gap: 1.25rem; + column-gap: 1.25rem; + } + + .md\:col-gap-6 { + grid-column-gap: 1.5rem; + column-gap: 1.5rem; + } + + .md\:col-gap-8 { + grid-column-gap: 2rem; + column-gap: 2rem; + } + + .md\:col-gap-10 { + grid-column-gap: 2.5rem; + column-gap: 2.5rem; + } + + .md\:col-gap-12 { + grid-column-gap: 3rem; + column-gap: 3rem; + } + + .md\:col-gap-16 { + grid-column-gap: 4rem; + column-gap: 4rem; + } + + .md\:col-gap-20 { + grid-column-gap: 5rem; + column-gap: 5rem; + } + + .md\:col-gap-24 { + grid-column-gap: 6rem; + column-gap: 6rem; + } + + .md\:col-gap-32 { + grid-column-gap: 8rem; + column-gap: 8rem; + } + + .md\:col-gap-40 { + grid-column-gap: 10rem; + column-gap: 10rem; + } + + .md\:col-gap-48 { + grid-column-gap: 12rem; + column-gap: 12rem; + } + + .md\:col-gap-56 { + grid-column-gap: 14rem; + column-gap: 14rem; + } + + .md\:col-gap-64 { + grid-column-gap: 16rem; + column-gap: 16rem; + } + + .md\:col-gap-px { + grid-column-gap: 1px; + column-gap: 1px; + } + + .md\:row-gap-0 { + grid-row-gap: 0; + row-gap: 0; + } + + .md\:row-gap-1 { + grid-row-gap: 0.25rem; + row-gap: 0.25rem; + } + + .md\:row-gap-2 { + grid-row-gap: 0.5rem; + row-gap: 0.5rem; + } + + .md\:row-gap-3 { + grid-row-gap: 0.75rem; + row-gap: 0.75rem; + } + + .md\:row-gap-4 { + grid-row-gap: 1rem; + row-gap: 1rem; + } + + .md\:row-gap-5 { + grid-row-gap: 1.25rem; + row-gap: 1.25rem; + } + + .md\:row-gap-6 { + grid-row-gap: 1.5rem; + row-gap: 1.5rem; + } + + .md\:row-gap-8 { + grid-row-gap: 2rem; + row-gap: 2rem; + } + + .md\:row-gap-10 { + grid-row-gap: 2.5rem; + row-gap: 2.5rem; + } + + .md\:row-gap-12 { + grid-row-gap: 3rem; + row-gap: 3rem; + } + + .md\:row-gap-16 { + grid-row-gap: 4rem; + row-gap: 4rem; + } + + .md\:row-gap-20 { + grid-row-gap: 5rem; + row-gap: 5rem; + } + + .md\:row-gap-24 { + grid-row-gap: 6rem; + row-gap: 6rem; + } + + .md\:row-gap-32 { + grid-row-gap: 8rem; + row-gap: 8rem; + } + + .md\:row-gap-40 { + grid-row-gap: 10rem; + row-gap: 10rem; + } + + .md\:row-gap-48 { + grid-row-gap: 12rem; + row-gap: 12rem; + } + + .md\:row-gap-56 { + grid-row-gap: 14rem; + row-gap: 14rem; + } + + .md\:row-gap-64 { + grid-row-gap: 16rem; + row-gap: 16rem; + } + + .md\:row-gap-px { + grid-row-gap: 1px; + row-gap: 1px; + } + + .md\:grid-flow-row { + grid-auto-flow: row; + } + + .md\:grid-flow-col { + grid-auto-flow: column; + } + + .md\:grid-flow-row-dense { + grid-auto-flow: row dense; + } + + .md\:grid-flow-col-dense { + grid-auto-flow: column dense; + } + + .md\:grid-cols-1 { + grid-template-columns: repeat(1, minmax(0, 1fr)); + } + + .md\:grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .md\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .md\:grid-cols-4 { + grid-template-columns: repeat(4, minmax(0, 1fr)); + } + + .md\:grid-cols-5 { + grid-template-columns: repeat(5, minmax(0, 1fr)); + } + + .md\:grid-cols-6 { + grid-template-columns: repeat(6, minmax(0, 1fr)); + } + + .md\:grid-cols-7 { + grid-template-columns: repeat(7, minmax(0, 1fr)); + } + + .md\:grid-cols-8 { + grid-template-columns: repeat(8, minmax(0, 1fr)); + } + + .md\:grid-cols-9 { + grid-template-columns: repeat(9, minmax(0, 1fr)); + } + + .md\:grid-cols-10 { + grid-template-columns: repeat(10, minmax(0, 1fr)); + } + + .md\:grid-cols-11 { + grid-template-columns: repeat(11, minmax(0, 1fr)); + } + + .md\:grid-cols-12 { + grid-template-columns: repeat(12, minmax(0, 1fr)); + } + + .md\:grid-cols-none { + grid-template-columns: none; + } + + .md\:col-auto { + grid-column: auto; + } + + .md\:col-span-1 { + grid-column: span 1 / span 1; + } + + .md\:col-span-2 { + grid-column: span 2 / span 2; + } + + .md\:col-span-3 { + grid-column: span 3 / span 3; + } + + .md\:col-span-4 { + grid-column: span 4 / span 4; + } + + .md\:col-span-5 { + grid-column: span 5 / span 5; + } + + .md\:col-span-6 { + grid-column: span 6 / span 6; + } + + .md\:col-span-7 { + grid-column: span 7 / span 7; + } + + .md\:col-span-8 { + grid-column: span 8 / span 8; + } + + .md\:col-span-9 { + grid-column: span 9 / span 9; + } + + .md\:col-span-10 { + grid-column: span 10 / span 10; + } + + .md\:col-span-11 { + grid-column: span 11 / span 11; + } + + .md\:col-span-12 { + grid-column: span 12 / span 12; + } + + .md\:col-start-1 { + grid-column-start: 1; + } + + .md\:col-start-2 { + grid-column-start: 2; + } + + .md\:col-start-3 { + grid-column-start: 3; + } + + .md\:col-start-4 { + grid-column-start: 4; + } + + .md\:col-start-5 { + grid-column-start: 5; + } + + .md\:col-start-6 { + grid-column-start: 6; + } + + .md\:col-start-7 { + grid-column-start: 7; + } + + .md\:col-start-8 { + grid-column-start: 8; + } + + .md\:col-start-9 { + grid-column-start: 9; + } + + .md\:col-start-10 { + grid-column-start: 10; + } + + .md\:col-start-11 { + grid-column-start: 11; + } + + .md\:col-start-12 { + grid-column-start: 12; + } + + .md\:col-start-13 { + grid-column-start: 13; + } + + .md\:col-start-auto { + grid-column-start: auto; + } + + .md\:col-end-1 { + grid-column-end: 1; + } + + .md\:col-end-2 { + grid-column-end: 2; + } + + .md\:col-end-3 { + grid-column-end: 3; + } + + .md\:col-end-4 { + grid-column-end: 4; + } + + .md\:col-end-5 { + grid-column-end: 5; + } + + .md\:col-end-6 { + grid-column-end: 6; + } + + .md\:col-end-7 { + grid-column-end: 7; + } + + .md\:col-end-8 { + grid-column-end: 8; + } + + .md\:col-end-9 { + grid-column-end: 9; + } + + .md\:col-end-10 { + grid-column-end: 10; + } + + .md\:col-end-11 { + grid-column-end: 11; + } + + .md\:col-end-12 { + grid-column-end: 12; + } + + .md\:col-end-13 { + grid-column-end: 13; + } + + .md\:col-end-auto { + grid-column-end: auto; + } + + .md\:grid-rows-1 { + grid-template-rows: repeat(1, minmax(0, 1fr)); + } + + .md\:grid-rows-2 { + grid-template-rows: repeat(2, minmax(0, 1fr)); + } + + .md\:grid-rows-3 { + grid-template-rows: repeat(3, minmax(0, 1fr)); + } + + .md\:grid-rows-4 { + grid-template-rows: repeat(4, minmax(0, 1fr)); + } + + .md\:grid-rows-5 { + grid-template-rows: repeat(5, minmax(0, 1fr)); + } + + .md\:grid-rows-6 { + grid-template-rows: repeat(6, minmax(0, 1fr)); + } + + .md\:grid-rows-none { + grid-template-rows: none; + } + + .md\:row-auto { + grid-row: auto; + } + + .md\:row-span-1 { + grid-row: span 1 / span 1; + } + + .md\:row-span-2 { + grid-row: span 2 / span 2; + } + + .md\:row-span-3 { + grid-row: span 3 / span 3; + } + + .md\:row-span-4 { + grid-row: span 4 / span 4; + } + + .md\:row-span-5 { + grid-row: span 5 / span 5; + } + + .md\:row-span-6 { + grid-row: span 6 / span 6; + } + + .md\:row-start-1 { + grid-row-start: 1; + } + + .md\:row-start-2 { + grid-row-start: 2; + } + + .md\:row-start-3 { + grid-row-start: 3; + } + + .md\:row-start-4 { + grid-row-start: 4; + } + + .md\:row-start-5 { + grid-row-start: 5; + } + + .md\:row-start-6 { + grid-row-start: 6; + } + + .md\:row-start-7 { + grid-row-start: 7; + } + + .md\:row-start-auto { + grid-row-start: auto; + } + + .md\:row-end-1 { + grid-row-end: 1; + } + + .md\:row-end-2 { + grid-row-end: 2; + } + + .md\:row-end-3 { + grid-row-end: 3; + } + + .md\:row-end-4 { + grid-row-end: 4; + } + + .md\:row-end-5 { + grid-row-end: 5; + } + + .md\:row-end-6 { + grid-row-end: 6; + } + + .md\:row-end-7 { + grid-row-end: 7; + } + + .md\:row-end-auto { + grid-row-end: auto; + } + + .md\:transform { + --transform-translate-x: 0; + --transform-translate-y: 0; + --transform-rotate: 0; + --transform-skew-x: 0; + --transform-skew-y: 0; + --transform-scale-x: 1; + --transform-scale-y: 1; + transform: translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y)); + } + + .md\:transform-none { + transform: none; + } + + .md\:origin-center { + transform-origin: center; + } + + .md\:origin-top { + transform-origin: top; + } + + .md\:origin-top-right { + transform-origin: top right; + } + + .md\:origin-right { + transform-origin: right; + } + + .md\:origin-bottom-right { + transform-origin: bottom right; + } + + .md\:origin-bottom { + transform-origin: bottom; + } + + .md\:origin-bottom-left { + transform-origin: bottom left; + } + + .md\:origin-left { + transform-origin: left; + } + + .md\:origin-top-left { + transform-origin: top left; + } + + .md\:scale-0 { + --transform-scale-x: 0; + --transform-scale-y: 0; + } + + .md\:scale-50 { + --transform-scale-x: .5; + --transform-scale-y: .5; + } + + .md\:scale-75 { + --transform-scale-x: .75; + --transform-scale-y: .75; + } + + .md\:scale-90 { + --transform-scale-x: .9; + --transform-scale-y: .9; + } + + .md\:scale-95 { + --transform-scale-x: .95; + --transform-scale-y: .95; + } + + .md\:scale-100 { + --transform-scale-x: 1; + --transform-scale-y: 1; + } + + .md\:scale-105 { + --transform-scale-x: 1.05; + --transform-scale-y: 1.05; + } + + .md\:scale-110 { + --transform-scale-x: 1.1; + --transform-scale-y: 1.1; + } + + .md\:scale-125 { + --transform-scale-x: 1.25; + --transform-scale-y: 1.25; + } + + .md\:scale-150 { + --transform-scale-x: 1.5; + --transform-scale-y: 1.5; + } + + .md\:scale-x-0 { + --transform-scale-x: 0; + } + + .md\:scale-x-50 { + --transform-scale-x: .5; + } + + .md\:scale-x-75 { + --transform-scale-x: .75; + } + + .md\:scale-x-90 { + --transform-scale-x: .9; + } + + .md\:scale-x-95 { + --transform-scale-x: .95; + } + + .md\:scale-x-100 { + --transform-scale-x: 1; + } + + .md\:scale-x-105 { + --transform-scale-x: 1.05; + } + + .md\:scale-x-110 { + --transform-scale-x: 1.1; + } + + .md\:scale-x-125 { + --transform-scale-x: 1.25; + } + + .md\:scale-x-150 { + --transform-scale-x: 1.5; + } + + .md\:scale-y-0 { + --transform-scale-y: 0; + } + + .md\:scale-y-50 { + --transform-scale-y: .5; + } + + .md\:scale-y-75 { + --transform-scale-y: .75; + } + + .md\:scale-y-90 { + --transform-scale-y: .9; + } + + .md\:scale-y-95 { + --transform-scale-y: .95; + } + + .md\:scale-y-100 { + --transform-scale-y: 1; + } + + .md\:scale-y-105 { + --transform-scale-y: 1.05; + } + + .md\:scale-y-110 { + --transform-scale-y: 1.1; + } + + .md\:scale-y-125 { + --transform-scale-y: 1.25; + } + + .md\:scale-y-150 { + --transform-scale-y: 1.5; + } + + .md\:hover\:scale-0:hover { + --transform-scale-x: 0; + --transform-scale-y: 0; + } + + .md\:hover\:scale-50:hover { + --transform-scale-x: .5; + --transform-scale-y: .5; + } + + .md\:hover\:scale-75:hover { + --transform-scale-x: .75; + --transform-scale-y: .75; + } + + .md\:hover\:scale-90:hover { + --transform-scale-x: .9; + --transform-scale-y: .9; + } + + .md\:hover\:scale-95:hover { + --transform-scale-x: .95; + --transform-scale-y: .95; + } + + .md\:hover\:scale-100:hover { + --transform-scale-x: 1; + --transform-scale-y: 1; + } + + .md\:hover\:scale-105:hover { + --transform-scale-x: 1.05; + --transform-scale-y: 1.05; + } + + .md\:hover\:scale-110:hover { + --transform-scale-x: 1.1; + --transform-scale-y: 1.1; + } + + .md\:hover\:scale-125:hover { + --transform-scale-x: 1.25; + --transform-scale-y: 1.25; + } + + .md\:hover\:scale-150:hover { + --transform-scale-x: 1.5; + --transform-scale-y: 1.5; + } + + .md\:hover\:scale-x-0:hover { + --transform-scale-x: 0; + } + + .md\:hover\:scale-x-50:hover { + --transform-scale-x: .5; + } + + .md\:hover\:scale-x-75:hover { + --transform-scale-x: .75; + } + + .md\:hover\:scale-x-90:hover { + --transform-scale-x: .9; + } + + .md\:hover\:scale-x-95:hover { + --transform-scale-x: .95; + } + + .md\:hover\:scale-x-100:hover { + --transform-scale-x: 1; + } + + .md\:hover\:scale-x-105:hover { + --transform-scale-x: 1.05; + } + + .md\:hover\:scale-x-110:hover { + --transform-scale-x: 1.1; + } + + .md\:hover\:scale-x-125:hover { + --transform-scale-x: 1.25; + } + + .md\:hover\:scale-x-150:hover { + --transform-scale-x: 1.5; + } + + .md\:hover\:scale-y-0:hover { + --transform-scale-y: 0; + } + + .md\:hover\:scale-y-50:hover { + --transform-scale-y: .5; + } + + .md\:hover\:scale-y-75:hover { + --transform-scale-y: .75; + } + + .md\:hover\:scale-y-90:hover { + --transform-scale-y: .9; + } + + .md\:hover\:scale-y-95:hover { + --transform-scale-y: .95; + } + + .md\:hover\:scale-y-100:hover { + --transform-scale-y: 1; + } + + .md\:hover\:scale-y-105:hover { + --transform-scale-y: 1.05; + } + + .md\:hover\:scale-y-110:hover { + --transform-scale-y: 1.1; + } + + .md\:hover\:scale-y-125:hover { + --transform-scale-y: 1.25; + } + + .md\:hover\:scale-y-150:hover { + --transform-scale-y: 1.5; + } + + .md\:focus\:scale-0:focus { + --transform-scale-x: 0; + --transform-scale-y: 0; + } + + .md\:focus\:scale-50:focus { + --transform-scale-x: .5; + --transform-scale-y: .5; + } + + .md\:focus\:scale-75:focus { + --transform-scale-x: .75; + --transform-scale-y: .75; + } + + .md\:focus\:scale-90:focus { + --transform-scale-x: .9; + --transform-scale-y: .9; + } + + .md\:focus\:scale-95:focus { + --transform-scale-x: .95; + --transform-scale-y: .95; + } + + .md\:focus\:scale-100:focus { + --transform-scale-x: 1; + --transform-scale-y: 1; + } + + .md\:focus\:scale-105:focus { + --transform-scale-x: 1.05; + --transform-scale-y: 1.05; + } + + .md\:focus\:scale-110:focus { + --transform-scale-x: 1.1; + --transform-scale-y: 1.1; + } + + .md\:focus\:scale-125:focus { + --transform-scale-x: 1.25; + --transform-scale-y: 1.25; + } + + .md\:focus\:scale-150:focus { + --transform-scale-x: 1.5; + --transform-scale-y: 1.5; + } + + .md\:focus\:scale-x-0:focus { + --transform-scale-x: 0; + } + + .md\:focus\:scale-x-50:focus { + --transform-scale-x: .5; + } + + .md\:focus\:scale-x-75:focus { + --transform-scale-x: .75; + } + + .md\:focus\:scale-x-90:focus { + --transform-scale-x: .9; + } + + .md\:focus\:scale-x-95:focus { + --transform-scale-x: .95; + } + + .md\:focus\:scale-x-100:focus { + --transform-scale-x: 1; + } + + .md\:focus\:scale-x-105:focus { + --transform-scale-x: 1.05; + } + + .md\:focus\:scale-x-110:focus { + --transform-scale-x: 1.1; + } + + .md\:focus\:scale-x-125:focus { + --transform-scale-x: 1.25; + } + + .md\:focus\:scale-x-150:focus { + --transform-scale-x: 1.5; + } + + .md\:focus\:scale-y-0:focus { + --transform-scale-y: 0; + } + + .md\:focus\:scale-y-50:focus { + --transform-scale-y: .5; + } + + .md\:focus\:scale-y-75:focus { + --transform-scale-y: .75; + } + + .md\:focus\:scale-y-90:focus { + --transform-scale-y: .9; + } + + .md\:focus\:scale-y-95:focus { + --transform-scale-y: .95; + } + + .md\:focus\:scale-y-100:focus { + --transform-scale-y: 1; + } + + .md\:focus\:scale-y-105:focus { + --transform-scale-y: 1.05; + } + + .md\:focus\:scale-y-110:focus { + --transform-scale-y: 1.1; + } + + .md\:focus\:scale-y-125:focus { + --transform-scale-y: 1.25; + } + + .md\:focus\:scale-y-150:focus { + --transform-scale-y: 1.5; + } + + .md\:rotate-0 { + --transform-rotate: 0; + } + + .md\:rotate-45 { + --transform-rotate: 45deg; + } + + .md\:rotate-90 { + --transform-rotate: 90deg; + } + + .md\:rotate-180 { + --transform-rotate: 180deg; + } + + .md\:-rotate-180 { + --transform-rotate: -180deg; + } + + .md\:-rotate-90 { + --transform-rotate: -90deg; + } + + .md\:-rotate-45 { + --transform-rotate: -45deg; + } + + .md\:hover\:rotate-0:hover { + --transform-rotate: 0; + } + + .md\:hover\:rotate-45:hover { + --transform-rotate: 45deg; + } + + .md\:hover\:rotate-90:hover { + --transform-rotate: 90deg; + } + + .md\:hover\:rotate-180:hover { + --transform-rotate: 180deg; + } + + .md\:hover\:-rotate-180:hover { + --transform-rotate: -180deg; + } + + .md\:hover\:-rotate-90:hover { + --transform-rotate: -90deg; + } + + .md\:hover\:-rotate-45:hover { + --transform-rotate: -45deg; + } + + .md\:focus\:rotate-0:focus { + --transform-rotate: 0; + } + + .md\:focus\:rotate-45:focus { + --transform-rotate: 45deg; + } + + .md\:focus\:rotate-90:focus { + --transform-rotate: 90deg; + } + + .md\:focus\:rotate-180:focus { + --transform-rotate: 180deg; + } + + .md\:focus\:-rotate-180:focus { + --transform-rotate: -180deg; + } + + .md\:focus\:-rotate-90:focus { + --transform-rotate: -90deg; + } + + .md\:focus\:-rotate-45:focus { + --transform-rotate: -45deg; + } + + .md\:translate-x-0 { + --transform-translate-x: 0; + } + + .md\:translate-x-1 { + --transform-translate-x: 0.25rem; + } + + .md\:translate-x-2 { + --transform-translate-x: 0.5rem; + } + + .md\:translate-x-3 { + --transform-translate-x: 0.75rem; + } + + .md\:translate-x-4 { + --transform-translate-x: 1rem; + } + + .md\:translate-x-5 { + --transform-translate-x: 1.25rem; + } + + .md\:translate-x-6 { + --transform-translate-x: 1.5rem; + } + + .md\:translate-x-8 { + --transform-translate-x: 2rem; + } + + .md\:translate-x-10 { + --transform-translate-x: 2.5rem; + } + + .md\:translate-x-12 { + --transform-translate-x: 3rem; + } + + .md\:translate-x-16 { + --transform-translate-x: 4rem; + } + + .md\:translate-x-20 { + --transform-translate-x: 5rem; + } + + .md\:translate-x-24 { + --transform-translate-x: 6rem; + } + + .md\:translate-x-32 { + --transform-translate-x: 8rem; + } + + .md\:translate-x-40 { + --transform-translate-x: 10rem; + } + + .md\:translate-x-48 { + --transform-translate-x: 12rem; + } + + .md\:translate-x-56 { + --transform-translate-x: 14rem; + } + + .md\:translate-x-64 { + --transform-translate-x: 16rem; + } + + .md\:translate-x-px { + --transform-translate-x: 1px; + } + + .md\:-translate-x-1 { + --transform-translate-x: -0.25rem; + } + + .md\:-translate-x-2 { + --transform-translate-x: -0.5rem; + } + + .md\:-translate-x-3 { + --transform-translate-x: -0.75rem; + } + + .md\:-translate-x-4 { + --transform-translate-x: -1rem; + } + + .md\:-translate-x-5 { + --transform-translate-x: -1.25rem; + } + + .md\:-translate-x-6 { + --transform-translate-x: -1.5rem; + } + + .md\:-translate-x-8 { + --transform-translate-x: -2rem; + } + + .md\:-translate-x-10 { + --transform-translate-x: -2.5rem; + } + + .md\:-translate-x-12 { + --transform-translate-x: -3rem; + } + + .md\:-translate-x-16 { + --transform-translate-x: -4rem; + } + + .md\:-translate-x-20 { + --transform-translate-x: -5rem; + } + + .md\:-translate-x-24 { + --transform-translate-x: -6rem; + } + + .md\:-translate-x-32 { + --transform-translate-x: -8rem; + } + + .md\:-translate-x-40 { + --transform-translate-x: -10rem; + } + + .md\:-translate-x-48 { + --transform-translate-x: -12rem; + } + + .md\:-translate-x-56 { + --transform-translate-x: -14rem; + } + + .md\:-translate-x-64 { + --transform-translate-x: -16rem; + } + + .md\:-translate-x-px { + --transform-translate-x: -1px; + } + + .md\:-translate-x-full { + --transform-translate-x: -100%; + } + + .md\:-translate-x-1\/2 { + --transform-translate-x: -50%; + } + + .md\:translate-x-1\/2 { + --transform-translate-x: 50%; + } + + .md\:translate-x-full { + --transform-translate-x: 100%; + } + + .md\:translate-y-0 { + --transform-translate-y: 0; + } + + .md\:translate-y-1 { + --transform-translate-y: 0.25rem; + } + + .md\:translate-y-2 { + --transform-translate-y: 0.5rem; + } + + .md\:translate-y-3 { + --transform-translate-y: 0.75rem; + } + + .md\:translate-y-4 { + --transform-translate-y: 1rem; + } + + .md\:translate-y-5 { + --transform-translate-y: 1.25rem; + } + + .md\:translate-y-6 { + --transform-translate-y: 1.5rem; + } + + .md\:translate-y-8 { + --transform-translate-y: 2rem; + } + + .md\:translate-y-10 { + --transform-translate-y: 2.5rem; + } + + .md\:translate-y-12 { + --transform-translate-y: 3rem; + } + + .md\:translate-y-16 { + --transform-translate-y: 4rem; + } + + .md\:translate-y-20 { + --transform-translate-y: 5rem; + } + + .md\:translate-y-24 { + --transform-translate-y: 6rem; + } + + .md\:translate-y-32 { + --transform-translate-y: 8rem; + } + + .md\:translate-y-40 { + --transform-translate-y: 10rem; + } + + .md\:translate-y-48 { + --transform-translate-y: 12rem; + } + + .md\:translate-y-56 { + --transform-translate-y: 14rem; + } + + .md\:translate-y-64 { + --transform-translate-y: 16rem; + } + + .md\:translate-y-px { + --transform-translate-y: 1px; + } + + .md\:-translate-y-1 { + --transform-translate-y: -0.25rem; + } + + .md\:-translate-y-2 { + --transform-translate-y: -0.5rem; + } + + .md\:-translate-y-3 { + --transform-translate-y: -0.75rem; + } + + .md\:-translate-y-4 { + --transform-translate-y: -1rem; + } + + .md\:-translate-y-5 { + --transform-translate-y: -1.25rem; + } + + .md\:-translate-y-6 { + --transform-translate-y: -1.5rem; + } + + .md\:-translate-y-8 { + --transform-translate-y: -2rem; + } + + .md\:-translate-y-10 { + --transform-translate-y: -2.5rem; + } + + .md\:-translate-y-12 { + --transform-translate-y: -3rem; + } + + .md\:-translate-y-16 { + --transform-translate-y: -4rem; + } + + .md\:-translate-y-20 { + --transform-translate-y: -5rem; + } + + .md\:-translate-y-24 { + --transform-translate-y: -6rem; + } + + .md\:-translate-y-32 { + --transform-translate-y: -8rem; + } + + .md\:-translate-y-40 { + --transform-translate-y: -10rem; + } + + .md\:-translate-y-48 { + --transform-translate-y: -12rem; + } + + .md\:-translate-y-56 { + --transform-translate-y: -14rem; + } + + .md\:-translate-y-64 { + --transform-translate-y: -16rem; + } + + .md\:-translate-y-px { + --transform-translate-y: -1px; + } + + .md\:-translate-y-full { + --transform-translate-y: -100%; + } + + .md\:-translate-y-1\/2 { + --transform-translate-y: -50%; + } + + .md\:translate-y-1\/2 { + --transform-translate-y: 50%; + } + + .md\:translate-y-full { + --transform-translate-y: 100%; + } + + .md\:hover\:translate-x-0:hover { + --transform-translate-x: 0; + } + + .md\:hover\:translate-x-1:hover { + --transform-translate-x: 0.25rem; + } + + .md\:hover\:translate-x-2:hover { + --transform-translate-x: 0.5rem; + } + + .md\:hover\:translate-x-3:hover { + --transform-translate-x: 0.75rem; + } + + .md\:hover\:translate-x-4:hover { + --transform-translate-x: 1rem; + } + + .md\:hover\:translate-x-5:hover { + --transform-translate-x: 1.25rem; + } + + .md\:hover\:translate-x-6:hover { + --transform-translate-x: 1.5rem; + } + + .md\:hover\:translate-x-8:hover { + --transform-translate-x: 2rem; + } + + .md\:hover\:translate-x-10:hover { + --transform-translate-x: 2.5rem; + } + + .md\:hover\:translate-x-12:hover { + --transform-translate-x: 3rem; + } + + .md\:hover\:translate-x-16:hover { + --transform-translate-x: 4rem; + } + + .md\:hover\:translate-x-20:hover { + --transform-translate-x: 5rem; + } + + .md\:hover\:translate-x-24:hover { + --transform-translate-x: 6rem; + } + + .md\:hover\:translate-x-32:hover { + --transform-translate-x: 8rem; + } + + .md\:hover\:translate-x-40:hover { + --transform-translate-x: 10rem; + } + + .md\:hover\:translate-x-48:hover { + --transform-translate-x: 12rem; + } + + .md\:hover\:translate-x-56:hover { + --transform-translate-x: 14rem; + } + + .md\:hover\:translate-x-64:hover { + --transform-translate-x: 16rem; + } + + .md\:hover\:translate-x-px:hover { + --transform-translate-x: 1px; + } + + .md\:hover\:-translate-x-1:hover { + --transform-translate-x: -0.25rem; + } + + .md\:hover\:-translate-x-2:hover { + --transform-translate-x: -0.5rem; + } + + .md\:hover\:-translate-x-3:hover { + --transform-translate-x: -0.75rem; + } + + .md\:hover\:-translate-x-4:hover { + --transform-translate-x: -1rem; + } + + .md\:hover\:-translate-x-5:hover { + --transform-translate-x: -1.25rem; + } + + .md\:hover\:-translate-x-6:hover { + --transform-translate-x: -1.5rem; + } + + .md\:hover\:-translate-x-8:hover { + --transform-translate-x: -2rem; + } + + .md\:hover\:-translate-x-10:hover { + --transform-translate-x: -2.5rem; + } + + .md\:hover\:-translate-x-12:hover { + --transform-translate-x: -3rem; + } + + .md\:hover\:-translate-x-16:hover { + --transform-translate-x: -4rem; + } + + .md\:hover\:-translate-x-20:hover { + --transform-translate-x: -5rem; + } + + .md\:hover\:-translate-x-24:hover { + --transform-translate-x: -6rem; + } + + .md\:hover\:-translate-x-32:hover { + --transform-translate-x: -8rem; + } + + .md\:hover\:-translate-x-40:hover { + --transform-translate-x: -10rem; + } + + .md\:hover\:-translate-x-48:hover { + --transform-translate-x: -12rem; + } + + .md\:hover\:-translate-x-56:hover { + --transform-translate-x: -14rem; + } + + .md\:hover\:-translate-x-64:hover { + --transform-translate-x: -16rem; + } + + .md\:hover\:-translate-x-px:hover { + --transform-translate-x: -1px; + } + + .md\:hover\:-translate-x-full:hover { + --transform-translate-x: -100%; + } + + .md\:hover\:-translate-x-1\/2:hover { + --transform-translate-x: -50%; + } + + .md\:hover\:translate-x-1\/2:hover { + --transform-translate-x: 50%; + } + + .md\:hover\:translate-x-full:hover { + --transform-translate-x: 100%; + } + + .md\:hover\:translate-y-0:hover { + --transform-translate-y: 0; + } + + .md\:hover\:translate-y-1:hover { + --transform-translate-y: 0.25rem; + } + + .md\:hover\:translate-y-2:hover { + --transform-translate-y: 0.5rem; + } + + .md\:hover\:translate-y-3:hover { + --transform-translate-y: 0.75rem; + } + + .md\:hover\:translate-y-4:hover { + --transform-translate-y: 1rem; + } + + .md\:hover\:translate-y-5:hover { + --transform-translate-y: 1.25rem; + } + + .md\:hover\:translate-y-6:hover { + --transform-translate-y: 1.5rem; + } + + .md\:hover\:translate-y-8:hover { + --transform-translate-y: 2rem; + } + + .md\:hover\:translate-y-10:hover { + --transform-translate-y: 2.5rem; + } + + .md\:hover\:translate-y-12:hover { + --transform-translate-y: 3rem; + } + + .md\:hover\:translate-y-16:hover { + --transform-translate-y: 4rem; + } + + .md\:hover\:translate-y-20:hover { + --transform-translate-y: 5rem; + } + + .md\:hover\:translate-y-24:hover { + --transform-translate-y: 6rem; + } + + .md\:hover\:translate-y-32:hover { + --transform-translate-y: 8rem; + } + + .md\:hover\:translate-y-40:hover { + --transform-translate-y: 10rem; + } + + .md\:hover\:translate-y-48:hover { + --transform-translate-y: 12rem; + } + + .md\:hover\:translate-y-56:hover { + --transform-translate-y: 14rem; + } + + .md\:hover\:translate-y-64:hover { + --transform-translate-y: 16rem; + } + + .md\:hover\:translate-y-px:hover { + --transform-translate-y: 1px; + } + + .md\:hover\:-translate-y-1:hover { + --transform-translate-y: -0.25rem; + } + + .md\:hover\:-translate-y-2:hover { + --transform-translate-y: -0.5rem; + } + + .md\:hover\:-translate-y-3:hover { + --transform-translate-y: -0.75rem; + } + + .md\:hover\:-translate-y-4:hover { + --transform-translate-y: -1rem; + } + + .md\:hover\:-translate-y-5:hover { + --transform-translate-y: -1.25rem; + } + + .md\:hover\:-translate-y-6:hover { + --transform-translate-y: -1.5rem; + } + + .md\:hover\:-translate-y-8:hover { + --transform-translate-y: -2rem; + } + + .md\:hover\:-translate-y-10:hover { + --transform-translate-y: -2.5rem; + } + + .md\:hover\:-translate-y-12:hover { + --transform-translate-y: -3rem; + } + + .md\:hover\:-translate-y-16:hover { + --transform-translate-y: -4rem; + } + + .md\:hover\:-translate-y-20:hover { + --transform-translate-y: -5rem; + } + + .md\:hover\:-translate-y-24:hover { + --transform-translate-y: -6rem; + } + + .md\:hover\:-translate-y-32:hover { + --transform-translate-y: -8rem; + } + + .md\:hover\:-translate-y-40:hover { + --transform-translate-y: -10rem; + } + + .md\:hover\:-translate-y-48:hover { + --transform-translate-y: -12rem; + } + + .md\:hover\:-translate-y-56:hover { + --transform-translate-y: -14rem; + } + + .md\:hover\:-translate-y-64:hover { + --transform-translate-y: -16rem; + } + + .md\:hover\:-translate-y-px:hover { + --transform-translate-y: -1px; + } + + .md\:hover\:-translate-y-full:hover { + --transform-translate-y: -100%; + } + + .md\:hover\:-translate-y-1\/2:hover { + --transform-translate-y: -50%; + } + + .md\:hover\:translate-y-1\/2:hover { + --transform-translate-y: 50%; + } + + .md\:hover\:translate-y-full:hover { + --transform-translate-y: 100%; + } + + .md\:focus\:translate-x-0:focus { + --transform-translate-x: 0; + } + + .md\:focus\:translate-x-1:focus { + --transform-translate-x: 0.25rem; + } + + .md\:focus\:translate-x-2:focus { + --transform-translate-x: 0.5rem; + } + + .md\:focus\:translate-x-3:focus { + --transform-translate-x: 0.75rem; + } + + .md\:focus\:translate-x-4:focus { + --transform-translate-x: 1rem; + } + + .md\:focus\:translate-x-5:focus { + --transform-translate-x: 1.25rem; + } + + .md\:focus\:translate-x-6:focus { + --transform-translate-x: 1.5rem; + } + + .md\:focus\:translate-x-8:focus { + --transform-translate-x: 2rem; + } + + .md\:focus\:translate-x-10:focus { + --transform-translate-x: 2.5rem; + } + + .md\:focus\:translate-x-12:focus { + --transform-translate-x: 3rem; + } + + .md\:focus\:translate-x-16:focus { + --transform-translate-x: 4rem; + } + + .md\:focus\:translate-x-20:focus { + --transform-translate-x: 5rem; + } + + .md\:focus\:translate-x-24:focus { + --transform-translate-x: 6rem; + } + + .md\:focus\:translate-x-32:focus { + --transform-translate-x: 8rem; + } + + .md\:focus\:translate-x-40:focus { + --transform-translate-x: 10rem; + } + + .md\:focus\:translate-x-48:focus { + --transform-translate-x: 12rem; + } + + .md\:focus\:translate-x-56:focus { + --transform-translate-x: 14rem; + } + + .md\:focus\:translate-x-64:focus { + --transform-translate-x: 16rem; + } + + .md\:focus\:translate-x-px:focus { + --transform-translate-x: 1px; + } + + .md\:focus\:-translate-x-1:focus { + --transform-translate-x: -0.25rem; + } + + .md\:focus\:-translate-x-2:focus { + --transform-translate-x: -0.5rem; + } + + .md\:focus\:-translate-x-3:focus { + --transform-translate-x: -0.75rem; + } + + .md\:focus\:-translate-x-4:focus { + --transform-translate-x: -1rem; + } + + .md\:focus\:-translate-x-5:focus { + --transform-translate-x: -1.25rem; + } + + .md\:focus\:-translate-x-6:focus { + --transform-translate-x: -1.5rem; + } + + .md\:focus\:-translate-x-8:focus { + --transform-translate-x: -2rem; + } + + .md\:focus\:-translate-x-10:focus { + --transform-translate-x: -2.5rem; + } + + .md\:focus\:-translate-x-12:focus { + --transform-translate-x: -3rem; + } + + .md\:focus\:-translate-x-16:focus { + --transform-translate-x: -4rem; + } + + .md\:focus\:-translate-x-20:focus { + --transform-translate-x: -5rem; + } + + .md\:focus\:-translate-x-24:focus { + --transform-translate-x: -6rem; + } + + .md\:focus\:-translate-x-32:focus { + --transform-translate-x: -8rem; + } + + .md\:focus\:-translate-x-40:focus { + --transform-translate-x: -10rem; + } + + .md\:focus\:-translate-x-48:focus { + --transform-translate-x: -12rem; + } + + .md\:focus\:-translate-x-56:focus { + --transform-translate-x: -14rem; + } + + .md\:focus\:-translate-x-64:focus { + --transform-translate-x: -16rem; + } + + .md\:focus\:-translate-x-px:focus { + --transform-translate-x: -1px; + } + + .md\:focus\:-translate-x-full:focus { + --transform-translate-x: -100%; + } + + .md\:focus\:-translate-x-1\/2:focus { + --transform-translate-x: -50%; + } + + .md\:focus\:translate-x-1\/2:focus { + --transform-translate-x: 50%; + } + + .md\:focus\:translate-x-full:focus { + --transform-translate-x: 100%; + } + + .md\:focus\:translate-y-0:focus { + --transform-translate-y: 0; + } + + .md\:focus\:translate-y-1:focus { + --transform-translate-y: 0.25rem; + } + + .md\:focus\:translate-y-2:focus { + --transform-translate-y: 0.5rem; + } + + .md\:focus\:translate-y-3:focus { + --transform-translate-y: 0.75rem; + } + + .md\:focus\:translate-y-4:focus { + --transform-translate-y: 1rem; + } + + .md\:focus\:translate-y-5:focus { + --transform-translate-y: 1.25rem; + } + + .md\:focus\:translate-y-6:focus { + --transform-translate-y: 1.5rem; + } + + .md\:focus\:translate-y-8:focus { + --transform-translate-y: 2rem; + } + + .md\:focus\:translate-y-10:focus { + --transform-translate-y: 2.5rem; + } + + .md\:focus\:translate-y-12:focus { + --transform-translate-y: 3rem; + } + + .md\:focus\:translate-y-16:focus { + --transform-translate-y: 4rem; + } + + .md\:focus\:translate-y-20:focus { + --transform-translate-y: 5rem; + } + + .md\:focus\:translate-y-24:focus { + --transform-translate-y: 6rem; + } + + .md\:focus\:translate-y-32:focus { + --transform-translate-y: 8rem; + } + + .md\:focus\:translate-y-40:focus { + --transform-translate-y: 10rem; + } + + .md\:focus\:translate-y-48:focus { + --transform-translate-y: 12rem; + } + + .md\:focus\:translate-y-56:focus { + --transform-translate-y: 14rem; + } + + .md\:focus\:translate-y-64:focus { + --transform-translate-y: 16rem; + } + + .md\:focus\:translate-y-px:focus { + --transform-translate-y: 1px; + } + + .md\:focus\:-translate-y-1:focus { + --transform-translate-y: -0.25rem; + } + + .md\:focus\:-translate-y-2:focus { + --transform-translate-y: -0.5rem; + } + + .md\:focus\:-translate-y-3:focus { + --transform-translate-y: -0.75rem; + } + + .md\:focus\:-translate-y-4:focus { + --transform-translate-y: -1rem; + } + + .md\:focus\:-translate-y-5:focus { + --transform-translate-y: -1.25rem; + } + + .md\:focus\:-translate-y-6:focus { + --transform-translate-y: -1.5rem; + } + + .md\:focus\:-translate-y-8:focus { + --transform-translate-y: -2rem; + } + + .md\:focus\:-translate-y-10:focus { + --transform-translate-y: -2.5rem; + } + + .md\:focus\:-translate-y-12:focus { + --transform-translate-y: -3rem; + } + + .md\:focus\:-translate-y-16:focus { + --transform-translate-y: -4rem; + } + + .md\:focus\:-translate-y-20:focus { + --transform-translate-y: -5rem; + } + + .md\:focus\:-translate-y-24:focus { + --transform-translate-y: -6rem; + } + + .md\:focus\:-translate-y-32:focus { + --transform-translate-y: -8rem; + } + + .md\:focus\:-translate-y-40:focus { + --transform-translate-y: -10rem; + } + + .md\:focus\:-translate-y-48:focus { + --transform-translate-y: -12rem; + } + + .md\:focus\:-translate-y-56:focus { + --transform-translate-y: -14rem; + } + + .md\:focus\:-translate-y-64:focus { + --transform-translate-y: -16rem; + } + + .md\:focus\:-translate-y-px:focus { + --transform-translate-y: -1px; + } + + .md\:focus\:-translate-y-full:focus { + --transform-translate-y: -100%; + } + + .md\:focus\:-translate-y-1\/2:focus { + --transform-translate-y: -50%; + } + + .md\:focus\:translate-y-1\/2:focus { + --transform-translate-y: 50%; + } + + .md\:focus\:translate-y-full:focus { + --transform-translate-y: 100%; + } + + .md\:skew-x-0 { + --transform-skew-x: 0; + } + + .md\:skew-x-3 { + --transform-skew-x: 3deg; + } + + .md\:skew-x-6 { + --transform-skew-x: 6deg; + } + + .md\:skew-x-12 { + --transform-skew-x: 12deg; + } + + .md\:-skew-x-12 { + --transform-skew-x: -12deg; + } + + .md\:-skew-x-6 { + --transform-skew-x: -6deg; + } + + .md\:-skew-x-3 { + --transform-skew-x: -3deg; + } + + .md\:skew-y-0 { + --transform-skew-y: 0; + } + + .md\:skew-y-3 { + --transform-skew-y: 3deg; + } + + .md\:skew-y-6 { + --transform-skew-y: 6deg; + } + + .md\:skew-y-12 { + --transform-skew-y: 12deg; + } + + .md\:-skew-y-12 { + --transform-skew-y: -12deg; + } + + .md\:-skew-y-6 { + --transform-skew-y: -6deg; + } + + .md\:-skew-y-3 { + --transform-skew-y: -3deg; + } + + .md\:hover\:skew-x-0:hover { + --transform-skew-x: 0; + } + + .md\:hover\:skew-x-3:hover { + --transform-skew-x: 3deg; + } + + .md\:hover\:skew-x-6:hover { + --transform-skew-x: 6deg; + } + + .md\:hover\:skew-x-12:hover { + --transform-skew-x: 12deg; + } + + .md\:hover\:-skew-x-12:hover { + --transform-skew-x: -12deg; + } + + .md\:hover\:-skew-x-6:hover { + --transform-skew-x: -6deg; + } + + .md\:hover\:-skew-x-3:hover { + --transform-skew-x: -3deg; + } + + .md\:hover\:skew-y-0:hover { + --transform-skew-y: 0; + } + + .md\:hover\:skew-y-3:hover { + --transform-skew-y: 3deg; + } + + .md\:hover\:skew-y-6:hover { + --transform-skew-y: 6deg; + } + + .md\:hover\:skew-y-12:hover { + --transform-skew-y: 12deg; + } + + .md\:hover\:-skew-y-12:hover { + --transform-skew-y: -12deg; + } + + .md\:hover\:-skew-y-6:hover { + --transform-skew-y: -6deg; + } + + .md\:hover\:-skew-y-3:hover { + --transform-skew-y: -3deg; + } + + .md\:focus\:skew-x-0:focus { + --transform-skew-x: 0; + } + + .md\:focus\:skew-x-3:focus { + --transform-skew-x: 3deg; + } + + .md\:focus\:skew-x-6:focus { + --transform-skew-x: 6deg; + } + + .md\:focus\:skew-x-12:focus { + --transform-skew-x: 12deg; + } + + .md\:focus\:-skew-x-12:focus { + --transform-skew-x: -12deg; + } + + .md\:focus\:-skew-x-6:focus { + --transform-skew-x: -6deg; + } + + .md\:focus\:-skew-x-3:focus { + --transform-skew-x: -3deg; + } + + .md\:focus\:skew-y-0:focus { + --transform-skew-y: 0; + } + + .md\:focus\:skew-y-3:focus { + --transform-skew-y: 3deg; + } + + .md\:focus\:skew-y-6:focus { + --transform-skew-y: 6deg; + } + + .md\:focus\:skew-y-12:focus { + --transform-skew-y: 12deg; + } + + .md\:focus\:-skew-y-12:focus { + --transform-skew-y: -12deg; + } + + .md\:focus\:-skew-y-6:focus { + --transform-skew-y: -6deg; + } + + .md\:focus\:-skew-y-3:focus { + --transform-skew-y: -3deg; + } + + .md\:transition-none { + transition-property: none; + } + + .md\:transition-all { + transition-property: all; + } + + .md\:transition { + transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform; + } + + .md\:transition-colors { + transition-property: background-color, border-color, color, fill, stroke; + } + + .md\:transition-opacity { + transition-property: opacity; + } + + .md\:transition-shadow { + transition-property: box-shadow; + } + + .md\:transition-transform { + transition-property: transform; + } + + .md\:ease-linear { + transition-timing-function: linear; + } + + .md\:ease-in { + transition-timing-function: cubic-bezier(0.4, 0, 1, 1); + } + + .md\:ease-out { + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + } + + .md\:ease-in-out { + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + } + + .md\:duration-75 { + transition-duration: 75ms; + } + + .md\:duration-100 { + transition-duration: 100ms; + } + + .md\:duration-150 { + transition-duration: 150ms; + } + + .md\:duration-200 { + transition-duration: 200ms; + } + + .md\:duration-300 { + transition-duration: 300ms; + } + + .md\:duration-500 { + transition-duration: 500ms; + } + + .md\:duration-700 { + transition-duration: 700ms; + } + + .md\:duration-1000 { + transition-duration: 1000ms; + } +} + +@media (min-width: 1024px) { + .lg\:sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; + } + + .lg\:not-sr-only { + position: static; + width: auto; + height: auto; + padding: 0; + margin: 0; + overflow: visible; + clip: auto; + white-space: normal; + } + + .lg\:focus\:sr-only:focus { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; + } + + .lg\:focus\:not-sr-only:focus { + position: static; + width: auto; + height: auto; + padding: 0; + margin: 0; + overflow: visible; + clip: auto; + white-space: normal; + } + + .lg\:appearance-none { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + } + + .lg\:bg-fixed { + background-attachment: fixed; + } + + .lg\:bg-local { + background-attachment: local; + } + + .lg\:bg-scroll { + background-attachment: scroll; + } + + .lg\:bg-transparent { + background-color: transparent; + } + + .lg\:bg-black { + background-color: #000; + } + + .lg\:bg-white { + background-color: #fff; + } + + .lg\:bg-gray-100 { + background-color: #f7fafc; + } + + .lg\:bg-gray-200 { + background-color: #edf2f7; + } + + .lg\:bg-gray-300 { + background-color: #e2e8f0; + } + + .lg\:bg-gray-400 { + background-color: #cbd5e0; + } + + .lg\:bg-gray-500 { + background-color: #a0aec0; + } + + .lg\:bg-gray-600 { + background-color: #718096; + } + + .lg\:bg-gray-700 { + background-color: #4a5568; + } + + .lg\:bg-gray-800 { + background-color: #2d3748; + } + + .lg\:bg-gray-900 { + background-color: #1a202c; + } + + .lg\:bg-red-100 { + background-color: #fff5f5; + } + + .lg\:bg-red-200 { + background-color: #fed7d7; + } + + .lg\:bg-red-300 { + background-color: #feb2b2; + } + + .lg\:bg-red-400 { + background-color: #fc8181; + } + + .lg\:bg-red-500 { + background-color: #f56565; + } + + .lg\:bg-red-600 { + background-color: #e53e3e; + } + + .lg\:bg-red-700 { + background-color: #c53030; + } + + .lg\:bg-red-800 { + background-color: #9b2c2c; + } + + .lg\:bg-red-900 { + background-color: #742a2a; + } + + .lg\:bg-orange-100 { + background-color: #fffaf0; + } + + .lg\:bg-orange-200 { + background-color: #feebc8; + } + + .lg\:bg-orange-300 { + background-color: #fbd38d; + } + + .lg\:bg-orange-400 { + background-color: #f6ad55; + } + + .lg\:bg-orange-500 { + background-color: #ed8936; + } + + .lg\:bg-orange-600 { + background-color: #dd6b20; + } + + .lg\:bg-orange-700 { + background-color: #c05621; + } + + .lg\:bg-orange-800 { + background-color: #9c4221; + } + + .lg\:bg-orange-900 { + background-color: #7b341e; + } + + .lg\:bg-yellow-100 { + background-color: #fffff0; + } + + .lg\:bg-yellow-200 { + background-color: #fefcbf; + } + + .lg\:bg-yellow-300 { + background-color: #faf089; + } + + .lg\:bg-yellow-400 { + background-color: #f6e05e; + } + + .lg\:bg-yellow-500 { + background-color: #ecc94b; + } + + .lg\:bg-yellow-600 { + background-color: #d69e2e; + } + + .lg\:bg-yellow-700 { + background-color: #b7791f; + } + + .lg\:bg-yellow-800 { + background-color: #975a16; + } + + .lg\:bg-yellow-900 { + background-color: #744210; + } + + .lg\:bg-green-100 { + background-color: #f0fff4; + } + + .lg\:bg-green-200 { + background-color: #c6f6d5; + } + + .lg\:bg-green-300 { + background-color: #9ae6b4; + } + + .lg\:bg-green-400 { + background-color: #68d391; + } + + .lg\:bg-green-500 { + background-color: #48bb78; + } + + .lg\:bg-green-600 { + background-color: #38a169; + } + + .lg\:bg-green-700 { + background-color: #2f855a; + } + + .lg\:bg-green-800 { + background-color: #276749; + } + + .lg\:bg-green-900 { + background-color: #22543d; + } + + .lg\:bg-teal-100 { + background-color: #e6fffa; + } + + .lg\:bg-teal-200 { + background-color: #b2f5ea; + } + + .lg\:bg-teal-300 { + background-color: #81e6d9; + } + + .lg\:bg-teal-400 { + background-color: #4fd1c5; + } + + .lg\:bg-teal-500 { + background-color: #38b2ac; + } + + .lg\:bg-teal-600 { + background-color: #319795; + } + + .lg\:bg-teal-700 { + background-color: #2c7a7b; + } + + .lg\:bg-teal-800 { + background-color: #285e61; + } + + .lg\:bg-teal-900 { + background-color: #234e52; + } + + .lg\:bg-blue-100 { + background-color: #ebf8ff; + } + + .lg\:bg-blue-200 { + background-color: #bee3f8; + } + + .lg\:bg-blue-300 { + background-color: #90cdf4; + } + + .lg\:bg-blue-400 { + background-color: #63b3ed; + } + + .lg\:bg-blue-500 { + background-color: #4299e1; + } + + .lg\:bg-blue-600 { + background-color: #3182ce; + } + + .lg\:bg-blue-700 { + background-color: #2b6cb0; + } + + .lg\:bg-blue-800 { + background-color: #2c5282; + } + + .lg\:bg-blue-900 { + background-color: #2a4365; + } + + .lg\:bg-indigo-100 { + background-color: #ebf4ff; + } + + .lg\:bg-indigo-200 { + background-color: #c3dafe; + } + + .lg\:bg-indigo-300 { + background-color: #a3bffa; + } + + .lg\:bg-indigo-400 { + background-color: #7f9cf5; + } + + .lg\:bg-indigo-500 { + background-color: #667eea; + } + + .lg\:bg-indigo-600 { + background-color: #5a67d8; + } + + .lg\:bg-indigo-700 { + background-color: #4c51bf; + } + + .lg\:bg-indigo-800 { + background-color: #434190; + } + + .lg\:bg-indigo-900 { + background-color: #3c366b; + } + + .lg\:bg-purple-100 { + background-color: #faf5ff; + } + + .lg\:bg-purple-200 { + background-color: #e9d8fd; + } + + .lg\:bg-purple-300 { + background-color: #d6bcfa; + } + + .lg\:bg-purple-400 { + background-color: #b794f4; + } + + .lg\:bg-purple-500 { + background-color: #9f7aea; + } + + .lg\:bg-purple-600 { + background-color: #805ad5; + } + + .lg\:bg-purple-700 { + background-color: #6b46c1; + } + + .lg\:bg-purple-800 { + background-color: #553c9a; + } + + .lg\:bg-purple-900 { + background-color: #44337a; + } + + .lg\:bg-pink-100 { + background-color: #fff5f7; + } + + .lg\:bg-pink-200 { + background-color: #fed7e2; + } + + .lg\:bg-pink-300 { + background-color: #fbb6ce; + } + + .lg\:bg-pink-400 { + background-color: #f687b3; + } + + .lg\:bg-pink-500 { + background-color: #ed64a6; + } + + .lg\:bg-pink-600 { + background-color: #d53f8c; + } + + .lg\:bg-pink-700 { + background-color: #b83280; + } + + .lg\:bg-pink-800 { + background-color: #97266d; + } + + .lg\:bg-pink-900 { + background-color: #702459; + } + + .lg\:hover\:bg-transparent:hover { + background-color: transparent; + } + + .lg\:hover\:bg-black:hover { + background-color: #000; + } + + .lg\:hover\:bg-white:hover { + background-color: #fff; + } + + .lg\:hover\:bg-gray-100:hover { + background-color: #f7fafc; + } + + .lg\:hover\:bg-gray-200:hover { + background-color: #edf2f7; + } + + .lg\:hover\:bg-gray-300:hover { + background-color: #e2e8f0; + } + + .lg\:hover\:bg-gray-400:hover { + background-color: #cbd5e0; + } + + .lg\:hover\:bg-gray-500:hover { + background-color: #a0aec0; + } + + .lg\:hover\:bg-gray-600:hover { + background-color: #718096; + } + + .lg\:hover\:bg-gray-700:hover { + background-color: #4a5568; + } + + .lg\:hover\:bg-gray-800:hover { + background-color: #2d3748; + } + + .lg\:hover\:bg-gray-900:hover { + background-color: #1a202c; + } + + .lg\:hover\:bg-red-100:hover { + background-color: #fff5f5; + } + + .lg\:hover\:bg-red-200:hover { + background-color: #fed7d7; + } + + .lg\:hover\:bg-red-300:hover { + background-color: #feb2b2; + } + + .lg\:hover\:bg-red-400:hover { + background-color: #fc8181; + } + + .lg\:hover\:bg-red-500:hover { + background-color: #f56565; + } + + .lg\:hover\:bg-red-600:hover { + background-color: #e53e3e; + } + + .lg\:hover\:bg-red-700:hover { + background-color: #c53030; + } + + .lg\:hover\:bg-red-800:hover { + background-color: #9b2c2c; + } + + .lg\:hover\:bg-red-900:hover { + background-color: #742a2a; + } + + .lg\:hover\:bg-orange-100:hover { + background-color: #fffaf0; + } + + .lg\:hover\:bg-orange-200:hover { + background-color: #feebc8; + } + + .lg\:hover\:bg-orange-300:hover { + background-color: #fbd38d; + } + + .lg\:hover\:bg-orange-400:hover { + background-color: #f6ad55; + } + + .lg\:hover\:bg-orange-500:hover { + background-color: #ed8936; + } + + .lg\:hover\:bg-orange-600:hover { + background-color: #dd6b20; + } + + .lg\:hover\:bg-orange-700:hover { + background-color: #c05621; + } + + .lg\:hover\:bg-orange-800:hover { + background-color: #9c4221; + } + + .lg\:hover\:bg-orange-900:hover { + background-color: #7b341e; + } + + .lg\:hover\:bg-yellow-100:hover { + background-color: #fffff0; + } + + .lg\:hover\:bg-yellow-200:hover { + background-color: #fefcbf; + } + + .lg\:hover\:bg-yellow-300:hover { + background-color: #faf089; + } + + .lg\:hover\:bg-yellow-400:hover { + background-color: #f6e05e; + } + + .lg\:hover\:bg-yellow-500:hover { + background-color: #ecc94b; + } + + .lg\:hover\:bg-yellow-600:hover { + background-color: #d69e2e; + } + + .lg\:hover\:bg-yellow-700:hover { + background-color: #b7791f; + } + + .lg\:hover\:bg-yellow-800:hover { + background-color: #975a16; + } + + .lg\:hover\:bg-yellow-900:hover { + background-color: #744210; + } + + .lg\:hover\:bg-green-100:hover { + background-color: #f0fff4; + } + + .lg\:hover\:bg-green-200:hover { + background-color: #c6f6d5; + } + + .lg\:hover\:bg-green-300:hover { + background-color: #9ae6b4; + } + + .lg\:hover\:bg-green-400:hover { + background-color: #68d391; + } + + .lg\:hover\:bg-green-500:hover { + background-color: #48bb78; + } + + .lg\:hover\:bg-green-600:hover { + background-color: #38a169; + } + + .lg\:hover\:bg-green-700:hover { + background-color: #2f855a; + } + + .lg\:hover\:bg-green-800:hover { + background-color: #276749; + } + + .lg\:hover\:bg-green-900:hover { + background-color: #22543d; + } + + .lg\:hover\:bg-teal-100:hover { + background-color: #e6fffa; + } + + .lg\:hover\:bg-teal-200:hover { + background-color: #b2f5ea; + } + + .lg\:hover\:bg-teal-300:hover { + background-color: #81e6d9; + } + + .lg\:hover\:bg-teal-400:hover { + background-color: #4fd1c5; + } + + .lg\:hover\:bg-teal-500:hover { + background-color: #38b2ac; + } + + .lg\:hover\:bg-teal-600:hover { + background-color: #319795; + } + + .lg\:hover\:bg-teal-700:hover { + background-color: #2c7a7b; + } + + .lg\:hover\:bg-teal-800:hover { + background-color: #285e61; + } + + .lg\:hover\:bg-teal-900:hover { + background-color: #234e52; + } + + .lg\:hover\:bg-blue-100:hover { + background-color: #ebf8ff; + } + + .lg\:hover\:bg-blue-200:hover { + background-color: #bee3f8; + } + + .lg\:hover\:bg-blue-300:hover { + background-color: #90cdf4; + } + + .lg\:hover\:bg-blue-400:hover { + background-color: #63b3ed; + } + + .lg\:hover\:bg-blue-500:hover { + background-color: #4299e1; + } + + .lg\:hover\:bg-blue-600:hover { + background-color: #3182ce; + } + + .lg\:hover\:bg-blue-700:hover { + background-color: #2b6cb0; + } + + .lg\:hover\:bg-blue-800:hover { + background-color: #2c5282; + } + + .lg\:hover\:bg-blue-900:hover { + background-color: #2a4365; + } + + .lg\:hover\:bg-indigo-100:hover { + background-color: #ebf4ff; + } + + .lg\:hover\:bg-indigo-200:hover { + background-color: #c3dafe; + } + + .lg\:hover\:bg-indigo-300:hover { + background-color: #a3bffa; + } + + .lg\:hover\:bg-indigo-400:hover { + background-color: #7f9cf5; + } + + .lg\:hover\:bg-indigo-500:hover { + background-color: #667eea; + } + + .lg\:hover\:bg-indigo-600:hover { + background-color: #5a67d8; + } + + .lg\:hover\:bg-indigo-700:hover { + background-color: #4c51bf; + } + + .lg\:hover\:bg-indigo-800:hover { + background-color: #434190; + } + + .lg\:hover\:bg-indigo-900:hover { + background-color: #3c366b; + } + + .lg\:hover\:bg-purple-100:hover { + background-color: #faf5ff; + } + + .lg\:hover\:bg-purple-200:hover { + background-color: #e9d8fd; + } + + .lg\:hover\:bg-purple-300:hover { + background-color: #d6bcfa; + } + + .lg\:hover\:bg-purple-400:hover { + background-color: #b794f4; + } + + .lg\:hover\:bg-purple-500:hover { + background-color: #9f7aea; + } + + .lg\:hover\:bg-purple-600:hover { + background-color: #805ad5; + } + + .lg\:hover\:bg-purple-700:hover { + background-color: #6b46c1; + } + + .lg\:hover\:bg-purple-800:hover { + background-color: #553c9a; + } + + .lg\:hover\:bg-purple-900:hover { + background-color: #44337a; + } + + .lg\:hover\:bg-pink-100:hover { + background-color: #fff5f7; + } + + .lg\:hover\:bg-pink-200:hover { + background-color: #fed7e2; + } + + .lg\:hover\:bg-pink-300:hover { + background-color: #fbb6ce; + } + + .lg\:hover\:bg-pink-400:hover { + background-color: #f687b3; + } + + .lg\:hover\:bg-pink-500:hover { + background-color: #ed64a6; + } + + .lg\:hover\:bg-pink-600:hover { + background-color: #d53f8c; + } + + .lg\:hover\:bg-pink-700:hover { + background-color: #b83280; + } + + .lg\:hover\:bg-pink-800:hover { + background-color: #97266d; + } + + .lg\:hover\:bg-pink-900:hover { + background-color: #702459; + } + + .lg\:focus\:bg-transparent:focus { + background-color: transparent; + } + + .lg\:focus\:bg-black:focus { + background-color: #000; + } + + .lg\:focus\:bg-white:focus { + background-color: #fff; + } + + .lg\:focus\:bg-gray-100:focus { + background-color: #f7fafc; + } + + .lg\:focus\:bg-gray-200:focus { + background-color: #edf2f7; + } + + .lg\:focus\:bg-gray-300:focus { + background-color: #e2e8f0; + } + + .lg\:focus\:bg-gray-400:focus { + background-color: #cbd5e0; + } + + .lg\:focus\:bg-gray-500:focus { + background-color: #a0aec0; + } + + .lg\:focus\:bg-gray-600:focus { + background-color: #718096; + } + + .lg\:focus\:bg-gray-700:focus { + background-color: #4a5568; + } + + .lg\:focus\:bg-gray-800:focus { + background-color: #2d3748; + } + + .lg\:focus\:bg-gray-900:focus { + background-color: #1a202c; + } + + .lg\:focus\:bg-red-100:focus { + background-color: #fff5f5; + } + + .lg\:focus\:bg-red-200:focus { + background-color: #fed7d7; + } + + .lg\:focus\:bg-red-300:focus { + background-color: #feb2b2; + } + + .lg\:focus\:bg-red-400:focus { + background-color: #fc8181; + } + + .lg\:focus\:bg-red-500:focus { + background-color: #f56565; + } + + .lg\:focus\:bg-red-600:focus { + background-color: #e53e3e; + } + + .lg\:focus\:bg-red-700:focus { + background-color: #c53030; + } + + .lg\:focus\:bg-red-800:focus { + background-color: #9b2c2c; + } + + .lg\:focus\:bg-red-900:focus { + background-color: #742a2a; + } + + .lg\:focus\:bg-orange-100:focus { + background-color: #fffaf0; + } + + .lg\:focus\:bg-orange-200:focus { + background-color: #feebc8; + } + + .lg\:focus\:bg-orange-300:focus { + background-color: #fbd38d; + } + + .lg\:focus\:bg-orange-400:focus { + background-color: #f6ad55; + } + + .lg\:focus\:bg-orange-500:focus { + background-color: #ed8936; + } + + .lg\:focus\:bg-orange-600:focus { + background-color: #dd6b20; + } + + .lg\:focus\:bg-orange-700:focus { + background-color: #c05621; + } + + .lg\:focus\:bg-orange-800:focus { + background-color: #9c4221; + } + + .lg\:focus\:bg-orange-900:focus { + background-color: #7b341e; + } + + .lg\:focus\:bg-yellow-100:focus { + background-color: #fffff0; + } + + .lg\:focus\:bg-yellow-200:focus { + background-color: #fefcbf; + } + + .lg\:focus\:bg-yellow-300:focus { + background-color: #faf089; + } + + .lg\:focus\:bg-yellow-400:focus { + background-color: #f6e05e; + } + + .lg\:focus\:bg-yellow-500:focus { + background-color: #ecc94b; + } + + .lg\:focus\:bg-yellow-600:focus { + background-color: #d69e2e; + } + + .lg\:focus\:bg-yellow-700:focus { + background-color: #b7791f; + } + + .lg\:focus\:bg-yellow-800:focus { + background-color: #975a16; + } + + .lg\:focus\:bg-yellow-900:focus { + background-color: #744210; + } + + .lg\:focus\:bg-green-100:focus { + background-color: #f0fff4; + } + + .lg\:focus\:bg-green-200:focus { + background-color: #c6f6d5; + } + + .lg\:focus\:bg-green-300:focus { + background-color: #9ae6b4; + } + + .lg\:focus\:bg-green-400:focus { + background-color: #68d391; + } + + .lg\:focus\:bg-green-500:focus { + background-color: #48bb78; + } + + .lg\:focus\:bg-green-600:focus { + background-color: #38a169; + } + + .lg\:focus\:bg-green-700:focus { + background-color: #2f855a; + } + + .lg\:focus\:bg-green-800:focus { + background-color: #276749; + } + + .lg\:focus\:bg-green-900:focus { + background-color: #22543d; + } + + .lg\:focus\:bg-teal-100:focus { + background-color: #e6fffa; + } + + .lg\:focus\:bg-teal-200:focus { + background-color: #b2f5ea; + } + + .lg\:focus\:bg-teal-300:focus { + background-color: #81e6d9; + } + + .lg\:focus\:bg-teal-400:focus { + background-color: #4fd1c5; + } + + .lg\:focus\:bg-teal-500:focus { + background-color: #38b2ac; + } + + .lg\:focus\:bg-teal-600:focus { + background-color: #319795; + } + + .lg\:focus\:bg-teal-700:focus { + background-color: #2c7a7b; + } + + .lg\:focus\:bg-teal-800:focus { + background-color: #285e61; + } + + .lg\:focus\:bg-teal-900:focus { + background-color: #234e52; + } + + .lg\:focus\:bg-blue-100:focus { + background-color: #ebf8ff; + } + + .lg\:focus\:bg-blue-200:focus { + background-color: #bee3f8; + } + + .lg\:focus\:bg-blue-300:focus { + background-color: #90cdf4; + } + + .lg\:focus\:bg-blue-400:focus { + background-color: #63b3ed; + } + + .lg\:focus\:bg-blue-500:focus { + background-color: #4299e1; + } + + .lg\:focus\:bg-blue-600:focus { + background-color: #3182ce; + } + + .lg\:focus\:bg-blue-700:focus { + background-color: #2b6cb0; + } + + .lg\:focus\:bg-blue-800:focus { + background-color: #2c5282; + } + + .lg\:focus\:bg-blue-900:focus { + background-color: #2a4365; + } + + .lg\:focus\:bg-indigo-100:focus { + background-color: #ebf4ff; + } + + .lg\:focus\:bg-indigo-200:focus { + background-color: #c3dafe; + } + + .lg\:focus\:bg-indigo-300:focus { + background-color: #a3bffa; + } + + .lg\:focus\:bg-indigo-400:focus { + background-color: #7f9cf5; + } + + .lg\:focus\:bg-indigo-500:focus { + background-color: #667eea; + } + + .lg\:focus\:bg-indigo-600:focus { + background-color: #5a67d8; + } + + .lg\:focus\:bg-indigo-700:focus { + background-color: #4c51bf; + } + + .lg\:focus\:bg-indigo-800:focus { + background-color: #434190; + } + + .lg\:focus\:bg-indigo-900:focus { + background-color: #3c366b; + } + + .lg\:focus\:bg-purple-100:focus { + background-color: #faf5ff; + } + + .lg\:focus\:bg-purple-200:focus { + background-color: #e9d8fd; + } + + .lg\:focus\:bg-purple-300:focus { + background-color: #d6bcfa; + } + + .lg\:focus\:bg-purple-400:focus { + background-color: #b794f4; + } + + .lg\:focus\:bg-purple-500:focus { + background-color: #9f7aea; + } + + .lg\:focus\:bg-purple-600:focus { + background-color: #805ad5; + } + + .lg\:focus\:bg-purple-700:focus { + background-color: #6b46c1; + } + + .lg\:focus\:bg-purple-800:focus { + background-color: #553c9a; + } + + .lg\:focus\:bg-purple-900:focus { + background-color: #44337a; + } + + .lg\:focus\:bg-pink-100:focus { + background-color: #fff5f7; + } + + .lg\:focus\:bg-pink-200:focus { + background-color: #fed7e2; + } + + .lg\:focus\:bg-pink-300:focus { + background-color: #fbb6ce; + } + + .lg\:focus\:bg-pink-400:focus { + background-color: #f687b3; + } + + .lg\:focus\:bg-pink-500:focus { + background-color: #ed64a6; + } + + .lg\:focus\:bg-pink-600:focus { + background-color: #d53f8c; + } + + .lg\:focus\:bg-pink-700:focus { + background-color: #b83280; + } + + .lg\:focus\:bg-pink-800:focus { + background-color: #97266d; + } + + .lg\:focus\:bg-pink-900:focus { + background-color: #702459; + } + + .lg\:bg-bottom { + background-position: bottom; + } + + .lg\:bg-center { + background-position: center; + } + + .lg\:bg-left { + background-position: left; + } + + .lg\:bg-left-bottom { + background-position: left bottom; + } + + .lg\:bg-left-top { + background-position: left top; + } + + .lg\:bg-right { + background-position: right; + } + + .lg\:bg-right-bottom { + background-position: right bottom; + } + + .lg\:bg-right-top { + background-position: right top; + } + + .lg\:bg-top { + background-position: top; + } + + .lg\:bg-repeat { + background-repeat: repeat; + } + + .lg\:bg-no-repeat { + background-repeat: no-repeat; + } + + .lg\:bg-repeat-x { + background-repeat: repeat-x; + } + + .lg\:bg-repeat-y { + background-repeat: repeat-y; + } + + .lg\:bg-repeat-round { + background-repeat: round; + } + + .lg\:bg-repeat-space { + background-repeat: space; + } + + .lg\:bg-auto { + background-size: auto; + } + + .lg\:bg-cover { + background-size: cover; + } + + .lg\:bg-contain { + background-size: contain; + } + + .lg\:border-collapse { + border-collapse: collapse; + } + + .lg\:border-separate { + border-collapse: separate; + } + + .lg\:border-transparent { + border-color: transparent; + } + + .lg\:border-black { + border-color: #000; + } + + .lg\:border-white { + border-color: #fff; + } + + .lg\:border-gray-100 { + border-color: #f7fafc; + } + + .lg\:border-gray-200 { + border-color: #edf2f7; + } + + .lg\:border-gray-300 { + border-color: #e2e8f0; + } + + .lg\:border-gray-400 { + border-color: #cbd5e0; + } + + .lg\:border-gray-500 { + border-color: #a0aec0; + } + + .lg\:border-gray-600 { + border-color: #718096; + } + + .lg\:border-gray-700 { + border-color: #4a5568; + } + + .lg\:border-gray-800 { + border-color: #2d3748; + } + + .lg\:border-gray-900 { + border-color: #1a202c; + } + + .lg\:border-red-100 { + border-color: #fff5f5; + } + + .lg\:border-red-200 { + border-color: #fed7d7; + } + + .lg\:border-red-300 { + border-color: #feb2b2; + } + + .lg\:border-red-400 { + border-color: #fc8181; + } + + .lg\:border-red-500 { + border-color: #f56565; + } + + .lg\:border-red-600 { + border-color: #e53e3e; + } + + .lg\:border-red-700 { + border-color: #c53030; + } + + .lg\:border-red-800 { + border-color: #9b2c2c; + } + + .lg\:border-red-900 { + border-color: #742a2a; + } + + .lg\:border-orange-100 { + border-color: #fffaf0; + } + + .lg\:border-orange-200 { + border-color: #feebc8; + } + + .lg\:border-orange-300 { + border-color: #fbd38d; + } + + .lg\:border-orange-400 { + border-color: #f6ad55; + } + + .lg\:border-orange-500 { + border-color: #ed8936; + } + + .lg\:border-orange-600 { + border-color: #dd6b20; + } + + .lg\:border-orange-700 { + border-color: #c05621; + } + + .lg\:border-orange-800 { + border-color: #9c4221; + } + + .lg\:border-orange-900 { + border-color: #7b341e; + } + + .lg\:border-yellow-100 { + border-color: #fffff0; + } + + .lg\:border-yellow-200 { + border-color: #fefcbf; + } + + .lg\:border-yellow-300 { + border-color: #faf089; + } + + .lg\:border-yellow-400 { + border-color: #f6e05e; + } + + .lg\:border-yellow-500 { + border-color: #ecc94b; + } + + .lg\:border-yellow-600 { + border-color: #d69e2e; + } + + .lg\:border-yellow-700 { + border-color: #b7791f; + } + + .lg\:border-yellow-800 { + border-color: #975a16; + } + + .lg\:border-yellow-900 { + border-color: #744210; + } + + .lg\:border-green-100 { + border-color: #f0fff4; + } + + .lg\:border-green-200 { + border-color: #c6f6d5; + } + + .lg\:border-green-300 { + border-color: #9ae6b4; + } + + .lg\:border-green-400 { + border-color: #68d391; + } + + .lg\:border-green-500 { + border-color: #48bb78; + } + + .lg\:border-green-600 { + border-color: #38a169; + } + + .lg\:border-green-700 { + border-color: #2f855a; + } + + .lg\:border-green-800 { + border-color: #276749; + } + + .lg\:border-green-900 { + border-color: #22543d; + } + + .lg\:border-teal-100 { + border-color: #e6fffa; + } + + .lg\:border-teal-200 { + border-color: #b2f5ea; + } + + .lg\:border-teal-300 { + border-color: #81e6d9; + } + + .lg\:border-teal-400 { + border-color: #4fd1c5; + } + + .lg\:border-teal-500 { + border-color: #38b2ac; + } + + .lg\:border-teal-600 { + border-color: #319795; + } + + .lg\:border-teal-700 { + border-color: #2c7a7b; + } + + .lg\:border-teal-800 { + border-color: #285e61; + } + + .lg\:border-teal-900 { + border-color: #234e52; + } + + .lg\:border-blue-100 { + border-color: #ebf8ff; + } + + .lg\:border-blue-200 { + border-color: #bee3f8; + } + + .lg\:border-blue-300 { + border-color: #90cdf4; + } + + .lg\:border-blue-400 { + border-color: #63b3ed; + } + + .lg\:border-blue-500 { + border-color: #4299e1; + } + + .lg\:border-blue-600 { + border-color: #3182ce; + } + + .lg\:border-blue-700 { + border-color: #2b6cb0; + } + + .lg\:border-blue-800 { + border-color: #2c5282; + } + + .lg\:border-blue-900 { + border-color: #2a4365; + } + + .lg\:border-indigo-100 { + border-color: #ebf4ff; + } + + .lg\:border-indigo-200 { + border-color: #c3dafe; + } + + .lg\:border-indigo-300 { + border-color: #a3bffa; + } + + .lg\:border-indigo-400 { + border-color: #7f9cf5; + } + + .lg\:border-indigo-500 { + border-color: #667eea; + } + + .lg\:border-indigo-600 { + border-color: #5a67d8; + } + + .lg\:border-indigo-700 { + border-color: #4c51bf; + } + + .lg\:border-indigo-800 { + border-color: #434190; + } + + .lg\:border-indigo-900 { + border-color: #3c366b; + } + + .lg\:border-purple-100 { + border-color: #faf5ff; + } + + .lg\:border-purple-200 { + border-color: #e9d8fd; + } + + .lg\:border-purple-300 { + border-color: #d6bcfa; + } + + .lg\:border-purple-400 { + border-color: #b794f4; + } + + .lg\:border-purple-500 { + border-color: #9f7aea; + } + + .lg\:border-purple-600 { + border-color: #805ad5; + } + + .lg\:border-purple-700 { + border-color: #6b46c1; + } + + .lg\:border-purple-800 { + border-color: #553c9a; + } + + .lg\:border-purple-900 { + border-color: #44337a; + } + + .lg\:border-pink-100 { + border-color: #fff5f7; + } + + .lg\:border-pink-200 { + border-color: #fed7e2; + } + + .lg\:border-pink-300 { + border-color: #fbb6ce; + } + + .lg\:border-pink-400 { + border-color: #f687b3; + } + + .lg\:border-pink-500 { + border-color: #ed64a6; + } + + .lg\:border-pink-600 { + border-color: #d53f8c; + } + + .lg\:border-pink-700 { + border-color: #b83280; + } + + .lg\:border-pink-800 { + border-color: #97266d; + } + + .lg\:border-pink-900 { + border-color: #702459; + } + + .lg\:hover\:border-transparent:hover { + border-color: transparent; + } + + .lg\:hover\:border-black:hover { + border-color: #000; + } + + .lg\:hover\:border-white:hover { + border-color: #fff; + } + + .lg\:hover\:border-gray-100:hover { + border-color: #f7fafc; + } + + .lg\:hover\:border-gray-200:hover { + border-color: #edf2f7; + } + + .lg\:hover\:border-gray-300:hover { + border-color: #e2e8f0; + } + + .lg\:hover\:border-gray-400:hover { + border-color: #cbd5e0; + } + + .lg\:hover\:border-gray-500:hover { + border-color: #a0aec0; + } + + .lg\:hover\:border-gray-600:hover { + border-color: #718096; + } + + .lg\:hover\:border-gray-700:hover { + border-color: #4a5568; + } + + .lg\:hover\:border-gray-800:hover { + border-color: #2d3748; + } + + .lg\:hover\:border-gray-900:hover { + border-color: #1a202c; + } + + .lg\:hover\:border-red-100:hover { + border-color: #fff5f5; + } + + .lg\:hover\:border-red-200:hover { + border-color: #fed7d7; + } + + .lg\:hover\:border-red-300:hover { + border-color: #feb2b2; + } + + .lg\:hover\:border-red-400:hover { + border-color: #fc8181; + } + + .lg\:hover\:border-red-500:hover { + border-color: #f56565; + } + + .lg\:hover\:border-red-600:hover { + border-color: #e53e3e; + } + + .lg\:hover\:border-red-700:hover { + border-color: #c53030; + } + + .lg\:hover\:border-red-800:hover { + border-color: #9b2c2c; + } + + .lg\:hover\:border-red-900:hover { + border-color: #742a2a; + } + + .lg\:hover\:border-orange-100:hover { + border-color: #fffaf0; + } + + .lg\:hover\:border-orange-200:hover { + border-color: #feebc8; + } + + .lg\:hover\:border-orange-300:hover { + border-color: #fbd38d; + } + + .lg\:hover\:border-orange-400:hover { + border-color: #f6ad55; + } + + .lg\:hover\:border-orange-500:hover { + border-color: #ed8936; + } + + .lg\:hover\:border-orange-600:hover { + border-color: #dd6b20; + } + + .lg\:hover\:border-orange-700:hover { + border-color: #c05621; + } + + .lg\:hover\:border-orange-800:hover { + border-color: #9c4221; + } + + .lg\:hover\:border-orange-900:hover { + border-color: #7b341e; + } + + .lg\:hover\:border-yellow-100:hover { + border-color: #fffff0; + } + + .lg\:hover\:border-yellow-200:hover { + border-color: #fefcbf; + } + + .lg\:hover\:border-yellow-300:hover { + border-color: #faf089; + } + + .lg\:hover\:border-yellow-400:hover { + border-color: #f6e05e; + } + + .lg\:hover\:border-yellow-500:hover { + border-color: #ecc94b; + } + + .lg\:hover\:border-yellow-600:hover { + border-color: #d69e2e; + } + + .lg\:hover\:border-yellow-700:hover { + border-color: #b7791f; + } + + .lg\:hover\:border-yellow-800:hover { + border-color: #975a16; + } + + .lg\:hover\:border-yellow-900:hover { + border-color: #744210; + } + + .lg\:hover\:border-green-100:hover { + border-color: #f0fff4; + } + + .lg\:hover\:border-green-200:hover { + border-color: #c6f6d5; + } + + .lg\:hover\:border-green-300:hover { + border-color: #9ae6b4; + } + + .lg\:hover\:border-green-400:hover { + border-color: #68d391; + } + + .lg\:hover\:border-green-500:hover { + border-color: #48bb78; + } + + .lg\:hover\:border-green-600:hover { + border-color: #38a169; + } + + .lg\:hover\:border-green-700:hover { + border-color: #2f855a; + } + + .lg\:hover\:border-green-800:hover { + border-color: #276749; + } + + .lg\:hover\:border-green-900:hover { + border-color: #22543d; + } + + .lg\:hover\:border-teal-100:hover { + border-color: #e6fffa; + } + + .lg\:hover\:border-teal-200:hover { + border-color: #b2f5ea; + } + + .lg\:hover\:border-teal-300:hover { + border-color: #81e6d9; + } + + .lg\:hover\:border-teal-400:hover { + border-color: #4fd1c5; + } + + .lg\:hover\:border-teal-500:hover { + border-color: #38b2ac; + } + + .lg\:hover\:border-teal-600:hover { + border-color: #319795; + } + + .lg\:hover\:border-teal-700:hover { + border-color: #2c7a7b; + } + + .lg\:hover\:border-teal-800:hover { + border-color: #285e61; + } + + .lg\:hover\:border-teal-900:hover { + border-color: #234e52; + } + + .lg\:hover\:border-blue-100:hover { + border-color: #ebf8ff; + } + + .lg\:hover\:border-blue-200:hover { + border-color: #bee3f8; + } + + .lg\:hover\:border-blue-300:hover { + border-color: #90cdf4; + } + + .lg\:hover\:border-blue-400:hover { + border-color: #63b3ed; + } + + .lg\:hover\:border-blue-500:hover { + border-color: #4299e1; + } + + .lg\:hover\:border-blue-600:hover { + border-color: #3182ce; + } + + .lg\:hover\:border-blue-700:hover { + border-color: #2b6cb0; + } + + .lg\:hover\:border-blue-800:hover { + border-color: #2c5282; + } + + .lg\:hover\:border-blue-900:hover { + border-color: #2a4365; + } + + .lg\:hover\:border-indigo-100:hover { + border-color: #ebf4ff; + } + + .lg\:hover\:border-indigo-200:hover { + border-color: #c3dafe; + } + + .lg\:hover\:border-indigo-300:hover { + border-color: #a3bffa; + } + + .lg\:hover\:border-indigo-400:hover { + border-color: #7f9cf5; + } + + .lg\:hover\:border-indigo-500:hover { + border-color: #667eea; + } + + .lg\:hover\:border-indigo-600:hover { + border-color: #5a67d8; + } + + .lg\:hover\:border-indigo-700:hover { + border-color: #4c51bf; + } + + .lg\:hover\:border-indigo-800:hover { + border-color: #434190; + } + + .lg\:hover\:border-indigo-900:hover { + border-color: #3c366b; + } + + .lg\:hover\:border-purple-100:hover { + border-color: #faf5ff; + } + + .lg\:hover\:border-purple-200:hover { + border-color: #e9d8fd; + } + + .lg\:hover\:border-purple-300:hover { + border-color: #d6bcfa; + } + + .lg\:hover\:border-purple-400:hover { + border-color: #b794f4; + } + + .lg\:hover\:border-purple-500:hover { + border-color: #9f7aea; + } + + .lg\:hover\:border-purple-600:hover { + border-color: #805ad5; + } + + .lg\:hover\:border-purple-700:hover { + border-color: #6b46c1; + } + + .lg\:hover\:border-purple-800:hover { + border-color: #553c9a; + } + + .lg\:hover\:border-purple-900:hover { + border-color: #44337a; + } + + .lg\:hover\:border-pink-100:hover { + border-color: #fff5f7; + } + + .lg\:hover\:border-pink-200:hover { + border-color: #fed7e2; + } + + .lg\:hover\:border-pink-300:hover { + border-color: #fbb6ce; + } + + .lg\:hover\:border-pink-400:hover { + border-color: #f687b3; + } + + .lg\:hover\:border-pink-500:hover { + border-color: #ed64a6; + } + + .lg\:hover\:border-pink-600:hover { + border-color: #d53f8c; + } + + .lg\:hover\:border-pink-700:hover { + border-color: #b83280; + } + + .lg\:hover\:border-pink-800:hover { + border-color: #97266d; + } + + .lg\:hover\:border-pink-900:hover { + border-color: #702459; + } + + .lg\:focus\:border-transparent:focus { + border-color: transparent; + } + + .lg\:focus\:border-black:focus { + border-color: #000; + } + + .lg\:focus\:border-white:focus { + border-color: #fff; + } + + .lg\:focus\:border-gray-100:focus { + border-color: #f7fafc; + } + + .lg\:focus\:border-gray-200:focus { + border-color: #edf2f7; + } + + .lg\:focus\:border-gray-300:focus { + border-color: #e2e8f0; + } + + .lg\:focus\:border-gray-400:focus { + border-color: #cbd5e0; + } + + .lg\:focus\:border-gray-500:focus { + border-color: #a0aec0; + } + + .lg\:focus\:border-gray-600:focus { + border-color: #718096; + } + + .lg\:focus\:border-gray-700:focus { + border-color: #4a5568; + } + + .lg\:focus\:border-gray-800:focus { + border-color: #2d3748; + } + + .lg\:focus\:border-gray-900:focus { + border-color: #1a202c; + } + + .lg\:focus\:border-red-100:focus { + border-color: #fff5f5; + } + + .lg\:focus\:border-red-200:focus { + border-color: #fed7d7; + } + + .lg\:focus\:border-red-300:focus { + border-color: #feb2b2; + } + + .lg\:focus\:border-red-400:focus { + border-color: #fc8181; + } + + .lg\:focus\:border-red-500:focus { + border-color: #f56565; + } + + .lg\:focus\:border-red-600:focus { + border-color: #e53e3e; + } + + .lg\:focus\:border-red-700:focus { + border-color: #c53030; + } + + .lg\:focus\:border-red-800:focus { + border-color: #9b2c2c; + } + + .lg\:focus\:border-red-900:focus { + border-color: #742a2a; + } + + .lg\:focus\:border-orange-100:focus { + border-color: #fffaf0; + } + + .lg\:focus\:border-orange-200:focus { + border-color: #feebc8; + } + + .lg\:focus\:border-orange-300:focus { + border-color: #fbd38d; + } + + .lg\:focus\:border-orange-400:focus { + border-color: #f6ad55; + } + + .lg\:focus\:border-orange-500:focus { + border-color: #ed8936; + } + + .lg\:focus\:border-orange-600:focus { + border-color: #dd6b20; + } + + .lg\:focus\:border-orange-700:focus { + border-color: #c05621; + } + + .lg\:focus\:border-orange-800:focus { + border-color: #9c4221; + } + + .lg\:focus\:border-orange-900:focus { + border-color: #7b341e; + } + + .lg\:focus\:border-yellow-100:focus { + border-color: #fffff0; + } + + .lg\:focus\:border-yellow-200:focus { + border-color: #fefcbf; + } + + .lg\:focus\:border-yellow-300:focus { + border-color: #faf089; + } + + .lg\:focus\:border-yellow-400:focus { + border-color: #f6e05e; + } + + .lg\:focus\:border-yellow-500:focus { + border-color: #ecc94b; + } + + .lg\:focus\:border-yellow-600:focus { + border-color: #d69e2e; + } + + .lg\:focus\:border-yellow-700:focus { + border-color: #b7791f; + } + + .lg\:focus\:border-yellow-800:focus { + border-color: #975a16; + } + + .lg\:focus\:border-yellow-900:focus { + border-color: #744210; + } + + .lg\:focus\:border-green-100:focus { + border-color: #f0fff4; + } + + .lg\:focus\:border-green-200:focus { + border-color: #c6f6d5; + } + + .lg\:focus\:border-green-300:focus { + border-color: #9ae6b4; + } + + .lg\:focus\:border-green-400:focus { + border-color: #68d391; + } + + .lg\:focus\:border-green-500:focus { + border-color: #48bb78; + } + + .lg\:focus\:border-green-600:focus { + border-color: #38a169; + } + + .lg\:focus\:border-green-700:focus { + border-color: #2f855a; + } + + .lg\:focus\:border-green-800:focus { + border-color: #276749; + } + + .lg\:focus\:border-green-900:focus { + border-color: #22543d; + } + + .lg\:focus\:border-teal-100:focus { + border-color: #e6fffa; + } + + .lg\:focus\:border-teal-200:focus { + border-color: #b2f5ea; + } + + .lg\:focus\:border-teal-300:focus { + border-color: #81e6d9; + } + + .lg\:focus\:border-teal-400:focus { + border-color: #4fd1c5; + } + + .lg\:focus\:border-teal-500:focus { + border-color: #38b2ac; + } + + .lg\:focus\:border-teal-600:focus { + border-color: #319795; + } + + .lg\:focus\:border-teal-700:focus { + border-color: #2c7a7b; + } + + .lg\:focus\:border-teal-800:focus { + border-color: #285e61; + } + + .lg\:focus\:border-teal-900:focus { + border-color: #234e52; + } + + .lg\:focus\:border-blue-100:focus { + border-color: #ebf8ff; + } + + .lg\:focus\:border-blue-200:focus { + border-color: #bee3f8; + } + + .lg\:focus\:border-blue-300:focus { + border-color: #90cdf4; + } + + .lg\:focus\:border-blue-400:focus { + border-color: #63b3ed; + } + + .lg\:focus\:border-blue-500:focus { + border-color: #4299e1; + } + + .lg\:focus\:border-blue-600:focus { + border-color: #3182ce; + } + + .lg\:focus\:border-blue-700:focus { + border-color: #2b6cb0; + } + + .lg\:focus\:border-blue-800:focus { + border-color: #2c5282; + } + + .lg\:focus\:border-blue-900:focus { + border-color: #2a4365; + } + + .lg\:focus\:border-indigo-100:focus { + border-color: #ebf4ff; + } + + .lg\:focus\:border-indigo-200:focus { + border-color: #c3dafe; + } + + .lg\:focus\:border-indigo-300:focus { + border-color: #a3bffa; + } + + .lg\:focus\:border-indigo-400:focus { + border-color: #7f9cf5; + } + + .lg\:focus\:border-indigo-500:focus { + border-color: #667eea; + } + + .lg\:focus\:border-indigo-600:focus { + border-color: #5a67d8; + } + + .lg\:focus\:border-indigo-700:focus { + border-color: #4c51bf; + } + + .lg\:focus\:border-indigo-800:focus { + border-color: #434190; + } + + .lg\:focus\:border-indigo-900:focus { + border-color: #3c366b; + } + + .lg\:focus\:border-purple-100:focus { + border-color: #faf5ff; + } + + .lg\:focus\:border-purple-200:focus { + border-color: #e9d8fd; + } + + .lg\:focus\:border-purple-300:focus { + border-color: #d6bcfa; + } + + .lg\:focus\:border-purple-400:focus { + border-color: #b794f4; + } + + .lg\:focus\:border-purple-500:focus { + border-color: #9f7aea; + } + + .lg\:focus\:border-purple-600:focus { + border-color: #805ad5; + } + + .lg\:focus\:border-purple-700:focus { + border-color: #6b46c1; + } + + .lg\:focus\:border-purple-800:focus { + border-color: #553c9a; + } + + .lg\:focus\:border-purple-900:focus { + border-color: #44337a; + } + + .lg\:focus\:border-pink-100:focus { + border-color: #fff5f7; + } + + .lg\:focus\:border-pink-200:focus { + border-color: #fed7e2; + } + + .lg\:focus\:border-pink-300:focus { + border-color: #fbb6ce; + } + + .lg\:focus\:border-pink-400:focus { + border-color: #f687b3; + } + + .lg\:focus\:border-pink-500:focus { + border-color: #ed64a6; + } + + .lg\:focus\:border-pink-600:focus { + border-color: #d53f8c; + } + + .lg\:focus\:border-pink-700:focus { + border-color: #b83280; + } + + .lg\:focus\:border-pink-800:focus { + border-color: #97266d; + } + + .lg\:focus\:border-pink-900:focus { + border-color: #702459; + } + + .lg\:rounded-none { + border-radius: 0; + } + + .lg\:rounded-sm { + border-radius: 0.125rem; + } + + .lg\:rounded { + border-radius: 0.25rem; + } + + .lg\:rounded-md { + border-radius: 0.375rem; + } + + .lg\:rounded-lg { + border-radius: 0.5rem; + } + + .lg\:rounded-full { + border-radius: 9999px; + } + + .lg\:rounded-t-none { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + + .lg\:rounded-r-none { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .lg\:rounded-b-none { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } + + .lg\:rounded-l-none { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + + .lg\:rounded-t-sm { + border-top-left-radius: 0.125rem; + border-top-right-radius: 0.125rem; + } + + .lg\:rounded-r-sm { + border-top-right-radius: 0.125rem; + border-bottom-right-radius: 0.125rem; + } + + .lg\:rounded-b-sm { + border-bottom-right-radius: 0.125rem; + border-bottom-left-radius: 0.125rem; + } + + .lg\:rounded-l-sm { + border-top-left-radius: 0.125rem; + border-bottom-left-radius: 0.125rem; + } + + .lg\:rounded-t { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; + } + + .lg\:rounded-r { + border-top-right-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; + } + + .lg\:rounded-b { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + } + + .lg\:rounded-l { + border-top-left-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + } + + .lg\:rounded-t-md { + border-top-left-radius: 0.375rem; + border-top-right-radius: 0.375rem; + } + + .lg\:rounded-r-md { + border-top-right-radius: 0.375rem; + border-bottom-right-radius: 0.375rem; + } + + .lg\:rounded-b-md { + border-bottom-right-radius: 0.375rem; + border-bottom-left-radius: 0.375rem; + } + + .lg\:rounded-l-md { + border-top-left-radius: 0.375rem; + border-bottom-left-radius: 0.375rem; + } + + .lg\:rounded-t-lg { + border-top-left-radius: 0.5rem; + border-top-right-radius: 0.5rem; + } + + .lg\:rounded-r-lg { + border-top-right-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; + } + + .lg\:rounded-b-lg { + border-bottom-right-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; + } + + .lg\:rounded-l-lg { + border-top-left-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; + } + + .lg\:rounded-t-full { + border-top-left-radius: 9999px; + border-top-right-radius: 9999px; + } + + .lg\:rounded-r-full { + border-top-right-radius: 9999px; + border-bottom-right-radius: 9999px; + } + + .lg\:rounded-b-full { + border-bottom-right-radius: 9999px; + border-bottom-left-radius: 9999px; + } + + .lg\:rounded-l-full { + border-top-left-radius: 9999px; + border-bottom-left-radius: 9999px; + } + + .lg\:rounded-tl-none { + border-top-left-radius: 0; + } + + .lg\:rounded-tr-none { + border-top-right-radius: 0; + } + + .lg\:rounded-br-none { + border-bottom-right-radius: 0; + } + + .lg\:rounded-bl-none { + border-bottom-left-radius: 0; + } + + .lg\:rounded-tl-sm { + border-top-left-radius: 0.125rem; + } + + .lg\:rounded-tr-sm { + border-top-right-radius: 0.125rem; + } + + .lg\:rounded-br-sm { + border-bottom-right-radius: 0.125rem; + } + + .lg\:rounded-bl-sm { + border-bottom-left-radius: 0.125rem; + } + + .lg\:rounded-tl { + border-top-left-radius: 0.25rem; + } + + .lg\:rounded-tr { + border-top-right-radius: 0.25rem; + } + + .lg\:rounded-br { + border-bottom-right-radius: 0.25rem; + } + + .lg\:rounded-bl { + border-bottom-left-radius: 0.25rem; + } + + .lg\:rounded-tl-md { + border-top-left-radius: 0.375rem; + } + + .lg\:rounded-tr-md { + border-top-right-radius: 0.375rem; + } + + .lg\:rounded-br-md { + border-bottom-right-radius: 0.375rem; + } + + .lg\:rounded-bl-md { + border-bottom-left-radius: 0.375rem; + } + + .lg\:rounded-tl-lg { + border-top-left-radius: 0.5rem; + } + + .lg\:rounded-tr-lg { + border-top-right-radius: 0.5rem; + } + + .lg\:rounded-br-lg { + border-bottom-right-radius: 0.5rem; + } + + .lg\:rounded-bl-lg { + border-bottom-left-radius: 0.5rem; + } + + .lg\:rounded-tl-full { + border-top-left-radius: 9999px; + } + + .lg\:rounded-tr-full { + border-top-right-radius: 9999px; + } + + .lg\:rounded-br-full { + border-bottom-right-radius: 9999px; + } + + .lg\:rounded-bl-full { + border-bottom-left-radius: 9999px; + } + + .lg\:border-solid { + border-style: solid; + } + + .lg\:border-dashed { + border-style: dashed; + } + + .lg\:border-dotted { + border-style: dotted; + } + + .lg\:border-double { + border-style: double; + } + + .lg\:border-none { + border-style: none; + } + + .lg\:border-0 { + border-width: 0; + } + + .lg\:border-2 { + border-width: 2px; + } + + .lg\:border-4 { + border-width: 4px; + } + + .lg\:border-8 { + border-width: 8px; + } + + .lg\:border { + border-width: 1px; + } + + .lg\:border-t-0 { + border-top-width: 0; + } + + .lg\:border-r-0 { + border-right-width: 0; + } + + .lg\:border-b-0 { + border-bottom-width: 0; + } + + .lg\:border-l-0 { + border-left-width: 0; + } + + .lg\:border-t-2 { + border-top-width: 2px; + } + + .lg\:border-r-2 { + border-right-width: 2px; + } + + .lg\:border-b-2 { + border-bottom-width: 2px; + } + + .lg\:border-l-2 { + border-left-width: 2px; + } + + .lg\:border-t-4 { + border-top-width: 4px; + } + + .lg\:border-r-4 { + border-right-width: 4px; + } + + .lg\:border-b-4 { + border-bottom-width: 4px; + } + + .lg\:border-l-4 { + border-left-width: 4px; + } + + .lg\:border-t-8 { + border-top-width: 8px; + } + + .lg\:border-r-8 { + border-right-width: 8px; + } + + .lg\:border-b-8 { + border-bottom-width: 8px; + } + + .lg\:border-l-8 { + border-left-width: 8px; + } + + .lg\:border-t { + border-top-width: 1px; + } + + .lg\:border-r { + border-right-width: 1px; + } + + .lg\:border-b { + border-bottom-width: 1px; + } + + .lg\:border-l { + border-left-width: 1px; + } + + .lg\:box-border { + box-sizing: border-box; + } + + .lg\:box-content { + box-sizing: content-box; + } + + .lg\:cursor-auto { + cursor: auto; + } + + .lg\:cursor-default { + cursor: default; + } + + .lg\:cursor-pointer { + cursor: pointer; + } + + .lg\:cursor-wait { + cursor: wait; + } + + .lg\:cursor-text { + cursor: text; + } + + .lg\:cursor-move { + cursor: move; + } + + .lg\:cursor-not-allowed { + cursor: not-allowed; + } + + .lg\:block { + display: block; + } + + .lg\:inline-block { + display: inline-block; + } + + .lg\:inline { + display: inline; + } + + .lg\:flex { + display: flex; + } + + .lg\:inline-flex { + display: inline-flex; + } + + .lg\:grid { + display: grid; + } + + .lg\:table { + display: table; + } + + .lg\:table-caption { + display: table-caption; + } + + .lg\:table-cell { + display: table-cell; + } + + .lg\:table-column { + display: table-column; + } + + .lg\:table-column-group { + display: table-column-group; + } + + .lg\:table-footer-group { + display: table-footer-group; + } + + .lg\:table-header-group { + display: table-header-group; + } + + .lg\:table-row-group { + display: table-row-group; + } + + .lg\:table-row { + display: table-row; + } + + .lg\:hidden { + display: none; + } + + .lg\:flex-row { + flex-direction: row; + } + + .lg\:flex-row-reverse { + flex-direction: row-reverse; + } + + .lg\:flex-col { + flex-direction: column; + } + + .lg\:flex-col-reverse { + flex-direction: column-reverse; + } + + .lg\:flex-wrap { + flex-wrap: wrap; + } + + .lg\:flex-wrap-reverse { + flex-wrap: wrap-reverse; + } + + .lg\:flex-no-wrap { + flex-wrap: nowrap; + } + + .lg\:items-start { + align-items: flex-start; + } + + .lg\:items-end { + align-items: flex-end; + } + + .lg\:items-center { + align-items: center; + } + + .lg\:items-baseline { + align-items: baseline; + } + + .lg\:items-stretch { + align-items: stretch; + } + + .lg\:self-auto { + align-self: auto; + } + + .lg\:self-start { + align-self: flex-start; + } + + .lg\:self-end { + align-self: flex-end; + } + + .lg\:self-center { + align-self: center; + } + + .lg\:self-stretch { + align-self: stretch; + } + + .lg\:justify-start { + justify-content: flex-start; + } + + .lg\:justify-end { + justify-content: flex-end; + } + + .lg\:justify-center { + justify-content: center; + } + + .lg\:justify-between { + justify-content: space-between; + } + + .lg\:justify-around { + justify-content: space-around; + } + + .lg\:justify-evenly { + justify-content: space-evenly; + } + + .lg\:content-center { + align-content: center; + } + + .lg\:content-start { + align-content: flex-start; + } + + .lg\:content-end { + align-content: flex-end; + } + + .lg\:content-between { + align-content: space-between; + } + + .lg\:content-around { + align-content: space-around; + } + + .lg\:flex-1 { + flex: 1 1 0%; + } + + .lg\:flex-auto { + flex: 1 1 auto; + } + + .lg\:flex-initial { + flex: 0 1 auto; + } + + .lg\:flex-none { + flex: none; + } + + .lg\:flex-grow-0 { + flex-grow: 0; + } + + .lg\:flex-grow { + flex-grow: 1; + } + + .lg\:flex-shrink-0 { + flex-shrink: 0; + } + + .lg\:flex-shrink { + flex-shrink: 1; + } + + .lg\:order-1 { + order: 1; + } + + .lg\:order-2 { + order: 2; + } + + .lg\:order-3 { + order: 3; + } + + .lg\:order-4 { + order: 4; + } + + .lg\:order-5 { + order: 5; + } + + .lg\:order-6 { + order: 6; + } + + .lg\:order-7 { + order: 7; + } + + .lg\:order-8 { + order: 8; + } + + .lg\:order-9 { + order: 9; + } + + .lg\:order-10 { + order: 10; + } + + .lg\:order-11 { + order: 11; + } + + .lg\:order-12 { + order: 12; + } + + .lg\:order-first { + order: -9999; + } + + .lg\:order-last { + order: 9999; + } + + .lg\:order-none { + order: 0; + } + + .lg\:float-right { + float: right; + } + + .lg\:float-left { + float: left; + } + + .lg\:float-none { + float: none; + } + + .lg\:clearfix:after { + content: ""; + display: table; + clear: both; + } + + .lg\:clear-left { + clear: left; + } + + .lg\:clear-right { + clear: right; + } + + .lg\:clear-both { + clear: both; + } + + .lg\:font-sans { + font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + } + + .lg\:font-serif { + font-family: Georgia, Cambria, "Times New Roman", Times, serif; + } + + .lg\:font-mono { + font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + } + + .lg\:font-hairline { + font-weight: 100; + } + + .lg\:font-thin { + font-weight: 200; + } + + .lg\:font-light { + font-weight: 300; + } + + .lg\:font-normal { + font-weight: 400; + } + + .lg\:font-medium { + font-weight: 500; + } + + .lg\:font-semibold { + font-weight: 600; + } + + .lg\:font-bold { + font-weight: 700; + } + + .lg\:font-extrabold { + font-weight: 800; + } + + .lg\:font-black { + font-weight: 900; + } + + .lg\:hover\:font-hairline:hover { + font-weight: 100; + } + + .lg\:hover\:font-thin:hover { + font-weight: 200; + } + + .lg\:hover\:font-light:hover { + font-weight: 300; + } + + .lg\:hover\:font-normal:hover { + font-weight: 400; + } + + .lg\:hover\:font-medium:hover { + font-weight: 500; + } + + .lg\:hover\:font-semibold:hover { + font-weight: 600; + } + + .lg\:hover\:font-bold:hover { + font-weight: 700; + } + + .lg\:hover\:font-extrabold:hover { + font-weight: 800; + } + + .lg\:hover\:font-black:hover { + font-weight: 900; + } + + .lg\:focus\:font-hairline:focus { + font-weight: 100; + } + + .lg\:focus\:font-thin:focus { + font-weight: 200; + } + + .lg\:focus\:font-light:focus { + font-weight: 300; + } + + .lg\:focus\:font-normal:focus { + font-weight: 400; + } + + .lg\:focus\:font-medium:focus { + font-weight: 500; + } + + .lg\:focus\:font-semibold:focus { + font-weight: 600; + } + + .lg\:focus\:font-bold:focus { + font-weight: 700; + } + + .lg\:focus\:font-extrabold:focus { + font-weight: 800; + } + + .lg\:focus\:font-black:focus { + font-weight: 900; + } + + .lg\:h-0 { + height: 0; + } + + .lg\:h-1 { + height: 0.25rem; + } + + .lg\:h-2 { + height: 0.5rem; + } + + .lg\:h-3 { + height: 0.75rem; + } + + .lg\:h-4 { + height: 1rem; + } + + .lg\:h-5 { + height: 1.25rem; + } + + .lg\:h-6 { + height: 1.5rem; + } + + .lg\:h-8 { + height: 2rem; + } + + .lg\:h-10 { + height: 2.5rem; + } + + .lg\:h-12 { + height: 3rem; + } + + .lg\:h-16 { + height: 4rem; + } + + .lg\:h-20 { + height: 5rem; + } + + .lg\:h-24 { + height: 6rem; + } + + .lg\:h-32 { + height: 8rem; + } + + .lg\:h-40 { + height: 10rem; + } + + .lg\:h-48 { + height: 12rem; + } + + .lg\:h-56 { + height: 14rem; + } + + .lg\:h-64 { + height: 16rem; + } + + .lg\:h-auto { + height: auto; + } + + .lg\:h-px { + height: 1px; + } + + .lg\:h-full { + height: 100%; + } + + .lg\:h-screen { + height: 100vh; + } + + .lg\:leading-3 { + line-height: .75rem; + } + + .lg\:leading-4 { + line-height: 1rem; + } + + .lg\:leading-5 { + line-height: 1.25rem; + } + + .lg\:leading-6 { + line-height: 1.5rem; + } + + .lg\:leading-7 { + line-height: 1.75rem; + } + + .lg\:leading-8 { + line-height: 2rem; + } + + .lg\:leading-9 { + line-height: 2.25rem; + } + + .lg\:leading-10 { + line-height: 2.5rem; + } + + .lg\:leading-none { + line-height: 1; + } + + .lg\:leading-tight { + line-height: 1.25; + } + + .lg\:leading-snug { + line-height: 1.375; + } + + .lg\:leading-normal { + line-height: 1.5; + } + + .lg\:leading-relaxed { + line-height: 1.625; + } + + .lg\:leading-loose { + line-height: 2; + } + + .lg\:list-inside { + list-style-position: inside; + } + + .lg\:list-outside { + list-style-position: outside; + } + + .lg\:list-none { + list-style-type: none; + } + + .lg\:list-disc { + list-style-type: disc; + } + + .lg\:list-decimal { + list-style-type: decimal; + } + + .lg\:m-0 { + margin: 0; + } + + .lg\:m-1 { + margin: 0.25rem; + } + + .lg\:m-2 { + margin: 0.5rem; + } + + .lg\:m-3 { + margin: 0.75rem; + } + + .lg\:m-4 { + margin: 1rem; + } + + .lg\:m-5 { + margin: 1.25rem; + } + + .lg\:m-6 { + margin: 1.5rem; + } + + .lg\:m-8 { + margin: 2rem; + } + + .lg\:m-10 { + margin: 2.5rem; + } + + .lg\:m-12 { + margin: 3rem; + } + + .lg\:m-16 { + margin: 4rem; + } + + .lg\:m-20 { + margin: 5rem; + } + + .lg\:m-24 { + margin: 6rem; + } + + .lg\:m-32 { + margin: 8rem; + } + + .lg\:m-40 { + margin: 10rem; + } + + .lg\:m-48 { + margin: 12rem; + } + + .lg\:m-56 { + margin: 14rem; + } + + .lg\:m-64 { + margin: 16rem; + } + + .lg\:m-auto { + margin: auto; + } + + .lg\:m-px { + margin: 1px; + } + + .lg\:-m-1 { + margin: -0.25rem; + } + + .lg\:-m-2 { + margin: -0.5rem; + } + + .lg\:-m-3 { + margin: -0.75rem; + } + + .lg\:-m-4 { + margin: -1rem; + } + + .lg\:-m-5 { + margin: -1.25rem; + } + + .lg\:-m-6 { + margin: -1.5rem; + } + + .lg\:-m-8 { + margin: -2rem; + } + + .lg\:-m-10 { + margin: -2.5rem; + } + + .lg\:-m-12 { + margin: -3rem; + } + + .lg\:-m-16 { + margin: -4rem; + } + + .lg\:-m-20 { + margin: -5rem; + } + + .lg\:-m-24 { + margin: -6rem; + } + + .lg\:-m-32 { + margin: -8rem; + } + + .lg\:-m-40 { + margin: -10rem; + } + + .lg\:-m-48 { + margin: -12rem; + } + + .lg\:-m-56 { + margin: -14rem; + } + + .lg\:-m-64 { + margin: -16rem; + } + + .lg\:-m-px { + margin: -1px; + } + + .lg\:my-0 { + margin-top: 0; + margin-bottom: 0; + } + + .lg\:mx-0 { + margin-left: 0; + margin-right: 0; + } + + .lg\:my-1 { + margin-top: 0.25rem; + margin-bottom: 0.25rem; + } + + .lg\:mx-1 { + margin-left: 0.25rem; + margin-right: 0.25rem; + } + + .lg\:my-2 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; + } + + .lg\:mx-2 { + margin-left: 0.5rem; + margin-right: 0.5rem; + } + + .lg\:my-3 { + margin-top: 0.75rem; + margin-bottom: 0.75rem; + } + + .lg\:mx-3 { + margin-left: 0.75rem; + margin-right: 0.75rem; + } + + .lg\:my-4 { + margin-top: 1rem; + margin-bottom: 1rem; + } + + .lg\:mx-4 { + margin-left: 1rem; + margin-right: 1rem; + } + + .lg\:my-5 { + margin-top: 1.25rem; + margin-bottom: 1.25rem; + } + + .lg\:mx-5 { + margin-left: 1.25rem; + margin-right: 1.25rem; + } + + .lg\:my-6 { + margin-top: 1.5rem; + margin-bottom: 1.5rem; + } + + .lg\:mx-6 { + margin-left: 1.5rem; + margin-right: 1.5rem; + } + + .lg\:my-8 { + margin-top: 2rem; + margin-bottom: 2rem; + } + + .lg\:mx-8 { + margin-left: 2rem; + margin-right: 2rem; + } + + .lg\:my-10 { + margin-top: 2.5rem; + margin-bottom: 2.5rem; + } + + .lg\:mx-10 { + margin-left: 2.5rem; + margin-right: 2.5rem; + } + + .lg\:my-12 { + margin-top: 3rem; + margin-bottom: 3rem; + } + + .lg\:mx-12 { + margin-left: 3rem; + margin-right: 3rem; + } + + .lg\:my-16 { + margin-top: 4rem; + margin-bottom: 4rem; + } + + .lg\:mx-16 { + margin-left: 4rem; + margin-right: 4rem; + } + + .lg\:my-20 { + margin-top: 5rem; + margin-bottom: 5rem; + } + + .lg\:mx-20 { + margin-left: 5rem; + margin-right: 5rem; + } + + .lg\:my-24 { + margin-top: 6rem; + margin-bottom: 6rem; + } + + .lg\:mx-24 { + margin-left: 6rem; + margin-right: 6rem; + } + + .lg\:my-32 { + margin-top: 8rem; + margin-bottom: 8rem; + } + + .lg\:mx-32 { + margin-left: 8rem; + margin-right: 8rem; + } + + .lg\:my-40 { + margin-top: 10rem; + margin-bottom: 10rem; + } + + .lg\:mx-40 { + margin-left: 10rem; + margin-right: 10rem; + } + + .lg\:my-48 { + margin-top: 12rem; + margin-bottom: 12rem; + } + + .lg\:mx-48 { + margin-left: 12rem; + margin-right: 12rem; + } + + .lg\:my-56 { + margin-top: 14rem; + margin-bottom: 14rem; + } + + .lg\:mx-56 { + margin-left: 14rem; + margin-right: 14rem; + } + + .lg\:my-64 { + margin-top: 16rem; + margin-bottom: 16rem; + } + + .lg\:mx-64 { + margin-left: 16rem; + margin-right: 16rem; + } + + .lg\:my-auto { + margin-top: auto; + margin-bottom: auto; + } + + .lg\:mx-auto { + margin-left: auto; + margin-right: auto; + } + + .lg\:my-px { + margin-top: 1px; + margin-bottom: 1px; + } + + .lg\:mx-px { + margin-left: 1px; + margin-right: 1px; + } + + .lg\:-my-1 { + margin-top: -0.25rem; + margin-bottom: -0.25rem; + } + + .lg\:-mx-1 { + margin-left: -0.25rem; + margin-right: -0.25rem; + } + + .lg\:-my-2 { + margin-top: -0.5rem; + margin-bottom: -0.5rem; + } + + .lg\:-mx-2 { + margin-left: -0.5rem; + margin-right: -0.5rem; + } + + .lg\:-my-3 { + margin-top: -0.75rem; + margin-bottom: -0.75rem; + } + + .lg\:-mx-3 { + margin-left: -0.75rem; + margin-right: -0.75rem; + } + + .lg\:-my-4 { + margin-top: -1rem; + margin-bottom: -1rem; + } + + .lg\:-mx-4 { + margin-left: -1rem; + margin-right: -1rem; + } + + .lg\:-my-5 { + margin-top: -1.25rem; + margin-bottom: -1.25rem; + } + + .lg\:-mx-5 { + margin-left: -1.25rem; + margin-right: -1.25rem; + } + + .lg\:-my-6 { + margin-top: -1.5rem; + margin-bottom: -1.5rem; + } + + .lg\:-mx-6 { + margin-left: -1.5rem; + margin-right: -1.5rem; + } + + .lg\:-my-8 { + margin-top: -2rem; + margin-bottom: -2rem; + } + + .lg\:-mx-8 { + margin-left: -2rem; + margin-right: -2rem; + } + + .lg\:-my-10 { + margin-top: -2.5rem; + margin-bottom: -2.5rem; + } + + .lg\:-mx-10 { + margin-left: -2.5rem; + margin-right: -2.5rem; + } + + .lg\:-my-12 { + margin-top: -3rem; + margin-bottom: -3rem; + } + + .lg\:-mx-12 { + margin-left: -3rem; + margin-right: -3rem; + } + + .lg\:-my-16 { + margin-top: -4rem; + margin-bottom: -4rem; + } + + .lg\:-mx-16 { + margin-left: -4rem; + margin-right: -4rem; + } + + .lg\:-my-20 { + margin-top: -5rem; + margin-bottom: -5rem; + } + + .lg\:-mx-20 { + margin-left: -5rem; + margin-right: -5rem; + } + + .lg\:-my-24 { + margin-top: -6rem; + margin-bottom: -6rem; + } + + .lg\:-mx-24 { + margin-left: -6rem; + margin-right: -6rem; + } + + .lg\:-my-32 { + margin-top: -8rem; + margin-bottom: -8rem; + } + + .lg\:-mx-32 { + margin-left: -8rem; + margin-right: -8rem; + } + + .lg\:-my-40 { + margin-top: -10rem; + margin-bottom: -10rem; + } + + .lg\:-mx-40 { + margin-left: -10rem; + margin-right: -10rem; + } + + .lg\:-my-48 { + margin-top: -12rem; + margin-bottom: -12rem; + } + + .lg\:-mx-48 { + margin-left: -12rem; + margin-right: -12rem; + } + + .lg\:-my-56 { + margin-top: -14rem; + margin-bottom: -14rem; + } + + .lg\:-mx-56 { + margin-left: -14rem; + margin-right: -14rem; + } + + .lg\:-my-64 { + margin-top: -16rem; + margin-bottom: -16rem; + } + + .lg\:-mx-64 { + margin-left: -16rem; + margin-right: -16rem; + } + + .lg\:-my-px { + margin-top: -1px; + margin-bottom: -1px; + } + + .lg\:-mx-px { + margin-left: -1px; + margin-right: -1px; + } + + .lg\:mt-0 { + margin-top: 0; + } + + .lg\:mr-0 { + margin-right: 0; + } + + .lg\:mb-0 { + margin-bottom: 0; + } + + .lg\:ml-0 { + margin-left: 0; + } + + .lg\:mt-1 { + margin-top: 0.25rem; + } + + .lg\:mr-1 { + margin-right: 0.25rem; + } + + .lg\:mb-1 { + margin-bottom: 0.25rem; + } + + .lg\:ml-1 { + margin-left: 0.25rem; + } + + .lg\:mt-2 { + margin-top: 0.5rem; + } + + .lg\:mr-2 { + margin-right: 0.5rem; + } + + .lg\:mb-2 { + margin-bottom: 0.5rem; + } + + .lg\:ml-2 { + margin-left: 0.5rem; + } + + .lg\:mt-3 { + margin-top: 0.75rem; + } + + .lg\:mr-3 { + margin-right: 0.75rem; + } + + .lg\:mb-3 { + margin-bottom: 0.75rem; + } + + .lg\:ml-3 { + margin-left: 0.75rem; + } + + .lg\:mt-4 { + margin-top: 1rem; + } + + .lg\:mr-4 { + margin-right: 1rem; + } + + .lg\:mb-4 { + margin-bottom: 1rem; + } + + .lg\:ml-4 { + margin-left: 1rem; + } + + .lg\:mt-5 { + margin-top: 1.25rem; + } + + .lg\:mr-5 { + margin-right: 1.25rem; + } + + .lg\:mb-5 { + margin-bottom: 1.25rem; + } + + .lg\:ml-5 { + margin-left: 1.25rem; + } + + .lg\:mt-6 { + margin-top: 1.5rem; + } + + .lg\:mr-6 { + margin-right: 1.5rem; + } + + .lg\:mb-6 { + margin-bottom: 1.5rem; + } + + .lg\:ml-6 { + margin-left: 1.5rem; + } + + .lg\:mt-8 { + margin-top: 2rem; + } + + .lg\:mr-8 { + margin-right: 2rem; + } + + .lg\:mb-8 { + margin-bottom: 2rem; + } + + .lg\:ml-8 { + margin-left: 2rem; + } + + .lg\:mt-10 { + margin-top: 2.5rem; + } + + .lg\:mr-10 { + margin-right: 2.5rem; + } + + .lg\:mb-10 { + margin-bottom: 2.5rem; + } + + .lg\:ml-10 { + margin-left: 2.5rem; + } + + .lg\:mt-12 { + margin-top: 3rem; + } + + .lg\:mr-12 { + margin-right: 3rem; + } + + .lg\:mb-12 { + margin-bottom: 3rem; + } + + .lg\:ml-12 { + margin-left: 3rem; + } + + .lg\:mt-16 { + margin-top: 4rem; + } + + .lg\:mr-16 { + margin-right: 4rem; + } + + .lg\:mb-16 { + margin-bottom: 4rem; + } + + .lg\:ml-16 { + margin-left: 4rem; + } + + .lg\:mt-20 { + margin-top: 5rem; + } + + .lg\:mr-20 { + margin-right: 5rem; + } + + .lg\:mb-20 { + margin-bottom: 5rem; + } + + .lg\:ml-20 { + margin-left: 5rem; + } + + .lg\:mt-24 { + margin-top: 6rem; + } + + .lg\:mr-24 { + margin-right: 6rem; + } + + .lg\:mb-24 { + margin-bottom: 6rem; + } + + .lg\:ml-24 { + margin-left: 6rem; + } + + .lg\:mt-32 { + margin-top: 8rem; + } + + .lg\:mr-32 { + margin-right: 8rem; + } + + .lg\:mb-32 { + margin-bottom: 8rem; + } + + .lg\:ml-32 { + margin-left: 8rem; + } + + .lg\:mt-40 { + margin-top: 10rem; + } + + .lg\:mr-40 { + margin-right: 10rem; + } + + .lg\:mb-40 { + margin-bottom: 10rem; + } + + .lg\:ml-40 { + margin-left: 10rem; + } + + .lg\:mt-48 { + margin-top: 12rem; + } + + .lg\:mr-48 { + margin-right: 12rem; + } + + .lg\:mb-48 { + margin-bottom: 12rem; + } + + .lg\:ml-48 { + margin-left: 12rem; + } + + .lg\:mt-56 { + margin-top: 14rem; + } + + .lg\:mr-56 { + margin-right: 14rem; + } + + .lg\:mb-56 { + margin-bottom: 14rem; + } + + .lg\:ml-56 { + margin-left: 14rem; + } + + .lg\:mt-64 { + margin-top: 16rem; + } + + .lg\:mr-64 { + margin-right: 16rem; + } + + .lg\:mb-64 { + margin-bottom: 16rem; + } + + .lg\:ml-64 { + margin-left: 16rem; + } + + .lg\:mt-auto { + margin-top: auto; + } + + .lg\:mr-auto { + margin-right: auto; + } + + .lg\:mb-auto { + margin-bottom: auto; + } + + .lg\:ml-auto { + margin-left: auto; + } + + .lg\:mt-px { + margin-top: 1px; + } + + .lg\:mr-px { + margin-right: 1px; + } + + .lg\:mb-px { + margin-bottom: 1px; + } + + .lg\:ml-px { + margin-left: 1px; + } + + .lg\:-mt-1 { + margin-top: -0.25rem; + } + + .lg\:-mr-1 { + margin-right: -0.25rem; + } + + .lg\:-mb-1 { + margin-bottom: -0.25rem; + } + + .lg\:-ml-1 { + margin-left: -0.25rem; + } + + .lg\:-mt-2 { + margin-top: -0.5rem; + } + + .lg\:-mr-2 { + margin-right: -0.5rem; + } + + .lg\:-mb-2 { + margin-bottom: -0.5rem; + } + + .lg\:-ml-2 { + margin-left: -0.5rem; + } + + .lg\:-mt-3 { + margin-top: -0.75rem; + } + + .lg\:-mr-3 { + margin-right: -0.75rem; + } + + .lg\:-mb-3 { + margin-bottom: -0.75rem; + } + + .lg\:-ml-3 { + margin-left: -0.75rem; + } + + .lg\:-mt-4 { + margin-top: -1rem; + } + + .lg\:-mr-4 { + margin-right: -1rem; + } + + .lg\:-mb-4 { + margin-bottom: -1rem; + } + + .lg\:-ml-4 { + margin-left: -1rem; + } + + .lg\:-mt-5 { + margin-top: -1.25rem; + } + + .lg\:-mr-5 { + margin-right: -1.25rem; + } + + .lg\:-mb-5 { + margin-bottom: -1.25rem; + } + + .lg\:-ml-5 { + margin-left: -1.25rem; + } + + .lg\:-mt-6 { + margin-top: -1.5rem; + } + + .lg\:-mr-6 { + margin-right: -1.5rem; + } + + .lg\:-mb-6 { + margin-bottom: -1.5rem; + } + + .lg\:-ml-6 { + margin-left: -1.5rem; + } + + .lg\:-mt-8 { + margin-top: -2rem; + } + + .lg\:-mr-8 { + margin-right: -2rem; + } + + .lg\:-mb-8 { + margin-bottom: -2rem; + } + + .lg\:-ml-8 { + margin-left: -2rem; + } + + .lg\:-mt-10 { + margin-top: -2.5rem; + } + + .lg\:-mr-10 { + margin-right: -2.5rem; + } + + .lg\:-mb-10 { + margin-bottom: -2.5rem; + } + + .lg\:-ml-10 { + margin-left: -2.5rem; + } + + .lg\:-mt-12 { + margin-top: -3rem; + } + + .lg\:-mr-12 { + margin-right: -3rem; + } + + .lg\:-mb-12 { + margin-bottom: -3rem; + } + + .lg\:-ml-12 { + margin-left: -3rem; + } + + .lg\:-mt-16 { + margin-top: -4rem; + } + + .lg\:-mr-16 { + margin-right: -4rem; + } + + .lg\:-mb-16 { + margin-bottom: -4rem; + } + + .lg\:-ml-16 { + margin-left: -4rem; + } + + .lg\:-mt-20 { + margin-top: -5rem; + } + + .lg\:-mr-20 { + margin-right: -5rem; + } + + .lg\:-mb-20 { + margin-bottom: -5rem; + } + + .lg\:-ml-20 { + margin-left: -5rem; + } + + .lg\:-mt-24 { + margin-top: -6rem; + } + + .lg\:-mr-24 { + margin-right: -6rem; + } + + .lg\:-mb-24 { + margin-bottom: -6rem; + } + + .lg\:-ml-24 { + margin-left: -6rem; + } + + .lg\:-mt-32 { + margin-top: -8rem; + } + + .lg\:-mr-32 { + margin-right: -8rem; + } + + .lg\:-mb-32 { + margin-bottom: -8rem; + } + + .lg\:-ml-32 { + margin-left: -8rem; + } + + .lg\:-mt-40 { + margin-top: -10rem; + } + + .lg\:-mr-40 { + margin-right: -10rem; + } + + .lg\:-mb-40 { + margin-bottom: -10rem; + } + + .lg\:-ml-40 { + margin-left: -10rem; + } + + .lg\:-mt-48 { + margin-top: -12rem; + } + + .lg\:-mr-48 { + margin-right: -12rem; + } + + .lg\:-mb-48 { + margin-bottom: -12rem; + } + + .lg\:-ml-48 { + margin-left: -12rem; + } + + .lg\:-mt-56 { + margin-top: -14rem; + } + + .lg\:-mr-56 { + margin-right: -14rem; + } + + .lg\:-mb-56 { + margin-bottom: -14rem; + } + + .lg\:-ml-56 { + margin-left: -14rem; + } + + .lg\:-mt-64 { + margin-top: -16rem; + } + + .lg\:-mr-64 { + margin-right: -16rem; + } + + .lg\:-mb-64 { + margin-bottom: -16rem; + } + + .lg\:-ml-64 { + margin-left: -16rem; + } + + .lg\:-mt-px { + margin-top: -1px; + } + + .lg\:-mr-px { + margin-right: -1px; + } + + .lg\:-mb-px { + margin-bottom: -1px; + } + + .lg\:-ml-px { + margin-left: -1px; + } + + .lg\:max-h-full { + max-height: 100%; + } + + .lg\:max-h-screen { + max-height: 100vh; + } + + .lg\:max-w-none { + max-width: none; + } + + .lg\:max-w-xs { + max-width: 20rem; + } + + .lg\:max-w-sm { + max-width: 24rem; + } + + .lg\:max-w-md { + max-width: 28rem; + } + + .lg\:max-w-lg { + max-width: 32rem; + } + + .lg\:max-w-xl { + max-width: 36rem; + } + + .lg\:max-w-2xl { + max-width: 42rem; + } + + .lg\:max-w-3xl { + max-width: 48rem; + } + + .lg\:max-w-4xl { + max-width: 56rem; + } + + .lg\:max-w-5xl { + max-width: 64rem; + } + + .lg\:max-w-6xl { + max-width: 72rem; + } + + .lg\:max-w-full { + max-width: 100%; + } + + .lg\:max-w-screen-sm { + max-width: 640px; + } + + .lg\:max-w-screen-md { + max-width: 768px; + } + + .lg\:max-w-screen-lg { + max-width: 1024px; + } + + .lg\:max-w-screen-xl { + max-width: 1280px; + } + + .lg\:min-h-0 { + min-height: 0; + } + + .lg\:min-h-full { + min-height: 100%; + } + + .lg\:min-h-screen { + min-height: 100vh; + } + + .lg\:min-w-0 { + min-width: 0; + } + + .lg\:min-w-full { + min-width: 100%; + } + + .lg\:object-contain { + object-fit: contain; + } + + .lg\:object-cover { + object-fit: cover; + } + + .lg\:object-fill { + object-fit: fill; + } + + .lg\:object-none { + object-fit: none; + } + + .lg\:object-scale-down { + object-fit: scale-down; + } + + .lg\:object-bottom { + object-position: bottom; + } + + .lg\:object-center { + object-position: center; + } + + .lg\:object-left { + object-position: left; + } + + .lg\:object-left-bottom { + object-position: left bottom; + } + + .lg\:object-left-top { + object-position: left top; + } + + .lg\:object-right { + object-position: right; + } + + .lg\:object-right-bottom { + object-position: right bottom; + } + + .lg\:object-right-top { + object-position: right top; + } + + .lg\:object-top { + object-position: top; + } + + .lg\:opacity-0 { + opacity: 0; + } + + .lg\:opacity-25 { + opacity: 0.25; + } + + .lg\:opacity-50 { + opacity: 0.5; + } + + .lg\:opacity-75 { + opacity: 0.75; + } + + .lg\:opacity-100 { + opacity: 1; + } + + .lg\:hover\:opacity-0:hover { + opacity: 0; + } + + .lg\:hover\:opacity-25:hover { + opacity: 0.25; + } + + .lg\:hover\:opacity-50:hover { + opacity: 0.5; + } + + .lg\:hover\:opacity-75:hover { + opacity: 0.75; + } + + .lg\:hover\:opacity-100:hover { + opacity: 1; + } + + .lg\:focus\:opacity-0:focus { + opacity: 0; + } + + .lg\:focus\:opacity-25:focus { + opacity: 0.25; + } + + .lg\:focus\:opacity-50:focus { + opacity: 0.5; + } + + .lg\:focus\:opacity-75:focus { + opacity: 0.75; + } + + .lg\:focus\:opacity-100:focus { + opacity: 1; + } + + .lg\:outline-none { + outline: 0; + } + + .lg\:focus\:outline-none:focus { + outline: 0; + } + + .lg\:overflow-auto { + overflow: auto; + } + + .lg\:overflow-hidden { + overflow: hidden; + } + + .lg\:overflow-visible { + overflow: visible; + } + + .lg\:overflow-scroll { + overflow: scroll; + } + + .lg\:overflow-x-auto { + overflow-x: auto; + } + + .lg\:overflow-y-auto { + overflow-y: auto; + } + + .lg\:overflow-x-hidden { + overflow-x: hidden; + } + + .lg\:overflow-y-hidden { + overflow-y: hidden; + } + + .lg\:overflow-x-visible { + overflow-x: visible; + } + + .lg\:overflow-y-visible { + overflow-y: visible; + } + + .lg\:overflow-x-scroll { + overflow-x: scroll; + } + + .lg\:overflow-y-scroll { + overflow-y: scroll; + } + + .lg\:scrolling-touch { + -webkit-overflow-scrolling: touch; + } + + .lg\:scrolling-auto { + -webkit-overflow-scrolling: auto; + } + + .lg\:p-0 { + padding: 0; + } + + .lg\:p-1 { + padding: 0.25rem; + } + + .lg\:p-2 { + padding: 0.5rem; + } + + .lg\:p-3 { + padding: 0.75rem; + } + + .lg\:p-4 { + padding: 1rem; + } + + .lg\:p-5 { + padding: 1.25rem; + } + + .lg\:p-6 { + padding: 1.5rem; + } + + .lg\:p-8 { + padding: 2rem; + } + + .lg\:p-10 { + padding: 2.5rem; + } + + .lg\:p-12 { + padding: 3rem; + } + + .lg\:p-16 { + padding: 4rem; + } + + .lg\:p-20 { + padding: 5rem; + } + + .lg\:p-24 { + padding: 6rem; + } + + .lg\:p-32 { + padding: 8rem; + } + + .lg\:p-40 { + padding: 10rem; + } + + .lg\:p-48 { + padding: 12rem; + } + + .lg\:p-56 { + padding: 14rem; + } + + .lg\:p-64 { + padding: 16rem; + } + + .lg\:p-px { + padding: 1px; + } + + .lg\:py-0 { + padding-top: 0; + padding-bottom: 0; + } + + .lg\:px-0 { + padding-left: 0; + padding-right: 0; + } + + .lg\:py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + + .lg\:px-1 { + padding-left: 0.25rem; + padding-right: 0.25rem; + } + + .lg\:py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + } + + .lg\:px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; + } + + .lg\:py-3 { + padding-top: 0.75rem; + padding-bottom: 0.75rem; + } + + .lg\:px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; + } + + .lg\:py-4 { + padding-top: 1rem; + padding-bottom: 1rem; + } + + .lg\:px-4 { + padding-left: 1rem; + padding-right: 1rem; + } + + .lg\:py-5 { + padding-top: 1.25rem; + padding-bottom: 1.25rem; + } + + .lg\:px-5 { + padding-left: 1.25rem; + padding-right: 1.25rem; + } + + .lg\:py-6 { + padding-top: 1.5rem; + padding-bottom: 1.5rem; + } + + .lg\:px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; + } + + .lg\:py-8 { + padding-top: 2rem; + padding-bottom: 2rem; + } + + .lg\:px-8 { + padding-left: 2rem; + padding-right: 2rem; + } + + .lg\:py-10 { + padding-top: 2.5rem; + padding-bottom: 2.5rem; + } + + .lg\:px-10 { + padding-left: 2.5rem; + padding-right: 2.5rem; + } + + .lg\:py-12 { + padding-top: 3rem; + padding-bottom: 3rem; + } + + .lg\:px-12 { + padding-left: 3rem; + padding-right: 3rem; + } + + .lg\:py-16 { + padding-top: 4rem; + padding-bottom: 4rem; + } + + .lg\:px-16 { + padding-left: 4rem; + padding-right: 4rem; + } + + .lg\:py-20 { + padding-top: 5rem; + padding-bottom: 5rem; + } + + .lg\:px-20 { + padding-left: 5rem; + padding-right: 5rem; + } + + .lg\:py-24 { + padding-top: 6rem; + padding-bottom: 6rem; + } + + .lg\:px-24 { + padding-left: 6rem; + padding-right: 6rem; + } + + .lg\:py-32 { + padding-top: 8rem; + padding-bottom: 8rem; + } + + .lg\:px-32 { + padding-left: 8rem; + padding-right: 8rem; + } + + .lg\:py-40 { + padding-top: 10rem; + padding-bottom: 10rem; + } + + .lg\:px-40 { + padding-left: 10rem; + padding-right: 10rem; + } + + .lg\:py-48 { + padding-top: 12rem; + padding-bottom: 12rem; + } + + .lg\:px-48 { + padding-left: 12rem; + padding-right: 12rem; + } + + .lg\:py-56 { + padding-top: 14rem; + padding-bottom: 14rem; + } + + .lg\:px-56 { + padding-left: 14rem; + padding-right: 14rem; + } + + .lg\:py-64 { + padding-top: 16rem; + padding-bottom: 16rem; + } + + .lg\:px-64 { + padding-left: 16rem; + padding-right: 16rem; + } + + .lg\:py-px { + padding-top: 1px; + padding-bottom: 1px; + } + + .lg\:px-px { + padding-left: 1px; + padding-right: 1px; + } + + .lg\:pt-0 { + padding-top: 0; + } + + .lg\:pr-0 { + padding-right: 0; + } + + .lg\:pb-0 { + padding-bottom: 0; + } + + .lg\:pl-0 { + padding-left: 0; + } + + .lg\:pt-1 { + padding-top: 0.25rem; + } + + .lg\:pr-1 { + padding-right: 0.25rem; + } + + .lg\:pb-1 { + padding-bottom: 0.25rem; + } + + .lg\:pl-1 { + padding-left: 0.25rem; + } + + .lg\:pt-2 { + padding-top: 0.5rem; + } + + .lg\:pr-2 { + padding-right: 0.5rem; + } + + .lg\:pb-2 { + padding-bottom: 0.5rem; + } + + .lg\:pl-2 { + padding-left: 0.5rem; + } + + .lg\:pt-3 { + padding-top: 0.75rem; + } + + .lg\:pr-3 { + padding-right: 0.75rem; + } + + .lg\:pb-3 { + padding-bottom: 0.75rem; + } + + .lg\:pl-3 { + padding-left: 0.75rem; + } + + .lg\:pt-4 { + padding-top: 1rem; + } + + .lg\:pr-4 { + padding-right: 1rem; + } + + .lg\:pb-4 { + padding-bottom: 1rem; + } + + .lg\:pl-4 { + padding-left: 1rem; + } + + .lg\:pt-5 { + padding-top: 1.25rem; + } + + .lg\:pr-5 { + padding-right: 1.25rem; + } + + .lg\:pb-5 { + padding-bottom: 1.25rem; + } + + .lg\:pl-5 { + padding-left: 1.25rem; + } + + .lg\:pt-6 { + padding-top: 1.5rem; + } + + .lg\:pr-6 { + padding-right: 1.5rem; + } + + .lg\:pb-6 { + padding-bottom: 1.5rem; + } + + .lg\:pl-6 { + padding-left: 1.5rem; + } + + .lg\:pt-8 { + padding-top: 2rem; + } + + .lg\:pr-8 { + padding-right: 2rem; + } + + .lg\:pb-8 { + padding-bottom: 2rem; + } + + .lg\:pl-8 { + padding-left: 2rem; + } + + .lg\:pt-10 { + padding-top: 2.5rem; + } + + .lg\:pr-10 { + padding-right: 2.5rem; + } + + .lg\:pb-10 { + padding-bottom: 2.5rem; + } + + .lg\:pl-10 { + padding-left: 2.5rem; + } + + .lg\:pt-12 { + padding-top: 3rem; + } + + .lg\:pr-12 { + padding-right: 3rem; + } + + .lg\:pb-12 { + padding-bottom: 3rem; + } + + .lg\:pl-12 { + padding-left: 3rem; + } + + .lg\:pt-16 { + padding-top: 4rem; + } + + .lg\:pr-16 { + padding-right: 4rem; + } + + .lg\:pb-16 { + padding-bottom: 4rem; + } + + .lg\:pl-16 { + padding-left: 4rem; + } + + .lg\:pt-20 { + padding-top: 5rem; + } + + .lg\:pr-20 { + padding-right: 5rem; + } + + .lg\:pb-20 { + padding-bottom: 5rem; + } + + .lg\:pl-20 { + padding-left: 5rem; + } + + .lg\:pt-24 { + padding-top: 6rem; + } + + .lg\:pr-24 { + padding-right: 6rem; + } + + .lg\:pb-24 { + padding-bottom: 6rem; + } + + .lg\:pl-24 { + padding-left: 6rem; + } + + .lg\:pt-32 { + padding-top: 8rem; + } + + .lg\:pr-32 { + padding-right: 8rem; + } + + .lg\:pb-32 { + padding-bottom: 8rem; + } + + .lg\:pl-32 { + padding-left: 8rem; + } + + .lg\:pt-40 { + padding-top: 10rem; + } + + .lg\:pr-40 { + padding-right: 10rem; + } + + .lg\:pb-40 { + padding-bottom: 10rem; + } + + .lg\:pl-40 { + padding-left: 10rem; + } + + .lg\:pt-48 { + padding-top: 12rem; + } + + .lg\:pr-48 { + padding-right: 12rem; + } + + .lg\:pb-48 { + padding-bottom: 12rem; + } + + .lg\:pl-48 { + padding-left: 12rem; + } + + .lg\:pt-56 { + padding-top: 14rem; + } + + .lg\:pr-56 { + padding-right: 14rem; + } + + .lg\:pb-56 { + padding-bottom: 14rem; + } + + .lg\:pl-56 { + padding-left: 14rem; + } + + .lg\:pt-64 { + padding-top: 16rem; + } + + .lg\:pr-64 { + padding-right: 16rem; + } + + .lg\:pb-64 { + padding-bottom: 16rem; + } + + .lg\:pl-64 { + padding-left: 16rem; + } + + .lg\:pt-px { + padding-top: 1px; + } + + .lg\:pr-px { + padding-right: 1px; + } + + .lg\:pb-px { + padding-bottom: 1px; + } + + .lg\:pl-px { + padding-left: 1px; + } + + .lg\:placeholder-transparent::placeholder { + color: transparent; + } + + .lg\:placeholder-black::placeholder { + color: #000; + } + + .lg\:placeholder-white::placeholder { + color: #fff; + } + + .lg\:placeholder-gray-100::placeholder { + color: #f7fafc; + } + + .lg\:placeholder-gray-200::placeholder { + color: #edf2f7; + } + + .lg\:placeholder-gray-300::placeholder { + color: #e2e8f0; + } + + .lg\:placeholder-gray-400::placeholder { + color: #cbd5e0; + } + + .lg\:placeholder-gray-500::placeholder { + color: #a0aec0; + } + + .lg\:placeholder-gray-600::placeholder { + color: #718096; + } + + .lg\:placeholder-gray-700::placeholder { + color: #4a5568; + } + + .lg\:placeholder-gray-800::placeholder { + color: #2d3748; + } + + .lg\:placeholder-gray-900::placeholder { + color: #1a202c; + } + + .lg\:placeholder-red-100::placeholder { + color: #fff5f5; + } + + .lg\:placeholder-red-200::placeholder { + color: #fed7d7; + } + + .lg\:placeholder-red-300::placeholder { + color: #feb2b2; + } + + .lg\:placeholder-red-400::placeholder { + color: #fc8181; + } + + .lg\:placeholder-red-500::placeholder { + color: #f56565; + } + + .lg\:placeholder-red-600::placeholder { + color: #e53e3e; + } + + .lg\:placeholder-red-700::placeholder { + color: #c53030; + } + + .lg\:placeholder-red-800::placeholder { + color: #9b2c2c; + } + + .lg\:placeholder-red-900::placeholder { + color: #742a2a; + } + + .lg\:placeholder-orange-100::placeholder { + color: #fffaf0; + } + + .lg\:placeholder-orange-200::placeholder { + color: #feebc8; + } + + .lg\:placeholder-orange-300::placeholder { + color: #fbd38d; + } + + .lg\:placeholder-orange-400::placeholder { + color: #f6ad55; + } + + .lg\:placeholder-orange-500::placeholder { + color: #ed8936; + } + + .lg\:placeholder-orange-600::placeholder { + color: #dd6b20; + } + + .lg\:placeholder-orange-700::placeholder { + color: #c05621; + } + + .lg\:placeholder-orange-800::placeholder { + color: #9c4221; + } + + .lg\:placeholder-orange-900::placeholder { + color: #7b341e; + } + + .lg\:placeholder-yellow-100::placeholder { + color: #fffff0; + } + + .lg\:placeholder-yellow-200::placeholder { + color: #fefcbf; + } + + .lg\:placeholder-yellow-300::placeholder { + color: #faf089; + } + + .lg\:placeholder-yellow-400::placeholder { + color: #f6e05e; + } + + .lg\:placeholder-yellow-500::placeholder { + color: #ecc94b; + } + + .lg\:placeholder-yellow-600::placeholder { + color: #d69e2e; + } + + .lg\:placeholder-yellow-700::placeholder { + color: #b7791f; + } + + .lg\:placeholder-yellow-800::placeholder { + color: #975a16; + } + + .lg\:placeholder-yellow-900::placeholder { + color: #744210; + } + + .lg\:placeholder-green-100::placeholder { + color: #f0fff4; + } + + .lg\:placeholder-green-200::placeholder { + color: #c6f6d5; + } + + .lg\:placeholder-green-300::placeholder { + color: #9ae6b4; + } + + .lg\:placeholder-green-400::placeholder { + color: #68d391; + } + + .lg\:placeholder-green-500::placeholder { + color: #48bb78; + } + + .lg\:placeholder-green-600::placeholder { + color: #38a169; + } + + .lg\:placeholder-green-700::placeholder { + color: #2f855a; + } + + .lg\:placeholder-green-800::placeholder { + color: #276749; + } + + .lg\:placeholder-green-900::placeholder { + color: #22543d; + } + + .lg\:placeholder-teal-100::placeholder { + color: #e6fffa; + } + + .lg\:placeholder-teal-200::placeholder { + color: #b2f5ea; + } + + .lg\:placeholder-teal-300::placeholder { + color: #81e6d9; + } + + .lg\:placeholder-teal-400::placeholder { + color: #4fd1c5; + } + + .lg\:placeholder-teal-500::placeholder { + color: #38b2ac; + } + + .lg\:placeholder-teal-600::placeholder { + color: #319795; + } + + .lg\:placeholder-teal-700::placeholder { + color: #2c7a7b; + } + + .lg\:placeholder-teal-800::placeholder { + color: #285e61; + } + + .lg\:placeholder-teal-900::placeholder { + color: #234e52; + } + + .lg\:placeholder-blue-100::placeholder { + color: #ebf8ff; + } + + .lg\:placeholder-blue-200::placeholder { + color: #bee3f8; + } + + .lg\:placeholder-blue-300::placeholder { + color: #90cdf4; + } + + .lg\:placeholder-blue-400::placeholder { + color: #63b3ed; + } + + .lg\:placeholder-blue-500::placeholder { + color: #4299e1; + } + + .lg\:placeholder-blue-600::placeholder { + color: #3182ce; + } + + .lg\:placeholder-blue-700::placeholder { + color: #2b6cb0; + } + + .lg\:placeholder-blue-800::placeholder { + color: #2c5282; + } + + .lg\:placeholder-blue-900::placeholder { + color: #2a4365; + } + + .lg\:placeholder-indigo-100::placeholder { + color: #ebf4ff; + } + + .lg\:placeholder-indigo-200::placeholder { + color: #c3dafe; + } + + .lg\:placeholder-indigo-300::placeholder { + color: #a3bffa; + } + + .lg\:placeholder-indigo-400::placeholder { + color: #7f9cf5; + } + + .lg\:placeholder-indigo-500::placeholder { + color: #667eea; + } + + .lg\:placeholder-indigo-600::placeholder { + color: #5a67d8; + } + + .lg\:placeholder-indigo-700::placeholder { + color: #4c51bf; + } + + .lg\:placeholder-indigo-800::placeholder { + color: #434190; + } + + .lg\:placeholder-indigo-900::placeholder { + color: #3c366b; + } + + .lg\:placeholder-purple-100::placeholder { + color: #faf5ff; + } + + .lg\:placeholder-purple-200::placeholder { + color: #e9d8fd; + } + + .lg\:placeholder-purple-300::placeholder { + color: #d6bcfa; + } + + .lg\:placeholder-purple-400::placeholder { + color: #b794f4; + } + + .lg\:placeholder-purple-500::placeholder { + color: #9f7aea; + } + + .lg\:placeholder-purple-600::placeholder { + color: #805ad5; + } + + .lg\:placeholder-purple-700::placeholder { + color: #6b46c1; + } + + .lg\:placeholder-purple-800::placeholder { + color: #553c9a; + } + + .lg\:placeholder-purple-900::placeholder { + color: #44337a; + } + + .lg\:placeholder-pink-100::placeholder { + color: #fff5f7; + } + + .lg\:placeholder-pink-200::placeholder { + color: #fed7e2; + } + + .lg\:placeholder-pink-300::placeholder { + color: #fbb6ce; + } + + .lg\:placeholder-pink-400::placeholder { + color: #f687b3; + } + + .lg\:placeholder-pink-500::placeholder { + color: #ed64a6; + } + + .lg\:placeholder-pink-600::placeholder { + color: #d53f8c; + } + + .lg\:placeholder-pink-700::placeholder { + color: #b83280; + } + + .lg\:placeholder-pink-800::placeholder { + color: #97266d; + } + + .lg\:placeholder-pink-900::placeholder { + color: #702459; + } + + .lg\:focus\:placeholder-transparent:focus::placeholder { + color: transparent; + } + + .lg\:focus\:placeholder-black:focus::placeholder { + color: #000; + } + + .lg\:focus\:placeholder-white:focus::placeholder { + color: #fff; + } + + .lg\:focus\:placeholder-gray-100:focus::placeholder { + color: #f7fafc; + } + + .lg\:focus\:placeholder-gray-200:focus::placeholder { + color: #edf2f7; + } + + .lg\:focus\:placeholder-gray-300:focus::placeholder { + color: #e2e8f0; + } + + .lg\:focus\:placeholder-gray-400:focus::placeholder { + color: #cbd5e0; + } + + .lg\:focus\:placeholder-gray-500:focus::placeholder { + color: #a0aec0; + } + + .lg\:focus\:placeholder-gray-600:focus::placeholder { + color: #718096; + } + + .lg\:focus\:placeholder-gray-700:focus::placeholder { + color: #4a5568; + } + + .lg\:focus\:placeholder-gray-800:focus::placeholder { + color: #2d3748; + } + + .lg\:focus\:placeholder-gray-900:focus::placeholder { + color: #1a202c; + } + + .lg\:focus\:placeholder-red-100:focus::placeholder { + color: #fff5f5; + } + + .lg\:focus\:placeholder-red-200:focus::placeholder { + color: #fed7d7; + } + + .lg\:focus\:placeholder-red-300:focus::placeholder { + color: #feb2b2; + } + + .lg\:focus\:placeholder-red-400:focus::placeholder { + color: #fc8181; + } + + .lg\:focus\:placeholder-red-500:focus::placeholder { + color: #f56565; + } + + .lg\:focus\:placeholder-red-600:focus::placeholder { + color: #e53e3e; + } + + .lg\:focus\:placeholder-red-700:focus::placeholder { + color: #c53030; + } + + .lg\:focus\:placeholder-red-800:focus::placeholder { + color: #9b2c2c; + } + + .lg\:focus\:placeholder-red-900:focus::placeholder { + color: #742a2a; + } + + .lg\:focus\:placeholder-orange-100:focus::placeholder { + color: #fffaf0; + } + + .lg\:focus\:placeholder-orange-200:focus::placeholder { + color: #feebc8; + } + + .lg\:focus\:placeholder-orange-300:focus::placeholder { + color: #fbd38d; + } + + .lg\:focus\:placeholder-orange-400:focus::placeholder { + color: #f6ad55; + } + + .lg\:focus\:placeholder-orange-500:focus::placeholder { + color: #ed8936; + } + + .lg\:focus\:placeholder-orange-600:focus::placeholder { + color: #dd6b20; + } + + .lg\:focus\:placeholder-orange-700:focus::placeholder { + color: #c05621; + } + + .lg\:focus\:placeholder-orange-800:focus::placeholder { + color: #9c4221; + } + + .lg\:focus\:placeholder-orange-900:focus::placeholder { + color: #7b341e; + } + + .lg\:focus\:placeholder-yellow-100:focus::placeholder { + color: #fffff0; + } + + .lg\:focus\:placeholder-yellow-200:focus::placeholder { + color: #fefcbf; + } + + .lg\:focus\:placeholder-yellow-300:focus::placeholder { + color: #faf089; + } + + .lg\:focus\:placeholder-yellow-400:focus::placeholder { + color: #f6e05e; + } + + .lg\:focus\:placeholder-yellow-500:focus::placeholder { + color: #ecc94b; + } + + .lg\:focus\:placeholder-yellow-600:focus::placeholder { + color: #d69e2e; + } + + .lg\:focus\:placeholder-yellow-700:focus::placeholder { + color: #b7791f; + } + + .lg\:focus\:placeholder-yellow-800:focus::placeholder { + color: #975a16; + } + + .lg\:focus\:placeholder-yellow-900:focus::placeholder { + color: #744210; + } + + .lg\:focus\:placeholder-green-100:focus::placeholder { + color: #f0fff4; + } + + .lg\:focus\:placeholder-green-200:focus::placeholder { + color: #c6f6d5; + } + + .lg\:focus\:placeholder-green-300:focus::placeholder { + color: #9ae6b4; + } + + .lg\:focus\:placeholder-green-400:focus::placeholder { + color: #68d391; + } + + .lg\:focus\:placeholder-green-500:focus::placeholder { + color: #48bb78; + } + + .lg\:focus\:placeholder-green-600:focus::placeholder { + color: #38a169; + } + + .lg\:focus\:placeholder-green-700:focus::placeholder { + color: #2f855a; + } + + .lg\:focus\:placeholder-green-800:focus::placeholder { + color: #276749; + } + + .lg\:focus\:placeholder-green-900:focus::placeholder { + color: #22543d; + } + + .lg\:focus\:placeholder-teal-100:focus::placeholder { + color: #e6fffa; + } + + .lg\:focus\:placeholder-teal-200:focus::placeholder { + color: #b2f5ea; + } + + .lg\:focus\:placeholder-teal-300:focus::placeholder { + color: #81e6d9; + } + + .lg\:focus\:placeholder-teal-400:focus::placeholder { + color: #4fd1c5; + } + + .lg\:focus\:placeholder-teal-500:focus::placeholder { + color: #38b2ac; + } + + .lg\:focus\:placeholder-teal-600:focus::placeholder { + color: #319795; + } + + .lg\:focus\:placeholder-teal-700:focus::placeholder { + color: #2c7a7b; + } + + .lg\:focus\:placeholder-teal-800:focus::placeholder { + color: #285e61; + } + + .lg\:focus\:placeholder-teal-900:focus::placeholder { + color: #234e52; + } + + .lg\:focus\:placeholder-blue-100:focus::placeholder { + color: #ebf8ff; + } + + .lg\:focus\:placeholder-blue-200:focus::placeholder { + color: #bee3f8; + } + + .lg\:focus\:placeholder-blue-300:focus::placeholder { + color: #90cdf4; + } + + .lg\:focus\:placeholder-blue-400:focus::placeholder { + color: #63b3ed; + } + + .lg\:focus\:placeholder-blue-500:focus::placeholder { + color: #4299e1; + } + + .lg\:focus\:placeholder-blue-600:focus::placeholder { + color: #3182ce; + } + + .lg\:focus\:placeholder-blue-700:focus::placeholder { + color: #2b6cb0; + } + + .lg\:focus\:placeholder-blue-800:focus::placeholder { + color: #2c5282; + } + + .lg\:focus\:placeholder-blue-900:focus::placeholder { + color: #2a4365; + } + + .lg\:focus\:placeholder-indigo-100:focus::placeholder { + color: #ebf4ff; + } + + .lg\:focus\:placeholder-indigo-200:focus::placeholder { + color: #c3dafe; + } + + .lg\:focus\:placeholder-indigo-300:focus::placeholder { + color: #a3bffa; + } + + .lg\:focus\:placeholder-indigo-400:focus::placeholder { + color: #7f9cf5; + } + + .lg\:focus\:placeholder-indigo-500:focus::placeholder { + color: #667eea; + } + + .lg\:focus\:placeholder-indigo-600:focus::placeholder { + color: #5a67d8; + } + + .lg\:focus\:placeholder-indigo-700:focus::placeholder { + color: #4c51bf; + } + + .lg\:focus\:placeholder-indigo-800:focus::placeholder { + color: #434190; + } + + .lg\:focus\:placeholder-indigo-900:focus::placeholder { + color: #3c366b; + } + + .lg\:focus\:placeholder-purple-100:focus::placeholder { + color: #faf5ff; + } + + .lg\:focus\:placeholder-purple-200:focus::placeholder { + color: #e9d8fd; + } + + .lg\:focus\:placeholder-purple-300:focus::placeholder { + color: #d6bcfa; + } + + .lg\:focus\:placeholder-purple-400:focus::placeholder { + color: #b794f4; + } + + .lg\:focus\:placeholder-purple-500:focus::placeholder { + color: #9f7aea; + } + + .lg\:focus\:placeholder-purple-600:focus::placeholder { + color: #805ad5; + } + + .lg\:focus\:placeholder-purple-700:focus::placeholder { + color: #6b46c1; + } + + .lg\:focus\:placeholder-purple-800:focus::placeholder { + color: #553c9a; + } + + .lg\:focus\:placeholder-purple-900:focus::placeholder { + color: #44337a; + } + + .lg\:focus\:placeholder-pink-100:focus::placeholder { + color: #fff5f7; + } + + .lg\:focus\:placeholder-pink-200:focus::placeholder { + color: #fed7e2; + } + + .lg\:focus\:placeholder-pink-300:focus::placeholder { + color: #fbb6ce; + } + + .lg\:focus\:placeholder-pink-400:focus::placeholder { + color: #f687b3; + } + + .lg\:focus\:placeholder-pink-500:focus::placeholder { + color: #ed64a6; + } + + .lg\:focus\:placeholder-pink-600:focus::placeholder { + color: #d53f8c; + } + + .lg\:focus\:placeholder-pink-700:focus::placeholder { + color: #b83280; + } + + .lg\:focus\:placeholder-pink-800:focus::placeholder { + color: #97266d; + } + + .lg\:focus\:placeholder-pink-900:focus::placeholder { + color: #702459; + } + + .lg\:pointer-events-none { + pointer-events: none; + } + + .lg\:pointer-events-auto { + pointer-events: auto; + } + + .lg\:static { + position: static; + } + + .lg\:fixed { + position: fixed; + } + + .lg\:absolute { + position: absolute; + } + + .lg\:relative { + position: relative; + } + + .lg\:sticky { + position: -webkit-sticky; + position: sticky; + } + + .lg\:inset-0 { + top: 0; + right: 0; + bottom: 0; + left: 0; + } + + .lg\:inset-auto { + top: auto; + right: auto; + bottom: auto; + left: auto; + } + + .lg\:inset-y-0 { + top: 0; + bottom: 0; + } + + .lg\:inset-x-0 { + right: 0; + left: 0; + } + + .lg\:inset-y-auto { + top: auto; + bottom: auto; + } + + .lg\:inset-x-auto { + right: auto; + left: auto; + } + + .lg\:top-0 { + top: 0; + } + + .lg\:right-0 { + right: 0; + } + + .lg\:bottom-0 { + bottom: 0; + } + + .lg\:left-0 { + left: 0; + } + + .lg\:top-auto { + top: auto; + } + + .lg\:right-auto { + right: auto; + } + + .lg\:bottom-auto { + bottom: auto; + } + + .lg\:left-auto { + left: auto; + } + + .lg\:resize-none { + resize: none; + } + + .lg\:resize-y { + resize: vertical; + } + + .lg\:resize-x { + resize: horizontal; + } + + .lg\:resize { + resize: both; + } + + .lg\:shadow-xs { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); + } + + .lg\:shadow-sm { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + } + + .lg\:shadow { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + } + + .lg\:shadow-md { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + } + + .lg\:shadow-lg { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + } + + .lg\:shadow-xl { + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + } + + .lg\:shadow-2xl { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + } + + .lg\:shadow-inner { + box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); + } + + .lg\:shadow-outline { + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); + } + + .lg\:shadow-none { + box-shadow: none; + } + + .lg\:hover\:shadow-xs:hover { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); + } + + .lg\:hover\:shadow-sm:hover { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + } + + .lg\:hover\:shadow:hover { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + } + + .lg\:hover\:shadow-md:hover { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + } + + .lg\:hover\:shadow-lg:hover { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + } + + .lg\:hover\:shadow-xl:hover { + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + } + + .lg\:hover\:shadow-2xl:hover { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + } + + .lg\:hover\:shadow-inner:hover { + box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); + } + + .lg\:hover\:shadow-outline:hover { + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); + } + + .lg\:hover\:shadow-none:hover { + box-shadow: none; + } + + .lg\:focus\:shadow-xs:focus { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); + } + + .lg\:focus\:shadow-sm:focus { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + } + + .lg\:focus\:shadow:focus { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + } + + .lg\:focus\:shadow-md:focus { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + } + + .lg\:focus\:shadow-lg:focus { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + } + + .lg\:focus\:shadow-xl:focus { + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + } + + .lg\:focus\:shadow-2xl:focus { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + } + + .lg\:focus\:shadow-inner:focus { + box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); + } + + .lg\:focus\:shadow-outline:focus { + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); + } + + .lg\:focus\:shadow-none:focus { + box-shadow: none; + } + + .lg\:fill-current { + fill: currentColor; + } + + .lg\:stroke-current { + stroke: currentColor; + } + + .lg\:stroke-0 { + stroke-width: 0; + } + + .lg\:stroke-1 { + stroke-width: 1; + } + + .lg\:stroke-2 { + stroke-width: 2; + } + + .lg\:table-auto { + table-layout: auto; + } + + .lg\:table-fixed { + table-layout: fixed; + } + + .lg\:text-left { + text-align: left; + } + + .lg\:text-center { + text-align: center; + } + + .lg\:text-right { + text-align: right; + } + + .lg\:text-justify { + text-align: justify; + } + + .lg\:text-transparent { + color: transparent; + } + + .lg\:text-black { + color: #000; + } + + .lg\:text-white { + color: #fff; + } + + .lg\:text-gray-100 { + color: #f7fafc; + } + + .lg\:text-gray-200 { + color: #edf2f7; + } + + .lg\:text-gray-300 { + color: #e2e8f0; + } + + .lg\:text-gray-400 { + color: #cbd5e0; + } + + .lg\:text-gray-500 { + color: #a0aec0; + } + + .lg\:text-gray-600 { + color: #718096; + } + + .lg\:text-gray-700 { + color: #4a5568; + } + + .lg\:text-gray-800 { + color: #2d3748; + } + + .lg\:text-gray-900 { + color: #1a202c; + } + + .lg\:text-red-100 { + color: #fff5f5; + } + + .lg\:text-red-200 { + color: #fed7d7; + } + + .lg\:text-red-300 { + color: #feb2b2; + } + + .lg\:text-red-400 { + color: #fc8181; + } + + .lg\:text-red-500 { + color: #f56565; + } + + .lg\:text-red-600 { + color: #e53e3e; + } + + .lg\:text-red-700 { + color: #c53030; + } + + .lg\:text-red-800 { + color: #9b2c2c; + } + + .lg\:text-red-900 { + color: #742a2a; + } + + .lg\:text-orange-100 { + color: #fffaf0; + } + + .lg\:text-orange-200 { + color: #feebc8; + } + + .lg\:text-orange-300 { + color: #fbd38d; + } + + .lg\:text-orange-400 { + color: #f6ad55; + } + + .lg\:text-orange-500 { + color: #ed8936; + } + + .lg\:text-orange-600 { + color: #dd6b20; + } + + .lg\:text-orange-700 { + color: #c05621; + } + + .lg\:text-orange-800 { + color: #9c4221; + } + + .lg\:text-orange-900 { + color: #7b341e; + } + + .lg\:text-yellow-100 { + color: #fffff0; + } + + .lg\:text-yellow-200 { + color: #fefcbf; + } + + .lg\:text-yellow-300 { + color: #faf089; + } + + .lg\:text-yellow-400 { + color: #f6e05e; + } + + .lg\:text-yellow-500 { + color: #ecc94b; + } + + .lg\:text-yellow-600 { + color: #d69e2e; + } + + .lg\:text-yellow-700 { + color: #b7791f; + } + + .lg\:text-yellow-800 { + color: #975a16; + } + + .lg\:text-yellow-900 { + color: #744210; + } + + .lg\:text-green-100 { + color: #f0fff4; + } + + .lg\:text-green-200 { + color: #c6f6d5; + } + + .lg\:text-green-300 { + color: #9ae6b4; + } + + .lg\:text-green-400 { + color: #68d391; + } + + .lg\:text-green-500 { + color: #48bb78; + } + + .lg\:text-green-600 { + color: #38a169; + } + + .lg\:text-green-700 { + color: #2f855a; + } + + .lg\:text-green-800 { + color: #276749; + } + + .lg\:text-green-900 { + color: #22543d; + } + + .lg\:text-teal-100 { + color: #e6fffa; + } + + .lg\:text-teal-200 { + color: #b2f5ea; + } + + .lg\:text-teal-300 { + color: #81e6d9; + } + + .lg\:text-teal-400 { + color: #4fd1c5; + } + + .lg\:text-teal-500 { + color: #38b2ac; + } + + .lg\:text-teal-600 { + color: #319795; + } + + .lg\:text-teal-700 { + color: #2c7a7b; + } + + .lg\:text-teal-800 { + color: #285e61; + } + + .lg\:text-teal-900 { + color: #234e52; + } + + .lg\:text-blue-100 { + color: #ebf8ff; + } + + .lg\:text-blue-200 { + color: #bee3f8; + } + + .lg\:text-blue-300 { + color: #90cdf4; + } + + .lg\:text-blue-400 { + color: #63b3ed; + } + + .lg\:text-blue-500 { + color: #4299e1; + } + + .lg\:text-blue-600 { + color: #3182ce; + } + + .lg\:text-blue-700 { + color: #2b6cb0; + } + + .lg\:text-blue-800 { + color: #2c5282; + } + + .lg\:text-blue-900 { + color: #2a4365; + } + + .lg\:text-indigo-100 { + color: #ebf4ff; + } + + .lg\:text-indigo-200 { + color: #c3dafe; + } + + .lg\:text-indigo-300 { + color: #a3bffa; + } + + .lg\:text-indigo-400 { + color: #7f9cf5; + } + + .lg\:text-indigo-500 { + color: #667eea; + } + + .lg\:text-indigo-600 { + color: #5a67d8; + } + + .lg\:text-indigo-700 { + color: #4c51bf; + } + + .lg\:text-indigo-800 { + color: #434190; + } + + .lg\:text-indigo-900 { + color: #3c366b; + } + + .lg\:text-purple-100 { + color: #faf5ff; + } + + .lg\:text-purple-200 { + color: #e9d8fd; + } + + .lg\:text-purple-300 { + color: #d6bcfa; + } + + .lg\:text-purple-400 { + color: #b794f4; + } + + .lg\:text-purple-500 { + color: #9f7aea; + } + + .lg\:text-purple-600 { + color: #805ad5; + } + + .lg\:text-purple-700 { + color: #6b46c1; + } + + .lg\:text-purple-800 { + color: #553c9a; + } + + .lg\:text-purple-900 { + color: #44337a; + } + + .lg\:text-pink-100 { + color: #fff5f7; + } + + .lg\:text-pink-200 { + color: #fed7e2; + } + + .lg\:text-pink-300 { + color: #fbb6ce; + } + + .lg\:text-pink-400 { + color: #f687b3; + } + + .lg\:text-pink-500 { + color: #ed64a6; + } + + .lg\:text-pink-600 { + color: #d53f8c; + } + + .lg\:text-pink-700 { + color: #b83280; + } + + .lg\:text-pink-800 { + color: #97266d; + } + + .lg\:text-pink-900 { + color: #702459; + } + + .lg\:hover\:text-transparent:hover { + color: transparent; + } + + .lg\:hover\:text-black:hover { + color: #000; + } + + .lg\:hover\:text-white:hover { + color: #fff; + } + + .lg\:hover\:text-gray-100:hover { + color: #f7fafc; + } + + .lg\:hover\:text-gray-200:hover { + color: #edf2f7; + } + + .lg\:hover\:text-gray-300:hover { + color: #e2e8f0; + } + + .lg\:hover\:text-gray-400:hover { + color: #cbd5e0; + } + + .lg\:hover\:text-gray-500:hover { + color: #a0aec0; + } + + .lg\:hover\:text-gray-600:hover { + color: #718096; + } + + .lg\:hover\:text-gray-700:hover { + color: #4a5568; + } + + .lg\:hover\:text-gray-800:hover { + color: #2d3748; + } + + .lg\:hover\:text-gray-900:hover { + color: #1a202c; + } + + .lg\:hover\:text-red-100:hover { + color: #fff5f5; + } + + .lg\:hover\:text-red-200:hover { + color: #fed7d7; + } + + .lg\:hover\:text-red-300:hover { + color: #feb2b2; + } + + .lg\:hover\:text-red-400:hover { + color: #fc8181; + } + + .lg\:hover\:text-red-500:hover { + color: #f56565; + } + + .lg\:hover\:text-red-600:hover { + color: #e53e3e; + } + + .lg\:hover\:text-red-700:hover { + color: #c53030; + } + + .lg\:hover\:text-red-800:hover { + color: #9b2c2c; + } + + .lg\:hover\:text-red-900:hover { + color: #742a2a; + } + + .lg\:hover\:text-orange-100:hover { + color: #fffaf0; + } + + .lg\:hover\:text-orange-200:hover { + color: #feebc8; + } + + .lg\:hover\:text-orange-300:hover { + color: #fbd38d; + } + + .lg\:hover\:text-orange-400:hover { + color: #f6ad55; + } + + .lg\:hover\:text-orange-500:hover { + color: #ed8936; + } + + .lg\:hover\:text-orange-600:hover { + color: #dd6b20; + } + + .lg\:hover\:text-orange-700:hover { + color: #c05621; + } + + .lg\:hover\:text-orange-800:hover { + color: #9c4221; + } + + .lg\:hover\:text-orange-900:hover { + color: #7b341e; + } + + .lg\:hover\:text-yellow-100:hover { + color: #fffff0; + } + + .lg\:hover\:text-yellow-200:hover { + color: #fefcbf; + } + + .lg\:hover\:text-yellow-300:hover { + color: #faf089; + } + + .lg\:hover\:text-yellow-400:hover { + color: #f6e05e; + } + + .lg\:hover\:text-yellow-500:hover { + color: #ecc94b; + } + + .lg\:hover\:text-yellow-600:hover { + color: #d69e2e; + } + + .lg\:hover\:text-yellow-700:hover { + color: #b7791f; + } + + .lg\:hover\:text-yellow-800:hover { + color: #975a16; + } + + .lg\:hover\:text-yellow-900:hover { + color: #744210; + } + + .lg\:hover\:text-green-100:hover { + color: #f0fff4; + } + + .lg\:hover\:text-green-200:hover { + color: #c6f6d5; + } + + .lg\:hover\:text-green-300:hover { + color: #9ae6b4; + } + + .lg\:hover\:text-green-400:hover { + color: #68d391; + } + + .lg\:hover\:text-green-500:hover { + color: #48bb78; + } + + .lg\:hover\:text-green-600:hover { + color: #38a169; + } + + .lg\:hover\:text-green-700:hover { + color: #2f855a; + } + + .lg\:hover\:text-green-800:hover { + color: #276749; + } + + .lg\:hover\:text-green-900:hover { + color: #22543d; + } + + .lg\:hover\:text-teal-100:hover { + color: #e6fffa; + } + + .lg\:hover\:text-teal-200:hover { + color: #b2f5ea; + } + + .lg\:hover\:text-teal-300:hover { + color: #81e6d9; + } + + .lg\:hover\:text-teal-400:hover { + color: #4fd1c5; + } + + .lg\:hover\:text-teal-500:hover { + color: #38b2ac; + } + + .lg\:hover\:text-teal-600:hover { + color: #319795; + } + + .lg\:hover\:text-teal-700:hover { + color: #2c7a7b; + } + + .lg\:hover\:text-teal-800:hover { + color: #285e61; + } + + .lg\:hover\:text-teal-900:hover { + color: #234e52; + } + + .lg\:hover\:text-blue-100:hover { + color: #ebf8ff; + } + + .lg\:hover\:text-blue-200:hover { + color: #bee3f8; + } + + .lg\:hover\:text-blue-300:hover { + color: #90cdf4; + } + + .lg\:hover\:text-blue-400:hover { + color: #63b3ed; + } + + .lg\:hover\:text-blue-500:hover { + color: #4299e1; + } + + .lg\:hover\:text-blue-600:hover { + color: #3182ce; + } + + .lg\:hover\:text-blue-700:hover { + color: #2b6cb0; + } + + .lg\:hover\:text-blue-800:hover { + color: #2c5282; + } + + .lg\:hover\:text-blue-900:hover { + color: #2a4365; + } + + .lg\:hover\:text-indigo-100:hover { + color: #ebf4ff; + } + + .lg\:hover\:text-indigo-200:hover { + color: #c3dafe; + } + + .lg\:hover\:text-indigo-300:hover { + color: #a3bffa; + } + + .lg\:hover\:text-indigo-400:hover { + color: #7f9cf5; + } + + .lg\:hover\:text-indigo-500:hover { + color: #667eea; + } + + .lg\:hover\:text-indigo-600:hover { + color: #5a67d8; + } + + .lg\:hover\:text-indigo-700:hover { + color: #4c51bf; + } + + .lg\:hover\:text-indigo-800:hover { + color: #434190; + } + + .lg\:hover\:text-indigo-900:hover { + color: #3c366b; + } + + .lg\:hover\:text-purple-100:hover { + color: #faf5ff; + } + + .lg\:hover\:text-purple-200:hover { + color: #e9d8fd; + } + + .lg\:hover\:text-purple-300:hover { + color: #d6bcfa; + } + + .lg\:hover\:text-purple-400:hover { + color: #b794f4; + } + + .lg\:hover\:text-purple-500:hover { + color: #9f7aea; + } + + .lg\:hover\:text-purple-600:hover { + color: #805ad5; + } + + .lg\:hover\:text-purple-700:hover { + color: #6b46c1; + } + + .lg\:hover\:text-purple-800:hover { + color: #553c9a; + } + + .lg\:hover\:text-purple-900:hover { + color: #44337a; + } + + .lg\:hover\:text-pink-100:hover { + color: #fff5f7; + } + + .lg\:hover\:text-pink-200:hover { + color: #fed7e2; + } + + .lg\:hover\:text-pink-300:hover { + color: #fbb6ce; + } + + .lg\:hover\:text-pink-400:hover { + color: #f687b3; + } + + .lg\:hover\:text-pink-500:hover { + color: #ed64a6; + } + + .lg\:hover\:text-pink-600:hover { + color: #d53f8c; + } + + .lg\:hover\:text-pink-700:hover { + color: #b83280; + } + + .lg\:hover\:text-pink-800:hover { + color: #97266d; + } + + .lg\:hover\:text-pink-900:hover { + color: #702459; + } + + .lg\:focus\:text-transparent:focus { + color: transparent; + } + + .lg\:focus\:text-black:focus { + color: #000; + } + + .lg\:focus\:text-white:focus { + color: #fff; + } + + .lg\:focus\:text-gray-100:focus { + color: #f7fafc; + } + + .lg\:focus\:text-gray-200:focus { + color: #edf2f7; + } + + .lg\:focus\:text-gray-300:focus { + color: #e2e8f0; + } + + .lg\:focus\:text-gray-400:focus { + color: #cbd5e0; + } + + .lg\:focus\:text-gray-500:focus { + color: #a0aec0; + } + + .lg\:focus\:text-gray-600:focus { + color: #718096; + } + + .lg\:focus\:text-gray-700:focus { + color: #4a5568; + } + + .lg\:focus\:text-gray-800:focus { + color: #2d3748; + } + + .lg\:focus\:text-gray-900:focus { + color: #1a202c; + } + + .lg\:focus\:text-red-100:focus { + color: #fff5f5; + } + + .lg\:focus\:text-red-200:focus { + color: #fed7d7; + } + + .lg\:focus\:text-red-300:focus { + color: #feb2b2; + } + + .lg\:focus\:text-red-400:focus { + color: #fc8181; + } + + .lg\:focus\:text-red-500:focus { + color: #f56565; + } + + .lg\:focus\:text-red-600:focus { + color: #e53e3e; + } + + .lg\:focus\:text-red-700:focus { + color: #c53030; + } + + .lg\:focus\:text-red-800:focus { + color: #9b2c2c; + } + + .lg\:focus\:text-red-900:focus { + color: #742a2a; + } + + .lg\:focus\:text-orange-100:focus { + color: #fffaf0; + } + + .lg\:focus\:text-orange-200:focus { + color: #feebc8; + } + + .lg\:focus\:text-orange-300:focus { + color: #fbd38d; + } + + .lg\:focus\:text-orange-400:focus { + color: #f6ad55; + } + + .lg\:focus\:text-orange-500:focus { + color: #ed8936; + } + + .lg\:focus\:text-orange-600:focus { + color: #dd6b20; + } + + .lg\:focus\:text-orange-700:focus { + color: #c05621; + } + + .lg\:focus\:text-orange-800:focus { + color: #9c4221; + } + + .lg\:focus\:text-orange-900:focus { + color: #7b341e; + } + + .lg\:focus\:text-yellow-100:focus { + color: #fffff0; + } + + .lg\:focus\:text-yellow-200:focus { + color: #fefcbf; + } + + .lg\:focus\:text-yellow-300:focus { + color: #faf089; + } + + .lg\:focus\:text-yellow-400:focus { + color: #f6e05e; + } + + .lg\:focus\:text-yellow-500:focus { + color: #ecc94b; + } + + .lg\:focus\:text-yellow-600:focus { + color: #d69e2e; + } + + .lg\:focus\:text-yellow-700:focus { + color: #b7791f; + } + + .lg\:focus\:text-yellow-800:focus { + color: #975a16; + } + + .lg\:focus\:text-yellow-900:focus { + color: #744210; + } + + .lg\:focus\:text-green-100:focus { + color: #f0fff4; + } + + .lg\:focus\:text-green-200:focus { + color: #c6f6d5; + } + + .lg\:focus\:text-green-300:focus { + color: #9ae6b4; + } + + .lg\:focus\:text-green-400:focus { + color: #68d391; + } + + .lg\:focus\:text-green-500:focus { + color: #48bb78; + } + + .lg\:focus\:text-green-600:focus { + color: #38a169; + } + + .lg\:focus\:text-green-700:focus { + color: #2f855a; + } + + .lg\:focus\:text-green-800:focus { + color: #276749; + } + + .lg\:focus\:text-green-900:focus { + color: #22543d; + } + + .lg\:focus\:text-teal-100:focus { + color: #e6fffa; + } + + .lg\:focus\:text-teal-200:focus { + color: #b2f5ea; + } + + .lg\:focus\:text-teal-300:focus { + color: #81e6d9; + } + + .lg\:focus\:text-teal-400:focus { + color: #4fd1c5; + } + + .lg\:focus\:text-teal-500:focus { + color: #38b2ac; + } + + .lg\:focus\:text-teal-600:focus { + color: #319795; + } + + .lg\:focus\:text-teal-700:focus { + color: #2c7a7b; + } + + .lg\:focus\:text-teal-800:focus { + color: #285e61; + } + + .lg\:focus\:text-teal-900:focus { + color: #234e52; + } + + .lg\:focus\:text-blue-100:focus { + color: #ebf8ff; + } + + .lg\:focus\:text-blue-200:focus { + color: #bee3f8; + } + + .lg\:focus\:text-blue-300:focus { + color: #90cdf4; + } + + .lg\:focus\:text-blue-400:focus { + color: #63b3ed; + } + + .lg\:focus\:text-blue-500:focus { + color: #4299e1; + } + + .lg\:focus\:text-blue-600:focus { + color: #3182ce; + } + + .lg\:focus\:text-blue-700:focus { + color: #2b6cb0; + } + + .lg\:focus\:text-blue-800:focus { + color: #2c5282; + } + + .lg\:focus\:text-blue-900:focus { + color: #2a4365; + } + + .lg\:focus\:text-indigo-100:focus { + color: #ebf4ff; + } + + .lg\:focus\:text-indigo-200:focus { + color: #c3dafe; + } + + .lg\:focus\:text-indigo-300:focus { + color: #a3bffa; + } + + .lg\:focus\:text-indigo-400:focus { + color: #7f9cf5; + } + + .lg\:focus\:text-indigo-500:focus { + color: #667eea; + } + + .lg\:focus\:text-indigo-600:focus { + color: #5a67d8; + } + + .lg\:focus\:text-indigo-700:focus { + color: #4c51bf; + } + + .lg\:focus\:text-indigo-800:focus { + color: #434190; + } + + .lg\:focus\:text-indigo-900:focus { + color: #3c366b; + } + + .lg\:focus\:text-purple-100:focus { + color: #faf5ff; + } + + .lg\:focus\:text-purple-200:focus { + color: #e9d8fd; + } + + .lg\:focus\:text-purple-300:focus { + color: #d6bcfa; + } + + .lg\:focus\:text-purple-400:focus { + color: #b794f4; + } + + .lg\:focus\:text-purple-500:focus { + color: #9f7aea; + } + + .lg\:focus\:text-purple-600:focus { + color: #805ad5; + } + + .lg\:focus\:text-purple-700:focus { + color: #6b46c1; + } + + .lg\:focus\:text-purple-800:focus { + color: #553c9a; + } + + .lg\:focus\:text-purple-900:focus { + color: #44337a; + } + + .lg\:focus\:text-pink-100:focus { + color: #fff5f7; + } + + .lg\:focus\:text-pink-200:focus { + color: #fed7e2; + } + + .lg\:focus\:text-pink-300:focus { + color: #fbb6ce; + } + + .lg\:focus\:text-pink-400:focus { + color: #f687b3; + } + + .lg\:focus\:text-pink-500:focus { + color: #ed64a6; + } + + .lg\:focus\:text-pink-600:focus { + color: #d53f8c; + } + + .lg\:focus\:text-pink-700:focus { + color: #b83280; + } + + .lg\:focus\:text-pink-800:focus { + color: #97266d; + } + + .lg\:focus\:text-pink-900:focus { + color: #702459; + } + + .lg\:text-xs { + font-size: 0.75rem; + } + + .lg\:text-sm { + font-size: 0.875rem; + } + + .lg\:text-base { + font-size: 1rem; + } + + .lg\:text-lg { + font-size: 1.125rem; + } + + .lg\:text-xl { + font-size: 1.25rem; + } + + .lg\:text-2xl { + font-size: 1.5rem; + } + + .lg\:text-3xl { + font-size: 1.875rem; + } + + .lg\:text-4xl { + font-size: 2.25rem; + } + + .lg\:text-5xl { + font-size: 3rem; + } + + .lg\:text-6xl { + font-size: 4rem; + } + + .lg\:italic { + font-style: italic; + } + + .lg\:not-italic { + font-style: normal; + } + + .lg\:uppercase { + text-transform: uppercase; + } + + .lg\:lowercase { + text-transform: lowercase; + } + + .lg\:capitalize { + text-transform: capitalize; + } + + .lg\:normal-case { + text-transform: none; + } + + .lg\:underline { + text-decoration: underline; + } + + .lg\:line-through { + text-decoration: line-through; + } + + .lg\:no-underline { + text-decoration: none; + } + + .lg\:hover\:underline:hover { + text-decoration: underline; + } + + .lg\:hover\:line-through:hover { + text-decoration: line-through; + } + + .lg\:hover\:no-underline:hover { + text-decoration: none; + } + + .lg\:focus\:underline:focus { + text-decoration: underline; + } + + .lg\:focus\:line-through:focus { + text-decoration: line-through; + } + + .lg\:focus\:no-underline:focus { + text-decoration: none; + } + + .lg\:antialiased { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + + .lg\:subpixel-antialiased { + -webkit-font-smoothing: auto; + -moz-osx-font-smoothing: auto; + } + + .lg\:tracking-tighter { + letter-spacing: -0.05em; + } + + .lg\:tracking-tight { + letter-spacing: -0.025em; + } + + .lg\:tracking-normal { + letter-spacing: 0; + } + + .lg\:tracking-wide { + letter-spacing: 0.025em; + } + + .lg\:tracking-wider { + letter-spacing: 0.05em; + } + + .lg\:tracking-widest { + letter-spacing: 0.1em; + } + + .lg\:select-none { + -webkit-user-select: none; + user-select: none; + } + + .lg\:select-text { + -webkit-user-select: text; + user-select: text; + } + + .lg\:select-all { + -webkit-user-select: all; + user-select: all; + } + + .lg\:select-auto { + -webkit-user-select: auto; + user-select: auto; + } + + .lg\:align-baseline { + vertical-align: baseline; + } + + .lg\:align-top { + vertical-align: top; + } + + .lg\:align-middle { + vertical-align: middle; + } + + .lg\:align-bottom { + vertical-align: bottom; + } + + .lg\:align-text-top { + vertical-align: text-top; + } + + .lg\:align-text-bottom { + vertical-align: text-bottom; + } + + .lg\:visible { + visibility: visible; + } + + .lg\:invisible { + visibility: hidden; + } + + .lg\:whitespace-normal { + white-space: normal; + } + + .lg\:whitespace-no-wrap { + white-space: nowrap; + } + + .lg\:whitespace-pre { + white-space: pre; + } + + .lg\:whitespace-pre-line { + white-space: pre-line; + } + + .lg\:whitespace-pre-wrap { + white-space: pre-wrap; + } + + .lg\:break-normal { + overflow-wrap: normal; + word-break: normal; + } + + .lg\:break-words { + overflow-wrap: break-word; + } + + .lg\:break-all { + word-break: break-all; + } + + .lg\:truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .lg\:w-0 { + width: 0; + } + + .lg\:w-1 { + width: 0.25rem; + } + + .lg\:w-2 { + width: 0.5rem; + } + + .lg\:w-3 { + width: 0.75rem; + } + + .lg\:w-4 { + width: 1rem; + } + + .lg\:w-5 { + width: 1.25rem; + } + + .lg\:w-6 { + width: 1.5rem; + } + + .lg\:w-8 { + width: 2rem; + } + + .lg\:w-10 { + width: 2.5rem; + } + + .lg\:w-12 { + width: 3rem; + } + + .lg\:w-16 { + width: 4rem; + } + + .lg\:w-20 { + width: 5rem; + } + + .lg\:w-24 { + width: 6rem; + } + + .lg\:w-32 { + width: 8rem; + } + + .lg\:w-40 { + width: 10rem; + } + + .lg\:w-48 { + width: 12rem; + } + + .lg\:w-56 { + width: 14rem; + } + + .lg\:w-64 { + width: 16rem; + } + + .lg\:w-auto { + width: auto; + } + + .lg\:w-px { + width: 1px; + } + + .lg\:w-1\/2 { + width: 50%; + } + + .lg\:w-1\/3 { + width: 33.333333%; + } + + .lg\:w-2\/3 { + width: 66.666667%; + } + + .lg\:w-1\/4 { + width: 25%; + } + + .lg\:w-2\/4 { + width: 50%; + } + + .lg\:w-3\/4 { + width: 75%; + } + + .lg\:w-1\/5 { + width: 20%; + } + + .lg\:w-2\/5 { + width: 40%; + } + + .lg\:w-3\/5 { + width: 60%; + } + + .lg\:w-4\/5 { + width: 80%; + } + + .lg\:w-1\/6 { + width: 16.666667%; + } + + .lg\:w-2\/6 { + width: 33.333333%; + } + + .lg\:w-3\/6 { + width: 50%; + } + + .lg\:w-4\/6 { + width: 66.666667%; + } + + .lg\:w-5\/6 { + width: 83.333333%; + } + + .lg\:w-1\/12 { + width: 8.333333%; + } + + .lg\:w-2\/12 { + width: 16.666667%; + } + + .lg\:w-3\/12 { + width: 25%; + } + + .lg\:w-4\/12 { + width: 33.333333%; + } + + .lg\:w-5\/12 { + width: 41.666667%; + } + + .lg\:w-6\/12 { + width: 50%; + } + + .lg\:w-7\/12 { + width: 58.333333%; + } + + .lg\:w-8\/12 { + width: 66.666667%; + } + + .lg\:w-9\/12 { + width: 75%; + } + + .lg\:w-10\/12 { + width: 83.333333%; + } + + .lg\:w-11\/12 { + width: 91.666667%; + } + + .lg\:w-full { + width: 100%; + } + + .lg\:w-screen { + width: 100vw; + } + + .lg\:z-0 { + z-index: 0; + } + + .lg\:z-10 { + z-index: 10; + } + + .lg\:z-20 { + z-index: 20; + } + + .lg\:z-30 { + z-index: 30; + } + + .lg\:z-40 { + z-index: 40; + } + + .lg\:z-50 { + z-index: 50; + } + + .lg\:z-auto { + z-index: auto; + } + + .lg\:gap-0 { + grid-gap: 0; + gap: 0; + } + + .lg\:gap-1 { + grid-gap: 0.25rem; + gap: 0.25rem; + } + + .lg\:gap-2 { + grid-gap: 0.5rem; + gap: 0.5rem; + } + + .lg\:gap-3 { + grid-gap: 0.75rem; + gap: 0.75rem; + } + + .lg\:gap-4 { + grid-gap: 1rem; + gap: 1rem; + } + + .lg\:gap-5 { + grid-gap: 1.25rem; + gap: 1.25rem; + } + + .lg\:gap-6 { + grid-gap: 1.5rem; + gap: 1.5rem; + } + + .lg\:gap-8 { + grid-gap: 2rem; + gap: 2rem; + } + + .lg\:gap-10 { + grid-gap: 2.5rem; + gap: 2.5rem; + } + + .lg\:gap-12 { + grid-gap: 3rem; + gap: 3rem; + } + + .lg\:gap-16 { + grid-gap: 4rem; + gap: 4rem; + } + + .lg\:gap-20 { + grid-gap: 5rem; + gap: 5rem; + } + + .lg\:gap-24 { + grid-gap: 6rem; + gap: 6rem; + } + + .lg\:gap-32 { + grid-gap: 8rem; + gap: 8rem; + } + + .lg\:gap-40 { + grid-gap: 10rem; + gap: 10rem; + } + + .lg\:gap-48 { + grid-gap: 12rem; + gap: 12rem; + } + + .lg\:gap-56 { + grid-gap: 14rem; + gap: 14rem; + } + + .lg\:gap-64 { + grid-gap: 16rem; + gap: 16rem; + } + + .lg\:gap-px { + grid-gap: 1px; + gap: 1px; + } + + .lg\:col-gap-0 { + grid-column-gap: 0; + column-gap: 0; + } + + .lg\:col-gap-1 { + grid-column-gap: 0.25rem; + column-gap: 0.25rem; + } + + .lg\:col-gap-2 { + grid-column-gap: 0.5rem; + column-gap: 0.5rem; + } + + .lg\:col-gap-3 { + grid-column-gap: 0.75rem; + column-gap: 0.75rem; + } + + .lg\:col-gap-4 { + grid-column-gap: 1rem; + column-gap: 1rem; + } + + .lg\:col-gap-5 { + grid-column-gap: 1.25rem; + column-gap: 1.25rem; + } + + .lg\:col-gap-6 { + grid-column-gap: 1.5rem; + column-gap: 1.5rem; + } + + .lg\:col-gap-8 { + grid-column-gap: 2rem; + column-gap: 2rem; + } + + .lg\:col-gap-10 { + grid-column-gap: 2.5rem; + column-gap: 2.5rem; + } + + .lg\:col-gap-12 { + grid-column-gap: 3rem; + column-gap: 3rem; + } + + .lg\:col-gap-16 { + grid-column-gap: 4rem; + column-gap: 4rem; + } + + .lg\:col-gap-20 { + grid-column-gap: 5rem; + column-gap: 5rem; + } + + .lg\:col-gap-24 { + grid-column-gap: 6rem; + column-gap: 6rem; + } + + .lg\:col-gap-32 { + grid-column-gap: 8rem; + column-gap: 8rem; + } + + .lg\:col-gap-40 { + grid-column-gap: 10rem; + column-gap: 10rem; + } + + .lg\:col-gap-48 { + grid-column-gap: 12rem; + column-gap: 12rem; + } + + .lg\:col-gap-56 { + grid-column-gap: 14rem; + column-gap: 14rem; + } + + .lg\:col-gap-64 { + grid-column-gap: 16rem; + column-gap: 16rem; + } + + .lg\:col-gap-px { + grid-column-gap: 1px; + column-gap: 1px; + } + + .lg\:row-gap-0 { + grid-row-gap: 0; + row-gap: 0; + } + + .lg\:row-gap-1 { + grid-row-gap: 0.25rem; + row-gap: 0.25rem; + } + + .lg\:row-gap-2 { + grid-row-gap: 0.5rem; + row-gap: 0.5rem; + } + + .lg\:row-gap-3 { + grid-row-gap: 0.75rem; + row-gap: 0.75rem; + } + + .lg\:row-gap-4 { + grid-row-gap: 1rem; + row-gap: 1rem; + } + + .lg\:row-gap-5 { + grid-row-gap: 1.25rem; + row-gap: 1.25rem; + } + + .lg\:row-gap-6 { + grid-row-gap: 1.5rem; + row-gap: 1.5rem; + } + + .lg\:row-gap-8 { + grid-row-gap: 2rem; + row-gap: 2rem; + } + + .lg\:row-gap-10 { + grid-row-gap: 2.5rem; + row-gap: 2.5rem; + } + + .lg\:row-gap-12 { + grid-row-gap: 3rem; + row-gap: 3rem; + } + + .lg\:row-gap-16 { + grid-row-gap: 4rem; + row-gap: 4rem; + } + + .lg\:row-gap-20 { + grid-row-gap: 5rem; + row-gap: 5rem; + } + + .lg\:row-gap-24 { + grid-row-gap: 6rem; + row-gap: 6rem; + } + + .lg\:row-gap-32 { + grid-row-gap: 8rem; + row-gap: 8rem; + } + + .lg\:row-gap-40 { + grid-row-gap: 10rem; + row-gap: 10rem; + } + + .lg\:row-gap-48 { + grid-row-gap: 12rem; + row-gap: 12rem; + } + + .lg\:row-gap-56 { + grid-row-gap: 14rem; + row-gap: 14rem; + } + + .lg\:row-gap-64 { + grid-row-gap: 16rem; + row-gap: 16rem; + } + + .lg\:row-gap-px { + grid-row-gap: 1px; + row-gap: 1px; + } + + .lg\:grid-flow-row { + grid-auto-flow: row; + } + + .lg\:grid-flow-col { + grid-auto-flow: column; + } + + .lg\:grid-flow-row-dense { + grid-auto-flow: row dense; + } + + .lg\:grid-flow-col-dense { + grid-auto-flow: column dense; + } + + .lg\:grid-cols-1 { + grid-template-columns: repeat(1, minmax(0, 1fr)); + } + + .lg\:grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .lg\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .lg\:grid-cols-4 { + grid-template-columns: repeat(4, minmax(0, 1fr)); + } + + .lg\:grid-cols-5 { + grid-template-columns: repeat(5, minmax(0, 1fr)); + } + + .lg\:grid-cols-6 { + grid-template-columns: repeat(6, minmax(0, 1fr)); + } + + .lg\:grid-cols-7 { + grid-template-columns: repeat(7, minmax(0, 1fr)); + } + + .lg\:grid-cols-8 { + grid-template-columns: repeat(8, minmax(0, 1fr)); + } + + .lg\:grid-cols-9 { + grid-template-columns: repeat(9, minmax(0, 1fr)); + } + + .lg\:grid-cols-10 { + grid-template-columns: repeat(10, minmax(0, 1fr)); + } + + .lg\:grid-cols-11 { + grid-template-columns: repeat(11, minmax(0, 1fr)); + } + + .lg\:grid-cols-12 { + grid-template-columns: repeat(12, minmax(0, 1fr)); + } + + .lg\:grid-cols-none { + grid-template-columns: none; + } + + .lg\:col-auto { + grid-column: auto; + } + + .lg\:col-span-1 { + grid-column: span 1 / span 1; + } + + .lg\:col-span-2 { + grid-column: span 2 / span 2; + } + + .lg\:col-span-3 { + grid-column: span 3 / span 3; + } + + .lg\:col-span-4 { + grid-column: span 4 / span 4; + } + + .lg\:col-span-5 { + grid-column: span 5 / span 5; + } + + .lg\:col-span-6 { + grid-column: span 6 / span 6; + } + + .lg\:col-span-7 { + grid-column: span 7 / span 7; + } + + .lg\:col-span-8 { + grid-column: span 8 / span 8; + } + + .lg\:col-span-9 { + grid-column: span 9 / span 9; + } + + .lg\:col-span-10 { + grid-column: span 10 / span 10; + } + + .lg\:col-span-11 { + grid-column: span 11 / span 11; + } + + .lg\:col-span-12 { + grid-column: span 12 / span 12; + } + + .lg\:col-start-1 { + grid-column-start: 1; + } + + .lg\:col-start-2 { + grid-column-start: 2; + } + + .lg\:col-start-3 { + grid-column-start: 3; + } + + .lg\:col-start-4 { + grid-column-start: 4; + } + + .lg\:col-start-5 { + grid-column-start: 5; + } + + .lg\:col-start-6 { + grid-column-start: 6; + } + + .lg\:col-start-7 { + grid-column-start: 7; + } + + .lg\:col-start-8 { + grid-column-start: 8; + } + + .lg\:col-start-9 { + grid-column-start: 9; + } + + .lg\:col-start-10 { + grid-column-start: 10; + } + + .lg\:col-start-11 { + grid-column-start: 11; + } + + .lg\:col-start-12 { + grid-column-start: 12; + } + + .lg\:col-start-13 { + grid-column-start: 13; + } + + .lg\:col-start-auto { + grid-column-start: auto; + } + + .lg\:col-end-1 { + grid-column-end: 1; + } + + .lg\:col-end-2 { + grid-column-end: 2; + } + + .lg\:col-end-3 { + grid-column-end: 3; + } + + .lg\:col-end-4 { + grid-column-end: 4; + } + + .lg\:col-end-5 { + grid-column-end: 5; + } + + .lg\:col-end-6 { + grid-column-end: 6; + } + + .lg\:col-end-7 { + grid-column-end: 7; + } + + .lg\:col-end-8 { + grid-column-end: 8; + } + + .lg\:col-end-9 { + grid-column-end: 9; + } + + .lg\:col-end-10 { + grid-column-end: 10; + } + + .lg\:col-end-11 { + grid-column-end: 11; + } + + .lg\:col-end-12 { + grid-column-end: 12; + } + + .lg\:col-end-13 { + grid-column-end: 13; + } + + .lg\:col-end-auto { + grid-column-end: auto; + } + + .lg\:grid-rows-1 { + grid-template-rows: repeat(1, minmax(0, 1fr)); + } + + .lg\:grid-rows-2 { + grid-template-rows: repeat(2, minmax(0, 1fr)); + } + + .lg\:grid-rows-3 { + grid-template-rows: repeat(3, minmax(0, 1fr)); + } + + .lg\:grid-rows-4 { + grid-template-rows: repeat(4, minmax(0, 1fr)); + } + + .lg\:grid-rows-5 { + grid-template-rows: repeat(5, minmax(0, 1fr)); + } + + .lg\:grid-rows-6 { + grid-template-rows: repeat(6, minmax(0, 1fr)); + } + + .lg\:grid-rows-none { + grid-template-rows: none; + } + + .lg\:row-auto { + grid-row: auto; + } + + .lg\:row-span-1 { + grid-row: span 1 / span 1; + } + + .lg\:row-span-2 { + grid-row: span 2 / span 2; + } + + .lg\:row-span-3 { + grid-row: span 3 / span 3; + } + + .lg\:row-span-4 { + grid-row: span 4 / span 4; + } + + .lg\:row-span-5 { + grid-row: span 5 / span 5; + } + + .lg\:row-span-6 { + grid-row: span 6 / span 6; + } + + .lg\:row-start-1 { + grid-row-start: 1; + } + + .lg\:row-start-2 { + grid-row-start: 2; + } + + .lg\:row-start-3 { + grid-row-start: 3; + } + + .lg\:row-start-4 { + grid-row-start: 4; + } + + .lg\:row-start-5 { + grid-row-start: 5; + } + + .lg\:row-start-6 { + grid-row-start: 6; + } + + .lg\:row-start-7 { + grid-row-start: 7; + } + + .lg\:row-start-auto { + grid-row-start: auto; + } + + .lg\:row-end-1 { + grid-row-end: 1; + } + + .lg\:row-end-2 { + grid-row-end: 2; + } + + .lg\:row-end-3 { + grid-row-end: 3; + } + + .lg\:row-end-4 { + grid-row-end: 4; + } + + .lg\:row-end-5 { + grid-row-end: 5; + } + + .lg\:row-end-6 { + grid-row-end: 6; + } + + .lg\:row-end-7 { + grid-row-end: 7; + } + + .lg\:row-end-auto { + grid-row-end: auto; + } + + .lg\:transform { + --transform-translate-x: 0; + --transform-translate-y: 0; + --transform-rotate: 0; + --transform-skew-x: 0; + --transform-skew-y: 0; + --transform-scale-x: 1; + --transform-scale-y: 1; + transform: translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y)); + } + + .lg\:transform-none { + transform: none; + } + + .lg\:origin-center { + transform-origin: center; + } + + .lg\:origin-top { + transform-origin: top; + } + + .lg\:origin-top-right { + transform-origin: top right; + } + + .lg\:origin-right { + transform-origin: right; + } + + .lg\:origin-bottom-right { + transform-origin: bottom right; + } + + .lg\:origin-bottom { + transform-origin: bottom; + } + + .lg\:origin-bottom-left { + transform-origin: bottom left; + } + + .lg\:origin-left { + transform-origin: left; + } + + .lg\:origin-top-left { + transform-origin: top left; + } + + .lg\:scale-0 { + --transform-scale-x: 0; + --transform-scale-y: 0; + } + + .lg\:scale-50 { + --transform-scale-x: .5; + --transform-scale-y: .5; + } + + .lg\:scale-75 { + --transform-scale-x: .75; + --transform-scale-y: .75; + } + + .lg\:scale-90 { + --transform-scale-x: .9; + --transform-scale-y: .9; + } + + .lg\:scale-95 { + --transform-scale-x: .95; + --transform-scale-y: .95; + } + + .lg\:scale-100 { + --transform-scale-x: 1; + --transform-scale-y: 1; + } + + .lg\:scale-105 { + --transform-scale-x: 1.05; + --transform-scale-y: 1.05; + } + + .lg\:scale-110 { + --transform-scale-x: 1.1; + --transform-scale-y: 1.1; + } + + .lg\:scale-125 { + --transform-scale-x: 1.25; + --transform-scale-y: 1.25; + } + + .lg\:scale-150 { + --transform-scale-x: 1.5; + --transform-scale-y: 1.5; + } + + .lg\:scale-x-0 { + --transform-scale-x: 0; + } + + .lg\:scale-x-50 { + --transform-scale-x: .5; + } + + .lg\:scale-x-75 { + --transform-scale-x: .75; + } + + .lg\:scale-x-90 { + --transform-scale-x: .9; + } + + .lg\:scale-x-95 { + --transform-scale-x: .95; + } + + .lg\:scale-x-100 { + --transform-scale-x: 1; + } + + .lg\:scale-x-105 { + --transform-scale-x: 1.05; + } + + .lg\:scale-x-110 { + --transform-scale-x: 1.1; + } + + .lg\:scale-x-125 { + --transform-scale-x: 1.25; + } + + .lg\:scale-x-150 { + --transform-scale-x: 1.5; + } + + .lg\:scale-y-0 { + --transform-scale-y: 0; + } + + .lg\:scale-y-50 { + --transform-scale-y: .5; + } + + .lg\:scale-y-75 { + --transform-scale-y: .75; + } + + .lg\:scale-y-90 { + --transform-scale-y: .9; + } + + .lg\:scale-y-95 { + --transform-scale-y: .95; + } + + .lg\:scale-y-100 { + --transform-scale-y: 1; + } + + .lg\:scale-y-105 { + --transform-scale-y: 1.05; + } + + .lg\:scale-y-110 { + --transform-scale-y: 1.1; + } + + .lg\:scale-y-125 { + --transform-scale-y: 1.25; + } + + .lg\:scale-y-150 { + --transform-scale-y: 1.5; + } + + .lg\:hover\:scale-0:hover { + --transform-scale-x: 0; + --transform-scale-y: 0; + } + + .lg\:hover\:scale-50:hover { + --transform-scale-x: .5; + --transform-scale-y: .5; + } + + .lg\:hover\:scale-75:hover { + --transform-scale-x: .75; + --transform-scale-y: .75; + } + + .lg\:hover\:scale-90:hover { + --transform-scale-x: .9; + --transform-scale-y: .9; + } + + .lg\:hover\:scale-95:hover { + --transform-scale-x: .95; + --transform-scale-y: .95; + } + + .lg\:hover\:scale-100:hover { + --transform-scale-x: 1; + --transform-scale-y: 1; + } + + .lg\:hover\:scale-105:hover { + --transform-scale-x: 1.05; + --transform-scale-y: 1.05; + } + + .lg\:hover\:scale-110:hover { + --transform-scale-x: 1.1; + --transform-scale-y: 1.1; + } + + .lg\:hover\:scale-125:hover { + --transform-scale-x: 1.25; + --transform-scale-y: 1.25; + } + + .lg\:hover\:scale-150:hover { + --transform-scale-x: 1.5; + --transform-scale-y: 1.5; + } + + .lg\:hover\:scale-x-0:hover { + --transform-scale-x: 0; + } + + .lg\:hover\:scale-x-50:hover { + --transform-scale-x: .5; + } + + .lg\:hover\:scale-x-75:hover { + --transform-scale-x: .75; + } + + .lg\:hover\:scale-x-90:hover { + --transform-scale-x: .9; + } + + .lg\:hover\:scale-x-95:hover { + --transform-scale-x: .95; + } + + .lg\:hover\:scale-x-100:hover { + --transform-scale-x: 1; + } + + .lg\:hover\:scale-x-105:hover { + --transform-scale-x: 1.05; + } + + .lg\:hover\:scale-x-110:hover { + --transform-scale-x: 1.1; + } + + .lg\:hover\:scale-x-125:hover { + --transform-scale-x: 1.25; + } + + .lg\:hover\:scale-x-150:hover { + --transform-scale-x: 1.5; + } + + .lg\:hover\:scale-y-0:hover { + --transform-scale-y: 0; + } + + .lg\:hover\:scale-y-50:hover { + --transform-scale-y: .5; + } + + .lg\:hover\:scale-y-75:hover { + --transform-scale-y: .75; + } + + .lg\:hover\:scale-y-90:hover { + --transform-scale-y: .9; + } + + .lg\:hover\:scale-y-95:hover { + --transform-scale-y: .95; + } + + .lg\:hover\:scale-y-100:hover { + --transform-scale-y: 1; + } + + .lg\:hover\:scale-y-105:hover { + --transform-scale-y: 1.05; + } + + .lg\:hover\:scale-y-110:hover { + --transform-scale-y: 1.1; + } + + .lg\:hover\:scale-y-125:hover { + --transform-scale-y: 1.25; + } + + .lg\:hover\:scale-y-150:hover { + --transform-scale-y: 1.5; + } + + .lg\:focus\:scale-0:focus { + --transform-scale-x: 0; + --transform-scale-y: 0; + } + + .lg\:focus\:scale-50:focus { + --transform-scale-x: .5; + --transform-scale-y: .5; + } + + .lg\:focus\:scale-75:focus { + --transform-scale-x: .75; + --transform-scale-y: .75; + } + + .lg\:focus\:scale-90:focus { + --transform-scale-x: .9; + --transform-scale-y: .9; + } + + .lg\:focus\:scale-95:focus { + --transform-scale-x: .95; + --transform-scale-y: .95; + } + + .lg\:focus\:scale-100:focus { + --transform-scale-x: 1; + --transform-scale-y: 1; + } + + .lg\:focus\:scale-105:focus { + --transform-scale-x: 1.05; + --transform-scale-y: 1.05; + } + + .lg\:focus\:scale-110:focus { + --transform-scale-x: 1.1; + --transform-scale-y: 1.1; + } + + .lg\:focus\:scale-125:focus { + --transform-scale-x: 1.25; + --transform-scale-y: 1.25; + } + + .lg\:focus\:scale-150:focus { + --transform-scale-x: 1.5; + --transform-scale-y: 1.5; + } + + .lg\:focus\:scale-x-0:focus { + --transform-scale-x: 0; + } + + .lg\:focus\:scale-x-50:focus { + --transform-scale-x: .5; + } + + .lg\:focus\:scale-x-75:focus { + --transform-scale-x: .75; + } + + .lg\:focus\:scale-x-90:focus { + --transform-scale-x: .9; + } + + .lg\:focus\:scale-x-95:focus { + --transform-scale-x: .95; + } + + .lg\:focus\:scale-x-100:focus { + --transform-scale-x: 1; + } + + .lg\:focus\:scale-x-105:focus { + --transform-scale-x: 1.05; + } + + .lg\:focus\:scale-x-110:focus { + --transform-scale-x: 1.1; + } + + .lg\:focus\:scale-x-125:focus { + --transform-scale-x: 1.25; + } + + .lg\:focus\:scale-x-150:focus { + --transform-scale-x: 1.5; + } + + .lg\:focus\:scale-y-0:focus { + --transform-scale-y: 0; + } + + .lg\:focus\:scale-y-50:focus { + --transform-scale-y: .5; + } + + .lg\:focus\:scale-y-75:focus { + --transform-scale-y: .75; + } + + .lg\:focus\:scale-y-90:focus { + --transform-scale-y: .9; + } + + .lg\:focus\:scale-y-95:focus { + --transform-scale-y: .95; + } + + .lg\:focus\:scale-y-100:focus { + --transform-scale-y: 1; + } + + .lg\:focus\:scale-y-105:focus { + --transform-scale-y: 1.05; + } + + .lg\:focus\:scale-y-110:focus { + --transform-scale-y: 1.1; + } + + .lg\:focus\:scale-y-125:focus { + --transform-scale-y: 1.25; + } + + .lg\:focus\:scale-y-150:focus { + --transform-scale-y: 1.5; + } + + .lg\:rotate-0 { + --transform-rotate: 0; + } + + .lg\:rotate-45 { + --transform-rotate: 45deg; + } + + .lg\:rotate-90 { + --transform-rotate: 90deg; + } + + .lg\:rotate-180 { + --transform-rotate: 180deg; + } + + .lg\:-rotate-180 { + --transform-rotate: -180deg; + } + + .lg\:-rotate-90 { + --transform-rotate: -90deg; + } + + .lg\:-rotate-45 { + --transform-rotate: -45deg; + } + + .lg\:hover\:rotate-0:hover { + --transform-rotate: 0; + } + + .lg\:hover\:rotate-45:hover { + --transform-rotate: 45deg; + } + + .lg\:hover\:rotate-90:hover { + --transform-rotate: 90deg; + } + + .lg\:hover\:rotate-180:hover { + --transform-rotate: 180deg; + } + + .lg\:hover\:-rotate-180:hover { + --transform-rotate: -180deg; + } + + .lg\:hover\:-rotate-90:hover { + --transform-rotate: -90deg; + } + + .lg\:hover\:-rotate-45:hover { + --transform-rotate: -45deg; + } + + .lg\:focus\:rotate-0:focus { + --transform-rotate: 0; + } + + .lg\:focus\:rotate-45:focus { + --transform-rotate: 45deg; + } + + .lg\:focus\:rotate-90:focus { + --transform-rotate: 90deg; + } + + .lg\:focus\:rotate-180:focus { + --transform-rotate: 180deg; + } + + .lg\:focus\:-rotate-180:focus { + --transform-rotate: -180deg; + } + + .lg\:focus\:-rotate-90:focus { + --transform-rotate: -90deg; + } + + .lg\:focus\:-rotate-45:focus { + --transform-rotate: -45deg; + } + + .lg\:translate-x-0 { + --transform-translate-x: 0; + } + + .lg\:translate-x-1 { + --transform-translate-x: 0.25rem; + } + + .lg\:translate-x-2 { + --transform-translate-x: 0.5rem; + } + + .lg\:translate-x-3 { + --transform-translate-x: 0.75rem; + } + + .lg\:translate-x-4 { + --transform-translate-x: 1rem; + } + + .lg\:translate-x-5 { + --transform-translate-x: 1.25rem; + } + + .lg\:translate-x-6 { + --transform-translate-x: 1.5rem; + } + + .lg\:translate-x-8 { + --transform-translate-x: 2rem; + } + + .lg\:translate-x-10 { + --transform-translate-x: 2.5rem; + } + + .lg\:translate-x-12 { + --transform-translate-x: 3rem; + } + + .lg\:translate-x-16 { + --transform-translate-x: 4rem; + } + + .lg\:translate-x-20 { + --transform-translate-x: 5rem; + } + + .lg\:translate-x-24 { + --transform-translate-x: 6rem; + } + + .lg\:translate-x-32 { + --transform-translate-x: 8rem; + } + + .lg\:translate-x-40 { + --transform-translate-x: 10rem; + } + + .lg\:translate-x-48 { + --transform-translate-x: 12rem; + } + + .lg\:translate-x-56 { + --transform-translate-x: 14rem; + } + + .lg\:translate-x-64 { + --transform-translate-x: 16rem; + } + + .lg\:translate-x-px { + --transform-translate-x: 1px; + } + + .lg\:-translate-x-1 { + --transform-translate-x: -0.25rem; + } + + .lg\:-translate-x-2 { + --transform-translate-x: -0.5rem; + } + + .lg\:-translate-x-3 { + --transform-translate-x: -0.75rem; + } + + .lg\:-translate-x-4 { + --transform-translate-x: -1rem; + } + + .lg\:-translate-x-5 { + --transform-translate-x: -1.25rem; + } + + .lg\:-translate-x-6 { + --transform-translate-x: -1.5rem; + } + + .lg\:-translate-x-8 { + --transform-translate-x: -2rem; + } + + .lg\:-translate-x-10 { + --transform-translate-x: -2.5rem; + } + + .lg\:-translate-x-12 { + --transform-translate-x: -3rem; + } + + .lg\:-translate-x-16 { + --transform-translate-x: -4rem; + } + + .lg\:-translate-x-20 { + --transform-translate-x: -5rem; + } + + .lg\:-translate-x-24 { + --transform-translate-x: -6rem; + } + + .lg\:-translate-x-32 { + --transform-translate-x: -8rem; + } + + .lg\:-translate-x-40 { + --transform-translate-x: -10rem; + } + + .lg\:-translate-x-48 { + --transform-translate-x: -12rem; + } + + .lg\:-translate-x-56 { + --transform-translate-x: -14rem; + } + + .lg\:-translate-x-64 { + --transform-translate-x: -16rem; + } + + .lg\:-translate-x-px { + --transform-translate-x: -1px; + } + + .lg\:-translate-x-full { + --transform-translate-x: -100%; + } + + .lg\:-translate-x-1\/2 { + --transform-translate-x: -50%; + } + + .lg\:translate-x-1\/2 { + --transform-translate-x: 50%; + } + + .lg\:translate-x-full { + --transform-translate-x: 100%; + } + + .lg\:translate-y-0 { + --transform-translate-y: 0; + } + + .lg\:translate-y-1 { + --transform-translate-y: 0.25rem; + } + + .lg\:translate-y-2 { + --transform-translate-y: 0.5rem; + } + + .lg\:translate-y-3 { + --transform-translate-y: 0.75rem; + } + + .lg\:translate-y-4 { + --transform-translate-y: 1rem; + } + + .lg\:translate-y-5 { + --transform-translate-y: 1.25rem; + } + + .lg\:translate-y-6 { + --transform-translate-y: 1.5rem; + } + + .lg\:translate-y-8 { + --transform-translate-y: 2rem; + } + + .lg\:translate-y-10 { + --transform-translate-y: 2.5rem; + } + + .lg\:translate-y-12 { + --transform-translate-y: 3rem; + } + + .lg\:translate-y-16 { + --transform-translate-y: 4rem; + } + + .lg\:translate-y-20 { + --transform-translate-y: 5rem; + } + + .lg\:translate-y-24 { + --transform-translate-y: 6rem; + } + + .lg\:translate-y-32 { + --transform-translate-y: 8rem; + } + + .lg\:translate-y-40 { + --transform-translate-y: 10rem; + } + + .lg\:translate-y-48 { + --transform-translate-y: 12rem; + } + + .lg\:translate-y-56 { + --transform-translate-y: 14rem; + } + + .lg\:translate-y-64 { + --transform-translate-y: 16rem; + } + + .lg\:translate-y-px { + --transform-translate-y: 1px; + } + + .lg\:-translate-y-1 { + --transform-translate-y: -0.25rem; + } + + .lg\:-translate-y-2 { + --transform-translate-y: -0.5rem; + } + + .lg\:-translate-y-3 { + --transform-translate-y: -0.75rem; + } + + .lg\:-translate-y-4 { + --transform-translate-y: -1rem; + } + + .lg\:-translate-y-5 { + --transform-translate-y: -1.25rem; + } + + .lg\:-translate-y-6 { + --transform-translate-y: -1.5rem; + } + + .lg\:-translate-y-8 { + --transform-translate-y: -2rem; + } + + .lg\:-translate-y-10 { + --transform-translate-y: -2.5rem; + } + + .lg\:-translate-y-12 { + --transform-translate-y: -3rem; + } + + .lg\:-translate-y-16 { + --transform-translate-y: -4rem; + } + + .lg\:-translate-y-20 { + --transform-translate-y: -5rem; + } + + .lg\:-translate-y-24 { + --transform-translate-y: -6rem; + } + + .lg\:-translate-y-32 { + --transform-translate-y: -8rem; + } + + .lg\:-translate-y-40 { + --transform-translate-y: -10rem; + } + + .lg\:-translate-y-48 { + --transform-translate-y: -12rem; + } + + .lg\:-translate-y-56 { + --transform-translate-y: -14rem; + } + + .lg\:-translate-y-64 { + --transform-translate-y: -16rem; + } + + .lg\:-translate-y-px { + --transform-translate-y: -1px; + } + + .lg\:-translate-y-full { + --transform-translate-y: -100%; + } + + .lg\:-translate-y-1\/2 { + --transform-translate-y: -50%; + } + + .lg\:translate-y-1\/2 { + --transform-translate-y: 50%; + } + + .lg\:translate-y-full { + --transform-translate-y: 100%; + } + + .lg\:hover\:translate-x-0:hover { + --transform-translate-x: 0; + } + + .lg\:hover\:translate-x-1:hover { + --transform-translate-x: 0.25rem; + } + + .lg\:hover\:translate-x-2:hover { + --transform-translate-x: 0.5rem; + } + + .lg\:hover\:translate-x-3:hover { + --transform-translate-x: 0.75rem; + } + + .lg\:hover\:translate-x-4:hover { + --transform-translate-x: 1rem; + } + + .lg\:hover\:translate-x-5:hover { + --transform-translate-x: 1.25rem; + } + + .lg\:hover\:translate-x-6:hover { + --transform-translate-x: 1.5rem; + } + + .lg\:hover\:translate-x-8:hover { + --transform-translate-x: 2rem; + } + + .lg\:hover\:translate-x-10:hover { + --transform-translate-x: 2.5rem; + } + + .lg\:hover\:translate-x-12:hover { + --transform-translate-x: 3rem; + } + + .lg\:hover\:translate-x-16:hover { + --transform-translate-x: 4rem; + } + + .lg\:hover\:translate-x-20:hover { + --transform-translate-x: 5rem; + } + + .lg\:hover\:translate-x-24:hover { + --transform-translate-x: 6rem; + } + + .lg\:hover\:translate-x-32:hover { + --transform-translate-x: 8rem; + } + + .lg\:hover\:translate-x-40:hover { + --transform-translate-x: 10rem; + } + + .lg\:hover\:translate-x-48:hover { + --transform-translate-x: 12rem; + } + + .lg\:hover\:translate-x-56:hover { + --transform-translate-x: 14rem; + } + + .lg\:hover\:translate-x-64:hover { + --transform-translate-x: 16rem; + } + + .lg\:hover\:translate-x-px:hover { + --transform-translate-x: 1px; + } + + .lg\:hover\:-translate-x-1:hover { + --transform-translate-x: -0.25rem; + } + + .lg\:hover\:-translate-x-2:hover { + --transform-translate-x: -0.5rem; + } + + .lg\:hover\:-translate-x-3:hover { + --transform-translate-x: -0.75rem; + } + + .lg\:hover\:-translate-x-4:hover { + --transform-translate-x: -1rem; + } + + .lg\:hover\:-translate-x-5:hover { + --transform-translate-x: -1.25rem; + } + + .lg\:hover\:-translate-x-6:hover { + --transform-translate-x: -1.5rem; + } + + .lg\:hover\:-translate-x-8:hover { + --transform-translate-x: -2rem; + } + + .lg\:hover\:-translate-x-10:hover { + --transform-translate-x: -2.5rem; + } + + .lg\:hover\:-translate-x-12:hover { + --transform-translate-x: -3rem; + } + + .lg\:hover\:-translate-x-16:hover { + --transform-translate-x: -4rem; + } + + .lg\:hover\:-translate-x-20:hover { + --transform-translate-x: -5rem; + } + + .lg\:hover\:-translate-x-24:hover { + --transform-translate-x: -6rem; + } + + .lg\:hover\:-translate-x-32:hover { + --transform-translate-x: -8rem; + } + + .lg\:hover\:-translate-x-40:hover { + --transform-translate-x: -10rem; + } + + .lg\:hover\:-translate-x-48:hover { + --transform-translate-x: -12rem; + } + + .lg\:hover\:-translate-x-56:hover { + --transform-translate-x: -14rem; + } + + .lg\:hover\:-translate-x-64:hover { + --transform-translate-x: -16rem; + } + + .lg\:hover\:-translate-x-px:hover { + --transform-translate-x: -1px; + } + + .lg\:hover\:-translate-x-full:hover { + --transform-translate-x: -100%; + } + + .lg\:hover\:-translate-x-1\/2:hover { + --transform-translate-x: -50%; + } + + .lg\:hover\:translate-x-1\/2:hover { + --transform-translate-x: 50%; + } + + .lg\:hover\:translate-x-full:hover { + --transform-translate-x: 100%; + } + + .lg\:hover\:translate-y-0:hover { + --transform-translate-y: 0; + } + + .lg\:hover\:translate-y-1:hover { + --transform-translate-y: 0.25rem; + } + + .lg\:hover\:translate-y-2:hover { + --transform-translate-y: 0.5rem; + } + + .lg\:hover\:translate-y-3:hover { + --transform-translate-y: 0.75rem; + } + + .lg\:hover\:translate-y-4:hover { + --transform-translate-y: 1rem; + } + + .lg\:hover\:translate-y-5:hover { + --transform-translate-y: 1.25rem; + } + + .lg\:hover\:translate-y-6:hover { + --transform-translate-y: 1.5rem; + } + + .lg\:hover\:translate-y-8:hover { + --transform-translate-y: 2rem; + } + + .lg\:hover\:translate-y-10:hover { + --transform-translate-y: 2.5rem; + } + + .lg\:hover\:translate-y-12:hover { + --transform-translate-y: 3rem; + } + + .lg\:hover\:translate-y-16:hover { + --transform-translate-y: 4rem; + } + + .lg\:hover\:translate-y-20:hover { + --transform-translate-y: 5rem; + } + + .lg\:hover\:translate-y-24:hover { + --transform-translate-y: 6rem; + } + + .lg\:hover\:translate-y-32:hover { + --transform-translate-y: 8rem; + } + + .lg\:hover\:translate-y-40:hover { + --transform-translate-y: 10rem; + } + + .lg\:hover\:translate-y-48:hover { + --transform-translate-y: 12rem; + } + + .lg\:hover\:translate-y-56:hover { + --transform-translate-y: 14rem; + } + + .lg\:hover\:translate-y-64:hover { + --transform-translate-y: 16rem; + } + + .lg\:hover\:translate-y-px:hover { + --transform-translate-y: 1px; + } + + .lg\:hover\:-translate-y-1:hover { + --transform-translate-y: -0.25rem; + } + + .lg\:hover\:-translate-y-2:hover { + --transform-translate-y: -0.5rem; + } + + .lg\:hover\:-translate-y-3:hover { + --transform-translate-y: -0.75rem; + } + + .lg\:hover\:-translate-y-4:hover { + --transform-translate-y: -1rem; + } + + .lg\:hover\:-translate-y-5:hover { + --transform-translate-y: -1.25rem; + } + + .lg\:hover\:-translate-y-6:hover { + --transform-translate-y: -1.5rem; + } + + .lg\:hover\:-translate-y-8:hover { + --transform-translate-y: -2rem; + } + + .lg\:hover\:-translate-y-10:hover { + --transform-translate-y: -2.5rem; + } + + .lg\:hover\:-translate-y-12:hover { + --transform-translate-y: -3rem; + } + + .lg\:hover\:-translate-y-16:hover { + --transform-translate-y: -4rem; + } + + .lg\:hover\:-translate-y-20:hover { + --transform-translate-y: -5rem; + } + + .lg\:hover\:-translate-y-24:hover { + --transform-translate-y: -6rem; + } + + .lg\:hover\:-translate-y-32:hover { + --transform-translate-y: -8rem; + } + + .lg\:hover\:-translate-y-40:hover { + --transform-translate-y: -10rem; + } + + .lg\:hover\:-translate-y-48:hover { + --transform-translate-y: -12rem; + } + + .lg\:hover\:-translate-y-56:hover { + --transform-translate-y: -14rem; + } + + .lg\:hover\:-translate-y-64:hover { + --transform-translate-y: -16rem; + } + + .lg\:hover\:-translate-y-px:hover { + --transform-translate-y: -1px; + } + + .lg\:hover\:-translate-y-full:hover { + --transform-translate-y: -100%; + } + + .lg\:hover\:-translate-y-1\/2:hover { + --transform-translate-y: -50%; + } + + .lg\:hover\:translate-y-1\/2:hover { + --transform-translate-y: 50%; + } + + .lg\:hover\:translate-y-full:hover { + --transform-translate-y: 100%; + } + + .lg\:focus\:translate-x-0:focus { + --transform-translate-x: 0; + } + + .lg\:focus\:translate-x-1:focus { + --transform-translate-x: 0.25rem; + } + + .lg\:focus\:translate-x-2:focus { + --transform-translate-x: 0.5rem; + } + + .lg\:focus\:translate-x-3:focus { + --transform-translate-x: 0.75rem; + } + + .lg\:focus\:translate-x-4:focus { + --transform-translate-x: 1rem; + } + + .lg\:focus\:translate-x-5:focus { + --transform-translate-x: 1.25rem; + } + + .lg\:focus\:translate-x-6:focus { + --transform-translate-x: 1.5rem; + } + + .lg\:focus\:translate-x-8:focus { + --transform-translate-x: 2rem; + } + + .lg\:focus\:translate-x-10:focus { + --transform-translate-x: 2.5rem; + } + + .lg\:focus\:translate-x-12:focus { + --transform-translate-x: 3rem; + } + + .lg\:focus\:translate-x-16:focus { + --transform-translate-x: 4rem; + } + + .lg\:focus\:translate-x-20:focus { + --transform-translate-x: 5rem; + } + + .lg\:focus\:translate-x-24:focus { + --transform-translate-x: 6rem; + } + + .lg\:focus\:translate-x-32:focus { + --transform-translate-x: 8rem; + } + + .lg\:focus\:translate-x-40:focus { + --transform-translate-x: 10rem; + } + + .lg\:focus\:translate-x-48:focus { + --transform-translate-x: 12rem; + } + + .lg\:focus\:translate-x-56:focus { + --transform-translate-x: 14rem; + } + + .lg\:focus\:translate-x-64:focus { + --transform-translate-x: 16rem; + } + + .lg\:focus\:translate-x-px:focus { + --transform-translate-x: 1px; + } + + .lg\:focus\:-translate-x-1:focus { + --transform-translate-x: -0.25rem; + } + + .lg\:focus\:-translate-x-2:focus { + --transform-translate-x: -0.5rem; + } + + .lg\:focus\:-translate-x-3:focus { + --transform-translate-x: -0.75rem; + } + + .lg\:focus\:-translate-x-4:focus { + --transform-translate-x: -1rem; + } + + .lg\:focus\:-translate-x-5:focus { + --transform-translate-x: -1.25rem; + } + + .lg\:focus\:-translate-x-6:focus { + --transform-translate-x: -1.5rem; + } + + .lg\:focus\:-translate-x-8:focus { + --transform-translate-x: -2rem; + } + + .lg\:focus\:-translate-x-10:focus { + --transform-translate-x: -2.5rem; + } + + .lg\:focus\:-translate-x-12:focus { + --transform-translate-x: -3rem; + } + + .lg\:focus\:-translate-x-16:focus { + --transform-translate-x: -4rem; + } + + .lg\:focus\:-translate-x-20:focus { + --transform-translate-x: -5rem; + } + + .lg\:focus\:-translate-x-24:focus { + --transform-translate-x: -6rem; + } + + .lg\:focus\:-translate-x-32:focus { + --transform-translate-x: -8rem; + } + + .lg\:focus\:-translate-x-40:focus { + --transform-translate-x: -10rem; + } + + .lg\:focus\:-translate-x-48:focus { + --transform-translate-x: -12rem; + } + + .lg\:focus\:-translate-x-56:focus { + --transform-translate-x: -14rem; + } + + .lg\:focus\:-translate-x-64:focus { + --transform-translate-x: -16rem; + } + + .lg\:focus\:-translate-x-px:focus { + --transform-translate-x: -1px; + } + + .lg\:focus\:-translate-x-full:focus { + --transform-translate-x: -100%; + } + + .lg\:focus\:-translate-x-1\/2:focus { + --transform-translate-x: -50%; + } + + .lg\:focus\:translate-x-1\/2:focus { + --transform-translate-x: 50%; + } + + .lg\:focus\:translate-x-full:focus { + --transform-translate-x: 100%; + } + + .lg\:focus\:translate-y-0:focus { + --transform-translate-y: 0; + } + + .lg\:focus\:translate-y-1:focus { + --transform-translate-y: 0.25rem; + } + + .lg\:focus\:translate-y-2:focus { + --transform-translate-y: 0.5rem; + } + + .lg\:focus\:translate-y-3:focus { + --transform-translate-y: 0.75rem; + } + + .lg\:focus\:translate-y-4:focus { + --transform-translate-y: 1rem; + } + + .lg\:focus\:translate-y-5:focus { + --transform-translate-y: 1.25rem; + } + + .lg\:focus\:translate-y-6:focus { + --transform-translate-y: 1.5rem; + } + + .lg\:focus\:translate-y-8:focus { + --transform-translate-y: 2rem; + } + + .lg\:focus\:translate-y-10:focus { + --transform-translate-y: 2.5rem; + } + + .lg\:focus\:translate-y-12:focus { + --transform-translate-y: 3rem; + } + + .lg\:focus\:translate-y-16:focus { + --transform-translate-y: 4rem; + } + + .lg\:focus\:translate-y-20:focus { + --transform-translate-y: 5rem; + } + + .lg\:focus\:translate-y-24:focus { + --transform-translate-y: 6rem; + } + + .lg\:focus\:translate-y-32:focus { + --transform-translate-y: 8rem; + } + + .lg\:focus\:translate-y-40:focus { + --transform-translate-y: 10rem; + } + + .lg\:focus\:translate-y-48:focus { + --transform-translate-y: 12rem; + } + + .lg\:focus\:translate-y-56:focus { + --transform-translate-y: 14rem; + } + + .lg\:focus\:translate-y-64:focus { + --transform-translate-y: 16rem; + } + + .lg\:focus\:translate-y-px:focus { + --transform-translate-y: 1px; + } + + .lg\:focus\:-translate-y-1:focus { + --transform-translate-y: -0.25rem; + } + + .lg\:focus\:-translate-y-2:focus { + --transform-translate-y: -0.5rem; + } + + .lg\:focus\:-translate-y-3:focus { + --transform-translate-y: -0.75rem; + } + + .lg\:focus\:-translate-y-4:focus { + --transform-translate-y: -1rem; + } + + .lg\:focus\:-translate-y-5:focus { + --transform-translate-y: -1.25rem; + } + + .lg\:focus\:-translate-y-6:focus { + --transform-translate-y: -1.5rem; + } + + .lg\:focus\:-translate-y-8:focus { + --transform-translate-y: -2rem; + } + + .lg\:focus\:-translate-y-10:focus { + --transform-translate-y: -2.5rem; + } + + .lg\:focus\:-translate-y-12:focus { + --transform-translate-y: -3rem; + } + + .lg\:focus\:-translate-y-16:focus { + --transform-translate-y: -4rem; + } + + .lg\:focus\:-translate-y-20:focus { + --transform-translate-y: -5rem; + } + + .lg\:focus\:-translate-y-24:focus { + --transform-translate-y: -6rem; + } + + .lg\:focus\:-translate-y-32:focus { + --transform-translate-y: -8rem; + } + + .lg\:focus\:-translate-y-40:focus { + --transform-translate-y: -10rem; + } + + .lg\:focus\:-translate-y-48:focus { + --transform-translate-y: -12rem; + } + + .lg\:focus\:-translate-y-56:focus { + --transform-translate-y: -14rem; + } + + .lg\:focus\:-translate-y-64:focus { + --transform-translate-y: -16rem; + } + + .lg\:focus\:-translate-y-px:focus { + --transform-translate-y: -1px; + } + + .lg\:focus\:-translate-y-full:focus { + --transform-translate-y: -100%; + } + + .lg\:focus\:-translate-y-1\/2:focus { + --transform-translate-y: -50%; + } + + .lg\:focus\:translate-y-1\/2:focus { + --transform-translate-y: 50%; + } + + .lg\:focus\:translate-y-full:focus { + --transform-translate-y: 100%; + } + + .lg\:skew-x-0 { + --transform-skew-x: 0; + } + + .lg\:skew-x-3 { + --transform-skew-x: 3deg; + } + + .lg\:skew-x-6 { + --transform-skew-x: 6deg; + } + + .lg\:skew-x-12 { + --transform-skew-x: 12deg; + } + + .lg\:-skew-x-12 { + --transform-skew-x: -12deg; + } + + .lg\:-skew-x-6 { + --transform-skew-x: -6deg; + } + + .lg\:-skew-x-3 { + --transform-skew-x: -3deg; + } + + .lg\:skew-y-0 { + --transform-skew-y: 0; + } + + .lg\:skew-y-3 { + --transform-skew-y: 3deg; + } + + .lg\:skew-y-6 { + --transform-skew-y: 6deg; + } + + .lg\:skew-y-12 { + --transform-skew-y: 12deg; + } + + .lg\:-skew-y-12 { + --transform-skew-y: -12deg; + } + + .lg\:-skew-y-6 { + --transform-skew-y: -6deg; + } + + .lg\:-skew-y-3 { + --transform-skew-y: -3deg; + } + + .lg\:hover\:skew-x-0:hover { + --transform-skew-x: 0; + } + + .lg\:hover\:skew-x-3:hover { + --transform-skew-x: 3deg; + } + + .lg\:hover\:skew-x-6:hover { + --transform-skew-x: 6deg; + } + + .lg\:hover\:skew-x-12:hover { + --transform-skew-x: 12deg; + } + + .lg\:hover\:-skew-x-12:hover { + --transform-skew-x: -12deg; + } + + .lg\:hover\:-skew-x-6:hover { + --transform-skew-x: -6deg; + } + + .lg\:hover\:-skew-x-3:hover { + --transform-skew-x: -3deg; + } + + .lg\:hover\:skew-y-0:hover { + --transform-skew-y: 0; + } + + .lg\:hover\:skew-y-3:hover { + --transform-skew-y: 3deg; + } + + .lg\:hover\:skew-y-6:hover { + --transform-skew-y: 6deg; + } + + .lg\:hover\:skew-y-12:hover { + --transform-skew-y: 12deg; + } + + .lg\:hover\:-skew-y-12:hover { + --transform-skew-y: -12deg; + } + + .lg\:hover\:-skew-y-6:hover { + --transform-skew-y: -6deg; + } + + .lg\:hover\:-skew-y-3:hover { + --transform-skew-y: -3deg; + } + + .lg\:focus\:skew-x-0:focus { + --transform-skew-x: 0; + } + + .lg\:focus\:skew-x-3:focus { + --transform-skew-x: 3deg; + } + + .lg\:focus\:skew-x-6:focus { + --transform-skew-x: 6deg; + } + + .lg\:focus\:skew-x-12:focus { + --transform-skew-x: 12deg; + } + + .lg\:focus\:-skew-x-12:focus { + --transform-skew-x: -12deg; + } + + .lg\:focus\:-skew-x-6:focus { + --transform-skew-x: -6deg; + } + + .lg\:focus\:-skew-x-3:focus { + --transform-skew-x: -3deg; + } + + .lg\:focus\:skew-y-0:focus { + --transform-skew-y: 0; + } + + .lg\:focus\:skew-y-3:focus { + --transform-skew-y: 3deg; + } + + .lg\:focus\:skew-y-6:focus { + --transform-skew-y: 6deg; + } + + .lg\:focus\:skew-y-12:focus { + --transform-skew-y: 12deg; + } + + .lg\:focus\:-skew-y-12:focus { + --transform-skew-y: -12deg; + } + + .lg\:focus\:-skew-y-6:focus { + --transform-skew-y: -6deg; + } + + .lg\:focus\:-skew-y-3:focus { + --transform-skew-y: -3deg; + } + + .lg\:transition-none { + transition-property: none; + } + + .lg\:transition-all { + transition-property: all; + } + + .lg\:transition { + transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform; + } + + .lg\:transition-colors { + transition-property: background-color, border-color, color, fill, stroke; + } + + .lg\:transition-opacity { + transition-property: opacity; + } + + .lg\:transition-shadow { + transition-property: box-shadow; + } + + .lg\:transition-transform { + transition-property: transform; + } + + .lg\:ease-linear { + transition-timing-function: linear; + } + + .lg\:ease-in { + transition-timing-function: cubic-bezier(0.4, 0, 1, 1); + } + + .lg\:ease-out { + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + } + + .lg\:ease-in-out { + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + } + + .lg\:duration-75 { + transition-duration: 75ms; + } + + .lg\:duration-100 { + transition-duration: 100ms; + } + + .lg\:duration-150 { + transition-duration: 150ms; + } + + .lg\:duration-200 { + transition-duration: 200ms; + } + + .lg\:duration-300 { + transition-duration: 300ms; + } + + .lg\:duration-500 { + transition-duration: 500ms; + } + + .lg\:duration-700 { + transition-duration: 700ms; + } + + .lg\:duration-1000 { + transition-duration: 1000ms; + } +} + +@media (min-width: 1280px) { + .xl\:sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; + } + + .xl\:not-sr-only { + position: static; + width: auto; + height: auto; + padding: 0; + margin: 0; + overflow: visible; + clip: auto; + white-space: normal; + } + + .xl\:focus\:sr-only:focus { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; + } + + .xl\:focus\:not-sr-only:focus { + position: static; + width: auto; + height: auto; + padding: 0; + margin: 0; + overflow: visible; + clip: auto; + white-space: normal; + } + + .xl\:appearance-none { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + } + + .xl\:bg-fixed { + background-attachment: fixed; + } + + .xl\:bg-local { + background-attachment: local; + } + + .xl\:bg-scroll { + background-attachment: scroll; + } + + .xl\:bg-transparent { + background-color: transparent; + } + + .xl\:bg-black { + background-color: #000; + } + + .xl\:bg-white { + background-color: #fff; + } + + .xl\:bg-gray-100 { + background-color: #f7fafc; + } + + .xl\:bg-gray-200 { + background-color: #edf2f7; + } + + .xl\:bg-gray-300 { + background-color: #e2e8f0; + } + + .xl\:bg-gray-400 { + background-color: #cbd5e0; + } + + .xl\:bg-gray-500 { + background-color: #a0aec0; + } + + .xl\:bg-gray-600 { + background-color: #718096; + } + + .xl\:bg-gray-700 { + background-color: #4a5568; + } + + .xl\:bg-gray-800 { + background-color: #2d3748; + } + + .xl\:bg-gray-900 { + background-color: #1a202c; + } + + .xl\:bg-red-100 { + background-color: #fff5f5; + } + + .xl\:bg-red-200 { + background-color: #fed7d7; + } + + .xl\:bg-red-300 { + background-color: #feb2b2; + } + + .xl\:bg-red-400 { + background-color: #fc8181; + } + + .xl\:bg-red-500 { + background-color: #f56565; + } + + .xl\:bg-red-600 { + background-color: #e53e3e; + } + + .xl\:bg-red-700 { + background-color: #c53030; + } + + .xl\:bg-red-800 { + background-color: #9b2c2c; + } + + .xl\:bg-red-900 { + background-color: #742a2a; + } + + .xl\:bg-orange-100 { + background-color: #fffaf0; + } + + .xl\:bg-orange-200 { + background-color: #feebc8; + } + + .xl\:bg-orange-300 { + background-color: #fbd38d; + } + + .xl\:bg-orange-400 { + background-color: #f6ad55; + } + + .xl\:bg-orange-500 { + background-color: #ed8936; + } + + .xl\:bg-orange-600 { + background-color: #dd6b20; + } + + .xl\:bg-orange-700 { + background-color: #c05621; + } + + .xl\:bg-orange-800 { + background-color: #9c4221; + } + + .xl\:bg-orange-900 { + background-color: #7b341e; + } + + .xl\:bg-yellow-100 { + background-color: #fffff0; + } + + .xl\:bg-yellow-200 { + background-color: #fefcbf; + } + + .xl\:bg-yellow-300 { + background-color: #faf089; + } + + .xl\:bg-yellow-400 { + background-color: #f6e05e; + } + + .xl\:bg-yellow-500 { + background-color: #ecc94b; + } + + .xl\:bg-yellow-600 { + background-color: #d69e2e; + } + + .xl\:bg-yellow-700 { + background-color: #b7791f; + } + + .xl\:bg-yellow-800 { + background-color: #975a16; + } + + .xl\:bg-yellow-900 { + background-color: #744210; + } + + .xl\:bg-green-100 { + background-color: #f0fff4; + } + + .xl\:bg-green-200 { + background-color: #c6f6d5; + } + + .xl\:bg-green-300 { + background-color: #9ae6b4; + } + + .xl\:bg-green-400 { + background-color: #68d391; + } + + .xl\:bg-green-500 { + background-color: #48bb78; + } + + .xl\:bg-green-600 { + background-color: #38a169; + } + + .xl\:bg-green-700 { + background-color: #2f855a; + } + + .xl\:bg-green-800 { + background-color: #276749; + } + + .xl\:bg-green-900 { + background-color: #22543d; + } + + .xl\:bg-teal-100 { + background-color: #e6fffa; + } + + .xl\:bg-teal-200 { + background-color: #b2f5ea; + } + + .xl\:bg-teal-300 { + background-color: #81e6d9; + } + + .xl\:bg-teal-400 { + background-color: #4fd1c5; + } + + .xl\:bg-teal-500 { + background-color: #38b2ac; + } + + .xl\:bg-teal-600 { + background-color: #319795; + } + + .xl\:bg-teal-700 { + background-color: #2c7a7b; + } + + .xl\:bg-teal-800 { + background-color: #285e61; + } + + .xl\:bg-teal-900 { + background-color: #234e52; + } + + .xl\:bg-blue-100 { + background-color: #ebf8ff; + } + + .xl\:bg-blue-200 { + background-color: #bee3f8; + } + + .xl\:bg-blue-300 { + background-color: #90cdf4; + } + + .xl\:bg-blue-400 { + background-color: #63b3ed; + } + + .xl\:bg-blue-500 { + background-color: #4299e1; + } + + .xl\:bg-blue-600 { + background-color: #3182ce; + } + + .xl\:bg-blue-700 { + background-color: #2b6cb0; + } + + .xl\:bg-blue-800 { + background-color: #2c5282; + } + + .xl\:bg-blue-900 { + background-color: #2a4365; + } + + .xl\:bg-indigo-100 { + background-color: #ebf4ff; + } + + .xl\:bg-indigo-200 { + background-color: #c3dafe; + } + + .xl\:bg-indigo-300 { + background-color: #a3bffa; + } + + .xl\:bg-indigo-400 { + background-color: #7f9cf5; + } + + .xl\:bg-indigo-500 { + background-color: #667eea; + } + + .xl\:bg-indigo-600 { + background-color: #5a67d8; + } + + .xl\:bg-indigo-700 { + background-color: #4c51bf; + } + + .xl\:bg-indigo-800 { + background-color: #434190; + } + + .xl\:bg-indigo-900 { + background-color: #3c366b; + } + + .xl\:bg-purple-100 { + background-color: #faf5ff; + } + + .xl\:bg-purple-200 { + background-color: #e9d8fd; + } + + .xl\:bg-purple-300 { + background-color: #d6bcfa; + } + + .xl\:bg-purple-400 { + background-color: #b794f4; + } + + .xl\:bg-purple-500 { + background-color: #9f7aea; + } + + .xl\:bg-purple-600 { + background-color: #805ad5; + } + + .xl\:bg-purple-700 { + background-color: #6b46c1; + } + + .xl\:bg-purple-800 { + background-color: #553c9a; + } + + .xl\:bg-purple-900 { + background-color: #44337a; + } + + .xl\:bg-pink-100 { + background-color: #fff5f7; + } + + .xl\:bg-pink-200 { + background-color: #fed7e2; + } + + .xl\:bg-pink-300 { + background-color: #fbb6ce; + } + + .xl\:bg-pink-400 { + background-color: #f687b3; + } + + .xl\:bg-pink-500 { + background-color: #ed64a6; + } + + .xl\:bg-pink-600 { + background-color: #d53f8c; + } + + .xl\:bg-pink-700 { + background-color: #b83280; + } + + .xl\:bg-pink-800 { + background-color: #97266d; + } + + .xl\:bg-pink-900 { + background-color: #702459; + } + + .xl\:hover\:bg-transparent:hover { + background-color: transparent; + } + + .xl\:hover\:bg-black:hover { + background-color: #000; + } + + .xl\:hover\:bg-white:hover { + background-color: #fff; + } + + .xl\:hover\:bg-gray-100:hover { + background-color: #f7fafc; + } + + .xl\:hover\:bg-gray-200:hover { + background-color: #edf2f7; + } + + .xl\:hover\:bg-gray-300:hover { + background-color: #e2e8f0; + } + + .xl\:hover\:bg-gray-400:hover { + background-color: #cbd5e0; + } + + .xl\:hover\:bg-gray-500:hover { + background-color: #a0aec0; + } + + .xl\:hover\:bg-gray-600:hover { + background-color: #718096; + } + + .xl\:hover\:bg-gray-700:hover { + background-color: #4a5568; + } + + .xl\:hover\:bg-gray-800:hover { + background-color: #2d3748; + } + + .xl\:hover\:bg-gray-900:hover { + background-color: #1a202c; + } + + .xl\:hover\:bg-red-100:hover { + background-color: #fff5f5; + } + + .xl\:hover\:bg-red-200:hover { + background-color: #fed7d7; + } + + .xl\:hover\:bg-red-300:hover { + background-color: #feb2b2; + } + + .xl\:hover\:bg-red-400:hover { + background-color: #fc8181; + } + + .xl\:hover\:bg-red-500:hover { + background-color: #f56565; + } + + .xl\:hover\:bg-red-600:hover { + background-color: #e53e3e; + } + + .xl\:hover\:bg-red-700:hover { + background-color: #c53030; + } + + .xl\:hover\:bg-red-800:hover { + background-color: #9b2c2c; + } + + .xl\:hover\:bg-red-900:hover { + background-color: #742a2a; + } + + .xl\:hover\:bg-orange-100:hover { + background-color: #fffaf0; + } + + .xl\:hover\:bg-orange-200:hover { + background-color: #feebc8; + } + + .xl\:hover\:bg-orange-300:hover { + background-color: #fbd38d; + } + + .xl\:hover\:bg-orange-400:hover { + background-color: #f6ad55; + } + + .xl\:hover\:bg-orange-500:hover { + background-color: #ed8936; + } + + .xl\:hover\:bg-orange-600:hover { + background-color: #dd6b20; + } + + .xl\:hover\:bg-orange-700:hover { + background-color: #c05621; + } + + .xl\:hover\:bg-orange-800:hover { + background-color: #9c4221; + } + + .xl\:hover\:bg-orange-900:hover { + background-color: #7b341e; + } + + .xl\:hover\:bg-yellow-100:hover { + background-color: #fffff0; + } + + .xl\:hover\:bg-yellow-200:hover { + background-color: #fefcbf; + } + + .xl\:hover\:bg-yellow-300:hover { + background-color: #faf089; + } + + .xl\:hover\:bg-yellow-400:hover { + background-color: #f6e05e; + } + + .xl\:hover\:bg-yellow-500:hover { + background-color: #ecc94b; + } + + .xl\:hover\:bg-yellow-600:hover { + background-color: #d69e2e; + } + + .xl\:hover\:bg-yellow-700:hover { + background-color: #b7791f; + } + + .xl\:hover\:bg-yellow-800:hover { + background-color: #975a16; + } + + .xl\:hover\:bg-yellow-900:hover { + background-color: #744210; + } + + .xl\:hover\:bg-green-100:hover { + background-color: #f0fff4; + } + + .xl\:hover\:bg-green-200:hover { + background-color: #c6f6d5; + } + + .xl\:hover\:bg-green-300:hover { + background-color: #9ae6b4; + } + + .xl\:hover\:bg-green-400:hover { + background-color: #68d391; + } + + .xl\:hover\:bg-green-500:hover { + background-color: #48bb78; + } + + .xl\:hover\:bg-green-600:hover { + background-color: #38a169; + } + + .xl\:hover\:bg-green-700:hover { + background-color: #2f855a; + } + + .xl\:hover\:bg-green-800:hover { + background-color: #276749; + } + + .xl\:hover\:bg-green-900:hover { + background-color: #22543d; + } + + .xl\:hover\:bg-teal-100:hover { + background-color: #e6fffa; + } + + .xl\:hover\:bg-teal-200:hover { + background-color: #b2f5ea; + } + + .xl\:hover\:bg-teal-300:hover { + background-color: #81e6d9; + } + + .xl\:hover\:bg-teal-400:hover { + background-color: #4fd1c5; + } + + .xl\:hover\:bg-teal-500:hover { + background-color: #38b2ac; + } + + .xl\:hover\:bg-teal-600:hover { + background-color: #319795; + } + + .xl\:hover\:bg-teal-700:hover { + background-color: #2c7a7b; + } + + .xl\:hover\:bg-teal-800:hover { + background-color: #285e61; + } + + .xl\:hover\:bg-teal-900:hover { + background-color: #234e52; + } + + .xl\:hover\:bg-blue-100:hover { + background-color: #ebf8ff; + } + + .xl\:hover\:bg-blue-200:hover { + background-color: #bee3f8; + } + + .xl\:hover\:bg-blue-300:hover { + background-color: #90cdf4; + } + + .xl\:hover\:bg-blue-400:hover { + background-color: #63b3ed; + } + + .xl\:hover\:bg-blue-500:hover { + background-color: #4299e1; + } + + .xl\:hover\:bg-blue-600:hover { + background-color: #3182ce; + } + + .xl\:hover\:bg-blue-700:hover { + background-color: #2b6cb0; + } + + .xl\:hover\:bg-blue-800:hover { + background-color: #2c5282; + } + + .xl\:hover\:bg-blue-900:hover { + background-color: #2a4365; + } + + .xl\:hover\:bg-indigo-100:hover { + background-color: #ebf4ff; + } + + .xl\:hover\:bg-indigo-200:hover { + background-color: #c3dafe; + } + + .xl\:hover\:bg-indigo-300:hover { + background-color: #a3bffa; + } + + .xl\:hover\:bg-indigo-400:hover { + background-color: #7f9cf5; + } + + .xl\:hover\:bg-indigo-500:hover { + background-color: #667eea; + } + + .xl\:hover\:bg-indigo-600:hover { + background-color: #5a67d8; + } + + .xl\:hover\:bg-indigo-700:hover { + background-color: #4c51bf; + } + + .xl\:hover\:bg-indigo-800:hover { + background-color: #434190; + } + + .xl\:hover\:bg-indigo-900:hover { + background-color: #3c366b; + } + + .xl\:hover\:bg-purple-100:hover { + background-color: #faf5ff; + } + + .xl\:hover\:bg-purple-200:hover { + background-color: #e9d8fd; + } + + .xl\:hover\:bg-purple-300:hover { + background-color: #d6bcfa; + } + + .xl\:hover\:bg-purple-400:hover { + background-color: #b794f4; + } + + .xl\:hover\:bg-purple-500:hover { + background-color: #9f7aea; + } + + .xl\:hover\:bg-purple-600:hover { + background-color: #805ad5; + } + + .xl\:hover\:bg-purple-700:hover { + background-color: #6b46c1; + } + + .xl\:hover\:bg-purple-800:hover { + background-color: #553c9a; + } + + .xl\:hover\:bg-purple-900:hover { + background-color: #44337a; + } + + .xl\:hover\:bg-pink-100:hover { + background-color: #fff5f7; + } + + .xl\:hover\:bg-pink-200:hover { + background-color: #fed7e2; + } + + .xl\:hover\:bg-pink-300:hover { + background-color: #fbb6ce; + } + + .xl\:hover\:bg-pink-400:hover { + background-color: #f687b3; + } + + .xl\:hover\:bg-pink-500:hover { + background-color: #ed64a6; + } + + .xl\:hover\:bg-pink-600:hover { + background-color: #d53f8c; + } + + .xl\:hover\:bg-pink-700:hover { + background-color: #b83280; + } + + .xl\:hover\:bg-pink-800:hover { + background-color: #97266d; + } + + .xl\:hover\:bg-pink-900:hover { + background-color: #702459; + } + + .xl\:focus\:bg-transparent:focus { + background-color: transparent; + } + + .xl\:focus\:bg-black:focus { + background-color: #000; + } + + .xl\:focus\:bg-white:focus { + background-color: #fff; + } + + .xl\:focus\:bg-gray-100:focus { + background-color: #f7fafc; + } + + .xl\:focus\:bg-gray-200:focus { + background-color: #edf2f7; + } + + .xl\:focus\:bg-gray-300:focus { + background-color: #e2e8f0; + } + + .xl\:focus\:bg-gray-400:focus { + background-color: #cbd5e0; + } + + .xl\:focus\:bg-gray-500:focus { + background-color: #a0aec0; + } + + .xl\:focus\:bg-gray-600:focus { + background-color: #718096; + } + + .xl\:focus\:bg-gray-700:focus { + background-color: #4a5568; + } + + .xl\:focus\:bg-gray-800:focus { + background-color: #2d3748; + } + + .xl\:focus\:bg-gray-900:focus { + background-color: #1a202c; + } + + .xl\:focus\:bg-red-100:focus { + background-color: #fff5f5; + } + + .xl\:focus\:bg-red-200:focus { + background-color: #fed7d7; + } + + .xl\:focus\:bg-red-300:focus { + background-color: #feb2b2; + } + + .xl\:focus\:bg-red-400:focus { + background-color: #fc8181; + } + + .xl\:focus\:bg-red-500:focus { + background-color: #f56565; + } + + .xl\:focus\:bg-red-600:focus { + background-color: #e53e3e; + } + + .xl\:focus\:bg-red-700:focus { + background-color: #c53030; + } + + .xl\:focus\:bg-red-800:focus { + background-color: #9b2c2c; + } + + .xl\:focus\:bg-red-900:focus { + background-color: #742a2a; + } + + .xl\:focus\:bg-orange-100:focus { + background-color: #fffaf0; + } + + .xl\:focus\:bg-orange-200:focus { + background-color: #feebc8; + } + + .xl\:focus\:bg-orange-300:focus { + background-color: #fbd38d; + } + + .xl\:focus\:bg-orange-400:focus { + background-color: #f6ad55; + } + + .xl\:focus\:bg-orange-500:focus { + background-color: #ed8936; + } + + .xl\:focus\:bg-orange-600:focus { + background-color: #dd6b20; + } + + .xl\:focus\:bg-orange-700:focus { + background-color: #c05621; + } + + .xl\:focus\:bg-orange-800:focus { + background-color: #9c4221; + } + + .xl\:focus\:bg-orange-900:focus { + background-color: #7b341e; + } + + .xl\:focus\:bg-yellow-100:focus { + background-color: #fffff0; + } + + .xl\:focus\:bg-yellow-200:focus { + background-color: #fefcbf; + } + + .xl\:focus\:bg-yellow-300:focus { + background-color: #faf089; + } + + .xl\:focus\:bg-yellow-400:focus { + background-color: #f6e05e; + } + + .xl\:focus\:bg-yellow-500:focus { + background-color: #ecc94b; + } + + .xl\:focus\:bg-yellow-600:focus { + background-color: #d69e2e; + } + + .xl\:focus\:bg-yellow-700:focus { + background-color: #b7791f; + } + + .xl\:focus\:bg-yellow-800:focus { + background-color: #975a16; + } + + .xl\:focus\:bg-yellow-900:focus { + background-color: #744210; + } + + .xl\:focus\:bg-green-100:focus { + background-color: #f0fff4; + } + + .xl\:focus\:bg-green-200:focus { + background-color: #c6f6d5; + } + + .xl\:focus\:bg-green-300:focus { + background-color: #9ae6b4; + } + + .xl\:focus\:bg-green-400:focus { + background-color: #68d391; + } + + .xl\:focus\:bg-green-500:focus { + background-color: #48bb78; + } + + .xl\:focus\:bg-green-600:focus { + background-color: #38a169; + } + + .xl\:focus\:bg-green-700:focus { + background-color: #2f855a; + } + + .xl\:focus\:bg-green-800:focus { + background-color: #276749; + } + + .xl\:focus\:bg-green-900:focus { + background-color: #22543d; + } + + .xl\:focus\:bg-teal-100:focus { + background-color: #e6fffa; + } + + .xl\:focus\:bg-teal-200:focus { + background-color: #b2f5ea; + } + + .xl\:focus\:bg-teal-300:focus { + background-color: #81e6d9; + } + + .xl\:focus\:bg-teal-400:focus { + background-color: #4fd1c5; + } + + .xl\:focus\:bg-teal-500:focus { + background-color: #38b2ac; + } + + .xl\:focus\:bg-teal-600:focus { + background-color: #319795; + } + + .xl\:focus\:bg-teal-700:focus { + background-color: #2c7a7b; + } + + .xl\:focus\:bg-teal-800:focus { + background-color: #285e61; + } + + .xl\:focus\:bg-teal-900:focus { + background-color: #234e52; + } + + .xl\:focus\:bg-blue-100:focus { + background-color: #ebf8ff; + } + + .xl\:focus\:bg-blue-200:focus { + background-color: #bee3f8; + } + + .xl\:focus\:bg-blue-300:focus { + background-color: #90cdf4; + } + + .xl\:focus\:bg-blue-400:focus { + background-color: #63b3ed; + } + + .xl\:focus\:bg-blue-500:focus { + background-color: #4299e1; + } + + .xl\:focus\:bg-blue-600:focus { + background-color: #3182ce; + } + + .xl\:focus\:bg-blue-700:focus { + background-color: #2b6cb0; + } + + .xl\:focus\:bg-blue-800:focus { + background-color: #2c5282; + } + + .xl\:focus\:bg-blue-900:focus { + background-color: #2a4365; + } + + .xl\:focus\:bg-indigo-100:focus { + background-color: #ebf4ff; + } + + .xl\:focus\:bg-indigo-200:focus { + background-color: #c3dafe; + } + + .xl\:focus\:bg-indigo-300:focus { + background-color: #a3bffa; + } + + .xl\:focus\:bg-indigo-400:focus { + background-color: #7f9cf5; + } + + .xl\:focus\:bg-indigo-500:focus { + background-color: #667eea; + } + + .xl\:focus\:bg-indigo-600:focus { + background-color: #5a67d8; + } + + .xl\:focus\:bg-indigo-700:focus { + background-color: #4c51bf; + } + + .xl\:focus\:bg-indigo-800:focus { + background-color: #434190; + } + + .xl\:focus\:bg-indigo-900:focus { + background-color: #3c366b; + } + + .xl\:focus\:bg-purple-100:focus { + background-color: #faf5ff; + } + + .xl\:focus\:bg-purple-200:focus { + background-color: #e9d8fd; + } + + .xl\:focus\:bg-purple-300:focus { + background-color: #d6bcfa; + } + + .xl\:focus\:bg-purple-400:focus { + background-color: #b794f4; + } + + .xl\:focus\:bg-purple-500:focus { + background-color: #9f7aea; + } + + .xl\:focus\:bg-purple-600:focus { + background-color: #805ad5; + } + + .xl\:focus\:bg-purple-700:focus { + background-color: #6b46c1; + } + + .xl\:focus\:bg-purple-800:focus { + background-color: #553c9a; + } + + .xl\:focus\:bg-purple-900:focus { + background-color: #44337a; + } + + .xl\:focus\:bg-pink-100:focus { + background-color: #fff5f7; + } + + .xl\:focus\:bg-pink-200:focus { + background-color: #fed7e2; + } + + .xl\:focus\:bg-pink-300:focus { + background-color: #fbb6ce; + } + + .xl\:focus\:bg-pink-400:focus { + background-color: #f687b3; + } + + .xl\:focus\:bg-pink-500:focus { + background-color: #ed64a6; + } + + .xl\:focus\:bg-pink-600:focus { + background-color: #d53f8c; + } + + .xl\:focus\:bg-pink-700:focus { + background-color: #b83280; + } + + .xl\:focus\:bg-pink-800:focus { + background-color: #97266d; + } + + .xl\:focus\:bg-pink-900:focus { + background-color: #702459; + } + + .xl\:bg-bottom { + background-position: bottom; + } + + .xl\:bg-center { + background-position: center; + } + + .xl\:bg-left { + background-position: left; + } + + .xl\:bg-left-bottom { + background-position: left bottom; + } + + .xl\:bg-left-top { + background-position: left top; + } + + .xl\:bg-right { + background-position: right; + } + + .xl\:bg-right-bottom { + background-position: right bottom; + } + + .xl\:bg-right-top { + background-position: right top; + } + + .xl\:bg-top { + background-position: top; + } + + .xl\:bg-repeat { + background-repeat: repeat; + } + + .xl\:bg-no-repeat { + background-repeat: no-repeat; + } + + .xl\:bg-repeat-x { + background-repeat: repeat-x; + } + + .xl\:bg-repeat-y { + background-repeat: repeat-y; + } + + .xl\:bg-repeat-round { + background-repeat: round; + } + + .xl\:bg-repeat-space { + background-repeat: space; + } + + .xl\:bg-auto { + background-size: auto; + } + + .xl\:bg-cover { + background-size: cover; + } + + .xl\:bg-contain { + background-size: contain; + } + + .xl\:border-collapse { + border-collapse: collapse; + } + + .xl\:border-separate { + border-collapse: separate; + } + + .xl\:border-transparent { + border-color: transparent; + } + + .xl\:border-black { + border-color: #000; + } + + .xl\:border-white { + border-color: #fff; + } + + .xl\:border-gray-100 { + border-color: #f7fafc; + } + + .xl\:border-gray-200 { + border-color: #edf2f7; + } + + .xl\:border-gray-300 { + border-color: #e2e8f0; + } + + .xl\:border-gray-400 { + border-color: #cbd5e0; + } + + .xl\:border-gray-500 { + border-color: #a0aec0; + } + + .xl\:border-gray-600 { + border-color: #718096; + } + + .xl\:border-gray-700 { + border-color: #4a5568; + } + + .xl\:border-gray-800 { + border-color: #2d3748; + } + + .xl\:border-gray-900 { + border-color: #1a202c; + } + + .xl\:border-red-100 { + border-color: #fff5f5; + } + + .xl\:border-red-200 { + border-color: #fed7d7; + } + + .xl\:border-red-300 { + border-color: #feb2b2; + } + + .xl\:border-red-400 { + border-color: #fc8181; + } + + .xl\:border-red-500 { + border-color: #f56565; + } + + .xl\:border-red-600 { + border-color: #e53e3e; + } + + .xl\:border-red-700 { + border-color: #c53030; + } + + .xl\:border-red-800 { + border-color: #9b2c2c; + } + + .xl\:border-red-900 { + border-color: #742a2a; + } + + .xl\:border-orange-100 { + border-color: #fffaf0; + } + + .xl\:border-orange-200 { + border-color: #feebc8; + } + + .xl\:border-orange-300 { + border-color: #fbd38d; + } + + .xl\:border-orange-400 { + border-color: #f6ad55; + } + + .xl\:border-orange-500 { + border-color: #ed8936; + } + + .xl\:border-orange-600 { + border-color: #dd6b20; + } + + .xl\:border-orange-700 { + border-color: #c05621; + } + + .xl\:border-orange-800 { + border-color: #9c4221; + } + + .xl\:border-orange-900 { + border-color: #7b341e; + } + + .xl\:border-yellow-100 { + border-color: #fffff0; + } + + .xl\:border-yellow-200 { + border-color: #fefcbf; + } + + .xl\:border-yellow-300 { + border-color: #faf089; + } + + .xl\:border-yellow-400 { + border-color: #f6e05e; + } + + .xl\:border-yellow-500 { + border-color: #ecc94b; + } + + .xl\:border-yellow-600 { + border-color: #d69e2e; + } + + .xl\:border-yellow-700 { + border-color: #b7791f; + } + + .xl\:border-yellow-800 { + border-color: #975a16; + } + + .xl\:border-yellow-900 { + border-color: #744210; + } + + .xl\:border-green-100 { + border-color: #f0fff4; + } + + .xl\:border-green-200 { + border-color: #c6f6d5; + } + + .xl\:border-green-300 { + border-color: #9ae6b4; + } + + .xl\:border-green-400 { + border-color: #68d391; + } + + .xl\:border-green-500 { + border-color: #48bb78; + } + + .xl\:border-green-600 { + border-color: #38a169; + } + + .xl\:border-green-700 { + border-color: #2f855a; + } + + .xl\:border-green-800 { + border-color: #276749; + } + + .xl\:border-green-900 { + border-color: #22543d; + } + + .xl\:border-teal-100 { + border-color: #e6fffa; + } + + .xl\:border-teal-200 { + border-color: #b2f5ea; + } + + .xl\:border-teal-300 { + border-color: #81e6d9; + } + + .xl\:border-teal-400 { + border-color: #4fd1c5; + } + + .xl\:border-teal-500 { + border-color: #38b2ac; + } + + .xl\:border-teal-600 { + border-color: #319795; + } + + .xl\:border-teal-700 { + border-color: #2c7a7b; + } + + .xl\:border-teal-800 { + border-color: #285e61; + } + + .xl\:border-teal-900 { + border-color: #234e52; + } + + .xl\:border-blue-100 { + border-color: #ebf8ff; + } + + .xl\:border-blue-200 { + border-color: #bee3f8; + } + + .xl\:border-blue-300 { + border-color: #90cdf4; + } + + .xl\:border-blue-400 { + border-color: #63b3ed; + } + + .xl\:border-blue-500 { + border-color: #4299e1; + } + + .xl\:border-blue-600 { + border-color: #3182ce; + } + + .xl\:border-blue-700 { + border-color: #2b6cb0; + } + + .xl\:border-blue-800 { + border-color: #2c5282; + } + + .xl\:border-blue-900 { + border-color: #2a4365; + } + + .xl\:border-indigo-100 { + border-color: #ebf4ff; + } + + .xl\:border-indigo-200 { + border-color: #c3dafe; + } + + .xl\:border-indigo-300 { + border-color: #a3bffa; + } + + .xl\:border-indigo-400 { + border-color: #7f9cf5; + } + + .xl\:border-indigo-500 { + border-color: #667eea; + } + + .xl\:border-indigo-600 { + border-color: #5a67d8; + } + + .xl\:border-indigo-700 { + border-color: #4c51bf; + } + + .xl\:border-indigo-800 { + border-color: #434190; + } + + .xl\:border-indigo-900 { + border-color: #3c366b; + } + + .xl\:border-purple-100 { + border-color: #faf5ff; + } + + .xl\:border-purple-200 { + border-color: #e9d8fd; + } + + .xl\:border-purple-300 { + border-color: #d6bcfa; + } + + .xl\:border-purple-400 { + border-color: #b794f4; + } + + .xl\:border-purple-500 { + border-color: #9f7aea; + } + + .xl\:border-purple-600 { + border-color: #805ad5; + } + + .xl\:border-purple-700 { + border-color: #6b46c1; + } + + .xl\:border-purple-800 { + border-color: #553c9a; + } + + .xl\:border-purple-900 { + border-color: #44337a; + } + + .xl\:border-pink-100 { + border-color: #fff5f7; + } + + .xl\:border-pink-200 { + border-color: #fed7e2; + } + + .xl\:border-pink-300 { + border-color: #fbb6ce; + } + + .xl\:border-pink-400 { + border-color: #f687b3; + } + + .xl\:border-pink-500 { + border-color: #ed64a6; + } + + .xl\:border-pink-600 { + border-color: #d53f8c; + } + + .xl\:border-pink-700 { + border-color: #b83280; + } + + .xl\:border-pink-800 { + border-color: #97266d; + } + + .xl\:border-pink-900 { + border-color: #702459; + } + + .xl\:hover\:border-transparent:hover { + border-color: transparent; + } + + .xl\:hover\:border-black:hover { + border-color: #000; + } + + .xl\:hover\:border-white:hover { + border-color: #fff; + } + + .xl\:hover\:border-gray-100:hover { + border-color: #f7fafc; + } + + .xl\:hover\:border-gray-200:hover { + border-color: #edf2f7; + } + + .xl\:hover\:border-gray-300:hover { + border-color: #e2e8f0; + } + + .xl\:hover\:border-gray-400:hover { + border-color: #cbd5e0; + } + + .xl\:hover\:border-gray-500:hover { + border-color: #a0aec0; + } + + .xl\:hover\:border-gray-600:hover { + border-color: #718096; + } + + .xl\:hover\:border-gray-700:hover { + border-color: #4a5568; + } + + .xl\:hover\:border-gray-800:hover { + border-color: #2d3748; + } + + .xl\:hover\:border-gray-900:hover { + border-color: #1a202c; + } + + .xl\:hover\:border-red-100:hover { + border-color: #fff5f5; + } + + .xl\:hover\:border-red-200:hover { + border-color: #fed7d7; + } + + .xl\:hover\:border-red-300:hover { + border-color: #feb2b2; + } + + .xl\:hover\:border-red-400:hover { + border-color: #fc8181; + } + + .xl\:hover\:border-red-500:hover { + border-color: #f56565; + } + + .xl\:hover\:border-red-600:hover { + border-color: #e53e3e; + } + + .xl\:hover\:border-red-700:hover { + border-color: #c53030; + } + + .xl\:hover\:border-red-800:hover { + border-color: #9b2c2c; + } + + .xl\:hover\:border-red-900:hover { + border-color: #742a2a; + } + + .xl\:hover\:border-orange-100:hover { + border-color: #fffaf0; + } + + .xl\:hover\:border-orange-200:hover { + border-color: #feebc8; + } + + .xl\:hover\:border-orange-300:hover { + border-color: #fbd38d; + } + + .xl\:hover\:border-orange-400:hover { + border-color: #f6ad55; + } + + .xl\:hover\:border-orange-500:hover { + border-color: #ed8936; + } + + .xl\:hover\:border-orange-600:hover { + border-color: #dd6b20; + } + + .xl\:hover\:border-orange-700:hover { + border-color: #c05621; + } + + .xl\:hover\:border-orange-800:hover { + border-color: #9c4221; + } + + .xl\:hover\:border-orange-900:hover { + border-color: #7b341e; + } + + .xl\:hover\:border-yellow-100:hover { + border-color: #fffff0; + } + + .xl\:hover\:border-yellow-200:hover { + border-color: #fefcbf; + } + + .xl\:hover\:border-yellow-300:hover { + border-color: #faf089; + } + + .xl\:hover\:border-yellow-400:hover { + border-color: #f6e05e; + } + + .xl\:hover\:border-yellow-500:hover { + border-color: #ecc94b; + } + + .xl\:hover\:border-yellow-600:hover { + border-color: #d69e2e; + } + + .xl\:hover\:border-yellow-700:hover { + border-color: #b7791f; + } + + .xl\:hover\:border-yellow-800:hover { + border-color: #975a16; + } + + .xl\:hover\:border-yellow-900:hover { + border-color: #744210; + } + + .xl\:hover\:border-green-100:hover { + border-color: #f0fff4; + } + + .xl\:hover\:border-green-200:hover { + border-color: #c6f6d5; + } + + .xl\:hover\:border-green-300:hover { + border-color: #9ae6b4; + } + + .xl\:hover\:border-green-400:hover { + border-color: #68d391; + } + + .xl\:hover\:border-green-500:hover { + border-color: #48bb78; + } + + .xl\:hover\:border-green-600:hover { + border-color: #38a169; + } + + .xl\:hover\:border-green-700:hover { + border-color: #2f855a; + } + + .xl\:hover\:border-green-800:hover { + border-color: #276749; + } + + .xl\:hover\:border-green-900:hover { + border-color: #22543d; + } + + .xl\:hover\:border-teal-100:hover { + border-color: #e6fffa; + } + + .xl\:hover\:border-teal-200:hover { + border-color: #b2f5ea; + } + + .xl\:hover\:border-teal-300:hover { + border-color: #81e6d9; + } + + .xl\:hover\:border-teal-400:hover { + border-color: #4fd1c5; + } + + .xl\:hover\:border-teal-500:hover { + border-color: #38b2ac; + } + + .xl\:hover\:border-teal-600:hover { + border-color: #319795; + } + + .xl\:hover\:border-teal-700:hover { + border-color: #2c7a7b; + } + + .xl\:hover\:border-teal-800:hover { + border-color: #285e61; + } + + .xl\:hover\:border-teal-900:hover { + border-color: #234e52; + } + + .xl\:hover\:border-blue-100:hover { + border-color: #ebf8ff; + } + + .xl\:hover\:border-blue-200:hover { + border-color: #bee3f8; + } + + .xl\:hover\:border-blue-300:hover { + border-color: #90cdf4; + } + + .xl\:hover\:border-blue-400:hover { + border-color: #63b3ed; + } + + .xl\:hover\:border-blue-500:hover { + border-color: #4299e1; + } + + .xl\:hover\:border-blue-600:hover { + border-color: #3182ce; + } + + .xl\:hover\:border-blue-700:hover { + border-color: #2b6cb0; + } + + .xl\:hover\:border-blue-800:hover { + border-color: #2c5282; + } + + .xl\:hover\:border-blue-900:hover { + border-color: #2a4365; + } + + .xl\:hover\:border-indigo-100:hover { + border-color: #ebf4ff; + } + + .xl\:hover\:border-indigo-200:hover { + border-color: #c3dafe; + } + + .xl\:hover\:border-indigo-300:hover { + border-color: #a3bffa; + } + + .xl\:hover\:border-indigo-400:hover { + border-color: #7f9cf5; + } + + .xl\:hover\:border-indigo-500:hover { + border-color: #667eea; + } + + .xl\:hover\:border-indigo-600:hover { + border-color: #5a67d8; + } + + .xl\:hover\:border-indigo-700:hover { + border-color: #4c51bf; + } + + .xl\:hover\:border-indigo-800:hover { + border-color: #434190; + } + + .xl\:hover\:border-indigo-900:hover { + border-color: #3c366b; + } + + .xl\:hover\:border-purple-100:hover { + border-color: #faf5ff; + } + + .xl\:hover\:border-purple-200:hover { + border-color: #e9d8fd; + } + + .xl\:hover\:border-purple-300:hover { + border-color: #d6bcfa; + } + + .xl\:hover\:border-purple-400:hover { + border-color: #b794f4; + } + + .xl\:hover\:border-purple-500:hover { + border-color: #9f7aea; + } + + .xl\:hover\:border-purple-600:hover { + border-color: #805ad5; + } + + .xl\:hover\:border-purple-700:hover { + border-color: #6b46c1; + } + + .xl\:hover\:border-purple-800:hover { + border-color: #553c9a; + } + + .xl\:hover\:border-purple-900:hover { + border-color: #44337a; + } + + .xl\:hover\:border-pink-100:hover { + border-color: #fff5f7; + } + + .xl\:hover\:border-pink-200:hover { + border-color: #fed7e2; + } + + .xl\:hover\:border-pink-300:hover { + border-color: #fbb6ce; + } + + .xl\:hover\:border-pink-400:hover { + border-color: #f687b3; + } + + .xl\:hover\:border-pink-500:hover { + border-color: #ed64a6; + } + + .xl\:hover\:border-pink-600:hover { + border-color: #d53f8c; + } + + .xl\:hover\:border-pink-700:hover { + border-color: #b83280; + } + + .xl\:hover\:border-pink-800:hover { + border-color: #97266d; + } + + .xl\:hover\:border-pink-900:hover { + border-color: #702459; + } + + .xl\:focus\:border-transparent:focus { + border-color: transparent; + } + + .xl\:focus\:border-black:focus { + border-color: #000; + } + + .xl\:focus\:border-white:focus { + border-color: #fff; + } + + .xl\:focus\:border-gray-100:focus { + border-color: #f7fafc; + } + + .xl\:focus\:border-gray-200:focus { + border-color: #edf2f7; + } + + .xl\:focus\:border-gray-300:focus { + border-color: #e2e8f0; + } + + .xl\:focus\:border-gray-400:focus { + border-color: #cbd5e0; + } + + .xl\:focus\:border-gray-500:focus { + border-color: #a0aec0; + } + + .xl\:focus\:border-gray-600:focus { + border-color: #718096; + } + + .xl\:focus\:border-gray-700:focus { + border-color: #4a5568; + } + + .xl\:focus\:border-gray-800:focus { + border-color: #2d3748; + } + + .xl\:focus\:border-gray-900:focus { + border-color: #1a202c; + } + + .xl\:focus\:border-red-100:focus { + border-color: #fff5f5; + } + + .xl\:focus\:border-red-200:focus { + border-color: #fed7d7; + } + + .xl\:focus\:border-red-300:focus { + border-color: #feb2b2; + } + + .xl\:focus\:border-red-400:focus { + border-color: #fc8181; + } + + .xl\:focus\:border-red-500:focus { + border-color: #f56565; + } + + .xl\:focus\:border-red-600:focus { + border-color: #e53e3e; + } + + .xl\:focus\:border-red-700:focus { + border-color: #c53030; + } + + .xl\:focus\:border-red-800:focus { + border-color: #9b2c2c; + } + + .xl\:focus\:border-red-900:focus { + border-color: #742a2a; + } + + .xl\:focus\:border-orange-100:focus { + border-color: #fffaf0; + } + + .xl\:focus\:border-orange-200:focus { + border-color: #feebc8; + } + + .xl\:focus\:border-orange-300:focus { + border-color: #fbd38d; + } + + .xl\:focus\:border-orange-400:focus { + border-color: #f6ad55; + } + + .xl\:focus\:border-orange-500:focus { + border-color: #ed8936; + } + + .xl\:focus\:border-orange-600:focus { + border-color: #dd6b20; + } + + .xl\:focus\:border-orange-700:focus { + border-color: #c05621; + } + + .xl\:focus\:border-orange-800:focus { + border-color: #9c4221; + } + + .xl\:focus\:border-orange-900:focus { + border-color: #7b341e; + } + + .xl\:focus\:border-yellow-100:focus { + border-color: #fffff0; + } + + .xl\:focus\:border-yellow-200:focus { + border-color: #fefcbf; + } + + .xl\:focus\:border-yellow-300:focus { + border-color: #faf089; + } + + .xl\:focus\:border-yellow-400:focus { + border-color: #f6e05e; + } + + .xl\:focus\:border-yellow-500:focus { + border-color: #ecc94b; + } + + .xl\:focus\:border-yellow-600:focus { + border-color: #d69e2e; + } + + .xl\:focus\:border-yellow-700:focus { + border-color: #b7791f; + } + + .xl\:focus\:border-yellow-800:focus { + border-color: #975a16; + } + + .xl\:focus\:border-yellow-900:focus { + border-color: #744210; + } + + .xl\:focus\:border-green-100:focus { + border-color: #f0fff4; + } + + .xl\:focus\:border-green-200:focus { + border-color: #c6f6d5; + } + + .xl\:focus\:border-green-300:focus { + border-color: #9ae6b4; + } + + .xl\:focus\:border-green-400:focus { + border-color: #68d391; + } + + .xl\:focus\:border-green-500:focus { + border-color: #48bb78; + } + + .xl\:focus\:border-green-600:focus { + border-color: #38a169; + } + + .xl\:focus\:border-green-700:focus { + border-color: #2f855a; + } + + .xl\:focus\:border-green-800:focus { + border-color: #276749; + } + + .xl\:focus\:border-green-900:focus { + border-color: #22543d; + } + + .xl\:focus\:border-teal-100:focus { + border-color: #e6fffa; + } + + .xl\:focus\:border-teal-200:focus { + border-color: #b2f5ea; + } + + .xl\:focus\:border-teal-300:focus { + border-color: #81e6d9; + } + + .xl\:focus\:border-teal-400:focus { + border-color: #4fd1c5; + } + + .xl\:focus\:border-teal-500:focus { + border-color: #38b2ac; + } + + .xl\:focus\:border-teal-600:focus { + border-color: #319795; + } + + .xl\:focus\:border-teal-700:focus { + border-color: #2c7a7b; + } + + .xl\:focus\:border-teal-800:focus { + border-color: #285e61; + } + + .xl\:focus\:border-teal-900:focus { + border-color: #234e52; + } + + .xl\:focus\:border-blue-100:focus { + border-color: #ebf8ff; + } + + .xl\:focus\:border-blue-200:focus { + border-color: #bee3f8; + } + + .xl\:focus\:border-blue-300:focus { + border-color: #90cdf4; + } + + .xl\:focus\:border-blue-400:focus { + border-color: #63b3ed; + } + + .xl\:focus\:border-blue-500:focus { + border-color: #4299e1; + } + + .xl\:focus\:border-blue-600:focus { + border-color: #3182ce; + } + + .xl\:focus\:border-blue-700:focus { + border-color: #2b6cb0; + } + + .xl\:focus\:border-blue-800:focus { + border-color: #2c5282; + } + + .xl\:focus\:border-blue-900:focus { + border-color: #2a4365; + } + + .xl\:focus\:border-indigo-100:focus { + border-color: #ebf4ff; + } + + .xl\:focus\:border-indigo-200:focus { + border-color: #c3dafe; + } + + .xl\:focus\:border-indigo-300:focus { + border-color: #a3bffa; + } + + .xl\:focus\:border-indigo-400:focus { + border-color: #7f9cf5; + } + + .xl\:focus\:border-indigo-500:focus { + border-color: #667eea; + } + + .xl\:focus\:border-indigo-600:focus { + border-color: #5a67d8; + } + + .xl\:focus\:border-indigo-700:focus { + border-color: #4c51bf; + } + + .xl\:focus\:border-indigo-800:focus { + border-color: #434190; + } + + .xl\:focus\:border-indigo-900:focus { + border-color: #3c366b; + } + + .xl\:focus\:border-purple-100:focus { + border-color: #faf5ff; + } + + .xl\:focus\:border-purple-200:focus { + border-color: #e9d8fd; + } + + .xl\:focus\:border-purple-300:focus { + border-color: #d6bcfa; + } + + .xl\:focus\:border-purple-400:focus { + border-color: #b794f4; + } + + .xl\:focus\:border-purple-500:focus { + border-color: #9f7aea; + } + + .xl\:focus\:border-purple-600:focus { + border-color: #805ad5; + } + + .xl\:focus\:border-purple-700:focus { + border-color: #6b46c1; + } + + .xl\:focus\:border-purple-800:focus { + border-color: #553c9a; + } + + .xl\:focus\:border-purple-900:focus { + border-color: #44337a; + } + + .xl\:focus\:border-pink-100:focus { + border-color: #fff5f7; + } + + .xl\:focus\:border-pink-200:focus { + border-color: #fed7e2; + } + + .xl\:focus\:border-pink-300:focus { + border-color: #fbb6ce; + } + + .xl\:focus\:border-pink-400:focus { + border-color: #f687b3; + } + + .xl\:focus\:border-pink-500:focus { + border-color: #ed64a6; + } + + .xl\:focus\:border-pink-600:focus { + border-color: #d53f8c; + } + + .xl\:focus\:border-pink-700:focus { + border-color: #b83280; + } + + .xl\:focus\:border-pink-800:focus { + border-color: #97266d; + } + + .xl\:focus\:border-pink-900:focus { + border-color: #702459; + } + + .xl\:rounded-none { + border-radius: 0; + } + + .xl\:rounded-sm { + border-radius: 0.125rem; + } + + .xl\:rounded { + border-radius: 0.25rem; + } + + .xl\:rounded-md { + border-radius: 0.375rem; + } + + .xl\:rounded-lg { + border-radius: 0.5rem; + } + + .xl\:rounded-full { + border-radius: 9999px; + } + + .xl\:rounded-t-none { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + + .xl\:rounded-r-none { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .xl\:rounded-b-none { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } + + .xl\:rounded-l-none { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + + .xl\:rounded-t-sm { + border-top-left-radius: 0.125rem; + border-top-right-radius: 0.125rem; + } + + .xl\:rounded-r-sm { + border-top-right-radius: 0.125rem; + border-bottom-right-radius: 0.125rem; + } + + .xl\:rounded-b-sm { + border-bottom-right-radius: 0.125rem; + border-bottom-left-radius: 0.125rem; + } + + .xl\:rounded-l-sm { + border-top-left-radius: 0.125rem; + border-bottom-left-radius: 0.125rem; + } + + .xl\:rounded-t { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; + } + + .xl\:rounded-r { + border-top-right-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; + } + + .xl\:rounded-b { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + } + + .xl\:rounded-l { + border-top-left-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + } + + .xl\:rounded-t-md { + border-top-left-radius: 0.375rem; + border-top-right-radius: 0.375rem; + } + + .xl\:rounded-r-md { + border-top-right-radius: 0.375rem; + border-bottom-right-radius: 0.375rem; + } + + .xl\:rounded-b-md { + border-bottom-right-radius: 0.375rem; + border-bottom-left-radius: 0.375rem; + } + + .xl\:rounded-l-md { + border-top-left-radius: 0.375rem; + border-bottom-left-radius: 0.375rem; + } + + .xl\:rounded-t-lg { + border-top-left-radius: 0.5rem; + border-top-right-radius: 0.5rem; + } + + .xl\:rounded-r-lg { + border-top-right-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; + } + + .xl\:rounded-b-lg { + border-bottom-right-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; + } + + .xl\:rounded-l-lg { + border-top-left-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; + } + + .xl\:rounded-t-full { + border-top-left-radius: 9999px; + border-top-right-radius: 9999px; + } + + .xl\:rounded-r-full { + border-top-right-radius: 9999px; + border-bottom-right-radius: 9999px; + } + + .xl\:rounded-b-full { + border-bottom-right-radius: 9999px; + border-bottom-left-radius: 9999px; + } + + .xl\:rounded-l-full { + border-top-left-radius: 9999px; + border-bottom-left-radius: 9999px; + } + + .xl\:rounded-tl-none { + border-top-left-radius: 0; + } + + .xl\:rounded-tr-none { + border-top-right-radius: 0; + } + + .xl\:rounded-br-none { + border-bottom-right-radius: 0; + } + + .xl\:rounded-bl-none { + border-bottom-left-radius: 0; + } + + .xl\:rounded-tl-sm { + border-top-left-radius: 0.125rem; + } + + .xl\:rounded-tr-sm { + border-top-right-radius: 0.125rem; + } + + .xl\:rounded-br-sm { + border-bottom-right-radius: 0.125rem; + } + + .xl\:rounded-bl-sm { + border-bottom-left-radius: 0.125rem; + } + + .xl\:rounded-tl { + border-top-left-radius: 0.25rem; + } + + .xl\:rounded-tr { + border-top-right-radius: 0.25rem; + } + + .xl\:rounded-br { + border-bottom-right-radius: 0.25rem; + } + + .xl\:rounded-bl { + border-bottom-left-radius: 0.25rem; + } + + .xl\:rounded-tl-md { + border-top-left-radius: 0.375rem; + } + + .xl\:rounded-tr-md { + border-top-right-radius: 0.375rem; + } + + .xl\:rounded-br-md { + border-bottom-right-radius: 0.375rem; + } + + .xl\:rounded-bl-md { + border-bottom-left-radius: 0.375rem; + } + + .xl\:rounded-tl-lg { + border-top-left-radius: 0.5rem; + } + + .xl\:rounded-tr-lg { + border-top-right-radius: 0.5rem; + } + + .xl\:rounded-br-lg { + border-bottom-right-radius: 0.5rem; + } + + .xl\:rounded-bl-lg { + border-bottom-left-radius: 0.5rem; + } + + .xl\:rounded-tl-full { + border-top-left-radius: 9999px; + } + + .xl\:rounded-tr-full { + border-top-right-radius: 9999px; + } + + .xl\:rounded-br-full { + border-bottom-right-radius: 9999px; + } + + .xl\:rounded-bl-full { + border-bottom-left-radius: 9999px; + } + + .xl\:border-solid { + border-style: solid; + } + + .xl\:border-dashed { + border-style: dashed; + } + + .xl\:border-dotted { + border-style: dotted; + } + + .xl\:border-double { + border-style: double; + } + + .xl\:border-none { + border-style: none; + } + + .xl\:border-0 { + border-width: 0; + } + + .xl\:border-2 { + border-width: 2px; + } + + .xl\:border-4 { + border-width: 4px; + } + + .xl\:border-8 { + border-width: 8px; + } + + .xl\:border { + border-width: 1px; + } + + .xl\:border-t-0 { + border-top-width: 0; + } + + .xl\:border-r-0 { + border-right-width: 0; + } + + .xl\:border-b-0 { + border-bottom-width: 0; + } + + .xl\:border-l-0 { + border-left-width: 0; + } + + .xl\:border-t-2 { + border-top-width: 2px; + } + + .xl\:border-r-2 { + border-right-width: 2px; + } + + .xl\:border-b-2 { + border-bottom-width: 2px; + } + + .xl\:border-l-2 { + border-left-width: 2px; + } + + .xl\:border-t-4 { + border-top-width: 4px; + } + + .xl\:border-r-4 { + border-right-width: 4px; + } + + .xl\:border-b-4 { + border-bottom-width: 4px; + } + + .xl\:border-l-4 { + border-left-width: 4px; + } + + .xl\:border-t-8 { + border-top-width: 8px; + } + + .xl\:border-r-8 { + border-right-width: 8px; + } + + .xl\:border-b-8 { + border-bottom-width: 8px; + } + + .xl\:border-l-8 { + border-left-width: 8px; + } + + .xl\:border-t { + border-top-width: 1px; + } + + .xl\:border-r { + border-right-width: 1px; + } + + .xl\:border-b { + border-bottom-width: 1px; + } + + .xl\:border-l { + border-left-width: 1px; + } + + .xl\:box-border { + box-sizing: border-box; + } + + .xl\:box-content { + box-sizing: content-box; + } + + .xl\:cursor-auto { + cursor: auto; + } + + .xl\:cursor-default { + cursor: default; + } + + .xl\:cursor-pointer { + cursor: pointer; + } + + .xl\:cursor-wait { + cursor: wait; + } + + .xl\:cursor-text { + cursor: text; + } + + .xl\:cursor-move { + cursor: move; + } + + .xl\:cursor-not-allowed { + cursor: not-allowed; + } + + .xl\:block { + display: block; + } + + .xl\:inline-block { + display: inline-block; + } + + .xl\:inline { + display: inline; + } + + .xl\:flex { + display: flex; + } + + .xl\:inline-flex { + display: inline-flex; + } + + .xl\:grid { + display: grid; + } + + .xl\:table { + display: table; + } + + .xl\:table-caption { + display: table-caption; + } + + .xl\:table-cell { + display: table-cell; + } + + .xl\:table-column { + display: table-column; + } + + .xl\:table-column-group { + display: table-column-group; + } + + .xl\:table-footer-group { + display: table-footer-group; + } + + .xl\:table-header-group { + display: table-header-group; + } + + .xl\:table-row-group { + display: table-row-group; + } + + .xl\:table-row { + display: table-row; + } + + .xl\:hidden { + display: none; + } + + .xl\:flex-row { + flex-direction: row; + } + + .xl\:flex-row-reverse { + flex-direction: row-reverse; + } + + .xl\:flex-col { + flex-direction: column; + } + + .xl\:flex-col-reverse { + flex-direction: column-reverse; + } + + .xl\:flex-wrap { + flex-wrap: wrap; + } + + .xl\:flex-wrap-reverse { + flex-wrap: wrap-reverse; + } + + .xl\:flex-no-wrap { + flex-wrap: nowrap; + } + + .xl\:items-start { + align-items: flex-start; + } + + .xl\:items-end { + align-items: flex-end; + } + + .xl\:items-center { + align-items: center; + } + + .xl\:items-baseline { + align-items: baseline; + } + + .xl\:items-stretch { + align-items: stretch; + } + + .xl\:self-auto { + align-self: auto; + } + + .xl\:self-start { + align-self: flex-start; + } + + .xl\:self-end { + align-self: flex-end; + } + + .xl\:self-center { + align-self: center; + } + + .xl\:self-stretch { + align-self: stretch; + } + + .xl\:justify-start { + justify-content: flex-start; + } + + .xl\:justify-end { + justify-content: flex-end; + } + + .xl\:justify-center { + justify-content: center; + } + + .xl\:justify-between { + justify-content: space-between; + } + + .xl\:justify-around { + justify-content: space-around; + } + + .xl\:justify-evenly { + justify-content: space-evenly; + } + + .xl\:content-center { + align-content: center; + } + + .xl\:content-start { + align-content: flex-start; + } + + .xl\:content-end { + align-content: flex-end; + } + + .xl\:content-between { + align-content: space-between; + } + + .xl\:content-around { + align-content: space-around; + } + + .xl\:flex-1 { + flex: 1 1 0%; + } + + .xl\:flex-auto { + flex: 1 1 auto; + } + + .xl\:flex-initial { + flex: 0 1 auto; + } + + .xl\:flex-none { + flex: none; + } + + .xl\:flex-grow-0 { + flex-grow: 0; + } + + .xl\:flex-grow { + flex-grow: 1; + } + + .xl\:flex-shrink-0 { + flex-shrink: 0; + } + + .xl\:flex-shrink { + flex-shrink: 1; + } + + .xl\:order-1 { + order: 1; + } + + .xl\:order-2 { + order: 2; + } + + .xl\:order-3 { + order: 3; + } + + .xl\:order-4 { + order: 4; + } + + .xl\:order-5 { + order: 5; + } + + .xl\:order-6 { + order: 6; + } + + .xl\:order-7 { + order: 7; + } + + .xl\:order-8 { + order: 8; + } + + .xl\:order-9 { + order: 9; + } + + .xl\:order-10 { + order: 10; + } + + .xl\:order-11 { + order: 11; + } + + .xl\:order-12 { + order: 12; + } + + .xl\:order-first { + order: -9999; + } + + .xl\:order-last { + order: 9999; + } + + .xl\:order-none { + order: 0; + } + + .xl\:float-right { + float: right; + } + + .xl\:float-left { + float: left; + } + + .xl\:float-none { + float: none; + } + + .xl\:clearfix:after { + content: ""; + display: table; + clear: both; + } + + .xl\:clear-left { + clear: left; + } + + .xl\:clear-right { + clear: right; + } + + .xl\:clear-both { + clear: both; + } + + .xl\:font-sans { + font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + } + + .xl\:font-serif { + font-family: Georgia, Cambria, "Times New Roman", Times, serif; + } + + .xl\:font-mono { + font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + } + + .xl\:font-hairline { + font-weight: 100; + } + + .xl\:font-thin { + font-weight: 200; + } + + .xl\:font-light { + font-weight: 300; + } + + .xl\:font-normal { + font-weight: 400; + } + + .xl\:font-medium { + font-weight: 500; + } + + .xl\:font-semibold { + font-weight: 600; + } + + .xl\:font-bold { + font-weight: 700; + } + + .xl\:font-extrabold { + font-weight: 800; + } + + .xl\:font-black { + font-weight: 900; + } + + .xl\:hover\:font-hairline:hover { + font-weight: 100; + } + + .xl\:hover\:font-thin:hover { + font-weight: 200; + } + + .xl\:hover\:font-light:hover { + font-weight: 300; + } + + .xl\:hover\:font-normal:hover { + font-weight: 400; + } + + .xl\:hover\:font-medium:hover { + font-weight: 500; + } + + .xl\:hover\:font-semibold:hover { + font-weight: 600; + } + + .xl\:hover\:font-bold:hover { + font-weight: 700; + } + + .xl\:hover\:font-extrabold:hover { + font-weight: 800; + } + + .xl\:hover\:font-black:hover { + font-weight: 900; + } + + .xl\:focus\:font-hairline:focus { + font-weight: 100; + } + + .xl\:focus\:font-thin:focus { + font-weight: 200; + } + + .xl\:focus\:font-light:focus { + font-weight: 300; + } + + .xl\:focus\:font-normal:focus { + font-weight: 400; + } + + .xl\:focus\:font-medium:focus { + font-weight: 500; + } + + .xl\:focus\:font-semibold:focus { + font-weight: 600; + } + + .xl\:focus\:font-bold:focus { + font-weight: 700; + } + + .xl\:focus\:font-extrabold:focus { + font-weight: 800; + } + + .xl\:focus\:font-black:focus { + font-weight: 900; + } + + .xl\:h-0 { + height: 0; + } + + .xl\:h-1 { + height: 0.25rem; + } + + .xl\:h-2 { + height: 0.5rem; + } + + .xl\:h-3 { + height: 0.75rem; + } + + .xl\:h-4 { + height: 1rem; + } + + .xl\:h-5 { + height: 1.25rem; + } + + .xl\:h-6 { + height: 1.5rem; + } + + .xl\:h-8 { + height: 2rem; + } + + .xl\:h-10 { + height: 2.5rem; + } + + .xl\:h-12 { + height: 3rem; + } + + .xl\:h-16 { + height: 4rem; + } + + .xl\:h-20 { + height: 5rem; + } + + .xl\:h-24 { + height: 6rem; + } + + .xl\:h-32 { + height: 8rem; + } + + .xl\:h-40 { + height: 10rem; + } + + .xl\:h-48 { + height: 12rem; + } + + .xl\:h-56 { + height: 14rem; + } + + .xl\:h-64 { + height: 16rem; + } + + .xl\:h-auto { + height: auto; + } + + .xl\:h-px { + height: 1px; + } + + .xl\:h-full { + height: 100%; + } + + .xl\:h-screen { + height: 100vh; + } + + .xl\:leading-3 { + line-height: .75rem; + } + + .xl\:leading-4 { + line-height: 1rem; + } + + .xl\:leading-5 { + line-height: 1.25rem; + } + + .xl\:leading-6 { + line-height: 1.5rem; + } + + .xl\:leading-7 { + line-height: 1.75rem; + } + + .xl\:leading-8 { + line-height: 2rem; + } + + .xl\:leading-9 { + line-height: 2.25rem; + } + + .xl\:leading-10 { + line-height: 2.5rem; + } + + .xl\:leading-none { + line-height: 1; + } + + .xl\:leading-tight { + line-height: 1.25; + } + + .xl\:leading-snug { + line-height: 1.375; + } + + .xl\:leading-normal { + line-height: 1.5; + } + + .xl\:leading-relaxed { + line-height: 1.625; + } + + .xl\:leading-loose { + line-height: 2; + } + + .xl\:list-inside { + list-style-position: inside; + } + + .xl\:list-outside { + list-style-position: outside; + } + + .xl\:list-none { + list-style-type: none; + } + + .xl\:list-disc { + list-style-type: disc; + } + + .xl\:list-decimal { + list-style-type: decimal; + } + + .xl\:m-0 { + margin: 0; + } + + .xl\:m-1 { + margin: 0.25rem; + } + + .xl\:m-2 { + margin: 0.5rem; + } + + .xl\:m-3 { + margin: 0.75rem; + } + + .xl\:m-4 { + margin: 1rem; + } + + .xl\:m-5 { + margin: 1.25rem; + } + + .xl\:m-6 { + margin: 1.5rem; + } + + .xl\:m-8 { + margin: 2rem; + } + + .xl\:m-10 { + margin: 2.5rem; + } + + .xl\:m-12 { + margin: 3rem; + } + + .xl\:m-16 { + margin: 4rem; + } + + .xl\:m-20 { + margin: 5rem; + } + + .xl\:m-24 { + margin: 6rem; + } + + .xl\:m-32 { + margin: 8rem; + } + + .xl\:m-40 { + margin: 10rem; + } + + .xl\:m-48 { + margin: 12rem; + } + + .xl\:m-56 { + margin: 14rem; + } + + .xl\:m-64 { + margin: 16rem; + } + + .xl\:m-auto { + margin: auto; + } + + .xl\:m-px { + margin: 1px; + } + + .xl\:-m-1 { + margin: -0.25rem; + } + + .xl\:-m-2 { + margin: -0.5rem; + } + + .xl\:-m-3 { + margin: -0.75rem; + } + + .xl\:-m-4 { + margin: -1rem; + } + + .xl\:-m-5 { + margin: -1.25rem; + } + + .xl\:-m-6 { + margin: -1.5rem; + } + + .xl\:-m-8 { + margin: -2rem; + } + + .xl\:-m-10 { + margin: -2.5rem; + } + + .xl\:-m-12 { + margin: -3rem; + } + + .xl\:-m-16 { + margin: -4rem; + } + + .xl\:-m-20 { + margin: -5rem; + } + + .xl\:-m-24 { + margin: -6rem; + } + + .xl\:-m-32 { + margin: -8rem; + } + + .xl\:-m-40 { + margin: -10rem; + } + + .xl\:-m-48 { + margin: -12rem; + } + + .xl\:-m-56 { + margin: -14rem; + } + + .xl\:-m-64 { + margin: -16rem; + } + + .xl\:-m-px { + margin: -1px; + } + + .xl\:my-0 { + margin-top: 0; + margin-bottom: 0; + } + + .xl\:mx-0 { + margin-left: 0; + margin-right: 0; + } + + .xl\:my-1 { + margin-top: 0.25rem; + margin-bottom: 0.25rem; + } + + .xl\:mx-1 { + margin-left: 0.25rem; + margin-right: 0.25rem; + } + + .xl\:my-2 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; + } + + .xl\:mx-2 { + margin-left: 0.5rem; + margin-right: 0.5rem; + } + + .xl\:my-3 { + margin-top: 0.75rem; + margin-bottom: 0.75rem; + } + + .xl\:mx-3 { + margin-left: 0.75rem; + margin-right: 0.75rem; + } + + .xl\:my-4 { + margin-top: 1rem; + margin-bottom: 1rem; + } + + .xl\:mx-4 { + margin-left: 1rem; + margin-right: 1rem; + } + + .xl\:my-5 { + margin-top: 1.25rem; + margin-bottom: 1.25rem; + } + + .xl\:mx-5 { + margin-left: 1.25rem; + margin-right: 1.25rem; + } + + .xl\:my-6 { + margin-top: 1.5rem; + margin-bottom: 1.5rem; + } + + .xl\:mx-6 { + margin-left: 1.5rem; + margin-right: 1.5rem; + } + + .xl\:my-8 { + margin-top: 2rem; + margin-bottom: 2rem; + } + + .xl\:mx-8 { + margin-left: 2rem; + margin-right: 2rem; + } + + .xl\:my-10 { + margin-top: 2.5rem; + margin-bottom: 2.5rem; + } + + .xl\:mx-10 { + margin-left: 2.5rem; + margin-right: 2.5rem; + } + + .xl\:my-12 { + margin-top: 3rem; + margin-bottom: 3rem; + } + + .xl\:mx-12 { + margin-left: 3rem; + margin-right: 3rem; + } + + .xl\:my-16 { + margin-top: 4rem; + margin-bottom: 4rem; + } + + .xl\:mx-16 { + margin-left: 4rem; + margin-right: 4rem; + } + + .xl\:my-20 { + margin-top: 5rem; + margin-bottom: 5rem; + } + + .xl\:mx-20 { + margin-left: 5rem; + margin-right: 5rem; + } + + .xl\:my-24 { + margin-top: 6rem; + margin-bottom: 6rem; + } + + .xl\:mx-24 { + margin-left: 6rem; + margin-right: 6rem; + } + + .xl\:my-32 { + margin-top: 8rem; + margin-bottom: 8rem; + } + + .xl\:mx-32 { + margin-left: 8rem; + margin-right: 8rem; + } + + .xl\:my-40 { + margin-top: 10rem; + margin-bottom: 10rem; + } + + .xl\:mx-40 { + margin-left: 10rem; + margin-right: 10rem; + } + + .xl\:my-48 { + margin-top: 12rem; + margin-bottom: 12rem; + } + + .xl\:mx-48 { + margin-left: 12rem; + margin-right: 12rem; + } + + .xl\:my-56 { + margin-top: 14rem; + margin-bottom: 14rem; + } + + .xl\:mx-56 { + margin-left: 14rem; + margin-right: 14rem; + } + + .xl\:my-64 { + margin-top: 16rem; + margin-bottom: 16rem; + } + + .xl\:mx-64 { + margin-left: 16rem; + margin-right: 16rem; + } + + .xl\:my-auto { + margin-top: auto; + margin-bottom: auto; + } + + .xl\:mx-auto { + margin-left: auto; + margin-right: auto; + } + + .xl\:my-px { + margin-top: 1px; + margin-bottom: 1px; + } + + .xl\:mx-px { + margin-left: 1px; + margin-right: 1px; + } + + .xl\:-my-1 { + margin-top: -0.25rem; + margin-bottom: -0.25rem; + } + + .xl\:-mx-1 { + margin-left: -0.25rem; + margin-right: -0.25rem; + } + + .xl\:-my-2 { + margin-top: -0.5rem; + margin-bottom: -0.5rem; + } + + .xl\:-mx-2 { + margin-left: -0.5rem; + margin-right: -0.5rem; + } + + .xl\:-my-3 { + margin-top: -0.75rem; + margin-bottom: -0.75rem; + } + + .xl\:-mx-3 { + margin-left: -0.75rem; + margin-right: -0.75rem; + } + + .xl\:-my-4 { + margin-top: -1rem; + margin-bottom: -1rem; + } + + .xl\:-mx-4 { + margin-left: -1rem; + margin-right: -1rem; + } + + .xl\:-my-5 { + margin-top: -1.25rem; + margin-bottom: -1.25rem; + } + + .xl\:-mx-5 { + margin-left: -1.25rem; + margin-right: -1.25rem; + } + + .xl\:-my-6 { + margin-top: -1.5rem; + margin-bottom: -1.5rem; + } + + .xl\:-mx-6 { + margin-left: -1.5rem; + margin-right: -1.5rem; + } + + .xl\:-my-8 { + margin-top: -2rem; + margin-bottom: -2rem; + } + + .xl\:-mx-8 { + margin-left: -2rem; + margin-right: -2rem; + } + + .xl\:-my-10 { + margin-top: -2.5rem; + margin-bottom: -2.5rem; + } + + .xl\:-mx-10 { + margin-left: -2.5rem; + margin-right: -2.5rem; + } + + .xl\:-my-12 { + margin-top: -3rem; + margin-bottom: -3rem; + } + + .xl\:-mx-12 { + margin-left: -3rem; + margin-right: -3rem; + } + + .xl\:-my-16 { + margin-top: -4rem; + margin-bottom: -4rem; + } + + .xl\:-mx-16 { + margin-left: -4rem; + margin-right: -4rem; + } + + .xl\:-my-20 { + margin-top: -5rem; + margin-bottom: -5rem; + } + + .xl\:-mx-20 { + margin-left: -5rem; + margin-right: -5rem; + } + + .xl\:-my-24 { + margin-top: -6rem; + margin-bottom: -6rem; + } + + .xl\:-mx-24 { + margin-left: -6rem; + margin-right: -6rem; + } + + .xl\:-my-32 { + margin-top: -8rem; + margin-bottom: -8rem; + } + + .xl\:-mx-32 { + margin-left: -8rem; + margin-right: -8rem; + } + + .xl\:-my-40 { + margin-top: -10rem; + margin-bottom: -10rem; + } + + .xl\:-mx-40 { + margin-left: -10rem; + margin-right: -10rem; + } + + .xl\:-my-48 { + margin-top: -12rem; + margin-bottom: -12rem; + } + + .xl\:-mx-48 { + margin-left: -12rem; + margin-right: -12rem; + } + + .xl\:-my-56 { + margin-top: -14rem; + margin-bottom: -14rem; + } + + .xl\:-mx-56 { + margin-left: -14rem; + margin-right: -14rem; + } + + .xl\:-my-64 { + margin-top: -16rem; + margin-bottom: -16rem; + } + + .xl\:-mx-64 { + margin-left: -16rem; + margin-right: -16rem; + } + + .xl\:-my-px { + margin-top: -1px; + margin-bottom: -1px; + } + + .xl\:-mx-px { + margin-left: -1px; + margin-right: -1px; + } + + .xl\:mt-0 { + margin-top: 0; + } + + .xl\:mr-0 { + margin-right: 0; + } + + .xl\:mb-0 { + margin-bottom: 0; + } + + .xl\:ml-0 { + margin-left: 0; + } + + .xl\:mt-1 { + margin-top: 0.25rem; + } + + .xl\:mr-1 { + margin-right: 0.25rem; + } + + .xl\:mb-1 { + margin-bottom: 0.25rem; + } + + .xl\:ml-1 { + margin-left: 0.25rem; + } + + .xl\:mt-2 { + margin-top: 0.5rem; + } + + .xl\:mr-2 { + margin-right: 0.5rem; + } + + .xl\:mb-2 { + margin-bottom: 0.5rem; + } + + .xl\:ml-2 { + margin-left: 0.5rem; + } + + .xl\:mt-3 { + margin-top: 0.75rem; + } + + .xl\:mr-3 { + margin-right: 0.75rem; + } + + .xl\:mb-3 { + margin-bottom: 0.75rem; + } + + .xl\:ml-3 { + margin-left: 0.75rem; + } + + .xl\:mt-4 { + margin-top: 1rem; + } + + .xl\:mr-4 { + margin-right: 1rem; + } + + .xl\:mb-4 { + margin-bottom: 1rem; + } + + .xl\:ml-4 { + margin-left: 1rem; + } + + .xl\:mt-5 { + margin-top: 1.25rem; + } + + .xl\:mr-5 { + margin-right: 1.25rem; + } + + .xl\:mb-5 { + margin-bottom: 1.25rem; + } + + .xl\:ml-5 { + margin-left: 1.25rem; + } + + .xl\:mt-6 { + margin-top: 1.5rem; + } + + .xl\:mr-6 { + margin-right: 1.5rem; + } + + .xl\:mb-6 { + margin-bottom: 1.5rem; + } + + .xl\:ml-6 { + margin-left: 1.5rem; + } + + .xl\:mt-8 { + margin-top: 2rem; + } + + .xl\:mr-8 { + margin-right: 2rem; + } + + .xl\:mb-8 { + margin-bottom: 2rem; + } + + .xl\:ml-8 { + margin-left: 2rem; + } + + .xl\:mt-10 { + margin-top: 2.5rem; + } + + .xl\:mr-10 { + margin-right: 2.5rem; + } + + .xl\:mb-10 { + margin-bottom: 2.5rem; + } + + .xl\:ml-10 { + margin-left: 2.5rem; + } + + .xl\:mt-12 { + margin-top: 3rem; + } + + .xl\:mr-12 { + margin-right: 3rem; + } + + .xl\:mb-12 { + margin-bottom: 3rem; + } + + .xl\:ml-12 { + margin-left: 3rem; + } + + .xl\:mt-16 { + margin-top: 4rem; + } + + .xl\:mr-16 { + margin-right: 4rem; + } + + .xl\:mb-16 { + margin-bottom: 4rem; + } + + .xl\:ml-16 { + margin-left: 4rem; + } + + .xl\:mt-20 { + margin-top: 5rem; + } + + .xl\:mr-20 { + margin-right: 5rem; + } + + .xl\:mb-20 { + margin-bottom: 5rem; + } + + .xl\:ml-20 { + margin-left: 5rem; + } + + .xl\:mt-24 { + margin-top: 6rem; + } + + .xl\:mr-24 { + margin-right: 6rem; + } + + .xl\:mb-24 { + margin-bottom: 6rem; + } + + .xl\:ml-24 { + margin-left: 6rem; + } + + .xl\:mt-32 { + margin-top: 8rem; + } + + .xl\:mr-32 { + margin-right: 8rem; + } + + .xl\:mb-32 { + margin-bottom: 8rem; + } + + .xl\:ml-32 { + margin-left: 8rem; + } + + .xl\:mt-40 { + margin-top: 10rem; + } + + .xl\:mr-40 { + margin-right: 10rem; + } + + .xl\:mb-40 { + margin-bottom: 10rem; + } + + .xl\:ml-40 { + margin-left: 10rem; + } + + .xl\:mt-48 { + margin-top: 12rem; + } + + .xl\:mr-48 { + margin-right: 12rem; + } + + .xl\:mb-48 { + margin-bottom: 12rem; + } + + .xl\:ml-48 { + margin-left: 12rem; + } + + .xl\:mt-56 { + margin-top: 14rem; + } + + .xl\:mr-56 { + margin-right: 14rem; + } + + .xl\:mb-56 { + margin-bottom: 14rem; + } + + .xl\:ml-56 { + margin-left: 14rem; + } + + .xl\:mt-64 { + margin-top: 16rem; + } + + .xl\:mr-64 { + margin-right: 16rem; + } + + .xl\:mb-64 { + margin-bottom: 16rem; + } + + .xl\:ml-64 { + margin-left: 16rem; + } + + .xl\:mt-auto { + margin-top: auto; + } + + .xl\:mr-auto { + margin-right: auto; + } + + .xl\:mb-auto { + margin-bottom: auto; + } + + .xl\:ml-auto { + margin-left: auto; + } + + .xl\:mt-px { + margin-top: 1px; + } + + .xl\:mr-px { + margin-right: 1px; + } + + .xl\:mb-px { + margin-bottom: 1px; + } + + .xl\:ml-px { + margin-left: 1px; + } + + .xl\:-mt-1 { + margin-top: -0.25rem; + } + + .xl\:-mr-1 { + margin-right: -0.25rem; + } + + .xl\:-mb-1 { + margin-bottom: -0.25rem; + } + + .xl\:-ml-1 { + margin-left: -0.25rem; + } + + .xl\:-mt-2 { + margin-top: -0.5rem; + } + + .xl\:-mr-2 { + margin-right: -0.5rem; + } + + .xl\:-mb-2 { + margin-bottom: -0.5rem; + } + + .xl\:-ml-2 { + margin-left: -0.5rem; + } + + .xl\:-mt-3 { + margin-top: -0.75rem; + } + + .xl\:-mr-3 { + margin-right: -0.75rem; + } + + .xl\:-mb-3 { + margin-bottom: -0.75rem; + } + + .xl\:-ml-3 { + margin-left: -0.75rem; + } + + .xl\:-mt-4 { + margin-top: -1rem; + } + + .xl\:-mr-4 { + margin-right: -1rem; + } + + .xl\:-mb-4 { + margin-bottom: -1rem; + } + + .xl\:-ml-4 { + margin-left: -1rem; + } + + .xl\:-mt-5 { + margin-top: -1.25rem; + } + + .xl\:-mr-5 { + margin-right: -1.25rem; + } + + .xl\:-mb-5 { + margin-bottom: -1.25rem; + } + + .xl\:-ml-5 { + margin-left: -1.25rem; + } + + .xl\:-mt-6 { + margin-top: -1.5rem; + } + + .xl\:-mr-6 { + margin-right: -1.5rem; + } + + .xl\:-mb-6 { + margin-bottom: -1.5rem; + } + + .xl\:-ml-6 { + margin-left: -1.5rem; + } + + .xl\:-mt-8 { + margin-top: -2rem; + } + + .xl\:-mr-8 { + margin-right: -2rem; + } + + .xl\:-mb-8 { + margin-bottom: -2rem; + } + + .xl\:-ml-8 { + margin-left: -2rem; + } + + .xl\:-mt-10 { + margin-top: -2.5rem; + } + + .xl\:-mr-10 { + margin-right: -2.5rem; + } + + .xl\:-mb-10 { + margin-bottom: -2.5rem; + } + + .xl\:-ml-10 { + margin-left: -2.5rem; + } + + .xl\:-mt-12 { + margin-top: -3rem; + } + + .xl\:-mr-12 { + margin-right: -3rem; + } + + .xl\:-mb-12 { + margin-bottom: -3rem; + } + + .xl\:-ml-12 { + margin-left: -3rem; + } + + .xl\:-mt-16 { + margin-top: -4rem; + } + + .xl\:-mr-16 { + margin-right: -4rem; + } + + .xl\:-mb-16 { + margin-bottom: -4rem; + } + + .xl\:-ml-16 { + margin-left: -4rem; + } + + .xl\:-mt-20 { + margin-top: -5rem; + } + + .xl\:-mr-20 { + margin-right: -5rem; + } + + .xl\:-mb-20 { + margin-bottom: -5rem; + } + + .xl\:-ml-20 { + margin-left: -5rem; + } + + .xl\:-mt-24 { + margin-top: -6rem; + } + + .xl\:-mr-24 { + margin-right: -6rem; + } + + .xl\:-mb-24 { + margin-bottom: -6rem; + } + + .xl\:-ml-24 { + margin-left: -6rem; + } + + .xl\:-mt-32 { + margin-top: -8rem; + } + + .xl\:-mr-32 { + margin-right: -8rem; + } + + .xl\:-mb-32 { + margin-bottom: -8rem; + } + + .xl\:-ml-32 { + margin-left: -8rem; + } + + .xl\:-mt-40 { + margin-top: -10rem; + } + + .xl\:-mr-40 { + margin-right: -10rem; + } + + .xl\:-mb-40 { + margin-bottom: -10rem; + } + + .xl\:-ml-40 { + margin-left: -10rem; + } + + .xl\:-mt-48 { + margin-top: -12rem; + } + + .xl\:-mr-48 { + margin-right: -12rem; + } + + .xl\:-mb-48 { + margin-bottom: -12rem; + } + + .xl\:-ml-48 { + margin-left: -12rem; + } + + .xl\:-mt-56 { + margin-top: -14rem; + } + + .xl\:-mr-56 { + margin-right: -14rem; + } + + .xl\:-mb-56 { + margin-bottom: -14rem; + } + + .xl\:-ml-56 { + margin-left: -14rem; + } + + .xl\:-mt-64 { + margin-top: -16rem; + } + + .xl\:-mr-64 { + margin-right: -16rem; + } + + .xl\:-mb-64 { + margin-bottom: -16rem; + } + + .xl\:-ml-64 { + margin-left: -16rem; + } + + .xl\:-mt-px { + margin-top: -1px; + } + + .xl\:-mr-px { + margin-right: -1px; + } + + .xl\:-mb-px { + margin-bottom: -1px; + } + + .xl\:-ml-px { + margin-left: -1px; + } + + .xl\:max-h-full { + max-height: 100%; + } + + .xl\:max-h-screen { + max-height: 100vh; + } + + .xl\:max-w-none { + max-width: none; + } + + .xl\:max-w-xs { + max-width: 20rem; + } + + .xl\:max-w-sm { + max-width: 24rem; + } + + .xl\:max-w-md { + max-width: 28rem; + } + + .xl\:max-w-lg { + max-width: 32rem; + } + + .xl\:max-w-xl { + max-width: 36rem; + } + + .xl\:max-w-2xl { + max-width: 42rem; + } + + .xl\:max-w-3xl { + max-width: 48rem; + } + + .xl\:max-w-4xl { + max-width: 56rem; + } + + .xl\:max-w-5xl { + max-width: 64rem; + } + + .xl\:max-w-6xl { + max-width: 72rem; + } + + .xl\:max-w-full { + max-width: 100%; + } + + .xl\:max-w-screen-sm { + max-width: 640px; + } + + .xl\:max-w-screen-md { + max-width: 768px; + } + + .xl\:max-w-screen-lg { + max-width: 1024px; + } + + .xl\:max-w-screen-xl { + max-width: 1280px; + } + + .xl\:min-h-0 { + min-height: 0; + } + + .xl\:min-h-full { + min-height: 100%; + } + + .xl\:min-h-screen { + min-height: 100vh; + } + + .xl\:min-w-0 { + min-width: 0; + } + + .xl\:min-w-full { + min-width: 100%; + } + + .xl\:object-contain { + object-fit: contain; + } + + .xl\:object-cover { + object-fit: cover; + } + + .xl\:object-fill { + object-fit: fill; + } + + .xl\:object-none { + object-fit: none; + } + + .xl\:object-scale-down { + object-fit: scale-down; + } + + .xl\:object-bottom { + object-position: bottom; + } + + .xl\:object-center { + object-position: center; + } + + .xl\:object-left { + object-position: left; + } + + .xl\:object-left-bottom { + object-position: left bottom; + } + + .xl\:object-left-top { + object-position: left top; + } + + .xl\:object-right { + object-position: right; + } + + .xl\:object-right-bottom { + object-position: right bottom; + } + + .xl\:object-right-top { + object-position: right top; + } + + .xl\:object-top { + object-position: top; + } + + .xl\:opacity-0 { + opacity: 0; + } + + .xl\:opacity-25 { + opacity: 0.25; + } + + .xl\:opacity-50 { + opacity: 0.5; + } + + .xl\:opacity-75 { + opacity: 0.75; + } + + .xl\:opacity-100 { + opacity: 1; + } + + .xl\:hover\:opacity-0:hover { + opacity: 0; + } + + .xl\:hover\:opacity-25:hover { + opacity: 0.25; + } + + .xl\:hover\:opacity-50:hover { + opacity: 0.5; + } + + .xl\:hover\:opacity-75:hover { + opacity: 0.75; + } + + .xl\:hover\:opacity-100:hover { + opacity: 1; + } + + .xl\:focus\:opacity-0:focus { + opacity: 0; + } + + .xl\:focus\:opacity-25:focus { + opacity: 0.25; + } + + .xl\:focus\:opacity-50:focus { + opacity: 0.5; + } + + .xl\:focus\:opacity-75:focus { + opacity: 0.75; + } + + .xl\:focus\:opacity-100:focus { + opacity: 1; + } + + .xl\:outline-none { + outline: 0; + } + + .xl\:focus\:outline-none:focus { + outline: 0; + } + + .xl\:overflow-auto { + overflow: auto; + } + + .xl\:overflow-hidden { + overflow: hidden; + } + + .xl\:overflow-visible { + overflow: visible; + } + + .xl\:overflow-scroll { + overflow: scroll; + } + + .xl\:overflow-x-auto { + overflow-x: auto; + } + + .xl\:overflow-y-auto { + overflow-y: auto; + } + + .xl\:overflow-x-hidden { + overflow-x: hidden; + } + + .xl\:overflow-y-hidden { + overflow-y: hidden; + } + + .xl\:overflow-x-visible { + overflow-x: visible; + } + + .xl\:overflow-y-visible { + overflow-y: visible; + } + + .xl\:overflow-x-scroll { + overflow-x: scroll; + } + + .xl\:overflow-y-scroll { + overflow-y: scroll; + } + + .xl\:scrolling-touch { + -webkit-overflow-scrolling: touch; + } + + .xl\:scrolling-auto { + -webkit-overflow-scrolling: auto; + } + + .xl\:p-0 { + padding: 0; + } + + .xl\:p-1 { + padding: 0.25rem; + } + + .xl\:p-2 { + padding: 0.5rem; + } + + .xl\:p-3 { + padding: 0.75rem; + } + + .xl\:p-4 { + padding: 1rem; + } + + .xl\:p-5 { + padding: 1.25rem; + } + + .xl\:p-6 { + padding: 1.5rem; + } + + .xl\:p-8 { + padding: 2rem; + } + + .xl\:p-10 { + padding: 2.5rem; + } + + .xl\:p-12 { + padding: 3rem; + } + + .xl\:p-16 { + padding: 4rem; + } + + .xl\:p-20 { + padding: 5rem; + } + + .xl\:p-24 { + padding: 6rem; + } + + .xl\:p-32 { + padding: 8rem; + } + + .xl\:p-40 { + padding: 10rem; + } + + .xl\:p-48 { + padding: 12rem; + } + + .xl\:p-56 { + padding: 14rem; + } + + .xl\:p-64 { + padding: 16rem; + } + + .xl\:p-px { + padding: 1px; + } + + .xl\:py-0 { + padding-top: 0; + padding-bottom: 0; + } + + .xl\:px-0 { + padding-left: 0; + padding-right: 0; + } + + .xl\:py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + + .xl\:px-1 { + padding-left: 0.25rem; + padding-right: 0.25rem; + } + + .xl\:py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + } + + .xl\:px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; + } + + .xl\:py-3 { + padding-top: 0.75rem; + padding-bottom: 0.75rem; + } + + .xl\:px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; + } + + .xl\:py-4 { + padding-top: 1rem; + padding-bottom: 1rem; + } + + .xl\:px-4 { + padding-left: 1rem; + padding-right: 1rem; + } + + .xl\:py-5 { + padding-top: 1.25rem; + padding-bottom: 1.25rem; + } + + .xl\:px-5 { + padding-left: 1.25rem; + padding-right: 1.25rem; + } + + .xl\:py-6 { + padding-top: 1.5rem; + padding-bottom: 1.5rem; + } + + .xl\:px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; + } + + .xl\:py-8 { + padding-top: 2rem; + padding-bottom: 2rem; + } + + .xl\:px-8 { + padding-left: 2rem; + padding-right: 2rem; + } + + .xl\:py-10 { + padding-top: 2.5rem; + padding-bottom: 2.5rem; + } + + .xl\:px-10 { + padding-left: 2.5rem; + padding-right: 2.5rem; + } + + .xl\:py-12 { + padding-top: 3rem; + padding-bottom: 3rem; + } + + .xl\:px-12 { + padding-left: 3rem; + padding-right: 3rem; + } + + .xl\:py-16 { + padding-top: 4rem; + padding-bottom: 4rem; + } + + .xl\:px-16 { + padding-left: 4rem; + padding-right: 4rem; + } + + .xl\:py-20 { + padding-top: 5rem; + padding-bottom: 5rem; + } + + .xl\:px-20 { + padding-left: 5rem; + padding-right: 5rem; + } + + .xl\:py-24 { + padding-top: 6rem; + padding-bottom: 6rem; + } + + .xl\:px-24 { + padding-left: 6rem; + padding-right: 6rem; + } + + .xl\:py-32 { + padding-top: 8rem; + padding-bottom: 8rem; + } + + .xl\:px-32 { + padding-left: 8rem; + padding-right: 8rem; + } + + .xl\:py-40 { + padding-top: 10rem; + padding-bottom: 10rem; + } + + .xl\:px-40 { + padding-left: 10rem; + padding-right: 10rem; + } + + .xl\:py-48 { + padding-top: 12rem; + padding-bottom: 12rem; + } + + .xl\:px-48 { + padding-left: 12rem; + padding-right: 12rem; + } + + .xl\:py-56 { + padding-top: 14rem; + padding-bottom: 14rem; + } + + .xl\:px-56 { + padding-left: 14rem; + padding-right: 14rem; + } + + .xl\:py-64 { + padding-top: 16rem; + padding-bottom: 16rem; + } + + .xl\:px-64 { + padding-left: 16rem; + padding-right: 16rem; + } + + .xl\:py-px { + padding-top: 1px; + padding-bottom: 1px; + } + + .xl\:px-px { + padding-left: 1px; + padding-right: 1px; + } + + .xl\:pt-0 { + padding-top: 0; + } + + .xl\:pr-0 { + padding-right: 0; + } + + .xl\:pb-0 { + padding-bottom: 0; + } + + .xl\:pl-0 { + padding-left: 0; + } + + .xl\:pt-1 { + padding-top: 0.25rem; + } + + .xl\:pr-1 { + padding-right: 0.25rem; + } + + .xl\:pb-1 { + padding-bottom: 0.25rem; + } + + .xl\:pl-1 { + padding-left: 0.25rem; + } + + .xl\:pt-2 { + padding-top: 0.5rem; + } + + .xl\:pr-2 { + padding-right: 0.5rem; + } + + .xl\:pb-2 { + padding-bottom: 0.5rem; + } + + .xl\:pl-2 { + padding-left: 0.5rem; + } + + .xl\:pt-3 { + padding-top: 0.75rem; + } + + .xl\:pr-3 { + padding-right: 0.75rem; + } + + .xl\:pb-3 { + padding-bottom: 0.75rem; + } + + .xl\:pl-3 { + padding-left: 0.75rem; + } + + .xl\:pt-4 { + padding-top: 1rem; + } + + .xl\:pr-4 { + padding-right: 1rem; + } + + .xl\:pb-4 { + padding-bottom: 1rem; + } + + .xl\:pl-4 { + padding-left: 1rem; + } + + .xl\:pt-5 { + padding-top: 1.25rem; + } + + .xl\:pr-5 { + padding-right: 1.25rem; + } + + .xl\:pb-5 { + padding-bottom: 1.25rem; + } + + .xl\:pl-5 { + padding-left: 1.25rem; + } + + .xl\:pt-6 { + padding-top: 1.5rem; + } + + .xl\:pr-6 { + padding-right: 1.5rem; + } + + .xl\:pb-6 { + padding-bottom: 1.5rem; + } + + .xl\:pl-6 { + padding-left: 1.5rem; + } + + .xl\:pt-8 { + padding-top: 2rem; + } + + .xl\:pr-8 { + padding-right: 2rem; + } + + .xl\:pb-8 { + padding-bottom: 2rem; + } + + .xl\:pl-8 { + padding-left: 2rem; + } + + .xl\:pt-10 { + padding-top: 2.5rem; + } + + .xl\:pr-10 { + padding-right: 2.5rem; + } + + .xl\:pb-10 { + padding-bottom: 2.5rem; + } + + .xl\:pl-10 { + padding-left: 2.5rem; + } + + .xl\:pt-12 { + padding-top: 3rem; + } + + .xl\:pr-12 { + padding-right: 3rem; + } + + .xl\:pb-12 { + padding-bottom: 3rem; + } + + .xl\:pl-12 { + padding-left: 3rem; + } + + .xl\:pt-16 { + padding-top: 4rem; + } + + .xl\:pr-16 { + padding-right: 4rem; + } + + .xl\:pb-16 { + padding-bottom: 4rem; + } + + .xl\:pl-16 { + padding-left: 4rem; + } + + .xl\:pt-20 { + padding-top: 5rem; + } + + .xl\:pr-20 { + padding-right: 5rem; + } + + .xl\:pb-20 { + padding-bottom: 5rem; + } + + .xl\:pl-20 { + padding-left: 5rem; + } + + .xl\:pt-24 { + padding-top: 6rem; + } + + .xl\:pr-24 { + padding-right: 6rem; + } + + .xl\:pb-24 { + padding-bottom: 6rem; + } + + .xl\:pl-24 { + padding-left: 6rem; + } + + .xl\:pt-32 { + padding-top: 8rem; + } + + .xl\:pr-32 { + padding-right: 8rem; + } + + .xl\:pb-32 { + padding-bottom: 8rem; + } + + .xl\:pl-32 { + padding-left: 8rem; + } + + .xl\:pt-40 { + padding-top: 10rem; + } + + .xl\:pr-40 { + padding-right: 10rem; + } + + .xl\:pb-40 { + padding-bottom: 10rem; + } + + .xl\:pl-40 { + padding-left: 10rem; + } + + .xl\:pt-48 { + padding-top: 12rem; + } + + .xl\:pr-48 { + padding-right: 12rem; + } + + .xl\:pb-48 { + padding-bottom: 12rem; + } + + .xl\:pl-48 { + padding-left: 12rem; + } + + .xl\:pt-56 { + padding-top: 14rem; + } + + .xl\:pr-56 { + padding-right: 14rem; + } + + .xl\:pb-56 { + padding-bottom: 14rem; + } + + .xl\:pl-56 { + padding-left: 14rem; + } + + .xl\:pt-64 { + padding-top: 16rem; + } + + .xl\:pr-64 { + padding-right: 16rem; + } + + .xl\:pb-64 { + padding-bottom: 16rem; + } + + .xl\:pl-64 { + padding-left: 16rem; + } + + .xl\:pt-px { + padding-top: 1px; + } + + .xl\:pr-px { + padding-right: 1px; + } + + .xl\:pb-px { + padding-bottom: 1px; + } + + .xl\:pl-px { + padding-left: 1px; + } + + .xl\:placeholder-transparent::placeholder { + color: transparent; + } + + .xl\:placeholder-black::placeholder { + color: #000; + } + + .xl\:placeholder-white::placeholder { + color: #fff; + } + + .xl\:placeholder-gray-100::placeholder { + color: #f7fafc; + } + + .xl\:placeholder-gray-200::placeholder { + color: #edf2f7; + } + + .xl\:placeholder-gray-300::placeholder { + color: #e2e8f0; + } + + .xl\:placeholder-gray-400::placeholder { + color: #cbd5e0; + } + + .xl\:placeholder-gray-500::placeholder { + color: #a0aec0; + } + + .xl\:placeholder-gray-600::placeholder { + color: #718096; + } + + .xl\:placeholder-gray-700::placeholder { + color: #4a5568; + } + + .xl\:placeholder-gray-800::placeholder { + color: #2d3748; + } + + .xl\:placeholder-gray-900::placeholder { + color: #1a202c; + } + + .xl\:placeholder-red-100::placeholder { + color: #fff5f5; + } + + .xl\:placeholder-red-200::placeholder { + color: #fed7d7; + } + + .xl\:placeholder-red-300::placeholder { + color: #feb2b2; + } + + .xl\:placeholder-red-400::placeholder { + color: #fc8181; + } + + .xl\:placeholder-red-500::placeholder { + color: #f56565; + } + + .xl\:placeholder-red-600::placeholder { + color: #e53e3e; + } + + .xl\:placeholder-red-700::placeholder { + color: #c53030; + } + + .xl\:placeholder-red-800::placeholder { + color: #9b2c2c; + } + + .xl\:placeholder-red-900::placeholder { + color: #742a2a; + } + + .xl\:placeholder-orange-100::placeholder { + color: #fffaf0; + } + + .xl\:placeholder-orange-200::placeholder { + color: #feebc8; + } + + .xl\:placeholder-orange-300::placeholder { + color: #fbd38d; + } + + .xl\:placeholder-orange-400::placeholder { + color: #f6ad55; + } + + .xl\:placeholder-orange-500::placeholder { + color: #ed8936; + } + + .xl\:placeholder-orange-600::placeholder { + color: #dd6b20; + } + + .xl\:placeholder-orange-700::placeholder { + color: #c05621; + } + + .xl\:placeholder-orange-800::placeholder { + color: #9c4221; + } + + .xl\:placeholder-orange-900::placeholder { + color: #7b341e; + } + + .xl\:placeholder-yellow-100::placeholder { + color: #fffff0; + } + + .xl\:placeholder-yellow-200::placeholder { + color: #fefcbf; + } + + .xl\:placeholder-yellow-300::placeholder { + color: #faf089; + } + + .xl\:placeholder-yellow-400::placeholder { + color: #f6e05e; + } + + .xl\:placeholder-yellow-500::placeholder { + color: #ecc94b; + } + + .xl\:placeholder-yellow-600::placeholder { + color: #d69e2e; + } + + .xl\:placeholder-yellow-700::placeholder { + color: #b7791f; + } + + .xl\:placeholder-yellow-800::placeholder { + color: #975a16; + } + + .xl\:placeholder-yellow-900::placeholder { + color: #744210; + } + + .xl\:placeholder-green-100::placeholder { + color: #f0fff4; + } + + .xl\:placeholder-green-200::placeholder { + color: #c6f6d5; + } + + .xl\:placeholder-green-300::placeholder { + color: #9ae6b4; + } + + .xl\:placeholder-green-400::placeholder { + color: #68d391; + } + + .xl\:placeholder-green-500::placeholder { + color: #48bb78; + } + + .xl\:placeholder-green-600::placeholder { + color: #38a169; + } + + .xl\:placeholder-green-700::placeholder { + color: #2f855a; + } + + .xl\:placeholder-green-800::placeholder { + color: #276749; + } + + .xl\:placeholder-green-900::placeholder { + color: #22543d; + } + + .xl\:placeholder-teal-100::placeholder { + color: #e6fffa; + } + + .xl\:placeholder-teal-200::placeholder { + color: #b2f5ea; + } + + .xl\:placeholder-teal-300::placeholder { + color: #81e6d9; + } + + .xl\:placeholder-teal-400::placeholder { + color: #4fd1c5; + } + + .xl\:placeholder-teal-500::placeholder { + color: #38b2ac; + } + + .xl\:placeholder-teal-600::placeholder { + color: #319795; + } + + .xl\:placeholder-teal-700::placeholder { + color: #2c7a7b; + } + + .xl\:placeholder-teal-800::placeholder { + color: #285e61; + } + + .xl\:placeholder-teal-900::placeholder { + color: #234e52; + } + + .xl\:placeholder-blue-100::placeholder { + color: #ebf8ff; + } + + .xl\:placeholder-blue-200::placeholder { + color: #bee3f8; + } + + .xl\:placeholder-blue-300::placeholder { + color: #90cdf4; + } + + .xl\:placeholder-blue-400::placeholder { + color: #63b3ed; + } + + .xl\:placeholder-blue-500::placeholder { + color: #4299e1; + } + + .xl\:placeholder-blue-600::placeholder { + color: #3182ce; + } + + .xl\:placeholder-blue-700::placeholder { + color: #2b6cb0; + } + + .xl\:placeholder-blue-800::placeholder { + color: #2c5282; + } + + .xl\:placeholder-blue-900::placeholder { + color: #2a4365; + } + + .xl\:placeholder-indigo-100::placeholder { + color: #ebf4ff; + } + + .xl\:placeholder-indigo-200::placeholder { + color: #c3dafe; + } + + .xl\:placeholder-indigo-300::placeholder { + color: #a3bffa; + } + + .xl\:placeholder-indigo-400::placeholder { + color: #7f9cf5; + } + + .xl\:placeholder-indigo-500::placeholder { + color: #667eea; + } + + .xl\:placeholder-indigo-600::placeholder { + color: #5a67d8; + } + + .xl\:placeholder-indigo-700::placeholder { + color: #4c51bf; + } + + .xl\:placeholder-indigo-800::placeholder { + color: #434190; + } + + .xl\:placeholder-indigo-900::placeholder { + color: #3c366b; + } + + .xl\:placeholder-purple-100::placeholder { + color: #faf5ff; + } + + .xl\:placeholder-purple-200::placeholder { + color: #e9d8fd; + } + + .xl\:placeholder-purple-300::placeholder { + color: #d6bcfa; + } + + .xl\:placeholder-purple-400::placeholder { + color: #b794f4; + } + + .xl\:placeholder-purple-500::placeholder { + color: #9f7aea; + } + + .xl\:placeholder-purple-600::placeholder { + color: #805ad5; + } + + .xl\:placeholder-purple-700::placeholder { + color: #6b46c1; + } + + .xl\:placeholder-purple-800::placeholder { + color: #553c9a; + } + + .xl\:placeholder-purple-900::placeholder { + color: #44337a; + } + + .xl\:placeholder-pink-100::placeholder { + color: #fff5f7; + } + + .xl\:placeholder-pink-200::placeholder { + color: #fed7e2; + } + + .xl\:placeholder-pink-300::placeholder { + color: #fbb6ce; + } + + .xl\:placeholder-pink-400::placeholder { + color: #f687b3; + } + + .xl\:placeholder-pink-500::placeholder { + color: #ed64a6; + } + + .xl\:placeholder-pink-600::placeholder { + color: #d53f8c; + } + + .xl\:placeholder-pink-700::placeholder { + color: #b83280; + } + + .xl\:placeholder-pink-800::placeholder { + color: #97266d; + } + + .xl\:placeholder-pink-900::placeholder { + color: #702459; + } + + .xl\:focus\:placeholder-transparent:focus::placeholder { + color: transparent; + } + + .xl\:focus\:placeholder-black:focus::placeholder { + color: #000; + } + + .xl\:focus\:placeholder-white:focus::placeholder { + color: #fff; + } + + .xl\:focus\:placeholder-gray-100:focus::placeholder { + color: #f7fafc; + } + + .xl\:focus\:placeholder-gray-200:focus::placeholder { + color: #edf2f7; + } + + .xl\:focus\:placeholder-gray-300:focus::placeholder { + color: #e2e8f0; + } + + .xl\:focus\:placeholder-gray-400:focus::placeholder { + color: #cbd5e0; + } + + .xl\:focus\:placeholder-gray-500:focus::placeholder { + color: #a0aec0; + } + + .xl\:focus\:placeholder-gray-600:focus::placeholder { + color: #718096; + } + + .xl\:focus\:placeholder-gray-700:focus::placeholder { + color: #4a5568; + } + + .xl\:focus\:placeholder-gray-800:focus::placeholder { + color: #2d3748; + } + + .xl\:focus\:placeholder-gray-900:focus::placeholder { + color: #1a202c; + } + + .xl\:focus\:placeholder-red-100:focus::placeholder { + color: #fff5f5; + } + + .xl\:focus\:placeholder-red-200:focus::placeholder { + color: #fed7d7; + } + + .xl\:focus\:placeholder-red-300:focus::placeholder { + color: #feb2b2; + } + + .xl\:focus\:placeholder-red-400:focus::placeholder { + color: #fc8181; + } + + .xl\:focus\:placeholder-red-500:focus::placeholder { + color: #f56565; + } + + .xl\:focus\:placeholder-red-600:focus::placeholder { + color: #e53e3e; + } + + .xl\:focus\:placeholder-red-700:focus::placeholder { + color: #c53030; + } + + .xl\:focus\:placeholder-red-800:focus::placeholder { + color: #9b2c2c; + } + + .xl\:focus\:placeholder-red-900:focus::placeholder { + color: #742a2a; + } + + .xl\:focus\:placeholder-orange-100:focus::placeholder { + color: #fffaf0; + } + + .xl\:focus\:placeholder-orange-200:focus::placeholder { + color: #feebc8; + } + + .xl\:focus\:placeholder-orange-300:focus::placeholder { + color: #fbd38d; + } + + .xl\:focus\:placeholder-orange-400:focus::placeholder { + color: #f6ad55; + } + + .xl\:focus\:placeholder-orange-500:focus::placeholder { + color: #ed8936; + } + + .xl\:focus\:placeholder-orange-600:focus::placeholder { + color: #dd6b20; + } + + .xl\:focus\:placeholder-orange-700:focus::placeholder { + color: #c05621; + } + + .xl\:focus\:placeholder-orange-800:focus::placeholder { + color: #9c4221; + } + + .xl\:focus\:placeholder-orange-900:focus::placeholder { + color: #7b341e; + } + + .xl\:focus\:placeholder-yellow-100:focus::placeholder { + color: #fffff0; + } + + .xl\:focus\:placeholder-yellow-200:focus::placeholder { + color: #fefcbf; + } + + .xl\:focus\:placeholder-yellow-300:focus::placeholder { + color: #faf089; + } + + .xl\:focus\:placeholder-yellow-400:focus::placeholder { + color: #f6e05e; + } + + .xl\:focus\:placeholder-yellow-500:focus::placeholder { + color: #ecc94b; + } + + .xl\:focus\:placeholder-yellow-600:focus::placeholder { + color: #d69e2e; + } + + .xl\:focus\:placeholder-yellow-700:focus::placeholder { + color: #b7791f; + } + + .xl\:focus\:placeholder-yellow-800:focus::placeholder { + color: #975a16; + } + + .xl\:focus\:placeholder-yellow-900:focus::placeholder { + color: #744210; + } + + .xl\:focus\:placeholder-green-100:focus::placeholder { + color: #f0fff4; + } + + .xl\:focus\:placeholder-green-200:focus::placeholder { + color: #c6f6d5; + } + + .xl\:focus\:placeholder-green-300:focus::placeholder { + color: #9ae6b4; + } + + .xl\:focus\:placeholder-green-400:focus::placeholder { + color: #68d391; + } + + .xl\:focus\:placeholder-green-500:focus::placeholder { + color: #48bb78; + } + + .xl\:focus\:placeholder-green-600:focus::placeholder { + color: #38a169; + } + + .xl\:focus\:placeholder-green-700:focus::placeholder { + color: #2f855a; + } + + .xl\:focus\:placeholder-green-800:focus::placeholder { + color: #276749; + } + + .xl\:focus\:placeholder-green-900:focus::placeholder { + color: #22543d; + } + + .xl\:focus\:placeholder-teal-100:focus::placeholder { + color: #e6fffa; + } + + .xl\:focus\:placeholder-teal-200:focus::placeholder { + color: #b2f5ea; + } + + .xl\:focus\:placeholder-teal-300:focus::placeholder { + color: #81e6d9; + } + + .xl\:focus\:placeholder-teal-400:focus::placeholder { + color: #4fd1c5; + } + + .xl\:focus\:placeholder-teal-500:focus::placeholder { + color: #38b2ac; + } + + .xl\:focus\:placeholder-teal-600:focus::placeholder { + color: #319795; + } + + .xl\:focus\:placeholder-teal-700:focus::placeholder { + color: #2c7a7b; + } + + .xl\:focus\:placeholder-teal-800:focus::placeholder { + color: #285e61; + } + + .xl\:focus\:placeholder-teal-900:focus::placeholder { + color: #234e52; + } + + .xl\:focus\:placeholder-blue-100:focus::placeholder { + color: #ebf8ff; + } + + .xl\:focus\:placeholder-blue-200:focus::placeholder { + color: #bee3f8; + } + + .xl\:focus\:placeholder-blue-300:focus::placeholder { + color: #90cdf4; + } + + .xl\:focus\:placeholder-blue-400:focus::placeholder { + color: #63b3ed; + } + + .xl\:focus\:placeholder-blue-500:focus::placeholder { + color: #4299e1; + } + + .xl\:focus\:placeholder-blue-600:focus::placeholder { + color: #3182ce; + } + + .xl\:focus\:placeholder-blue-700:focus::placeholder { + color: #2b6cb0; + } + + .xl\:focus\:placeholder-blue-800:focus::placeholder { + color: #2c5282; + } + + .xl\:focus\:placeholder-blue-900:focus::placeholder { + color: #2a4365; + } + + .xl\:focus\:placeholder-indigo-100:focus::placeholder { + color: #ebf4ff; + } + + .xl\:focus\:placeholder-indigo-200:focus::placeholder { + color: #c3dafe; + } + + .xl\:focus\:placeholder-indigo-300:focus::placeholder { + color: #a3bffa; + } + + .xl\:focus\:placeholder-indigo-400:focus::placeholder { + color: #7f9cf5; + } + + .xl\:focus\:placeholder-indigo-500:focus::placeholder { + color: #667eea; + } + + .xl\:focus\:placeholder-indigo-600:focus::placeholder { + color: #5a67d8; + } + + .xl\:focus\:placeholder-indigo-700:focus::placeholder { + color: #4c51bf; + } + + .xl\:focus\:placeholder-indigo-800:focus::placeholder { + color: #434190; + } + + .xl\:focus\:placeholder-indigo-900:focus::placeholder { + color: #3c366b; + } + + .xl\:focus\:placeholder-purple-100:focus::placeholder { + color: #faf5ff; + } + + .xl\:focus\:placeholder-purple-200:focus::placeholder { + color: #e9d8fd; + } + + .xl\:focus\:placeholder-purple-300:focus::placeholder { + color: #d6bcfa; + } + + .xl\:focus\:placeholder-purple-400:focus::placeholder { + color: #b794f4; + } + + .xl\:focus\:placeholder-purple-500:focus::placeholder { + color: #9f7aea; + } + + .xl\:focus\:placeholder-purple-600:focus::placeholder { + color: #805ad5; + } + + .xl\:focus\:placeholder-purple-700:focus::placeholder { + color: #6b46c1; + } + + .xl\:focus\:placeholder-purple-800:focus::placeholder { + color: #553c9a; + } + + .xl\:focus\:placeholder-purple-900:focus::placeholder { + color: #44337a; + } + + .xl\:focus\:placeholder-pink-100:focus::placeholder { + color: #fff5f7; + } + + .xl\:focus\:placeholder-pink-200:focus::placeholder { + color: #fed7e2; + } + + .xl\:focus\:placeholder-pink-300:focus::placeholder { + color: #fbb6ce; + } + + .xl\:focus\:placeholder-pink-400:focus::placeholder { + color: #f687b3; + } + + .xl\:focus\:placeholder-pink-500:focus::placeholder { + color: #ed64a6; + } + + .xl\:focus\:placeholder-pink-600:focus::placeholder { + color: #d53f8c; + } + + .xl\:focus\:placeholder-pink-700:focus::placeholder { + color: #b83280; + } + + .xl\:focus\:placeholder-pink-800:focus::placeholder { + color: #97266d; + } + + .xl\:focus\:placeholder-pink-900:focus::placeholder { + color: #702459; + } + + .xl\:pointer-events-none { + pointer-events: none; + } + + .xl\:pointer-events-auto { + pointer-events: auto; + } + + .xl\:static { + position: static; + } + + .xl\:fixed { + position: fixed; + } + + .xl\:absolute { + position: absolute; + } + + .xl\:relative { + position: relative; + } + + .xl\:sticky { + position: -webkit-sticky; + position: sticky; + } + + .xl\:inset-0 { + top: 0; + right: 0; + bottom: 0; + left: 0; + } + + .xl\:inset-auto { + top: auto; + right: auto; + bottom: auto; + left: auto; + } + + .xl\:inset-y-0 { + top: 0; + bottom: 0; + } + + .xl\:inset-x-0 { + right: 0; + left: 0; + } + + .xl\:inset-y-auto { + top: auto; + bottom: auto; + } + + .xl\:inset-x-auto { + right: auto; + left: auto; + } + + .xl\:top-0 { + top: 0; + } + + .xl\:right-0 { + right: 0; + } + + .xl\:bottom-0 { + bottom: 0; + } + + .xl\:left-0 { + left: 0; + } + + .xl\:top-auto { + top: auto; + } + + .xl\:right-auto { + right: auto; + } + + .xl\:bottom-auto { + bottom: auto; + } + + .xl\:left-auto { + left: auto; + } + + .xl\:resize-none { + resize: none; + } + + .xl\:resize-y { + resize: vertical; + } + + .xl\:resize-x { + resize: horizontal; + } + + .xl\:resize { + resize: both; + } + + .xl\:shadow-xs { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); + } + + .xl\:shadow-sm { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + } + + .xl\:shadow { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + } + + .xl\:shadow-md { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + } + + .xl\:shadow-lg { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + } + + .xl\:shadow-xl { + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + } + + .xl\:shadow-2xl { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + } + + .xl\:shadow-inner { + box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); + } + + .xl\:shadow-outline { + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); + } + + .xl\:shadow-none { + box-shadow: none; + } + + .xl\:hover\:shadow-xs:hover { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); + } + + .xl\:hover\:shadow-sm:hover { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + } + + .xl\:hover\:shadow:hover { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + } + + .xl\:hover\:shadow-md:hover { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + } + + .xl\:hover\:shadow-lg:hover { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + } + + .xl\:hover\:shadow-xl:hover { + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + } + + .xl\:hover\:shadow-2xl:hover { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + } + + .xl\:hover\:shadow-inner:hover { + box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); + } + + .xl\:hover\:shadow-outline:hover { + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); + } + + .xl\:hover\:shadow-none:hover { + box-shadow: none; + } + + .xl\:focus\:shadow-xs:focus { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); + } + + .xl\:focus\:shadow-sm:focus { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + } + + .xl\:focus\:shadow:focus { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + } + + .xl\:focus\:shadow-md:focus { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + } + + .xl\:focus\:shadow-lg:focus { + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + } + + .xl\:focus\:shadow-xl:focus { + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + } + + .xl\:focus\:shadow-2xl:focus { + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + } + + .xl\:focus\:shadow-inner:focus { + box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); + } + + .xl\:focus\:shadow-outline:focus { + box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5); + } + + .xl\:focus\:shadow-none:focus { + box-shadow: none; + } + + .xl\:fill-current { + fill: currentColor; + } + + .xl\:stroke-current { + stroke: currentColor; + } + + .xl\:stroke-0 { + stroke-width: 0; + } + + .xl\:stroke-1 { + stroke-width: 1; + } + + .xl\:stroke-2 { + stroke-width: 2; + } + + .xl\:table-auto { + table-layout: auto; + } + + .xl\:table-fixed { + table-layout: fixed; + } + + .xl\:text-left { + text-align: left; + } + + .xl\:text-center { + text-align: center; + } + + .xl\:text-right { + text-align: right; + } + + .xl\:text-justify { + text-align: justify; + } + + .xl\:text-transparent { + color: transparent; + } + + .xl\:text-black { + color: #000; + } + + .xl\:text-white { + color: #fff; + } + + .xl\:text-gray-100 { + color: #f7fafc; + } + + .xl\:text-gray-200 { + color: #edf2f7; + } + + .xl\:text-gray-300 { + color: #e2e8f0; + } + + .xl\:text-gray-400 { + color: #cbd5e0; + } + + .xl\:text-gray-500 { + color: #a0aec0; + } + + .xl\:text-gray-600 { + color: #718096; + } + + .xl\:text-gray-700 { + color: #4a5568; + } + + .xl\:text-gray-800 { + color: #2d3748; + } + + .xl\:text-gray-900 { + color: #1a202c; + } + + .xl\:text-red-100 { + color: #fff5f5; + } + + .xl\:text-red-200 { + color: #fed7d7; + } + + .xl\:text-red-300 { + color: #feb2b2; + } + + .xl\:text-red-400 { + color: #fc8181; + } + + .xl\:text-red-500 { + color: #f56565; + } + + .xl\:text-red-600 { + color: #e53e3e; + } + + .xl\:text-red-700 { + color: #c53030; + } + + .xl\:text-red-800 { + color: #9b2c2c; + } + + .xl\:text-red-900 { + color: #742a2a; + } + + .xl\:text-orange-100 { + color: #fffaf0; + } + + .xl\:text-orange-200 { + color: #feebc8; + } + + .xl\:text-orange-300 { + color: #fbd38d; + } + + .xl\:text-orange-400 { + color: #f6ad55; + } + + .xl\:text-orange-500 { + color: #ed8936; + } + + .xl\:text-orange-600 { + color: #dd6b20; + } + + .xl\:text-orange-700 { + color: #c05621; + } + + .xl\:text-orange-800 { + color: #9c4221; + } + + .xl\:text-orange-900 { + color: #7b341e; + } + + .xl\:text-yellow-100 { + color: #fffff0; + } + + .xl\:text-yellow-200 { + color: #fefcbf; + } + + .xl\:text-yellow-300 { + color: #faf089; + } + + .xl\:text-yellow-400 { + color: #f6e05e; + } + + .xl\:text-yellow-500 { + color: #ecc94b; + } + + .xl\:text-yellow-600 { + color: #d69e2e; + } + + .xl\:text-yellow-700 { + color: #b7791f; + } + + .xl\:text-yellow-800 { + color: #975a16; + } + + .xl\:text-yellow-900 { + color: #744210; + } + + .xl\:text-green-100 { + color: #f0fff4; + } + + .xl\:text-green-200 { + color: #c6f6d5; + } + + .xl\:text-green-300 { + color: #9ae6b4; + } + + .xl\:text-green-400 { + color: #68d391; + } + + .xl\:text-green-500 { + color: #48bb78; + } + + .xl\:text-green-600 { + color: #38a169; + } + + .xl\:text-green-700 { + color: #2f855a; + } + + .xl\:text-green-800 { + color: #276749; + } + + .xl\:text-green-900 { + color: #22543d; + } + + .xl\:text-teal-100 { + color: #e6fffa; + } + + .xl\:text-teal-200 { + color: #b2f5ea; + } + + .xl\:text-teal-300 { + color: #81e6d9; + } + + .xl\:text-teal-400 { + color: #4fd1c5; + } + + .xl\:text-teal-500 { + color: #38b2ac; + } + + .xl\:text-teal-600 { + color: #319795; + } + + .xl\:text-teal-700 { + color: #2c7a7b; + } + + .xl\:text-teal-800 { + color: #285e61; + } + + .xl\:text-teal-900 { + color: #234e52; + } + + .xl\:text-blue-100 { + color: #ebf8ff; + } + + .xl\:text-blue-200 { + color: #bee3f8; + } + + .xl\:text-blue-300 { + color: #90cdf4; + } + + .xl\:text-blue-400 { + color: #63b3ed; + } + + .xl\:text-blue-500 { + color: #4299e1; + } + + .xl\:text-blue-600 { + color: #3182ce; + } + + .xl\:text-blue-700 { + color: #2b6cb0; + } + + .xl\:text-blue-800 { + color: #2c5282; + } + + .xl\:text-blue-900 { + color: #2a4365; + } + + .xl\:text-indigo-100 { + color: #ebf4ff; + } + + .xl\:text-indigo-200 { + color: #c3dafe; + } + + .xl\:text-indigo-300 { + color: #a3bffa; + } + + .xl\:text-indigo-400 { + color: #7f9cf5; + } + + .xl\:text-indigo-500 { + color: #667eea; + } + + .xl\:text-indigo-600 { + color: #5a67d8; + } + + .xl\:text-indigo-700 { + color: #4c51bf; + } + + .xl\:text-indigo-800 { + color: #434190; + } + + .xl\:text-indigo-900 { + color: #3c366b; + } + + .xl\:text-purple-100 { + color: #faf5ff; + } + + .xl\:text-purple-200 { + color: #e9d8fd; + } + + .xl\:text-purple-300 { + color: #d6bcfa; + } + + .xl\:text-purple-400 { + color: #b794f4; + } + + .xl\:text-purple-500 { + color: #9f7aea; + } + + .xl\:text-purple-600 { + color: #805ad5; + } + + .xl\:text-purple-700 { + color: #6b46c1; + } + + .xl\:text-purple-800 { + color: #553c9a; + } + + .xl\:text-purple-900 { + color: #44337a; + } + + .xl\:text-pink-100 { + color: #fff5f7; + } + + .xl\:text-pink-200 { + color: #fed7e2; + } + + .xl\:text-pink-300 { + color: #fbb6ce; + } + + .xl\:text-pink-400 { + color: #f687b3; + } + + .xl\:text-pink-500 { + color: #ed64a6; + } + + .xl\:text-pink-600 { + color: #d53f8c; + } + + .xl\:text-pink-700 { + color: #b83280; + } + + .xl\:text-pink-800 { + color: #97266d; + } + + .xl\:text-pink-900 { + color: #702459; + } + + .xl\:hover\:text-transparent:hover { + color: transparent; + } + + .xl\:hover\:text-black:hover { + color: #000; + } + + .xl\:hover\:text-white:hover { + color: #fff; + } + + .xl\:hover\:text-gray-100:hover { + color: #f7fafc; + } + + .xl\:hover\:text-gray-200:hover { + color: #edf2f7; + } + + .xl\:hover\:text-gray-300:hover { + color: #e2e8f0; + } + + .xl\:hover\:text-gray-400:hover { + color: #cbd5e0; + } + + .xl\:hover\:text-gray-500:hover { + color: #a0aec0; + } + + .xl\:hover\:text-gray-600:hover { + color: #718096; + } + + .xl\:hover\:text-gray-700:hover { + color: #4a5568; + } + + .xl\:hover\:text-gray-800:hover { + color: #2d3748; + } + + .xl\:hover\:text-gray-900:hover { + color: #1a202c; + } + + .xl\:hover\:text-red-100:hover { + color: #fff5f5; + } + + .xl\:hover\:text-red-200:hover { + color: #fed7d7; + } + + .xl\:hover\:text-red-300:hover { + color: #feb2b2; + } + + .xl\:hover\:text-red-400:hover { + color: #fc8181; + } + + .xl\:hover\:text-red-500:hover { + color: #f56565; + } + + .xl\:hover\:text-red-600:hover { + color: #e53e3e; + } + + .xl\:hover\:text-red-700:hover { + color: #c53030; + } + + .xl\:hover\:text-red-800:hover { + color: #9b2c2c; + } + + .xl\:hover\:text-red-900:hover { + color: #742a2a; + } + + .xl\:hover\:text-orange-100:hover { + color: #fffaf0; + } + + .xl\:hover\:text-orange-200:hover { + color: #feebc8; + } + + .xl\:hover\:text-orange-300:hover { + color: #fbd38d; + } + + .xl\:hover\:text-orange-400:hover { + color: #f6ad55; + } + + .xl\:hover\:text-orange-500:hover { + color: #ed8936; + } + + .xl\:hover\:text-orange-600:hover { + color: #dd6b20; + } + + .xl\:hover\:text-orange-700:hover { + color: #c05621; + } + + .xl\:hover\:text-orange-800:hover { + color: #9c4221; + } + + .xl\:hover\:text-orange-900:hover { + color: #7b341e; + } + + .xl\:hover\:text-yellow-100:hover { + color: #fffff0; + } + + .xl\:hover\:text-yellow-200:hover { + color: #fefcbf; + } + + .xl\:hover\:text-yellow-300:hover { + color: #faf089; + } + + .xl\:hover\:text-yellow-400:hover { + color: #f6e05e; + } + + .xl\:hover\:text-yellow-500:hover { + color: #ecc94b; + } + + .xl\:hover\:text-yellow-600:hover { + color: #d69e2e; + } + + .xl\:hover\:text-yellow-700:hover { + color: #b7791f; + } + + .xl\:hover\:text-yellow-800:hover { + color: #975a16; + } + + .xl\:hover\:text-yellow-900:hover { + color: #744210; + } + + .xl\:hover\:text-green-100:hover { + color: #f0fff4; + } + + .xl\:hover\:text-green-200:hover { + color: #c6f6d5; + } + + .xl\:hover\:text-green-300:hover { + color: #9ae6b4; + } + + .xl\:hover\:text-green-400:hover { + color: #68d391; + } + + .xl\:hover\:text-green-500:hover { + color: #48bb78; + } + + .xl\:hover\:text-green-600:hover { + color: #38a169; + } + + .xl\:hover\:text-green-700:hover { + color: #2f855a; + } + + .xl\:hover\:text-green-800:hover { + color: #276749; + } + + .xl\:hover\:text-green-900:hover { + color: #22543d; + } + + .xl\:hover\:text-teal-100:hover { + color: #e6fffa; + } + + .xl\:hover\:text-teal-200:hover { + color: #b2f5ea; + } + + .xl\:hover\:text-teal-300:hover { + color: #81e6d9; + } + + .xl\:hover\:text-teal-400:hover { + color: #4fd1c5; + } + + .xl\:hover\:text-teal-500:hover { + color: #38b2ac; + } + + .xl\:hover\:text-teal-600:hover { + color: #319795; + } + + .xl\:hover\:text-teal-700:hover { + color: #2c7a7b; + } + + .xl\:hover\:text-teal-800:hover { + color: #285e61; + } + + .xl\:hover\:text-teal-900:hover { + color: #234e52; + } + + .xl\:hover\:text-blue-100:hover { + color: #ebf8ff; + } + + .xl\:hover\:text-blue-200:hover { + color: #bee3f8; + } + + .xl\:hover\:text-blue-300:hover { + color: #90cdf4; + } + + .xl\:hover\:text-blue-400:hover { + color: #63b3ed; + } + + .xl\:hover\:text-blue-500:hover { + color: #4299e1; + } + + .xl\:hover\:text-blue-600:hover { + color: #3182ce; + } + + .xl\:hover\:text-blue-700:hover { + color: #2b6cb0; + } + + .xl\:hover\:text-blue-800:hover { + color: #2c5282; + } + + .xl\:hover\:text-blue-900:hover { + color: #2a4365; + } + + .xl\:hover\:text-indigo-100:hover { + color: #ebf4ff; + } + + .xl\:hover\:text-indigo-200:hover { + color: #c3dafe; + } + + .xl\:hover\:text-indigo-300:hover { + color: #a3bffa; + } + + .xl\:hover\:text-indigo-400:hover { + color: #7f9cf5; + } + + .xl\:hover\:text-indigo-500:hover { + color: #667eea; + } + + .xl\:hover\:text-indigo-600:hover { + color: #5a67d8; + } + + .xl\:hover\:text-indigo-700:hover { + color: #4c51bf; + } + + .xl\:hover\:text-indigo-800:hover { + color: #434190; + } + + .xl\:hover\:text-indigo-900:hover { + color: #3c366b; + } + + .xl\:hover\:text-purple-100:hover { + color: #faf5ff; + } + + .xl\:hover\:text-purple-200:hover { + color: #e9d8fd; + } + + .xl\:hover\:text-purple-300:hover { + color: #d6bcfa; + } + + .xl\:hover\:text-purple-400:hover { + color: #b794f4; + } + + .xl\:hover\:text-purple-500:hover { + color: #9f7aea; + } + + .xl\:hover\:text-purple-600:hover { + color: #805ad5; + } + + .xl\:hover\:text-purple-700:hover { + color: #6b46c1; + } + + .xl\:hover\:text-purple-800:hover { + color: #553c9a; + } + + .xl\:hover\:text-purple-900:hover { + color: #44337a; + } + + .xl\:hover\:text-pink-100:hover { + color: #fff5f7; + } + + .xl\:hover\:text-pink-200:hover { + color: #fed7e2; + } + + .xl\:hover\:text-pink-300:hover { + color: #fbb6ce; + } + + .xl\:hover\:text-pink-400:hover { + color: #f687b3; + } + + .xl\:hover\:text-pink-500:hover { + color: #ed64a6; + } + + .xl\:hover\:text-pink-600:hover { + color: #d53f8c; + } + + .xl\:hover\:text-pink-700:hover { + color: #b83280; + } + + .xl\:hover\:text-pink-800:hover { + color: #97266d; + } + + .xl\:hover\:text-pink-900:hover { + color: #702459; + } + + .xl\:focus\:text-transparent:focus { + color: transparent; + } + + .xl\:focus\:text-black:focus { + color: #000; + } + + .xl\:focus\:text-white:focus { + color: #fff; + } + + .xl\:focus\:text-gray-100:focus { + color: #f7fafc; + } + + .xl\:focus\:text-gray-200:focus { + color: #edf2f7; + } + + .xl\:focus\:text-gray-300:focus { + color: #e2e8f0; + } + + .xl\:focus\:text-gray-400:focus { + color: #cbd5e0; + } + + .xl\:focus\:text-gray-500:focus { + color: #a0aec0; + } + + .xl\:focus\:text-gray-600:focus { + color: #718096; + } + + .xl\:focus\:text-gray-700:focus { + color: #4a5568; + } + + .xl\:focus\:text-gray-800:focus { + color: #2d3748; + } + + .xl\:focus\:text-gray-900:focus { + color: #1a202c; + } + + .xl\:focus\:text-red-100:focus { + color: #fff5f5; + } + + .xl\:focus\:text-red-200:focus { + color: #fed7d7; + } + + .xl\:focus\:text-red-300:focus { + color: #feb2b2; + } + + .xl\:focus\:text-red-400:focus { + color: #fc8181; + } + + .xl\:focus\:text-red-500:focus { + color: #f56565; + } + + .xl\:focus\:text-red-600:focus { + color: #e53e3e; + } + + .xl\:focus\:text-red-700:focus { + color: #c53030; + } + + .xl\:focus\:text-red-800:focus { + color: #9b2c2c; + } + + .xl\:focus\:text-red-900:focus { + color: #742a2a; + } + + .xl\:focus\:text-orange-100:focus { + color: #fffaf0; + } + + .xl\:focus\:text-orange-200:focus { + color: #feebc8; + } + + .xl\:focus\:text-orange-300:focus { + color: #fbd38d; + } + + .xl\:focus\:text-orange-400:focus { + color: #f6ad55; + } + + .xl\:focus\:text-orange-500:focus { + color: #ed8936; + } + + .xl\:focus\:text-orange-600:focus { + color: #dd6b20; + } + + .xl\:focus\:text-orange-700:focus { + color: #c05621; + } + + .xl\:focus\:text-orange-800:focus { + color: #9c4221; + } + + .xl\:focus\:text-orange-900:focus { + color: #7b341e; + } + + .xl\:focus\:text-yellow-100:focus { + color: #fffff0; + } + + .xl\:focus\:text-yellow-200:focus { + color: #fefcbf; + } + + .xl\:focus\:text-yellow-300:focus { + color: #faf089; + } + + .xl\:focus\:text-yellow-400:focus { + color: #f6e05e; + } + + .xl\:focus\:text-yellow-500:focus { + color: #ecc94b; + } + + .xl\:focus\:text-yellow-600:focus { + color: #d69e2e; + } + + .xl\:focus\:text-yellow-700:focus { + color: #b7791f; + } + + .xl\:focus\:text-yellow-800:focus { + color: #975a16; + } + + .xl\:focus\:text-yellow-900:focus { + color: #744210; + } + + .xl\:focus\:text-green-100:focus { + color: #f0fff4; + } + + .xl\:focus\:text-green-200:focus { + color: #c6f6d5; + } + + .xl\:focus\:text-green-300:focus { + color: #9ae6b4; + } + + .xl\:focus\:text-green-400:focus { + color: #68d391; + } + + .xl\:focus\:text-green-500:focus { + color: #48bb78; + } + + .xl\:focus\:text-green-600:focus { + color: #38a169; + } + + .xl\:focus\:text-green-700:focus { + color: #2f855a; + } + + .xl\:focus\:text-green-800:focus { + color: #276749; + } + + .xl\:focus\:text-green-900:focus { + color: #22543d; + } + + .xl\:focus\:text-teal-100:focus { + color: #e6fffa; + } + + .xl\:focus\:text-teal-200:focus { + color: #b2f5ea; + } + + .xl\:focus\:text-teal-300:focus { + color: #81e6d9; + } + + .xl\:focus\:text-teal-400:focus { + color: #4fd1c5; + } + + .xl\:focus\:text-teal-500:focus { + color: #38b2ac; + } + + .xl\:focus\:text-teal-600:focus { + color: #319795; + } + + .xl\:focus\:text-teal-700:focus { + color: #2c7a7b; + } + + .xl\:focus\:text-teal-800:focus { + color: #285e61; + } + + .xl\:focus\:text-teal-900:focus { + color: #234e52; + } + + .xl\:focus\:text-blue-100:focus { + color: #ebf8ff; + } + + .xl\:focus\:text-blue-200:focus { + color: #bee3f8; + } + + .xl\:focus\:text-blue-300:focus { + color: #90cdf4; + } + + .xl\:focus\:text-blue-400:focus { + color: #63b3ed; + } + + .xl\:focus\:text-blue-500:focus { + color: #4299e1; + } + + .xl\:focus\:text-blue-600:focus { + color: #3182ce; + } + + .xl\:focus\:text-blue-700:focus { + color: #2b6cb0; + } + + .xl\:focus\:text-blue-800:focus { + color: #2c5282; + } + + .xl\:focus\:text-blue-900:focus { + color: #2a4365; + } + + .xl\:focus\:text-indigo-100:focus { + color: #ebf4ff; + } + + .xl\:focus\:text-indigo-200:focus { + color: #c3dafe; + } + + .xl\:focus\:text-indigo-300:focus { + color: #a3bffa; + } + + .xl\:focus\:text-indigo-400:focus { + color: #7f9cf5; + } + + .xl\:focus\:text-indigo-500:focus { + color: #667eea; + } + + .xl\:focus\:text-indigo-600:focus { + color: #5a67d8; + } + + .xl\:focus\:text-indigo-700:focus { + color: #4c51bf; + } + + .xl\:focus\:text-indigo-800:focus { + color: #434190; + } + + .xl\:focus\:text-indigo-900:focus { + color: #3c366b; + } + + .xl\:focus\:text-purple-100:focus { + color: #faf5ff; + } + + .xl\:focus\:text-purple-200:focus { + color: #e9d8fd; + } + + .xl\:focus\:text-purple-300:focus { + color: #d6bcfa; + } + + .xl\:focus\:text-purple-400:focus { + color: #b794f4; + } + + .xl\:focus\:text-purple-500:focus { + color: #9f7aea; + } + + .xl\:focus\:text-purple-600:focus { + color: #805ad5; + } + + .xl\:focus\:text-purple-700:focus { + color: #6b46c1; + } + + .xl\:focus\:text-purple-800:focus { + color: #553c9a; + } + + .xl\:focus\:text-purple-900:focus { + color: #44337a; + } + + .xl\:focus\:text-pink-100:focus { + color: #fff5f7; + } + + .xl\:focus\:text-pink-200:focus { + color: #fed7e2; + } + + .xl\:focus\:text-pink-300:focus { + color: #fbb6ce; + } + + .xl\:focus\:text-pink-400:focus { + color: #f687b3; + } + + .xl\:focus\:text-pink-500:focus { + color: #ed64a6; + } + + .xl\:focus\:text-pink-600:focus { + color: #d53f8c; + } + + .xl\:focus\:text-pink-700:focus { + color: #b83280; + } + + .xl\:focus\:text-pink-800:focus { + color: #97266d; + } + + .xl\:focus\:text-pink-900:focus { + color: #702459; + } + + .xl\:text-xs { + font-size: 0.75rem; + } + + .xl\:text-sm { + font-size: 0.875rem; + } + + .xl\:text-base { + font-size: 1rem; + } + + .xl\:text-lg { + font-size: 1.125rem; + } + + .xl\:text-xl { + font-size: 1.25rem; + } + + .xl\:text-2xl { + font-size: 1.5rem; + } + + .xl\:text-3xl { + font-size: 1.875rem; + } + + .xl\:text-4xl { + font-size: 2.25rem; + } + + .xl\:text-5xl { + font-size: 3rem; + } + + .xl\:text-6xl { + font-size: 4rem; + } + + .xl\:italic { + font-style: italic; + } + + .xl\:not-italic { + font-style: normal; + } + + .xl\:uppercase { + text-transform: uppercase; + } + + .xl\:lowercase { + text-transform: lowercase; + } + + .xl\:capitalize { + text-transform: capitalize; + } + + .xl\:normal-case { + text-transform: none; + } + + .xl\:underline { + text-decoration: underline; + } + + .xl\:line-through { + text-decoration: line-through; + } + + .xl\:no-underline { + text-decoration: none; + } + + .xl\:hover\:underline:hover { + text-decoration: underline; + } + + .xl\:hover\:line-through:hover { + text-decoration: line-through; + } + + .xl\:hover\:no-underline:hover { + text-decoration: none; + } + + .xl\:focus\:underline:focus { + text-decoration: underline; + } + + .xl\:focus\:line-through:focus { + text-decoration: line-through; + } + + .xl\:focus\:no-underline:focus { + text-decoration: none; + } + + .xl\:antialiased { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + + .xl\:subpixel-antialiased { + -webkit-font-smoothing: auto; + -moz-osx-font-smoothing: auto; + } + + .xl\:tracking-tighter { + letter-spacing: -0.05em; + } + + .xl\:tracking-tight { + letter-spacing: -0.025em; + } + + .xl\:tracking-normal { + letter-spacing: 0; + } + + .xl\:tracking-wide { + letter-spacing: 0.025em; + } + + .xl\:tracking-wider { + letter-spacing: 0.05em; + } + + .xl\:tracking-widest { + letter-spacing: 0.1em; + } + + .xl\:select-none { + -webkit-user-select: none; + user-select: none; + } + + .xl\:select-text { + -webkit-user-select: text; + user-select: text; + } + + .xl\:select-all { + -webkit-user-select: all; + user-select: all; + } + + .xl\:select-auto { + -webkit-user-select: auto; + user-select: auto; + } + + .xl\:align-baseline { + vertical-align: baseline; + } + + .xl\:align-top { + vertical-align: top; + } + + .xl\:align-middle { + vertical-align: middle; + } + + .xl\:align-bottom { + vertical-align: bottom; + } + + .xl\:align-text-top { + vertical-align: text-top; + } + + .xl\:align-text-bottom { + vertical-align: text-bottom; + } + + .xl\:visible { + visibility: visible; + } + + .xl\:invisible { + visibility: hidden; + } + + .xl\:whitespace-normal { + white-space: normal; + } + + .xl\:whitespace-no-wrap { + white-space: nowrap; + } + + .xl\:whitespace-pre { + white-space: pre; + } + + .xl\:whitespace-pre-line { + white-space: pre-line; + } + + .xl\:whitespace-pre-wrap { + white-space: pre-wrap; + } + + .xl\:break-normal { + overflow-wrap: normal; + word-break: normal; + } + + .xl\:break-words { + overflow-wrap: break-word; + } + + .xl\:break-all { + word-break: break-all; + } + + .xl\:truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .xl\:w-0 { + width: 0; + } + + .xl\:w-1 { + width: 0.25rem; + } + + .xl\:w-2 { + width: 0.5rem; + } + + .xl\:w-3 { + width: 0.75rem; + } + + .xl\:w-4 { + width: 1rem; + } + + .xl\:w-5 { + width: 1.25rem; + } + + .xl\:w-6 { + width: 1.5rem; + } + + .xl\:w-8 { + width: 2rem; + } + + .xl\:w-10 { + width: 2.5rem; + } + + .xl\:w-12 { + width: 3rem; + } + + .xl\:w-16 { + width: 4rem; + } + + .xl\:w-20 { + width: 5rem; + } + + .xl\:w-24 { + width: 6rem; + } + + .xl\:w-32 { + width: 8rem; + } + + .xl\:w-40 { + width: 10rem; + } + + .xl\:w-48 { + width: 12rem; + } + + .xl\:w-56 { + width: 14rem; + } + + .xl\:w-64 { + width: 16rem; + } + + .xl\:w-auto { + width: auto; + } + + .xl\:w-px { + width: 1px; + } + + .xl\:w-1\/2 { + width: 50%; + } + + .xl\:w-1\/3 { + width: 33.333333%; + } + + .xl\:w-2\/3 { + width: 66.666667%; + } + + .xl\:w-1\/4 { + width: 25%; + } + + .xl\:w-2\/4 { + width: 50%; + } + + .xl\:w-3\/4 { + width: 75%; + } + + .xl\:w-1\/5 { + width: 20%; + } + + .xl\:w-2\/5 { + width: 40%; + } + + .xl\:w-3\/5 { + width: 60%; + } + + .xl\:w-4\/5 { + width: 80%; + } + + .xl\:w-1\/6 { + width: 16.666667%; + } + + .xl\:w-2\/6 { + width: 33.333333%; + } + + .xl\:w-3\/6 { + width: 50%; + } + + .xl\:w-4\/6 { + width: 66.666667%; + } + + .xl\:w-5\/6 { + width: 83.333333%; + } + + .xl\:w-1\/12 { + width: 8.333333%; + } + + .xl\:w-2\/12 { + width: 16.666667%; + } + + .xl\:w-3\/12 { + width: 25%; + } + + .xl\:w-4\/12 { + width: 33.333333%; + } + + .xl\:w-5\/12 { + width: 41.666667%; + } + + .xl\:w-6\/12 { + width: 50%; + } + + .xl\:w-7\/12 { + width: 58.333333%; + } + + .xl\:w-8\/12 { + width: 66.666667%; + } + + .xl\:w-9\/12 { + width: 75%; + } + + .xl\:w-10\/12 { + width: 83.333333%; + } + + .xl\:w-11\/12 { + width: 91.666667%; + } + + .xl\:w-full { + width: 100%; + } + + .xl\:w-screen { + width: 100vw; + } + + .xl\:z-0 { + z-index: 0; + } + + .xl\:z-10 { + z-index: 10; + } + + .xl\:z-20 { + z-index: 20; + } + + .xl\:z-30 { + z-index: 30; + } + + .xl\:z-40 { + z-index: 40; + } + + .xl\:z-50 { + z-index: 50; + } + + .xl\:z-auto { + z-index: auto; + } + + .xl\:gap-0 { + grid-gap: 0; + gap: 0; + } + + .xl\:gap-1 { + grid-gap: 0.25rem; + gap: 0.25rem; + } + + .xl\:gap-2 { + grid-gap: 0.5rem; + gap: 0.5rem; + } + + .xl\:gap-3 { + grid-gap: 0.75rem; + gap: 0.75rem; + } + + .xl\:gap-4 { + grid-gap: 1rem; + gap: 1rem; + } + + .xl\:gap-5 { + grid-gap: 1.25rem; + gap: 1.25rem; + } + + .xl\:gap-6 { + grid-gap: 1.5rem; + gap: 1.5rem; + } + + .xl\:gap-8 { + grid-gap: 2rem; + gap: 2rem; + } + + .xl\:gap-10 { + grid-gap: 2.5rem; + gap: 2.5rem; + } + + .xl\:gap-12 { + grid-gap: 3rem; + gap: 3rem; + } + + .xl\:gap-16 { + grid-gap: 4rem; + gap: 4rem; + } + + .xl\:gap-20 { + grid-gap: 5rem; + gap: 5rem; + } + + .xl\:gap-24 { + grid-gap: 6rem; + gap: 6rem; + } + + .xl\:gap-32 { + grid-gap: 8rem; + gap: 8rem; + } + + .xl\:gap-40 { + grid-gap: 10rem; + gap: 10rem; + } + + .xl\:gap-48 { + grid-gap: 12rem; + gap: 12rem; + } + + .xl\:gap-56 { + grid-gap: 14rem; + gap: 14rem; + } + + .xl\:gap-64 { + grid-gap: 16rem; + gap: 16rem; + } + + .xl\:gap-px { + grid-gap: 1px; + gap: 1px; + } + + .xl\:col-gap-0 { + grid-column-gap: 0; + column-gap: 0; + } + + .xl\:col-gap-1 { + grid-column-gap: 0.25rem; + column-gap: 0.25rem; + } + + .xl\:col-gap-2 { + grid-column-gap: 0.5rem; + column-gap: 0.5rem; + } + + .xl\:col-gap-3 { + grid-column-gap: 0.75rem; + column-gap: 0.75rem; + } + + .xl\:col-gap-4 { + grid-column-gap: 1rem; + column-gap: 1rem; + } + + .xl\:col-gap-5 { + grid-column-gap: 1.25rem; + column-gap: 1.25rem; + } + + .xl\:col-gap-6 { + grid-column-gap: 1.5rem; + column-gap: 1.5rem; + } + + .xl\:col-gap-8 { + grid-column-gap: 2rem; + column-gap: 2rem; + } + + .xl\:col-gap-10 { + grid-column-gap: 2.5rem; + column-gap: 2.5rem; + } + + .xl\:col-gap-12 { + grid-column-gap: 3rem; + column-gap: 3rem; + } + + .xl\:col-gap-16 { + grid-column-gap: 4rem; + column-gap: 4rem; + } + + .xl\:col-gap-20 { + grid-column-gap: 5rem; + column-gap: 5rem; + } + + .xl\:col-gap-24 { + grid-column-gap: 6rem; + column-gap: 6rem; + } + + .xl\:col-gap-32 { + grid-column-gap: 8rem; + column-gap: 8rem; + } + + .xl\:col-gap-40 { + grid-column-gap: 10rem; + column-gap: 10rem; + } + + .xl\:col-gap-48 { + grid-column-gap: 12rem; + column-gap: 12rem; + } + + .xl\:col-gap-56 { + grid-column-gap: 14rem; + column-gap: 14rem; + } + + .xl\:col-gap-64 { + grid-column-gap: 16rem; + column-gap: 16rem; + } + + .xl\:col-gap-px { + grid-column-gap: 1px; + column-gap: 1px; + } + + .xl\:row-gap-0 { + grid-row-gap: 0; + row-gap: 0; + } + + .xl\:row-gap-1 { + grid-row-gap: 0.25rem; + row-gap: 0.25rem; + } + + .xl\:row-gap-2 { + grid-row-gap: 0.5rem; + row-gap: 0.5rem; + } + + .xl\:row-gap-3 { + grid-row-gap: 0.75rem; + row-gap: 0.75rem; + } + + .xl\:row-gap-4 { + grid-row-gap: 1rem; + row-gap: 1rem; + } + + .xl\:row-gap-5 { + grid-row-gap: 1.25rem; + row-gap: 1.25rem; + } + + .xl\:row-gap-6 { + grid-row-gap: 1.5rem; + row-gap: 1.5rem; + } + + .xl\:row-gap-8 { + grid-row-gap: 2rem; + row-gap: 2rem; + } + + .xl\:row-gap-10 { + grid-row-gap: 2.5rem; + row-gap: 2.5rem; + } + + .xl\:row-gap-12 { + grid-row-gap: 3rem; + row-gap: 3rem; + } + + .xl\:row-gap-16 { + grid-row-gap: 4rem; + row-gap: 4rem; + } + + .xl\:row-gap-20 { + grid-row-gap: 5rem; + row-gap: 5rem; + } + + .xl\:row-gap-24 { + grid-row-gap: 6rem; + row-gap: 6rem; + } + + .xl\:row-gap-32 { + grid-row-gap: 8rem; + row-gap: 8rem; + } + + .xl\:row-gap-40 { + grid-row-gap: 10rem; + row-gap: 10rem; + } + + .xl\:row-gap-48 { + grid-row-gap: 12rem; + row-gap: 12rem; + } + + .xl\:row-gap-56 { + grid-row-gap: 14rem; + row-gap: 14rem; + } + + .xl\:row-gap-64 { + grid-row-gap: 16rem; + row-gap: 16rem; + } + + .xl\:row-gap-px { + grid-row-gap: 1px; + row-gap: 1px; + } + + .xl\:grid-flow-row { + grid-auto-flow: row; + } + + .xl\:grid-flow-col { + grid-auto-flow: column; + } + + .xl\:grid-flow-row-dense { + grid-auto-flow: row dense; + } + + .xl\:grid-flow-col-dense { + grid-auto-flow: column dense; + } + + .xl\:grid-cols-1 { + grid-template-columns: repeat(1, minmax(0, 1fr)); + } + + .xl\:grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .xl\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .xl\:grid-cols-4 { + grid-template-columns: repeat(4, minmax(0, 1fr)); + } + + .xl\:grid-cols-5 { + grid-template-columns: repeat(5, minmax(0, 1fr)); + } + + .xl\:grid-cols-6 { + grid-template-columns: repeat(6, minmax(0, 1fr)); + } + + .xl\:grid-cols-7 { + grid-template-columns: repeat(7, minmax(0, 1fr)); + } + + .xl\:grid-cols-8 { + grid-template-columns: repeat(8, minmax(0, 1fr)); + } + + .xl\:grid-cols-9 { + grid-template-columns: repeat(9, minmax(0, 1fr)); + } + + .xl\:grid-cols-10 { + grid-template-columns: repeat(10, minmax(0, 1fr)); + } + + .xl\:grid-cols-11 { + grid-template-columns: repeat(11, minmax(0, 1fr)); + } + + .xl\:grid-cols-12 { + grid-template-columns: repeat(12, minmax(0, 1fr)); + } + + .xl\:grid-cols-none { + grid-template-columns: none; + } + + .xl\:col-auto { + grid-column: auto; + } + + .xl\:col-span-1 { + grid-column: span 1 / span 1; + } + + .xl\:col-span-2 { + grid-column: span 2 / span 2; + } + + .xl\:col-span-3 { + grid-column: span 3 / span 3; + } + + .xl\:col-span-4 { + grid-column: span 4 / span 4; + } + + .xl\:col-span-5 { + grid-column: span 5 / span 5; + } + + .xl\:col-span-6 { + grid-column: span 6 / span 6; + } + + .xl\:col-span-7 { + grid-column: span 7 / span 7; + } + + .xl\:col-span-8 { + grid-column: span 8 / span 8; + } + + .xl\:col-span-9 { + grid-column: span 9 / span 9; + } + + .xl\:col-span-10 { + grid-column: span 10 / span 10; + } + + .xl\:col-span-11 { + grid-column: span 11 / span 11; + } + + .xl\:col-span-12 { + grid-column: span 12 / span 12; + } + + .xl\:col-start-1 { + grid-column-start: 1; + } + + .xl\:col-start-2 { + grid-column-start: 2; + } + + .xl\:col-start-3 { + grid-column-start: 3; + } + + .xl\:col-start-4 { + grid-column-start: 4; + } + + .xl\:col-start-5 { + grid-column-start: 5; + } + + .xl\:col-start-6 { + grid-column-start: 6; + } + + .xl\:col-start-7 { + grid-column-start: 7; + } + + .xl\:col-start-8 { + grid-column-start: 8; + } + + .xl\:col-start-9 { + grid-column-start: 9; + } + + .xl\:col-start-10 { + grid-column-start: 10; + } + + .xl\:col-start-11 { + grid-column-start: 11; + } + + .xl\:col-start-12 { + grid-column-start: 12; + } + + .xl\:col-start-13 { + grid-column-start: 13; + } + + .xl\:col-start-auto { + grid-column-start: auto; + } + + .xl\:col-end-1 { + grid-column-end: 1; + } + + .xl\:col-end-2 { + grid-column-end: 2; + } + + .xl\:col-end-3 { + grid-column-end: 3; + } + + .xl\:col-end-4 { + grid-column-end: 4; + } + + .xl\:col-end-5 { + grid-column-end: 5; + } + + .xl\:col-end-6 { + grid-column-end: 6; + } + + .xl\:col-end-7 { + grid-column-end: 7; + } + + .xl\:col-end-8 { + grid-column-end: 8; + } + + .xl\:col-end-9 { + grid-column-end: 9; + } + + .xl\:col-end-10 { + grid-column-end: 10; + } + + .xl\:col-end-11 { + grid-column-end: 11; + } + + .xl\:col-end-12 { + grid-column-end: 12; + } + + .xl\:col-end-13 { + grid-column-end: 13; + } + + .xl\:col-end-auto { + grid-column-end: auto; + } + + .xl\:grid-rows-1 { + grid-template-rows: repeat(1, minmax(0, 1fr)); + } + + .xl\:grid-rows-2 { + grid-template-rows: repeat(2, minmax(0, 1fr)); + } + + .xl\:grid-rows-3 { + grid-template-rows: repeat(3, minmax(0, 1fr)); + } + + .xl\:grid-rows-4 { + grid-template-rows: repeat(4, minmax(0, 1fr)); + } + + .xl\:grid-rows-5 { + grid-template-rows: repeat(5, minmax(0, 1fr)); + } + + .xl\:grid-rows-6 { + grid-template-rows: repeat(6, minmax(0, 1fr)); + } + + .xl\:grid-rows-none { + grid-template-rows: none; + } + + .xl\:row-auto { + grid-row: auto; + } + + .xl\:row-span-1 { + grid-row: span 1 / span 1; + } + + .xl\:row-span-2 { + grid-row: span 2 / span 2; + } + + .xl\:row-span-3 { + grid-row: span 3 / span 3; + } + + .xl\:row-span-4 { + grid-row: span 4 / span 4; + } + + .xl\:row-span-5 { + grid-row: span 5 / span 5; + } + + .xl\:row-span-6 { + grid-row: span 6 / span 6; + } + + .xl\:row-start-1 { + grid-row-start: 1; + } + + .xl\:row-start-2 { + grid-row-start: 2; + } + + .xl\:row-start-3 { + grid-row-start: 3; + } + + .xl\:row-start-4 { + grid-row-start: 4; + } + + .xl\:row-start-5 { + grid-row-start: 5; + } + + .xl\:row-start-6 { + grid-row-start: 6; + } + + .xl\:row-start-7 { + grid-row-start: 7; + } + + .xl\:row-start-auto { + grid-row-start: auto; + } + + .xl\:row-end-1 { + grid-row-end: 1; + } + + .xl\:row-end-2 { + grid-row-end: 2; + } + + .xl\:row-end-3 { + grid-row-end: 3; + } + + .xl\:row-end-4 { + grid-row-end: 4; + } + + .xl\:row-end-5 { + grid-row-end: 5; + } + + .xl\:row-end-6 { + grid-row-end: 6; + } + + .xl\:row-end-7 { + grid-row-end: 7; + } + + .xl\:row-end-auto { + grid-row-end: auto; + } + + .xl\:transform { + --transform-translate-x: 0; + --transform-translate-y: 0; + --transform-rotate: 0; + --transform-skew-x: 0; + --transform-skew-y: 0; + --transform-scale-x: 1; + --transform-scale-y: 1; + transform: translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y)); + } + + .xl\:transform-none { + transform: none; + } + + .xl\:origin-center { + transform-origin: center; + } + + .xl\:origin-top { + transform-origin: top; + } + + .xl\:origin-top-right { + transform-origin: top right; + } + + .xl\:origin-right { + transform-origin: right; + } + + .xl\:origin-bottom-right { + transform-origin: bottom right; + } + + .xl\:origin-bottom { + transform-origin: bottom; + } + + .xl\:origin-bottom-left { + transform-origin: bottom left; + } + + .xl\:origin-left { + transform-origin: left; + } + + .xl\:origin-top-left { + transform-origin: top left; + } + + .xl\:scale-0 { + --transform-scale-x: 0; + --transform-scale-y: 0; + } + + .xl\:scale-50 { + --transform-scale-x: .5; + --transform-scale-y: .5; + } + + .xl\:scale-75 { + --transform-scale-x: .75; + --transform-scale-y: .75; + } + + .xl\:scale-90 { + --transform-scale-x: .9; + --transform-scale-y: .9; + } + + .xl\:scale-95 { + --transform-scale-x: .95; + --transform-scale-y: .95; + } + + .xl\:scale-100 { + --transform-scale-x: 1; + --transform-scale-y: 1; + } + + .xl\:scale-105 { + --transform-scale-x: 1.05; + --transform-scale-y: 1.05; + } + + .xl\:scale-110 { + --transform-scale-x: 1.1; + --transform-scale-y: 1.1; + } + + .xl\:scale-125 { + --transform-scale-x: 1.25; + --transform-scale-y: 1.25; + } + + .xl\:scale-150 { + --transform-scale-x: 1.5; + --transform-scale-y: 1.5; + } + + .xl\:scale-x-0 { + --transform-scale-x: 0; + } + + .xl\:scale-x-50 { + --transform-scale-x: .5; + } + + .xl\:scale-x-75 { + --transform-scale-x: .75; + } + + .xl\:scale-x-90 { + --transform-scale-x: .9; + } + + .xl\:scale-x-95 { + --transform-scale-x: .95; + } + + .xl\:scale-x-100 { + --transform-scale-x: 1; + } + + .xl\:scale-x-105 { + --transform-scale-x: 1.05; + } + + .xl\:scale-x-110 { + --transform-scale-x: 1.1; + } + + .xl\:scale-x-125 { + --transform-scale-x: 1.25; + } + + .xl\:scale-x-150 { + --transform-scale-x: 1.5; + } + + .xl\:scale-y-0 { + --transform-scale-y: 0; + } + + .xl\:scale-y-50 { + --transform-scale-y: .5; + } + + .xl\:scale-y-75 { + --transform-scale-y: .75; + } + + .xl\:scale-y-90 { + --transform-scale-y: .9; + } + + .xl\:scale-y-95 { + --transform-scale-y: .95; + } + + .xl\:scale-y-100 { + --transform-scale-y: 1; + } + + .xl\:scale-y-105 { + --transform-scale-y: 1.05; + } + + .xl\:scale-y-110 { + --transform-scale-y: 1.1; + } + + .xl\:scale-y-125 { + --transform-scale-y: 1.25; + } + + .xl\:scale-y-150 { + --transform-scale-y: 1.5; + } + + .xl\:hover\:scale-0:hover { + --transform-scale-x: 0; + --transform-scale-y: 0; + } + + .xl\:hover\:scale-50:hover { + --transform-scale-x: .5; + --transform-scale-y: .5; + } + + .xl\:hover\:scale-75:hover { + --transform-scale-x: .75; + --transform-scale-y: .75; + } + + .xl\:hover\:scale-90:hover { + --transform-scale-x: .9; + --transform-scale-y: .9; + } + + .xl\:hover\:scale-95:hover { + --transform-scale-x: .95; + --transform-scale-y: .95; + } + + .xl\:hover\:scale-100:hover { + --transform-scale-x: 1; + --transform-scale-y: 1; + } + + .xl\:hover\:scale-105:hover { + --transform-scale-x: 1.05; + --transform-scale-y: 1.05; + } + + .xl\:hover\:scale-110:hover { + --transform-scale-x: 1.1; + --transform-scale-y: 1.1; + } + + .xl\:hover\:scale-125:hover { + --transform-scale-x: 1.25; + --transform-scale-y: 1.25; + } + + .xl\:hover\:scale-150:hover { + --transform-scale-x: 1.5; + --transform-scale-y: 1.5; + } + + .xl\:hover\:scale-x-0:hover { + --transform-scale-x: 0; + } + + .xl\:hover\:scale-x-50:hover { + --transform-scale-x: .5; + } + + .xl\:hover\:scale-x-75:hover { + --transform-scale-x: .75; + } + + .xl\:hover\:scale-x-90:hover { + --transform-scale-x: .9; + } + + .xl\:hover\:scale-x-95:hover { + --transform-scale-x: .95; + } + + .xl\:hover\:scale-x-100:hover { + --transform-scale-x: 1; + } + + .xl\:hover\:scale-x-105:hover { + --transform-scale-x: 1.05; + } + + .xl\:hover\:scale-x-110:hover { + --transform-scale-x: 1.1; + } + + .xl\:hover\:scale-x-125:hover { + --transform-scale-x: 1.25; + } + + .xl\:hover\:scale-x-150:hover { + --transform-scale-x: 1.5; + } + + .xl\:hover\:scale-y-0:hover { + --transform-scale-y: 0; + } + + .xl\:hover\:scale-y-50:hover { + --transform-scale-y: .5; + } + + .xl\:hover\:scale-y-75:hover { + --transform-scale-y: .75; + } + + .xl\:hover\:scale-y-90:hover { + --transform-scale-y: .9; + } + + .xl\:hover\:scale-y-95:hover { + --transform-scale-y: .95; + } + + .xl\:hover\:scale-y-100:hover { + --transform-scale-y: 1; + } + + .xl\:hover\:scale-y-105:hover { + --transform-scale-y: 1.05; + } + + .xl\:hover\:scale-y-110:hover { + --transform-scale-y: 1.1; + } + + .xl\:hover\:scale-y-125:hover { + --transform-scale-y: 1.25; + } + + .xl\:hover\:scale-y-150:hover { + --transform-scale-y: 1.5; + } + + .xl\:focus\:scale-0:focus { + --transform-scale-x: 0; + --transform-scale-y: 0; + } + + .xl\:focus\:scale-50:focus { + --transform-scale-x: .5; + --transform-scale-y: .5; + } + + .xl\:focus\:scale-75:focus { + --transform-scale-x: .75; + --transform-scale-y: .75; + } + + .xl\:focus\:scale-90:focus { + --transform-scale-x: .9; + --transform-scale-y: .9; + } + + .xl\:focus\:scale-95:focus { + --transform-scale-x: .95; + --transform-scale-y: .95; + } + + .xl\:focus\:scale-100:focus { + --transform-scale-x: 1; + --transform-scale-y: 1; + } + + .xl\:focus\:scale-105:focus { + --transform-scale-x: 1.05; + --transform-scale-y: 1.05; + } + + .xl\:focus\:scale-110:focus { + --transform-scale-x: 1.1; + --transform-scale-y: 1.1; + } + + .xl\:focus\:scale-125:focus { + --transform-scale-x: 1.25; + --transform-scale-y: 1.25; + } + + .xl\:focus\:scale-150:focus { + --transform-scale-x: 1.5; + --transform-scale-y: 1.5; + } + + .xl\:focus\:scale-x-0:focus { + --transform-scale-x: 0; + } + + .xl\:focus\:scale-x-50:focus { + --transform-scale-x: .5; + } + + .xl\:focus\:scale-x-75:focus { + --transform-scale-x: .75; + } + + .xl\:focus\:scale-x-90:focus { + --transform-scale-x: .9; + } + + .xl\:focus\:scale-x-95:focus { + --transform-scale-x: .95; + } + + .xl\:focus\:scale-x-100:focus { + --transform-scale-x: 1; + } + + .xl\:focus\:scale-x-105:focus { + --transform-scale-x: 1.05; + } + + .xl\:focus\:scale-x-110:focus { + --transform-scale-x: 1.1; + } + + .xl\:focus\:scale-x-125:focus { + --transform-scale-x: 1.25; + } + + .xl\:focus\:scale-x-150:focus { + --transform-scale-x: 1.5; + } + + .xl\:focus\:scale-y-0:focus { + --transform-scale-y: 0; + } + + .xl\:focus\:scale-y-50:focus { + --transform-scale-y: .5; + } + + .xl\:focus\:scale-y-75:focus { + --transform-scale-y: .75; + } + + .xl\:focus\:scale-y-90:focus { + --transform-scale-y: .9; + } + + .xl\:focus\:scale-y-95:focus { + --transform-scale-y: .95; + } + + .xl\:focus\:scale-y-100:focus { + --transform-scale-y: 1; + } + + .xl\:focus\:scale-y-105:focus { + --transform-scale-y: 1.05; + } + + .xl\:focus\:scale-y-110:focus { + --transform-scale-y: 1.1; + } + + .xl\:focus\:scale-y-125:focus { + --transform-scale-y: 1.25; + } + + .xl\:focus\:scale-y-150:focus { + --transform-scale-y: 1.5; + } + + .xl\:rotate-0 { + --transform-rotate: 0; + } + + .xl\:rotate-45 { + --transform-rotate: 45deg; + } + + .xl\:rotate-90 { + --transform-rotate: 90deg; + } + + .xl\:rotate-180 { + --transform-rotate: 180deg; + } + + .xl\:-rotate-180 { + --transform-rotate: -180deg; + } + + .xl\:-rotate-90 { + --transform-rotate: -90deg; + } + + .xl\:-rotate-45 { + --transform-rotate: -45deg; + } + + .xl\:hover\:rotate-0:hover { + --transform-rotate: 0; + } + + .xl\:hover\:rotate-45:hover { + --transform-rotate: 45deg; + } + + .xl\:hover\:rotate-90:hover { + --transform-rotate: 90deg; + } + + .xl\:hover\:rotate-180:hover { + --transform-rotate: 180deg; + } + + .xl\:hover\:-rotate-180:hover { + --transform-rotate: -180deg; + } + + .xl\:hover\:-rotate-90:hover { + --transform-rotate: -90deg; + } + + .xl\:hover\:-rotate-45:hover { + --transform-rotate: -45deg; + } + + .xl\:focus\:rotate-0:focus { + --transform-rotate: 0; + } + + .xl\:focus\:rotate-45:focus { + --transform-rotate: 45deg; + } + + .xl\:focus\:rotate-90:focus { + --transform-rotate: 90deg; + } + + .xl\:focus\:rotate-180:focus { + --transform-rotate: 180deg; + } + + .xl\:focus\:-rotate-180:focus { + --transform-rotate: -180deg; + } + + .xl\:focus\:-rotate-90:focus { + --transform-rotate: -90deg; + } + + .xl\:focus\:-rotate-45:focus { + --transform-rotate: -45deg; + } + + .xl\:translate-x-0 { + --transform-translate-x: 0; + } + + .xl\:translate-x-1 { + --transform-translate-x: 0.25rem; + } + + .xl\:translate-x-2 { + --transform-translate-x: 0.5rem; + } + + .xl\:translate-x-3 { + --transform-translate-x: 0.75rem; + } + + .xl\:translate-x-4 { + --transform-translate-x: 1rem; + } + + .xl\:translate-x-5 { + --transform-translate-x: 1.25rem; + } + + .xl\:translate-x-6 { + --transform-translate-x: 1.5rem; + } + + .xl\:translate-x-8 { + --transform-translate-x: 2rem; + } + + .xl\:translate-x-10 { + --transform-translate-x: 2.5rem; + } + + .xl\:translate-x-12 { + --transform-translate-x: 3rem; + } + + .xl\:translate-x-16 { + --transform-translate-x: 4rem; + } + + .xl\:translate-x-20 { + --transform-translate-x: 5rem; + } + + .xl\:translate-x-24 { + --transform-translate-x: 6rem; + } + + .xl\:translate-x-32 { + --transform-translate-x: 8rem; + } + + .xl\:translate-x-40 { + --transform-translate-x: 10rem; + } + + .xl\:translate-x-48 { + --transform-translate-x: 12rem; + } + + .xl\:translate-x-56 { + --transform-translate-x: 14rem; + } + + .xl\:translate-x-64 { + --transform-translate-x: 16rem; + } + + .xl\:translate-x-px { + --transform-translate-x: 1px; + } + + .xl\:-translate-x-1 { + --transform-translate-x: -0.25rem; + } + + .xl\:-translate-x-2 { + --transform-translate-x: -0.5rem; + } + + .xl\:-translate-x-3 { + --transform-translate-x: -0.75rem; + } + + .xl\:-translate-x-4 { + --transform-translate-x: -1rem; + } + + .xl\:-translate-x-5 { + --transform-translate-x: -1.25rem; + } + + .xl\:-translate-x-6 { + --transform-translate-x: -1.5rem; + } + + .xl\:-translate-x-8 { + --transform-translate-x: -2rem; + } + + .xl\:-translate-x-10 { + --transform-translate-x: -2.5rem; + } + + .xl\:-translate-x-12 { + --transform-translate-x: -3rem; + } + + .xl\:-translate-x-16 { + --transform-translate-x: -4rem; + } + + .xl\:-translate-x-20 { + --transform-translate-x: -5rem; + } + + .xl\:-translate-x-24 { + --transform-translate-x: -6rem; + } + + .xl\:-translate-x-32 { + --transform-translate-x: -8rem; + } + + .xl\:-translate-x-40 { + --transform-translate-x: -10rem; + } + + .xl\:-translate-x-48 { + --transform-translate-x: -12rem; + } + + .xl\:-translate-x-56 { + --transform-translate-x: -14rem; + } + + .xl\:-translate-x-64 { + --transform-translate-x: -16rem; + } + + .xl\:-translate-x-px { + --transform-translate-x: -1px; + } + + .xl\:-translate-x-full { + --transform-translate-x: -100%; + } + + .xl\:-translate-x-1\/2 { + --transform-translate-x: -50%; + } + + .xl\:translate-x-1\/2 { + --transform-translate-x: 50%; + } + + .xl\:translate-x-full { + --transform-translate-x: 100%; + } + + .xl\:translate-y-0 { + --transform-translate-y: 0; + } + + .xl\:translate-y-1 { + --transform-translate-y: 0.25rem; + } + + .xl\:translate-y-2 { + --transform-translate-y: 0.5rem; + } + + .xl\:translate-y-3 { + --transform-translate-y: 0.75rem; + } + + .xl\:translate-y-4 { + --transform-translate-y: 1rem; + } + + .xl\:translate-y-5 { + --transform-translate-y: 1.25rem; + } + + .xl\:translate-y-6 { + --transform-translate-y: 1.5rem; + } + + .xl\:translate-y-8 { + --transform-translate-y: 2rem; + } + + .xl\:translate-y-10 { + --transform-translate-y: 2.5rem; + } + + .xl\:translate-y-12 { + --transform-translate-y: 3rem; + } + + .xl\:translate-y-16 { + --transform-translate-y: 4rem; + } + + .xl\:translate-y-20 { + --transform-translate-y: 5rem; + } + + .xl\:translate-y-24 { + --transform-translate-y: 6rem; + } + + .xl\:translate-y-32 { + --transform-translate-y: 8rem; + } + + .xl\:translate-y-40 { + --transform-translate-y: 10rem; + } + + .xl\:translate-y-48 { + --transform-translate-y: 12rem; + } + + .xl\:translate-y-56 { + --transform-translate-y: 14rem; + } + + .xl\:translate-y-64 { + --transform-translate-y: 16rem; + } + + .xl\:translate-y-px { + --transform-translate-y: 1px; + } + + .xl\:-translate-y-1 { + --transform-translate-y: -0.25rem; + } + + .xl\:-translate-y-2 { + --transform-translate-y: -0.5rem; + } + + .xl\:-translate-y-3 { + --transform-translate-y: -0.75rem; + } + + .xl\:-translate-y-4 { + --transform-translate-y: -1rem; + } + + .xl\:-translate-y-5 { + --transform-translate-y: -1.25rem; + } + + .xl\:-translate-y-6 { + --transform-translate-y: -1.5rem; + } + + .xl\:-translate-y-8 { + --transform-translate-y: -2rem; + } + + .xl\:-translate-y-10 { + --transform-translate-y: -2.5rem; + } + + .xl\:-translate-y-12 { + --transform-translate-y: -3rem; + } + + .xl\:-translate-y-16 { + --transform-translate-y: -4rem; + } + + .xl\:-translate-y-20 { + --transform-translate-y: -5rem; + } + + .xl\:-translate-y-24 { + --transform-translate-y: -6rem; + } + + .xl\:-translate-y-32 { + --transform-translate-y: -8rem; + } + + .xl\:-translate-y-40 { + --transform-translate-y: -10rem; + } + + .xl\:-translate-y-48 { + --transform-translate-y: -12rem; + } + + .xl\:-translate-y-56 { + --transform-translate-y: -14rem; + } + + .xl\:-translate-y-64 { + --transform-translate-y: -16rem; + } + + .xl\:-translate-y-px { + --transform-translate-y: -1px; + } + + .xl\:-translate-y-full { + --transform-translate-y: -100%; + } + + .xl\:-translate-y-1\/2 { + --transform-translate-y: -50%; + } + + .xl\:translate-y-1\/2 { + --transform-translate-y: 50%; + } + + .xl\:translate-y-full { + --transform-translate-y: 100%; + } + + .xl\:hover\:translate-x-0:hover { + --transform-translate-x: 0; + } + + .xl\:hover\:translate-x-1:hover { + --transform-translate-x: 0.25rem; + } + + .xl\:hover\:translate-x-2:hover { + --transform-translate-x: 0.5rem; + } + + .xl\:hover\:translate-x-3:hover { + --transform-translate-x: 0.75rem; + } + + .xl\:hover\:translate-x-4:hover { + --transform-translate-x: 1rem; + } + + .xl\:hover\:translate-x-5:hover { + --transform-translate-x: 1.25rem; + } + + .xl\:hover\:translate-x-6:hover { + --transform-translate-x: 1.5rem; + } + + .xl\:hover\:translate-x-8:hover { + --transform-translate-x: 2rem; + } + + .xl\:hover\:translate-x-10:hover { + --transform-translate-x: 2.5rem; + } + + .xl\:hover\:translate-x-12:hover { + --transform-translate-x: 3rem; + } + + .xl\:hover\:translate-x-16:hover { + --transform-translate-x: 4rem; + } + + .xl\:hover\:translate-x-20:hover { + --transform-translate-x: 5rem; + } + + .xl\:hover\:translate-x-24:hover { + --transform-translate-x: 6rem; + } + + .xl\:hover\:translate-x-32:hover { + --transform-translate-x: 8rem; + } + + .xl\:hover\:translate-x-40:hover { + --transform-translate-x: 10rem; + } + + .xl\:hover\:translate-x-48:hover { + --transform-translate-x: 12rem; + } + + .xl\:hover\:translate-x-56:hover { + --transform-translate-x: 14rem; + } + + .xl\:hover\:translate-x-64:hover { + --transform-translate-x: 16rem; + } + + .xl\:hover\:translate-x-px:hover { + --transform-translate-x: 1px; + } + + .xl\:hover\:-translate-x-1:hover { + --transform-translate-x: -0.25rem; + } + + .xl\:hover\:-translate-x-2:hover { + --transform-translate-x: -0.5rem; + } + + .xl\:hover\:-translate-x-3:hover { + --transform-translate-x: -0.75rem; + } + + .xl\:hover\:-translate-x-4:hover { + --transform-translate-x: -1rem; + } + + .xl\:hover\:-translate-x-5:hover { + --transform-translate-x: -1.25rem; + } + + .xl\:hover\:-translate-x-6:hover { + --transform-translate-x: -1.5rem; + } + + .xl\:hover\:-translate-x-8:hover { + --transform-translate-x: -2rem; + } + + .xl\:hover\:-translate-x-10:hover { + --transform-translate-x: -2.5rem; + } + + .xl\:hover\:-translate-x-12:hover { + --transform-translate-x: -3rem; + } + + .xl\:hover\:-translate-x-16:hover { + --transform-translate-x: -4rem; + } + + .xl\:hover\:-translate-x-20:hover { + --transform-translate-x: -5rem; + } + + .xl\:hover\:-translate-x-24:hover { + --transform-translate-x: -6rem; + } + + .xl\:hover\:-translate-x-32:hover { + --transform-translate-x: -8rem; + } + + .xl\:hover\:-translate-x-40:hover { + --transform-translate-x: -10rem; + } + + .xl\:hover\:-translate-x-48:hover { + --transform-translate-x: -12rem; + } + + .xl\:hover\:-translate-x-56:hover { + --transform-translate-x: -14rem; + } + + .xl\:hover\:-translate-x-64:hover { + --transform-translate-x: -16rem; + } + + .xl\:hover\:-translate-x-px:hover { + --transform-translate-x: -1px; + } + + .xl\:hover\:-translate-x-full:hover { + --transform-translate-x: -100%; + } + + .xl\:hover\:-translate-x-1\/2:hover { + --transform-translate-x: -50%; + } + + .xl\:hover\:translate-x-1\/2:hover { + --transform-translate-x: 50%; + } + + .xl\:hover\:translate-x-full:hover { + --transform-translate-x: 100%; + } + + .xl\:hover\:translate-y-0:hover { + --transform-translate-y: 0; + } + + .xl\:hover\:translate-y-1:hover { + --transform-translate-y: 0.25rem; + } + + .xl\:hover\:translate-y-2:hover { + --transform-translate-y: 0.5rem; + } + + .xl\:hover\:translate-y-3:hover { + --transform-translate-y: 0.75rem; + } + + .xl\:hover\:translate-y-4:hover { + --transform-translate-y: 1rem; + } + + .xl\:hover\:translate-y-5:hover { + --transform-translate-y: 1.25rem; + } + + .xl\:hover\:translate-y-6:hover { + --transform-translate-y: 1.5rem; + } + + .xl\:hover\:translate-y-8:hover { + --transform-translate-y: 2rem; + } + + .xl\:hover\:translate-y-10:hover { + --transform-translate-y: 2.5rem; + } + + .xl\:hover\:translate-y-12:hover { + --transform-translate-y: 3rem; + } + + .xl\:hover\:translate-y-16:hover { + --transform-translate-y: 4rem; + } + + .xl\:hover\:translate-y-20:hover { + --transform-translate-y: 5rem; + } + + .xl\:hover\:translate-y-24:hover { + --transform-translate-y: 6rem; + } + + .xl\:hover\:translate-y-32:hover { + --transform-translate-y: 8rem; + } + + .xl\:hover\:translate-y-40:hover { + --transform-translate-y: 10rem; + } + + .xl\:hover\:translate-y-48:hover { + --transform-translate-y: 12rem; + } + + .xl\:hover\:translate-y-56:hover { + --transform-translate-y: 14rem; + } + + .xl\:hover\:translate-y-64:hover { + --transform-translate-y: 16rem; + } + + .xl\:hover\:translate-y-px:hover { + --transform-translate-y: 1px; + } + + .xl\:hover\:-translate-y-1:hover { + --transform-translate-y: -0.25rem; + } + + .xl\:hover\:-translate-y-2:hover { + --transform-translate-y: -0.5rem; + } + + .xl\:hover\:-translate-y-3:hover { + --transform-translate-y: -0.75rem; + } + + .xl\:hover\:-translate-y-4:hover { + --transform-translate-y: -1rem; + } + + .xl\:hover\:-translate-y-5:hover { + --transform-translate-y: -1.25rem; + } + + .xl\:hover\:-translate-y-6:hover { + --transform-translate-y: -1.5rem; + } + + .xl\:hover\:-translate-y-8:hover { + --transform-translate-y: -2rem; + } + + .xl\:hover\:-translate-y-10:hover { + --transform-translate-y: -2.5rem; + } + + .xl\:hover\:-translate-y-12:hover { + --transform-translate-y: -3rem; + } + + .xl\:hover\:-translate-y-16:hover { + --transform-translate-y: -4rem; + } + + .xl\:hover\:-translate-y-20:hover { + --transform-translate-y: -5rem; + } + + .xl\:hover\:-translate-y-24:hover { + --transform-translate-y: -6rem; + } + + .xl\:hover\:-translate-y-32:hover { + --transform-translate-y: -8rem; + } + + .xl\:hover\:-translate-y-40:hover { + --transform-translate-y: -10rem; + } + + .xl\:hover\:-translate-y-48:hover { + --transform-translate-y: -12rem; + } + + .xl\:hover\:-translate-y-56:hover { + --transform-translate-y: -14rem; + } + + .xl\:hover\:-translate-y-64:hover { + --transform-translate-y: -16rem; + } + + .xl\:hover\:-translate-y-px:hover { + --transform-translate-y: -1px; + } + + .xl\:hover\:-translate-y-full:hover { + --transform-translate-y: -100%; + } + + .xl\:hover\:-translate-y-1\/2:hover { + --transform-translate-y: -50%; + } + + .xl\:hover\:translate-y-1\/2:hover { + --transform-translate-y: 50%; + } + + .xl\:hover\:translate-y-full:hover { + --transform-translate-y: 100%; + } + + .xl\:focus\:translate-x-0:focus { + --transform-translate-x: 0; + } + + .xl\:focus\:translate-x-1:focus { + --transform-translate-x: 0.25rem; + } + + .xl\:focus\:translate-x-2:focus { + --transform-translate-x: 0.5rem; + } + + .xl\:focus\:translate-x-3:focus { + --transform-translate-x: 0.75rem; + } + + .xl\:focus\:translate-x-4:focus { + --transform-translate-x: 1rem; + } + + .xl\:focus\:translate-x-5:focus { + --transform-translate-x: 1.25rem; + } + + .xl\:focus\:translate-x-6:focus { + --transform-translate-x: 1.5rem; + } + + .xl\:focus\:translate-x-8:focus { + --transform-translate-x: 2rem; + } + + .xl\:focus\:translate-x-10:focus { + --transform-translate-x: 2.5rem; + } + + .xl\:focus\:translate-x-12:focus { + --transform-translate-x: 3rem; + } + + .xl\:focus\:translate-x-16:focus { + --transform-translate-x: 4rem; + } + + .xl\:focus\:translate-x-20:focus { + --transform-translate-x: 5rem; + } + + .xl\:focus\:translate-x-24:focus { + --transform-translate-x: 6rem; + } + + .xl\:focus\:translate-x-32:focus { + --transform-translate-x: 8rem; + } + + .xl\:focus\:translate-x-40:focus { + --transform-translate-x: 10rem; + } + + .xl\:focus\:translate-x-48:focus { + --transform-translate-x: 12rem; + } + + .xl\:focus\:translate-x-56:focus { + --transform-translate-x: 14rem; + } + + .xl\:focus\:translate-x-64:focus { + --transform-translate-x: 16rem; + } + + .xl\:focus\:translate-x-px:focus { + --transform-translate-x: 1px; + } + + .xl\:focus\:-translate-x-1:focus { + --transform-translate-x: -0.25rem; + } + + .xl\:focus\:-translate-x-2:focus { + --transform-translate-x: -0.5rem; + } + + .xl\:focus\:-translate-x-3:focus { + --transform-translate-x: -0.75rem; + } + + .xl\:focus\:-translate-x-4:focus { + --transform-translate-x: -1rem; + } + + .xl\:focus\:-translate-x-5:focus { + --transform-translate-x: -1.25rem; + } + + .xl\:focus\:-translate-x-6:focus { + --transform-translate-x: -1.5rem; + } + + .xl\:focus\:-translate-x-8:focus { + --transform-translate-x: -2rem; + } + + .xl\:focus\:-translate-x-10:focus { + --transform-translate-x: -2.5rem; + } + + .xl\:focus\:-translate-x-12:focus { + --transform-translate-x: -3rem; + } + + .xl\:focus\:-translate-x-16:focus { + --transform-translate-x: -4rem; + } + + .xl\:focus\:-translate-x-20:focus { + --transform-translate-x: -5rem; + } + + .xl\:focus\:-translate-x-24:focus { + --transform-translate-x: -6rem; + } + + .xl\:focus\:-translate-x-32:focus { + --transform-translate-x: -8rem; + } + + .xl\:focus\:-translate-x-40:focus { + --transform-translate-x: -10rem; + } + + .xl\:focus\:-translate-x-48:focus { + --transform-translate-x: -12rem; + } + + .xl\:focus\:-translate-x-56:focus { + --transform-translate-x: -14rem; + } + + .xl\:focus\:-translate-x-64:focus { + --transform-translate-x: -16rem; + } + + .xl\:focus\:-translate-x-px:focus { + --transform-translate-x: -1px; + } + + .xl\:focus\:-translate-x-full:focus { + --transform-translate-x: -100%; + } + + .xl\:focus\:-translate-x-1\/2:focus { + --transform-translate-x: -50%; + } + + .xl\:focus\:translate-x-1\/2:focus { + --transform-translate-x: 50%; + } + + .xl\:focus\:translate-x-full:focus { + --transform-translate-x: 100%; + } + + .xl\:focus\:translate-y-0:focus { + --transform-translate-y: 0; + } + + .xl\:focus\:translate-y-1:focus { + --transform-translate-y: 0.25rem; + } + + .xl\:focus\:translate-y-2:focus { + --transform-translate-y: 0.5rem; + } + + .xl\:focus\:translate-y-3:focus { + --transform-translate-y: 0.75rem; + } + + .xl\:focus\:translate-y-4:focus { + --transform-translate-y: 1rem; + } + + .xl\:focus\:translate-y-5:focus { + --transform-translate-y: 1.25rem; + } + + .xl\:focus\:translate-y-6:focus { + --transform-translate-y: 1.5rem; + } + + .xl\:focus\:translate-y-8:focus { + --transform-translate-y: 2rem; + } + + .xl\:focus\:translate-y-10:focus { + --transform-translate-y: 2.5rem; + } + + .xl\:focus\:translate-y-12:focus { + --transform-translate-y: 3rem; + } + + .xl\:focus\:translate-y-16:focus { + --transform-translate-y: 4rem; + } + + .xl\:focus\:translate-y-20:focus { + --transform-translate-y: 5rem; + } + + .xl\:focus\:translate-y-24:focus { + --transform-translate-y: 6rem; + } + + .xl\:focus\:translate-y-32:focus { + --transform-translate-y: 8rem; + } + + .xl\:focus\:translate-y-40:focus { + --transform-translate-y: 10rem; + } + + .xl\:focus\:translate-y-48:focus { + --transform-translate-y: 12rem; + } + + .xl\:focus\:translate-y-56:focus { + --transform-translate-y: 14rem; + } + + .xl\:focus\:translate-y-64:focus { + --transform-translate-y: 16rem; + } + + .xl\:focus\:translate-y-px:focus { + --transform-translate-y: 1px; + } + + .xl\:focus\:-translate-y-1:focus { + --transform-translate-y: -0.25rem; + } + + .xl\:focus\:-translate-y-2:focus { + --transform-translate-y: -0.5rem; + } + + .xl\:focus\:-translate-y-3:focus { + --transform-translate-y: -0.75rem; + } + + .xl\:focus\:-translate-y-4:focus { + --transform-translate-y: -1rem; + } + + .xl\:focus\:-translate-y-5:focus { + --transform-translate-y: -1.25rem; + } + + .xl\:focus\:-translate-y-6:focus { + --transform-translate-y: -1.5rem; + } + + .xl\:focus\:-translate-y-8:focus { + --transform-translate-y: -2rem; + } + + .xl\:focus\:-translate-y-10:focus { + --transform-translate-y: -2.5rem; + } + + .xl\:focus\:-translate-y-12:focus { + --transform-translate-y: -3rem; + } + + .xl\:focus\:-translate-y-16:focus { + --transform-translate-y: -4rem; + } + + .xl\:focus\:-translate-y-20:focus { + --transform-translate-y: -5rem; + } + + .xl\:focus\:-translate-y-24:focus { + --transform-translate-y: -6rem; + } + + .xl\:focus\:-translate-y-32:focus { + --transform-translate-y: -8rem; + } + + .xl\:focus\:-translate-y-40:focus { + --transform-translate-y: -10rem; + } + + .xl\:focus\:-translate-y-48:focus { + --transform-translate-y: -12rem; + } + + .xl\:focus\:-translate-y-56:focus { + --transform-translate-y: -14rem; + } + + .xl\:focus\:-translate-y-64:focus { + --transform-translate-y: -16rem; + } + + .xl\:focus\:-translate-y-px:focus { + --transform-translate-y: -1px; + } + + .xl\:focus\:-translate-y-full:focus { + --transform-translate-y: -100%; + } + + .xl\:focus\:-translate-y-1\/2:focus { + --transform-translate-y: -50%; + } + + .xl\:focus\:translate-y-1\/2:focus { + --transform-translate-y: 50%; + } + + .xl\:focus\:translate-y-full:focus { + --transform-translate-y: 100%; + } + + .xl\:skew-x-0 { + --transform-skew-x: 0; + } + + .xl\:skew-x-3 { + --transform-skew-x: 3deg; + } + + .xl\:skew-x-6 { + --transform-skew-x: 6deg; + } + + .xl\:skew-x-12 { + --transform-skew-x: 12deg; + } + + .xl\:-skew-x-12 { + --transform-skew-x: -12deg; + } + + .xl\:-skew-x-6 { + --transform-skew-x: -6deg; + } + + .xl\:-skew-x-3 { + --transform-skew-x: -3deg; + } + + .xl\:skew-y-0 { + --transform-skew-y: 0; + } + + .xl\:skew-y-3 { + --transform-skew-y: 3deg; + } + + .xl\:skew-y-6 { + --transform-skew-y: 6deg; + } + + .xl\:skew-y-12 { + --transform-skew-y: 12deg; + } + + .xl\:-skew-y-12 { + --transform-skew-y: -12deg; + } + + .xl\:-skew-y-6 { + --transform-skew-y: -6deg; + } + + .xl\:-skew-y-3 { + --transform-skew-y: -3deg; + } + + .xl\:hover\:skew-x-0:hover { + --transform-skew-x: 0; + } + + .xl\:hover\:skew-x-3:hover { + --transform-skew-x: 3deg; + } + + .xl\:hover\:skew-x-6:hover { + --transform-skew-x: 6deg; + } + + .xl\:hover\:skew-x-12:hover { + --transform-skew-x: 12deg; + } + + .xl\:hover\:-skew-x-12:hover { + --transform-skew-x: -12deg; + } + + .xl\:hover\:-skew-x-6:hover { + --transform-skew-x: -6deg; + } + + .xl\:hover\:-skew-x-3:hover { + --transform-skew-x: -3deg; + } + + .xl\:hover\:skew-y-0:hover { + --transform-skew-y: 0; + } + + .xl\:hover\:skew-y-3:hover { + --transform-skew-y: 3deg; + } + + .xl\:hover\:skew-y-6:hover { + --transform-skew-y: 6deg; + } + + .xl\:hover\:skew-y-12:hover { + --transform-skew-y: 12deg; + } + + .xl\:hover\:-skew-y-12:hover { + --transform-skew-y: -12deg; + } + + .xl\:hover\:-skew-y-6:hover { + --transform-skew-y: -6deg; + } + + .xl\:hover\:-skew-y-3:hover { + --transform-skew-y: -3deg; + } + + .xl\:focus\:skew-x-0:focus { + --transform-skew-x: 0; + } + + .xl\:focus\:skew-x-3:focus { + --transform-skew-x: 3deg; + } + + .xl\:focus\:skew-x-6:focus { + --transform-skew-x: 6deg; + } + + .xl\:focus\:skew-x-12:focus { + --transform-skew-x: 12deg; + } + + .xl\:focus\:-skew-x-12:focus { + --transform-skew-x: -12deg; + } + + .xl\:focus\:-skew-x-6:focus { + --transform-skew-x: -6deg; + } + + .xl\:focus\:-skew-x-3:focus { + --transform-skew-x: -3deg; + } + + .xl\:focus\:skew-y-0:focus { + --transform-skew-y: 0; + } + + .xl\:focus\:skew-y-3:focus { + --transform-skew-y: 3deg; + } + + .xl\:focus\:skew-y-6:focus { + --transform-skew-y: 6deg; + } + + .xl\:focus\:skew-y-12:focus { + --transform-skew-y: 12deg; + } + + .xl\:focus\:-skew-y-12:focus { + --transform-skew-y: -12deg; + } + + .xl\:focus\:-skew-y-6:focus { + --transform-skew-y: -6deg; + } + + .xl\:focus\:-skew-y-3:focus { + --transform-skew-y: -3deg; + } + + .xl\:transition-none { + transition-property: none; + } + + .xl\:transition-all { + transition-property: all; + } + + .xl\:transition { + transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform; + } + + .xl\:transition-colors { + transition-property: background-color, border-color, color, fill, stroke; + } + + .xl\:transition-opacity { + transition-property: opacity; + } + + .xl\:transition-shadow { + transition-property: box-shadow; + } + + .xl\:transition-transform { + transition-property: transform; + } + + .xl\:ease-linear { + transition-timing-function: linear; + } + + .xl\:ease-in { + transition-timing-function: cubic-bezier(0.4, 0, 1, 1); + } + + .xl\:ease-out { + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + } + + .xl\:ease-in-out { + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + } + + .xl\:duration-75 { + transition-duration: 75ms; + } + + .xl\:duration-100 { + transition-duration: 100ms; + } + + .xl\:duration-150 { + transition-duration: 150ms; + } + + .xl\:duration-200 { + transition-duration: 200ms; + } + + .xl\:duration-300 { + transition-duration: 300ms; + } + + .xl\:duration-500 { + transition-duration: 500ms; + } + + .xl\:duration-700 { + transition-duration: 700ms; + } + + .xl\:duration-1000 { + transition-duration: 1000ms; + } +} diff --git a/packages/frame/src/tailwind.css b/packages/frame/src/tailwind.css new file mode 100644 index 0000000..efa490f --- /dev/null +++ b/packages/frame/src/tailwind.css @@ -0,0 +1,4 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; +@import '~@fortawesome/fontawesome-free/css/all.css'; diff --git a/packages/frame/src/utils/history.ts b/packages/frame/src/utils/history.ts new file mode 100644 index 0000000..e5987c4 --- /dev/null +++ b/packages/frame/src/utils/history.ts @@ -0,0 +1,3 @@ +import { createBrowserHistory } from 'history' + +export default createBrowserHistory() diff --git a/packages/frame/tailwind.js b/packages/frame/tailwind.js new file mode 100644 index 0000000..1a1c818 --- /dev/null +++ b/packages/frame/tailwind.js @@ -0,0 +1,694 @@ +module.exports = { + prefix: '', + important: false, + separator: ':', + theme: { + screens: { + sm: '640px', + md: '768px', + lg: '1024px', + xl: '1280px', + }, + colors: { + transparent: 'transparent', + + black: '#000', + white: '#fff', + + gray: { + 100: '#f7fafc', + 200: '#edf2f7', + 300: '#e2e8f0', + 400: '#cbd5e0', + 500: '#a0aec0', + 600: '#718096', + 700: '#4a5568', + 800: '#2d3748', + 900: '#1a202c', + }, + red: { + 100: '#fff5f5', + 200: '#fed7d7', + 300: '#feb2b2', + 400: '#fc8181', + 500: '#f56565', + 600: '#e53e3e', + 700: '#c53030', + 800: '#9b2c2c', + 900: '#742a2a', + }, + orange: { + 100: '#fffaf0', + 200: '#feebc8', + 300: '#fbd38d', + 400: '#f6ad55', + 500: '#ed8936', + 600: '#dd6b20', + 700: '#c05621', + 800: '#9c4221', + 900: '#7b341e', + }, + yellow: { + 100: '#fffff0', + 200: '#fefcbf', + 300: '#faf089', + 400: '#f6e05e', + 500: '#ecc94b', + 600: '#d69e2e', + 700: '#b7791f', + 800: '#975a16', + 900: '#744210', + }, + green: { + 100: '#f0fff4', + 200: '#c6f6d5', + 300: '#9ae6b4', + 400: '#68d391', + 500: '#48bb78', + 600: '#38a169', + 700: '#2f855a', + 800: '#276749', + 900: '#22543d', + }, + teal: { + 100: '#e6fffa', + 200: '#b2f5ea', + 300: '#81e6d9', + 400: '#4fd1c5', + 500: '#38b2ac', + 600: '#319795', + 700: '#2c7a7b', + 800: '#285e61', + 900: '#234e52', + }, + blue: { + 100: '#ebf8ff', + 200: '#bee3f8', + 300: '#90cdf4', + 400: '#63b3ed', + 500: '#4299e1', + 600: '#3182ce', + 700: '#2b6cb0', + 800: '#2c5282', + 900: '#2a4365', + }, + indigo: { + 100: '#ebf4ff', + 200: '#c3dafe', + 300: '#a3bffa', + 400: '#7f9cf5', + 500: '#667eea', + 600: '#5a67d8', + 700: '#4c51bf', + 800: '#434190', + 900: '#3c366b', + }, + purple: { + 100: '#faf5ff', + 200: '#e9d8fd', + 300: '#d6bcfa', + 400: '#b794f4', + 500: '#9f7aea', + 600: '#805ad5', + 700: '#6b46c1', + 800: '#553c9a', + 900: '#44337a', + }, + pink: { + 100: '#fff5f7', + 200: '#fed7e2', + 300: '#fbb6ce', + 400: '#f687b3', + 500: '#ed64a6', + 600: '#d53f8c', + 700: '#b83280', + 800: '#97266d', + 900: '#702459', + }, + }, + spacing: { + px: '1px', + '0': '0', + '1': '0.25rem', + '2': '0.5rem', + '3': '0.75rem', + '4': '1rem', + '5': '1.25rem', + '6': '1.5rem', + '8': '2rem', + '10': '2.5rem', + '12': '3rem', + '16': '4rem', + '20': '5rem', + '24': '6rem', + '32': '8rem', + '40': '10rem', + '48': '12rem', + '56': '14rem', + '64': '16rem', + }, + backgroundColor: theme => theme('colors'), + backgroundPosition: { + bottom: 'bottom', + center: 'center', + left: 'left', + 'left-bottom': 'left bottom', + 'left-top': 'left top', + right: 'right', + 'right-bottom': 'right bottom', + 'right-top': 'right top', + top: 'top', + }, + backgroundSize: { + auto: 'auto', + cover: 'cover', + contain: 'contain', + }, + borderColor: theme => ({ + ...theme('colors'), + default: theme('colors.gray.300', 'currentColor'), + }), + borderRadius: { + none: '0', + sm: '0.125rem', + default: '0.25rem', + md: '0.375rem', + lg: '0.5rem', + full: '9999px', + }, + borderWidth: { + default: '1px', + '0': '0', + '2': '2px', + '4': '4px', + '8': '8px', + }, + boxShadow: { + xs: '0 0 0 1px rgba(0, 0, 0, 0.05)', + sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)', + default: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', + md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', + lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', + xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', + '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)', + outline: '0 0 0 3px rgba(66, 153, 225, 0.5)', + none: 'none', + }, + container: {}, + cursor: { + auto: 'auto', + default: 'default', + pointer: 'pointer', + wait: 'wait', + text: 'text', + move: 'move', + 'not-allowed': 'not-allowed', + }, + fill: { + current: 'currentColor', + }, + flex: { + '1': '1 1 0%', + auto: '1 1 auto', + initial: '0 1 auto', + none: 'none', + }, + flexGrow: { + '0': '0', + default: '1', + }, + flexShrink: { + '0': '0', + default: '1', + }, + fontFamily: { + sans: [ + 'system-ui', + '-apple-system', + 'BlinkMacSystemFont', + '"Segoe UI"', + 'Roboto', + '"Helvetica Neue"', + 'Arial', + '"Noto Sans"', + 'sans-serif', + '"Apple Color Emoji"', + '"Segoe UI Emoji"', + '"Segoe UI Symbol"', + '"Noto Color Emoji"', + ], + serif: ['Georgia', 'Cambria', '"Times New Roman"', 'Times', 'serif'], + mono: ['Menlo', 'Monaco', 'Consolas', '"Liberation Mono"', '"Courier New"', 'monospace'], + }, + fontSize: { + xs: '0.75rem', + sm: '0.875rem', + base: '1rem', + lg: '1.125rem', + xl: '1.25rem', + '2xl': '1.5rem', + '3xl': '1.875rem', + '4xl': '2.25rem', + '5xl': '3rem', + '6xl': '4rem', + }, + fontWeight: { + hairline: '100', + thin: '200', + light: '300', + normal: '400', + medium: '500', + semibold: '600', + bold: '700', + extrabold: '800', + black: '900', + }, + height: theme => ({ + auto: 'auto', + ...theme('spacing'), + full: '100%', + screen: '100vh', + }), + inset: { + '0': '0', + auto: 'auto', + }, + letterSpacing: { + tighter: '-0.05em', + tight: '-0.025em', + normal: '0', + wide: '0.025em', + wider: '0.05em', + widest: '0.1em', + }, + lineHeight: { + none: '1', + tight: '1.25', + snug: '1.375', + normal: '1.5', + relaxed: '1.625', + loose: '2', + '3': '.75rem', + '4': '1rem', + '5': '1.25rem', + '6': '1.5rem', + '7': '1.75rem', + '8': '2rem', + '9': '2.25rem', + '10': '2.5rem', + }, + listStyleType: { + none: 'none', + disc: 'disc', + decimal: 'decimal', + }, + margin: (theme, { negative }) => ({ + auto: 'auto', + ...theme('spacing'), + ...negative(theme('spacing')), + }), + maxHeight: { + full: '100%', + screen: '100vh', + }, + maxWidth: (theme, { breakpoints }) => ({ + none: 'none', + xs: '20rem', + sm: '24rem', + md: '28rem', + lg: '32rem', + xl: '36rem', + '2xl': '42rem', + '3xl': '48rem', + '4xl': '56rem', + '5xl': '64rem', + '6xl': '72rem', + full: '100%', + ...breakpoints(theme('screens')), + }), + minHeight: { + '0': '0', + full: '100%', + screen: '100vh', + }, + minWidth: { + '0': '0', + full: '100%', + }, + objectPosition: { + bottom: 'bottom', + center: 'center', + left: 'left', + 'left-bottom': 'left bottom', + 'left-top': 'left top', + right: 'right', + 'right-bottom': 'right bottom', + 'right-top': 'right top', + top: 'top', + }, + opacity: { + '0': '0', + '25': '0.25', + '50': '0.5', + '75': '0.75', + '100': '1', + }, + order: { + first: '-9999', + last: '9999', + none: '0', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + '8': '8', + '9': '9', + '10': '10', + '11': '11', + '12': '12', + }, + padding: theme => theme('spacing'), + placeholderColor: theme => theme('colors'), + stroke: { + current: 'currentColor', + }, + strokeWidth: { + '0': '0', + '1': '1', + '2': '2', + }, + textColor: theme => theme('colors'), + width: theme => ({ + auto: 'auto', + ...theme('spacing'), + '1/2': '50%', + '1/3': '33.333333%', + '2/3': '66.666667%', + '1/4': '25%', + '2/4': '50%', + '3/4': '75%', + '1/5': '20%', + '2/5': '40%', + '3/5': '60%', + '4/5': '80%', + '1/6': '16.666667%', + '2/6': '33.333333%', + '3/6': '50%', + '4/6': '66.666667%', + '5/6': '83.333333%', + '1/12': '8.333333%', + '2/12': '16.666667%', + '3/12': '25%', + '4/12': '33.333333%', + '5/12': '41.666667%', + '6/12': '50%', + '7/12': '58.333333%', + '8/12': '66.666667%', + '9/12': '75%', + '10/12': '83.333333%', + '11/12': '91.666667%', + full: '100%', + screen: '100vw', + }), + zIndex: { + auto: 'auto', + '0': '0', + '10': '10', + '20': '20', + '30': '30', + '40': '40', + '50': '50', + }, + gap: theme => theme('spacing'), + gridTemplateColumns: { + none: 'none', + '1': 'repeat(1, minmax(0, 1fr))', + '2': 'repeat(2, minmax(0, 1fr))', + '3': 'repeat(3, minmax(0, 1fr))', + '4': 'repeat(4, minmax(0, 1fr))', + '5': 'repeat(5, minmax(0, 1fr))', + '6': 'repeat(6, minmax(0, 1fr))', + '7': 'repeat(7, minmax(0, 1fr))', + '8': 'repeat(8, minmax(0, 1fr))', + '9': 'repeat(9, minmax(0, 1fr))', + '10': 'repeat(10, minmax(0, 1fr))', + '11': 'repeat(11, minmax(0, 1fr))', + '12': 'repeat(12, minmax(0, 1fr))', + }, + gridColumn: { + auto: 'auto', + 'span-1': 'span 1 / span 1', + 'span-2': 'span 2 / span 2', + 'span-3': 'span 3 / span 3', + 'span-4': 'span 4 / span 4', + 'span-5': 'span 5 / span 5', + 'span-6': 'span 6 / span 6', + 'span-7': 'span 7 / span 7', + 'span-8': 'span 8 / span 8', + 'span-9': 'span 9 / span 9', + 'span-10': 'span 10 / span 10', + 'span-11': 'span 11 / span 11', + 'span-12': 'span 12 / span 12', + }, + gridColumnStart: { + auto: 'auto', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + '8': '8', + '9': '9', + '10': '10', + '11': '11', + '12': '12', + '13': '13', + }, + gridColumnEnd: { + auto: 'auto', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + '8': '8', + '9': '9', + '10': '10', + '11': '11', + '12': '12', + '13': '13', + }, + gridTemplateRows: { + none: 'none', + '1': 'repeat(1, minmax(0, 1fr))', + '2': 'repeat(2, minmax(0, 1fr))', + '3': 'repeat(3, minmax(0, 1fr))', + '4': 'repeat(4, minmax(0, 1fr))', + '5': 'repeat(5, minmax(0, 1fr))', + '6': 'repeat(6, minmax(0, 1fr))', + }, + gridRow: { + auto: 'auto', + 'span-1': 'span 1 / span 1', + 'span-2': 'span 2 / span 2', + 'span-3': 'span 3 / span 3', + 'span-4': 'span 4 / span 4', + 'span-5': 'span 5 / span 5', + 'span-6': 'span 6 / span 6', + }, + gridRowStart: { + auto: 'auto', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + }, + gridRowEnd: { + auto: 'auto', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + }, + transformOrigin: { + center: 'center', + top: 'top', + 'top-right': 'top right', + right: 'right', + 'bottom-right': 'bottom right', + bottom: 'bottom', + 'bottom-left': 'bottom left', + left: 'left', + 'top-left': 'top left', + }, + scale: { + '0': '0', + '50': '.5', + '75': '.75', + '90': '.9', + '95': '.95', + '100': '1', + '105': '1.05', + '110': '1.1', + '125': '1.25', + '150': '1.5', + }, + rotate: { + '-180': '-180deg', + '-90': '-90deg', + '-45': '-45deg', + '0': '0', + '45': '45deg', + '90': '90deg', + '180': '180deg', + }, + translate: (theme, { negative }) => ({ + ...theme('spacing'), + ...negative(theme('spacing')), + '-full': '-100%', + '-1/2': '-50%', + '1/2': '50%', + full: '100%', + }), + skew: { + '-12': '-12deg', + '-6': '-6deg', + '-3': '-3deg', + '0': '0', + '3': '3deg', + '6': '6deg', + '12': '12deg', + }, + transitionProperty: { + none: 'none', + all: 'all', + default: 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform', + colors: 'background-color, border-color, color, fill, stroke', + opacity: 'opacity', + shadow: 'box-shadow', + transform: 'transform', + }, + transitionTimingFunction: { + linear: 'linear', + in: 'cubic-bezier(0.4, 0, 1, 1)', + out: 'cubic-bezier(0, 0, 0.2, 1)', + 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)', + }, + transitionDuration: { + '75': '75ms', + '100': '100ms', + '150': '150ms', + '200': '200ms', + '300': '300ms', + '500': '500ms', + '700': '700ms', + '1000': '1000ms', + }, + }, + variants: { + accessibility: ['responsive', 'focus'], + alignContent: ['responsive'], + alignItems: ['responsive'], + alignSelf: ['responsive'], + appearance: ['responsive'], + backgroundAttachment: ['responsive'], + backgroundColor: ['responsive', 'hover', 'focus'], + backgroundPosition: ['responsive'], + backgroundRepeat: ['responsive'], + backgroundSize: ['responsive'], + borderCollapse: ['responsive'], + borderColor: ['responsive', 'hover', 'focus'], + borderRadius: ['responsive'], + borderStyle: ['responsive'], + borderWidth: ['responsive'], + boxShadow: ['responsive', 'hover', 'focus'], + boxSizing: ['responsive'], + cursor: ['responsive'], + display: ['responsive'], + fill: ['responsive'], + flex: ['responsive'], + flexDirection: ['responsive'], + flexGrow: ['responsive'], + flexShrink: ['responsive'], + flexWrap: ['responsive'], + float: ['responsive'], + clear: ['responsive'], + fontFamily: ['responsive'], + fontSize: ['responsive'], + fontSmoothing: ['responsive'], + fontStyle: ['responsive'], + fontWeight: ['responsive', 'hover', 'focus'], + height: ['responsive'], + inset: ['responsive'], + justifyContent: ['responsive'], + letterSpacing: ['responsive'], + lineHeight: ['responsive'], + listStylePosition: ['responsive'], + listStyleType: ['responsive'], + margin: ['responsive'], + maxHeight: ['responsive'], + maxWidth: ['responsive'], + minHeight: ['responsive'], + minWidth: ['responsive'], + objectFit: ['responsive'], + objectPosition: ['responsive'], + opacity: ['responsive', 'hover', 'focus'], + order: ['responsive'], + outline: ['responsive', 'focus'], + overflow: ['responsive'], + padding: ['responsive'], + placeholderColor: ['responsive', 'focus'], + pointerEvents: ['responsive'], + position: ['responsive'], + resize: ['responsive'], + stroke: ['responsive'], + strokeWidth: ['responsive'], + tableLayout: ['responsive'], + textAlign: ['responsive'], + textColor: ['responsive', 'hover', 'focus'], + textDecoration: ['responsive', 'hover', 'focus'], + textTransform: ['responsive'], + userSelect: ['responsive'], + verticalAlign: ['responsive'], + visibility: ['responsive'], + whitespace: ['responsive'], + width: ['responsive'], + wordBreak: ['responsive'], + zIndex: ['responsive'], + gap: ['responsive'], + gridAutoFlow: ['responsive'], + gridTemplateColumns: ['responsive'], + gridColumn: ['responsive'], + gridColumnStart: ['responsive'], + gridColumnEnd: ['responsive'], + gridTemplateRows: ['responsive'], + gridRow: ['responsive'], + gridRowStart: ['responsive'], + gridRowEnd: ['responsive'], + transform: ['responsive'], + transformOrigin: ['responsive'], + scale: ['responsive', 'hover', 'focus'], + rotate: ['responsive', 'hover', 'focus'], + translate: ['responsive', 'hover', 'focus'], + skew: ['responsive', 'hover', 'focus'], + transitionProperty: ['responsive'], + transitionTimingFunction: ['responsive'], + transitionDuration: ['responsive'], + }, + corePlugins: {}, + plugins: [], +} diff --git a/packages/frame/tsconfig.json b/packages/frame/tsconfig.json new file mode 100644 index 0000000..c8121d5 --- /dev/null +++ b/packages/frame/tsconfig.json @@ -0,0 +1,26 @@ +{ + "extends": "./tsconfig.paths.json", + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react" + }, + "include": [ + "src" + ] +} diff --git a/packages/frame/tsconfig.paths.json b/packages/frame/tsconfig.paths.json new file mode 100644 index 0000000..486c7be --- /dev/null +++ b/packages/frame/tsconfig.paths.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "baseUrl": "./", + "paths": { + "@/*": ["src/*"] + } + } +} diff --git a/packages/frame/yarn.lock b/packages/frame/yarn.lock new file mode 100644 index 0000000..c28b332 --- /dev/null +++ b/packages/frame/yarn.lock @@ -0,0 +1,11391 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@7.8.3", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" + integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== + dependencies: + "@babel/highlight" "^7.8.3" + +"@babel/compat-data@^7.8.6", "@babel/compat-data@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.9.0.tgz#04815556fc90b0c174abd2c0c1bb966faa036a6c" + integrity sha512-zeFQrr+284Ekvd9e7KAX954LkapWiOmQtsfHirhxqfdlX6MEC32iRE+pqUGlYIBchdevaCwvzxWGSy/YBNI85g== + dependencies: + browserslist "^4.9.1" + invariant "^2.2.4" + semver "^5.5.0" + +"@babel/core@7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.4.tgz#d496799e5c12195b3602d0fddd77294e3e38e80e" + integrity sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.8.4" + "@babel/helpers" "^7.8.4" + "@babel/parser" "^7.8.4" + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.8.4" + "@babel/types" "^7.8.3" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.0" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/core@7.9.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" + integrity sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.0" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helpers" "^7.9.0" + "@babel/parser" "^7.9.0" + "@babel/template" "^7.8.6" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.4.0", "@babel/generator@^7.8.4", "@babel/generator@^7.9.0": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.4.tgz#12441e90c3b3c4159cdecf312075bf1a8ce2dbce" + integrity sha512-rjP8ahaDy/ouhrvCoU1E5mqaitWrxwuNGU+dy1EpaoK48jZay4MdkskKGIMHLZNewg8sAsqpGSREJwP0zH3YQA== + dependencies: + "@babel/types" "^7.9.0" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz#60bc0bc657f63a0924ff9a4b4a0b24a13cf4deee" + integrity sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz#c84097a427a061ac56a1c30ebf54b7b22d241503" + integrity sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-builder-react-jsx-experimental@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.9.0.tgz#066d80262ade488f9c1b1823ce5db88a4cedaa43" + integrity sha512-3xJEiyuYU4Q/Ar9BsHisgdxZsRlsShMe90URZ0e6przL26CCs8NJbDoxH94kKT17PcxlMhsCAwZd90evCo26VQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-module-imports" "^7.8.3" + "@babel/types" "^7.9.0" + +"@babel/helper-builder-react-jsx@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.9.0.tgz#16bf391990b57732700a3278d4d9a81231ea8d32" + integrity sha512-weiIo4gaoGgnhff54GQ3P5wsUQmnSwpkvU0r6ZHq6TzoSzKy4JxHEgnxNytaKbov2a9z/CVNyzliuCOUPEX3Jw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/types" "^7.9.0" + +"@babel/helper-compilation-targets@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz#dac1eea159c0e4bd46e309b5a1b04a66b53c1dde" + integrity sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw== + dependencies: + "@babel/compat-data" "^7.8.6" + browserslist "^4.9.1" + invariant "^2.2.4" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/helper-create-class-features-plugin@^7.8.3": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.6.tgz#243a5b46e2f8f0f674dc1387631eb6b28b851de0" + integrity sha512-klTBDdsr+VFFqaDHm5rR69OpEQtO2Qv8ECxHS1mNhJJvaHArR6a1xTf5K/eZW7eZpJbhCx3NW1Yt/sKsLXLblg== + dependencies: + "@babel/helper-function-name" "^7.8.3" + "@babel/helper-member-expression-to-functions" "^7.8.3" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-split-export-declaration" "^7.8.3" + +"@babel/helper-create-regexp-features-plugin@^7.8.3", "@babel/helper-create-regexp-features-plugin@^7.8.8": + version "7.8.8" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz#5d84180b588f560b7864efaeea89243e58312087" + integrity sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-regex" "^7.8.3" + regexpu-core "^4.7.0" + +"@babel/helper-define-map@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz#a0655cad5451c3760b726eba875f1cd8faa02c15" + integrity sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g== + dependencies: + "@babel/helper-function-name" "^7.8.3" + "@babel/types" "^7.8.3" + lodash "^4.17.13" + +"@babel/helper-explode-assignable-expression@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz#a728dc5b4e89e30fc2dfc7d04fa28a930653f982" + integrity sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw== + dependencies: + "@babel/traverse" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-function-name@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" + integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA== + dependencies: + "@babel/helper-get-function-arity" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-get-function-arity@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" + integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-hoist-variables@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz#1dbe9b6b55d78c9b4183fc8cdc6e30ceb83b7134" + integrity sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-member-expression-to-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz#659b710498ea6c1d9907e0c73f206eee7dadc24c" + integrity sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz#7fe39589b39c016331b6b8c3f441e8f0b1419498" + integrity sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-transforms@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz#43b34dfe15961918707d247327431388e9fe96e5" + integrity sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-simple-access" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/template" "^7.8.6" + "@babel/types" "^7.9.0" + lodash "^4.17.13" + +"@babel/helper-optimise-call-expression@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz#7ed071813d09c75298ef4f208956006b6111ecb9" + integrity sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670" + integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ== + +"@babel/helper-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.8.3.tgz#139772607d51b93f23effe72105b319d2a4c6965" + integrity sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ== + dependencies: + lodash "^4.17.13" + +"@babel/helper-remap-async-to-generator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz#273c600d8b9bf5006142c1e35887d555c12edd86" + integrity sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-wrap-function" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-replace-supers@^7.8.3", "@babel/helper-replace-supers@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8" + integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.8.3" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/traverse" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/helper-simple-access@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz#7f8109928b4dab4654076986af575231deb639ae" + integrity sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw== + dependencies: + "@babel/template" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-split-export-declaration@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" + integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-validator-identifier@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed" + integrity sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw== + +"@babel/helper-wrap-function@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz#9dbdb2bb55ef14aaa01fe8c99b629bd5352d8610" + integrity sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ== + dependencies: + "@babel/helper-function-name" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helpers@^7.8.4", "@babel/helpers@^7.9.0": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.2.tgz#b42a81a811f1e7313b88cba8adc66b3d9ae6c09f" + integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA== + dependencies: + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + +"@babel/highlight@^7.8.3": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" + integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== + dependencies: + "@babel/helper-validator-identifier" "^7.9.0" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.8.4", "@babel/parser@^7.8.6", "@babel/parser@^7.9.0": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8" + integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA== + +"@babel/plugin-proposal-async-generator-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz#bad329c670b382589721b27540c7d288601c6e6f" + integrity sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-remap-async-to-generator" "^7.8.3" + "@babel/plugin-syntax-async-generators" "^7.8.0" + +"@babel/plugin-proposal-class-properties@7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz#5e06654af5cd04b608915aada9b2a6788004464e" + integrity sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-proposal-decorators@7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.8.3.tgz#2156860ab65c5abf068c3f67042184041066543e" + integrity sha512-e3RvdvS4qPJVTe288DlXjwKflpfy1hr0j5dz5WpIYYeP7vQZg2WfAEIp8k5/Lwis/m5REXEteIz6rrcDtXXG7w== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-decorators" "^7.8.3" + +"@babel/plugin-proposal-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz#38c4fe555744826e97e2ae930b0fb4cc07e66054" + integrity sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + +"@babel/plugin-proposal-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz#da5216b238a98b58a1e05d6852104b10f9a70d6b" + integrity sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.0" + +"@babel/plugin-proposal-nullish-coalescing-operator@7.8.3", "@babel/plugin-proposal-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz#e4572253fdeed65cddeecfdab3f928afeb2fd5d2" + integrity sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + +"@babel/plugin-proposal-numeric-separator@7.8.3", "@babel/plugin-proposal-numeric-separator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz#5d6769409699ec9b3b68684cd8116cedff93bad8" + integrity sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + +"@babel/plugin-proposal-object-rest-spread@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.0.tgz#a28993699fc13df165995362693962ba6b061d6f" + integrity sha512-UgqBv6bjq4fDb8uku9f+wcm1J7YxJ5nT7WO/jBr0cl0PLKb7t1O6RNR1kZbjgx2LQtsDI9hwoQVmn0yhXeQyow== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + +"@babel/plugin-proposal-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz#9dee96ab1650eed88646ae9734ca167ac4a9c5c9" + integrity sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + +"@babel/plugin-proposal-optional-chaining@7.9.0", "@babel/plugin-proposal-optional-chaining@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz#31db16b154c39d6b8a645292472b98394c292a58" + integrity sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + +"@babel/plugin-proposal-unicode-property-regex@^7.4.4", "@babel/plugin-proposal-unicode-property-regex@^7.8.3": + version "7.8.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz#ee3a95e90cdc04fe8cd92ec3279fa017d68a0d1d" + integrity sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.8" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-async-generators@^7.8.0": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-decorators@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.8.3.tgz#8d2c15a9f1af624b0025f961682a9d53d3001bda" + integrity sha512-8Hg4dNNT9/LcA1zQlfwuKR8BUc/if7Q7NkTam9sGTcJphLwpf2g4S42uhspQrIrR+dpzE0dtTqBVFoHl8GtnnQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-dynamic-import@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-flow@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.8.3.tgz#f2c883bd61a6316f2c89380ae5122f923ba4527f" + integrity sha512-innAx3bUbA0KSYj2E2MNFSn9hiCeowOFLxlsuhXzw8hMQnzkDomUr9QCD7E9VF60NmnG1sNTuuv6Qf4f8INYsg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-json-strings@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz#521b06c83c40480f1e58b4fd33b92eceb1d6ea94" + integrity sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.0", "@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz#0e3fb63e09bea1b11e96467271c8308007e7c41f" + integrity sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz#3acdece695e6b13aaf57fc291d1a800950c71391" + integrity sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-typescript@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.8.3.tgz#c1f659dda97711a569cef75275f7e15dcaa6cabc" + integrity sha512-GO1MQ/SGGGoiEXY0e0bSpHimJvxqB7lktLLIq2pv8xG7WZ8IMEle74jIe1FhprHBWjwjZtXHkycDLZXIWM5Wfg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-arrow-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz#82776c2ed0cd9e1a49956daeb896024c9473b8b6" + integrity sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-async-to-generator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz#4308fad0d9409d71eafb9b1a6ee35f9d64b64086" + integrity sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-remap-async-to-generator" "^7.8.3" + +"@babel/plugin-transform-block-scoped-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz#437eec5b799b5852072084b3ae5ef66e8349e8a3" + integrity sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-block-scoping@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz#97d35dab66857a437c166358b91d09050c868f3a" + integrity sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + lodash "^4.17.13" + +"@babel/plugin-transform-classes@^7.9.0": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.2.tgz#8603fc3cc449e31fdbdbc257f67717536a11af8d" + integrity sha512-TC2p3bPzsfvSsqBZo0kJnuelnoK9O3welkUpqSqBQuBF6R5MN2rysopri8kNvtlGIb2jmUO7i15IooAZJjZuMQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-define-map" "^7.8.3" + "@babel/helper-function-name" "^7.8.3" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-split-export-declaration" "^7.8.3" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz#96d0d28b7f7ce4eb5b120bb2e0e943343c86f81b" + integrity sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-destructuring@^7.8.3": + version "7.8.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.8.tgz#fadb2bc8e90ccaf5658de6f8d4d22ff6272a2f4b" + integrity sha512-eRJu4Vs2rmttFCdhPUM3bV0Yo/xPSdPw6ML9KHs/bjB4bLA5HXlbvYXPOD5yASodGod+krjYx21xm1QmL8dCJQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-dotall-regex@^7.4.4", "@babel/plugin-transform-dotall-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz#c3c6ec5ee6125c6993c5cbca20dc8621a9ea7a6e" + integrity sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-duplicate-keys@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz#8d12df309aa537f272899c565ea1768e286e21f1" + integrity sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-exponentiation-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz#581a6d7f56970e06bf51560cd64f5e947b70d7b7" + integrity sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-flow-strip-types@7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.9.0.tgz#8a3538aa40434e000b8f44a3c5c9ac7229bd2392" + integrity sha512-7Qfg0lKQhEHs93FChxVLAvhBshOPQDtJUTVHr/ZwQNRccCm4O9D79r9tVSoV8iNwjP1YgfD+e/fgHcPkN1qEQg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-flow" "^7.8.3" + +"@babel/plugin-transform-for-of@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz#0f260e27d3e29cd1bb3128da5e76c761aa6c108e" + integrity sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-function-name@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz#279373cb27322aaad67c2683e776dfc47196ed8b" + integrity sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ== + dependencies: + "@babel/helper-function-name" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz#aef239823d91994ec7b68e55193525d76dbd5dc1" + integrity sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-member-expression-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz#963fed4b620ac7cbf6029c755424029fa3a40410" + integrity sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-modules-amd@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz#19755ee721912cf5bb04c07d50280af3484efef4" + integrity sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q== + dependencies: + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + babel-plugin-dynamic-import-node "^2.3.0" + +"@babel/plugin-transform-modules-commonjs@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz#e3e72f4cbc9b4a260e30be0ea59bdf5a39748940" + integrity sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g== + dependencies: + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-simple-access" "^7.8.3" + babel-plugin-dynamic-import-node "^2.3.0" + +"@babel/plugin-transform-modules-systemjs@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz#e9fd46a296fc91e009b64e07ddaa86d6f0edeb90" + integrity sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ== + dependencies: + "@babel/helper-hoist-variables" "^7.8.3" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + babel-plugin-dynamic-import-node "^2.3.0" + +"@babel/plugin-transform-modules-umd@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz#e909acae276fec280f9b821a5f38e1f08b480697" + integrity sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ== + dependencies: + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz#a2a72bffa202ac0e2d0506afd0939c5ecbc48c6c" + integrity sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.3" + +"@babel/plugin-transform-new-target@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz#60cc2ae66d85c95ab540eb34babb6434d4c70c43" + integrity sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-object-super@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz#ebb6a1e7a86ffa96858bd6ac0102d65944261725" + integrity sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.3" + +"@babel/plugin-transform-parameters@^7.8.7": + version "7.9.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.3.tgz#3028d0cc20ddc733166c6e9c8534559cee09f54a" + integrity sha512-fzrQFQhp7mIhOzmOtPiKffvCYQSK10NR8t6BBz2yPbeUHb9OLW8RZGtgDRBn8z2hGcwvKDL3vC7ojPTLNxmqEg== + dependencies: + "@babel/helper-get-function-arity" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-property-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz#33194300d8539c1ed28c62ad5087ba3807b98263" + integrity sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-react-constant-elements@^7.0.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.9.0.tgz#a75abc936a3819edec42d3386d9f1c93f28d9d9e" + integrity sha512-wXMXsToAUOxJuBBEHajqKLFWcCkOSLshTI2ChCFFj1zDd7od4IOxiwLCOObNUvOpkxLpjIuaIdBMmNt6ocCPAw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-react-display-name@7.8.3", "@babel/plugin-transform-react-display-name@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.8.3.tgz#70ded987c91609f78353dd76d2fb2a0bb991e8e5" + integrity sha512-3Jy/PCw8Fe6uBKtEgz3M82ljt+lTg+xJaM4og+eyu83qLT87ZUSckn0wy7r31jflURWLO83TW6Ylf7lyXj3m5A== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-react-jsx-development@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.9.0.tgz#3c2a130727caf00c2a293f0aed24520825dbf754" + integrity sha512-tK8hWKrQncVvrhvtOiPpKrQjfNX3DtkNLSX4ObuGcpS9p0QrGetKmlySIGR07y48Zft8WVgPakqd/bk46JrMSw== + dependencies: + "@babel/helper-builder-react-jsx-experimental" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-jsx" "^7.8.3" + +"@babel/plugin-transform-react-jsx-self@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.9.0.tgz#f4f26a325820205239bb915bad8e06fcadabb49b" + integrity sha512-K2ObbWPKT7KUTAoyjCsFilOkEgMvFG+y0FqOl6Lezd0/13kMkkjHskVsZvblRPj1PHA44PrToaZANrryppzTvQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-jsx" "^7.8.3" + +"@babel/plugin-transform-react-jsx-source@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.9.0.tgz#89ef93025240dd5d17d3122294a093e5e0183de0" + integrity sha512-K6m3LlSnTSfRkM6FcRk8saNEeaeyG5k7AVkBU2bZK3+1zdkSED3qNdsWrUgQBeTVD2Tp3VMmerxVO2yM5iITmw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-jsx" "^7.8.3" + +"@babel/plugin-transform-react-jsx@^7.9.1", "@babel/plugin-transform-react-jsx@^7.9.4": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.9.4.tgz#86f576c8540bd06d0e95e0b61ea76d55f6cbd03f" + integrity sha512-Mjqf3pZBNLt854CK0C/kRuXAnE6H/bo7xYojP+WGtX8glDGSibcwnsWwhwoSuRg0+EBnxPC1ouVnuetUIlPSAw== + dependencies: + "@babel/helper-builder-react-jsx" "^7.9.0" + "@babel/helper-builder-react-jsx-experimental" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-jsx" "^7.8.3" + +"@babel/plugin-transform-regenerator@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz#5e46a0dca2bee1ad8285eb0527e6abc9c37672f8" + integrity sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA== + dependencies: + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz#9a0635ac4e665d29b162837dd3cc50745dfdf1f5" + integrity sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-runtime@7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.0.tgz#45468c0ae74cc13204e1d3b1f4ce6ee83258af0b" + integrity sha512-pUu9VSf3kI1OqbWINQ7MaugnitRss1z533436waNXp+0N3ur3zfut37sXiQMxkuCF4VUjwZucen/quskCh7NHw== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + resolve "^1.8.1" + semver "^5.5.1" + +"@babel/plugin-transform-shorthand-properties@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz#28545216e023a832d4d3a1185ed492bcfeac08c8" + integrity sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz#9c8ffe8170fdfb88b114ecb920b82fb6e95fe5e8" + integrity sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-sticky-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz#be7a1290f81dae767475452199e1f76d6175b100" + integrity sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-regex" "^7.8.3" + +"@babel/plugin-transform-template-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz#7bfa4732b455ea6a43130adc0ba767ec0e402a80" + integrity sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-typeof-symbol@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz#ede4062315ce0aaf8a657a920858f1a2f35fc412" + integrity sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-typescript@^7.9.0": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.9.4.tgz#4bb4dde4f10bbf2d787fce9707fb09b483e33359" + integrity sha512-yeWeUkKx2auDbSxRe8MusAG+n4m9BFY/v+lPjmQDgOFX5qnySkUY5oXzkp6FwPdsYqnKay6lorXYdC0n3bZO7w== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-typescript" "^7.8.3" + +"@babel/plugin-transform-unicode-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz#0cef36e3ba73e5c57273effb182f46b91a1ecaad" + integrity sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/preset-env@7.9.0", "@babel/preset-env@^7.4.5": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.9.0.tgz#a5fc42480e950ae8f5d9f8f2bbc03f52722df3a8" + integrity sha512-712DeRXT6dyKAM/FMbQTV/FvRCms2hPCx+3weRjZ8iQVQWZejWWk1wwG6ViWMyqb/ouBbGOl5b6aCk0+j1NmsQ== + dependencies: + "@babel/compat-data" "^7.9.0" + "@babel/helper-compilation-targets" "^7.8.7" + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-proposal-async-generator-functions" "^7.8.3" + "@babel/plugin-proposal-dynamic-import" "^7.8.3" + "@babel/plugin-proposal-json-strings" "^7.8.3" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-proposal-numeric-separator" "^7.8.3" + "@babel/plugin-proposal-object-rest-spread" "^7.9.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.8.3" + "@babel/plugin-proposal-optional-chaining" "^7.9.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.8.3" + "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.8.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + "@babel/plugin-transform-arrow-functions" "^7.8.3" + "@babel/plugin-transform-async-to-generator" "^7.8.3" + "@babel/plugin-transform-block-scoped-functions" "^7.8.3" + "@babel/plugin-transform-block-scoping" "^7.8.3" + "@babel/plugin-transform-classes" "^7.9.0" + "@babel/plugin-transform-computed-properties" "^7.8.3" + "@babel/plugin-transform-destructuring" "^7.8.3" + "@babel/plugin-transform-dotall-regex" "^7.8.3" + "@babel/plugin-transform-duplicate-keys" "^7.8.3" + "@babel/plugin-transform-exponentiation-operator" "^7.8.3" + "@babel/plugin-transform-for-of" "^7.9.0" + "@babel/plugin-transform-function-name" "^7.8.3" + "@babel/plugin-transform-literals" "^7.8.3" + "@babel/plugin-transform-member-expression-literals" "^7.8.3" + "@babel/plugin-transform-modules-amd" "^7.9.0" + "@babel/plugin-transform-modules-commonjs" "^7.9.0" + "@babel/plugin-transform-modules-systemjs" "^7.9.0" + "@babel/plugin-transform-modules-umd" "^7.9.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.8.3" + "@babel/plugin-transform-new-target" "^7.8.3" + "@babel/plugin-transform-object-super" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.8.7" + "@babel/plugin-transform-property-literals" "^7.8.3" + "@babel/plugin-transform-regenerator" "^7.8.7" + "@babel/plugin-transform-reserved-words" "^7.8.3" + "@babel/plugin-transform-shorthand-properties" "^7.8.3" + "@babel/plugin-transform-spread" "^7.8.3" + "@babel/plugin-transform-sticky-regex" "^7.8.3" + "@babel/plugin-transform-template-literals" "^7.8.3" + "@babel/plugin-transform-typeof-symbol" "^7.8.4" + "@babel/plugin-transform-unicode-regex" "^7.8.3" + "@babel/preset-modules" "^0.1.3" + "@babel/types" "^7.9.0" + browserslist "^4.9.1" + core-js-compat "^3.6.2" + invariant "^2.2.2" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/preset-modules@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72" + integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/preset-react@7.9.1": + version "7.9.1" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.9.1.tgz#b346403c36d58c3bb544148272a0cefd9c28677a" + integrity sha512-aJBYF23MPj0RNdp/4bHnAP0NVqqZRr9kl0NAOP4nJCex6OYVio59+dnQzsAWFuogdLyeaKA1hmfUIVZkY5J+TQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-transform-react-display-name" "^7.8.3" + "@babel/plugin-transform-react-jsx" "^7.9.1" + "@babel/plugin-transform-react-jsx-development" "^7.9.0" + "@babel/plugin-transform-react-jsx-self" "^7.9.0" + "@babel/plugin-transform-react-jsx-source" "^7.9.0" + +"@babel/preset-react@^7.0.0": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.9.4.tgz#c6c97693ac65b6b9c0b4f25b948a8f665463014d" + integrity sha512-AxylVB3FXeOTQXNXyiuAQJSvss62FEotbX2Pzx3K/7c+MKJMdSg6Ose6QYllkdCFA8EInCJVw7M/o5QbLuA4ZQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-transform-react-display-name" "^7.8.3" + "@babel/plugin-transform-react-jsx" "^7.9.4" + "@babel/plugin-transform-react-jsx-development" "^7.9.0" + "@babel/plugin-transform-react-jsx-self" "^7.9.0" + "@babel/plugin-transform-react-jsx-source" "^7.9.0" + +"@babel/preset-typescript@7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.9.0.tgz#87705a72b1f0d59df21c179f7c3d2ef4b16ce192" + integrity sha512-S4cueFnGrIbvYJgwsVFKdvOmpiL0XGw9MFW9D0vgRys5g36PBhZRL8NX8Gr2akz8XRtzq6HuDXPD/1nniagNUg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-transform-typescript" "^7.9.0" + +"@babel/runtime-corejs3@^7.7.4": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.9.2.tgz#26fe4aa77e9f1ecef9b776559bbb8e84d34284b7" + integrity sha512-HHxmgxbIzOfFlZ+tdeRKtaxWOMUoCG5Mu3wKeUmOxjYrwb3AAHgnmtCUbPPK11/raIWLIBK250t8E2BPO0p7jA== + dependencies: + core-js-pure "^3.0.0" + regenerator-runtime "^0.13.4" + +"@babel/runtime@7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.0.tgz#337eda67401f5b066a6f205a3113d4ac18ba495b" + integrity sha512-cTIudHnzuWLS56ik4DnRnqqNf8MkdUzV4iFFI1h7Jo9xvrpQROYaAnaSd2mHLQAzzZAPfATynX5ord6YlNYNMA== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.4", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" + integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.4.0", "@babel/template@^7.8.3", "@babel/template@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" + integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/parser" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.4", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.0.tgz#d3882c2830e513f4fe4cec9fe76ea1cc78747892" + integrity sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.0" + "@babel/helper-function-name" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/parser" "^7.9.0" + "@babel/types" "^7.9.0" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.0.tgz#00b064c3df83ad32b2dbf5ff07312b15c7f1efb5" + integrity sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng== + dependencies: + "@babel/helper-validator-identifier" "^7.9.0" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@cnakazawa/watch@^1.0.3": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" + integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== + dependencies: + exec-sh "^0.3.2" + minimist "^1.2.0" + +"@craco/craco@^5.6.3": + version "5.6.4" + resolved "https://registry.yarnpkg.com/@craco/craco/-/craco-5.6.4.tgz#de7a707c727864f39e6afc192fb6732c3ca45f90" + integrity sha512-/Qi6yPMOBC7SEZJEDI5vYaPiGFs7HzO4AAZkGB0W3MX2OCw4u4FZC+ZO6TBptGzM3QLrF7WFt5AyQnXhNBcn3A== + dependencies: + cross-spawn "^7.0.0" + lodash "^4.17.15" + webpack-merge "^4.2.2" + +"@csstools/convert-colors@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" + integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== + +"@csstools/normalize.css@^10.1.0": + version "10.1.0" + resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18" + integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg== + +"@emotion/cache@^10.0.27": + version "10.0.29" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.29.tgz#87e7e64f412c060102d589fe7c6dc042e6f9d1e0" + integrity sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ== + dependencies: + "@emotion/sheet" "0.9.4" + "@emotion/stylis" "0.8.5" + "@emotion/utils" "0.11.3" + "@emotion/weak-memoize" "0.2.5" + +"@emotion/core@^10.0.27": + version "10.0.28" + resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.28.tgz#bb65af7262a234593a9e952c041d0f1c9b9bef3d" + integrity sha512-pH8UueKYO5jgg0Iq+AmCLxBsvuGtvlmiDCOuv8fGNYn3cowFpLN98L8zO56U0H1PjDIyAlXymgL3Wu7u7v6hbA== + dependencies: + "@babel/runtime" "^7.5.5" + "@emotion/cache" "^10.0.27" + "@emotion/css" "^10.0.27" + "@emotion/serialize" "^0.11.15" + "@emotion/sheet" "0.9.4" + "@emotion/utils" "0.11.3" + +"@emotion/css@^10.0.27": + version "10.0.27" + resolved "https://registry.yarnpkg.com/@emotion/css/-/css-10.0.27.tgz#3a7458198fbbebb53b01b2b87f64e5e21241e14c" + integrity sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw== + dependencies: + "@emotion/serialize" "^0.11.15" + "@emotion/utils" "0.11.3" + babel-plugin-emotion "^10.0.27" + +"@emotion/hash@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" + integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== + +"@emotion/is-prop-valid@0.8.8": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" + integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== + dependencies: + "@emotion/memoize" "0.7.4" + +"@emotion/memoize@0.7.4": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" + integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== + +"@emotion/serialize@^0.11.15", "@emotion/serialize@^0.11.16": + version "0.11.16" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.16.tgz#dee05f9e96ad2fb25a5206b6d759b2d1ed3379ad" + integrity sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg== + dependencies: + "@emotion/hash" "0.8.0" + "@emotion/memoize" "0.7.4" + "@emotion/unitless" "0.7.5" + "@emotion/utils" "0.11.3" + csstype "^2.5.7" + +"@emotion/sheet@0.9.4": + version "0.9.4" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.4.tgz#894374bea39ec30f489bbfc3438192b9774d32e5" + integrity sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA== + +"@emotion/styled-base@^10.0.27": + version "10.0.31" + resolved "https://registry.yarnpkg.com/@emotion/styled-base/-/styled-base-10.0.31.tgz#940957ee0aa15c6974adc7d494ff19765a2f742a" + integrity sha512-wTOE1NcXmqMWlyrtwdkqg87Mu6Rj1MaukEoEmEkHirO5IoHDJ8LgCQL4MjJODgxWxXibGR3opGp1p7YvkNEdXQ== + dependencies: + "@babel/runtime" "^7.5.5" + "@emotion/is-prop-valid" "0.8.8" + "@emotion/serialize" "^0.11.15" + "@emotion/utils" "0.11.3" + +"@emotion/styled@^10.0.27": + version "10.0.27" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-10.0.27.tgz#12cb67e91f7ad7431e1875b1d83a94b814133eaf" + integrity sha512-iK/8Sh7+NLJzyp9a5+vIQIXTYxfT4yB/OJbjzQanB2RZpvmzBQOHZWhpAMZWYEKRNNbsD6WfBw5sVWkb6WzS/Q== + dependencies: + "@emotion/styled-base" "^10.0.27" + babel-plugin-emotion "^10.0.27" + +"@emotion/stylis@0.8.5": + version "0.8.5" + resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" + integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== + +"@emotion/unitless@0.7.5": + version "0.7.5" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" + integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== + +"@emotion/utils@0.11.3": + version "0.11.3" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.3.tgz#a759863867befa7e583400d322652a3f44820924" + integrity sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw== + +"@emotion/weak-memoize@0.2.5": + version "0.2.5" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" + integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== + +"@fortawesome/fontawesome-free@^5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.13.0.tgz#fcb113d1aca4b471b709e8c9c168674fbd6e06d9" + integrity sha512-xKOeQEl5O47GPZYIMToj6uuA2syyFlq9EMSl2ui0uytjY9xbe8XS0pexNWmxrdcCyNGyDmLyYw5FtKsalBUeOg== + +"@hapi/address@2.x.x": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" + integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ== + +"@hapi/bourne@1.x.x": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a" + integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== + +"@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0": + version "8.5.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06" + integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow== + +"@hapi/joi@^15.0.0": + version "15.1.1" + resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7" + integrity sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ== + dependencies: + "@hapi/address" "2.x.x" + "@hapi/bourne" "1.x.x" + "@hapi/hoek" "8.x.x" + "@hapi/topo" "3.x.x" + +"@hapi/topo@3.x.x": + version "3.1.6" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29" + integrity sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ== + dependencies: + "@hapi/hoek" "^8.3.0" + +"@jest/console@^24.7.1", "@jest/console@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" + integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ== + dependencies: + "@jest/source-map" "^24.9.0" + chalk "^2.0.1" + slash "^2.0.0" + +"@jest/core@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.9.0.tgz#2ceccd0b93181f9c4850e74f2a9ad43d351369c4" + integrity sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A== + dependencies: + "@jest/console" "^24.7.1" + "@jest/reporters" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + graceful-fs "^4.1.15" + jest-changed-files "^24.9.0" + jest-config "^24.9.0" + jest-haste-map "^24.9.0" + jest-message-util "^24.9.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.9.0" + jest-resolve-dependencies "^24.9.0" + jest-runner "^24.9.0" + jest-runtime "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + jest-watcher "^24.9.0" + micromatch "^3.1.10" + p-each-series "^1.0.0" + realpath-native "^1.1.0" + rimraf "^2.5.4" + slash "^2.0.0" + strip-ansi "^5.0.0" + +"@jest/environment@^24.3.0", "@jest/environment@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18" + integrity sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ== + dependencies: + "@jest/fake-timers" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + +"@jest/fake-timers@^24.3.0", "@jest/fake-timers@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" + integrity sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A== + dependencies: + "@jest/types" "^24.9.0" + jest-message-util "^24.9.0" + jest-mock "^24.9.0" + +"@jest/reporters@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" + integrity sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + istanbul-lib-coverage "^2.0.2" + istanbul-lib-instrument "^3.0.1" + istanbul-lib-report "^2.0.4" + istanbul-lib-source-maps "^3.0.1" + istanbul-reports "^2.2.6" + jest-haste-map "^24.9.0" + jest-resolve "^24.9.0" + jest-runtime "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.6.0" + node-notifier "^5.4.2" + slash "^2.0.0" + source-map "^0.6.0" + string-length "^2.0.0" + +"@jest/source-map@^24.3.0", "@jest/source-map@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" + integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.1.15" + source-map "^0.6.0" + +"@jest/test-result@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" + integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA== + dependencies: + "@jest/console" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/istanbul-lib-coverage" "^2.0.0" + +"@jest/test-sequencer@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz#f8f334f35b625a4f2f355f2fe7e6036dad2e6b31" + integrity sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A== + dependencies: + "@jest/test-result" "^24.9.0" + jest-haste-map "^24.9.0" + jest-runner "^24.9.0" + jest-runtime "^24.9.0" + +"@jest/transform@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56" + integrity sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^24.9.0" + babel-plugin-istanbul "^5.1.0" + chalk "^2.0.1" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.1.15" + jest-haste-map "^24.9.0" + jest-regex-util "^24.9.0" + jest-util "^24.9.0" + micromatch "^3.1.10" + pirates "^4.0.1" + realpath-native "^1.1.0" + slash "^2.0.0" + source-map "^0.6.1" + write-file-atomic "2.4.1" + +"@jest/types@^24.3.0", "@jest/types@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" + integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^13.0.0" + +"@jest/types@^25.2.0": + version "25.2.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.2.0.tgz#0659866d9b31843a737b601b950a690e576a415a" + integrity sha512-RLWBAON8LEjzD60Cn0XFmvMNTuV+scKlufIUApnG7VF7oA2jCEk5J0uzEchx6xuOwhrHohQM28K4CmEjgtDEwg== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^15.0.0" + chalk "^3.0.0" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.scandir@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" + integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== + dependencies: + "@nodelib/fs.stat" "2.0.3" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" + integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" + integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== + dependencies: + "@nodelib/fs.scandir" "2.1.3" + fastq "^1.6.0" + +"@reduxjs/toolkit@^1.2.5": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.3.0.tgz#c8be2e02e1a42f2507d4bf15dc71720e96011fa4" + integrity sha512-8biLZwP9nbAjV+XbY/h5ONmM19gdUojjC9ybkmQvfDdQds1Lf4ZC+bifUstl1e6kRwTArsJ3pXmXDvWEyxUi1w== + dependencies: + immer "^6.0.1" + redux "^4.0.0" + redux-thunk "^2.3.0" + reselect "^4.0.0" + +"@sheerun/mutationobserver-shim@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz#5405ee8e444ed212db44e79351f0c70a582aae25" + integrity sha512-DetpxZw1fzPD5xUBrIAoplLChO2VB8DlL5Gg+I1IR9b2wPqYIca2WSUxL5g1vLeR4MsQq1NeWriXAVffV+U1Fw== + +"@svgr/babel-plugin-add-jsx-attribute@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz#dadcb6218503532d6884b210e7f3c502caaa44b1" + integrity sha512-j7KnilGyZzYr/jhcrSYS3FGWMZVaqyCG0vzMCwzvei0coIkczuYMcniK07nI0aHJINciujjH11T72ICW5eL5Ig== + +"@svgr/babel-plugin-remove-jsx-attribute@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-4.2.0.tgz#297550b9a8c0c7337bea12bdfc8a80bb66f85abc" + integrity sha512-3XHLtJ+HbRCH4n28S7y/yZoEQnRpl0tvTZQsHqvaeNXPra+6vE5tbRliH3ox1yZYPCxrlqaJT/Mg+75GpDKlvQ== + +"@svgr/babel-plugin-remove-jsx-empty-expression@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-4.2.0.tgz#c196302f3e68eab6a05e98af9ca8570bc13131c7" + integrity sha512-yTr2iLdf6oEuUE9MsRdvt0NmdpMBAkgK8Bjhl6epb+eQWk6abBaX3d65UZ3E3FWaOwePyUgNyNCMVG61gGCQ7w== + +"@svgr/babel-plugin-replace-jsx-attribute-value@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-4.2.0.tgz#310ec0775de808a6a2e4fd4268c245fd734c1165" + integrity sha512-U9m870Kqm0ko8beHawRXLGLvSi/ZMrl89gJ5BNcT452fAjtF2p4uRzXkdzvGJJJYBgx7BmqlDjBN/eCp5AAX2w== + +"@svgr/babel-plugin-svg-dynamic-title@^4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.3.3.tgz#2cdedd747e5b1b29ed4c241e46256aac8110dd93" + integrity sha512-w3Be6xUNdwgParsvxkkeZb545VhXEwjGMwExMVBIdPQJeyMQHqm9Msnb2a1teHBqUYL66qtwfhNkbj1iarCG7w== + +"@svgr/babel-plugin-svg-em-dimensions@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-4.2.0.tgz#9a94791c9a288108d20a9d2cc64cac820f141391" + integrity sha512-C0Uy+BHolCHGOZ8Dnr1zXy/KgpBOkEUYY9kI/HseHVPeMbluaX3CijJr7D4C5uR8zrc1T64nnq/k63ydQuGt4w== + +"@svgr/babel-plugin-transform-react-native-svg@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-4.2.0.tgz#151487322843359a1ca86b21a3815fd21a88b717" + integrity sha512-7YvynOpZDpCOUoIVlaaOUU87J4Z6RdD6spYN4eUb5tfPoKGSF9OG2NuhgYnq4jSkAxcpMaXWPf1cePkzmqTPNw== + +"@svgr/babel-plugin-transform-svg-component@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-4.2.0.tgz#5f1e2f886b2c85c67e76da42f0f6be1b1767b697" + integrity sha512-hYfYuZhQPCBVotABsXKSCfel2slf/yvJY8heTVX1PCTaq/IgASq1IyxPPKJ0chWREEKewIU/JMSsIGBtK1KKxw== + +"@svgr/babel-preset@^4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-4.3.3.tgz#a75d8c2f202ac0e5774e6bfc165d028b39a1316c" + integrity sha512-6PG80tdz4eAlYUN3g5GZiUjg2FMcp+Wn6rtnz5WJG9ITGEF1pmFdzq02597Hn0OmnQuCVaBYQE1OVFAnwOl+0A== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "^4.2.0" + "@svgr/babel-plugin-remove-jsx-attribute" "^4.2.0" + "@svgr/babel-plugin-remove-jsx-empty-expression" "^4.2.0" + "@svgr/babel-plugin-replace-jsx-attribute-value" "^4.2.0" + "@svgr/babel-plugin-svg-dynamic-title" "^4.3.3" + "@svgr/babel-plugin-svg-em-dimensions" "^4.2.0" + "@svgr/babel-plugin-transform-react-native-svg" "^4.2.0" + "@svgr/babel-plugin-transform-svg-component" "^4.2.0" + +"@svgr/core@^4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.3.3.tgz#b37b89d5b757dc66e8c74156d00c368338d24293" + integrity sha512-qNuGF1QON1626UCaZamWt5yedpgOytvLj5BQZe2j1k1B8DUG4OyugZyfEwBeXozCUwhLEpsrgPrE+eCu4fY17w== + dependencies: + "@svgr/plugin-jsx" "^4.3.3" + camelcase "^5.3.1" + cosmiconfig "^5.2.1" + +"@svgr/hast-util-to-babel-ast@^4.3.2": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.3.2.tgz#1d5a082f7b929ef8f1f578950238f630e14532b8" + integrity sha512-JioXclZGhFIDL3ddn4Kiq8qEqYM2PyDKV0aYno8+IXTLuYt6TOgHUbUAAFvqtb0Xn37NwP0BTHglejFoYr8RZg== + dependencies: + "@babel/types" "^7.4.4" + +"@svgr/plugin-jsx@^4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-4.3.3.tgz#e2ba913dbdfbe85252a34db101abc7ebd50992fa" + integrity sha512-cLOCSpNWQnDB1/v+SUENHH7a0XY09bfuMKdq9+gYvtuwzC2rU4I0wKGFEp1i24holdQdwodCtDQdFtJiTCWc+w== + dependencies: + "@babel/core" "^7.4.5" + "@svgr/babel-preset" "^4.3.3" + "@svgr/hast-util-to-babel-ast" "^4.3.2" + svg-parser "^2.0.0" + +"@svgr/plugin-svgo@^4.3.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-4.3.1.tgz#daac0a3d872e3f55935c6588dd370336865e9e32" + integrity sha512-PrMtEDUWjX3Ea65JsVCwTIXuSqa3CG9px+DluF1/eo9mlDrgrtFE7NE/DjdhjJgSM9wenlVBzkzneSIUgfUI/w== + dependencies: + cosmiconfig "^5.2.1" + merge-deep "^3.0.2" + svgo "^1.2.2" + +"@svgr/webpack@4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-4.3.3.tgz#13cc2423bf3dff2d494f16b17eb7eacb86895017" + integrity sha512-bjnWolZ6KVsHhgyCoYRFmbd26p8XVbulCzSG53BDQqAr+JOAderYK7CuYrB3bDjHJuF6LJ7Wrr42+goLRV9qIg== + dependencies: + "@babel/core" "^7.4.5" + "@babel/plugin-transform-react-constant-elements" "^7.0.0" + "@babel/preset-env" "^7.4.5" + "@babel/preset-react" "^7.0.0" + "@svgr/core" "^4.3.3" + "@svgr/plugin-jsx" "^4.3.3" + "@svgr/plugin-svgo" "^4.3.1" + loader-utils "^1.2.3" + +"@testing-library/dom@^6.15.0": + version "6.16.0" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-6.16.0.tgz#04ada27ed74ad4c0f0d984a1245bb29b1fd90ba9" + integrity sha512-lBD88ssxqEfz0wFL6MeUyyWZfV/2cjEZZV3YRpb2IoJRej/4f1jB0TzqIOznTpfR1r34CNesrubxwIlAQ8zgPA== + dependencies: + "@babel/runtime" "^7.8.4" + "@sheerun/mutationobserver-shim" "^0.3.2" + "@types/testing-library__dom" "^6.12.1" + aria-query "^4.0.2" + dom-accessibility-api "^0.3.0" + pretty-format "^25.1.0" + wait-for-expect "^3.0.2" + +"@testing-library/jest-dom@^4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-4.2.4.tgz#00dfa0cbdd837d9a3c2a7f3f0a248ea6e7b89742" + integrity sha512-j31Bn0rQo12fhCWOUWy9fl7wtqkp7In/YP2p5ZFyRuiiB9Qs3g+hS4gAmDWONbAHcRmVooNJ5eOHQDCOmUFXHg== + dependencies: + "@babel/runtime" "^7.5.1" + chalk "^2.4.1" + css "^2.2.3" + css.escape "^1.5.1" + jest-diff "^24.0.0" + jest-matcher-utils "^24.0.0" + lodash "^4.17.11" + pretty-format "^24.0.0" + redent "^3.0.0" + +"@testing-library/react@^9.4.1": + version "9.5.0" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-9.5.0.tgz#71531655a7890b61e77a1b39452fbedf0472ca5e" + integrity sha512-di1b+D0p+rfeboHO5W7gTVeZDIK5+maEgstrZbWZSSvxDyfDRkkyBE1AJR5Psd6doNldluXlCWqXriUfqu/9Qg== + dependencies: + "@babel/runtime" "^7.8.4" + "@testing-library/dom" "^6.15.0" + "@types/testing-library__react" "^9.1.2" + +"@testing-library/user-event@^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-10.0.0.tgz#68dc84111c882cbf595d6bafa3691e4daa375fbd" + integrity sha512-ygQ1SaX3AzWDGPer5e2LF7FvWwLPG+XYViHvpW4ObseOkqmJI2ruawp9iLmEwxQW88jNCCExvonh0jBAwwiYZw== + +"@types/babel__core@^7.1.0": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.6.tgz#16ff42a5ae203c9af1c6e190ed1f30f83207b610" + integrity sha512-tTnhWszAqvXnhW7m5jQU9PomXSiKXk2sFxpahXvI20SZKu9ylPi8WtIxueZ6ehDWikPT0jeFujMj3X4ZHuf3Tg== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.1" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.1.tgz#4901767b397e8711aeb99df8d396d7ba7b7f0e04" + integrity sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307" + integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.9.tgz#be82fab304b141c3eee81a4ce3b034d0eba1590a" + integrity sha512-jEFQ8L1tuvPjOI8lnpaf73oCJe+aoxL6ygqSy6c8LcW98zaC+4mzWuQIRCEvKeCOu+lbqdXcg4Uqmm1S8AP1tw== + dependencies: + "@babel/types" "^7.3.0" + +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + +"@types/eslint-visitor-keys@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" + integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== + +"@types/events@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" + integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== + +"@types/glob@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" + integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== + dependencies: + "@types/events" "*" + "@types/minimatch" "*" + "@types/node" "*" + +"@types/history@*": + version "4.7.5" + resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.5.tgz#527d20ef68571a4af02ed74350164e7a67544860" + integrity sha512-wLD/Aq2VggCJXSjxEwrMafIP51Z+13H78nXIX0ABEuIGhmB5sNGbR113MOKo+yfw+RDo1ZU3DM6yfnnRF/+ouw== + +"@types/hoist-non-react-statics@^3.3.0": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" + integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" + integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a" + integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA== + dependencies: + "@types/istanbul-lib-coverage" "*" + "@types/istanbul-lib-report" "*" + +"@types/jest@^24.0.0": + version "24.9.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.9.1.tgz#02baf9573c78f1b9974a5f36778b366aa77bd534" + integrity sha512-Fb38HkXSVA4L8fGKEZ6le5bB8r6MRWlOCZbVuWZcmOMSCd2wCYOwN1ibj8daIoV9naq7aaOZjrLCoCMptKU/4Q== + dependencies: + jest-diff "^24.3.0" + +"@types/json-schema@^7.0.3": + version "7.0.4" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" + integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== + +"@types/lodash@^4.14.149": + version "4.14.149" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440" + integrity sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ== + +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + +"@types/node@*", "@types/node@^12.0.0": + version "12.12.31" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.31.tgz#d6b4f9645fee17f11319b508fb1001797425da51" + integrity sha512-T+wnJno8uh27G9c+1T+a1/WYCHzLeDqtsGJkoEdSp2X8RTh3oOCZQcUnjAx90CS8cmmADX51O0FI/tu9s0yssg== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/prop-types@*": + version "15.7.3" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" + integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + +"@types/q@^1.5.1": + version "1.5.2" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" + integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== + +"@types/react-dom@*", "@types/react-dom@^16.9.0": + version "16.9.5" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.5.tgz#5de610b04a35d07ffd8f44edad93a71032d9aaa7" + integrity sha512-BX6RQ8s9D+2/gDhxrj8OW+YD4R+8hj7FEM/OJHGNR0KipE1h1mSsf39YeyC81qafkq+N3rU3h3RFbLSwE5VqUg== + dependencies: + "@types/react" "*" + +"@types/react-redux@^7.1.5": + version "7.1.7" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.7.tgz#12a0c529aba660696947384a059c5c6e08185c7a" + integrity sha512-U+WrzeFfI83+evZE2dkZ/oF/1vjIYgqrb5dGgedkqVV8HEfDFujNgWCwHL89TDuWKb47U0nTBT6PLGq4IIogWg== + dependencies: + "@types/hoist-non-react-statics" "^3.3.0" + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + redux "^4.0.0" + +"@types/react-router-dom@^5.1.3": + version "5.1.3" + resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.1.3.tgz#b5d28e7850bd274d944c0fbbe5d57e6b30d71196" + integrity sha512-pCq7AkOvjE65jkGS5fQwQhvUp4+4PVD9g39gXLZViP2UqFiFzsEpB3PKf0O6mdbKsewSK8N14/eegisa/0CwnA== + dependencies: + "@types/history" "*" + "@types/react" "*" + "@types/react-router" "*" + +"@types/react-router@*", "@types/react-router@^5.1.3": + version "5.1.4" + resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.4.tgz#7d70bd905543cb6bcbdcc6bd98902332054f31a6" + integrity sha512-PZtnBuyfL07sqCJvGg3z+0+kt6fobc/xmle08jBiezLS8FrmGeiGkJnuxL/8Zgy9L83ypUhniV5atZn/L8n9MQ== + dependencies: + "@types/history" "*" + "@types/react" "*" + +"@types/react@*", "@types/react@^16.9.0": + version "16.9.25" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.25.tgz#6ae2159b40138c792058a23c3c04fd3db49e929e" + integrity sha512-Dlj2V72cfYLPNscIG3/SMUOzhzj7GK3bpSrfefwt2YT9GLynvLCCZjbhyF6VsT0q0+aRACRX03TDJGb7cA0cqg== + dependencies: + "@types/prop-types" "*" + csstype "^2.2.0" + +"@types/stack-utils@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" + integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== + +"@types/testing-library__dom@*": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@types/testing-library__dom/-/testing-library__dom-7.0.0.tgz#c0fb7d1c2495a3d26f19342102142d47500f0319" + integrity sha512-1TEPWyqQ6IQ7R1hCegZmFSA3KrBQjdzJW7yC9ybpRcFst5XuPOqBGNr0mTAKbxwI/TrTyc1skeyLJrpcvAf93w== + dependencies: + pretty-format "^25.1.0" + +"@types/testing-library__dom@^6.12.1": + version "6.14.0" + resolved "https://registry.yarnpkg.com/@types/testing-library__dom/-/testing-library__dom-6.14.0.tgz#1aede831cb4ed4a398448df5a2c54b54a365644e" + integrity sha512-sMl7OSv0AvMOqn1UJ6j1unPMIHRXen0Ita1ujnMX912rrOcawe4f7wu0Zt9GIQhBhJvH2BaibqFgQ3lP+Pj2hA== + dependencies: + pretty-format "^24.3.0" + +"@types/testing-library__react@^9.1.2": + version "9.1.3" + resolved "https://registry.yarnpkg.com/@types/testing-library__react/-/testing-library__react-9.1.3.tgz#35eca61cc6ea923543796f16034882a1603d7302" + integrity sha512-iCdNPKU3IsYwRK9JieSYAiX0+aYDXOGAmrC/3/M7AqqSDKnWWVv07X+Zk1uFSL7cMTUYzv4lQRfohucEocn5/w== + dependencies: + "@types/react-dom" "*" + "@types/testing-library__dom" "*" + pretty-format "^25.1.0" + +"@types/yargs-parser@*": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" + integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== + +"@types/yargs@^13.0.0": + version "13.0.8" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.8.tgz#a38c22def2f1c2068f8971acb3ea734eb3c64a99" + integrity sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA== + dependencies: + "@types/yargs-parser" "*" + +"@types/yargs@^15.0.0": + version "15.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.4.tgz#7e5d0f8ca25e9d5849f2ea443cf7c402decd8299" + integrity sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg== + dependencies: + "@types/yargs-parser" "*" + +"@typescript-eslint/eslint-plugin@^2.10.0": + version "2.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.25.0.tgz#0b60917332f20dcff54d0eb9be2a9e9f4c9fbd02" + integrity sha512-W2YyMtjmlrOjtXc+FtTelVs9OhuR6OlYc4XKIslJ8PUJOqgYYAPRJhAqkYRQo3G4sjvG8jSodsNycEn4W2gHUw== + dependencies: + "@typescript-eslint/experimental-utils" "2.25.0" + functional-red-black-tree "^1.0.1" + regexpp "^3.0.0" + tsutils "^3.17.1" + +"@typescript-eslint/experimental-utils@2.25.0": + version "2.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.25.0.tgz#13691c4fe368bd377b1e5b1e4ad660b220bf7714" + integrity sha512-0IZ4ZR5QkFYbaJk+8eJ2kYeA+1tzOE1sBjbwwtSV85oNWYUBep+EyhlZ7DLUCyhMUGuJpcCCFL0fDtYAP1zMZw== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/typescript-estree" "2.25.0" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + +"@typescript-eslint/parser@^2.10.0": + version "2.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.25.0.tgz#abfb3d999084824d9a756d9b9c0f36fba03adb76" + integrity sha512-mccBLaBSpNVgp191CP5W+8U1crTyXsRziWliCqzj02kpxdjKMvFHGJbK33NroquH3zB/gZ8H511HEsJBa2fNEg== + dependencies: + "@types/eslint-visitor-keys" "^1.0.0" + "@typescript-eslint/experimental-utils" "2.25.0" + "@typescript-eslint/typescript-estree" "2.25.0" + eslint-visitor-keys "^1.1.0" + +"@typescript-eslint/typescript-estree@2.25.0": + version "2.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.25.0.tgz#b790497556734b7476fa7dd3fa539955a5c79e2c" + integrity sha512-VUksmx5lDxSi6GfmwSK7SSoIKSw9anukWWNitQPqt58LuYrKalzsgeuignbqnB+rK/xxGlSsCy8lYnwFfB6YJg== + dependencies: + debug "^4.1.1" + eslint-visitor-keys "^1.1.0" + glob "^7.1.6" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^6.3.0" + tsutils "^3.17.1" + +"@webassemblyjs/ast@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" + integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== + dependencies: + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + +"@webassemblyjs/floating-point-hex-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" + integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== + +"@webassemblyjs/helper-api-error@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" + integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== + +"@webassemblyjs/helper-buffer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" + integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== + +"@webassemblyjs/helper-code-frame@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" + integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== + dependencies: + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/helper-fsm@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" + integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== + +"@webassemblyjs/helper-module-context@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" + integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== + dependencies: + "@webassemblyjs/ast" "1.8.5" + mamacro "^0.0.3" + +"@webassemblyjs/helper-wasm-bytecode@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" + integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== + +"@webassemblyjs/helper-wasm-section@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" + integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + +"@webassemblyjs/ieee754@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" + integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" + integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" + integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== + +"@webassemblyjs/wasm-edit@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" + integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/helper-wasm-section" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-opt" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/wasm-gen@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" + integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wasm-opt@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" + integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + +"@webassemblyjs/wasm-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" + integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wast-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" + integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/floating-point-hex-parser" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-code-frame" "1.8.5" + "@webassemblyjs/helper-fsm" "1.8.5" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" + integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abab@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" + integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-globals@^4.1.0, acorn-globals@^4.3.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" + integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== + dependencies: + acorn "^6.0.1" + acorn-walk "^6.0.1" + +acorn-jsx@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" + integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== + +acorn-node@^1.6.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8" + integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A== + dependencies: + acorn "^7.0.0" + acorn-walk "^7.0.0" + xtend "^4.0.2" + +acorn-walk@^6.0.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" + integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== + +acorn-walk@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.1.1.tgz#345f0dffad5c735e7373d2fec9a1023e6a44b83e" + integrity sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ== + +acorn@^5.5.3: + version "5.7.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" + integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== + +acorn@^6.0.1, acorn@^6.0.4, acorn@^6.2.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" + integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== + +acorn@^7.0.0, acorn@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" + integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== + +address@1.1.2, address@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" + integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== + +adjust-sourcemap-loader@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-2.0.0.tgz#6471143af75ec02334b219f54bc7970c52fb29a4" + integrity sha512-4hFsTsn58+YjrU9qKzML2JSSDqKvN8mUGQ0nNIrfPi8hmIONT4L3uUaT6MKdMsZ9AjsU6D2xDkZxCkbQPxChrA== + dependencies: + assert "1.4.1" + camelcase "5.0.0" + loader-utils "1.2.3" + object-path "0.11.4" + regex-parser "2.2.10" + +aggregate-error@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0" + integrity sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" + integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== + +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.5.5: + version "6.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" + integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +alphanum-sort@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= + +ansi-colors@^3.0.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== + +ansi-escapes@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-escapes@^4.2.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" + integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== + dependencies: + type-fest "^0.11.0" + +ansi-html@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.0.0, ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +aria-query@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc" + integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w= + dependencies: + ast-types-flow "0.0.7" + commander "^2.11.0" + +aria-query@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.0.2.tgz#250687b4ccde1ab86d127da0432ae3552fc7b145" + integrity sha512-S1G1V790fTaigUSM/Gd0NngzEfiMy9uTUfMyHhKhVyy4cH5O/eTuR01ydhGL0z4Za1PXFTRGH3qL8VhUQuEO5w== + dependencies: + "@babel/runtime" "^7.7.4" + "@babel/runtime-corejs3" "^7.7.4" + +arity-n@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/arity-n/-/arity-n-1.0.4.tgz#d9e76b11733e08569c0847ae7b39b2860b30b745" + integrity sha1-2edrEXM+CFacCEeuezmyhgswt0U= + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-includes@^3.0.3, array-includes@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" + integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0" + is-string "^1.0.5" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +array.prototype.flat@^1.2.1: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" + integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asap@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= + dependencies: + util "0.10.3" + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +ast-types-flow@0.0.7, ast-types-flow@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" + integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +autoprefixer@^9.4.5, autoprefixer@^9.6.1, autoprefixer@^9.7.4: + version "9.7.5" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.5.tgz#8df10b9ff9b5814a8d411a5cfbab9c793c392376" + integrity sha512-URo6Zvt7VYifomeAfJlMFnYDhow1rk2bufwkbamPEAtQFcL11moLk4PnR7n9vlu7M+BkXAZkHFA0mIcY7tjQFg== + dependencies: + browserslist "^4.11.0" + caniuse-lite "^1.0.30001036" + chalk "^2.4.2" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^7.0.27" + postcss-value-parser "^4.0.3" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" + integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== + +axobject-query@^2.0.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.1.2.tgz#2bdffc0371e643e5f03ba99065d5179b9ca79799" + integrity sha512-ICt34ZmrVt8UQnvPl6TVyDTkmhXmAyAT4Jh5ugfGUX4MOrZ+U/ZY6/sdylRw3qGNr9Ub5AJsaHeDMzNLehRdOQ== + +babel-code-frame@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-eslint@10.0.3: + version "10.0.3" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.3.tgz#81a2c669be0f205e19462fed2482d33e4687a88a" + integrity sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + eslint-visitor-keys "^1.0.0" + resolve "^1.12.0" + +babel-extract-comments@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz#0a2aedf81417ed391b85e18b4614e693a0351a21" + integrity sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ== + dependencies: + babylon "^6.18.0" + +babel-jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54" + integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw== + dependencies: + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/babel__core" "^7.1.0" + babel-plugin-istanbul "^5.1.0" + babel-preset-jest "^24.9.0" + chalk "^2.4.2" + slash "^2.0.0" + +babel-loader@8.0.6: + version "8.0.6" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb" + integrity sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw== + dependencies: + find-cache-dir "^2.0.0" + loader-utils "^1.0.2" + mkdirp "^0.5.1" + pify "^4.0.1" + +babel-plugin-dynamic-import-node@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" + integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ== + dependencies: + object.assign "^4.1.0" + +babel-plugin-emotion@^10.0.27: + version "10.0.29" + resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.0.29.tgz#89d8e497091fcd3d10331f097f1471e4cc3f35b4" + integrity sha512-7Jpi1OCxjyz0k163lKtqP+LHMg5z3S6A7vMBfHnF06l2unmtsOmFDzZBpGf0CWo1G4m8UACfVcDJiSiRuu/cSw== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@emotion/hash" "0.8.0" + "@emotion/memoize" "0.7.4" + "@emotion/serialize" "^0.11.16" + babel-plugin-macros "^2.0.0" + babel-plugin-syntax-jsx "^6.18.0" + convert-source-map "^1.5.0" + escape-string-regexp "^1.0.5" + find-root "^1.1.0" + source-map "^0.5.7" + +babel-plugin-istanbul@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854" + integrity sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + find-up "^3.0.0" + istanbul-lib-instrument "^3.3.0" + test-exclude "^5.2.3" + +babel-plugin-jest-hoist@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756" + integrity sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw== + dependencies: + "@types/babel__traverse" "^7.0.6" + +babel-plugin-macros@2.8.0, babel-plugin-macros@^2.0.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" + integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg== + dependencies: + "@babel/runtime" "^7.7.2" + cosmiconfig "^6.0.0" + resolve "^1.12.0" + +babel-plugin-named-asset-import@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.6.tgz#c9750a1b38d85112c9e166bf3ef7c5dbc605f4be" + integrity sha512-1aGDUfL1qOOIoqk9QKGIo2lANk+C7ko/fqH0uIyC71x3PEGz0uVP8ISgfEsFuG+FKmjHTvFK/nNM8dowpmUxLA== + +babel-plugin-syntax-jsx@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= + +babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= + +babel-plugin-transform-object-rest-spread@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" + integrity sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY= + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.26.0" + +babel-plugin-transform-react-remove-prop-types@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a" + integrity sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA== + +babel-preset-jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc" + integrity sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg== + dependencies: + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + babel-plugin-jest-hoist "^24.9.0" + +babel-preset-react-app@^9.1.1: + version "9.1.2" + resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-9.1.2.tgz#54775d976588a8a6d1a99201a702befecaf48030" + integrity sha512-k58RtQOKH21NyKtzptoAvtAODuAJJs3ZhqBMl456/GnXEQ/0La92pNmwgWoMn5pBTrsvk3YYXdY7zpY4e3UIxA== + dependencies: + "@babel/core" "7.9.0" + "@babel/plugin-proposal-class-properties" "7.8.3" + "@babel/plugin-proposal-decorators" "7.8.3" + "@babel/plugin-proposal-nullish-coalescing-operator" "7.8.3" + "@babel/plugin-proposal-numeric-separator" "7.8.3" + "@babel/plugin-proposal-optional-chaining" "7.9.0" + "@babel/plugin-transform-flow-strip-types" "7.9.0" + "@babel/plugin-transform-react-display-name" "7.8.3" + "@babel/plugin-transform-runtime" "7.9.0" + "@babel/preset-env" "7.9.0" + "@babel/preset-react" "7.9.1" + "@babel/preset-typescript" "7.9.0" + "@babel/runtime" "7.9.0" + babel-plugin-macros "2.8.0" + babel-plugin-transform-react-remove-prop-types "0.4.24" + +babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" + integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + 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.17" + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +boolbase@^1.0.0, boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + +browser-resolve@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" + integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== + dependencies: + resolve "1.1.7" + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@4.10.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.10.0.tgz#f179737913eaf0d2b98e4926ac1ca6a15cbcc6a9" + integrity sha512-TpfK0TDgv71dzuTsEAlQiHeWQ/tiPqgNZVdv046fvNtBZrjbv2O3TsWCDU0AWGJJKCF/KsjNdLzR9hXOsh/CfA== + dependencies: + caniuse-lite "^1.0.30001035" + electron-to-chromium "^1.3.378" + node-releases "^1.1.52" + pkg-up "^3.1.0" + +browserslist@^4.0.0, browserslist@^4.11.0, browserslist@^4.6.2, browserslist@^4.6.4, browserslist@^4.8.3, browserslist@^4.9.1: + version "4.11.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.11.0.tgz#aef4357b10a8abda00f97aac7cd587b2082ba1ad" + integrity sha512-WqEC7Yr5wUH5sg6ruR++v2SGOQYpyUdYYd4tZoAq1F7y+QXoLoYGXVbxhtaIqWmAJjtNTRjVD3HuJc1OXTel2A== + dependencies: + caniuse-lite "^1.0.30001035" + electron-to-chromium "^1.3.380" + node-releases "^1.1.52" + pkg-up "^3.1.0" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.0, bytes@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cacache@^12.0.2: + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cacache@^13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-13.0.1.tgz#a8000c21697089082f85287a1aec6e382024a71c" + integrity sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w== + dependencies: + chownr "^1.1.2" + figgy-pudding "^3.5.1" + fs-minipass "^2.0.0" + glob "^7.1.4" + graceful-fs "^4.2.2" + infer-owner "^1.0.4" + lru-cache "^5.1.1" + minipass "^3.0.0" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + p-map "^3.0.0" + promise-inflight "^1.0.1" + rimraf "^2.7.1" + ssri "^7.0.0" + unique-filename "^1.1.1" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camel-case@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.1.tgz#1fc41c854f00e2f7d0139dfeba1542d6896fe547" + integrity sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q== + dependencies: + pascal-case "^3.1.1" + tslib "^1.10.0" + +camelcase-css@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + +camelcase@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" + integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== + +camelcase@5.3.1, camelcase@^5.0.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001035, caniuse-lite@^1.0.30001036: + version "1.0.30001037" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001037.tgz#cf666560b14f8dfa18abc235db1ef2699273af6e" + integrity sha512-qQP40FzWQ1i9RTjxppOUnpM8OwTBFL5DQbjoR9Az32EtM7YUZOw9orFO6rj1C+xWAGzz+X3bUe09Jf5Ep+zpuA== + +capture-exit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" + integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== + dependencies: + rsvp "^4.8.4" + +case-sensitive-paths-webpack-plugin@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz#23ac613cc9a856e4f88ff8bb73bbb5e989825cf7" + integrity sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +chokidar@^2.0.2, chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chokidar@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450" + integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.3.0" + optionalDependencies: + fsevents "~2.1.2" + +chownr@^1.1.1, chownr@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chrome-trace-event@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" + integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== + dependencies: + tslib "^1.9.0" + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-css@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" + integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== + dependencies: + source-map "~0.6.0" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + +clone-deep@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-0.2.4.tgz#4e73dd09e9fb971cc38670c5dced9c1896481cc6" + integrity sha1-TnPdCen7lxzDhnDF3O2cGJZIHMY= + dependencies: + for-own "^0.1.3" + is-plain-object "^2.0.1" + kind-of "^3.0.2" + lazy-cache "^1.0.3" + shallow-clone "^0.1.2" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +clsx@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.0.tgz#62937c6adfea771247c34b54d320fb99624f5702" + integrity sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA== + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +coa@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" + integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== + dependencies: + "@types/q" "^1.5.1" + chalk "^2.4.1" + q "^1.1.2" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0, color-convert@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" + integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.11.0, commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +common-tags@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" + integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +compose-function@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/compose-function/-/compose-function-3.0.3.tgz#9ed675f13cc54501d30950a486ff6a7ba3ab185f" + integrity sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8= + dependencies: + arity-n "^1.0.4" + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +confusing-browser-globals@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz#72bc13b483c0276801681871d4898516f8f54fdd" + integrity sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw== + +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@1.7.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +convert-source-map@^0.3.3: + version "0.3.5" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-0.3.5.tgz#f1d802950af7dd2631a1febe0596550c86ab3190" + integrity sha1-8dgClQr33SYxof6+BZZVDIarMZA= + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-js-compat@^3.6.2: + version "3.6.4" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.4.tgz#938476569ebb6cda80d339bcf199fae4f16fff17" + integrity sha512-zAa3IZPvsJ0slViBQ2z+vgyyTuhd3MFn1rBQjZSKVEgB0UMYhUkCj9jJUVPgGTGqWvsBVmfnruXgTcNyTlEiSA== + dependencies: + browserslist "^4.8.3" + semver "7.0.0" + +core-js-pure@^3.0.0: + version "3.6.4" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.4.tgz#4bf1ba866e25814f149d4e9aaa08c36173506e3a" + integrity sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw== + +core-js@^2.4.0: + version "2.6.11" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" + integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== + +core-js@^3.5.0: + version "3.6.4" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647" + integrity sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw== + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cosmiconfig@^5.0.0, cosmiconfig@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" + integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.13.1" + parse-json "^4.0.0" + +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@7.0.1, cross-spawn@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" + integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-blank-pseudo@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5" + integrity sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w== + dependencies: + postcss "^7.0.5" + +css-color-names@0.0.4, css-color-names@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" + integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= + +css-declaration-sorter@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" + integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA== + dependencies: + postcss "^7.0.1" + timsort "^0.3.0" + +css-has-pseudo@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz#3c642ab34ca242c59c41a125df9105841f6966ee" + integrity sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^5.0.0-rc.4" + +css-loader@3.4.2: + version "3.4.2" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.4.2.tgz#d3fdb3358b43f233b78501c5ed7b1c6da6133202" + integrity sha512-jYq4zdZT0oS0Iykt+fqnzVLRIeiPWhka+7BqPn+oSIpWJAHak5tmB/WZrJ2a21JhCeFyNnnlroSl8c+MtVndzA== + dependencies: + camelcase "^5.3.1" + cssesc "^3.0.0" + icss-utils "^4.1.1" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.23" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.2" + postcss-modules-scope "^2.1.1" + postcss-modules-values "^3.0.0" + postcss-value-parser "^4.0.2" + schema-utils "^2.6.0" + +css-prefers-color-scheme@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz#6f830a2714199d4f0d0d0bb8a27916ed65cff1f4" + integrity sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg== + dependencies: + postcss "^7.0.5" + +css-select-base-adapter@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" + integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== + +css-select@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-select@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" + integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== + dependencies: + boolbase "^1.0.0" + css-what "^3.2.1" + domutils "^1.7.0" + nth-check "^1.0.2" + +css-tree@1.0.0-alpha.37: + version "1.0.0-alpha.37" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" + integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== + dependencies: + mdn-data "2.0.4" + source-map "^0.6.1" + +css-tree@1.0.0-alpha.39: + version "1.0.0-alpha.39" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb" + integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA== + dependencies: + mdn-data "2.0.6" + source-map "^0.6.1" + +css-unit-converter@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.1.tgz#d9b9281adcfd8ced935bdbaba83786897f64e996" + integrity sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY= + +css-what@2.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== + +css-what@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.2.1.tgz#f4a8f12421064621b456755e34a03a2c22df5da1" + integrity sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw== + +css.escape@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= + +css@^2.0.0, css@^2.2.3: + version "2.2.4" + resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" + integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw== + dependencies: + inherits "^2.0.3" + source-map "^0.6.1" + source-map-resolve "^0.5.2" + urix "^0.1.0" + +cssdb@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-4.4.0.tgz#3bf2f2a68c10f5c6a08abd92378331ee803cddb0" + integrity sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ== + +cssesc@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" + integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssnano-preset-default@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" + integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA== + dependencies: + css-declaration-sorter "^4.0.1" + cssnano-util-raw-cache "^4.0.1" + postcss "^7.0.0" + postcss-calc "^7.0.1" + postcss-colormin "^4.0.3" + postcss-convert-values "^4.0.1" + postcss-discard-comments "^4.0.2" + postcss-discard-duplicates "^4.0.2" + postcss-discard-empty "^4.0.1" + postcss-discard-overridden "^4.0.1" + postcss-merge-longhand "^4.0.11" + postcss-merge-rules "^4.0.3" + postcss-minify-font-values "^4.0.2" + postcss-minify-gradients "^4.0.2" + postcss-minify-params "^4.0.2" + postcss-minify-selectors "^4.0.2" + postcss-normalize-charset "^4.0.1" + postcss-normalize-display-values "^4.0.2" + postcss-normalize-positions "^4.0.2" + postcss-normalize-repeat-style "^4.0.2" + postcss-normalize-string "^4.0.2" + postcss-normalize-timing-functions "^4.0.2" + postcss-normalize-unicode "^4.0.1" + postcss-normalize-url "^4.0.1" + postcss-normalize-whitespace "^4.0.2" + postcss-ordered-values "^4.1.2" + postcss-reduce-initial "^4.0.3" + postcss-reduce-transforms "^4.0.2" + postcss-svgo "^4.0.2" + postcss-unique-selectors "^4.0.1" + +cssnano-util-get-arguments@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" + integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= + +cssnano-util-get-match@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" + integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= + +cssnano-util-raw-cache@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" + integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA== + dependencies: + postcss "^7.0.0" + +cssnano-util-same-parent@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" + integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== + +cssnano@^4.1.10: + version "4.1.10" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" + integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ== + dependencies: + cosmiconfig "^5.0.0" + cssnano-preset-default "^4.0.7" + is-resolvable "^1.0.0" + postcss "^7.0.0" + +csso@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.0.3.tgz#0d9985dc852c7cc2b2cacfbbe1079014d1a8e903" + integrity sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ== + dependencies: + css-tree "1.0.0-alpha.39" + +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@^0.3.4: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^1.0.0, cssstyle@^1.1.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" + integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== + dependencies: + cssom "0.3.x" + +csstype@^2.2.0, csstype@^2.5.7: + version "2.6.9" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.9.tgz#05141d0cd557a56b8891394c1911c40c8a98d098" + integrity sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q== + +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +damerau-levenshtein@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz#143c1641cb3d85c60c32329e26899adea8701791" + integrity sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug== + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +data-urls@^1.0.0, data-urls@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" + integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== + dependencies: + abab "^2.0.0" + whatwg-mimetype "^2.2.0" + whatwg-url "^7.0.0" + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.0.0, debug@^3.1.1, debug@^3.2.5: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-equal@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +default-gateway@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" + integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA== + dependencies: + execa "^1.0.0" + ip-regex "^2.1.0" + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +defined@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= + +del@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" + integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== + dependencies: + "@types/glob" "^7.1.1" + globby "^6.1.0" + is-path-cwd "^2.0.0" + is-path-in-cwd "^2.0.0" + p-map "^2.0.0" + pify "^4.0.1" + rimraf "^2.6.3" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +dependency-graph@^0.8.0: + version "0.8.1" + resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.8.1.tgz#9b8cae3aa2c7bd95ccb3347a09a2d1047a6c3c5a" + integrity sha512-g213uqF8fyk40W8SBjm079n3CZB4qSpCrA2ye1fLGzH/4HEgB6tzuW2CbLE7leb4t45/6h44Ud59Su1/ROTfqw== + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= + +detect-node@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" + integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== + +detect-port-alt@1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" + integrity sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q== + dependencies: + address "^1.0.1" + debug "^2.6.0" + +detective@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.0.tgz#feb2a77e85b904ecdea459ad897cc90a99bd2a7b" + integrity sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg== + dependencies: + acorn-node "^1.6.1" + defined "^1.0.0" + minimist "^1.1.1" + +diff-sequences@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" + integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag== + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" + integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-accessibility-api@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.3.0.tgz#511e5993dd673b97c87ea47dba0e3892f7e0c983" + integrity sha512-PzwHEmsRP3IGY4gv/Ug+rMeaTIyTJvadCb+ujYXYeIylbHJezIyNToe8KfEgHTCEYyC+/bUghYOGg8yMGlZ6vA== + +dom-converter@^0.2: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domelementtype@1, domelementtype@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== + dependencies: + webidl-conversions "^4.0.2" + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1, domutils@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +dot-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.3.tgz#21d3b52efaaba2ea5fda875bb1aa8124521cf4aa" + integrity sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA== + dependencies: + no-case "^3.0.3" + tslib "^1.10.0" + +dot-prop@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" + integrity sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A== + dependencies: + is-obj "^2.0.0" + +dotenv-expand@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" + integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== + +dotenv@8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" + integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== + +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +electron-to-chromium@^1.3.378, electron-to-chromium@^1.3.380: + version "1.3.384" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.384.tgz#ca1d5710a4c53168431f1cbef39c8a971b646bf8" + integrity sha512-9jGNF78o450ymPf63n7/j1HrRAD4xGTsDkKY2X6jtCAWaYgph2A9xQjwfwRpj+AovkARMO+JfZuVCFTdandD6w== + +elliptic@^6.0.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" + integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emoji-regex@^7.0.1, emoji-regex@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" + integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +entities@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" + integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2: + version "1.17.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" + integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.1.5" + is-regex "^1.0.5" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimleft "^2.1.1" + string.prototype.trimright "^2.1.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@2.0.3, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escodegen@^1.11.0, escodegen@^1.9.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.1.tgz#ba01d0c8278b5e95a9a45350142026659027a457" + integrity sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +eslint-config-react-app@^5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-5.2.1.tgz#698bf7aeee27f0cea0139eaef261c7bf7dd623df" + integrity sha512-pGIZ8t0mFLcV+6ZirRgYK6RVqUIKRIi9MmgzUEmrIknsn3AdO0I32asO86dJgloHq+9ZPl8UIg8mYrvgP5u2wQ== + dependencies: + confusing-browser-globals "^1.0.9" + +eslint-import-resolver-node@^0.3.2: + version "0.3.3" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404" + integrity sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg== + dependencies: + debug "^2.6.9" + resolve "^1.13.1" + +eslint-loader@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-3.0.3.tgz#e018e3d2722381d982b1201adb56819c73b480ca" + integrity sha512-+YRqB95PnNvxNp1HEjQmvf9KNvCin5HXYYseOXVC2U0KEcw4IkQ2IQEBG46j7+gW39bMzeu0GsUhVbBY3Votpw== + dependencies: + fs-extra "^8.1.0" + loader-fs-cache "^1.0.2" + loader-utils "^1.2.3" + object-hash "^2.0.1" + schema-utils "^2.6.1" + +eslint-module-utils@^2.4.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz#7878f7504824e1b857dd2505b59a8e5eda26a708" + integrity sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q== + dependencies: + debug "^2.6.9" + pkg-dir "^2.0.0" + +eslint-plugin-flowtype@4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-4.6.0.tgz#82b2bd6f21770e0e5deede0228e456cb35308451" + integrity sha512-W5hLjpFfZyZsXfo5anlu7HM970JBDqbEshAJUkeczP6BFCIfJXuiIBQXyberLRtOStT0OGPF8efeTbxlHk4LpQ== + dependencies: + lodash "^4.17.15" + +eslint-plugin-import@2.20.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.0.tgz#d749a7263fb6c29980def8e960d380a6aa6aecaa" + integrity sha512-NK42oA0mUc8Ngn4kONOPsPB1XhbUvNHqF+g307dPV28aknPoiNnKLFd9em4nkswwepdF5ouieqv5Th/63U7YJQ== + dependencies: + array-includes "^3.0.3" + array.prototype.flat "^1.2.1" + contains-path "^0.1.0" + debug "^2.6.9" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.2" + eslint-module-utils "^2.4.1" + has "^1.0.3" + minimatch "^3.0.4" + object.values "^1.1.0" + read-pkg-up "^2.0.0" + resolve "^1.12.0" + +eslint-plugin-jsx-a11y@6.2.3: + version "6.2.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz#b872a09d5de51af70a97db1eea7dc933043708aa" + integrity sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg== + dependencies: + "@babel/runtime" "^7.4.5" + aria-query "^3.0.0" + array-includes "^3.0.3" + ast-types-flow "^0.0.7" + axobject-query "^2.0.2" + damerau-levenshtein "^1.0.4" + emoji-regex "^7.0.2" + has "^1.0.3" + jsx-ast-utils "^2.2.1" + +eslint-plugin-react-hooks@^1.6.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04" + integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA== + +eslint-plugin-react@7.18.0: + version "7.18.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.18.0.tgz#2317831284d005b30aff8afb7c4e906f13fa8e7e" + integrity sha512-p+PGoGeV4SaZRDsXqdj9OWcOrOpZn8gXoGPcIQTzo2IDMbAKhNDnME9myZWqO3Ic4R3YmwAZ1lDjWl2R2hMUVQ== + dependencies: + array-includes "^3.1.1" + doctrine "^2.1.0" + has "^1.0.3" + jsx-ast-utils "^2.2.3" + object.entries "^1.1.1" + object.fromentries "^2.0.2" + object.values "^1.1.1" + prop-types "^15.7.2" + resolve "^1.14.2" + +eslint-plugin-simple-import-sort@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-5.0.2.tgz#43b5c4ab5affa2dd8481ef40216c71723becd2e2" + integrity sha512-YPEGo7DbMANQ01d2OXlREcaHRszsW8LoUQ9mIjI7gXSdwpnWKfogtzL6FiBfDf1teCBx+AdcjcfDXSKpmhTWeA== + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-scope@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" + integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" + integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.0.0.tgz#7be1cc70f27a72a76cd14aa698bcabed6890e1cd" + integrity sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== + +eslint@^6.6.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" + integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.10.0" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^5.0.0" + eslint-utils "^1.4.3" + eslint-visitor-keys "^1.1.0" + espree "^6.1.2" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^7.0.0" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.14" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.3" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^6.1.2" + strip-ansi "^5.2.0" + strip-json-comments "^3.0.1" + table "^5.2.3" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^6.1.2: + version "6.2.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" + integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== + dependencies: + acorn "^7.1.1" + acorn-jsx "^5.2.0" + eslint-visitor-keys "^1.1.0" + +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.2.0.tgz#a010a519c0288f2530b3404124bfb5f02e9797fe" + integrity sha512-weltsSqdeWIX9G2qQZz7KlTRJdkkOCTPgLYJUz1Hacf48R4YOwGPHO3+ORfWedqJKbq5WQmsgK90n+pFLIKt/Q== + dependencies: + estraverse "^5.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.0.0.tgz#ac81750b482c11cca26e4b07e83ed8f75fbcdc22" + integrity sha512-j3acdrMzqrxmJTNj5dbr1YbjacrYgAxVMeF0gK16E3j494mOe7xygM/ZLIguEQ0ETwAg2hlJCtHRGav+y0Ny5A== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eventemitter3@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb" + integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg== + +events@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" + integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== + +eventsource@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" + integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== + dependencies: + original "^1.0.0" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +exec-sh@^0.3.2: + version "0.3.4" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" + integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expect@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" + integrity sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q== + dependencies: + "@jest/types" "^24.9.0" + ansi-styles "^3.2.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-regex-util "^24.9.0" + +express@^4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" + integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== + dependencies: + type "^2.0.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + +fast-glob@^2.0.2: + version "2.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" + integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + +fast-glob@^3.0.3: + version "3.2.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.2.tgz#ade1a9d91148965d4bf7c51f72e1ca662d32e63d" + integrity sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastq@^1.6.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.1.tgz#4570c74f2ded173e71cf0beb08ac70bb85826791" + integrity sha512-mpIH5sKYueh3YyeJwqtVo8sORi0CgtmkVbK6kZStpQlZBYQuTzG2CZ7idSiJuA7bY0SFCWUc5WIs+oYumGCQNw== + dependencies: + reusify "^1.0.4" + +faye-websocket@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= + dependencies: + websocket-driver ">=0.5.1" + +faye-websocket@~0.11.1: + version "0.11.3" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" + integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== + dependencies: + websocket-driver ">=0.5.1" + +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.1" + +figgy-pudding@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== + +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + +file-loader@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-4.3.0.tgz#780f040f729b3d18019f20605f723e844b8a58af" + integrity sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA== + dependencies: + loader-utils "^1.2.3" + schema-utils "^2.5.0" + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +filesize@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.0.1.tgz#f850b509909c7c86f7e450ea19006c31c2ed3d2f" + integrity sha512-u4AYWPgbI5GBhs6id1KdImZWn5yfyFrrQ8OWZdN7ZMfA8Bf4HcO0BGo9bmUIEV8yrp8I1xVfJ/dn90GtFNNJcg== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + 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" + +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + integrity sha1-yN765XyKUqinhPnjHFfHQumToLk= + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + +find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-cache-dir@^3.2.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" + integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + +find-up@4.1.0, find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" + integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== + +flatten@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" + integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +follow-redirects@^1.0.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.10.0.tgz#01f5263aee921c6a54fb91667f08f4155ce169eb" + integrity sha512-4eyLK6s6lH32nOvLLwlIOnr9zrL8Sm+OvW4pVTJNoXeGzYIkHVf+pADQi+OJ0E67hiuSLezPVPyBcIZO50TmmQ== + dependencies: + debug "^3.0.0" + +for-in@^0.1.3: + version "0.1.8" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1" + integrity sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE= + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +fork-ts-checker-webpack-plugin@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz#a1642c0d3e65f50c2cc1742e9c0a80f441f86b19" + integrity sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ== + dependencies: + babel-code-frame "^6.22.0" + chalk "^2.4.1" + chokidar "^3.3.0" + micromatch "^3.1.10" + minimatch "^3.0.4" + semver "^5.6.0" + tapable "^1.0.0" + worker-rpc "^0.1.0" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-extra@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^8.0.0, fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@2.1.2, fsevents@~2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" + integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA== + +fsevents@^1.2.7: + version "1.2.12" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.12.tgz#db7e0d8ec3b0b45724fd4d83d43554a8f1f0de5c" + integrity sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +gensync@^1.0.0-beta.1: + version "1.0.0-beta.1" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" + integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== + +get-stdin@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-7.0.0.tgz#8d5de98f15171a125c5e516643c7a6d0ea8a96f6" + integrity sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ== + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + +glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^12.1.0: + version "12.4.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" + integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== + dependencies: + type-fest "^0.8.1" + +globby@8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.2.tgz#5697619ccd95c5275dbb2d6faa42087c1a941d8d" + integrity sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w== + dependencies: + array-union "^1.0.1" + dir-glob "2.0.0" + fast-glob "^2.0.2" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +globby@^10.0.1: + version "10.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" + integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.0.3" + glob "^7.1.3" + ignore "^5.1.1" + merge2 "^1.2.3" + slash "^3.0.0" + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2: + version "4.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" + integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== + +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= + +gud@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0" + integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw== + +gzip-size@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" + integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA== + dependencies: + duplexer "^0.1.1" + pify "^4.0.1" + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +harmony-reflect@^1.4.6: + version "1.6.1" + resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.1.tgz#c108d4f2bb451efef7a37861fdbdae72c9bdefa9" + integrity sha512-WJTeyp0JzGtHcuMsi7rw2VwtkvLa+JyfEKJCFyfcS0+CDkjQ5lHPu7zEhFZP+PDSRrEgXa5Ah0l1MbgbE41XjA== + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.0, has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.0, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hex-color-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" + integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== + +history@^4.9.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" + integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== + dependencies: + "@babel/runtime" "^7.1.2" + loose-envify "^1.2.0" + resolve-pathname "^3.0.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + value-equal "^1.0.1" + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +hosted-git-info@^2.1.4: + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +hsl-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" + integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= + +hsla-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" + integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= + +html-comment-regex@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" + integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== + dependencies: + whatwg-encoding "^1.0.1" + +html-entities@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" + integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= + +html-escaper@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.1.tgz#beed86b5d2b921e92533aa11bce6d8e3b583dee7" + integrity sha512-hNX23TjWwD3q56HpWjUHOKj1+4KKlnjv9PcmBUYKVpga+2cnb9nDx/B1o0yO4n+RZXZdiNxzx6B24C9aNMTkkQ== + +html-minifier-terser@^5.0.1: + version "5.0.5" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.0.5.tgz#8f12f639789f04faa9f5cf2ff9b9f65607f21f8b" + integrity sha512-cBSFFghQh/uHcfSiL42KxxIRMF7A144+3E44xdlctIjxEmkEfCvouxNyFH2wysXk1fCGBPwtcr3hDWlGTfkDew== + dependencies: + camel-case "^4.1.1" + clean-css "^4.2.3" + commander "^4.1.1" + he "^1.2.0" + param-case "^3.0.3" + relateurl "^0.2.7" + terser "^4.6.3" + +html-webpack-plugin@4.0.0-beta.11: + version "4.0.0-beta.11" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.11.tgz#3059a69144b5aecef97708196ca32f9e68677715" + integrity sha512-4Xzepf0qWxf8CGg7/WQM5qBB2Lc/NFI7MhU59eUDTkuQp3skZczH4UA1d6oQyDEIoMDgERVhRyTdtUPZ5s5HBg== + dependencies: + html-minifier-terser "^5.0.1" + loader-utils "^1.2.3" + lodash "^4.17.15" + pretty-error "^2.1.1" + tapable "^1.1.3" + util.promisify "1.0.0" + +htmlparser2@^3.3.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +"http-parser-js@>=0.4.0 <0.4.11": + version "0.4.10" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" + integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= + +http-proxy-middleware@0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" + integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== + dependencies: + http-proxy "^1.17.0" + is-glob "^4.0.0" + lodash "^4.17.11" + micromatch "^3.1.10" + +http-proxy@^1.17.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a" + integrity sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +iconv-lite@0.4.24, iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-utils@^4.0.0, icss-utils@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== + dependencies: + postcss "^7.0.14" + +identity-obj-proxy@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz#94d2bda96084453ef36fbc5aaec37e0f79f1fc14" + integrity sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ= + dependencies: + harmony-reflect "^1.4.6" + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.1: + version "5.1.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" + integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== + +immer@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/immer/-/immer-1.10.0.tgz#bad67605ba9c810275d91e1c2a47d4582e98286d" + integrity sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg== + +immer@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/immer/-/immer-6.0.2.tgz#5bc08dc4930c756d0749533a2afbd88c8de0cd19" + integrity sha512-56CMvUMZl4kkWJFFUe1TjBgGbyb9ibzpLyHD+RSKSVdytuDXgT/HXO1S+GJVywMVl5neGTdAogoR15eRVEd10Q== + +import-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" + integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= + dependencies: + import-from "^2.1.0" + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + +import-fresh@^3.0.0, import-fresh@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-from@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" + integrity sha1-M1238qev/VOqpHHUuAId7ja387E= + dependencies: + resolve-from "^3.0.0" + +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + +infer-owner@^1.0.3, infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +inquirer@7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.4.tgz#99af5bde47153abca23f5c7fc30db247f39da703" + integrity sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ== + dependencies: + ansi-escapes "^4.2.1" + chalk "^2.4.2" + cli-cursor "^3.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.15" + mute-stream "0.0.8" + run-async "^2.2.0" + rxjs "^6.5.3" + string-width "^4.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + +inquirer@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.1.0.tgz#1298a01859883e17c7264b82870ae1034f92dd29" + integrity sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg== + dependencies: + ansi-escapes "^4.2.1" + chalk "^3.0.0" + cli-cursor "^3.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.15" + mute-stream "0.0.8" + run-async "^2.4.0" + rxjs "^6.5.3" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + +internal-ip@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" + integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg== + dependencies: + default-gateway "^4.2.0" + ipaddr.js "^1.9.0" + +invariant@^2.2.2, invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + +ip@^1.1.0, ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.9.1, ipaddr.js@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-absolute-url@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" + integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= + +is-absolute-url@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" + integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-buffer@^1.0.2, is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-callable@^1.1.4, is-callable@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" + integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + +is-color-stop@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" + integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= + dependencies: + css-color-names "^0.0.4" + hex-color-regex "^1.1.0" + hsl-regex "^1.0.0" + hsla-regex "^1.0.0" + rgb-regex "^1.0.1" + rgba-regex "^1.0.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + +is-docker@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.0.0.tgz#2cb0df0e75e2d064fe1864c37cdeacb7b2dcf25b" + integrity sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ== + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + +is-path-cwd@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-in-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" + integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== + dependencies: + is-path-inside "^2.1.0" + +is-path-inside@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" + integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== + dependencies: + path-is-inside "^1.0.2" + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-regex@^1.0.4, is-regex@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" + integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== + dependencies: + has "^1.0.3" + +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-root@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" + integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== + +is-svg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" + integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ== + dependencies: + html-comment-regex "^1.1.0" + +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +is-wsl@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.1.1.tgz#4a1c152d429df3d441669498e2486d3596ebaf1d" + integrity sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog== + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" + integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== + +istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" + integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== + dependencies: + "@babel/generator" "^7.4.0" + "@babel/parser" "^7.4.3" + "@babel/template" "^7.4.0" + "@babel/traverse" "^7.4.3" + "@babel/types" "^7.4.0" + istanbul-lib-coverage "^2.0.5" + semver "^6.0.0" + +istanbul-lib-report@^2.0.4: + version "2.0.8" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" + integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ== + dependencies: + istanbul-lib-coverage "^2.0.5" + make-dir "^2.1.0" + supports-color "^6.1.0" + +istanbul-lib-source-maps@^3.0.1: + version "3.0.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" + integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^2.0.5" + make-dir "^2.1.0" + rimraf "^2.6.3" + source-map "^0.6.1" + +istanbul-reports@^2.2.6: + version "2.2.7" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.7.tgz#5d939f6237d7b48393cc0959eab40cd4fd056931" + integrity sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg== + dependencies: + html-escaper "^2.0.0" + +jest-changed-files@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" + integrity sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg== + dependencies: + "@jest/types" "^24.9.0" + execa "^1.0.0" + throat "^4.0.0" + +jest-cli@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" + integrity sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg== + dependencies: + "@jest/core" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + exit "^0.1.2" + import-local "^2.0.0" + is-ci "^2.0.0" + jest-config "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + prompts "^2.0.1" + realpath-native "^1.1.0" + yargs "^13.3.0" + +jest-config@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" + integrity sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ== + dependencies: + "@babel/core" "^7.1.0" + "@jest/test-sequencer" "^24.9.0" + "@jest/types" "^24.9.0" + babel-jest "^24.9.0" + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^24.9.0" + jest-environment-node "^24.9.0" + jest-get-type "^24.9.0" + jest-jasmine2 "^24.9.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + micromatch "^3.1.10" + pretty-format "^24.9.0" + realpath-native "^1.1.0" + +jest-diff@^24.0.0, jest-diff@^24.3.0, jest-diff@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" + integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== + dependencies: + chalk "^2.0.1" + diff-sequences "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + +jest-docblock@^24.3.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" + integrity sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA== + dependencies: + detect-newline "^2.1.0" + +jest-each@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" + integrity sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog== + dependencies: + "@jest/types" "^24.9.0" + chalk "^2.0.1" + jest-get-type "^24.9.0" + jest-util "^24.9.0" + pretty-format "^24.9.0" + +jest-environment-jsdom-fourteen@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom-fourteen/-/jest-environment-jsdom-fourteen-1.0.1.tgz#4cd0042f58b4ab666950d96532ecb2fc188f96fb" + integrity sha512-DojMX1sY+at5Ep+O9yME34CdidZnO3/zfPh8UW+918C5fIZET5vCjfkegixmsi7AtdYfkr4bPlIzmWnlvQkP7Q== + dependencies: + "@jest/environment" "^24.3.0" + "@jest/fake-timers" "^24.3.0" + "@jest/types" "^24.3.0" + jest-mock "^24.0.0" + jest-util "^24.0.0" + jsdom "^14.1.0" + +jest-environment-jsdom@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" + integrity sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + jest-util "^24.9.0" + jsdom "^11.5.1" + +jest-environment-node@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.9.0.tgz#333d2d2796f9687f2aeebf0742b519f33c1cbfd3" + integrity sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + jest-util "^24.9.0" + +jest-get-type@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" + integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== + +jest-haste-map@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" + integrity sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ== + dependencies: + "@jest/types" "^24.9.0" + anymatch "^2.0.0" + fb-watchman "^2.0.0" + graceful-fs "^4.1.15" + invariant "^2.2.4" + jest-serializer "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.9.0" + micromatch "^3.1.10" + sane "^4.0.3" + walker "^1.0.7" + optionalDependencies: + fsevents "^1.2.7" + +jest-jasmine2@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" + integrity sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw== + dependencies: + "@babel/traverse" "^7.1.0" + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + co "^4.6.0" + expect "^24.9.0" + is-generator-fn "^2.0.0" + jest-each "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-runtime "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + pretty-format "^24.9.0" + throat "^4.0.0" + +jest-leak-detector@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz#b665dea7c77100c5c4f7dfcb153b65cf07dcf96a" + integrity sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA== + dependencies: + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + +jest-matcher-utils@^24.0.0, jest-matcher-utils@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" + integrity sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA== + dependencies: + chalk "^2.0.1" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + +jest-message-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" + integrity sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/stack-utils" "^1.0.1" + chalk "^2.0.1" + micromatch "^3.1.10" + slash "^2.0.0" + stack-utils "^1.0.1" + +jest-mock@^24.0.0, jest-mock@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" + integrity sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w== + dependencies: + "@jest/types" "^24.9.0" + +jest-pnp-resolver@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" + integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== + +jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" + integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== + +jest-resolve-dependencies@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" + integrity sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g== + dependencies: + "@jest/types" "^24.9.0" + jest-regex-util "^24.3.0" + jest-snapshot "^24.9.0" + +jest-resolve@24.9.0, jest-resolve@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" + integrity sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ== + dependencies: + "@jest/types" "^24.9.0" + browser-resolve "^1.11.3" + chalk "^2.0.1" + jest-pnp-resolver "^1.2.1" + realpath-native "^1.1.0" + +jest-runner@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" + integrity sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg== + dependencies: + "@jest/console" "^24.7.1" + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.4.2" + exit "^0.1.2" + graceful-fs "^4.1.15" + jest-config "^24.9.0" + jest-docblock "^24.3.0" + jest-haste-map "^24.9.0" + jest-jasmine2 "^24.9.0" + jest-leak-detector "^24.9.0" + jest-message-util "^24.9.0" + jest-resolve "^24.9.0" + jest-runtime "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.6.0" + source-map-support "^0.5.6" + throat "^4.0.0" + +jest-runtime@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" + integrity sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw== + dependencies: + "@jest/console" "^24.7.1" + "@jest/environment" "^24.9.0" + "@jest/source-map" "^24.3.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/yargs" "^13.0.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.1.15" + jest-config "^24.9.0" + jest-haste-map "^24.9.0" + jest-message-util "^24.9.0" + jest-mock "^24.9.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + realpath-native "^1.1.0" + slash "^2.0.0" + strip-bom "^3.0.0" + yargs "^13.3.0" + +jest-serializer@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" + integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== + +jest-snapshot@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" + integrity sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew== + dependencies: + "@babel/types" "^7.0.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + expect "^24.9.0" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-resolve "^24.9.0" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^24.9.0" + semver "^6.2.0" + +jest-util@^24.0.0, jest-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162" + integrity sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg== + dependencies: + "@jest/console" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/source-map" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + callsites "^3.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.15" + is-ci "^2.0.0" + mkdirp "^0.5.1" + slash "^2.0.0" + source-map "^0.6.0" + +jest-validate@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" + integrity sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ== + dependencies: + "@jest/types" "^24.9.0" + camelcase "^5.3.1" + chalk "^2.0.1" + jest-get-type "^24.9.0" + leven "^3.1.0" + pretty-format "^24.9.0" + +jest-watch-typeahead@0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-0.4.2.tgz#e5be959698a7fa2302229a5082c488c3c8780a4a" + integrity sha512-f7VpLebTdaXs81rg/oj4Vg/ObZy2QtGzAmGLNsqUS5G5KtSN68tFcIsbvNODfNyQxU78g7D8x77o3bgfBTR+2Q== + dependencies: + ansi-escapes "^4.2.1" + chalk "^2.4.1" + jest-regex-util "^24.9.0" + jest-watcher "^24.3.0" + slash "^3.0.0" + string-length "^3.1.0" + strip-ansi "^5.0.0" + +jest-watcher@^24.3.0, jest-watcher@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.9.0.tgz#4b56e5d1ceff005f5b88e528dc9afc8dd4ed2b3b" + integrity sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw== + dependencies: + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/yargs" "^13.0.0" + ansi-escapes "^3.0.0" + chalk "^2.0.1" + jest-util "^24.9.0" + string-length "^2.0.0" + +jest-worker@^24.6.0, jest-worker@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" + integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== + dependencies: + merge-stream "^2.0.0" + supports-color "^6.1.0" + +jest-worker@^25.1.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.2.0.tgz#2716fbf74fcae7d713778f60187fd1f96fa09d1a" + integrity sha512-oGzUBnVnRdb51Aru3XFNa0zOafAIEerqZoQow+Vy8LDDiy12dvSrOeVeO8oNrxCMkGG4JtXqX9IPC93JJiAk+g== + dependencies: + merge-stream "^2.0.0" + supports-color "^7.0.0" + +jest@24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" + integrity sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw== + dependencies: + import-local "^2.0.0" + jest-cli "^24.9.0" + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +js-yaml@^3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsdom@^11.5.1: + version "11.12.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" + integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== + dependencies: + abab "^2.0.0" + acorn "^5.5.3" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle "^1.0.0" + data-urls "^1.0.0" + domexception "^1.0.1" + escodegen "^1.9.1" + html-encoding-sniffer "^1.0.2" + left-pad "^1.3.0" + nwsapi "^2.0.7" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.87.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.4" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^5.2.0" + xml-name-validator "^3.0.0" + +jsdom@^14.1.0: + version "14.1.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-14.1.0.tgz#916463b6094956b0a6c1782c94e380cd30e1981b" + integrity sha512-O901mfJSuTdwU2w3Sn+74T+RnDVP+FuV5fH8tcPWyqrseRAb0s5xOtPgCFiPOtLcyK7CLIJwPyD83ZqQWvA5ng== + dependencies: + abab "^2.0.0" + acorn "^6.0.4" + acorn-globals "^4.3.0" + array-equal "^1.0.0" + cssom "^0.3.4" + cssstyle "^1.1.1" + data-urls "^1.1.0" + domexception "^1.0.1" + escodegen "^1.11.0" + html-encoding-sniffer "^1.0.2" + nwsapi "^2.1.3" + parse5 "5.1.0" + pn "^1.1.0" + request "^2.88.0" + request-promise-native "^1.0.5" + saxes "^3.1.9" + symbol-tree "^3.2.2" + tough-cookie "^2.5.0" + w3c-hr-time "^1.0.1" + w3c-xmlserializer "^1.1.2" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^7.0.0" + ws "^6.1.2" + xml-name-validator "^3.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json3@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" + integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.0, json5@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.2.tgz#43ef1f0af9835dd624751a6b7fa48874fb2d608e" + integrity sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ== + dependencies: + minimist "^1.2.5" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +jsx-ast-utils@^2.2.1, jsx-ast-utils@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz#8a9364e402448a3ce7f14d357738310d9248054f" + integrity sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA== + dependencies: + array-includes "^3.0.3" + object.assign "^4.1.0" + +killable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" + integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== + +kind-of@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5" + integrity sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU= + dependencies: + is-buffer "^1.0.2" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +last-call-webpack-plugin@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555" + integrity sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w== + dependencies: + lodash "^4.17.5" + webpack-sources "^1.1.0" + +lazy-cache@^0.2.3: + version "0.2.7" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65" + integrity sha1-f+3fLctu23fRHvHRF6tf/fCrG2U= + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +left-pad@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levenary@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" + integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== + dependencies: + leven "^3.1.0" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +loader-fs-cache@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz#f08657646d607078be2f0a032f8bd69dd6f277d9" + integrity sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA== + dependencies: + find-cache-dir "^0.1.1" + mkdirp "^0.5.1" + +loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== + dependencies: + big.js "^5.2.2" + emojis-list "^2.0.0" + json5 "^1.0.1" + +loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash.template@^4.4.0, lodash.template@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" + integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" + integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== + dependencies: + lodash._reinterpolate "^3.0.0" + +lodash.toarray@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" + integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE= + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +"lodash@>=3.5 <5", lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.5: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +loglevel@^1.6.6: + version "1.6.7" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.7.tgz#b3e034233188c68b889f5b862415306f565e2c56" + integrity sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A== + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lower-case@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.1.tgz#39eeb36e396115cc05e29422eaea9e692c9408c7" + integrity sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ== + dependencies: + tslib "^1.10.0" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +make-dir@^2.0.0, make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392" + integrity sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w== + dependencies: + semver "^6.0.0" + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= + dependencies: + tmpl "1.0.x" + +mamacro@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" + integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +mdn-data@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" + integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== + +mdn-data@2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978" + integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + +memory-fs@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +merge-deep@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/merge-deep/-/merge-deep-3.0.2.tgz#f39fa100a4f1bd34ff29f7d2bf4508fbb8d83ad2" + integrity sha512-T7qC8kg4Zoti1cFd8Cr0M+qaZfOwjlPDEdZIIPPB2JZctjaPM4fX+i7HOId69tAti2fvO6X5ldfYUONDODsrkA== + dependencies: + arr-union "^3.1.0" + clone-deep "^0.2.4" + kind-of "^3.0.2" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.2.3, merge2@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" + integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +microevent.ts@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" + integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g== + +micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.43.0, "mime-db@>= 1.43.0 < 2": + version "1.43.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" + integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.26" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" + integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== + dependencies: + mime-db "1.43.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" + integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== + +mimic-fn@^2.0.0, mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +min-indent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.0.tgz#cfc45c37e9ec0d8f0a0ec3dd4ef7f7c3abe39256" + integrity sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY= + +mini-create-react-context@^0.3.0: + version "0.3.2" + resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.3.2.tgz#79fc598f283dd623da8e088b05db8cddab250189" + integrity sha512-2v+OeetEyliMt5VHMXsBhABoJ0/M4RCe7fatd/fBy6SMiKazUSEt3gxxypfnk2SHMkdBYvorHRoQxuGoiwbzAw== + dependencies: + "@babel/runtime" "^7.4.0" + gud "^1.0.0" + tiny-warning "^1.0.2" + +mini-css-extract-plugin@0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz#47f2cf07aa165ab35733b1fc97d4c46c0564339e" + integrity sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A== + dependencies: + loader-utils "^1.1.0" + normalize-url "1.9.1" + schema-utils "^1.0.0" + webpack-sources "^1.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@3.0.4, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz#3dcb6bb4a546e32969c7ad710f2c79a86abba93a" + integrity sha512-3JS5A2DKhD2g0Gg8x3yamO0pj7YeKGwVlDS90pF++kxptwx/F+B//roxf9SqYil5tQo65bijy+dAuAFZmYOouA== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5" + integrity sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w== + dependencies: + yallist "^4.0.0" + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mixin-object@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mixin-object/-/mixin-object-2.0.1.tgz#4fb949441dab182540f1fe035ba60e1947a5e57e" + integrity sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4= + dependencies: + for-in "^0.1.3" + is-extendable "^0.1.1" + +mkdirp@^0.5.1, mkdirp@~0.5.1: + version "0.5.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.4.tgz#fd01504a6797ec5c9be81ff43d204961ed64a512" + integrity sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw== + dependencies: + minimist "^1.2.5" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +nan@^2.12.1: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.5.0, neo-async@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +no-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.3.tgz#c21b434c1ffe48b39087e86cfb4d2582e9df18f8" + integrity sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw== + dependencies: + lower-case "^2.0.1" + tslib "^1.10.0" + +node-emoji@^1.8.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" + integrity sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw== + dependencies: + lodash.toarray "^4.4.0" + +node-forge@0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" + integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ== + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + +node-modules-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" + integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= + +node-notifier@^5.4.2: + version "5.4.3" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" + integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== + dependencies: + growly "^1.3.0" + is-wsl "^1.1.0" + semver "^5.5.0" + shellwords "^0.1.1" + which "^1.3.0" + +node-releases@^1.1.52: + version "1.1.52" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.52.tgz#bcffee3e0a758e92e44ecfaecd0a47554b0bcba9" + integrity sha512-snSiT1UypkgGt2wxPqS6ImEUICbNCMb31yaxWrOLXjhlt2z2/IBpaOxzONExqSm4y5oLnAqjjRWu+wsDzK5yNQ== + dependencies: + semver "^6.3.0" + +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +normalize-url@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" + integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= + dependencies: + object-assign "^4.0.1" + prepend-http "^1.0.0" + query-string "^4.1.0" + sort-keys "^1.0.0" + +normalize-url@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" + integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== + +normalize.css@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-8.0.1.tgz#9b98a208738b9cc2634caacbc42d131c97487bf3" + integrity sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg== + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +nth-check@^1.0.2, nth-check@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +nwsapi@^2.0.7, nwsapi@^2.1.3: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-hash@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.3.tgz#d12db044e03cd2ca3d77c0570d87225b02e1e6ea" + integrity sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg== + +object-inspect@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + +object-is@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4" + integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-path@0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949" + integrity sha1-NwrnUvvzfePqcKhhwju6iRVpGUk= + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.entries@^1.1.0, object.entries@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.1.tgz#ee1cf04153de02bb093fec33683900f57ce5399b" + integrity sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + has "^1.0.3" + +object.fromentries@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.2.tgz#4a09c9b9bb3843dd0f89acdb517a794d4f355ac9" + integrity sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + has "^1.0.3" + +object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" + integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +object.values@^1.1.0, object.values@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" + integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + has "^1.0.3" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" + integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== + dependencies: + mimic-fn "^2.1.0" + +open@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/open/-/open-7.0.3.tgz#db551a1af9c7ab4c7af664139930826138531c48" + integrity sha512-sP2ru2v0P290WFfv49Ap8MF6PkzGNnGlAwHweB4WR4mr5d2d0woiCluUeJ218w7/+PmoBy9JmYgD5A4mLcWOFA== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + +opn@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== + dependencies: + is-wsl "^1.1.0" + +optimize-css-assets-webpack-plugin@5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz#e2f1d4d94ad8c0af8967ebd7cf138dcb1ef14572" + integrity sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA== + dependencies: + cssnano "^4.1.10" + last-call-webpack-plugin "^3.0.0" + +optionator@^0.8.1, optionator@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +original@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== + dependencies: + url-parse "^1.4.3" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-locale@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-each-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" + integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= + dependencies: + p-reduce "^1.0.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" + integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-map@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" + integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== + dependencies: + aggregate-error "^3.0.0" + +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= + +p-retry@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" + integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w== + dependencies: + retry "^0.12.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + +param-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.3.tgz#4be41f8399eff621c56eebb829a5e451d9801238" + integrity sha512-VWBVyimc1+QrzappRs7waeN2YmoZFCGXWASRYX1/rGHtXqEcrGEIDm+jqIwFa2fRXNgQEwrxaYuIrX0WcAguTA== + dependencies: + dot-case "^3.0.3" + tslib "^1.10.0" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-asn1@^5.0.0: + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-json@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f" + integrity sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + lines-and-columns "^1.1.6" + +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== + +parse5@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" + integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascal-case@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.1.tgz#5ac1975133ed619281e88920973d2cd1f279de5f" + integrity sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA== + dependencies: + no-case "^3.0.3" + tslib "^1.10.0" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-to-regexp@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.0.7, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pirates@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" + integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== + dependencies: + node-modules-regexp "^1.0.0" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= + dependencies: + find-up "^1.0.0" + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pkg-up@3.1.0, pkg-up@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== + dependencies: + find-up "^3.0.0" + +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== + +pnp-webpack-plugin@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.0.tgz#d5c068013a2fdc82224ca50ed179c8fba9036a8e" + integrity sha512-ZcMGn/xF/fCOq+9kWMP9vVVxjIkMCja72oy3lziR7UHy0hHFZ57iVpQ71OtveVbmzeCmphBg8pxNdk/hlK99aQ== + dependencies: + ts-pnp "^1.1.2" + +portfinder@^1.0.25: + version "1.0.25" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.25.tgz#254fd337ffba869f4b9d37edc298059cb4d35eca" + integrity sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.1" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-attribute-case-insensitive@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz#d93e46b504589e94ac7277b0463226c68041a880" + integrity sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^6.0.2" + +postcss-browser-comments@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-browser-comments/-/postcss-browser-comments-3.0.0.tgz#1248d2d935fb72053c8e1f61a84a57292d9f65e9" + integrity sha512-qfVjLfq7HFd2e0HW4s1dvU8X080OZdG46fFbIBFjW7US7YPDcWfRvdElvwMJr2LI6hMmD+7LnH2HcmXTs+uOig== + dependencies: + postcss "^7" + +postcss-calc@^7.0.1: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.2.tgz#504efcd008ca0273120568b0792b16cdcde8aac1" + integrity sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ== + dependencies: + postcss "^7.0.27" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.2" + +postcss-cli@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/postcss-cli/-/postcss-cli-7.1.0.tgz#769b07b8865aaa3e98c7c63a3d256b4f51e3e237" + integrity sha512-tCGK0GO2reu644dUHxks8U2SAtKnzftQTAXN1dwzFPoKXZr0b7VX4vTkQ2Pl2Lunas6+o8uHR56hlcYBm1srZg== + dependencies: + chalk "^3.0.0" + chokidar "^3.3.0" + dependency-graph "^0.8.0" + fs-extra "^8.1.0" + get-stdin "^7.0.0" + globby "^10.0.1" + postcss "^7.0.0" + postcss-load-config "^2.0.0" + postcss-reporter "^6.0.0" + pretty-hrtime "^1.0.3" + read-cache "^1.0.0" + yargs "^15.0.2" + +postcss-color-functional-notation@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz#5efd37a88fbabeb00a2966d1e53d98ced93f74e0" + integrity sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-gray@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz#532a31eb909f8da898ceffe296fdc1f864be8547" + integrity sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-color-hex-alpha@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz#a8d9ca4c39d497c9661e374b9c51899ef0f87388" + integrity sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw== + dependencies: + postcss "^7.0.14" + postcss-values-parser "^2.0.1" + +postcss-color-mod-function@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz#816ba145ac11cc3cb6baa905a75a49f903e4d31d" + integrity sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-rebeccapurple@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz#c7a89be872bb74e45b1e3022bfe5748823e6de77" + integrity sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-colormin@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" + integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw== + dependencies: + browserslist "^4.0.0" + color "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-convert-values@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" + integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-custom-media@^7.0.8: + version "7.0.8" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz#fffd13ffeffad73621be5f387076a28b00294e0c" + integrity sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg== + dependencies: + postcss "^7.0.14" + +postcss-custom-properties@^8.0.11: + version "8.0.11" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz#2d61772d6e92f22f5e0d52602df8fae46fa30d97" + integrity sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA== + dependencies: + postcss "^7.0.17" + postcss-values-parser "^2.0.1" + +postcss-custom-selectors@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz#64858c6eb2ecff2fb41d0b28c9dd7b3db4de7fba" + integrity sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-dir-pseudo-class@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz#6e3a4177d0edb3abcc85fdb6fbb1c26dabaeaba2" + integrity sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-discard-comments@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" + integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg== + dependencies: + postcss "^7.0.0" + +postcss-discard-duplicates@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" + integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ== + dependencies: + postcss "^7.0.0" + +postcss-discard-empty@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" + integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w== + dependencies: + postcss "^7.0.0" + +postcss-discard-overridden@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" + integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg== + dependencies: + postcss "^7.0.0" + +postcss-double-position-gradients@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz#fc927d52fddc896cb3a2812ebc5df147e110522e" + integrity sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA== + dependencies: + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-env-function@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-2.0.2.tgz#0f3e3d3c57f094a92c2baf4b6241f0b0da5365d7" + integrity sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-flexbugs-fixes@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.1.0.tgz#e094a9df1783e2200b7b19f875dcad3b3aff8b20" + integrity sha512-jr1LHxQvStNNAHlgco6PzY308zvLklh7SJVYuWUwyUQncofaAlD2l+P/gxKHOdqWKe7xJSkVLFF/2Tp+JqMSZA== + dependencies: + postcss "^7.0.0" + +postcss-focus-visible@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz#477d107113ade6024b14128317ade2bd1e17046e" + integrity sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g== + dependencies: + postcss "^7.0.2" + +postcss-focus-within@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz#763b8788596cee9b874c999201cdde80659ef680" + integrity sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w== + dependencies: + postcss "^7.0.2" + +postcss-font-variant@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.0.tgz#71dd3c6c10a0d846c5eda07803439617bbbabacc" + integrity sha512-M8BFYKOvCrI2aITzDad7kWuXXTm0YhGdP9Q8HanmN4EF1Hmcgs1KK5rSHylt/lUJe8yLxiSwWAHdScoEiIxztg== + dependencies: + postcss "^7.0.2" + +postcss-functions@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-functions/-/postcss-functions-3.0.0.tgz#0e94d01444700a481de20de4d55fb2640564250e" + integrity sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4= + dependencies: + glob "^7.1.2" + object-assign "^4.1.1" + postcss "^6.0.9" + postcss-value-parser "^3.3.0" + +postcss-gap-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz#431c192ab3ed96a3c3d09f2ff615960f902c1715" + integrity sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg== + dependencies: + postcss "^7.0.2" + +postcss-image-set-function@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz#28920a2f29945bed4c3198d7df6496d410d3f288" + integrity sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-initial@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.2.tgz#f018563694b3c16ae8eaabe3c585ac6319637b2d" + integrity sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA== + dependencies: + lodash.template "^4.5.0" + postcss "^7.0.2" + +postcss-js@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-2.0.3.tgz#a96f0f23ff3d08cec7dc5b11bf11c5f8077cdab9" + integrity sha512-zS59pAk3deu6dVHyrGqmC3oDXBdNdajk4k1RyxeVXCrcEDBUBHoIhE4QTsmhxgzXxsaqFDAkUZfmMa5f/N/79w== + dependencies: + camelcase-css "^2.0.1" + postcss "^7.0.18" + +postcss-lab-function@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz#bb51a6856cd12289ab4ae20db1e3821ef13d7d2e" + integrity sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-load-config@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.0.tgz#c84d692b7bb7b41ddced94ee62e8ab31b417b003" + integrity sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q== + dependencies: + cosmiconfig "^5.0.0" + import-cwd "^2.0.0" + +postcss-loader@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" + integrity sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA== + dependencies: + loader-utils "^1.1.0" + postcss "^7.0.0" + postcss-load-config "^2.0.0" + schema-utils "^1.0.0" + +postcss-logical@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-3.0.0.tgz#2495d0f8b82e9f262725f75f9401b34e7b45d5b5" + integrity sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA== + dependencies: + postcss "^7.0.2" + +postcss-media-minmax@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz#b75bb6cbc217c8ac49433e12f22048814a4f5ed5" + integrity sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw== + dependencies: + postcss "^7.0.2" + +postcss-merge-longhand@^4.0.11: + version "4.0.11" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" + integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw== + dependencies: + css-color-names "0.0.4" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + stylehacks "^4.0.0" + +postcss-merge-rules@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" + integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + cssnano-util-same-parent "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + vendors "^1.0.0" + +postcss-minify-font-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" + integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-gradients@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" + integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + is-color-stop "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-params@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" + integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg== + dependencies: + alphanum-sort "^1.0.0" + browserslist "^4.0.0" + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + uniqs "^2.0.0" + +postcss-minify-selectors@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" + integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g== + dependencies: + alphanum-sort "^1.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== + dependencies: + postcss "^7.0.5" + +postcss-modules-local-by-default@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz#e8a6561be914aaf3c052876377524ca90dbb7915" + integrity sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ== + dependencies: + icss-utils "^4.1.1" + postcss "^7.0.16" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.0" + +postcss-modules-scope@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + +postcss-modules-values@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" + integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== + dependencies: + icss-utils "^4.0.0" + postcss "^7.0.6" + +postcss-nested@^4.1.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-4.2.1.tgz#4bc2e5b35e3b1e481ff81e23b700da7f82a8b248" + integrity sha512-AMayXX8tS0HCp4O4lolp4ygj9wBn32DJWXvG6gCv+ZvJrEa00GUxJcJEEzMh87BIe6FrWdYkpR2cuyqHKrxmXw== + dependencies: + postcss "^7.0.21" + postcss-selector-parser "^6.0.2" + +postcss-nesting@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-7.0.1.tgz#b50ad7b7f0173e5b5e3880c3501344703e04c052" + integrity sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg== + dependencies: + postcss "^7.0.2" + +postcss-normalize-charset@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" + integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g== + dependencies: + postcss "^7.0.0" + +postcss-normalize-display-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" + integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-positions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" + integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA== + dependencies: + cssnano-util-get-arguments "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-repeat-style@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" + integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-string@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" + integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA== + dependencies: + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-timing-functions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" + integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-unicode@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" + integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-url@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" + integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA== + dependencies: + is-absolute-url "^2.0.0" + normalize-url "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-whitespace@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" + integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize/-/postcss-normalize-8.0.1.tgz#90e80a7763d7fdf2da6f2f0f82be832ce4f66776" + integrity sha512-rt9JMS/m9FHIRroDDBGSMsyW1c0fkvOJPy62ggxSHUldJO7B195TqFMqIf+lY5ezpDcYOV4j86aUp3/XbxzCCQ== + dependencies: + "@csstools/normalize.css" "^10.1.0" + browserslist "^4.6.2" + postcss "^7.0.17" + postcss-browser-comments "^3.0.0" + sanitize.css "^10.0.0" + +postcss-ordered-values@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" + integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw== + dependencies: + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-overflow-shorthand@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz#31ecf350e9c6f6ddc250a78f0c3e111f32dd4c30" + integrity sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g== + dependencies: + postcss "^7.0.2" + +postcss-page-break@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-2.0.0.tgz#add52d0e0a528cabe6afee8b46e2abb277df46bf" + integrity sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ== + dependencies: + postcss "^7.0.2" + +postcss-place@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-4.0.1.tgz#e9f39d33d2dc584e46ee1db45adb77ca9d1dcc62" + integrity sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-preset-env@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz#c34ddacf8f902383b35ad1e030f178f4cdf118a5" + integrity sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg== + dependencies: + autoprefixer "^9.6.1" + browserslist "^4.6.4" + caniuse-lite "^1.0.30000981" + css-blank-pseudo "^0.1.4" + css-has-pseudo "^0.10.0" + css-prefers-color-scheme "^3.1.1" + cssdb "^4.4.0" + postcss "^7.0.17" + postcss-attribute-case-insensitive "^4.0.1" + postcss-color-functional-notation "^2.0.1" + postcss-color-gray "^5.0.0" + postcss-color-hex-alpha "^5.0.3" + postcss-color-mod-function "^3.0.3" + postcss-color-rebeccapurple "^4.0.1" + postcss-custom-media "^7.0.8" + postcss-custom-properties "^8.0.11" + postcss-custom-selectors "^5.1.2" + postcss-dir-pseudo-class "^5.0.0" + postcss-double-position-gradients "^1.0.0" + postcss-env-function "^2.0.2" + postcss-focus-visible "^4.0.0" + postcss-focus-within "^3.0.0" + postcss-font-variant "^4.0.0" + postcss-gap-properties "^2.0.0" + postcss-image-set-function "^3.0.1" + postcss-initial "^3.0.0" + postcss-lab-function "^2.0.1" + postcss-logical "^3.0.0" + postcss-media-minmax "^4.0.0" + postcss-nesting "^7.0.0" + postcss-overflow-shorthand "^2.0.0" + postcss-page-break "^2.0.0" + postcss-place "^4.0.1" + postcss-pseudo-class-any-link "^6.0.0" + postcss-replace-overflow-wrap "^3.0.0" + postcss-selector-matches "^4.0.0" + postcss-selector-not "^4.0.0" + +postcss-pseudo-class-any-link@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz#2ed3eed393b3702879dec4a87032b210daeb04d1" + integrity sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-reduce-initial@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" + integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + +postcss-reduce-transforms@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" + integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg== + dependencies: + cssnano-util-get-match "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-replace-overflow-wrap@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz#61b360ffdaedca84c7c918d2b0f0d0ea559ab01c" + integrity sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw== + dependencies: + postcss "^7.0.2" + +postcss-reporter@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-6.0.1.tgz#7c055120060a97c8837b4e48215661aafb74245f" + integrity sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw== + dependencies: + chalk "^2.4.1" + lodash "^4.17.11" + log-symbols "^2.2.0" + postcss "^7.0.7" + +postcss-safe-parser@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-4.0.1.tgz#8756d9e4c36fdce2c72b091bbc8ca176ab1fcdea" + integrity sha512-xZsFA3uX8MO3yAda03QrG3/Eg1LN3EPfjjf07vke/46HERLZyHrTsQ9E1r1w1W//fWEhtYNndo2hQplN2cVpCQ== + dependencies: + postcss "^7.0.0" + +postcss-selector-matches@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz#71c8248f917ba2cc93037c9637ee09c64436fcff" + integrity sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + +postcss-selector-not@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.0.tgz#c68ff7ba96527499e832724a2674d65603b645c0" + integrity sha512-W+bkBZRhqJaYN8XAnbbZPLWMvZD1wKTu0UxtFKdhtGjWYmxhkUneoeOhRJKdAE5V7ZTlnbHfCR+6bNwK9e1dTQ== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + +postcss-selector-parser@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz#b310f5c4c0fdaf76f94902bbaa30db6aa84f5270" + integrity sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA== + dependencies: + dot-prop "^5.2.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" + integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== + dependencies: + cssesc "^2.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" + integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== + dependencies: + cssesc "^3.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-svgo@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" + integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw== + dependencies: + is-svg "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + svgo "^1.0.0" + +postcss-unique-selectors@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" + integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg== + dependencies: + alphanum-sort "^1.0.0" + postcss "^7.0.0" + uniqs "^2.0.0" + +postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz#651ff4593aa9eda8d5d0d66593a2417aeaeb325d" + integrity sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg== + +postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz#da8b472d901da1e205b47bdc98637b9e9e550e5f" + integrity sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg== + dependencies: + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss@7.0.21: + version "7.0.21" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.21.tgz#06bb07824c19c2021c5d056d5b10c35b989f7e17" + integrity sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +postcss@^6.0.9: + version "6.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" + integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" + +postcss@^7, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.11, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.17, postcss@^7.0.18, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.23, postcss@^7.0.27, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7: + version "7.0.27" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.27.tgz#cc67cdc6b0daa375105b7c424a85567345fc54d9" + integrity sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +pretty-bytes@^5.1.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2" + integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg== + +pretty-error@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" + integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM= + dependencies: + renderkid "^2.0.1" + utila "~0.4" + +pretty-format@^24.0.0, pretty-format@^24.3.0, pretty-format@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" + integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== + dependencies: + "@jest/types" "^24.9.0" + ansi-regex "^4.0.0" + ansi-styles "^3.2.0" + react-is "^16.8.4" + +pretty-format@^25.1.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.2.0.tgz#645003fb5da71a0ded46c90007dff0e03857de7d" + integrity sha512-BzmuH01b/lm0nl3M7Lcnku9Cv2UNMk9FgIrAiSuIus2QrjzV7Lf2DW+88SgEQUXQNkYWGtBV1289AuF6yMCtCQ== + dependencies: + "@jest/types" "^25.2.0" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^16.12.0" + +pretty-hrtime@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= + +private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +promise@^8.0.3: + version "8.1.0" + resolved "https://registry.yarnpkg.com/promise/-/promise-8.1.0.tgz#697c25c3dfe7435dd79fcd58c38a135888eaf05e" + integrity sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q== + dependencies: + asap "~2.0.6" + +prompts@^2.0.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.2.tgz#480572d89ecf39566d2bd3fe2c9fccb7c4c0b068" + integrity sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.4" + +prop-types@^15.6.2, prop-types@^15.7.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +q@^1.1.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +query-string@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" + integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= + dependencies: + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +querystringify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" + integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== + +raf@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" + integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== + dependencies: + performance-now "^2.1.0" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +react-app-polyfill@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-1.0.6.tgz#890f8d7f2842ce6073f030b117de9130a5f385f0" + integrity sha512-OfBnObtnGgLGfweORmdZbyEz+3dgVePQBb3zipiaDsMHV1NpWm0rDFYIVXFV/AK+x4VIIfWHhrdMIeoTLyRr2g== + dependencies: + core-js "^3.5.0" + object-assign "^4.1.1" + promise "^8.0.3" + raf "^3.4.1" + regenerator-runtime "^0.13.3" + whatwg-fetch "^3.0.0" + +react-dev-utils@^10.2.0: + version "10.2.1" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19" + integrity sha512-XxTbgJnYZmxuPtY3y/UV0D8/65NKkmaia4rXzViknVnZeVlklSh8u6TnaEYPfAi/Gh1TP4mEOXHI6jQOPbeakQ== + dependencies: + "@babel/code-frame" "7.8.3" + address "1.1.2" + browserslist "4.10.0" + chalk "2.4.2" + cross-spawn "7.0.1" + detect-port-alt "1.1.6" + escape-string-regexp "2.0.0" + filesize "6.0.1" + find-up "4.1.0" + fork-ts-checker-webpack-plugin "3.1.1" + global-modules "2.0.0" + globby "8.0.2" + gzip-size "5.1.1" + immer "1.10.0" + inquirer "7.0.4" + is-root "2.1.0" + loader-utils "1.2.3" + open "^7.0.2" + pkg-up "3.1.0" + react-error-overlay "^6.0.7" + recursive-readdir "2.2.2" + shell-quote "1.7.2" + strip-ansi "6.0.0" + text-table "0.2.0" + +react-dom@^16.12.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f" + integrity sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.19.1" + +react-error-overlay@^6.0.7: + version "6.0.7" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.7.tgz#1dcfb459ab671d53f660a991513cb2f0a0553108" + integrity sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA== + +react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.9.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-redux@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.0.tgz#f970f62192b3981642fec46fd0db18a074fe879d" + integrity sha512-EvCAZYGfOLqwV7gh849xy9/pt55rJXPwmYvI4lilPM5rUT/1NxuuN59ipdBksRVSvz0KInbPnp4IfoXJXCqiDA== + dependencies: + "@babel/runtime" "^7.5.5" + hoist-non-react-statics "^3.3.0" + loose-envify "^1.4.0" + prop-types "^15.7.2" + react-is "^16.9.0" + +react-router-dom@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.1.2.tgz#06701b834352f44d37fbb6311f870f84c76b9c18" + integrity sha512-7BPHAaIwWpZS074UKaw1FjVdZBSVWEk8IuDXdB+OkLb8vd/WRQIpA4ag9WQk61aEfQs47wHyjWUoUGGZxpQXew== + dependencies: + "@babel/runtime" "^7.1.2" + history "^4.9.0" + loose-envify "^1.3.1" + prop-types "^15.6.2" + react-router "5.1.2" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + +react-router@5.1.2, react-router@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.1.2.tgz#6ea51d789cb36a6be1ba5f7c0d48dd9e817d3418" + integrity sha512-yjEuMFy1ONK246B+rsa0cUam5OeAQ8pyclRDgpxuSCrAlJ1qN9uZ5IgyKC7gQg0w8OM50NXHEegPh/ks9YuR2A== + dependencies: + "@babel/runtime" "^7.1.2" + history "^4.9.0" + hoist-non-react-statics "^3.1.0" + loose-envify "^1.3.1" + mini-create-react-context "^0.3.0" + path-to-regexp "^1.7.0" + prop-types "^15.6.2" + react-is "^16.6.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + +react-scripts@3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-3.4.0.tgz#f413680f0b5b937c8879ba1ffdae9b8c5b364bf5" + integrity sha512-pBqaAroFoHnFAkuX+uSK9Th1uEh2GYdGY2IG1I9/7HmuEf+ls3lLCk1p2GFYRSrLMz6ieQR/SyN6TLIGK3hKRg== + dependencies: + "@babel/core" "7.8.4" + "@svgr/webpack" "4.3.3" + "@typescript-eslint/eslint-plugin" "^2.10.0" + "@typescript-eslint/parser" "^2.10.0" + babel-eslint "10.0.3" + babel-jest "^24.9.0" + babel-loader "8.0.6" + babel-plugin-named-asset-import "^0.3.6" + babel-preset-react-app "^9.1.1" + camelcase "^5.3.1" + case-sensitive-paths-webpack-plugin "2.3.0" + css-loader "3.4.2" + dotenv "8.2.0" + dotenv-expand "5.1.0" + eslint "^6.6.0" + eslint-config-react-app "^5.2.0" + eslint-loader "3.0.3" + eslint-plugin-flowtype "4.6.0" + eslint-plugin-import "2.20.0" + eslint-plugin-jsx-a11y "6.2.3" + eslint-plugin-react "7.18.0" + eslint-plugin-react-hooks "^1.6.1" + file-loader "4.3.0" + fs-extra "^8.1.0" + html-webpack-plugin "4.0.0-beta.11" + identity-obj-proxy "3.0.0" + jest "24.9.0" + jest-environment-jsdom-fourteen "1.0.1" + jest-resolve "24.9.0" + jest-watch-typeahead "0.4.2" + mini-css-extract-plugin "0.9.0" + optimize-css-assets-webpack-plugin "5.0.3" + pnp-webpack-plugin "1.6.0" + postcss-flexbugs-fixes "4.1.0" + postcss-loader "3.0.0" + postcss-normalize "8.0.1" + postcss-preset-env "6.7.0" + postcss-safe-parser "4.0.1" + react-app-polyfill "^1.0.6" + react-dev-utils "^10.2.0" + resolve "1.15.0" + resolve-url-loader "3.1.1" + sass-loader "8.0.2" + semver "6.3.0" + style-loader "0.23.1" + terser-webpack-plugin "2.3.4" + ts-pnp "1.1.5" + url-loader "2.3.0" + webpack "4.41.5" + webpack-dev-server "3.10.2" + webpack-manifest-plugin "2.2.0" + workbox-webpack-plugin "4.3.1" + optionalDependencies: + fsevents "2.1.2" + +react@^16.12.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" + integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha1-5mTvMRYRZsl1HNvo28+GtftY93Q= + dependencies: + pify "^2.3.0" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg-up@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" + integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== + dependencies: + find-up "^3.0.0" + read-pkg "^3.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6, readable-stream@^3.1.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readdirp@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.3.0.tgz#984458d13a1e42e2e9f5841b129e162f369aff17" + integrity sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ== + dependencies: + picomatch "^2.0.7" + +realpath-native@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" + integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA== + dependencies: + util.promisify "^1.0.0" + +recursive-readdir@2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" + integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== + dependencies: + minimatch "3.0.4" + +redent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" + integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== + dependencies: + indent-string "^4.0.0" + strip-indent "^3.0.0" + +reduce-css-calc@^2.1.6: + version "2.1.7" + resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.7.tgz#1ace2e02c286d78abcd01fd92bfe8097ab0602c2" + integrity sha512-fDnlZ+AybAS3C7Q9xDq5y8A2z+lT63zLbynew/lur/IR24OQF5x98tfNwf79mzEdfywZ0a2wpM860FhFfMxZlA== + dependencies: + css-unit-converter "^1.1.1" + postcss-value-parser "^3.3.0" + +redux-thunk@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" + integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== + +redux@^4.0.0: + version "4.0.5" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" + integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== + dependencies: + loose-envify "^1.4.0" + symbol-observable "^1.2.0" + +regenerate-unicode-properties@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4: + version "0.13.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" + integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== + +regenerator-transform@^0.14.2: + version "0.14.4" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.4.tgz#5266857896518d1616a78a0479337a30ea974cc7" + integrity sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw== + dependencies: + "@babel/runtime" "^7.8.4" + private "^0.1.8" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regex-parser@2.2.10: + version "2.2.10" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.10.tgz#9e66a8f73d89a107616e63b39d4deddfee912b37" + integrity sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA== + +regexp.prototype.flags@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" + integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +regexpp@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.0.0.tgz#dd63982ee3300e67b41c1956f850aa680d9d330e" + integrity sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g== + +regexpu-core@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" + integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.2.0" + regjsgen "^0.5.1" + regjsparser "^0.6.4" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.2.0" + +regjsgen@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c" + integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg== + +regjsparser@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" + integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== + dependencies: + jsesc "~0.5.0" + +relateurl@^0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +renderkid@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.3.tgz#380179c2ff5ae1365c522bf2fcfcff01c5b74149" + integrity sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA== + dependencies: + css-select "^1.1.0" + dom-converter "^0.2" + htmlparser2 "^3.3.0" + strip-ansi "^3.0.0" + utila "^0.4.0" + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +request-promise-core@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" + integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ== + dependencies: + lodash "^4.17.15" + +request-promise-native@^1.0.5: + version "1.0.8" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" + integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ== + dependencies: + request-promise-core "1.1.3" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + +request@^2.87.0, request@^2.88.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +reselect@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7" + integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA== + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-pathname@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" + integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== + +resolve-url-loader@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.1.tgz#28931895fa1eab9be0647d3b2958c100ae3c0bf0" + integrity sha512-K1N5xUjj7v0l2j/3Sgs5b8CjrrgtC70SmdCuZiJ8tSyb5J+uk3FoeZ4b7yTnH6j7ngI+Bc5bldHJIa8hYdu2gQ== + dependencies: + adjust-sourcemap-loader "2.0.0" + camelcase "5.3.1" + compose-function "3.0.3" + convert-source-map "1.7.0" + es6-iterator "2.0.3" + loader-utils "1.2.3" + postcss "7.0.21" + rework "1.0.1" + rework-visit "1.0.0" + source-map "0.6.1" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + +resolve@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.0.tgz#1b7ca96073ebb52e741ffd799f6b39ea462c67f5" + integrity sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw== + dependencies: + path-parse "^1.0.6" + +resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.3.2, resolve@^1.8.1: + version "1.15.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" + integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== + dependencies: + path-parse "^1.0.6" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rework-visit@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rework-visit/-/rework-visit-1.0.0.tgz#9945b2803f219e2f7aca00adb8bc9f640f842c9a" + integrity sha1-mUWygD8hni96ygCtuLyfZA+ELJo= + +rework@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/rework/-/rework-1.0.1.tgz#30806a841342b54510aa4110850cd48534144aa7" + integrity sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc= + dependencies: + convert-source-map "^0.3.3" + css "^2.0.0" + +rgb-regex@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" + integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= + +rgba-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" + integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= + +rimraf@2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +rimraf@^2.5.4, rimraf@^2.6.3, rimraf@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +rsvp@^4.8.4: + version "4.8.5" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" + integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== + +run-async@^2.2.0, run-async@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.0.tgz#e59054a5b86876cfae07f431d18cbaddc594f1e8" + integrity sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg== + dependencies: + is-promise "^2.1.0" + +run-parallel@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" + integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +rxjs@^6.5.3: + version "6.5.4" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" + integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sane@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" + integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== + dependencies: + "@cnakazawa/watch" "^1.0.3" + anymatch "^2.0.0" + capture-exit "^2.0.0" + exec-sh "^0.3.2" + execa "^1.0.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + +sanitize.css@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/sanitize.css/-/sanitize.css-10.0.0.tgz#b5cb2547e96d8629a60947544665243b1dc3657a" + integrity sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg== + +sass-loader@8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-8.0.2.tgz#debecd8c3ce243c76454f2e8290482150380090d" + integrity sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ== + dependencies: + clone-deep "^4.0.1" + loader-utils "^1.2.3" + neo-async "^2.6.1" + schema-utils "^2.6.1" + semver "^6.3.0" + +sax@^1.2.4, sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +saxes@^3.1.9: + version "3.1.11" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b" + integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g== + dependencies: + xmlchars "^2.1.1" + +scheduler@^0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196" + integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.1, schema-utils@^2.6.4: + version "2.6.5" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.5.tgz#c758f0a7e624263073d396e29cd40aa101152d8a" + integrity sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ== + dependencies: + ajv "^6.12.0" + ajv-keywords "^3.4.1" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +selfsigned@^1.10.7: + version "1.10.7" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.7.tgz#da5819fd049d5574f28e88a9bcc6dbc6e6f3906b" + integrity sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA== + dependencies: + node-forge "0.9.0" + +"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@6.3.0, semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + 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.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-javascript@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" + integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shallow-clone@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-0.1.2.tgz#5909e874ba77106d73ac414cfec1ffca87d97060" + integrity sha1-WQnodLp3EG1zrEFM/sH/yofZcGA= + dependencies: + is-extendable "^0.1.1" + kind-of "^2.0.1" + lazy-cache "^0.2.3" + mixin-object "^2.0.1" + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shell-quote@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" + integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== + +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + +sisteransi@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sockjs-client@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5" + integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g== + dependencies: + debug "^3.2.5" + eventsource "^1.0.7" + faye-websocket "~0.11.1" + inherits "^2.0.3" + json3 "^3.3.2" + url-parse "^1.4.3" + +sockjs@0.3.19: + version "0.3.19" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d" + integrity sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw== + dependencies: + faye-websocket "^0.10.0" + uuid "^3.0.1" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= + dependencies: + is-plain-obj "^1.0.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.5.6, source-map-support@~0.5.12: + version "0.5.16" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" + integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" + integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.1.tgz#6f12ed1c5db7ea4f24ebb8b89ba58c87c08257f2" + integrity sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +ssri@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-7.1.0.tgz#92c241bf6de82365b5c7fb4bd76e975522e1294d" + integrity sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g== + dependencies: + figgy-pudding "^3.5.1" + minipass "^3.1.1" + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +stack-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" + integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +stealthy-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + +string-length@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" + integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= + dependencies: + astral-regex "^1.0.0" + strip-ansi "^4.0.0" + +string-length@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837" + integrity sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA== + dependencies: + astral-regex "^1.0.0" + strip-ansi "^5.2.0" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^2.0.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.trimleft@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" + integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string.prototype.trimright@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" + integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +stringify-object@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +strip-ansi@6.0.0, strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-comments@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-1.0.2.tgz#82b9c45e7f05873bee53f37168af930aa368679d" + integrity sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw== + dependencies: + babel-extract-comments "^1.0.0" + babel-plugin-transform-object-rest-spread "^6.26.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-indent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" + integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== + dependencies: + min-indent "^1.0.0" + +strip-json-comments@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" + integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== + +style-loader@0.23.1: + version "0.23.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.1.tgz#cb9154606f3e771ab6c4ab637026a1049174d925" + integrity sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg== + dependencies: + loader-utils "^1.1.0" + schema-utils "^1.0.0" + +stylehacks@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" + integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^5.3.0, supports-color@^5.4.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + +svg-parser@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" + integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== + +svgo@^1.0.0, svgo@^1.2.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" + integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== + dependencies: + chalk "^2.4.1" + coa "^2.0.2" + css-select "^2.0.0" + css-select-base-adapter "^0.1.1" + css-tree "1.0.0-alpha.37" + csso "^4.0.2" + js-yaml "^3.13.1" + mkdirp "~0.5.1" + object.values "^1.1.0" + sax "~1.2.4" + stable "^0.1.8" + unquote "~1.1.1" + util.promisify "~1.0.0" + +symbol-observable@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + +symbol-tree@^3.2.2: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +tailwindcss@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-1.2.0.tgz#5df317cebac4f3131f275d258a39da1ba3a0f291" + integrity sha512-CKvY0ytB3ze5qvynG7qv4XSpQtFNGPbu9pUn8qFdkqgD8Yo/vGss8mhzbqls44YCXTl4G62p3qVZBj45qrd6FQ== + dependencies: + autoprefixer "^9.4.5" + bytes "^3.0.0" + chalk "^3.0.0" + detective "^5.2.0" + fs-extra "^8.0.0" + lodash "^4.17.15" + node-emoji "^1.8.1" + normalize.css "^8.0.1" + postcss "^7.0.11" + postcss-functions "^3.0.0" + postcss-js "^2.0.0" + postcss-nested "^4.1.1" + postcss-selector-parser "^6.0.0" + pretty-hrtime "^1.0.3" + reduce-css-calc "^2.1.6" + resolve "^1.14.2" + +tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +terser-webpack-plugin@2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.3.4.tgz#ac045703bd8da0936ce910d8fb6350d0e1dee5fe" + integrity sha512-Nv96Nws2R2nrFOpbzF6IxRDpIkkIfmhvOws+IqMvYdFLO7o6wAILWFKONFgaYy8+T4LVz77DQW0f7wOeDEAjrg== + dependencies: + cacache "^13.0.1" + find-cache-dir "^3.2.0" + jest-worker "^25.1.0" + p-limit "^2.2.2" + schema-utils "^2.6.4" + serialize-javascript "^2.1.2" + source-map "^0.6.1" + terser "^4.4.3" + webpack-sources "^1.4.3" + +terser-webpack-plugin@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" + integrity sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^2.1.2" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser@^4.1.2, terser@^4.4.3, terser@^4.6.3: + version "4.6.7" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.7.tgz#478d7f9394ec1907f0e488c5f6a6a9a2bad55e72" + integrity sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +test-exclude@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0" + integrity sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g== + dependencies: + glob "^7.1.3" + minimatch "^3.0.4" + read-pkg-up "^4.0.0" + require-main-filename "^2.0.0" + +text-table@0.2.0, text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +throat@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +timers-browserify@^2.0.4: + version "2.0.11" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" + integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== + dependencies: + setimmediate "^1.0.4" + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= + +tiny-invariant@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" + integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== + +tiny-warning@^1.0.0, tiny-warning@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.5.0, tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + +ts-pnp@1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.5.tgz#840e0739c89fce5f3abd9037bb091dbff16d9dec" + integrity sha512-ti7OGMOUOzo66wLF3liskw6YQIaSsBgc4GOAlWRnIEj8htCxJUxskanMUoJOD6MDCRAXo36goXJZch+nOS0VMA== + +ts-pnp@^1.1.2: + version "1.1.6" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.6.tgz#389a24396d425a0d3162e96d2b4638900fdc289a" + integrity sha512-CrG5GqAAzMT7144Cl+UIFP7mz/iIhiy+xQ6GGcnjTezhALT02uPMRw7tgDSESgB5MsfKt55+GPWw4ir1kVtMIQ== + +tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0: + version "1.11.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" + integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== + +tsutils@^3.17.1: + version "3.17.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" + integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== + dependencies: + tslib "^1.8.1" + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-fest@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" + integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" + integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +typescript@~3.8.2: + version "3.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" + integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== + +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" + integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + +uniqs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-loader@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-2.3.0.tgz#e0e2ef658f003efb8ca41b0f3ffbf76bab88658b" + integrity sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog== + dependencies: + loader-utils "^1.2.3" + mime "^2.4.4" + schema-utils "^2.5.0" + +url-parse@^1.4.3: + version "1.4.7" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" + integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +util.promisify@^1.0.0, util.promisify@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utila@^0.4.0, utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.0.1, uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +v8-compile-cache@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" + integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +value-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" + integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +vendors@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" + integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +w3c-hr-time@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + +w3c-xmlserializer@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz#30485ca7d70a6fd052420a3d12fd90e6339ce794" + integrity sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg== + dependencies: + domexception "^1.0.1" + webidl-conversions "^4.0.2" + xml-name-validator "^3.0.0" + +wait-for-expect@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-3.0.2.tgz#d2f14b2f7b778c9b82144109c8fa89ceaadaa463" + integrity sha512-cfS1+DZxuav1aBYbaO/kE06EOS8yRw7qOFoD3XtjTkYvCvh3zUvNST8DXK/nPaeqIzIv3P3kL3lRJn8iwOiSag== + +walker@^1.0.7, walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + dependencies: + makeerror "1.0.x" + +watchpack@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== + dependencies: + chokidar "^2.0.2" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +webpack-dev-middleware@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" + integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw== + dependencies: + memory-fs "^0.4.1" + mime "^2.4.4" + mkdirp "^0.5.1" + range-parser "^1.2.1" + webpack-log "^2.0.0" + +webpack-dev-server@3.10.2: + version "3.10.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.10.2.tgz#3403287d674c7407aab6d9b3f72259ecd0aa0874" + integrity sha512-pxZKPYb+n77UN8u9YxXT4IaIrGcNtijh/mi8TXbErHmczw0DtPnMTTjHj+eNjkqLOaAZM/qD7V59j/qJsEiaZA== + dependencies: + ansi-html "0.0.7" + bonjour "^3.5.0" + chokidar "^2.1.8" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + debug "^4.1.1" + del "^4.1.1" + express "^4.17.1" + html-entities "^1.2.1" + http-proxy-middleware "0.19.1" + import-local "^2.0.0" + internal-ip "^4.3.0" + ip "^1.1.5" + is-absolute-url "^3.0.3" + killable "^1.0.1" + loglevel "^1.6.6" + opn "^5.5.0" + p-retry "^3.0.1" + portfinder "^1.0.25" + schema-utils "^1.0.0" + selfsigned "^1.10.7" + semver "^6.3.0" + serve-index "^1.9.1" + sockjs "0.3.19" + sockjs-client "1.4.0" + spdy "^4.0.1" + strip-ansi "^3.0.1" + supports-color "^6.1.0" + url "^0.11.0" + webpack-dev-middleware "^3.7.2" + webpack-log "^2.0.0" + ws "^6.2.1" + yargs "12.0.5" + +webpack-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" + integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== + dependencies: + ansi-colors "^3.0.0" + uuid "^3.3.2" + +webpack-manifest-plugin@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/webpack-manifest-plugin/-/webpack-manifest-plugin-2.2.0.tgz#19ca69b435b0baec7e29fbe90fb4015de2de4f16" + integrity sha512-9S6YyKKKh/Oz/eryM1RyLVDVmy3NSPV0JXMRhZ18fJsq+AwGxUY34X54VNwkzYcEmEkDwNxuEOboCZEebJXBAQ== + dependencies: + fs-extra "^7.0.0" + lodash ">=3.5 <5" + object.entries "^1.1.0" + tapable "^1.0.0" + +webpack-merge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" + integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== + dependencies: + lodash "^4.17.15" + +webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@4.41.5: + version "4.41.5" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.5.tgz#3210f1886bce5310e62bb97204d18c263341b77c" + integrity sha512-wp0Co4vpyumnp3KlkmpM5LWuzvZYayDwM2n17EHFr4qxBBbRokC7DJawPJC7TfSFZ9HZ6GsdH40EBj4UV0nmpw== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/wasm-edit" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + acorn "^6.2.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.1" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.3" + watchpack "^1.6.0" + webpack-sources "^1.4.1" + +websocket-driver@>=0.5.1: + version "0.7.3" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9" + integrity sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg== + dependencies: + http-parser-js ">=0.4.0 <0.4.11" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" + integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-fetch@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" + integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== + +whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" + integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@^1.2.9, which@^1.3.0, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +workbox-background-sync@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz#26821b9bf16e9e37fd1d640289edddc08afd1950" + integrity sha512-1uFkvU8JXi7L7fCHVBEEnc3asPpiAL33kO495UMcD5+arew9IbKW2rV5lpzhoWcm/qhGB89YfO4PmB/0hQwPRg== + dependencies: + workbox-core "^4.3.1" + +workbox-broadcast-update@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-4.3.1.tgz#e2c0280b149e3a504983b757606ad041f332c35b" + integrity sha512-MTSfgzIljpKLTBPROo4IpKjESD86pPFlZwlvVG32Kb70hW+aob4Jxpblud8EhNb1/L5m43DUM4q7C+W6eQMMbA== + dependencies: + workbox-core "^4.3.1" + +workbox-build@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-4.3.1.tgz#414f70fb4d6de47f6538608b80ec52412d233e64" + integrity sha512-UHdwrN3FrDvicM3AqJS/J07X0KXj67R8Cg0waq1MKEOqzo89ap6zh6LmaLnRAjpB+bDIz+7OlPye9iii9KBnxw== + dependencies: + "@babel/runtime" "^7.3.4" + "@hapi/joi" "^15.0.0" + common-tags "^1.8.0" + fs-extra "^4.0.2" + glob "^7.1.3" + lodash.template "^4.4.0" + pretty-bytes "^5.1.0" + stringify-object "^3.3.0" + strip-comments "^1.0.2" + workbox-background-sync "^4.3.1" + workbox-broadcast-update "^4.3.1" + workbox-cacheable-response "^4.3.1" + workbox-core "^4.3.1" + workbox-expiration "^4.3.1" + workbox-google-analytics "^4.3.1" + workbox-navigation-preload "^4.3.1" + workbox-precaching "^4.3.1" + workbox-range-requests "^4.3.1" + workbox-routing "^4.3.1" + workbox-strategies "^4.3.1" + workbox-streams "^4.3.1" + workbox-sw "^4.3.1" + workbox-window "^4.3.1" + +workbox-cacheable-response@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-4.3.1.tgz#f53e079179c095a3f19e5313b284975c91428c91" + integrity sha512-Rp5qlzm6z8IOvnQNkCdO9qrDgDpoPNguovs0H8C+wswLuPgSzSp9p2afb5maUt9R1uTIwOXrVQMmPfPypv+npw== + dependencies: + workbox-core "^4.3.1" + +workbox-core@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-4.3.1.tgz#005d2c6a06a171437afd6ca2904a5727ecd73be6" + integrity sha512-I3C9jlLmMKPxAC1t0ExCq+QoAMd0vAAHULEgRZ7kieCdUd919n53WC0AfvokHNwqRhGn+tIIj7vcb5duCjs2Kg== + +workbox-expiration@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-4.3.1.tgz#d790433562029e56837f341d7f553c4a78ebe921" + integrity sha512-vsJLhgQsQouv9m0rpbXubT5jw0jMQdjpkum0uT+d9tTwhXcEZks7qLfQ9dGSaufTD2eimxbUOJfWLbNQpIDMPw== + dependencies: + workbox-core "^4.3.1" + +workbox-google-analytics@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-4.3.1.tgz#9eda0183b103890b5c256e6f4ea15a1f1548519a" + integrity sha512-xzCjAoKuOb55CBSwQrbyWBKqp35yg1vw9ohIlU2wTy06ZrYfJ8rKochb1MSGlnoBfXGWss3UPzxR5QL5guIFdg== + dependencies: + workbox-background-sync "^4.3.1" + workbox-core "^4.3.1" + workbox-routing "^4.3.1" + workbox-strategies "^4.3.1" + +workbox-navigation-preload@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-4.3.1.tgz#29c8e4db5843803b34cd96dc155f9ebd9afa453d" + integrity sha512-K076n3oFHYp16/C+F8CwrRqD25GitA6Rkd6+qAmLmMv1QHPI2jfDwYqrytOfKfYq42bYtW8Pr21ejZX7GvALOw== + dependencies: + workbox-core "^4.3.1" + +workbox-precaching@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-4.3.1.tgz#9fc45ed122d94bbe1f0ea9584ff5940960771cba" + integrity sha512-piSg/2csPoIi/vPpp48t1q5JLYjMkmg5gsXBQkh/QYapCdVwwmKlU9mHdmy52KsDGIjVaqEUMFvEzn2LRaigqQ== + dependencies: + workbox-core "^4.3.1" + +workbox-range-requests@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-4.3.1.tgz#f8a470188922145cbf0c09a9a2d5e35645244e74" + integrity sha512-S+HhL9+iTFypJZ/yQSl/x2Bf5pWnbXdd3j57xnb0V60FW1LVn9LRZkPtneODklzYuFZv7qK6riZ5BNyc0R0jZA== + dependencies: + workbox-core "^4.3.1" + +workbox-routing@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-4.3.1.tgz#a675841af623e0bb0c67ce4ed8e724ac0bed0cda" + integrity sha512-FkbtrODA4Imsi0p7TW9u9MXuQ5P4pVs1sWHK4dJMMChVROsbEltuE79fBoIk/BCztvOJ7yUpErMKa4z3uQLX+g== + dependencies: + workbox-core "^4.3.1" + +workbox-strategies@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-4.3.1.tgz#d2be03c4ef214c115e1ab29c9c759c9fe3e9e646" + integrity sha512-F/+E57BmVG8dX6dCCopBlkDvvhg/zj6VDs0PigYwSN23L8hseSRwljrceU2WzTvk/+BSYICsWmRq5qHS2UYzhw== + dependencies: + workbox-core "^4.3.1" + +workbox-streams@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-4.3.1.tgz#0b57da70e982572de09c8742dd0cb40a6b7c2cc3" + integrity sha512-4Kisis1f/y0ihf4l3u/+ndMkJkIT4/6UOacU3A4BwZSAC9pQ9vSvJpIi/WFGQRH/uPXvuVjF5c2RfIPQFSS2uA== + dependencies: + workbox-core "^4.3.1" + +workbox-sw@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-4.3.1.tgz#df69e395c479ef4d14499372bcd84c0f5e246164" + integrity sha512-0jXdusCL2uC5gM3yYFT6QMBzKfBr2XTk0g5TPAV4y8IZDyVNDyj1a8uSXy3/XrvkVTmQvLN4O5k3JawGReXr9w== + +workbox-webpack-plugin@4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-4.3.1.tgz#47ff5ea1cc074b6c40fb5a86108863a24120d4bd" + integrity sha512-gJ9jd8Mb8wHLbRz9ZvGN57IAmknOipD3W4XNE/Lk/4lqs5Htw4WOQgakQy/o/4CoXQlMCYldaqUg+EJ35l9MEQ== + dependencies: + "@babel/runtime" "^7.0.0" + json-stable-stringify "^1.0.1" + workbox-build "^4.3.1" + +workbox-window@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-4.3.1.tgz#ee6051bf10f06afa5483c9b8dfa0531994ede0f3" + integrity sha512-C5gWKh6I58w3GeSc0wp2Ne+rqVw8qwcmZnQGpjiek8A2wpbxSJb1FdCoQVO+jDJs35bFgo/WETgl1fqgsxN0Hg== + dependencies: + workbox-core "^4.3.1" + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +worker-rpc@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/worker-rpc/-/worker-rpc-0.1.1.tgz#cb565bd6d7071a8f16660686051e969ad32f54d5" + integrity sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg== + dependencies: + microevent.ts "~0.1.1" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529" + integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + +ws@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" + integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== + dependencies: + async-limiter "~1.0.0" + +ws@^6.1.2, ws@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + +xmlchars@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.7.2: + version "1.8.3" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.8.3.tgz#2f420fca58b68ce3a332d0ca64be1d191dd3f87a" + integrity sha512-X/v7VDnK+sxbQ2Imq4Jt2PRUsRsP7UcpSl3Llg6+NRRqWLIvxkMFYtH1FmvwNGYRKKPa+EPA4qDBlI9WVG1UKw== + dependencies: + "@babel/runtime" "^7.8.7" + +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^18.1.1: + version "18.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.1.tgz#bf7407b915427fc760fcbbccc6c82b4f0ffcbd37" + integrity sha512-KRHEsOM16IX7XuLnMOqImcPNbLVXMNHYAoFc3BKR8Ortl5gzDbtXvvEoGx9imk5E+X1VeNKNlcHr8B8vi+7ipA== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@12.0.5: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" + +yargs@^13.3.0: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" + +yargs@^15.0.2: + version "15.3.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.1.tgz#9505b472763963e54afe60148ad27a330818e98b" + integrity sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.1" diff --git a/packages/server/.eslintrc.js b/packages/server/.eslintrc.js new file mode 100644 index 0000000..0ae17ca --- /dev/null +++ b/packages/server/.eslintrc.js @@ -0,0 +1,24 @@ +module.exports = { + parser: '@typescript-eslint/parser', + parserOptions: { + project: 'tsconfig.json', + sourceType: 'module', + }, + plugins: ['@typescript-eslint/eslint-plugin'], + extends: [ + 'plugin:@typescript-eslint/eslint-recommended', + 'plugin:@typescript-eslint/recommended', + 'prettier', + 'prettier/@typescript-eslint', + ], + root: true, + env: { + node: true, + jest: true, + }, + rules: { + '@typescript-eslint/interface-name-prefix': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/no-explicit-any': 'off', + }, +}; diff --git a/packages/server/.gitignore b/packages/server/.gitignore new file mode 100644 index 0000000..0fcb15a --- /dev/null +++ b/packages/server/.gitignore @@ -0,0 +1,392 @@ +# Created by .ignore support plugin (hsz.mobi) +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/dictionaries + +# Sensitive or high-churn files: +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.xml +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml + +# Gradle: +.idea/**/gradle.xml +.idea/**/libraries + +# CMake +cmake-build-debug/ + +# Mongo Explorer plugin: +.idea/**/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +### VisualStudio template +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Typescript v1 declaration files +typings/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ +coverage/ + +### macOS template +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +======= +# Local +docker-compose.yml +.env +dist diff --git a/packages/server/.prettierrc b/packages/server/.prettierrc new file mode 100644 index 0000000..dcb7279 --- /dev/null +++ b/packages/server/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "trailingComma": "all" +} \ No newline at end of file diff --git a/packages/server/README.md b/packages/server/README.md new file mode 100644 index 0000000..82b32cb --- /dev/null +++ b/packages/server/README.md @@ -0,0 +1,75 @@ +<p align="center"> + <a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo_text.svg" width="320" alt="Nest Logo" /></a> +</p> + +[travis-image]: https://api.travis-ci.org/nestjs/nest.svg?branch=master +[travis-url]: https://travis-ci.org/nestjs/nest +[linux-image]: https://img.shields.io/travis/nestjs/nest/master.svg?label=linux +[linux-url]: https://travis-ci.org/nestjs/nest + + <p align="center">A progressive <a href="http://nodejs.org" target="blank">Node.js</a> framework for building efficient and scalable server-side applications.</p> + <p align="center"> +<a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a> +<a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a> +<a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/dm/@nestjs/core.svg" alt="NPM Downloads" /></a> +<a href="https://travis-ci.org/nestjs/nest"><img src="https://api.travis-ci.org/nestjs/nest.svg?branch=master" alt="Travis" /></a> +<a href="https://travis-ci.org/nestjs/nest"><img src="https://img.shields.io/travis/nestjs/nest/master.svg?label=linux" alt="Linux" /></a> +<a href="https://coveralls.io/github/nestjs/nest?branch=master"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#5" alt="Coverage" /></a> +<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a> +<a href="https://opencollective.com/nest#backer"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a> +<a href="https://opencollective.com/nest#sponsor"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a> + <a href="https://paypal.me/kamilmysliwiec"><img src="https://img.shields.io/badge/Donate-PayPal-dc3d53.svg"/></a> + <a href="https://twitter.com/nestframework"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a> +</p> + <!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer) + [![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)--> + +## Description + +[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. + +## Installation + +```bash +$ npm install +``` + +## Running the app + +```bash +# development +$ npm run start + +# watch mode +$ npm run start:dev + +# production mode +$ npm run start:prod +``` + +## Test + +```bash +# unit tests +$ npm run test + +# e2e tests +$ npm run test:e2e + +# test coverage +$ npm run test:cov +``` + +## Support + +Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). + +## Stay in touch + +- Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec) +- Website - [https://nestjs.com](https://nestjs.com/) +- Twitter - [@nestframework](https://twitter.com/nestframework) + +## License + + Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE). diff --git a/packages/server/nest-cli.json b/packages/server/nest-cli.json new file mode 100644 index 0000000..64b992a --- /dev/null +++ b/packages/server/nest-cli.json @@ -0,0 +1,9 @@ +{ + "collection": "@nestjs/schematics", + "sourceRoot": "src", + "compilerOptions": { + "plugins": ["@nestjs/swagger/plugin"] + + } + +} \ No newline at end of file diff --git a/packages/server/package.json b/packages/server/package.json new file mode 100644 index 0000000..1790d66 --- /dev/null +++ b/packages/server/package.json @@ -0,0 +1,76 @@ +{ + "name": "@trycrypto/dappstarter-server", + "private": true, + "version": "1.0.0", + "description": "Nest TypeScript starter repository", + "license": "MIT", + "scripts": { + "prebuild": "rimraf dist", + "build": "nest build", + "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", + "start": "nest start", + "dev": "wait-on ../dapplib/src/dapp-config.json && nest start --exec ts-node-dev --watch --preserveWatchOutput", + "start:dev": "nest start --watch", + "start:debug": "nest start --debug --watch", + "start:prod": "node dist/main", + "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "test": "jest", + "test:watch": "jest --watch", + "test:cov": "jest --coverage", + "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", + "test:e2e": "jest --config ./test/jest-e2e.json" + }, + "dependencies": { + "@trycrypto/dappstarter-dapplib": "^0.1.0", + "@nestjs/common": "^7.0.1", + "@nestjs/core": "^7.0.1", + "@nestjs/platform-express": "^7.0.1", + "@nestjs/swagger": "^4.4.0", + "btoa": "^1.2.1", + "reflect-metadata": "^0.1.13", + "rimraf": "^3.0.2", + "rxjs": "^6.5.4", + "swagger-ui-express": "^4.1.3" + }, + "devDependencies": { + "@nestjs/cli": "^7.0.0", + "@nestjs/schematics": "^7.0.0", + "@nestjs/testing": "^7.0.1", + "@types/express": "^4.17.3", + "@types/jest": "^25.1.4", + "@types/node": "^13.9.1", + "@types/supertest": "^2.0.8", + "@typescript-eslint/eslint-plugin": "^2.23.0", + "@typescript-eslint/parser": "^2.23.0", + "eslint": "^6.8.0", + "eslint-config-prettier": "^6.10.0", + "eslint-plugin-import": "^2.20.1", + "jest": "^25.1.0", + "prettier": "^1.19.1", + "supertest": "^4.0.2", + "ts-jest": "^25.2.1", + "ts-loader": "^6.2.1", + "ts-node": "^8.6.2", + "ts-node-dev": "^1.0.0-pre.44", + "tsconfig-paths": "^3.9.0", + "typescript": "^3.8.3", + "wait-on": "^4.0.2" + }, + "jest": { + "moduleFileExtensions": [ + "js", + "json", + "ts" + ], + "rootDir": "src", + "testRegex": ".spec.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + }, + "collectCoverageFrom": [ + "**/*.(t|j)s" + ], + "coverageDirectory": "../coverage", + "testEnvironment": "node" + } +} diff --git a/packages/server/src/app.controller.ts b/packages/server/src/app.controller.ts new file mode 100644 index 0000000..8fd58ce --- /dev/null +++ b/packages/server/src/app.controller.ts @@ -0,0 +1,11 @@ +import { Controller, Get } from '@nestjs/common'; +import { AppService } from './app.service'; +import * as DappLib from '@trycrypto/dappstarter-dapplib'; +@Controller() +export class AppController { + constructor(private readonly appService: AppService) { } + @Get('isContractRunStateActive') + async isContractRunStateActive(): Promise<string> { + return await DappLib["isContractRunStateActive"].call(null, {}); + } +} diff --git a/packages/server/src/app.module.ts b/packages/server/src/app.module.ts new file mode 100644 index 0000000..8662803 --- /dev/null +++ b/packages/server/src/app.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { AppController } from './app.controller'; +import { AppService } from './app.service'; + +@Module({ + imports: [], + controllers: [AppController], + providers: [AppService], +}) +export class AppModule {} diff --git a/packages/server/src/app.service.ts b/packages/server/src/app.service.ts new file mode 100644 index 0000000..927d7cc --- /dev/null +++ b/packages/server/src/app.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class AppService { + getHello(): string { + return 'Hello World!'; + } +} diff --git a/packages/server/src/main.ts b/packages/server/src/main.ts new file mode 100644 index 0000000..be0a48b --- /dev/null +++ b/packages/server/src/main.ts @@ -0,0 +1,26 @@ +import { NestFactory } from '@nestjs/core'; +import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger' +import { AppModule } from './app.module'; + +async function bootstrap() { + const app = await NestFactory.create(AppModule); + app.enableCors({ + origin: true, + preflightContinue: false + }); + const options = new DocumentBuilder() + .setTitle('DappStarter') + .setDescription('Full-Stack Blockchain App Mojo') + .setVersion('1.0') + .addTag('trycrypto') + .build(); + const document = SwaggerModule.createDocument(app, options); + SwaggerModule.setup('/', app, document, { + customCss: ` + .topbar {display: none} + ` + }); + + await app.listen(process.env.PORT || 5002); +} +bootstrap(); diff --git a/packages/server/tsconfig.build.json b/packages/server/tsconfig.build.json new file mode 100644 index 0000000..2fe1df2 --- /dev/null +++ b/packages/server/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] +} diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json new file mode 100644 index 0000000..69f185f --- /dev/null +++ b/packages/server/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "module": "commonjs", + "declaration": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "target": "es2017", + "sourceMap": true, + "outDir": "./dist", + "baseUrl": "./", + "incremental": true + }, + "exclude": ["node_modules", "dist"] +} diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock new file mode 100644 index 0000000..cf8325d --- /dev/null +++ b/packages/server/yarn.lock @@ -0,0 +1,7072 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@angular-devkit/core@9.0.6": + version "9.0.6" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.6.tgz#cd4862e54f4dad9b47f515abf24e4d440cf8ba13" + integrity sha512-hCZJbnqLEm1F5Bx+ILcdd3LPgQTn4WFWpfUqMEGGj7UirRInWcz+6UpYotKGTJw85/mV01LrIbtWIkAUXbkkhg== + dependencies: + ajv "6.10.2" + fast-json-stable-stringify "2.0.0" + magic-string "0.25.4" + rxjs "6.5.3" + source-map "0.7.3" + +"@angular-devkit/schematics-cli@0.900.6": + version "0.900.6" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics-cli/-/schematics-cli-0.900.6.tgz#30bbc87c0d502526fb242a3394f083ec994c6315" + integrity sha512-TH8uPGK0sL2UACnYXnpnXLvH8rThDxfWCJrPQAWbFtE9R6vpb5n1jGqVt0DEacI1fcvOd2ANHiBGHDMShOHv1g== + dependencies: + "@angular-devkit/core" "9.0.6" + "@angular-devkit/schematics" "9.0.6" + "@schematics/schematics" "0.900.6" + inquirer "7.0.0" + minimist "1.2.0" + rxjs "6.5.3" + symbol-observable "1.2.0" + +"@angular-devkit/schematics@9.0.6": + version "9.0.6" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.6.tgz#5ad6e523919fee1314a12c9aa773612b4f5dbedb" + integrity sha512-X7qZDJVrFcPUn+jNUeOH7Bx1D7YTpTFr0d3DBIsQzseReSGu7ugWziQPS4gc5Xm5K0nb8vx6DYtyW0FaIvX0ZA== + dependencies: + "@angular-devkit/core" "9.0.6" + ora "4.0.2" + rxjs "6.5.3" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" + integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== + dependencies: + "@babel/highlight" "^7.8.3" + +"@babel/core@^7.1.0", "@babel/core@^7.7.5": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" + integrity sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.0" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helpers" "^7.9.0" + "@babel/parser" "^7.9.0" + "@babel/template" "^7.8.6" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.9.0": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.4.tgz#12441e90c3b3c4159cdecf312075bf1a8ce2dbce" + integrity sha512-rjP8ahaDy/ouhrvCoU1E5mqaitWrxwuNGU+dy1EpaoK48jZay4MdkskKGIMHLZNewg8sAsqpGSREJwP0zH3YQA== + dependencies: + "@babel/types" "^7.9.0" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/helper-function-name@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" + integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA== + dependencies: + "@babel/helper-get-function-arity" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-get-function-arity@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" + integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-member-expression-to-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz#659b710498ea6c1d9907e0c73f206eee7dadc24c" + integrity sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-imports@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz#7fe39589b39c016331b6b8c3f441e8f0b1419498" + integrity sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-transforms@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz#43b34dfe15961918707d247327431388e9fe96e5" + integrity sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-simple-access" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/template" "^7.8.6" + "@babel/types" "^7.9.0" + lodash "^4.17.13" + +"@babel/helper-optimise-call-expression@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz#7ed071813d09c75298ef4f208956006b6111ecb9" + integrity sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670" + integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ== + +"@babel/helper-replace-supers@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8" + integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.8.3" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/traverse" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/helper-simple-access@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz#7f8109928b4dab4654076986af575231deb639ae" + integrity sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw== + dependencies: + "@babel/template" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-split-export-declaration@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" + integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-validator-identifier@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed" + integrity sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw== + +"@babel/helpers@^7.9.0": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.2.tgz#b42a81a811f1e7313b88cba8adc66b3d9ae6c09f" + integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA== + dependencies: + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + +"@babel/highlight@^7.8.3": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" + integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== + dependencies: + "@babel/helper-validator-identifier" "^7.9.0" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.7.5", "@babel/parser@^7.8.6", "@babel/parser@^7.9.0": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8" + integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA== + +"@babel/plugin-syntax-bigint@^7.0.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-object-rest-spread@^7.0.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/template@^7.7.4", "@babel/template@^7.8.3", "@babel/template@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" + integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/parser" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/traverse@^7.1.0", "@babel/traverse@^7.7.4", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.0.tgz#d3882c2830e513f4fe4cec9fe76ea1cc78747892" + integrity sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.0" + "@babel/helper-function-name" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/parser" "^7.9.0" + "@babel/types" "^7.9.0" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.0.tgz#00b064c3df83ad32b2dbf5ff07312b15c7f1efb5" + integrity sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng== + dependencies: + "@babel/helper-validator-identifier" "^7.9.0" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@cnakazawa/watch@^1.0.3": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" + integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== + dependencies: + exec-sh "^0.3.2" + minimist "^1.2.0" + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz#10602de5570baea82f8afbfa2630b24e7a8cfe5b" + integrity sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" + integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== + +"@jest/console@^25.2.0": + version "25.2.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.2.0.tgz#e2c37024d97ded0448be8c846db4ce54aa4b66dd" + integrity sha512-mUQTLxw/q0S8duskmb1PY0Yq7RQ0Sr1st7pUhFCcJ7wcPRPFs5t6k6bJWTellAF/8wH/ar8tZSwSIiBYAj559w== + dependencies: + "@jest/source-map" "^25.2.0" + chalk "^3.0.0" + jest-util "^25.2.0" + slash "^3.0.0" + +"@jest/core@^25.2.0": + version "25.2.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.2.0.tgz#c1d65a7a2e4339b815dc0fe16d447f5eea7ed591" + integrity sha512-8R7gaUuMnilS8QBQOT5lF6KS/+ocHIiM6Ou9gnRB0GQA138I2G9tRs/D9MR9hkvuYGLy+VoqOTdLKUT60nzlVw== + dependencies: + "@jest/console" "^25.2.0" + "@jest/reporters" "^25.2.0" + "@jest/test-result" "^25.2.0" + "@jest/transform" "^25.2.0" + "@jest/types" "^25.2.0" + ansi-escapes "^4.2.1" + chalk "^3.0.0" + exit "^0.1.2" + graceful-fs "^4.2.3" + jest-changed-files "^25.2.0" + jest-config "^25.2.0" + jest-haste-map "^25.2.0" + jest-message-util "^25.2.0" + jest-regex-util "^25.2.0" + jest-resolve "^25.2.0" + jest-resolve-dependencies "^25.2.0" + jest-runner "^25.2.0" + jest-runtime "^25.2.0" + jest-snapshot "^25.2.0" + jest-util "^25.2.0" + jest-validate "^25.2.0" + jest-watcher "^25.2.0" + micromatch "^4.0.2" + p-each-series "^2.1.0" + realpath-native "^2.0.0" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^25.2.0": + version "25.2.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.2.0.tgz#20984739c9d85d03a15c0fb2a75558702202353c" + integrity sha512-cLkCRmVYg9QnyTLxZMUK72BVnwe/+ukxhwbt0DyFK+wayrlUtseusLfl9yvnarPzHtCWVx2LL68C6iOg2V1TdA== + dependencies: + "@jest/fake-timers" "^25.2.0" + "@jest/types" "^25.2.0" + jest-mock "^25.2.0" + +"@jest/fake-timers@^25.2.0": + version "25.2.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.2.0.tgz#9410a2f4db59f09d661005193d1626df22b316bb" + integrity sha512-IcxxIEHsBspeentekQW5OLJqBWfAb+CSabDo8yyYG13iX5mKq54B2bdqvvPdAZ5LGK7dgBsTsFgteEn0xTtylQ== + dependencies: + "@jest/types" "^25.2.0" + jest-message-util "^25.2.0" + jest-mock "^25.2.0" + jest-util "^25.2.0" + lolex "^5.0.0" + +"@jest/reporters@^25.2.0": + version "25.2.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.2.0.tgz#828dc217cb7480cdb138e5ff91174deaae80624a" + integrity sha512-raHy7kGJACB+F5ioLoKMsbWJv2RgaFAq/RdnMUtOODqGo973NeWcUJckSSY/FCvAvf3Mw2UOmQA90x5UZ4C0sg== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^25.2.0" + "@jest/test-result" "^25.2.0" + "@jest/transform" "^25.2.0" + "@jest/types" "^25.2.0" + chalk "^3.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.2" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^4.0.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.0.0" + jest-haste-map "^25.2.0" + jest-resolve "^25.2.0" + jest-util "^25.2.0" + jest-worker "^25.2.0" + slash "^3.0.0" + source-map "^0.6.0" + string-length "^3.1.0" + terminal-link "^2.0.0" + v8-to-istanbul "^4.0.1" + optionalDependencies: + node-notifier "^6.0.0" + +"@jest/source-map@^25.2.0": + version "25.2.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-25.2.0.tgz#2b2d4e587a85fd95dcf6f3bb757680ac9f662bda" + integrity sha512-KX8sYbzd8h7Nfc6dQjED8FzzR6o3QocpJllrBmsnb4BuVN7k2pLeIc2lRrUPXrPiidUwvA1H/AeIgGWNVacZvw== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.2.3" + source-map "^0.6.0" + +"@jest/test-result@^25.2.0": + version "25.2.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.2.0.tgz#8c0e50247c4633c92d463c5494a711215f7c1773" + integrity sha512-FoxHScuV+h2LFFF7I2Me22qSv+Rh1aBBKLvVqWNM0Rkevjil1+wKpri7hQh9NaTk28rAo/iZB1J4n4U75PzGQw== + dependencies: + "@jest/console" "^25.2.0" + "@jest/transform" "^25.2.0" + "@jest/types" "^25.2.0" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^25.2.0": + version "25.2.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.2.0.tgz#9d700bdd3296ee093c4797fb31fe4a705aad86bf" + integrity sha512-eYbitqvFZo1S6nJIEoyeqcIK4WY6Z/Dz+8/7DoloYpgxUFHvJVK95UPGFMC36zvA9nB4Xpr7ICqOzrOvg2iVRg== + dependencies: + "@jest/test-result" "^25.2.0" + jest-haste-map "^25.2.0" + jest-runner "^25.2.0" + jest-runtime "^25.2.0" + +"@jest/transform@^25.2.0": + version "25.2.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.2.0.tgz#c45ebbdc0414b1b20050b1fb58aadc67054a8643" + integrity sha512-PVElAX0TILnRB4iS81Yus0kvU1g/M4+jwies/joBg4Z6SljFRaWnz5ZEcb1io194hRp6G5VI+em8XTYNDVWHoQ== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^25.2.0" + babel-plugin-istanbul "^6.0.0" + chalk "^3.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.3" + jest-haste-map "^25.2.0" + jest-regex-util "^25.2.0" + jest-util "^25.2.0" + micromatch "^4.0.2" + pirates "^4.0.1" + realpath-native "^2.0.0" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + +"@jest/types@^25.2.0": + version "25.2.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.2.0.tgz#0659866d9b31843a737b601b950a690e576a415a" + integrity sha512-RLWBAON8LEjzD60Cn0XFmvMNTuV+scKlufIUApnG7VF7oA2jCEk5J0uzEchx6xuOwhrHohQM28K4CmEjgtDEwg== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^15.0.0" + chalk "^3.0.0" + +"@nestjs/cli@^7.0.0": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@nestjs/cli/-/cli-7.0.2.tgz#7c43b5acf42fffc1adba9d1653309d93cd04667b" + integrity sha512-Y2lbEVP8GUd4KsfTMIt4RKEYP1DkFAyjIaD+BN6hTi57uFTbRcoAQhBAbaHQzZgGrV8sAL7DXaLF0QDuZ8l1Ww== + dependencies: + "@angular-devkit/core" "9.0.6" + "@angular-devkit/schematics" "9.0.6" + "@angular-devkit/schematics-cli" "0.900.6" + "@nestjs/schematics" "^7.0.0" + "@types/webpack" "4.41.7" + chalk "3.0.0" + chokidar "3.3.1" + cli-table3 "0.5.1" + commander "4.1.1" + fork-ts-checker-webpack-plugin "4.1.0" + inquirer "7.1.0" + node-emoji "1.10.0" + ora "4.0.3" + os-name "3.1.0" + rimraf "3.0.2" + shelljs "0.8.3" + tree-kill "1.2.2" + tsconfig-paths "3.9.0" + tsconfig-paths-webpack-plugin "3.2.0" + typescript "^3.6.4" + webpack "4.42.0" + webpack-node-externals "1.7.2" + +"@nestjs/common@^7.0.1": + version "7.0.5" + resolved "https://registry.yarnpkg.com/@nestjs/common/-/common-7.0.5.tgz#244069292d4bbdc338a6700e86e7775f2168260d" + integrity sha512-9h7FDyg3rSjztTe9mLhvdIeGpqoNf2uwpJIeyizRcQFAdQfJWiPsV2mRkt/VYdit+nrv6C1ADtvQD47qqUuj6A== + dependencies: + axios "0.19.2" + cli-color "2.0.0" + tslib "1.11.1" + uuid "7.0.2" + +"@nestjs/core@^7.0.1": + version "7.0.5" + resolved "https://registry.yarnpkg.com/@nestjs/core/-/core-7.0.5.tgz#6fc07527f7b1434cac088322c231539c8a41a416" + integrity sha512-imIkdGOeraURKLGAGB5UT/9Lz5Hvujn6wJ0ONEXb7MvbmkbmIe1K4Mj8hngQc9/PXMssslVE7tbFLNsiG2Rubg== + dependencies: + "@nuxtjs/opencollective" "0.2.2" + fast-safe-stringify "2.0.7" + iterare "1.2.0" + object-hash "2.0.3" + path-to-regexp "3.2.0" + tslib "1.11.1" + uuid "7.0.2" + +"@nestjs/platform-express@^7.0.1": + version "7.0.5" + resolved "https://registry.yarnpkg.com/@nestjs/platform-express/-/platform-express-7.0.5.tgz#0c84487b0daa006b4062e60a404227cb911806a3" + integrity sha512-8o6+mTuIuOMJTwftS9y/bcFmnyp5uQMMZWSE7tjxdtPuQiZl7v0P00NdsUeBpwUmATJax07KH1zuSrcok57+KA== + dependencies: + body-parser "1.19.0" + cors "2.8.5" + express "4.17.1" + multer "1.4.2" + tslib "1.11.1" + +"@nestjs/schematics@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@nestjs/schematics/-/schematics-7.0.0.tgz#7b48bdcd50dad430957b2c112d555a5147c2e60e" + integrity sha512-R7Yw7wbRk5FNLyeJhvnAys+6ZXymIQWD6vKHOMRbSlR5LV8Q2F0st0EVw/sMmBOtp0EYAwGiXjwNV4ye/znmHA== + dependencies: + "@angular-devkit/core" "9.0.6" + "@angular-devkit/schematics" "9.0.6" + fs-extra "8.1.0" + +"@nestjs/swagger@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@nestjs/swagger/-/swagger-4.4.0.tgz#0d778b9e0c6cf68acb378d46332439c173e867e3" + integrity sha512-QatyTW8VANCEltPErW1t3yBam17e/5fsaZI7DfnLEMtya5LypDlicKdQN1BrWDbhBEhSbwQ5TZifdUs7lo3dlw== + dependencies: + lodash "4.17.15" + path-to-regexp "3.2.0" + +"@nestjs/testing@^7.0.1": + version "7.0.5" + resolved "https://registry.yarnpkg.com/@nestjs/testing/-/testing-7.0.5.tgz#b6d6ee4de31669e87e231d18b73f2f76e358719c" + integrity sha512-pk30gGvgcymftm6PJELTSpOd9txYl11YgTwU1WOXjTtHxzYQscIMU2+eUi5JOZlKcC9/tVMZ5K/G6IxS9UWDPQ== + dependencies: + optional "0.1.4" + tslib "1.11.1" + +"@nuxtjs/opencollective@0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@nuxtjs/opencollective/-/opencollective-0.2.2.tgz#26a761ebf588cc92a422d7cee996a66bd6e2761e" + integrity sha512-69gFVDs7mJfNjv9Zs5DFVD+pvBW+k1TaHSOqUWqAyTTfLcKI/EMYQgvEvziRd+zAFtUOoye6MfWh0qvinGISPw== + dependencies: + chalk "^2.4.1" + consola "^2.3.0" + node-fetch "^2.3.0" + +"@schematics/schematics@0.900.6": + version "0.900.6" + resolved "https://registry.yarnpkg.com/@schematics/schematics/-/schematics-0.900.6.tgz#2357c21da7129d4e9e122751ec14a221b8346ebf" + integrity sha512-AIHhA4qWffUHARZPgyIRVijB/AR14x+Esf6JRZ2OImoF9k8pc2uqb1NYlyHN9zMjd4XPsG9o9ZgPuSO+ClmUHg== + dependencies: + "@angular-devkit/core" "9.0.6" + "@angular-devkit/schematics" "9.0.6" + +"@sinonjs/commons@^1.7.0": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.1.tgz#da5fd19a5f71177a53778073978873964f49acf1" + integrity sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ== + dependencies: + type-detect "4.0.8" + +"@types/anymatch@*": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== + +"@types/babel__core@^7.1.0": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.6.tgz#16ff42a5ae203c9af1c6e190ed1f30f83207b610" + integrity sha512-tTnhWszAqvXnhW7m5jQU9PomXSiKXk2sFxpahXvI20SZKu9ylPi8WtIxueZ6ehDWikPT0jeFujMj3X4ZHuf3Tg== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.1" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.1.tgz#4901767b397e8711aeb99df8d396d7ba7b7f0e04" + integrity sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307" + integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.9.tgz#be82fab304b141c3eee81a4ce3b034d0eba1590a" + integrity sha512-jEFQ8L1tuvPjOI8lnpaf73oCJe+aoxL6ygqSy6c8LcW98zaC+4mzWuQIRCEvKeCOu+lbqdXcg4Uqmm1S8AP1tw== + dependencies: + "@babel/types" "^7.3.0" + +"@types/body-parser@*": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" + integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + +"@types/connect@*": + version "3.4.33" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" + integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== + dependencies: + "@types/node" "*" + +"@types/cookiejar@*": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.1.tgz#90b68446364baf9efd8e8349bb36bd3852b75b80" + integrity sha512-aRnpPa7ysx3aNW60hTiCtLHlQaIFsXFCgQlpakNgDNVFzbtusSY8PwjAQgRWfSk0ekNoBjO51eQRB6upA9uuyw== + +"@types/eslint-visitor-keys@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" + integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== + +"@types/express-serve-static-core@*": + version "4.17.3" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.3.tgz#dc8068ee3e354d7fba69feb86b3dfeee49b10f09" + integrity sha512-sHEsvEzjqN+zLbqP+8OXTipc10yH1QLR+hnr5uw29gi9AhCAAAdri8ClNV7iMdrJrIzXIQtlkPvq8tJGhj3QJQ== + dependencies: + "@types/node" "*" + "@types/range-parser" "*" + +"@types/express@^4.17.3": + version "4.17.3" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.3.tgz#38e4458ce2067873b09a73908df488870c303bd9" + integrity sha512-I8cGRJj3pyOLs/HndoP+25vOqhqWkAZsWMEmq1qXy/b/M3ppufecUwaK2/TVDVxcV61/iSdhykUjQQ2DLSrTdg== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/serve-static" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" + integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a" + integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA== + dependencies: + "@types/istanbul-lib-coverage" "*" + "@types/istanbul-lib-report" "*" + +"@types/jest@^25.1.4": + version "25.1.4" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-25.1.4.tgz#9e9f1e59dda86d3fd56afce71d1ea1b331f6f760" + integrity sha512-QDDY2uNAhCV7TMCITrxz+MRk1EizcsevzfeS6LykIlq2V1E5oO4wXG8V2ZEd9w7Snxeeagk46YbMgZ8ESHx3sw== + dependencies: + jest-diff "^25.1.0" + pretty-format "^25.1.0" + +"@types/json-schema@^7.0.3": + version "7.0.4" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" + integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + +"@types/mime@*": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d" + integrity sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw== + +"@types/node@*": + version "12.12.31" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.31.tgz#d6b4f9645fee17f11319b508fb1001797425da51" + integrity sha512-T+wnJno8uh27G9c+1T+a1/WYCHzLeDqtsGJkoEdSp2X8RTh3oOCZQcUnjAx90CS8cmmADX51O0FI/tu9s0yssg== + +"@types/node@^13.9.1": + version "13.9.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.4.tgz#63c58e67999bfbfa688dd49ed84639b01b543606" + integrity sha512-uzaaDXey/NI2l7kU+xCgWu852Dh/zmf6ZKApc0YQEQpY4DaiZFmLN29E6SLHJfSedj3iNWAndSwfSBpEDadJfg== + +"@types/prettier@^1.19.0": + version "1.19.1" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.1.tgz#33509849f8e679e4add158959fdb086440e9553f" + integrity sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ== + +"@types/range-parser@*": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" + integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== + +"@types/serve-static@*": + version "1.13.3" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.3.tgz#eb7e1c41c4468272557e897e9171ded5e2ded9d1" + integrity sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g== + dependencies: + "@types/express-serve-static-core" "*" + "@types/mime" "*" + +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== + +"@types/stack-utils@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" + integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== + +"@types/strip-bom@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/strip-bom/-/strip-bom-3.0.0.tgz#14a8ec3956c2e81edb7520790aecf21c290aebd2" + integrity sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I= + +"@types/strip-json-comments@0.0.30": + version "0.0.30" + resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1" + integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ== + +"@types/superagent@*": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@types/superagent/-/superagent-4.1.7.tgz#a7d92d98c490ee0f802a127fdf149b9a114f77a5" + integrity sha512-JSwNPgRYjIC4pIeOqLwWwfGj6iP1n5NE6kNBEbGx2V8H78xCPwx7QpNp9plaI30+W3cFEzJO7BIIsXE+dbtaGg== + dependencies: + "@types/cookiejar" "*" + "@types/node" "*" + +"@types/supertest@^2.0.8": + version "2.0.8" + resolved "https://registry.yarnpkg.com/@types/supertest/-/supertest-2.0.8.tgz#23801236e2b85204ed771a8e7c40febba7da2bda" + integrity sha512-wcax7/ip4XSSJRLbNzEIUVy2xjcBIZZAuSd2vtltQfRK7kxhx5WMHbLHkYdxN3wuQCrwpYrg86/9byDjPXoGMA== + dependencies: + "@types/superagent" "*" + +"@types/tapable@*": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.5.tgz#9adbc12950582aa65ead76bffdf39fe0c27a3c02" + integrity sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ== + +"@types/uglify-js@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082" + integrity sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ== + dependencies: + source-map "^0.6.1" + +"@types/webpack-sources@*": + version "0.1.7" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.7.tgz#0a330a9456113410c74a5d64180af0cbca007141" + integrity sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw== + dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.6.1" + +"@types/webpack@4.41.7": + version "4.41.7" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.7.tgz#22be27dbd4362b01c3954ca9b021dbc9328d9511" + integrity sha512-OQG9viYwO0V1NaNV7d0n79V+n6mjOV30CwgFPIfTzwmk8DHbt+C4f2aBGdCYbo3yFyYD6sjXfqqOjwkl1j+ulA== + dependencies: + "@types/anymatch" "*" + "@types/node" "*" + "@types/tapable" "*" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + source-map "^0.6.0" + +"@types/yargs-parser@*": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" + integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== + +"@types/yargs@^15.0.0": + version "15.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.4.tgz#7e5d0f8ca25e9d5849f2ea443cf7c402decd8299" + integrity sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg== + dependencies: + "@types/yargs-parser" "*" + +"@typescript-eslint/eslint-plugin@^2.23.0": + version "2.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.25.0.tgz#0b60917332f20dcff54d0eb9be2a9e9f4c9fbd02" + integrity sha512-W2YyMtjmlrOjtXc+FtTelVs9OhuR6OlYc4XKIslJ8PUJOqgYYAPRJhAqkYRQo3G4sjvG8jSodsNycEn4W2gHUw== + dependencies: + "@typescript-eslint/experimental-utils" "2.25.0" + functional-red-black-tree "^1.0.1" + regexpp "^3.0.0" + tsutils "^3.17.1" + +"@typescript-eslint/experimental-utils@2.25.0": + version "2.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.25.0.tgz#13691c4fe368bd377b1e5b1e4ad660b220bf7714" + integrity sha512-0IZ4ZR5QkFYbaJk+8eJ2kYeA+1tzOE1sBjbwwtSV85oNWYUBep+EyhlZ7DLUCyhMUGuJpcCCFL0fDtYAP1zMZw== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/typescript-estree" "2.25.0" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + +"@typescript-eslint/parser@^2.23.0": + version "2.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.25.0.tgz#abfb3d999084824d9a756d9b9c0f36fba03adb76" + integrity sha512-mccBLaBSpNVgp191CP5W+8U1crTyXsRziWliCqzj02kpxdjKMvFHGJbK33NroquH3zB/gZ8H511HEsJBa2fNEg== + dependencies: + "@types/eslint-visitor-keys" "^1.0.0" + "@typescript-eslint/experimental-utils" "2.25.0" + "@typescript-eslint/typescript-estree" "2.25.0" + eslint-visitor-keys "^1.1.0" + +"@typescript-eslint/typescript-estree@2.25.0": + version "2.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.25.0.tgz#b790497556734b7476fa7dd3fa539955a5c79e2c" + integrity sha512-VUksmx5lDxSi6GfmwSK7SSoIKSw9anukWWNitQPqt58LuYrKalzsgeuignbqnB+rK/xxGlSsCy8lYnwFfB6YJg== + dependencies: + debug "^4.1.1" + eslint-visitor-keys "^1.1.0" + glob "^7.1.6" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^6.3.0" + tsutils "^3.17.1" + +"@webassemblyjs/ast@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" + integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== + dependencies: + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + +"@webassemblyjs/floating-point-hex-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" + integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== + +"@webassemblyjs/helper-api-error@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" + integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== + +"@webassemblyjs/helper-buffer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" + integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== + +"@webassemblyjs/helper-code-frame@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" + integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== + dependencies: + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/helper-fsm@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" + integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== + +"@webassemblyjs/helper-module-context@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" + integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== + dependencies: + "@webassemblyjs/ast" "1.8.5" + mamacro "^0.0.3" + +"@webassemblyjs/helper-wasm-bytecode@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" + integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== + +"@webassemblyjs/helper-wasm-section@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" + integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + +"@webassemblyjs/ieee754@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" + integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" + integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" + integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== + +"@webassemblyjs/wasm-edit@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" + integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/helper-wasm-section" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-opt" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/wasm-gen@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" + integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wasm-opt@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" + integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + +"@webassemblyjs/wasm-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" + integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wast-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" + integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/floating-point-hex-parser" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-code-frame" "1.8.5" + "@webassemblyjs/helper-fsm" "1.8.5" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" + integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abab@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" + integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== + +accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-globals@^4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" + integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== + dependencies: + acorn "^6.0.1" + acorn-walk "^6.0.1" + +acorn-jsx@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" + integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== + +acorn-walk@^6.0.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" + integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== + +acorn@^6.0.1, acorn@^6.2.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" + integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== + +acorn@^7.1.0, acorn@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" + integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" + integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== + +ajv@6.10.2: + version "6.10.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" + integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5: + version "6.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" + integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-escapes@^4.2.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" + integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== + dependencies: + type-fest "^0.11.0" + +ansi-regex@^2.0.0, ansi-regex@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@^3.0.3, anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +append-field@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" + integrity sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY= + +aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-includes@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" + integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0" + is-string "^1.0.5" + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +array.prototype.flat@^1.2.1: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" + integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" + integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== + +axios@0.19.2: + version "0.19.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" + integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== + dependencies: + follow-redirects "1.5.10" + +babel-code-frame@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-jest@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.2.0.tgz#480de84cfa43c9403d7a5eaa6bf51a3ca75b2f84" + integrity sha512-N1ECYb8AvQ55yc5QkrdFAThYNDU9ec14b7GgGO8ohFp1p2KDw5fga1NFr8YLFjgtuyVaa2rfVTBAYKnVHzOyYA== + dependencies: + "@jest/transform" "^25.2.0" + "@jest/types" "^25.2.0" + "@types/babel__core" "^7.1.0" + babel-plugin-istanbul "^6.0.0" + babel-preset-jest "^25.2.0" + chalk "^3.0.0" + slash "^3.0.0" + +babel-plugin-istanbul@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" + integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^4.0.0" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.2.0.tgz#08785be7f40bda12e54a09cc89a44c5560a96f61" + integrity sha512-3JlSf80rRq8q8PTrLQ/6Tt1H6w+xCUJ6jiJdHoRzMXGy7ppb9fMBJLzq1iL2K5FIr3wzga6q9E9uRFB7E5aNLQ== + dependencies: + "@types/babel__traverse" "^7.0.6" + +babel-preset-jest@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-25.2.0.tgz#e0e2532ec023d3c0192475f911ff0a952191cdeb" + integrity sha512-rgqa2neISQ+PT3KyzNTKK51PUuezRUB2AB5SiBidbvme5cVkic5CbWzsRkz7nP6WVqVxsnc6te1F+pHs9rhd7g== + dependencies: + "@babel/plugin-syntax-bigint" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + babel-plugin-jest-hoist "^25.2.0" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" + integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + 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.17" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + +browser-resolve@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" + integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== + dependencies: + resolve "1.1.7" + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +btoa@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73" + integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g== + +buffer-from@1.x, buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +busboy@^0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" + integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM= + dependencies: + dicer "0.2.5" + readable-stream "1.1.x" + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cacache@^12.0.2: + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + +camelcase@^5.0.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +capture-exit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" + integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== + dependencies: + rsvp "^4.8.4" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@3.0.0, chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +chokidar@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450" + integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.3.0" + optionalDependencies: + fsevents "~2.1.2" + +chokidar@^2.0.2: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chrome-trace-event@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" + integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== + dependencies: + tslib "^1.9.0" + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cli-color@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-2.0.0.tgz#11ecfb58a79278cf6035a60c54e338f9d837897c" + integrity sha512-a0VZ8LeraW0jTuCkuAGMNufareGHhyZU9z8OGsW0gXd1hZGi1SRuNRXdbGkraBBKnhyUhyebFWnRbp+dIn0f0A== + dependencies: + ansi-regex "^2.1.1" + d "^1.0.1" + es5-ext "^0.10.51" + es6-iterator "^2.0.3" + memoizee "^0.4.14" + timers-ext "^0.1.7" + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-spinners@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77" + integrity sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ== + +cli-table3@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" + integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== + dependencies: + object-assign "^4.1.0" + string-width "^2.1.1" + optionalDependencies: + colors "^1.1.2" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +collect-v8-coverage@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.0.tgz#150ee634ac3650b71d9c985eb7f608942334feb1" + integrity sha512-VKIhJgvk8E1W28m5avZ2Gv2Ruv5YiF56ug2oclvaG9md69BuZImMG2sk9g7QNKLUbtYAKQjXjYxbYZVUlMMKmQ== + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colors@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-emitter@^1.2.0, component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0, concat-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +consola@^2.3.0: + version "2.11.3" + resolved "https://registry.yarnpkg.com/consola/-/consola-2.11.3.tgz#f7315836224c143ac5094b47fd4c816c2cd1560e" + integrity sha512-aoW0YIIAmeftGR8GSpw6CGQluNdkWMWh3yEFjH/hmynTYnMtibXszii3lxCXmk8YxJtI3FAK5aTiquA5VH68Gw== + +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +cookiejar@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" + integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cors@2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" + integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +cssom@^0.4.1: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.2.0.tgz#e4c44debccd6b7911ed617a4395e5754bba59992" + integrity sha512-sEb3XFPx3jNnCAMtqrXPDeSgQr+jojtCeNf8cvMNMh1cG970+lljssvQDzPq6lmmJu2Vhqood/gtEomBiHOGnA== + dependencies: + cssom "~0.3.6" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +data-urls@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" + integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== + dependencies: + abab "^2.0.0" + whatwg-mimetype "^2.2.0" + whatwg-url "^7.0.0" + +dateformat@~1.0.4-1.2.3: + version "1.0.12" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" + integrity sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk= + dependencies: + get-stdin "^4.0.1" + meow "^3.3.0" + +debounce@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.0.tgz#44a540abc0ea9943018dc0eaa95cce87f65cd131" + integrity sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg== + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@=3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^3.1.0: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize@^1.1.2, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +dicer@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" + integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8= + dependencies: + readable-stream "1.1.x" + streamsearch "0.1.2" + +diff-sequences@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.0.tgz#180bd89ff45c490b175de6dbb1d346db7b998a94" + integrity sha512-qTbUrz80F9q6rmEZjUoK2/SQTwgaOvnE5WjKlemKuod1iuB4WlSjY5ft2VUXacsqD9pXrWmERMPLi+j9RldxGg== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== + dependencies: + webidl-conversions "^4.0.2" + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +dynamic-dedupe@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz#06e44c223f5e4e94d78ef9db23a6515ce2f962a1" + integrity sha1-BuRMIj9eTpTXjvnbI6ZRXOL5YqE= + dependencies: + xtend "^4.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +elliptic@^6.0.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" + integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" + integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.17.0, es-abstract@^1.17.0-next.1: + version "1.17.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" + integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.1.5" + is-regex "^1.0.5" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimleft "^2.1.1" + string.prototype.trimright "^2.1.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.45, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.51, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@^2.0.3, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +es6-weak-map@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escodegen@^1.11.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.1.tgz#ba01d0c8278b5e95a9a45350142026659027a457" + integrity sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +eslint-config-prettier@^6.10.0: + version "6.10.1" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.10.1.tgz#129ef9ec575d5ddc0e269667bf09defcd898642a" + integrity sha512-svTy6zh1ecQojvpbJSgH3aei/Rt7C6i090l5f2WQ4aB05lYHeZIR1qL4wZyyILTbtmnbHP5Yn8MrsOJMGa8RkQ== + dependencies: + get-stdin "^6.0.0" + +eslint-import-resolver-node@^0.3.2: + version "0.3.3" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404" + integrity sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg== + dependencies: + debug "^2.6.9" + resolve "^1.13.1" + +eslint-module-utils@^2.4.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz#7878f7504824e1b857dd2505b59a8e5eda26a708" + integrity sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q== + dependencies: + debug "^2.6.9" + pkg-dir "^2.0.0" + +eslint-plugin-import@^2.20.1: + version "2.20.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz#802423196dcb11d9ce8435a5fc02a6d3b46939b3" + integrity sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw== + dependencies: + array-includes "^3.0.3" + array.prototype.flat "^1.2.1" + contains-path "^0.1.0" + debug "^2.6.9" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.2" + eslint-module-utils "^2.4.1" + has "^1.0.3" + minimatch "^3.0.4" + object.values "^1.1.0" + read-pkg-up "^2.0.0" + resolve "^1.12.0" + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-scope@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" + integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" + integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.0.0.tgz#7be1cc70f27a72a76cd14aa698bcabed6890e1cd" + integrity sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== + +eslint@^6.8.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" + integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.10.0" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^5.0.0" + eslint-utils "^1.4.3" + eslint-visitor-keys "^1.1.0" + espree "^6.1.2" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^7.0.0" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.14" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.3" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^6.1.2" + strip-ansi "^5.2.0" + strip-json-comments "^3.0.1" + table "^5.2.3" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^6.1.2: + version "6.2.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" + integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== + dependencies: + acorn "^7.1.1" + acorn-jsx "^5.2.0" + eslint-visitor-keys "^1.1.0" + +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.2.0.tgz#a010a519c0288f2530b3404124bfb5f02e9797fe" + integrity sha512-weltsSqdeWIX9G2qQZz7KlTRJdkkOCTPgLYJUz1Hacf48R4YOwGPHO3+ORfWedqJKbq5WQmsgK90n+pFLIKt/Q== + dependencies: + estraverse "^5.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.0.0.tgz#ac81750b482c11cca26e4b07e83ed8f75fbcdc22" + integrity sha512-j3acdrMzqrxmJTNj5dbr1YbjacrYgAxVMeF0gK16E3j494mOe7xygM/ZLIguEQ0ETwAg2hlJCtHRGav+y0Ny5A== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +event-emitter@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= + dependencies: + d "1" + es5-ext "~0.10.14" + +events@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" + integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +exec-sh@^0.3.2: + version "0.3.4" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" + integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^3.2.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" + integrity sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + p-finally "^2.0.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expect@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-25.2.0.tgz#7f365c1a5c08a224dbe8d335edd263b37b3c7932" + integrity sha512-T+s8WKwJ9NCmju9cFQ5ZTlYpEld2iNl1bhO4jXIFiaLF1hfW7wA91q4x1LYZrQ55HZZYs6x9skRLm//ImFK6BA== + dependencies: + "@jest/types" "^25.2.0" + ansi-styles "^4.0.0" + jest-get-type "^25.1.0" + jest-matcher-utils "^25.2.0" + jest-message-util "^25.2.0" + jest-regex-util "^25.2.0" + +express@4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" + integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== + dependencies: + type "^2.0.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + +fast-json-stable-stringify@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fast-safe-stringify@2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" + integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== + +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.1" + +figgy-pudding@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== + +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +filewatcher@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/filewatcher/-/filewatcher-3.0.1.tgz#f4a1957355ddaf443ccd78a895f3d55e23c8a034" + integrity sha1-9KGVc1Xdr0Q8zXiolfPVXiPIoDQ= + dependencies: + debounce "^1.0.0" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + 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" + +find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" + integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +fork-ts-checker-webpack-plugin@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.0.tgz#62bffe704426770fee33f15f0c0d56c86297fefd" + integrity sha512-2DLwUVUR/AdNmMD2utfmSR8r4qHRFhnfL6QQDQS5q4g5uBZzXYDgg8MXPIbu0HzyLjyvbogqjBNKILG5fufwzg== + dependencies: + babel-code-frame "^6.22.0" + chalk "^2.4.1" + micromatch "^3.1.10" + minimatch "^3.0.4" + semver "^5.6.0" + tapable "^1.0.0" + worker-rpc "^0.1.0" + +form-data@^2.3.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +formidable@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9" + integrity sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q== + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-extra@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.7: + version "1.2.12" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.12.tgz#db7e0d8ec3b0b45724fd4d83d43554a8f1f0de5c" + integrity sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +fsevents@^2.1.2, fsevents@~2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" + integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +gensync@^1.0.0-beta.1: + version "1.0.0-beta.1" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" + integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" + integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@^5.0.0, glob-parent@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + +glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^12.1.0: + version "12.4.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" + integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== + dependencies: + type-fest "^0.8.1" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" + integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== + +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.0, has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hosted-git-info@^2.1.4: + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== + dependencies: + whatwg-encoding "^1.0.1" + +html-escaper@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.1.tgz#beed86b5d2b921e92533aa11bce6d8e3b583dee7" + integrity sha512-hNX23TjWwD3q56HpWjUHOKj1+4KKlnjv9PcmBUYKVpga+2cnb9nDx/B1o0yO4n+RZXZdiNxzx6B24C9aNMTkkQ== + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + +iconv-lite@0.4.24, iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +import-fresh@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-local@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" + integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +inquirer@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.0.tgz#9e2b032dde77da1db5db804758b8fea3a970519a" + integrity sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ== + dependencies: + ansi-escapes "^4.2.1" + chalk "^2.4.2" + cli-cursor "^3.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.15" + mute-stream "0.0.8" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^4.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + +inquirer@7.1.0, inquirer@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.1.0.tgz#1298a01859883e17c7264b82870ae1034f92dd29" + integrity sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg== + dependencies: + ansi-escapes "^4.2.1" + chalk "^3.0.0" + cli-cursor "^3.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.15" + mute-stream "0.0.8" + run-async "^2.4.0" + rxjs "^6.5.3" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + +interpret@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" + integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== + +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-callable@^1.1.4, is-callable@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" + integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-promise@^2.1, is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-regex@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" + integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== + dependencies: + has "^1.0.3" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + +is-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== + +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + +is-typedarray@^1.0.0, is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +is-wsl@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.1.1.tgz#4a1c152d429df3d441669498e2486d3596ebaf1d" + integrity sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog== + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +istanbul-lib-coverage@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" + integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== + +istanbul-lib-instrument@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz#61f13ac2c96cfefb076fe7131156cc05907874e6" + integrity sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg== + dependencies: + "@babel/core" "^7.7.5" + "@babel/parser" "^7.7.5" + "@babel/template" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.0.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9" + integrity sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.0.tgz#d4d16d035db99581b6194e119bbf36c963c5eb70" + integrity sha512-2osTcC8zcOSUkImzN2EWQta3Vdi4WjjKw99P2yWx5mLnigAM0Rd5uYFn1cf2i/Ois45GkNjaoTqc5CxgMSX80A== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +iterare@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/iterare/-/iterare-1.2.0.tgz#7427f5ed45986e4b73e2fea903579f1117f3dd15" + integrity sha512-RxMV9p/UzdK0Iplnd8mVgRvNdXlsTOiuDrqMRnDi3wIhbT+JP4xDquAX9ay13R3CH72NBzQ91KWe0+C168QAyQ== + +jest-changed-files@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.2.0.tgz#b2d7ba9a389346d7e83cc10f95ca4cd05350de63" + integrity sha512-4pKQ0Be43Glqptu3HvXL4Vk3vZnAWI/S7nfonVM8ZBECJ85UVs+MOQrXc+4E4j4zIZ7Hoj7puq2g9Hw0ysjc1g== + dependencies: + "@jest/types" "^25.2.0" + execa "^3.2.0" + throat "^5.0.0" + +jest-cli@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.2.0.tgz#cd5a30862df63b5db7daaf67a005e4da35e6d9dd" + integrity sha512-lf/ZGpR45oAvtr+3jqJYIoOrAfqLMUg6qKfmELDpeh7k7COst/xw598CBauWng0m3TO4fYhaNMzuJhGAQQuKfA== + dependencies: + "@jest/core" "^25.2.0" + "@jest/test-result" "^25.2.0" + "@jest/types" "^25.2.0" + chalk "^3.0.0" + exit "^0.1.2" + import-local "^3.0.2" + is-ci "^2.0.0" + jest-config "^25.2.0" + jest-util "^25.2.0" + jest-validate "^25.2.0" + prompts "^2.0.1" + realpath-native "^2.0.0" + yargs "^15.3.1" + +jest-config@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.2.0.tgz#073f22c0679cce5de2dd5f7514966dc3c2bc2fbf" + integrity sha512-O8eKPyIiDNp6rRwSVyYiy5EZP2zKzIMEonzi0g4XBeZJIM/qebcMnPryzLR3eXKx4R8RlucLjLq6LOdKafrhOQ== + dependencies: + "@babel/core" "^7.1.0" + "@jest/test-sequencer" "^25.2.0" + "@jest/types" "^25.2.0" + babel-jest "^25.2.0" + chalk "^3.0.0" + deepmerge "^4.2.2" + glob "^7.1.1" + jest-environment-jsdom "^25.2.0" + jest-environment-node "^25.2.0" + jest-get-type "^25.1.0" + jest-jasmine2 "^25.2.0" + jest-regex-util "^25.2.0" + jest-resolve "^25.2.0" + jest-util "^25.2.0" + jest-validate "^25.2.0" + micromatch "^4.0.2" + pretty-format "^25.2.0" + realpath-native "^2.0.0" + +jest-diff@^25.1.0, jest-diff@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.2.0.tgz#d9d0138494b9c34acbb63508836cf11b6736f5dc" + integrity sha512-4qNJ9ELNECVeApQ62d8HWGyWzLOXwO81awCoKkHA34Kz8jyP8fQE1lQiZDmLmZRnzoFfIZAAo84u2DlBQ8SrsQ== + dependencies: + chalk "^3.0.0" + diff-sequences "^25.2.0" + jest-get-type "^25.1.0" + pretty-format "^25.2.0" + +jest-docblock@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-25.2.0.tgz#b1b78e275131bcaa9a5722e663545ed949c278ee" + integrity sha512-M7ZDbghaxFd2unWkyDFGLZDjPpIbDtEbICXSzwGrUBccFwVG/1dhLLAYX3D+98bFksaJuM0iMZGuIQUzKgnkQw== + dependencies: + detect-newline "^3.0.0" + +jest-each@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-25.2.0.tgz#745c60f5ada853e55af821e87d6f0ca0ad422d49" + integrity sha512-F8yllj7HhLvcvXO9FGmWm19S8N6ndGryx1INmyUVLduwph8nKos0vFTi0DzGC3QpCfyvlWIA/uCBry0zKbksNg== + dependencies: + "@jest/types" "^25.2.0" + chalk "^3.0.0" + jest-get-type "^25.1.0" + jest-util "^25.2.0" + pretty-format "^25.2.0" + +jest-environment-jsdom@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.2.0.tgz#15b38b1ba30e22763f9b44e27d5865dfcd44b52e" + integrity sha512-ODoKx5G3KOlfyREL9ZqekChZFsOJzNtt3nsna0AeptWwEO+BYT0k0Gj89EkWNg7uwjVTomIlQpSeA45E9uTk1A== + dependencies: + "@jest/environment" "^25.2.0" + "@jest/fake-timers" "^25.2.0" + "@jest/types" "^25.2.0" + jest-mock "^25.2.0" + jest-util "^25.2.0" + jsdom "^15.2.1" + +jest-environment-node@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.2.0.tgz#80726d398421368e90546e4c05b9dc1130f8c4fe" + integrity sha512-TP8kV360YWCbR96Kw2YQW8/SaF4jDcw5k2ImUvfmxXE8x2hqz6ARrj/2RE2Jstpn2RVihbyR45PBerg4yIvWPg== + dependencies: + "@jest/environment" "^25.2.0" + "@jest/fake-timers" "^25.2.0" + "@jest/types" "^25.2.0" + jest-mock "^25.2.0" + jest-util "^25.2.0" + +jest-get-type@^25.1.0: + version "25.1.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.1.0.tgz#1cfe5fc34f148dc3a8a3b7275f6b9ce9e2e8a876" + integrity sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw== + +jest-haste-map@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.2.0.tgz#ad425ff825f3fb8777154f055c5a7d11b3c6e7d2" + integrity sha512-VeoodAL671sKKXDvaT2r1Z/0GSDWJi/fAcDGuRAHrRCqkrPnPsV0Uq35YTNO0RrMF8LdRRogu6Mie1Eli2CVLA== + dependencies: + "@jest/types" "^25.2.0" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.3" + jest-serializer "^25.2.0" + jest-util "^25.2.0" + jest-worker "^25.2.0" + micromatch "^4.0.2" + sane "^4.0.3" + walker "^1.0.7" + which "^2.0.2" + optionalDependencies: + fsevents "^2.1.2" + +jest-jasmine2@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.2.0.tgz#255026fd3beefd463c0b85d0ce7628a83a91e1f8" + integrity sha512-MWb5J32Ft/CsV8raj/DZrt3Yx/uJgODev0WFSiD0K3BA+Iowcds/+Z5m3Xv0SyV7P4jO1gJD7stUX9gEiJ1U/g== + dependencies: + "@babel/traverse" "^7.1.0" + "@jest/environment" "^25.2.0" + "@jest/source-map" "^25.2.0" + "@jest/test-result" "^25.2.0" + "@jest/types" "^25.2.0" + chalk "^3.0.0" + co "^4.6.0" + expect "^25.2.0" + is-generator-fn "^2.0.0" + jest-each "^25.2.0" + jest-matcher-utils "^25.2.0" + jest-message-util "^25.2.0" + jest-runtime "^25.2.0" + jest-snapshot "^25.2.0" + jest-util "^25.2.0" + pretty-format "^25.2.0" + throat "^5.0.0" + +jest-leak-detector@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.2.0.tgz#0106b59877e79f180642e047ae24897f2b8fdb12" + integrity sha512-q9T+0roWegOMjoeGO4uxmnBSqvm33CXq6H+Eu2YmJxvUOiuVhfqMKekZqQS8SRxBiPZHXqEPVHgM3tDtWz0qIg== + dependencies: + jest-get-type "^25.1.0" + pretty-format "^25.2.0" + +jest-matcher-utils@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.2.0.tgz#d61f725b14f46e9eaf1b335324ecdf0b28845124" + integrity sha512-8E2ggFOJ5h1DPUqAswp78rasfqPap2Iryt06wtwrYXNJrbX0R5pi76eYdduSpPXn1atIbK+uxeJNmqYXLpddog== + dependencies: + chalk "^3.0.0" + jest-diff "^25.2.0" + jest-get-type "^25.1.0" + pretty-format "^25.2.0" + +jest-message-util@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.2.0.tgz#acafbc2343421bc1d157d7dfff86a1defdb9efdd" + integrity sha512-M0cFd+XU+G1MWB7M3BWM2Dejln4Uzub+P8+pCPZKfo8cBwGH1kZTgsXchV2MgOmhj2QQGKVwsuPqkLb0hhmiiw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@jest/test-result" "^25.2.0" + "@jest/types" "^25.2.0" + "@types/stack-utils" "^1.0.1" + chalk "^3.0.0" + micromatch "^4.0.2" + slash "^3.0.0" + stack-utils "^1.0.1" + +jest-mock@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.2.0.tgz#494f750595ef1539e49d1546fb20520180acb3b8" + integrity sha512-nnYlMdySmipWkTIqQprLDY9zXDSi9kkQdiDVnlga5+rygQ0ORhljIkGbx3+qH9Nhh5kXDu8ae2otIK0ptY4aWw== + dependencies: + "@jest/types" "^25.2.0" + +jest-pnp-resolver@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" + integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== + +jest-regex-util@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.0.tgz#1386764a0f57b79a3d930b628ca83696c0ac142f" + integrity sha512-D85pUKyzdi4zFAnub4EDp48eB08oua2aaN8wPrcaL98SnmJmJCSC+8iMZvonyy8qTtXgElK8JcsdPl4Y8+WhGg== + +jest-resolve-dependencies@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.2.0.tgz#dc89deefe635b1e08f11519fb3e7ea9e257af55e" + integrity sha512-hwPhteqTnlZyC19qQWBFaLW9+IqCyjmajb5nHqTEi+Jsn+Y74xrugBW0NlkFyCFsP7Chq+MjfU6z/wMGZJelbQ== + dependencies: + "@jest/types" "^25.2.0" + jest-regex-util "^25.2.0" + jest-snapshot "^25.2.0" + +jest-resolve@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-25.2.0.tgz#b1f5cc1ca1a67a215b9f425003eeabf5e60e98ad" + integrity sha512-VvmYRMDBFjKUri59zVa91s3V22XfON05oBIl+iNIktxOHxir0ui52+wVTBFGK19p2/aX0UzjKHkW/wJY1cELAw== + dependencies: + "@jest/types" "^25.2.0" + browser-resolve "^1.11.3" + chalk "^3.0.0" + jest-pnp-resolver "^1.2.1" + realpath-native "^2.0.0" + resolve "^1.15.1" + +jest-runner@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.2.0.tgz#f3fcfc57cd6fb0b848896ce309a57723d665acaf" + integrity sha512-x2QqSL2lGYkFLruD/5kGvSBpus5VoP464lkxwrmipKsu+hV3E1bhLuSi0vxM2WSQDCRGC0bzwkwo5LoT5NralA== + dependencies: + "@jest/console" "^25.2.0" + "@jest/environment" "^25.2.0" + "@jest/test-result" "^25.2.0" + "@jest/types" "^25.2.0" + chalk "^3.0.0" + exit "^0.1.2" + graceful-fs "^4.2.3" + jest-config "^25.2.0" + jest-docblock "^25.2.0" + jest-haste-map "^25.2.0" + jest-jasmine2 "^25.2.0" + jest-leak-detector "^25.2.0" + jest-message-util "^25.2.0" + jest-resolve "^25.2.0" + jest-runtime "^25.2.0" + jest-util "^25.2.0" + jest-worker "^25.2.0" + source-map-support "^0.5.6" + throat "^5.0.0" + +jest-runtime@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.2.0.tgz#8bff94eeb1d74c8807dc8080ab669b5b5ec69575" + integrity sha512-1FW9GrsYk5nfoD+ngICFu4Q2VglQyjg73/BixZkHwxSFIU5OKPrwBIL33lBFtRC/dwpn/rZDxmkxmqOH7jRGyg== + dependencies: + "@jest/console" "^25.2.0" + "@jest/environment" "^25.2.0" + "@jest/source-map" "^25.2.0" + "@jest/test-result" "^25.2.0" + "@jest/transform" "^25.2.0" + "@jest/types" "^25.2.0" + "@types/yargs" "^15.0.0" + chalk "^3.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.3" + jest-config "^25.2.0" + jest-haste-map "^25.2.0" + jest-message-util "^25.2.0" + jest-mock "^25.2.0" + jest-regex-util "^25.2.0" + jest-resolve "^25.2.0" + jest-snapshot "^25.2.0" + jest-util "^25.2.0" + jest-validate "^25.2.0" + realpath-native "^2.0.0" + slash "^3.0.0" + strip-bom "^4.0.0" + yargs "^15.3.1" + +jest-serializer@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-25.2.0.tgz#fd81440a0bd52f3c182ecabc2426c8efb4c0cf41" + integrity sha512-wCaA4dM1F4klHEpjRzAnv/8K4eqvB/0x4f6AA4W8ie8DP2XarCt6yAsdRCE+zw+htZSwcNOWvYvpOVov8y8pJA== + +jest-snapshot@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.2.0.tgz#2d852cce911ee93c801b2137d7e5e71ae43d57f7" + integrity sha512-oOVNsWwXWW5U6SozenTFkPTJdTkIudc5H2zpT4l8MA++HVU0pwNGKSZq0otbjaMUCs1ZE1PI/TfjaSKKg6fqNg== + dependencies: + "@babel/types" "^7.0.0" + "@jest/types" "^25.2.0" + "@types/prettier" "^1.19.0" + chalk "^3.0.0" + expect "^25.2.0" + jest-diff "^25.2.0" + jest-get-type "^25.1.0" + jest-matcher-utils "^25.2.0" + jest-message-util "^25.2.0" + jest-resolve "^25.2.0" + make-dir "^3.0.0" + natural-compare "^1.4.0" + pretty-format "^25.2.0" + semver "^6.3.0" + +jest-util@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.2.0.tgz#56aa5e3fc4ba3510849c805f362bd8f18959c0c5" + integrity sha512-xdpHSYUdqQy6JO52AQR02Z7QnaeRCXFqpuXm2gDvCYarXyodAcOs8J330OTNheHNpQz1fLkB09g8hW5fkZgvYg== + dependencies: + "@jest/types" "^25.2.0" + chalk "^3.0.0" + is-ci "^2.0.0" + make-dir "^3.0.0" + +jest-validate@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-25.2.0.tgz#2ea5ec81b0c4dec5454bcc4834c68f60c42a9b8c" + integrity sha512-FcueQUXWhnD45DJFhDux3FQDrXcLLFvPU6mNQimu1FCOblWxiqDPc9GzRc8dvvU5U8F+j6ohtd+vH/BkjZ1M/g== + dependencies: + "@jest/types" "^25.2.0" + camelcase "^5.3.1" + chalk "^3.0.0" + jest-get-type "^25.1.0" + leven "^3.1.0" + pretty-format "^25.2.0" + +jest-watcher@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.2.0.tgz#5cb37355602b743eda565227ce2252bdc0ce92ee" + integrity sha512-jfUrHJfr4OEhJ0oGOqzH5yAXsUrtFWPalV2o6EI72T3Kp/mY3roUj/8RMmi7md/fL2GJ1BbcWzsQuaXuDRhJ0A== + dependencies: + "@jest/test-result" "^25.2.0" + "@jest/types" "^25.2.0" + ansi-escapes "^4.2.1" + chalk "^3.0.0" + jest-util "^25.2.0" + string-length "^3.1.0" + +jest-worker@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.2.0.tgz#2716fbf74fcae7d713778f60187fd1f96fa09d1a" + integrity sha512-oGzUBnVnRdb51Aru3XFNa0zOafAIEerqZoQow+Vy8LDDiy12dvSrOeVeO8oNrxCMkGG4JtXqX9IPC93JJiAk+g== + dependencies: + merge-stream "^2.0.0" + supports-color "^7.0.0" + +jest@^25.1.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-25.2.0.tgz#d7b9b9ce7007002a9b4586da9bf0e0414a10a27d" + integrity sha512-6vlNxNhkZZcFBpn6GkVHyEQZKE9zAsnYithlHAnkVLJYFdD6o4dV2S7uTFcxi6k9XEEN2ilVLuTe6PJ1qgbi4w== + dependencies: + "@jest/core" "^25.2.0" + import-local "^3.0.2" + jest-cli "^25.2.0" + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsdom@^15.2.1: + version "15.2.1" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-15.2.1.tgz#d2feb1aef7183f86be521b8c6833ff5296d07ec5" + integrity sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g== + dependencies: + abab "^2.0.0" + acorn "^7.1.0" + acorn-globals "^4.3.2" + array-equal "^1.0.0" + cssom "^0.4.1" + cssstyle "^2.0.0" + data-urls "^1.1.0" + domexception "^1.0.1" + escodegen "^1.11.1" + html-encoding-sniffer "^1.0.2" + nwsapi "^2.2.0" + parse5 "5.1.0" + pn "^1.1.0" + request "^2.88.0" + request-promise-native "^1.0.7" + saxes "^3.1.9" + symbol-tree "^3.2.2" + tough-cookie "^3.0.1" + w3c-hr-time "^1.0.1" + w3c-xmlserializer "^1.1.2" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^7.0.0" + ws "^7.0.0" + xml-name-validator "^3.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json5@2.x, json5@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.2.tgz#43ef1f0af9835dd624751a6b7fa48874fb2d608e" + integrity sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ== + dependencies: + minimist "^1.2.5" + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@^1.0.2, loader-utils@^1.2.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.memoize@4.x: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash.toarray@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" + integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE= + +lodash@4.17.15, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +log-symbols@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" + integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== + dependencies: + chalk "^2.4.2" + +lolex@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367" + integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A== + dependencies: + "@sinonjs/commons" "^1.7.0" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-queue@0.1: + version "0.1.0" + resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" + integrity sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM= + dependencies: + es5-ext "~0.10.2" + +macos-release@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f" + integrity sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA== + +magic-string@0.25.4: + version "0.25.4" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.4.tgz#325b8a0a79fc423db109b77fd5a19183b7ba5143" + integrity sha512-oycWO9nEVAP2RVPbIoDoA4Y7LFIJ3xRYov93gAyJhZkET1tNuB0u7uWkZS2LpBWTJUWnmau/To8ECWRC+jKNfw== + dependencies: + sourcemap-codec "^1.4.4" + +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392" + integrity sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w== + dependencies: + semver "^6.0.0" + +make-error@1.x, make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= + dependencies: + tmpl "1.0.x" + +mamacro@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" + integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +memoizee@^0.4.14: + version "0.4.14" + resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.14.tgz#07a00f204699f9a95c2d9e77218271c7cd610d57" + integrity sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg== + dependencies: + d "1" + es5-ext "^0.10.45" + es6-weak-map "^2.0.2" + event-emitter "^0.3.5" + is-promise "^2.1" + lru-queue "0.1" + next-tick "1" + timers-ext "^0.1.5" + +memory-fs@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +meow@^3.3.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +methods@^1.1.1, methods@^1.1.2, methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +microevent.ts@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" + integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g== + +micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.0, micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.43.0: + version "1.43.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" + integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== + +mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.26" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" + integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== + dependencies: + mime-db "1.43.0" + +mime@1.6.0, mime@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.x, mkdirp@^0.5.1: + version "0.5.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.4.tgz#fd01504a6797ec5c9be81ff43d204961ed64a512" + integrity sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw== + dependencies: + minimist "^1.2.5" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +multer@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.2.tgz#2f1f4d12dbaeeba74cb37e623f234bf4d3d2057a" + integrity sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg== + dependencies: + append-field "^1.0.0" + busboy "^0.2.11" + concat-stream "^1.5.2" + mkdirp "^0.5.1" + object-assign "^4.1.1" + on-finished "^2.3.0" + type-is "^1.6.4" + xtend "^4.0.0" + +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +nan@^2.12.1: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.5.0, neo-async@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +next-tick@1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-emoji@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" + integrity sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw== + dependencies: + lodash.toarray "^4.4.0" + +node-fetch@^2.3.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" + integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + +node-modules-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" + integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= + +node-notifier@^5.4.0: + version "5.4.3" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" + integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== + dependencies: + growly "^1.3.0" + is-wsl "^1.1.0" + semver "^5.5.0" + shellwords "^0.1.1" + which "^1.3.0" + +node-notifier@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-6.0.0.tgz#cea319e06baa16deec8ce5cd7f133c4a46b68e12" + integrity sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw== + dependencies: + growly "^1.3.0" + is-wsl "^2.1.1" + semver "^6.3.0" + shellwords "^0.1.1" + which "^1.3.1" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +npm-run-path@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +nwsapi@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-hash@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.3.tgz#d12db044e03cd2ca3d77c0570d87225b02e1e6ea" + integrity sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg== + +object-inspect@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +object.values@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" + integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + has "^1.0.3" + +on-finished@^2.3.0, on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" + integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== + dependencies: + mimic-fn "^2.1.0" + +optional@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/optional/-/optional-0.1.4.tgz#cdb1a9bedc737d2025f690ceeb50e049444fd5b3" + integrity sha512-gtvrrCfkE08wKcgXaVwQVgwEQ8vel2dc5DDBn9RLQZ3YtmtkBss6A2HY6BnJH4N/4Ku97Ri/SF8sNWE2225WJw== + +optionator@^0.8.1, optionator@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +ora@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/ora/-/ora-4.0.2.tgz#0e1e68fd45b135d28648b27cf08081fa6e8a297d" + integrity sha512-YUOZbamht5mfLxPmk4M35CD/5DuOkAacxlEUbStVXpBAt4fyhBf+vZHI/HRkI++QUp3sNoeA2Gw4C+hi4eGSig== + dependencies: + chalk "^2.4.2" + cli-cursor "^3.1.0" + cli-spinners "^2.2.0" + is-interactive "^1.0.0" + log-symbols "^3.0.0" + strip-ansi "^5.2.0" + wcwidth "^1.0.1" + +ora@4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/ora/-/ora-4.0.3.tgz#752a1b7b4be4825546a7a3d59256fa523b6b6d05" + integrity sha512-fnDebVFyz309A73cqCipVL1fBZewq4vwgSHfxh43vVy31mbyoQ8sCH3Oeaog/owYOs/lLlGVPCISQonTneg6Pg== + dependencies: + chalk "^3.0.0" + cli-cursor "^3.1.0" + cli-spinners "^2.2.0" + is-interactive "^1.0.0" + log-symbols "^3.0.0" + mute-stream "0.0.8" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-name@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801" + integrity sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg== + dependencies: + macos-release "^2.2.0" + windows-release "^3.1.0" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-each-series@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.1.0.tgz#961c8dd3f195ea96c747e636b262b800a6b1af48" + integrity sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ== + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-finally@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" + integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" + integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-asn1@^5.0.0: + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse5@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" + integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-to-regexp@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-3.2.0.tgz#fa7877ecbc495c601907562222453c43cc204a5f" + integrity sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA== + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.0.7: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pirates@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" + integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== + dependencies: + node-modules-regexp "^1.0.0" + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prettier@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" + integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== + +pretty-format@^25.1.0, pretty-format@^25.2.0: + version "25.2.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.2.0.tgz#645003fb5da71a0ded46c90007dff0e03857de7d" + integrity sha512-BzmuH01b/lm0nl3M7Lcnku9Cv2UNMk9FgIrAiSuIus2QrjzV7Lf2DW+88SgEQUXQNkYWGtBV1289AuF6yMCtCQ== + dependencies: + "@jest/types" "^25.2.0" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^16.12.0" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +prompts@^2.0.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.2.tgz#480572d89ecf39566d2bd3fe2c9fccb7c4c0b068" + integrity sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.4" + +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +qs@^6.5.1: + version "6.9.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e" + integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +react-is@^16.12.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@1.1.x: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readdirp@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.3.0.tgz#984458d13a1e42e2e9f5841b129e162f369aff17" + integrity sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ== + dependencies: + picomatch "^2.0.7" + +realpath-native@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-2.0.0.tgz#7377ac429b6e1fd599dc38d08ed942d0d7beb866" + integrity sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q== + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +reflect-metadata@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +regexpp@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.0.0.tgz#dd63982ee3300e67b41c1956f850aa680d9d330e" + integrity sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g== + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +request-promise-core@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" + integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ== + dependencies: + lodash "^4.17.15" + +request-promise-native@^1.0.7: + version "1.0.8" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" + integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ== + dependencies: + request-promise-core "1.1.3" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + +request@^2.88.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + +resolve@1.x, resolve@^1.0.0, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.1, resolve@^1.3.2: + version "1.15.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" + integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== + dependencies: + path-parse "^1.0.6" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +rimraf@2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +rsvp@^4.8.4: + version "4.8.5" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" + integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== + +run-async@^2.2.0, run-async@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.0.tgz#e59054a5b86876cfae07f431d18cbaddc594f1e8" + integrity sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg== + dependencies: + is-promise "^2.1.0" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +rxjs@6.5.3: + version "6.5.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" + integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== + dependencies: + tslib "^1.9.0" + +rxjs@^6.4.0, rxjs@^6.5.3, rxjs@^6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" + integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sane@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" + integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== + dependencies: + "@cnakazawa/watch" "^1.0.3" + anymatch "^2.0.0" + capture-exit "^2.0.0" + exec-sh "^0.3.2" + execa "^1.0.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + +saxes@^3.1.9: + version "3.1.11" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b" + integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g== + dependencies: + xmlchars "^2.1.1" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5, semver@^5.5.0, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.1.2, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + 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.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-javascript@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" + integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shelljs@0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.3.tgz#a7f3319520ebf09ee81275b2368adb286659b097" + integrity sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +sisteransi@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.5.12, source-map-support@^0.5.6, source-map-support@~0.5.12: + version "0.5.16" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" + integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@0.7.3, source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +source-map@^0.5.0, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sourcemap-codec@^1.4.4: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" + integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +stack-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" + integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +stealthy-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +streamsearch@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= + +string-length@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837" + integrity sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA== + dependencies: + astral-regex "^1.0.0" + strip-ansi "^5.2.0" + +string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.trimleft@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" + integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string.prototype.trimright@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" + integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string_decoder@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +strip-json-comments@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" + integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== + +superagent@^3.8.3: + version "3.8.3" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.3.tgz#460ea0dbdb7d5b11bc4f78deba565f86a178e128" + integrity sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA== + dependencies: + component-emitter "^1.2.0" + cookiejar "^2.1.0" + debug "^3.1.0" + extend "^3.0.0" + form-data "^2.3.1" + formidable "^1.2.0" + methods "^1.1.1" + mime "^1.4.1" + qs "^6.5.1" + readable-stream "^2.3.5" + +supertest@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/supertest/-/supertest-4.0.2.tgz#c2234dbdd6dc79b6f15b99c8d6577b90e4ce3f36" + integrity sha512-1BAbvrOZsGA3YTCWqbmh14L0YEq0EGICX/nBnfkfVJn7SrxQV1I3pMYjSzG9y/7ZU2V9dWqyqk2POwxlb09duQ== + dependencies: + methods "^1.1.2" + superagent "^3.8.3" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + +supports-hyperlinks@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz#f663df252af5f37c5d49bbd7eeefa9e0b9e59e47" + integrity sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + +swagger-ui-dist@^3.18.1: + version "3.25.0" + resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-3.25.0.tgz#90279cdcc56e591fcfbe7b5240a9d653b989336d" + integrity sha512-vwvJPPbdooTvDwLGzjIXinOXizDJJ6U1hxnJL3y6U3aL1d2MSXDmKg2139XaLBhsVZdnQJV2bOkX4reB+RXamg== + +swagger-ui-express@^4.1.3: + version "4.1.4" + resolved "https://registry.yarnpkg.com/swagger-ui-express/-/swagger-ui-express-4.1.4.tgz#8b814ad998b850a1cf90e71808d6d0a8a8daf742" + integrity sha512-Ea96ecpC+Iq9GUqkeD/LFR32xSs8gYqmTW1gXCuKg81c26WV6ZC2FsBSPVExQP6WkyUuz5HEiR0sEv/HCC343g== + dependencies: + swagger-ui-dist "^3.18.1" + +symbol-observable@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + +symbol-tree@^3.2.2: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + +terser-webpack-plugin@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" + integrity sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^2.1.2" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser@^4.1.2: + version "4.6.7" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.7.tgz#478d7f9394ec1907f0e488c5f6a6a9a2bad55e72" + integrity sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +throat@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" + integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +timers-browserify@^2.0.4: + version "2.0.11" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" + integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== + dependencies: + setimmediate "^1.0.4" + +timers-ext@^0.1.5, timers-ext@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" + integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== + dependencies: + es5-ext "~0.10.46" + next-tick "1" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +tough-cookie@^2.3.3, tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tough-cookie@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" + integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== + dependencies: + ip-regex "^2.1.0" + psl "^1.1.28" + punycode "^2.1.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + +tree-kill@1.2.2, tree-kill@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + +ts-jest@^25.2.1: + version "25.2.1" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.2.1.tgz#49bf05da26a8b7fbfbc36b4ae2fcdc2fef35c85d" + integrity sha512-TnntkEEjuXq/Gxpw7xToarmHbAafgCaAzOpnajnFC6jI7oo1trMzAHA04eWpc3MhV6+yvhE8uUBAmN+teRJh0A== + dependencies: + bs-logger "0.x" + buffer-from "1.x" + fast-json-stable-stringify "2.x" + json5 "2.x" + lodash.memoize "4.x" + make-error "1.x" + mkdirp "0.x" + resolve "1.x" + semver "^5.5" + yargs-parser "^16.1.0" + +ts-loader@^6.2.1: + version "6.2.2" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-6.2.2.tgz#dffa3879b01a1a1e0a4b85e2b8421dc0dfff1c58" + integrity sha512-HDo5kXZCBml3EUPcc7RlZOV/JGlLHwppTLEHb3SHnr5V7NXD4klMEkrhJe5wgRbaWsSXi+Y1SIBN/K9B6zWGWQ== + dependencies: + chalk "^2.3.0" + enhanced-resolve "^4.0.0" + loader-utils "^1.0.2" + micromatch "^4.0.0" + semver "^6.0.0" + +ts-node-dev@^1.0.0-pre.44: + version "1.0.0-pre.44" + resolved "https://registry.yarnpkg.com/ts-node-dev/-/ts-node-dev-1.0.0-pre.44.tgz#2f4d666088481fb9c4e4f5bc8f15995bd8b06ecb" + integrity sha512-M5ZwvB6FU3jtc70i5lFth86/6Qj5XR5nMMBwVxZF4cZhpO7XcbWw6tbNiJo22Zx0KfjEj9py5DANhwLOkPPufw== + dependencies: + dateformat "~1.0.4-1.2.3" + dynamic-dedupe "^0.3.0" + filewatcher "~3.0.0" + minimist "^1.1.3" + mkdirp "^0.5.1" + node-notifier "^5.4.0" + resolve "^1.0.0" + rimraf "^2.6.1" + source-map-support "^0.5.12" + tree-kill "^1.2.1" + ts-node "*" + tsconfig "^7.0.0" + +ts-node@*, ts-node@^8.6.2: + version "8.8.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.8.1.tgz#7c4d3e9ed33aa703b64b28d7f9d194768be5064d" + integrity sha512-10DE9ONho06QORKAaCBpPiFCdW+tZJuY/84tyypGtl6r+/C7Asq0dhqbRZURuUlLQtZxxDvT8eoj8cGW0ha6Bg== + dependencies: + arg "^4.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.6" + yn "3.1.1" + +tsconfig-paths-webpack-plugin@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-3.2.0.tgz#6e70bd42915ad0efb64d3385163f0c1270f3e04d" + integrity sha512-S/gOOPOkV8rIL4LurZ1vUdYCVgo15iX9ZMJ6wx6w2OgcpT/G4wMyHB6WM+xheSqGMrWKuxFul+aXpCju3wmj/g== + dependencies: + chalk "^2.3.0" + enhanced-resolve "^4.0.0" + tsconfig-paths "^3.4.0" + +tsconfig-paths@3.9.0, tsconfig-paths@^3.4.0, tsconfig-paths@^3.9.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" + integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.0" + strip-bom "^3.0.0" + +tsconfig@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-7.0.0.tgz#84538875a4dc216e5c4a5432b3a4dec3d54e91b7" + integrity sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw== + dependencies: + "@types/strip-bom" "^3.0.0" + "@types/strip-json-comments" "0.0.30" + strip-bom "^3.0.0" + strip-json-comments "^2.0.0" + +tslib@1.11.1, tslib@^1.8.1, tslib@^1.9.0: + version "1.11.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" + integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== + +tsutils@^3.17.1: + version "3.17.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" + integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== + dependencies: + tslib "^1.8.1" + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" + integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +type-is@^1.6.4, type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" + integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +typescript@^3.6.4, typescript@^3.8.3: + version "3.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" + integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.2.tgz#7ff5c203467e91f5e0d85cfcbaaf7d2ebbca9be6" + integrity sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw== + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +v8-compile-cache@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" + integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== + +v8-to-istanbul@^4.0.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-4.1.2.tgz#387d173be5383dbec209d21af033dcb892e3ac82" + integrity sha512-G9R+Hpw0ITAmPSr47lSlc5A1uekSYzXxTMlFxso2xoffwo4jQnzbv1p9yXIinO8UMZKfAFewaCHwWvnH4Jb4Ug== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +w3c-hr-time@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + +w3c-xmlserializer@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz#30485ca7d70a6fd052420a3d12fd90e6339ce794" + integrity sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg== + dependencies: + domexception "^1.0.1" + webidl-conversions "^4.0.2" + xml-name-validator "^3.0.0" + +walker@^1.0.7, walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + dependencies: + makeerror "1.0.x" + +watchpack@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== + dependencies: + chokidar "^2.0.2" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + dependencies: + defaults "^1.0.3" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +webpack-node-externals@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz#6e1ee79ac67c070402ba700ef033a9b8d52ac4e3" + integrity sha512-ajerHZ+BJKeCLviLUUmnyd5B4RavLF76uv3cs6KNuO8W+HuQaEs0y0L7o40NQxdPy5w0pcv8Ew7yPUAQG0UdCg== + +webpack-sources@^1.4.0, webpack-sources@^1.4.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@4.42.0: + version "4.42.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.42.0.tgz#b901635dd6179391d90740a63c93f76f39883eb8" + integrity sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/wasm-edit" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + acorn "^6.2.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.1" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.3" + watchpack "^1.6.0" + webpack-sources "^1.4.1" + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@^1.2.9, which@^1.3.0, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1, which@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +windows-release@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.2.0.tgz#8122dad5afc303d833422380680a79cdfa91785f" + integrity sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA== + dependencies: + execa "^1.0.0" + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +worker-rpc@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/worker-rpc/-/worker-rpc-0.1.1.tgz#cb565bd6d7071a8f16660686051e969ad32f54d5" + integrity sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg== + dependencies: + microevent.ts "~0.1.1" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + +ws@^7.0.0: + version "7.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" + integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ== + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + +xmlchars@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yargs-parser@^16.1.0: + version "16.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-16.1.0.tgz#73747d53ae187e7b8dbe333f95714c76ea00ecf1" + integrity sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^18.1.1: + version "18.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.1.tgz#bf7407b915427fc760fcbbccc6c82b4f0ffcbd37" + integrity sha512-KRHEsOM16IX7XuLnMOqImcPNbLVXMNHYAoFc3BKR8Ortl5gzDbtXvvEoGx9imk5E+X1VeNKNlcHr8B8vi+7ipA== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^15.3.1: + version "15.3.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.1.tgz#9505b472763963e54afe60148ad27a330818e98b" + integrity sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.1" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== diff --git a/precheck.js b/precheck.js new file mode 100644 index 0000000..3960c4c --- /dev/null +++ b/precheck.js @@ -0,0 +1,21 @@ +const chalk = require("chalk"); +const detect = require("detect-port"); + +const preCheck = async (port) => { + const result = await detect(port); + if (result == port) return true; + throw new Error(`Required port [${port}] is currently in use`); +}; + +(async () => { + try { + await preCheck(5000); + await preCheck(5001); + await preCheck(5002); + await preCheck(5003); + } catch (error) { + console.error(chalk.yellowBright(error)); + process.exit(1); + } + process.exit(0); +})();